@usejourney/cli 0.1.5 → 0.2.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.
- package/dist/index.js +70 -57
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -24,8 +24,8 @@ async function runEnvList(projectDir) {
|
|
|
24
24
|
|
|
25
25
|
// src/commands/exportK6.ts
|
|
26
26
|
import { stat } from "fs/promises";
|
|
27
|
-
import { isAbsolute, resolve } from "path";
|
|
28
|
-
import { exportToK6 } from "@usejourney/k6-adapter";
|
|
27
|
+
import { dirname as dirname2, isAbsolute, resolve } from "path";
|
|
28
|
+
import { exportToK6, findProjectDir } from "@usejourney/k6-adapter";
|
|
29
29
|
|
|
30
30
|
// src/util/discover.ts
|
|
31
31
|
import { readdir } from "fs/promises";
|
|
@@ -58,6 +58,35 @@ async function importJourneyFiles(files) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
// src/util/projectCoreLink.ts
|
|
62
|
+
import { existsSync, readFileSync } from "fs";
|
|
63
|
+
import { mkdir, symlink } from "fs/promises";
|
|
64
|
+
import { dirname, join as join2 } from "path";
|
|
65
|
+
import { fileURLToPath } from "url";
|
|
66
|
+
function locateJourneyCoreDir() {
|
|
67
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
68
|
+
for (let depth = 0; depth < 50; depth++) {
|
|
69
|
+
const pkgJson = join2(dir, "node_modules", "@usejourney", "core", "package.json");
|
|
70
|
+
if (existsSync(pkgJson)) {
|
|
71
|
+
JSON.parse(readFileSync(pkgJson, "utf8"));
|
|
72
|
+
return dirname(pkgJson);
|
|
73
|
+
}
|
|
74
|
+
const parent = dirname(dir);
|
|
75
|
+
if (parent === dir) break;
|
|
76
|
+
dir = parent;
|
|
77
|
+
}
|
|
78
|
+
throw new Error("ensureProjectCoreLink: could not locate the CLI-bundled @usejourney/core");
|
|
79
|
+
}
|
|
80
|
+
var cachedCoreDir;
|
|
81
|
+
async function ensureProjectCoreLink(projectDir) {
|
|
82
|
+
const link = join2(projectDir, "node_modules", "@usejourney", "core");
|
|
83
|
+
if (existsSync(link)) return;
|
|
84
|
+
if (!cachedCoreDir) cachedCoreDir = locateJourneyCoreDir();
|
|
85
|
+
await mkdir(dirname(link), { recursive: true });
|
|
86
|
+
const type = process.platform === "win32" ? "junction" : "dir";
|
|
87
|
+
await symlink(cachedCoreDir, link, type);
|
|
88
|
+
}
|
|
89
|
+
|
|
61
90
|
// src/commands/exportK6.ts
|
|
62
91
|
function matches(def, tags) {
|
|
63
92
|
if (tags.length === 0) return true;
|
|
@@ -97,6 +126,8 @@ async function runExportK6(opts) {
|
|
|
97
126
|
console.log(`No .journey.ts files found in ${opts.path}`);
|
|
98
127
|
return 0;
|
|
99
128
|
}
|
|
129
|
+
const projectDir = findProjectDir(isDir ? target : dirname2(target)) ?? process.cwd();
|
|
130
|
+
await ensureProjectCoreLink(projectDir);
|
|
100
131
|
const work = [];
|
|
101
132
|
for (const file of files) {
|
|
102
133
|
const defs = await loadJourneyDefs(file);
|
|
@@ -114,7 +145,10 @@ async function runExportK6(opts) {
|
|
|
114
145
|
journeyFile: file,
|
|
115
146
|
...opts.out !== void 0 ? { outFile: opts.out } : {},
|
|
116
147
|
...opts.outDir !== void 0 ? { outDir: opts.outDir } : {},
|
|
117
|
-
...k6Options !== void 0 ? { k6Options } : {}
|
|
148
|
+
...k6Options !== void 0 ? { k6Options } : {},
|
|
149
|
+
...opts.metricsPrefix !== void 0 ? { metricsPrefix: opts.metricsPrefix } : {},
|
|
150
|
+
...opts.haltOnFailure ? { haltOnFailure: true } : {},
|
|
151
|
+
projectDir
|
|
118
152
|
});
|
|
119
153
|
console.log(`Wrote k6 script \u2192 ${result.outFile}`);
|
|
120
154
|
exported++;
|
|
@@ -126,8 +160,8 @@ async function runExportK6(opts) {
|
|
|
126
160
|
}
|
|
127
161
|
|
|
128
162
|
// src/commands/exportPostman.ts
|
|
129
|
-
import { mkdir, stat as stat2, writeFile } from "fs/promises";
|
|
130
|
-
import { basename, dirname, isAbsolute as isAbsolute2, join as
|
|
163
|
+
import { mkdir as mkdir2, stat as stat2, writeFile } from "fs/promises";
|
|
164
|
+
import { basename, dirname as dirname3, isAbsolute as isAbsolute2, join as join3, resolve as resolve2 } from "path";
|
|
131
165
|
import {
|
|
132
166
|
clearActiveEnvironment,
|
|
133
167
|
collectPipeline,
|
|
@@ -232,8 +266,8 @@ function uniqueFolderName(name, seen) {
|
|
|
232
266
|
async function exportEnvironment(environmentsDir, envName, outDir) {
|
|
233
267
|
const values = await loadEnvironment(environmentsDir, envName);
|
|
234
268
|
const env = buildEnvironment(envName, values);
|
|
235
|
-
const outFile =
|
|
236
|
-
await
|
|
269
|
+
const outFile = join3(outDir, `${envName}.postman_environment.json`);
|
|
270
|
+
await mkdir2(dirname3(outFile), { recursive: true });
|
|
237
271
|
await writeFile(outFile, JSON.stringify(env, null, 2), "utf8");
|
|
238
272
|
return outFile;
|
|
239
273
|
}
|
|
@@ -319,8 +353,8 @@ async function runExportPostman(opts) {
|
|
|
319
353
|
const collection = buildCollection(opts.name ?? "journeys", mergedFolders, {
|
|
320
354
|
reset: opts.threadState ?? false
|
|
321
355
|
});
|
|
322
|
-
const collectionOutDir =
|
|
323
|
-
await
|
|
356
|
+
const collectionOutDir = dirname3(outFile);
|
|
357
|
+
await mkdir2(collectionOutDir, { recursive: true });
|
|
324
358
|
await writeFile(outFile, JSON.stringify(collection, null, 2), "utf8");
|
|
325
359
|
console.log(`Wrote Postman collection \u2192 ${outFile}`);
|
|
326
360
|
exported++;
|
|
@@ -351,9 +385,9 @@ async function runExportPostman(opts) {
|
|
|
351
385
|
reset: opts.threadState ?? false
|
|
352
386
|
});
|
|
353
387
|
const json = JSON.stringify(collection, null, 2);
|
|
354
|
-
const outFile = opts.out ? resolve2(process.cwd(), opts.out) : opts.outDir ? resolve2(process.cwd(), opts.outDir, `${fileBase}.postman_collection.json`) :
|
|
355
|
-
const collectionOutDir =
|
|
356
|
-
await
|
|
388
|
+
const outFile = opts.out ? resolve2(process.cwd(), opts.out) : opts.outDir ? resolve2(process.cwd(), opts.outDir, `${fileBase}.postman_collection.json`) : join3(dirname3(file), `${fileBase}.postman_collection.json`);
|
|
389
|
+
const collectionOutDir = dirname3(outFile);
|
|
390
|
+
await mkdir2(collectionOutDir, { recursive: true });
|
|
357
391
|
await writeFile(outFile, json, "utf8");
|
|
358
392
|
console.log(`Wrote Postman collection \u2192 ${outFile}`);
|
|
359
393
|
exported++;
|
|
@@ -388,8 +422,8 @@ async function runGenerate(projectDir) {
|
|
|
388
422
|
}
|
|
389
423
|
|
|
390
424
|
// src/commands/init.ts
|
|
391
|
-
import { access, copyFile, mkdir as
|
|
392
|
-
import { basename as basename2, isAbsolute as isAbsolute3, join as
|
|
425
|
+
import { access, copyFile, mkdir as mkdir3, readdir as readdir2, writeFile as writeFile2 } from "fs/promises";
|
|
426
|
+
import { basename as basename2, isAbsolute as isAbsolute3, join as join4, resolve as resolve3 } from "path";
|
|
393
427
|
import { generate as generate2, loadSpec } from "@usejourney/codegen";
|
|
394
428
|
async function isEmpty(dir) {
|
|
395
429
|
try {
|
|
@@ -416,12 +450,12 @@ async function runInit(opts) {
|
|
|
416
450
|
}
|
|
417
451
|
await loadSpec(specSource);
|
|
418
452
|
const specDestName = basename2(specSource);
|
|
419
|
-
const specDest =
|
|
420
|
-
await
|
|
421
|
-
await
|
|
422
|
-
await
|
|
423
|
-
await
|
|
424
|
-
await
|
|
453
|
+
const specDest = join4(projectDir, specDestName);
|
|
454
|
+
await mkdir3(projectDir, { recursive: true });
|
|
455
|
+
await mkdir3(join4(projectDir, "generated"), { recursive: true });
|
|
456
|
+
await mkdir3(join4(projectDir, "journeys"), { recursive: true });
|
|
457
|
+
await mkdir3(join4(projectDir, "environments"), { recursive: true });
|
|
458
|
+
await mkdir3(join4(projectDir, ".journey", "cache"), { recursive: true });
|
|
425
459
|
await copyFile(specSource, specDest);
|
|
426
460
|
const config = {
|
|
427
461
|
name: basename2(projectDir),
|
|
@@ -431,23 +465,23 @@ async function runInit(opts) {
|
|
|
431
465
|
environmentsDir: "environments"
|
|
432
466
|
};
|
|
433
467
|
await writeFile2(
|
|
434
|
-
|
|
468
|
+
join4(projectDir, "journey.config.json"),
|
|
435
469
|
`${JSON.stringify(config, null, 2)}
|
|
436
470
|
`,
|
|
437
471
|
"utf8"
|
|
438
472
|
);
|
|
439
|
-
await writeFile2(
|
|
473
|
+
await writeFile2(join4(projectDir, ".gitignore"), `.journey/cache/
|
|
440
474
|
node_modules/
|
|
441
475
|
`, "utf8");
|
|
442
476
|
await writeFile2(
|
|
443
|
-
|
|
477
|
+
join4(projectDir, "package.json"),
|
|
444
478
|
`${JSON.stringify({ name: basename2(projectDir), private: true, type: "module" }, null, 2)}
|
|
445
479
|
`,
|
|
446
480
|
"utf8"
|
|
447
481
|
);
|
|
448
482
|
const generated = await generate2({
|
|
449
483
|
specPath: specDest,
|
|
450
|
-
outDir:
|
|
484
|
+
outDir: join4(projectDir, "generated")
|
|
451
485
|
});
|
|
452
486
|
console.log(
|
|
453
487
|
`Initialized Journey project at ${projectDir} (${generated.operationCount} operations).`
|
|
@@ -461,7 +495,7 @@ node_modules/
|
|
|
461
495
|
|
|
462
496
|
// src/commands/run.ts
|
|
463
497
|
import { watch } from "fs/promises";
|
|
464
|
-
import { dirname as
|
|
498
|
+
import { dirname as dirname4, isAbsolute as isAbsolute4, join as join5, resolve as resolve4 } from "path";
|
|
465
499
|
import {
|
|
466
500
|
clearActiveEnvironment as clearActiveEnvironment2,
|
|
467
501
|
createConsoleLogger,
|
|
@@ -533,35 +567,6 @@ async function configureDispatcher(opts) {
|
|
|
533
567
|
return agent;
|
|
534
568
|
}
|
|
535
569
|
|
|
536
|
-
// src/util/projectCoreLink.ts
|
|
537
|
-
import { existsSync, readFileSync } from "fs";
|
|
538
|
-
import { mkdir as mkdir3, symlink } from "fs/promises";
|
|
539
|
-
import { dirname as dirname2, join as join4 } from "path";
|
|
540
|
-
import { fileURLToPath } from "url";
|
|
541
|
-
function locateJourneyCoreDir() {
|
|
542
|
-
let dir = dirname2(fileURLToPath(import.meta.url));
|
|
543
|
-
for (let depth = 0; depth < 50; depth++) {
|
|
544
|
-
const pkgJson = join4(dir, "node_modules", "@usejourney", "core", "package.json");
|
|
545
|
-
if (existsSync(pkgJson)) {
|
|
546
|
-
JSON.parse(readFileSync(pkgJson, "utf8"));
|
|
547
|
-
return dirname2(pkgJson);
|
|
548
|
-
}
|
|
549
|
-
const parent = dirname2(dir);
|
|
550
|
-
if (parent === dir) break;
|
|
551
|
-
dir = parent;
|
|
552
|
-
}
|
|
553
|
-
throw new Error("ensureProjectCoreLink: could not locate the CLI-bundled @usejourney/core");
|
|
554
|
-
}
|
|
555
|
-
var cachedCoreDir;
|
|
556
|
-
async function ensureProjectCoreLink(projectDir) {
|
|
557
|
-
const link = join4(projectDir, "node_modules", "@usejourney", "core");
|
|
558
|
-
if (existsSync(link)) return;
|
|
559
|
-
if (!cachedCoreDir) cachedCoreDir = locateJourneyCoreDir();
|
|
560
|
-
await mkdir3(dirname2(link), { recursive: true });
|
|
561
|
-
const type = process.platform === "win32" ? "junction" : "dir";
|
|
562
|
-
await symlink(cachedCoreDir, link, type);
|
|
563
|
-
}
|
|
564
|
-
|
|
565
570
|
// src/commands/run.ts
|
|
566
571
|
async function runCommand(opts) {
|
|
567
572
|
const loaded = await loadConfig4(opts.projectDir);
|
|
@@ -578,7 +583,7 @@ async function runCommand(opts) {
|
|
|
578
583
|
}
|
|
579
584
|
await ensureProjectCoreLink(opts.projectDir);
|
|
580
585
|
await importJourneyFiles(files);
|
|
581
|
-
const ctx = {};
|
|
586
|
+
const ctx = { baseDir: opts.projectDir };
|
|
582
587
|
const baseUrl = resolveBaseUrl(loaded.config);
|
|
583
588
|
if (baseUrl) ctx.baseUrl = baseUrl;
|
|
584
589
|
const logger = opts.debug ? createConsoleLogger() : loggerFromEnv();
|
|
@@ -624,7 +629,7 @@ async function runCommand(opts) {
|
|
|
624
629
|
timer = setTimeout(() => void rerun(), DEBOUNCE_MS);
|
|
625
630
|
};
|
|
626
631
|
const dirs = /* @__PURE__ */ new Set([paths.journeysDir]);
|
|
627
|
-
for (const f of files) dirs.add(
|
|
632
|
+
for (const f of files) dirs.add(dirname4(f));
|
|
628
633
|
const watchers = [];
|
|
629
634
|
for (const dir of dirs) {
|
|
630
635
|
try {
|
|
@@ -741,7 +746,7 @@ async function runJourneyFile(opts) {
|
|
|
741
746
|
}
|
|
742
747
|
await ensureProjectCoreLink(opts.loaded.projectDir);
|
|
743
748
|
await importJourneyFiles([abs]);
|
|
744
|
-
const ctx = {};
|
|
749
|
+
const ctx = { baseDir: opts.loaded.projectDir };
|
|
745
750
|
const baseUrl = resolveBaseUrl2(opts.loaded.config);
|
|
746
751
|
if (baseUrl) ctx.baseUrl = baseUrl;
|
|
747
752
|
const logger = opts.logger ?? (opts.debug ? createConsoleLogger2() : loggerFromEnv2());
|
|
@@ -1815,12 +1820,20 @@ function buildProgram() {
|
|
|
1815
1820
|
"Only export journeys with this tag (repeatable, AND across repeats)",
|
|
1816
1821
|
(v, prev = []) => [...prev, v],
|
|
1817
1822
|
[]
|
|
1823
|
+
).option(
|
|
1824
|
+
"--metrics-prefix <prefix>",
|
|
1825
|
+
"Emit custom metrics per step (<prefix>_<step>_duration Trend, <prefix>_<step>_tps Counter) and per iteration (<prefix>_flow_duration / <prefix>_flow_tps)"
|
|
1826
|
+
).option(
|
|
1827
|
+
"--halt-on-failure",
|
|
1828
|
+
"Stop an iteration's remaining steps when an assert fails (mirrors journey run)"
|
|
1818
1829
|
).description("Export one or more journeys as k6 scripts (path may be a file or directory)").action(
|
|
1819
1830
|
(path, options) => handle(
|
|
1820
1831
|
() => runExportK6({
|
|
1821
1832
|
path,
|
|
1822
1833
|
...options.out !== void 0 ? { out: options.out } : {},
|
|
1823
1834
|
...options.outDir !== void 0 ? { outDir: options.outDir } : {},
|
|
1835
|
+
...options.metricsPrefix !== void 0 ? { metricsPrefix: options.metricsPrefix } : {},
|
|
1836
|
+
...options.haltOnFailure ? { haltOnFailure: true } : {},
|
|
1824
1837
|
tags: options.tag
|
|
1825
1838
|
})
|
|
1826
1839
|
)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usejourney/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"commander": "^12.1.0",
|
|
24
24
|
"tsx": "^4.21.0",
|
|
25
25
|
"undici": "^8.3.0",
|
|
26
|
-
"@usejourney/codegen": "^0.
|
|
27
|
-
"@usejourney/core": "0.
|
|
28
|
-
"@usejourney/k6-adapter": "^0.
|
|
29
|
-
"@usejourney/postman-adapter": "^0.
|
|
26
|
+
"@usejourney/codegen": "^0.2.0",
|
|
27
|
+
"@usejourney/core": "0.2.0",
|
|
28
|
+
"@usejourney/k6-adapter": "^0.2.0",
|
|
29
|
+
"@usejourney/postman-adapter": "^0.2.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/newman": "^5.3.6",
|