Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c0c451b
move modified openapi generated logic from ConductorClient
DmitryBorisov-sm Sep 10, 2025
c259b6d
cleanup
DmitryBorisov-sm Sep 10, 2025
c7b73f9
move token to AuthConductorClient
DmitryBorisov-sm Sep 10, 2025
60014db
move ConductorClientAPIConfig from openapi generated code
DmitryBorisov-sm Sep 10, 2025
13a7835
Merge branch 'main' into enable-http2
DmitryBorisov-sm Sep 11, 2025
f9b30dc
Merge branch 'main' into enable-http2
DmitryBorisov-sm Sep 11, 2025
2bfe23e
replace useEnvVars config variable with automatic selection
DmitryBorisov-sm Sep 12, 2025
7dd3525
refactor top layer code
DmitryBorisov-sm Sep 12, 2025
345ec05
regenerate OpenAPI code related to auth service
DmitryBorisov-sm Sep 12, 2025
4e34a7c
regenerate ConductorClient OpenAPI code
DmitryBorisov-sm Sep 12, 2025
d8439a2
ConductorClientWithAuth ts cleanup
DmitryBorisov-sm Sep 12, 2025
c301077
add http2 fetch
DmitryBorisov-sm Sep 15, 2025
34b1050
add support for native browser fetch
DmitryBorisov-sm Sep 15, 2025
9fa7db8
refactor
DmitryBorisov-sm Sep 15, 2025
c56103c
add ability to pass custom fetchFn, refactor code
DmitryBorisov-sm Sep 15, 2025
3558ed0
Update index.ts
DmitryBorisov-sm Sep 15, 2025
efe8bfa
restore OrkesConductorClient filename, restore openapi warnings
DmitryBorisov-sm Sep 15, 2025
4a52795
add deprecated warnings
DmitryBorisov-sm Sep 16, 2025
8fb92c3
refactor to add node v18 support
DmitryBorisov-sm Sep 16, 2025
63a101d
ConductorClientWithAuth: add automatic deAuth in case of multiple aut…
DmitryBorisov-sm Sep 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import { OrkesApiConfig, orkesConductorClient } from "@io-orkes/conductor-javasc
const config: Partial<OrkesApiConfig> = {
keyId: "XXX", // optional
keySecret: "XXXX", // optional
refreshTokenInterval: 0, // optional (in milliseconds) defaults to 30 minutes (30 * 60 * 1000). 0 no refresh
refreshTokenInterval: 0, // optional (in milliseconds) | defaults to 30 minutes | 0 = no refresh
serverUrl: "https://play.orkes.io/api",
};

Expand Down
File renamed without changes.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,8 @@
"suiteNameTemplate": "{filepath}",
"classNameTemplate": "{classname}",
"titleTemplate": "{title}"
},
"optionalDependencies": {
"undici": "^7.16.0"
}
}
}
2 changes: 1 addition & 1 deletion src/__test__/readme.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { TaskType } from "../common";
import { TaskRunner } from "../task";

