@camunda8/sdk
Version:
[](https://www.npmjs.com/package/@camunda8/sdk)
395 lines • 17.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Camunda8 = void 0;
const orchestration_cluster_api_1 = require("@camunda8/orchestration-cluster-api");
const admin_1 = require("../admin");
const lib_1 = require("../lib");
const modeler_1 = require("../modeler");
const operate_1 = require("../operate");
const optimize_1 = require("../optimize");
const tasklist_1 = require("../tasklist");
const zeebe_1 = require("../zeebe");
// Progressive adoption bridge: translate existing SDK config into OCA env-style overrides
const CamundaClientConfigTranslator_1 = require("../lib/CamundaClientConfigTranslator");
const CamundaSupportLogger_1 = require("../lib/CamundaSupportLogger");
const C8Logger_1 = require("./lib/C8Logger");
const CamundaRestClient_1 = require("./lib/CamundaRestClient");
/**
* A single point of configuration for all Camunda Platform 8 clients.
*
* This class is a factory for all the clients in the Camunda Platform 8 SDK. It allows a single point of configuration for all clients.
*
* @example
* ```typescript
* import { Camunda8 } from '@camunda8/sdk'
*
* const c8 = new Camunda8()
* // 8.8 REST API client - recommended
* const camunda = c8.getOrchestrationClusterApiClient() // returns `CamundaClient`
* // Loosely-typed 8.8 REST API client, for migration
* const camundaLoose = c8.getOrchestrationClusterApiClientLoose() // returns `CamundaClientLoose`
* // 8.7 REST API client
* const c8Rest = c8.getCamundaRestClient()
* // gRPC API client
* const zeebe = c8.getZeebeGrpcApiClient()
* // Infrastructure APIs
* const modeler = c8.getModelerApiClient()
* const admin = c8.getAdminApiClient()
* // Legacy v1 API clients
* const operate = c8.getOperateApiClient()
* const optimize = c8.getOptimizeApiClient()
* const tasklist = c8.getTasklistApiClient()
* ```
*/
class Camunda8 {
/**
* All constructor parameters for configuration are optional. If no configuration is provided, the SDK will use environment variables to configure itself.
* See {@link CamundaSDKConfiguration} for the complete list of configuration parameters. Values can be passed in explicitly in code, or set via environment variables (recommended: separate configuration and application logic).
* Explicitly set values will override environment variables, which are merged into the configuration.
*/
constructor(
/**
* Optional explicit overrides. With no configuration, the SDK will use environment variables to configure itself.
*/
config = {},
/**
* Optional global configuration for the Camunda8 instance.
*/
options = { defaultCached: true }) {
// Enhanced configuration-based caching (new functionality)
this.zeebeGrpcApiClients = new Map();
this.camundaRestClients = new Map();
this.operateApiClients = new Map();
this.tasklistApiClients = new Map();
this.optimizeApiClients = new Map();
this.adminApiClients = new Map();
this.modelerApiClients = new Map();
this.orchestrationRestClients = new Map();
this.orchestrationLooseClients = new Map();
// Client tracking for lifecycle management
this.createdClients = new Set();
this.configuration =
lib_1.CamundaEnvironmentConfigurator.mergeConfigWithEnvironment(config);
// Allow custom oAuthProvider to be passed in.
// See: https://github.com/camunda/camunda-8-js-sdk/issues/448
this.oAuthProvider =
config.oAuthProvider ??
(0, lib_1.constructOAuthProvider)(this.configuration, {
explicitFromConstructor: Object.prototype.hasOwnProperty.call(config ?? {}, 'CAMUNDA_AUTH_STRATEGY'),
});
this.defaultCached = options.defaultCached ?? true;
this.log = (0, C8Logger_1.getLogger)(config);
this.log.debug('Camunda8 SDK initialized');
}
/**
* @internal
* Private hook for framework integration. Not part of public API.
* Subject to change without notice. Use at your own risk.
*/
// @ts-expect-error - Intentionally unused, accessed via type bypass in frameworks
__registerApiClientCreationListener(callback) {
this.__apiClientCreationListener = callback;
}
/**
* Creates a deterministic cache key from configuration object
*/
createConfigKey(config) {
return JSON.stringify(config, Object.keys(config).sort());
}
/**
* Closes all created API clients and clears all caches
*/
async closeAllClients() {
const promises = Array.from(this.createdClients).map((client) => {
if (client instanceof zeebe_1.ZeebeGrpcClient) {
return client
.close()
.catch((err) => console.warn('Failed to close ZeebeGrpc client:', err));
}
if (client instanceof CamundaRestClient_1.CamundaRestClient) {
client.stopWorkers();
}
return Promise.resolve();
});
await Promise.all(promises);
// Clear all tracking
this.createdClients.clear();
// Clear all configuration-based caches
this.zeebeGrpcApiClients.clear();
this.camundaRestClients.clear();
this.operateApiClients.clear();
this.tasklistApiClients.clear();
this.optimizeApiClients.clear();
this.adminApiClients.clear();
this.modelerApiClients.clear();
}
/**
* Returns a client for the "Operate REST API"
* See: https://docs.camunda.io/docs/apis-tools/operate-api/overview/
*/
getOperateApiClient(config = {}, options = {}) {
const { cached = this.defaultCached } = options;
if (!cached) {
return this.createNewOperateApiClient(config);
}
const configKey = this.createConfigKey(config);
if (this.operateApiClients.has(configKey)) {
return this.operateApiClients.get(configKey);
}
const client = this.createNewOperateApiClient(config);
this.operateApiClients.set(configKey, client);
return client;
}
createNewOperateApiClient(config) {
const client = new operate_1.OperateApiClient({
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
});
this.createdClients.add(client);
this.__apiClientCreationListener?.(client);
return client;
}
/**
* Returns a client for the Administration REST API
* See: https://docs.camunda.io/docs/apis-tools/administration-api/administration-api-reference/
*/
getAdminApiClient(config = {}, options = {}) {
const { cached = this.defaultCached } = options;
if (!cached) {
return this.createNewAdminApiClient(config);
}
const configKey = this.createConfigKey(config);
if (this.adminApiClients.has(configKey)) {
return this.adminApiClients.get(configKey);
}
const client = this.createNewAdminApiClient(config);
this.adminApiClients.set(configKey, client);
return client;
}
createNewAdminApiClient(config) {
const client = new admin_1.AdminApiClient({
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
});
this.createdClients.add(client);
this.__apiClientCreationListener?.(client);
return client;
}
/**
* Returns a client for the Web Modeler REST API
* See: https://docs.camunda.io/docs/apis-tools/web-modeler-api/overview/
*/
getModelerApiClient(config = {}, options = {}) {
const { cached = this.defaultCached } = options;
if (!cached) {
return this.createNewModelerApiClient(config);
}
const configKey = this.createConfigKey(config);
if (this.modelerApiClients.has(configKey)) {
return this.modelerApiClients.get(configKey);
}
const client = this.createNewModelerApiClient(config);
this.modelerApiClients.set(configKey, client);
return client;
}
createNewModelerApiClient(config) {
const client = new modeler_1.ModelerApiClient({
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
});
this.createdClients.add(client);
this.__apiClientCreationListener?.(client);
return client;
}
/**
* Returns a client for the Optimize REST API
* See: https://docs.camunda.io/docs/apis-tools/optimize-api/overview/
*/
getOptimizeApiClient(config = {}, options = {}) {
const { cached = this.defaultCached } = options;
if (!cached) {
return this.createNewOptimizeApiClient(config);
}
const configKey = this.createConfigKey(config);
if (this.optimizeApiClients.has(configKey)) {
return this.optimizeApiClients.get(configKey);
}
const client = this.createNewOptimizeApiClient(config);
this.optimizeApiClients.set(configKey, client);
return client;
}
createNewOptimizeApiClient(config) {
const client = new optimize_1.OptimizeApiClient({
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
});
this.createdClients.add(client);
this.__apiClientCreationListener?.(client);
return client;
}
/**
* Returns a client for the Tasklist REST API
* See: https://docs.camunda.io/docs/apis-tools/tasklist-api-rest/tasklist-api-rest-overview/
*/
getTasklistApiClient(config = {}, options = {}) {
const { cached = this.defaultCached } = options;
if (!cached) {
return this.createNewTasklistApiClient(config);
}
const configKey = this.createConfigKey(config);
if (this.tasklistApiClients.has(configKey)) {
return this.tasklistApiClients.get(configKey);
}
const client = this.createNewTasklistApiClient(config);
this.tasklistApiClients.set(configKey, client);
return client;
}
createNewTasklistApiClient(config) {
const client = new tasklist_1.TasklistApiClient({
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
});
this.createdClients.add(client);
this.__apiClientCreationListener?.(client);
return client;
}
/**
* Returns a client for the Zeebe gRPC API
* See: https://docs.camunda.io/docs/apis-tools/zeebe-api/overview/
*/
getZeebeGrpcApiClient(config = {}, options = {}) {
const { cached = this.defaultCached } = options;
if (!cached) {
return this.createNewZeebeGrpcClient(config);
}
const configKey = this.createConfigKey(config);
if (this.zeebeGrpcApiClients.has(configKey)) {
return this.zeebeGrpcApiClients.get(configKey);
}
const client = this.createNewZeebeGrpcClient(config);
this.zeebeGrpcApiClients.set(configKey, client);
return client;
}
createNewZeebeGrpcClient(config) {
const client = new zeebe_1.ZeebeGrpcClient({
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
});
this.createdClients.add(client);
this.__apiClientCreationListener?.(client);
return client;
}
/**
* Returns a client for the Camunda 8 REST API
* See: https://docs.camunda.io/docs/apis-tools/camunda-api-rest/camunda-api-rest-overview/
*/
getCamundaRestClient(config = {}, options = {}) {
const { cached = this.defaultCached } = options;
if (!cached) {
return this.createNewCamundaRestClient(config);
}
const configKey = this.createConfigKey(config);
if (this.camundaRestClients.has(configKey)) {
return this.camundaRestClients.get(configKey);
}
const client = this.createNewCamundaRestClient(config);
this.camundaRestClients.set(configKey, client);
return client;
}
/**
* Returns a strongly-typed Orchestration Cluster API client, of type `CamundaClient`.
* See [here](https://camunda.github.io/orchestration-cluster-api-js/classes/index.CamundaClient.html) for full API documentation of the `CamundaClient`.
*
* This client exposes branded identifier types (e.g. {@link OrchestrationLifters.ProcessInstanceKey})
* to provide additional compile-time safety when interacting with the Orchestration Cluster API.
*
* The configuration passed here is merged with environment variables (see {@link CamundaSDKConfiguration}).
* When `options.cached` (default) is true, a client instance keyed by its effective configuration is reused.
*
* @param config Optional explicit SDK configuration overrides.
* @param options Client creation options (e.g. caching control).
* @returns {@link CamundaClient} A branded Orchestration Cluster API client instance.
*/
getOrchestrationClusterApiClient(config = {}, options = {}) {
const { cached = this.defaultCached } = options;
if (!cached) {
return this.createNewOrchestrationClusterApiClient(config);
}
const configKey = this.createConfigKey(config);
if (this.orchestrationRestClients.has(configKey)) {
return this.orchestrationRestClients.get(configKey);
}
const client = this.createNewOrchestrationClusterApiClient(config);
this.orchestrationRestClients.set(configKey, client);
return client;
}
/**
* Returns a loosely-typed Orchestration Cluster API client.
* This variant widens branded key types to primitive strings for progressive adoption.
*/
/**
* Returns a loosely-typed Orchestration Cluster API client.
*
* This variant widens branded identifier types to plain strings to make incremental adoption easier
* in existing codebases that already use raw string IDs. Use this when you prefer flexibility over
* the additional type safety provided by {@link getOrchestrationClusterApiClient}.
*
* @param config Optional explicit SDK configuration overrides.
* @param options Client creation options (e.g. caching control).
* @returns {@link CamundaClientLoose} A loose Orchestration Cluster API client instance.
*/
getOrchestrationClusterApiClientLoose(config = {}, options = {}) {
const { cached = this.defaultCached } = options;
if (!cached) {
return this.createNewOrchestrationClusterApiClientLoose(config);
}
const configKey = this.createConfigKey(config);
if (this.orchestrationLooseClients.has(configKey)) {
return this.orchestrationLooseClients.get(configKey);
}
const client = this.createNewOrchestrationClusterApiClientLoose(config);
this.orchestrationLooseClients.set(configKey, client);
return client;
}
createNewOrchestrationClusterApiClientLoose(config) {
const sdkMergedConfig = { ...this.configuration, ...config };
const envOverrides = (0, CamundaClientConfigTranslator_1.translateToOcaEnvOverrides)({
sdkConfig: sdkMergedConfig,
});
// Pass existing support logger instance so OCA client reuses singleton (no duplicate init)
const client = (0, orchestration_cluster_api_1.createCamundaClientLoose)({
config: envOverrides,
supportLogger: CamundaSupportLogger_1.CamundaSupportLogger.getInstance(),
});
this.createdClients.add(client);
this.__apiClientCreationListener?.(client);
return client;
}
createNewOrchestrationClusterApiClient(config) {
// Progressive adoption: translate existing SDK config to OCA overrides and pass directly.
// No mutation of process.env required now that CamundaOptions.config is exposed upstream.
const sdkMergedConfig = { ...this.configuration, ...config };
const envOverrides = (0, CamundaClientConfigTranslator_1.translateToOcaEnvOverrides)({
sdkConfig: sdkMergedConfig,
});
// Inject singleton support logger for unified diagnostic logging
const client = (0, orchestration_cluster_api_1.createCamundaClient)({
config: envOverrides,
supportLogger: CamundaSupportLogger_1.CamundaSupportLogger.getInstance(),
});
this.createdClients.add(client);
this.__apiClientCreationListener?.(client);
return client;
}
createNewCamundaRestClient(config) {
const client = new CamundaRestClient_1.CamundaRestClient({
config: { ...this.configuration, ...config },
oAuthProvider: this.oAuthProvider,
});
this.createdClients.add(client);
this.__apiClientCreationListener?.(client);
return client;
}
}
exports.Camunda8 = Camunda8;
//# sourceMappingURL=index.js.map