@openworkflow/cli 0.1.0 → 0.2.1
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.
- package/dist/cli.js +6 -2
- package/dist/commands.d.ts +11 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +97 -12
- package/dist/commands.test.js +19 -2
- package/dist/config.d.ts +6 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +32 -21
- package/dist/config.test.js +0 -1
- package/dist/errors.js +0 -1
- package/dist/index.js +0 -1
- package/dist/internal.d.ts +2 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +1 -0
- package/dist/templates.d.ts +5 -4
- package/dist/templates.d.ts.map +1 -1
- package/dist/templates.js +33 -29
- package/dist/templates.test.js +22 -16
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -6
- package/dist/cli.js.map +0 -1
- package/dist/cli.test.d.ts +0 -2
- package/dist/cli.test.d.ts.map +0 -1
- package/dist/cli.test.js +0 -7
- package/dist/cli.test.js.map +0 -1
- package/dist/commands.js.map +0 -1
- package/dist/commands.test.js.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/config.test.js.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.test.d.ts +0 -2
- package/dist/index.test.d.ts.map +0 -1
- package/dist/index.test.js +0 -11
- package/dist/index.test.js.map +0 -1
- package/dist/init.test.d.ts +0 -2
- package/dist/init.test.d.ts.map +0 -1
- package/dist/init.test.js +0 -148
- package/dist/init.test.js.map +0 -1
- package/dist/templates.js.map +0 -1
- package/dist/templates.test.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/* v8 ignore file -- @preserve */
|
|
3
|
-
import { doctor, getVersion, init, workerStart } from "./commands.js";
|
|
3
|
+
import { dashboard, doctor, getVersion, init, workerStart, } from "./commands.js";
|
|
4
4
|
import { withErrorHandling } from "./errors.js";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
// openworkflow | ow
|
|
@@ -28,5 +28,9 @@ workerCmd
|
|
|
28
28
|
.description("start a worker to process workflows")
|
|
29
29
|
.option("-c, --concurrency <number>", "number of concurrent workflows to process", Number.parseInt)
|
|
30
30
|
.action(withErrorHandling(workerStart));
|
|
31
|
+
// dashboard
|
|
32
|
+
program
|
|
33
|
+
.command("dashboard")
|
|
34
|
+
.description("start the dashboard to view workflow runs")
|
|
35
|
+
.action(withErrorHandling(dashboard));
|
|
31
36
|
await program.parseAsync(process.argv);
|
|
32
|
-
//# sourceMappingURL=cli.js.map
|
package/dist/commands.d.ts
CHANGED
|
@@ -13,6 +13,11 @@ export declare function doctor(): Promise<void>;
|
|
|
13
13
|
* @param cliOptions - Worker config overrides
|
|
14
14
|
*/
|
|
15
15
|
export declare function workerStart(cliOptions: WorkerConfig): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* openworkflow dashboard
|
|
18
|
+
* Starts the dashboard by delegating to `@openworkflow/dashboard` via npx.
|
|
19
|
+
*/
|
|
20
|
+
export declare function dashboard(): Promise<void>;
|
|
16
21
|
interface PackageJsonForDoctor {
|
|
17
22
|
dependencies?: Record<string, string>;
|
|
18
23
|
devDependencies?: Record<string, string>;
|
|
@@ -29,5 +34,11 @@ export declare function getConfigFileName(packageJson: Readonly<PackageJsonForDo
|
|
|
29
34
|
* @returns The example workflow file name to create
|
|
30
35
|
*/
|
|
31
36
|
export declare function getExampleWorkflowFileName(packageJson: Readonly<PackageJsonForDoctor> | null): string;
|
|
37
|
+
/**
|
|
38
|
+
* Determine the client filename to write during init.
|
|
39
|
+
* @param packageJson - Parsed package.json (or null if missing)
|
|
40
|
+
* @returns The client file name to create
|
|
41
|
+
*/
|
|
42
|
+
export declare function getClientFileName(packageJson: Readonly<PackageJsonForDoctor> | null): string;
|
|
32
43
|
export {};
|
|
33
44
|
//# sourceMappingURL=commands.d.ts.map
|
package/dist/commands.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAc,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAc,MAAM,aAAa,CAAC;AAgCvD;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAoBnC;AAED,wBAAwB;AACxB,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA8H1C;AAED,0BAA0B;AAC1B,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAiD5C;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,UAAU,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAqEzE;AAED;;;GAGG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CA0D/C;AAqfD,UAAU,oBAAoB;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAsBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,IAAI,GACjD,MAAM,CAMR;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,IAAI,GACjD,MAAM,CAKR;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,GAAG,IAAI,GACjD,MAAM,CAKR"}
|
package/dist/commands.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { loadConfig } from "./config.js";
|
|
2
2
|
import { CLIError } from "./errors.js";
|
|
3
|
-
import { HELLO_WORLD_WORKFLOW,
|
|
3
|
+
import { CONFIG, HELLO_WORLD_WORKFLOW, POSTGRES_CLIENT, POSTGRES_PROD_SQLITE_DEV_CLIENT, SQLITE_CLIENT, } from "./templates.js";
|
|
4
4
|
import * as p from "@clack/prompts";
|
|
5
5
|
import { consola } from "consola";
|
|
6
6
|
import { config as loadDotenv } from "dotenv";
|
|
7
7
|
import { createJiti } from "jiti";
|
|
8
|
+
import { spawn } from "node:child_process";
|
|
8
9
|
import { existsSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
9
10
|
import path from "node:path";
|
|
10
11
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
@@ -85,7 +86,11 @@ export async function init() {
|
|
|
85
86
|
const packageManager = pm?.name ?? "your package manager";
|
|
86
87
|
spinner.stop(`Using ${packageManager}`);
|
|
87
88
|
const packageJson = readPackageJsonForDoctor();
|
|
89
|
+
if (!packageJson) {
|
|
90
|
+
throw new CLIError("No package.json found.", "Please create a package.json file first by running `npm init` or `npm init -y`.");
|
|
91
|
+
}
|
|
88
92
|
const configFileName = getConfigFileName(packageJson);
|
|
93
|
+
const clientFileName = getClientFileName(packageJson);
|
|
89
94
|
const exampleWorkflowFileName = getExampleWorkflowFileName(packageJson);
|
|
90
95
|
const shouldSetup = await p.confirm({
|
|
91
96
|
message: `Install packages and set up project files (.env, .gitignore, package.json, ${configFileName}, openworkflow/${exampleWorkflowFileName})?`,
|
|
@@ -115,6 +120,7 @@ export async function init() {
|
|
|
115
120
|
await addDependency(devDependencies, { silent: true, dev: true });
|
|
116
121
|
spinner.stop(`Installed ${devDependencies.join(", ")}`);
|
|
117
122
|
}
|
|
123
|
+
createClientFile(backendChoice, clientFileName);
|
|
118
124
|
createExampleWorkflow(exampleWorkflowFileName);
|
|
119
125
|
if (backendChoice === "sqlite" || backendChoice === "both") {
|
|
120
126
|
updateGitignoreForSqlite();
|
|
@@ -125,7 +131,7 @@ export async function init() {
|
|
|
125
131
|
addWorkerScriptToPackageJson();
|
|
126
132
|
// write config file last, so canceling earlier doesn't leave a config file
|
|
127
133
|
// which would prevent re-running init
|
|
128
|
-
createConfigFile(
|
|
134
|
+
createConfigFile(configFileName);
|
|
129
135
|
// wrap up
|
|
130
136
|
p.note(`➡️ Start a worker with:\n$ ${packageManager === "npm" ? "npm run" : packageManager} worker\n\nOr directly with:\n$ ow worker start`, "Next steps");
|
|
131
137
|
p.outro("✅ Setup complete!");
|
|
@@ -224,6 +230,51 @@ export async function workerStart(cliOptions) {
|
|
|
224
230
|
throw error;
|
|
225
231
|
}
|
|
226
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* openworkflow dashboard
|
|
235
|
+
* Starts the dashboard by delegating to `@openworkflow/dashboard` via npx.
|
|
236
|
+
*/
|
|
237
|
+
export async function dashboard() {
|
|
238
|
+
consola.start("Starting dashboard...");
|
|
239
|
+
const { configFile } = await loadConfigWithEnv();
|
|
240
|
+
if (!configFile) {
|
|
241
|
+
throw new CLIError("No config file found.", "Run `ow init` to create a config file before starting the dashboard.");
|
|
242
|
+
}
|
|
243
|
+
consola.info(`Using config: ${configFile}`);
|
|
244
|
+
// eslint-disable-next-line sonarjs/no-os-command-from-path
|
|
245
|
+
const child = spawn("npx", ["@openworkflow/dashboard"], {
|
|
246
|
+
stdio: "inherit",
|
|
247
|
+
});
|
|
248
|
+
await new Promise((resolve, reject) => {
|
|
249
|
+
/** remove signal handlers after the child exits */
|
|
250
|
+
function cleanupSignalHandlers() {
|
|
251
|
+
process.off("SIGINT", signalHandler);
|
|
252
|
+
process.off("SIGTERM", signalHandler);
|
|
253
|
+
}
|
|
254
|
+
child.on("error", (error) => {
|
|
255
|
+
cleanupSignalHandlers();
|
|
256
|
+
reject(new CLIError("Failed to start dashboard.", `Could not spawn npx: ${error.message}`));
|
|
257
|
+
});
|
|
258
|
+
child.on("exit", (code) => {
|
|
259
|
+
cleanupSignalHandlers();
|
|
260
|
+
if (code === 0 || code === null) {
|
|
261
|
+
resolve();
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
reject(new CLIError("Dashboard exited with an error.", `Exit code: ${String(code)}`));
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
/**
|
|
268
|
+
* Graceful shutdown on signals.
|
|
269
|
+
* @param signal - Signal
|
|
270
|
+
*/
|
|
271
|
+
function signalHandler(signal) {
|
|
272
|
+
child.kill(signal);
|
|
273
|
+
}
|
|
274
|
+
process.on("SIGINT", signalHandler);
|
|
275
|
+
process.on("SIGTERM", signalHandler);
|
|
276
|
+
});
|
|
277
|
+
}
|
|
227
278
|
// -----------------------------------------------------------------------------
|
|
228
279
|
/**
|
|
229
280
|
* Get workflow directories from config.
|
|
@@ -410,16 +461,21 @@ async function discoverWorkflowsInDirs(dirs, baseDir) {
|
|
|
410
461
|
* @param backendChoice - The selected backend choice
|
|
411
462
|
* @returns The config template string
|
|
412
463
|
*/
|
|
413
|
-
|
|
464
|
+
/**
|
|
465
|
+
* Get the client template for a backend choice.
|
|
466
|
+
* @param backendChoice - The selected backend choice
|
|
467
|
+
* @returns The client template string
|
|
468
|
+
*/
|
|
469
|
+
function getClientTemplate(backendChoice) {
|
|
414
470
|
switch (backendChoice) {
|
|
415
471
|
case "sqlite": {
|
|
416
|
-
return
|
|
472
|
+
return SQLITE_CLIENT;
|
|
417
473
|
}
|
|
418
474
|
case "postgres": {
|
|
419
|
-
return
|
|
475
|
+
return POSTGRES_CLIENT;
|
|
420
476
|
}
|
|
421
477
|
case "both": {
|
|
422
|
-
return
|
|
478
|
+
return POSTGRES_PROD_SQLITE_DEV_CLIENT;
|
|
423
479
|
}
|
|
424
480
|
}
|
|
425
481
|
}
|
|
@@ -447,17 +503,37 @@ function getDevDependenciesToInstall() {
|
|
|
447
503
|
}
|
|
448
504
|
/**
|
|
449
505
|
* Create config file.
|
|
450
|
-
* @param backendChoice - The selected backend choice
|
|
451
506
|
* @param configFileName - The config file name to write
|
|
452
507
|
*/
|
|
453
|
-
function createConfigFile(
|
|
508
|
+
function createConfigFile(configFileName) {
|
|
454
509
|
const spinner = p.spinner();
|
|
455
510
|
spinner.start("Writing config...");
|
|
456
|
-
const configTemplate = getConfigTemplate(backendChoice);
|
|
457
511
|
const configDestPath = path.join(process.cwd(), configFileName);
|
|
458
|
-
writeFileSync(configDestPath,
|
|
512
|
+
writeFileSync(configDestPath, CONFIG, "utf8");
|
|
459
513
|
spinner.stop(`Config written to ${configDestPath}`);
|
|
460
514
|
}
|
|
515
|
+
/**
|
|
516
|
+
* Create client file.
|
|
517
|
+
* @param backendChoice - The selected backend choice
|
|
518
|
+
* @param clientFileName - The client filename to write
|
|
519
|
+
*/
|
|
520
|
+
function createClientFile(backendChoice, clientFileName) {
|
|
521
|
+
const spinner = p.spinner();
|
|
522
|
+
const workflowsDir = path.join(process.cwd(), "openworkflow");
|
|
523
|
+
if (!existsSync(workflowsDir)) {
|
|
524
|
+
mkdirSync(workflowsDir, { recursive: true });
|
|
525
|
+
}
|
|
526
|
+
const clientDestPath = path.join(workflowsDir, clientFileName);
|
|
527
|
+
if (existsSync(clientDestPath)) {
|
|
528
|
+
spinner.start("Checking client file...");
|
|
529
|
+
spinner.stop(`Client file already exists at ${clientDestPath}`);
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
spinner.start("Creating client file...");
|
|
533
|
+
const clientTemplate = getClientTemplate(backendChoice);
|
|
534
|
+
writeFileSync(clientDestPath, clientTemplate, "utf8");
|
|
535
|
+
spinner.stop(`Created client file at ${clientDestPath}`);
|
|
536
|
+
}
|
|
461
537
|
/**
|
|
462
538
|
* Create example workflow.
|
|
463
539
|
* @param exampleWorkflowFileName - The example workflow filename to write
|
|
@@ -507,7 +583,7 @@ function addWorkerScriptToPackageJson() {
|
|
|
507
583
|
try {
|
|
508
584
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
509
585
|
packageJson.scripts ??= {};
|
|
510
|
-
packageJson.scripts["worker"] = "
|
|
586
|
+
packageJson.scripts["worker"] = "npx @openworkflow/cli worker start";
|
|
511
587
|
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n", "utf8");
|
|
512
588
|
spinner.stop('Added "worker" script to package.json');
|
|
513
589
|
}
|
|
@@ -613,6 +689,16 @@ export function getExampleWorkflowFileName(packageJson) {
|
|
|
613
689
|
const extension = path.extname(configFileName) || ".js";
|
|
614
690
|
return `hello-world${extension}`;
|
|
615
691
|
}
|
|
692
|
+
/**
|
|
693
|
+
* Determine the client filename to write during init.
|
|
694
|
+
* @param packageJson - Parsed package.json (or null if missing)
|
|
695
|
+
* @returns The client file name to create
|
|
696
|
+
*/
|
|
697
|
+
export function getClientFileName(packageJson) {
|
|
698
|
+
const configFileName = getConfigFileName(packageJson);
|
|
699
|
+
const extension = path.extname(configFileName) || ".js";
|
|
700
|
+
return `client${extension}`;
|
|
701
|
+
}
|
|
616
702
|
/**
|
|
617
703
|
* Check whether a dependency is declared in package.json.
|
|
618
704
|
* @param packageJson - Parsed package.json.
|
|
@@ -715,4 +801,3 @@ function mergeDefinedOptions(base, overrides) {
|
|
|
715
801
|
}
|
|
716
802
|
return merged;
|
|
717
803
|
}
|
|
718
|
-
//# sourceMappingURL=commands.js.map
|
package/dist/commands.test.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getConfigFileName, getExampleWorkflowFileName } from "./commands.js";
|
|
1
|
+
import { getClientFileName, getConfigFileName, getExampleWorkflowFileName, } from "./commands.js";
|
|
2
2
|
import { describe, expect, test } from "vitest";
|
|
3
3
|
describe("getConfigFileName", () => {
|
|
4
4
|
test("prefers TypeScript when it is in devDependencies", () => {
|
|
@@ -32,4 +32,21 @@ describe("getExampleWorkflowFileName", () => {
|
|
|
32
32
|
expect(getExampleWorkflowFileName({ dependencies: {}, devDependencies: {} })).toBe("hello-world.js");
|
|
33
33
|
});
|
|
34
34
|
});
|
|
35
|
-
|
|
35
|
+
describe("getClientFileName", () => {
|
|
36
|
+
test("uses TypeScript when it is in devDependencies", () => {
|
|
37
|
+
expect(getClientFileName({
|
|
38
|
+
devDependencies: { typescript: "^5.0.0" },
|
|
39
|
+
})).toBe("client.ts");
|
|
40
|
+
});
|
|
41
|
+
test("uses TypeScript when it is in dependencies", () => {
|
|
42
|
+
expect(getClientFileName({
|
|
43
|
+
dependencies: { typescript: "^5.0.0" },
|
|
44
|
+
})).toBe("client.ts");
|
|
45
|
+
});
|
|
46
|
+
test("falls back to JavaScript when package.json is missing", () => {
|
|
47
|
+
expect(getClientFileName(null)).toBe("client.js");
|
|
48
|
+
});
|
|
49
|
+
test("falls back to JavaScript when package.json has no TypeScript", () => {
|
|
50
|
+
expect(getClientFileName({ dependencies: {}, devDependencies: {} })).toBe("client.js");
|
|
51
|
+
});
|
|
52
|
+
});
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { WorkerOptions } from "openworkflow";
|
|
1
|
+
import type { WorkerOptions } from "openworkflow";
|
|
2
2
|
import type { Backend } from "openworkflow/internal";
|
|
3
3
|
export interface OpenWorkflowConfig {
|
|
4
4
|
backend: Backend;
|
|
@@ -25,10 +25,12 @@ interface LoadedConfig {
|
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Load the OpenWorkflow config at openworkflow.config.{ts,mts,cts,js,mjs,cjs}.
|
|
28
|
-
*
|
|
29
|
-
*
|
|
28
|
+
* Searches up the directory tree from the starting directory to find the
|
|
29
|
+
* nearest config file.
|
|
30
|
+
* @param startDir - Optional starting directory to search from (defaults to
|
|
31
|
+
* process.cwd()). Will search this directory and all parent directories.
|
|
30
32
|
* @returns The loaded configuration and metadata
|
|
31
33
|
*/
|
|
32
|
-
export declare function loadConfig(
|
|
34
|
+
export declare function loadConfig(startDir?: string): Promise<LoadedConfig>;
|
|
33
35
|
export {};
|
|
34
36
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAE9D;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,CAE3E;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAMD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA8CzE"}
|
package/dist/config.js
CHANGED
|
@@ -15,30 +15,42 @@ const CONFIG_EXTENSIONS = ["ts", "mts", "cts", "js", "mjs", "cjs"];
|
|
|
15
15
|
const jiti = createJiti(import.meta.url);
|
|
16
16
|
/**
|
|
17
17
|
* Load the OpenWorkflow config at openworkflow.config.{ts,mts,cts,js,mjs,cjs}.
|
|
18
|
-
*
|
|
19
|
-
*
|
|
18
|
+
* Searches up the directory tree from the starting directory to find the
|
|
19
|
+
* nearest config file.
|
|
20
|
+
* @param startDir - Optional starting directory to search from (defaults to
|
|
21
|
+
* process.cwd()). Will search this directory and all parent directories.
|
|
20
22
|
* @returns The loaded configuration and metadata
|
|
21
23
|
*/
|
|
22
|
-
export async function loadConfig(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
24
|
+
export async function loadConfig(startDir) {
|
|
25
|
+
let currentDir = path.resolve(startDir ?? process.cwd());
|
|
26
|
+
// search up the directory tree
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
28
|
+
while (true) {
|
|
29
|
+
for (const ext of CONFIG_EXTENSIONS) {
|
|
30
|
+
const fileName = `${CONFIG_NAME}.${ext}`;
|
|
31
|
+
const filePath = path.join(currentDir, fileName);
|
|
32
|
+
if (existsSync(filePath)) {
|
|
33
|
+
try {
|
|
34
|
+
const fileUrl = pathToFileURL(filePath).href;
|
|
35
|
+
const config = await jiti.import(fileUrl, {
|
|
36
|
+
default: true,
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
config,
|
|
40
|
+
configFile: filePath,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
throw new Error(`Failed to load config file ${filePath}: ${String(error)}`);
|
|
45
|
+
}
|
|
40
46
|
}
|
|
41
47
|
}
|
|
48
|
+
const parentDir = path.dirname(currentDir);
|
|
49
|
+
if (parentDir === currentDir) {
|
|
50
|
+
// reached filesystem root without finding config
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
currentDir = parentDir;
|
|
42
54
|
}
|
|
43
55
|
return {
|
|
44
56
|
// not great, but meant to match the c12 api since that is what was used in
|
|
@@ -48,4 +60,3 @@ export async function loadConfig(rootDir) {
|
|
|
48
60
|
configFile: undefined, // no config found
|
|
49
61
|
};
|
|
50
62
|
}
|
|
51
|
-
//# sourceMappingURL=config.js.map
|
package/dist/config.test.js
CHANGED
package/dist/errors.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/internal.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { loadConfig } from "./config.js";
|
package/dist/templates.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export declare const
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const
|
|
1
|
+
export declare const SQLITE_CLIENT = "import { BackendSqlite } from \"@openworkflow/backend-sqlite\";\nimport { OpenWorkflow } from \"openworkflow\";\n\nexport const backend = BackendSqlite.connect(\"openworkflow/backend.db\");\nexport const ow = new OpenWorkflow({ backend });\n";
|
|
2
|
+
export declare const POSTGRES_CLIENT = "import { BackendPostgres } from \"@openworkflow/backend-postgres\";\nimport { OpenWorkflow } from \"openworkflow\";\n\nexport const backend = await BackendPostgres.connect(\n process.env[\"OPENWORKFLOW_POSTGRES_URL\"],\n);\nexport const ow = new OpenWorkflow({ backend });\n";
|
|
3
|
+
export declare const POSTGRES_PROD_SQLITE_DEV_CLIENT = "import { BackendPostgres } from \"@openworkflow/backend-postgres\";\nimport { BackendSqlite } from \"@openworkflow/backend-sqlite\";\nimport { OpenWorkflow } from \"openworkflow\";\n\nexport const backend =\n process.env[\"NODE_ENV\"] === \"production\"\n ? await BackendPostgres.connect(process.env[\"OPENWORKFLOW_POSTGRES_URL\"])\n : BackendSqlite.connect(\"openworkflow/backend.db\");\nexport const ow = new OpenWorkflow({ backend });\n";
|
|
4
|
+
export declare const CONFIG = "import { backend } from \"./openworkflow/client.js\";\nimport { defineConfig } from \"@openworkflow/cli\";\n\nexport default defineConfig({\n backend,\n dirs: \"./openworkflow\",\n});\n";
|
|
5
|
+
export declare const HELLO_WORLD_WORKFLOW = "import { defineWorkflow } from \"openworkflow\";\n\n/**\n * Example workflow that greets the world.\n *\n * This workflow is auto-discovered by the CLI worker.\n * To trigger it, use ow.runWorkflow() from your app:\n * ```ts\n * import { ow } from \"./openworkflow/client.js\";\n * import { helloWorld } from \"./openworkflow/hello-world.js\";\n * const handle = await ow.runWorkflow(helloWorld.spec, {});\n * const result = await handle.result();\n * ```\n */\nexport const helloWorld = defineWorkflow(\n { name: \"hello-world\" },\n async ({ step }) => {\n const greeting = await step.run({ name: \"greet\" }, () => {\n return \"Hello, World!\";\n });\n\n await step.sleep(\"wait-a-bit\", \"1s\");\n\n return { greeting };\n },\n);\n";
|
|
5
6
|
//# sourceMappingURL=templates.d.ts.map
|
package/dist/templates.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../templates.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../templates.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,sPAKzB,CAAC;AAEF,eAAO,MAAM,eAAe,wRAO3B,CAAC;AAEF,eAAO,MAAM,+BAA+B,mcAS3C,CAAC;AAEF,eAAO,MAAM,MAAM,gMAOlB,CAAC;AAEF,eAAO,MAAM,oBAAoB,wvBA0BhC,CAAC"}
|
package/dist/templates.js
CHANGED
|
@@ -1,44 +1,49 @@
|
|
|
1
|
-
export const
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export default defineConfig({
|
|
5
|
-
// Use SQLite as the backend
|
|
6
|
-
backend: BackendSqlite.connect("openworkflow/backend.db"),
|
|
1
|
+
export const SQLITE_CLIENT = `import { BackendSqlite } from "@openworkflow/backend-sqlite";
|
|
2
|
+
import { OpenWorkflow } from "openworkflow";
|
|
7
3
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
});
|
|
4
|
+
export const backend = BackendSqlite.connect("openworkflow/backend.db");
|
|
5
|
+
export const ow = new OpenWorkflow({ backend });
|
|
11
6
|
`;
|
|
12
|
-
export const
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
export default defineConfig({
|
|
16
|
-
// Use Postgres as the backend
|
|
17
|
-
backend: await BackendPostgres.connect(
|
|
18
|
-
process.env["OPENWORKFLOW_POSTGRES_URL"],
|
|
19
|
-
),
|
|
7
|
+
export const POSTGRES_CLIENT = `import { BackendPostgres } from "@openworkflow/backend-postgres";
|
|
8
|
+
import { OpenWorkflow } from "openworkflow";
|
|
20
9
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
10
|
+
export const backend = await BackendPostgres.connect(
|
|
11
|
+
process.env["OPENWORKFLOW_POSTGRES_URL"],
|
|
12
|
+
);
|
|
13
|
+
export const ow = new OpenWorkflow({ backend });
|
|
24
14
|
`;
|
|
25
|
-
export const
|
|
15
|
+
export const POSTGRES_PROD_SQLITE_DEV_CLIENT = `import { BackendPostgres } from "@openworkflow/backend-postgres";
|
|
26
16
|
import { BackendSqlite } from "@openworkflow/backend-sqlite";
|
|
17
|
+
import { OpenWorkflow } from "openworkflow";
|
|
18
|
+
|
|
19
|
+
export const backend =
|
|
20
|
+
process.env["NODE_ENV"] === "production"
|
|
21
|
+
? await BackendPostgres.connect(process.env["OPENWORKFLOW_POSTGRES_URL"])
|
|
22
|
+
: BackendSqlite.connect("openworkflow/backend.db");
|
|
23
|
+
export const ow = new OpenWorkflow({ backend });
|
|
24
|
+
`;
|
|
25
|
+
export const CONFIG = `import { backend } from "./openworkflow/client.js";
|
|
27
26
|
import { defineConfig } from "@openworkflow/cli";
|
|
28
27
|
|
|
29
28
|
export default defineConfig({
|
|
30
|
-
|
|
31
|
-
backend:
|
|
32
|
-
process.env["NODE_ENV"] === "production"
|
|
33
|
-
? await BackendPostgres.connect(process.env["OPENWORKFLOW_POSTGRES_URL"])
|
|
34
|
-
: BackendSqlite.connect("openworkflow/backend.db"),
|
|
35
|
-
|
|
36
|
-
// The directories where your workflows are defined
|
|
29
|
+
backend,
|
|
37
30
|
dirs: "./openworkflow",
|
|
38
31
|
});
|
|
39
32
|
`;
|
|
40
33
|
export const HELLO_WORLD_WORKFLOW = `import { defineWorkflow } from "openworkflow";
|
|
41
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Example workflow that greets the world.
|
|
37
|
+
*
|
|
38
|
+
* This workflow is auto-discovered by the CLI worker.
|
|
39
|
+
* To trigger it, use ow.runWorkflow() from your app:
|
|
40
|
+
* \`\`\`ts
|
|
41
|
+
* import { ow } from "./openworkflow/client.js";
|
|
42
|
+
* import { helloWorld } from "./openworkflow/hello-world.js";
|
|
43
|
+
* const handle = await ow.runWorkflow(helloWorld.spec, {});
|
|
44
|
+
* const result = await handle.result();
|
|
45
|
+
* \`\`\`
|
|
46
|
+
*/
|
|
42
47
|
export const helloWorld = defineWorkflow(
|
|
43
48
|
{ name: "hello-world" },
|
|
44
49
|
async ({ step }) => {
|
|
@@ -52,4 +57,3 @@ export const helloWorld = defineWorkflow(
|
|
|
52
57
|
},
|
|
53
58
|
);
|
|
54
59
|
`;
|
|
55
|
-
//# sourceMappingURL=templates.js.map
|
package/dist/templates.test.js
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CONFIG_TEMPLATE, POSTGRES_CLIENT, POSTGRES_PROD_SQLITE_DEV_CLIENT, SQLITE_CLIENT, } from "./templates.js";
|
|
2
2
|
import { describe, expect, test } from "vitest";
|
|
3
|
-
describe("
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
test("
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
describe("client templates", () => {
|
|
4
|
+
test("sqlite client exports backend and ow", () => {
|
|
5
|
+
expect(SQLITE_CLIENT).toContain("export const backend");
|
|
6
|
+
expect(SQLITE_CLIENT).toContain("new OpenWorkflow");
|
|
7
|
+
expect(SQLITE_CLIENT).toContain("BackendSqlite");
|
|
8
|
+
});
|
|
9
|
+
test("postgres client exports backend and ow", () => {
|
|
10
|
+
expect(POSTGRES_CLIENT).toContain("export const backend");
|
|
11
|
+
expect(POSTGRES_CLIENT).toContain("new OpenWorkflow");
|
|
12
|
+
expect(POSTGRES_CLIENT).toContain("BackendPostgres");
|
|
13
|
+
});
|
|
14
|
+
test("prod postgres dev sqlite client exports backend and ow", () => {
|
|
15
|
+
expect(POSTGRES_PROD_SQLITE_DEV_CLIENT).toContain("export const backend");
|
|
16
|
+
expect(POSTGRES_PROD_SQLITE_DEV_CLIENT).toContain("new OpenWorkflow");
|
|
17
|
+
expect(POSTGRES_PROD_SQLITE_DEV_CLIENT).toContain("BackendSqlite");
|
|
18
|
+
expect(POSTGRES_PROD_SQLITE_DEV_CLIENT).toContain("BackendPostgres");
|
|
13
19
|
});
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
20
|
+
});
|
|
21
|
+
describe("config templates", () => {
|
|
22
|
+
test("config references backend from client file", () => {
|
|
23
|
+
expect(CONFIG_TEMPLATE).toContain('import { backend } from "./openworkflow/client.js"');
|
|
24
|
+
expect(CONFIG_TEMPLATE).toContain("backend,");
|
|
18
25
|
});
|
|
19
26
|
});
|
|
20
|
-
//# sourceMappingURL=templates.test.js.map
|