describe("TaskManager", () => {
const clientPromise = orkesConductorClient({ useEnvVars: true });
const clientPromise = orkesConductorClient();

jest.setTimeout(20000);
test("worker example ", async () => {
Expand Down
1 change: 0 additions & 1 deletion src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ export {
ConductorClient,
ApiRequestOptions,
ApiResult,
ConductorClientAPIConfig,
OpenAPIConfig,
OnCancel,
ApiError,
Expand Down
69 changes: 11 additions & 58 deletions src/common/open-api/ConductorClient.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { BaseHttpRequest } from "./core/BaseHttpRequest";
import type { OpenAPIConfig, Resolver } from "./core/OpenAPI";

import type { OpenAPIConfig } from "./core/OpenAPI";
import { EventResourceService } from "./services/EventResourceService";
import { HealthCheckResourceService } from "./services/HealthCheckResourceService";
import { MetadataResourceService } from "./services/MetadataResourceService";
Expand All @@ -12,36 +12,12 @@ import { TaskResourceService } from "./services/TaskResourceService";
import { TokenResourceService } from "./services/TokenResourceService";
import { WorkflowBulkResourceService } from "./services/WorkflowBulkResourceService";
import { WorkflowResourceService } from "./services/WorkflowResourceService";
import { request as baseRequest } from "./core/request";
import { ConductorHttpRequest } from "../RequestCustomizer";
import { HumanTaskService } from "./services/HumanTaskService";
import { HumanTaskResourceService } from "./services/HumanTaskResourceService";
import {ServiceRegistryResourceService} from "./services/ServiceRegistryResourceService";

export const defaultRequestHandler: ConductorHttpRequest = (
request,
config,
options
) => request(config, options);

export interface ConductorClientAPIConfig extends Omit<OpenAPIConfig, "BASE"> {
serverUrl: string;
useEnvVars: boolean;
}

const getServerBaseURL = (config?: Partial<ConductorClientAPIConfig>) => {
if (config?.useEnvVars) {
if(!process.env.CONDUCTOR_SERVER_URL) {
throw new Error(
"Environment variable CONDUCTOR_SERVER_URL is not defined."
);
}
import { ServiceRegistryResourceService } from "./services/ServiceRegistryResourceService";
import { NodeHttpRequest } from "./core/NodeHttpRequest";

return process.env.CONDUCTOR_SERVER_URL;
}

return config?.serverUrl ?? "http://localhost:8080";
};
type HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest;

export class ConductorClient {
public readonly eventResource: EventResourceService;
Expand All @@ -53,47 +29,25 @@ export class ConductorClient {
public readonly workflowBulkResource: WorkflowBulkResourceService;
public readonly workflowResource: WorkflowResourceService;
public readonly serviceRegistryResource: ServiceRegistryResourceService;

public readonly humanTask: HumanTaskService;
public readonly humanTaskResource: HumanTaskResourceService;
public readonly request: BaseHttpRequest;

public token?: string | Resolver<string>;

constructor(
config?: Partial<ConductorClientAPIConfig>,
requestHandler: ConductorHttpRequest = defaultRequestHandler
config?: Partial<OpenAPIConfig>,
HttpRequest: HttpRequestConstructor = NodeHttpRequest
) {
const resolvedConfig = {
BASE: getServerBaseURL(config),
VERSION: config?.VERSION ?? "0",
this.request = new HttpRequest({
BASE: config?.BASE ?? "http://localhost:8080",
VERSION: config?.VERSION ?? "2",
WITH_CREDENTIALS: config?.WITH_CREDENTIALS ?? false,
CREDENTIALS: config?.CREDENTIALS ?? "include",
TOKEN: config?.TOKEN,
USERNAME: config?.USERNAME,
PASSWORD: config?.PASSWORD,
HEADERS: config?.HEADERS,
ENCODE_PATH: config?.ENCODE_PATH,
};

// START conductor-client-modification
/* The generated models are all based on the concept of an instantiated base http
class. To avoid making edits there, we just create an object that satisfies the same
interface. Yay typescript!
*/
this.request = {
config: resolvedConfig,
request: (apiConfig) => {
return requestHandler(
baseRequest,
{ ...resolvedConfig, TOKEN: this.token },
apiConfig
);
},
};
this.token = config?.TOKEN;
// END conductor-client-modification

});
this.eventResource = new EventResourceService(this.request);
this.healthCheckResource = new HealthCheckResourceService(this.request);
this.metadataResource = new MetadataResourceService(this.request);
Expand All @@ -106,5 +60,4 @@ export class ConductorClient {
this.humanTask = new HumanTaskService(this.request);
this.humanTaskResource = new HumanTaskResourceService(this.request);
}
stop() {}
}
2 changes: 1 addition & 1 deletion src/common/open-api/__test__/EventResourceService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { orkesConductorClient } from "../../../orkes";

describe("EventResourceService", () => {
test("Should create an event handler with description and tags and then delete it", async () => {
const orkesClient = await orkesConductorClient({ useEnvVars: true });
const orkesClient = await orkesConductorClient();
const eventApi = orkesClient.eventResource;

const [eventName, event, eventDescription, eventTagKey, eventTagValue] = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ describe("WorkflowResourceService", () => {
jest.setTimeout(120000);

test("Should test a workflow", async () => {
const client = await orkesConductorClient({ useEnvVars: true });
const client = await orkesConductorClient();
const metadataClient = new MetadataClient(client);
const tasks: TaskDefTypes[] = [
simpleTask("simple_ref", "le_simple_task", {}),
Expand Down
77 changes: 40 additions & 37 deletions src/common/open-api/core/CancelablePromise.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
Expand All @@ -22,15 +23,13 @@ export interface OnCancel {
}

export class CancelablePromise<T> implements Promise<T> {
readonly [Symbol.toStringTag]!: string;

private _isResolved: boolean;
private _isRejected: boolean;
private _isCancelled: boolean;
private readonly _cancelHandlers: (() => void)[];
private readonly _promise: Promise<T>;
private _resolve?: (value: T | PromiseLike<T>) => void;
private _reject?: (reason?: any) => void;
#isResolved: boolean;
#isRejected: boolean;
#isCancelled: boolean;
readonly #cancelHandlers: (() => void)[];
readonly #promise: Promise<T>;
#resolve?: (value: T | PromiseLike<T>) => void;
#reject?: (reason?: any) => void;

constructor(
executor: (
Expand All @@ -39,90 +38,94 @@ export class CancelablePromise<T> implements Promise<T> {
onCancel: OnCancel
) => void
) {
this._isResolved = false;
this._isRejected = false;
this._isCancelled = false;
this._cancelHandlers = [];
this._promise = new Promise<T>((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
this.#isResolved = false;
this.#isRejected = false;
this.#isCancelled = false;
this.#cancelHandlers = [];
this.#promise = new Promise<T>((resolve, reject) => {
this.#resolve = resolve;
this.#reject = reject;

const onResolve = (value: T | PromiseLike<T>): void => {
if (this._isResolved || this._isRejected || this._isCancelled) {
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
return;
}
this._isResolved = true;
this._resolve?.(value);
this.#isResolved = true;
if (this.#resolve) this.#resolve(value);
};

const onReject = (reason?: any): void => {
if (this._isResolved || this._isRejected || this._isCancelled) {
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
return;
}
this._isRejected = true;
this._reject?.(reason);
this.#isRejected = true;
if (this.#reject) this.#reject(reason);
};

const onCancel = (cancelHandler: () => void): void => {
if (this._isResolved || this._isRejected || this._isCancelled) {
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
return;
}
this._cancelHandlers.push(cancelHandler);
this.#cancelHandlers.push(cancelHandler);
};

Object.defineProperty(onCancel, 'isResolved', {
get: (): boolean => this._isResolved,
get: (): boolean => this.#isResolved,
});

Object.defineProperty(onCancel, 'isRejected', {
get: (): boolean => this._isRejected,
get: (): boolean => this.#isRejected,
});

Object.defineProperty(onCancel, 'isCancelled', {
get: (): boolean => this._isCancelled,
get: (): boolean => this.#isCancelled,
});

return executor(onResolve, onReject, onCancel as OnCancel);
});
}

get [Symbol.toStringTag]() {
return "Cancellable Promise";
}

public then<TResult1 = T, TResult2 = never>(
onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
): Promise<TResult1 | TResult2> {
return this._promise.then(onFulfilled, onRejected);
return this.#promise.then(onFulfilled, onRejected);
}

public catch<TResult = never>(
onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null
): Promise<T | TResult> {
return this._promise.catch(onRejected);
return this.#promise.catch(onRejected);
}

public finally(onFinally?: (() => void) | null): Promise<T> {
return this._promise.finally(onFinally);
return this.#promise.finally(onFinally);
}

public cancel(): void {
if (this._isResolved || this._isRejected || this._isCancelled) {
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
return;
}
this._isCancelled = true;
if (this._cancelHandlers.length) {
this.#isCancelled = true;
if (this.#cancelHandlers.length) {
try {
for (const cancelHandler of this._cancelHandlers) {
for (const cancelHandler of this.#cancelHandlers) {
cancelHandler();
}
} catch (error) {
console.warn('Cancellation threw an error', error);
return;
}
}
this._cancelHandlers.length = 0;
this._reject?.(new CancelError('Request aborted'));
this.#cancelHandlers.length = 0;
if (this.#reject) this.#reject(new CancelError('Request aborted'));
Comment thread
DmitryBorisov-sm marked this conversation as resolved.
}

public get isCancelled(): boolean {
return this._isCancelled;
return this.#isCancelled;
}
}
15 changes: 8 additions & 7 deletions src/common/open-api/core/OpenAPI.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ApiRequestOptions } from './ApiRequestOptions';

export type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
type Headers = Record<string, string>;

export type OpenAPIConfig = {
BASE: string;
VERSION: string;
WITH_CREDENTIALS: boolean;
CREDENTIALS: 'include' | 'omit' | 'same-origin';
TOKEN?: string | Resolver<string>;
USERNAME?: string | Resolver<string>;
PASSWORD?: string | Resolver<string>;
HEADERS?: Headers | Resolver<Headers>;
ENCODE_PATH?: (path: string) => string;
TOKEN?: string | Resolver<string> | undefined;
USERNAME?: string | Resolver<string> | undefined;
PASSWORD?: string | Resolver<string> | undefined;
HEADERS?: Headers | Resolver<Headers> | undefined;
ENCODE_PATH?: ((path: string) => string) | undefined;
Comment thread
DmitryBorisov-sm marked this conversation as resolved.
};

export const OpenAPI: OpenAPIConfig = {
BASE: 'http://localhost:8080',
VERSION: '0',
VERSION: '2',
WITH_CREDENTIALS: false,
CREDENTIALS: 'include',
TOKEN: undefined,
Expand Down
4 changes: 3 additions & 1 deletion src/common/open-api/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export { ConductorClient, ConductorClientAPIConfig } from "./ConductorClient";
export { ConductorClient } from "./ConductorClient";

export { ApiError } from "./core/ApiError";
export { BaseHttpRequest } from "./core/BaseHttpRequest";
Expand Down
4 changes: 2 additions & 2 deletions src/common/open-api/models/GenerateTokenRequest.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */

export type GenerateTokenRequest = {
expiration?: number;
keyId: string;
keySecret: string;
refreshTokenInterval?:number; // 0 no refresh
};

6 changes: 2 additions & 4 deletions src/common/open-api/models/Response.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
/* generated using openapi-typescript-codegen -- do not edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */

export type Response = {
};

export type Response = Record<string, any>;
Loading