@voyantjs/workflows-react 0.66.6 → 0.69.0
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.
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export interface WorkflowScheduleDecl {
|
|
2
|
+
cron?: string;
|
|
3
|
+
every?: string | number;
|
|
4
|
+
at?: string;
|
|
5
|
+
timezone?: string;
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
overlap?: "skip" | "queue" | "allow";
|
|
8
|
+
environments?: ("production" | "preview" | "development")[];
|
|
9
|
+
name?: string;
|
|
10
|
+
input?: unknown;
|
|
11
|
+
}
|
|
12
|
+
export interface WorkflowScheduleSummary {
|
|
13
|
+
workflowId: string;
|
|
14
|
+
scheduleId: string;
|
|
15
|
+
schedule: WorkflowScheduleDecl;
|
|
16
|
+
/** Epoch millis of the next computed fire, or null when undecidable. */
|
|
17
|
+
nextRunAt: number | null;
|
|
18
|
+
enabled: boolean;
|
|
19
|
+
disabledReason?: "registration_disabled" | "env_filtered";
|
|
20
|
+
}
|
|
21
|
+
export interface ListWorkflowSchedulesResponse {
|
|
22
|
+
environment: string;
|
|
23
|
+
versionId: string;
|
|
24
|
+
schedulesEnabledByEnv?: boolean;
|
|
25
|
+
data: WorkflowScheduleSummary[];
|
|
26
|
+
}
|
|
27
|
+
export interface WorkflowSchedulesApi {
|
|
28
|
+
listSchedules(environment: string): Promise<ListWorkflowSchedulesResponse>;
|
|
29
|
+
}
|
|
30
|
+
export type WorkflowSchedulesFetcher = (input: string, init?: RequestInit) => Promise<Response>;
|
|
31
|
+
export interface WorkflowSchedulesApiClientOptions {
|
|
32
|
+
/** Base URL for the orchestrator. Defaults to the current origin. */
|
|
33
|
+
apiBase?: string;
|
|
34
|
+
baseUrl?: string;
|
|
35
|
+
fetcher?: WorkflowSchedulesFetcher;
|
|
36
|
+
credentials?: RequestCredentials;
|
|
37
|
+
headers?: HeadersInit;
|
|
38
|
+
}
|
|
39
|
+
export interface WorkflowSchedulesClientOptions {
|
|
40
|
+
baseUrl: string;
|
|
41
|
+
fetcher: WorkflowSchedulesFetcher;
|
|
42
|
+
credentials?: RequestCredentials;
|
|
43
|
+
headers?: HeadersInit;
|
|
44
|
+
}
|
|
45
|
+
export declare class WorkflowSchedulesApiError extends Error {
|
|
46
|
+
readonly status: number;
|
|
47
|
+
readonly body: unknown;
|
|
48
|
+
constructor(message: string, status: number, body: unknown);
|
|
49
|
+
}
|
|
50
|
+
export declare const defaultWorkflowSchedulesFetcher: WorkflowSchedulesFetcher;
|
|
51
|
+
export declare const workflowSchedulesQueryKeys: {
|
|
52
|
+
readonly all: readonly ["voyant", "workflow-schedules"];
|
|
53
|
+
readonly list: (environment: string) => readonly ["voyant", "workflow-schedules", "list", string];
|
|
54
|
+
};
|
|
55
|
+
export declare function createWorkflowSchedulesClientOptions(client?: Partial<WorkflowSchedulesClientOptions>): WorkflowSchedulesClientOptions;
|
|
56
|
+
export declare function createWorkflowSchedulesApiClient(options?: WorkflowSchedulesApiClientOptions): WorkflowSchedulesApi;
|
|
57
|
+
export declare function listWorkflowSchedules(environment: string, client?: WorkflowSchedulesClientOptions): Promise<ListWorkflowSchedulesResponse>;
|
|
58
|
+
//# sourceMappingURL=workflow-schedules-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-schedules-client.d.ts","sourceRoot":"","sources":["../src/workflow-schedules-client.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAA;IACpC,YAAY,CAAC,EAAE,CAAC,YAAY,GAAG,SAAS,GAAG,aAAa,CAAC,EAAE,CAAA;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,oBAAoB,CAAA;IAC9B,wEAAwE;IACxE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,OAAO,EAAE,OAAO,CAAA;IAChB,cAAc,CAAC,EAAE,uBAAuB,GAAG,cAAc,CAAA;CAC1D;AAED,MAAM,WAAW,6BAA6B;IAC5C,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,IAAI,EAAE,uBAAuB,EAAE,CAAA;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAAA;CAC3E;AAED,MAAM,MAAM,wBAAwB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE/F,MAAM,WAAW,iCAAiC;IAChD,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,wBAAwB,CAAA;IAClC,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC,OAAO,CAAC,EAAE,WAAW,CAAA;CACtB;AAED,MAAM,WAAW,8BAA8B;IAC7C,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,wBAAwB,CAAA;IACjC,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC,OAAO,CAAC,EAAE,WAAW,CAAA;CACtB;AAED,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;gBAEV,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO;CAM3D;AAED,eAAO,MAAM,+BAA+B,EAAE,wBAC1B,CAAA;AAEpB,eAAO,MAAM,0BAA0B;;iCAEjB,MAAM;CAClB,CAAA;AAEV,wBAAgB,oCAAoC,CAClD,MAAM,CAAC,EAAE,OAAO,CAAC,8BAA8B,CAAC,GAC/C,8BAA8B,CAOhC;AAED,wBAAgB,gCAAgC,CAC9C,OAAO,GAAE,iCAAsC,GAC9C,oBAAoB,CAWtB;AAED,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,MAAM,GAAE,8BAAuE,GAC9E,OAAO,CAAC,6BAA6B,CAAC,CAYxC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Client for the orchestrator's `/api/schedules/:env` aggregate view.
|
|
2
|
+
// Mirrors `workflow-runs-client.ts` so the workflow-schedules UI can be
|
|
3
|
+
// pointed at any worker that exposes `@voyantjs/workflows-orchestrator-cloudflare`'s
|
|
4
|
+
// schedules handler.
|
|
5
|
+
export class WorkflowSchedulesApiError extends Error {
|
|
6
|
+
status;
|
|
7
|
+
body;
|
|
8
|
+
constructor(message, status, body) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "WorkflowSchedulesApiError";
|
|
11
|
+
this.status = status;
|
|
12
|
+
this.body = body;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export const defaultWorkflowSchedulesFetcher = (input, init) => fetch(input, init);
|
|
16
|
+
export const workflowSchedulesQueryKeys = {
|
|
17
|
+
all: ["voyant", "workflow-schedules"],
|
|
18
|
+
list: (environment) => [...workflowSchedulesQueryKeys.all, "list", environment],
|
|
19
|
+
};
|
|
20
|
+
export function createWorkflowSchedulesClientOptions(client) {
|
|
21
|
+
return {
|
|
22
|
+
baseUrl: client?.baseUrl ?? "",
|
|
23
|
+
fetcher: client?.fetcher ?? defaultWorkflowSchedulesFetcher,
|
|
24
|
+
credentials: client?.credentials,
|
|
25
|
+
headers: client?.headers,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function createWorkflowSchedulesApiClient(options = {}) {
|
|
29
|
+
const client = createWorkflowSchedulesClientOptions({
|
|
30
|
+
baseUrl: options.baseUrl ?? options.apiBase ?? "",
|
|
31
|
+
fetcher: options.fetcher,
|
|
32
|
+
credentials: options.credentials ?? "include",
|
|
33
|
+
headers: options.headers,
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
listSchedules: (environment) => listWorkflowSchedules(environment, client),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export async function listWorkflowSchedules(environment, client = createWorkflowSchedulesClientOptions()) {
|
|
40
|
+
const path = `/api/schedules/${encodeURIComponent(environment)}`;
|
|
41
|
+
const response = await request(path, { method: "GET" }, client);
|
|
42
|
+
const body = await safeJson(response);
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
throw new WorkflowSchedulesApiError(extractErrorMessage(response.status, response.statusText, body), response.status, body);
|
|
45
|
+
}
|
|
46
|
+
return body;
|
|
47
|
+
}
|
|
48
|
+
async function request(path, init, client) {
|
|
49
|
+
const headers = new Headers(client.headers);
|
|
50
|
+
for (const [key, value] of new Headers(init.headers).entries()) {
|
|
51
|
+
headers.set(key, value);
|
|
52
|
+
}
|
|
53
|
+
const requestInit = { ...init, headers };
|
|
54
|
+
if (client.credentials !== undefined) {
|
|
55
|
+
requestInit.credentials = client.credentials;
|
|
56
|
+
}
|
|
57
|
+
return client.fetcher(joinUrl(client.baseUrl, path), requestInit);
|
|
58
|
+
}
|
|
59
|
+
async function safeJson(response) {
|
|
60
|
+
const text = await response.text();
|
|
61
|
+
if (!text)
|
|
62
|
+
return undefined;
|
|
63
|
+
try {
|
|
64
|
+
return JSON.parse(text);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return text;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function extractErrorMessage(status, statusText, body) {
|
|
71
|
+
if (typeof body === "object" && body !== null) {
|
|
72
|
+
if ("error" in body && typeof body.error === "string")
|
|
73
|
+
return body.error;
|
|
74
|
+
if ("message" in body && typeof body.message === "string")
|
|
75
|
+
return body.message;
|
|
76
|
+
}
|
|
77
|
+
return `Workflow schedules API error: ${status} ${statusText}`;
|
|
78
|
+
}
|
|
79
|
+
function joinUrl(baseUrl, path) {
|
|
80
|
+
const resolved = resolveBaseUrl(baseUrl);
|
|
81
|
+
const trimmedBase = resolved.endsWith("/") ? resolved.slice(0, -1) : resolved;
|
|
82
|
+
const trimmedPath = path.startsWith("/") ? path : `/${path}`;
|
|
83
|
+
return `${trimmedBase}${trimmedPath}`;
|
|
84
|
+
}
|
|
85
|
+
function resolveBaseUrl(baseUrl) {
|
|
86
|
+
if (baseUrl.trim())
|
|
87
|
+
return baseUrl;
|
|
88
|
+
if (typeof window !== "undefined")
|
|
89
|
+
return window.location.origin;
|
|
90
|
+
return "http://localhost:8787";
|
|
91
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyantjs/workflows-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.69.0",
|
|
4
4
|
"description": "React hooks for Voyant Workflows — trigger, subscribe, and stream runs.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -25,6 +25,11 @@
|
|
|
25
25
|
"types": "./dist/workflow-runs-client.d.ts",
|
|
26
26
|
"import": "./dist/workflow-runs-client.js",
|
|
27
27
|
"default": "./dist/workflow-runs-client.js"
|
|
28
|
+
},
|
|
29
|
+
"./workflow-schedules-client": {
|
|
30
|
+
"types": "./dist/workflow-schedules-client.d.ts",
|
|
31
|
+
"import": "./dist/workflow-schedules-client.js",
|
|
32
|
+
"default": "./dist/workflow-schedules-client.js"
|
|
28
33
|
}
|
|
29
34
|
},
|
|
30
35
|
"main": "./dist/index.js",
|
|
@@ -37,8 +42,8 @@
|
|
|
37
42
|
"NOTICE"
|
|
38
43
|
],
|
|
39
44
|
"dependencies": {
|
|
40
|
-
"@voyantjs/react": "0.
|
|
41
|
-
"@voyantjs/workflows": "0.
|
|
45
|
+
"@voyantjs/react": "0.69.0",
|
|
46
|
+
"@voyantjs/workflows": "0.69.0"
|
|
42
47
|
},
|
|
43
48
|
"peerDependencies": {
|
|
44
49
|
"@tanstack/react-query": "^5.0.0",
|
|
@@ -53,7 +58,7 @@
|
|
|
53
58
|
"react-dom": "^19.2.4",
|
|
54
59
|
"typescript": "^5.9.2",
|
|
55
60
|
"vitest": "^4.1.2",
|
|
56
|
-
"@voyantjs/react": "0.
|
|
61
|
+
"@voyantjs/react": "0.69.0",
|
|
57
62
|
"@voyantjs/voyant-typescript-config": "0.1.0"
|
|
58
63
|
},
|
|
59
64
|
"publishConfig": {
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// Client for the orchestrator's `/api/schedules/:env` aggregate view.
|
|
2
|
+
// Mirrors `workflow-runs-client.ts` so the workflow-schedules UI can be
|
|
3
|
+
// pointed at any worker that exposes `@voyantjs/workflows-orchestrator-cloudflare`'s
|
|
4
|
+
// schedules handler.
|
|
5
|
+
|
|
6
|
+
export interface WorkflowScheduleDecl {
|
|
7
|
+
cron?: string
|
|
8
|
+
every?: string | number
|
|
9
|
+
at?: string
|
|
10
|
+
timezone?: string
|
|
11
|
+
enabled?: boolean
|
|
12
|
+
overlap?: "skip" | "queue" | "allow"
|
|
13
|
+
environments?: ("production" | "preview" | "development")[]
|
|
14
|
+
name?: string
|
|
15
|
+
input?: unknown
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface WorkflowScheduleSummary {
|
|
19
|
+
workflowId: string
|
|
20
|
+
scheduleId: string
|
|
21
|
+
schedule: WorkflowScheduleDecl
|
|
22
|
+
/** Epoch millis of the next computed fire, or null when undecidable. */
|
|
23
|
+
nextRunAt: number | null
|
|
24
|
+
enabled: boolean
|
|
25
|
+
disabledReason?: "registration_disabled" | "env_filtered"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ListWorkflowSchedulesResponse {
|
|
29
|
+
environment: string
|
|
30
|
+
versionId: string
|
|
31
|
+
schedulesEnabledByEnv?: boolean
|
|
32
|
+
data: WorkflowScheduleSummary[]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface WorkflowSchedulesApi {
|
|
36
|
+
listSchedules(environment: string): Promise<ListWorkflowSchedulesResponse>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type WorkflowSchedulesFetcher = (input: string, init?: RequestInit) => Promise<Response>
|
|
40
|
+
|
|
41
|
+
export interface WorkflowSchedulesApiClientOptions {
|
|
42
|
+
/** Base URL for the orchestrator. Defaults to the current origin. */
|
|
43
|
+
apiBase?: string
|
|
44
|
+
baseUrl?: string
|
|
45
|
+
fetcher?: WorkflowSchedulesFetcher
|
|
46
|
+
credentials?: RequestCredentials
|
|
47
|
+
headers?: HeadersInit
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface WorkflowSchedulesClientOptions {
|
|
51
|
+
baseUrl: string
|
|
52
|
+
fetcher: WorkflowSchedulesFetcher
|
|
53
|
+
credentials?: RequestCredentials
|
|
54
|
+
headers?: HeadersInit
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export class WorkflowSchedulesApiError extends Error {
|
|
58
|
+
readonly status: number
|
|
59
|
+
readonly body: unknown
|
|
60
|
+
|
|
61
|
+
constructor(message: string, status: number, body: unknown) {
|
|
62
|
+
super(message)
|
|
63
|
+
this.name = "WorkflowSchedulesApiError"
|
|
64
|
+
this.status = status
|
|
65
|
+
this.body = body
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const defaultWorkflowSchedulesFetcher: WorkflowSchedulesFetcher = (input, init) =>
|
|
70
|
+
fetch(input, init)
|
|
71
|
+
|
|
72
|
+
export const workflowSchedulesQueryKeys = {
|
|
73
|
+
all: ["voyant", "workflow-schedules"] as const,
|
|
74
|
+
list: (environment: string) => [...workflowSchedulesQueryKeys.all, "list", environment] as const,
|
|
75
|
+
} as const
|
|
76
|
+
|
|
77
|
+
export function createWorkflowSchedulesClientOptions(
|
|
78
|
+
client?: Partial<WorkflowSchedulesClientOptions>,
|
|
79
|
+
): WorkflowSchedulesClientOptions {
|
|
80
|
+
return {
|
|
81
|
+
baseUrl: client?.baseUrl ?? "",
|
|
82
|
+
fetcher: client?.fetcher ?? defaultWorkflowSchedulesFetcher,
|
|
83
|
+
credentials: client?.credentials,
|
|
84
|
+
headers: client?.headers,
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function createWorkflowSchedulesApiClient(
|
|
89
|
+
options: WorkflowSchedulesApiClientOptions = {},
|
|
90
|
+
): WorkflowSchedulesApi {
|
|
91
|
+
const client = createWorkflowSchedulesClientOptions({
|
|
92
|
+
baseUrl: options.baseUrl ?? options.apiBase ?? "",
|
|
93
|
+
fetcher: options.fetcher,
|
|
94
|
+
credentials: options.credentials ?? "include",
|
|
95
|
+
headers: options.headers,
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
listSchedules: (environment) => listWorkflowSchedules(environment, client),
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export async function listWorkflowSchedules(
|
|
104
|
+
environment: string,
|
|
105
|
+
client: WorkflowSchedulesClientOptions = createWorkflowSchedulesClientOptions(),
|
|
106
|
+
): Promise<ListWorkflowSchedulesResponse> {
|
|
107
|
+
const path = `/api/schedules/${encodeURIComponent(environment)}`
|
|
108
|
+
const response = await request(path, { method: "GET" }, client)
|
|
109
|
+
const body = await safeJson(response)
|
|
110
|
+
if (!response.ok) {
|
|
111
|
+
throw new WorkflowSchedulesApiError(
|
|
112
|
+
extractErrorMessage(response.status, response.statusText, body),
|
|
113
|
+
response.status,
|
|
114
|
+
body,
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
return body as ListWorkflowSchedulesResponse
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function request(
|
|
121
|
+
path: string,
|
|
122
|
+
init: RequestInit,
|
|
123
|
+
client: WorkflowSchedulesClientOptions,
|
|
124
|
+
): Promise<Response> {
|
|
125
|
+
const headers = new Headers(client.headers)
|
|
126
|
+
for (const [key, value] of new Headers(init.headers).entries()) {
|
|
127
|
+
headers.set(key, value)
|
|
128
|
+
}
|
|
129
|
+
const requestInit: RequestInit = { ...init, headers }
|
|
130
|
+
if (client.credentials !== undefined) {
|
|
131
|
+
requestInit.credentials = client.credentials
|
|
132
|
+
}
|
|
133
|
+
return client.fetcher(joinUrl(client.baseUrl, path), requestInit)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function safeJson(response: Response): Promise<unknown> {
|
|
137
|
+
const text = await response.text()
|
|
138
|
+
if (!text) return undefined
|
|
139
|
+
try {
|
|
140
|
+
return JSON.parse(text)
|
|
141
|
+
} catch {
|
|
142
|
+
return text
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function extractErrorMessage(status: number, statusText: string, body: unknown): string {
|
|
147
|
+
if (typeof body === "object" && body !== null) {
|
|
148
|
+
if ("error" in body && typeof body.error === "string") return body.error
|
|
149
|
+
if ("message" in body && typeof body.message === "string") return body.message
|
|
150
|
+
}
|
|
151
|
+
return `Workflow schedules API error: ${status} ${statusText}`
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function joinUrl(baseUrl: string, path: string): string {
|
|
155
|
+
const resolved = resolveBaseUrl(baseUrl)
|
|
156
|
+
const trimmedBase = resolved.endsWith("/") ? resolved.slice(0, -1) : resolved
|
|
157
|
+
const trimmedPath = path.startsWith("/") ? path : `/${path}`
|
|
158
|
+
return `${trimmedBase}${trimmedPath}`
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function resolveBaseUrl(baseUrl: string): string {
|
|
162
|
+
if (baseUrl.trim()) return baseUrl
|
|
163
|
+
if (typeof window !== "undefined") return window.location.origin
|
|
164
|
+
return "http://localhost:8787"
|
|
165
|
+
}
|