@voiden/runner 0.1.0-beta.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.
Files changed (66) hide show
  1. package/README.md +748 -0
  2. package/dist/blockSchemaRegistry.d.ts +49 -0
  3. package/dist/blockSchemaRegistry.d.ts.map +1 -0
  4. package/dist/blockSchemaRegistry.js +68 -0
  5. package/dist/blockSchemaRegistry.js.map +1 -0
  6. package/dist/cliElectron.d.ts +55 -0
  7. package/dist/cliElectron.d.ts.map +1 -0
  8. package/dist/cliElectron.js +120 -0
  9. package/dist/cliElectron.js.map +1 -0
  10. package/dist/headlessContext.d.ts +18 -0
  11. package/dist/headlessContext.d.ts.map +1 -0
  12. package/dist/headlessContext.js +85 -0
  13. package/dist/headlessContext.js.map +1 -0
  14. package/dist/index.d.ts +3 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +945 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/parser.d.ts +24 -0
  19. package/dist/parser.d.ts.map +1 -0
  20. package/dist/parser.js +87 -0
  21. package/dist/parser.js.map +1 -0
  22. package/dist/parserRegistry.d.ts +17 -0
  23. package/dist/parserRegistry.d.ts.map +1 -0
  24. package/dist/parserRegistry.js +27 -0
  25. package/dist/parserRegistry.js.map +1 -0
  26. package/dist/plugins/community.d.ts +42 -0
  27. package/dist/plugins/community.d.ts.map +1 -0
  28. package/dist/plugins/community.js +105 -0
  29. package/dist/plugins/community.js.map +1 -0
  30. package/dist/plugins/loader.d.ts +17 -0
  31. package/dist/plugins/loader.d.ts.map +1 -0
  32. package/dist/plugins/loader.js +120 -0
  33. package/dist/plugins/loader.js.map +1 -0
  34. package/dist/plugins/registry.d.ts +30 -0
  35. package/dist/plugins/registry.d.ts.map +1 -0
  36. package/dist/plugins/registry.js +52 -0
  37. package/dist/plugins/registry.js.map +1 -0
  38. package/dist/plugins/store.d.ts +19 -0
  39. package/dist/plugins/store.d.ts.map +1 -0
  40. package/dist/plugins/store.js +68 -0
  41. package/dist/plugins/store.js.map +1 -0
  42. package/dist/report/csv.d.ts +6 -0
  43. package/dist/report/csv.d.ts.map +1 -0
  44. package/dist/report/csv.js +71 -0
  45. package/dist/report/csv.js.map +1 -0
  46. package/dist/report/mail.d.ts +17 -0
  47. package/dist/report/mail.d.ts.map +1 -0
  48. package/dist/report/mail.js +84 -0
  49. package/dist/report/mail.js.map +1 -0
  50. package/dist/runner.d.ts +41 -0
  51. package/dist/runner.d.ts.map +1 -0
  52. package/dist/runner.js +193 -0
  53. package/dist/runner.js.map +1 -0
  54. package/dist/runtimeVars.d.ts +55 -0
  55. package/dist/runtimeVars.d.ts.map +1 -0
  56. package/dist/runtimeVars.js +248 -0
  57. package/dist/runtimeVars.js.map +1 -0
  58. package/dist/session.d.ts +10 -0
  59. package/dist/session.d.ts.map +1 -0
  60. package/dist/session.js +32 -0
  61. package/dist/session.js.map +1 -0
  62. package/dist/types.d.ts +45 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +3 -0
  65. package/dist/types.js.map +1 -0
  66. package/package.json +43 -0
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Plugin Registry
3
+ *
4
+ * Derives the list of runner-capable core extensions from the @voiden/core-extensions
5
+ * metadata registry — the same source the Electron app uses.
6
+ *
7
+ * All plugins (parser and hook alike) are treated identically: they each have a
8
+ * runner.ts that exports a RunnerFactory and are opt-out by default (enabled unless
9
+ * explicitly disabled in ~/.voiden/plugins.json). No plugin type is hard-coded as
10
+ * "always active" — if a plugin is disabled its runner.ts never loads, so its
11
+ * onBuildRequest / pipeline hooks are never registered.
12
+ *
13
+ * ID_TO_FOLDER handles the few cases where the registry ID differs from the
14
+ * folder name inside @voiden/core-extensions/src/.
15
+ */
16
+ import { coreExtensions } from '@voiden/core-extensions/registry';
17
+ // ─── ID → folder mapping ──────────────────────────────────────────────────────
18
+ // Most extension IDs match their folder name inside @voiden/core-extensions/src.
19
+ // List exceptions here.
20
+ const ID_TO_FOLDER = {
21
+ 'voiden-sockets-grpcs': 'voiden-sockets',
22
+ };
23
+ function folder(id) {
24
+ return ID_TO_FOLDER[id] ?? id;
25
+ }
26
+ // ─── IDs that have a headless runner.ts in @voiden/core-extensions ────────────
27
+ // All core extensions listed here are treated equally: they are opt-out (enabled
28
+ // by default) and each owns its runner.ts entry point.
29
+ const RUNNER_IDS = new Set([
30
+ 'voiden-rest-api',
31
+ 'voiden-graphql',
32
+ 'voiden-sockets-grpcs',
33
+ 'voiden-scripting',
34
+ 'simple-assertions',
35
+ 'voiden-faker',
36
+ 'voiden-advanced-auth',
37
+ ]);
38
+ // ─── Derive plugin definitions from the shared registry ───────────────────────
39
+ export const CORE_PLUGINS = coreExtensions
40
+ .filter(e => RUNNER_IDS.has(e.id))
41
+ .map(e => ({
42
+ name: e.id,
43
+ description: e.description,
44
+ pluginPath: `@voiden/core-extensions/${folder(e.id)}/runner`,
45
+ }));
46
+ export function findPlugin(name) {
47
+ return CORE_PLUGINS.find(p => p.name === name);
48
+ }
49
+ export function listPluginNames() {
50
+ return CORE_PLUGINS.map(p => p.name);
51
+ }
52
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/plugins/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AAcjE,iFAAiF;AACjF,iFAAiF;AACjF,wBAAwB;AACxB,MAAM,YAAY,GAA2B;IAC3C,sBAAsB,EAAE,gBAAgB;CACzC,CAAA;AAED,SAAS,MAAM,CAAC,EAAU;IACxB,OAAO,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAA;AAC/B,CAAC;AAED,iFAAiF;AACjF,iFAAiF;AACjF,uDAAuD;AACvD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,iBAAiB;IACjB,gBAAgB;IAChB,sBAAsB;IACtB,kBAAkB;IAClB,mBAAmB;IACnB,cAAc;IACd,sBAAsB;CACvB,CAAC,CAAA;AAEF,iFAAiF;AAEjF,MAAM,CAAC,MAAM,YAAY,GAAuB,cAAc;KAC3D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KACjC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACT,IAAI,EAAS,CAAC,CAAC,EAAE;IACjB,WAAW,EAAE,CAAC,CAAC,WAAW;IAC1B,UAAU,EAAG,2BAA2B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS;CAC9D,CAAC,CAAC,CAAA;AAEL,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;AACtC,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Plugin Store — persists installed/enabled plugin state to ~/.voiden/plugins.json
3
+ */
4
+ export interface InstalledPlugin {
5
+ name: string;
6
+ enabled: boolean;
7
+ installedAt: string;
8
+ }
9
+ export interface PluginStore {
10
+ installedPlugins: Record<string, InstalledPlugin>;
11
+ }
12
+ export declare const STORE_DIR: string;
13
+ export declare function readStore(): PluginStore;
14
+ export declare function installPlugin(name: string): boolean;
15
+ export declare function uninstallPlugin(name: string): boolean;
16
+ export declare function setPluginEnabled(name: string, enabled: boolean): void;
17
+ export declare function getEnabledPlugins(): InstalledPlugin[];
18
+ export declare function getAllInstalledPlugins(): InstalledPlugin[];
19
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/plugins/store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CAClD;AAED,eAAO,MAAM,SAAS,QAA6B,CAAA;AAOnD,wBAAgB,SAAS,IAAI,WAAW,CAOvC;AAOD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAYnD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMrD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAYrE;AAED,wBAAgB,iBAAiB,IAAI,eAAe,EAAE,CAGrD;AAED,wBAAgB,sBAAsB,IAAI,eAAe,EAAE,CAE1D"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Plugin Store — persists installed/enabled plugin state to ~/.voiden/plugins.json
3
+ */
4
+ import { homedir } from 'os';
5
+ import { join } from 'path';
6
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
7
+ export const STORE_DIR = join(homedir(), '.voiden');
8
+ const STORE_PATH = join(STORE_DIR, 'plugins.json');
9
+ function emptyStore() {
10
+ return { installedPlugins: {} };
11
+ }
12
+ export function readStore() {
13
+ if (!existsSync(STORE_PATH))
14
+ return emptyStore();
15
+ try {
16
+ return JSON.parse(readFileSync(STORE_PATH, 'utf-8'));
17
+ }
18
+ catch {
19
+ return emptyStore();
20
+ }
21
+ }
22
+ function writeStore(store) {
23
+ mkdirSync(STORE_DIR, { recursive: true });
24
+ writeFileSync(STORE_PATH, JSON.stringify(store, null, 2) + '\n', 'utf-8');
25
+ }
26
+ export function installPlugin(name) {
27
+ const store = readStore();
28
+ const alreadyInstalled = !!store.installedPlugins[name];
29
+ if (!alreadyInstalled) {
30
+ store.installedPlugins[name] = {
31
+ name,
32
+ enabled: true,
33
+ installedAt: new Date().toISOString(),
34
+ };
35
+ writeStore(store);
36
+ }
37
+ return !alreadyInstalled;
38
+ }
39
+ export function uninstallPlugin(name) {
40
+ const store = readStore();
41
+ if (!store.installedPlugins[name])
42
+ return false;
43
+ delete store.installedPlugins[name];
44
+ writeStore(store);
45
+ return true;
46
+ }
47
+ export function setPluginEnabled(name, enabled) {
48
+ const store = readStore();
49
+ if (!store.installedPlugins[name]) {
50
+ store.installedPlugins[name] = {
51
+ name,
52
+ enabled,
53
+ installedAt: new Date().toISOString(),
54
+ };
55
+ }
56
+ else {
57
+ store.installedPlugins[name].enabled = enabled;
58
+ }
59
+ writeStore(store);
60
+ }
61
+ export function getEnabledPlugins() {
62
+ const store = readStore();
63
+ return Object.values(store.installedPlugins).filter(p => p.enabled);
64
+ }
65
+ export function getAllInstalledPlugins() {
66
+ return Object.values(readStore().installedPlugins);
67
+ }
68
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/plugins/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { RunResult } from '../types.js';
2
+ export declare function exportToCsv(results: Array<{
3
+ file: string;
4
+ result: RunResult;
5
+ }>, outputPath: string): string;
6
+ //# sourceMappingURL=csv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv.d.ts","sourceRoot":"","sources":["../../src/report/csv.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,aAAa,CAAA;AA6C5D,wBAAgB,WAAW,CACzB,OAAO,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC,EACnD,UAAU,EAAE,MAAM,GACjB,MAAM,CA6BR"}
@@ -0,0 +1,71 @@
1
+ import { writeFileSync, statSync, existsSync } from 'fs';
2
+ import { join, resolve } from 'path';
3
+ function resolveOutputPath(input) {
4
+ const abs = resolve(input);
5
+ if (existsSync(abs) && statSync(abs).isDirectory()) {
6
+ const ts = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
7
+ return join(abs, `voiden-report-${ts}.csv`);
8
+ }
9
+ return abs;
10
+ }
11
+ function cell(val) {
12
+ if (val === undefined || val === null)
13
+ return '';
14
+ const s = String(val);
15
+ if (s.includes(',') || s.includes('"') || s.includes('\n') || s.includes('\r')) {
16
+ return `"${s.replace(/"/g, '""')}"`;
17
+ }
18
+ return s;
19
+ }
20
+ function headersToString(headers) {
21
+ if (!headers)
22
+ return '';
23
+ return Object.entries(headers).map(([k, v]) => `${k}: ${v}`).join('\n');
24
+ }
25
+ function assertionSummary(entries) {
26
+ const assertions = (entries ?? []).filter(e => e.type === 'assertion');
27
+ const passed = assertions.filter(e => e.type === 'assertion' && e.passed).length;
28
+ const failed = assertions.length - passed;
29
+ const detail = assertions
30
+ .map(e => e.type === 'assertion' ? `${e.passed ? 'PASS' : 'FAIL'}: ${e.message}` : '')
31
+ .join('\n');
32
+ return { passed, failed, detail };
33
+ }
34
+ const COLUMNS = [
35
+ 'File',
36
+ 'Protocol', 'Method', 'URL',
37
+ 'Success', 'Status', 'StatusText',
38
+ 'DurationMs', 'SizeBytes', 'Error',
39
+ 'RequestHeaders', 'RequestBody',
40
+ 'ResponseHeaders', 'ResponseBody',
41
+ 'AssertionsPassed', 'AssertionsFailed', 'AssertionDetail',
42
+ ];
43
+ export function exportToCsv(results, outputPath) {
44
+ outputPath = resolveOutputPath(outputPath);
45
+ const rows = [COLUMNS.join(',')];
46
+ for (const { file, result } of results) {
47
+ const { passed, failed, detail } = assertionSummary(result.reportEntries);
48
+ rows.push([
49
+ file,
50
+ result.protocol,
51
+ result.method ?? '',
52
+ result.url,
53
+ result.success ? 'true' : 'false',
54
+ String(result.status ?? ''),
55
+ result.statusText ?? '',
56
+ String(result.durationMs),
57
+ String(result.size ?? ''),
58
+ result.error ?? '',
59
+ headersToString(result.requestHeaders),
60
+ result.requestBody ?? '',
61
+ headersToString(result.responseHeaders),
62
+ result.body ?? '',
63
+ String(passed),
64
+ String(failed),
65
+ detail,
66
+ ].map(cell).join(','));
67
+ }
68
+ writeFileSync(outputPath, rows.join('\n') + '\n', 'utf-8');
69
+ return outputPath;
70
+ }
71
+ //# sourceMappingURL=csv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv.js","sourceRoot":"","sources":["../../src/report/csv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,IAAI,CAAA;AACxD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAGpC,SAAS,iBAAiB,CAAC,KAAa;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;IAC1B,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACnD,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACtE,OAAO,IAAI,CAAC,GAAG,EAAE,iBAAiB,EAAE,MAAM,CAAC,CAAA;IAC7C,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,IAAI,CAAC,GAAY;IACxB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,EAAE,CAAA;IAChD,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IACrB,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/E,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAA;IACrC,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC;AAED,SAAS,eAAe,CAAC,OAAgC;IACvD,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAA;IACvB,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzE,CAAC;AAED,SAAS,gBAAgB,CAAC,OAA0B;IAClD,MAAM,UAAU,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAA;IACtE,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAA;IAChF,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,GAAG,MAAM,CAAA;IACzC,MAAM,MAAM,GAAG,UAAU;SACtB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrF,IAAI,CAAC,IAAI,CAAC,CAAA;IACb,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;AACnC,CAAC;AAED,MAAM,OAAO,GAAG;IACd,MAAM;IACN,UAAU,EAAE,QAAQ,EAAE,KAAK;IAC3B,SAAS,EAAE,QAAQ,EAAE,YAAY;IACjC,YAAY,EAAE,WAAW,EAAE,OAAO;IAClC,gBAAgB,EAAE,aAAa;IAC/B,iBAAiB,EAAE,cAAc;IACjC,kBAAkB,EAAE,kBAAkB,EAAE,iBAAiB;CAC1D,CAAA;AAED,MAAM,UAAU,WAAW,CACzB,OAAmD,EACnD,UAAkB;IAElB,UAAU,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAA;IAC1C,MAAM,IAAI,GAAa,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IAE1C,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACvC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;QACzE,IAAI,CAAC,IAAI,CAAC;YACR,IAAI;YACJ,MAAM,CAAC,QAAQ;YACf,MAAM,CAAC,MAAM,IAAI,EAAE;YACnB,MAAM,CAAC,GAAG;YACV,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;YACjC,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;YAC3B,MAAM,CAAC,UAAU,IAAI,EAAE;YACvB,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;YACzB,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACzB,MAAM,CAAC,KAAK,IAAI,EAAE;YAClB,eAAe,CAAC,MAAM,CAAC,cAAc,CAAC;YACtC,MAAM,CAAC,WAAW,IAAI,EAAE;YACxB,eAAe,CAAC,MAAM,CAAC,eAAe,CAAC;YACvC,MAAM,CAAC,IAAI,IAAI,EAAE;YACjB,MAAM,CAAC,MAAM,CAAC;YACd,MAAM,CAAC,MAAM,CAAC;YACd,MAAM;SACP,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;IACxB,CAAC;IAED,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAA;IAC1D,OAAO,UAAU,CAAA;AACnB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { RunResult } from '../types.js';
2
+ export interface MailReportOptions {
3
+ to: string;
4
+ from?: string;
5
+ subject?: string;
6
+ smtpHost: string;
7
+ smtpPort?: number;
8
+ smtpSecure?: boolean;
9
+ smtpUser?: string;
10
+ smtpPass?: string;
11
+ csvPath?: string;
12
+ }
13
+ export declare function sendMailReport(results: Array<{
14
+ file: string;
15
+ result: RunResult;
16
+ }>, totalMs: number, opts: MailReportOptions): Promise<void>;
17
+ //# sourceMappingURL=mail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail.d.ts","sourceRoot":"","sources":["../../src/report/mail.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,aAAa,CAAA;AAE5D,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAmED,wBAAsB,cAAc,CAClC,OAAO,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC,EACnD,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
@@ -0,0 +1,84 @@
1
+ import { createTransport } from 'nodemailer';
2
+ // ─── HTML helpers ─────────────────────────────────────────────────────────────
3
+ function esc(s) {
4
+ return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
5
+ }
6
+ function buildHtml(results, totalMs) {
7
+ const passed = results.filter(r => r.result.success).length;
8
+ const failed = results.length - passed;
9
+ const fileRows = results.map(({ file, result }, i) => {
10
+ const statusColor = result.success ? '#4ade80' : '#f87171';
11
+ const icon = result.success ? '✓' : '✗';
12
+ return `
13
+ <div style="background:#1e293b;padding:12px 16px;margin-bottom:8px;border-radius:6px;display:flex;align-items:center;gap:12px;border:1px solid #334155">
14
+ <span style="color:${statusColor};font-weight:700">${icon}</span>
15
+ <span style="color:#94a3b8;font-size:12px;width:40px">[${i + 1}/${results.length}]</span>
16
+ <span style="color:#e2e8f0;font-size:14px;flex:1">${esc(file)}</span>
17
+ <span style="color:#64748b;font-size:12px">${result.durationMs}ms</span>
18
+ </div>`;
19
+ }).join('');
20
+ return `<!DOCTYPE html>
21
+ <html lang="en">
22
+ <head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
23
+ <title>voiden-runner report</title>
24
+ </head>
25
+ <body style="margin:0;padding:40px;background:#0f172a;color:#e2e8f0;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif">
26
+ <div style="max-width:700px;margin:0 auto">
27
+ <h1 style="color:#7dd3fc;font-size:24px;margin:0 0 8px">voiden-runner report</h1>
28
+ <p style="color:#64748b;font-size:14px;margin:0 0 32px">${new Date().toUTCString()} · ${totalMs}ms total</p>
29
+
30
+ <div style="background:#1e293b;border-radius:12px;padding:32px;margin-bottom:32px;display:flex;gap:48px;border:1px solid #334155">
31
+ <div>
32
+ <span style="color:#64748b;font-size:12px;display:block;margin-bottom:8px;letter-spacing:1px">PASSED</span>
33
+ <span style="font-size:36px;font-weight:700;color:#4ade80">${passed}</span>
34
+ </div>
35
+ <div>
36
+ <span style="color:#64748b;font-size:12px;display:block;margin-bottom:8px;letter-spacing:1px">FAILED</span>
37
+ <span style="font-size:36px;font-weight:700;color:${failed > 0 ? '#f87171' : '#64748b'}">${failed}</span>
38
+ </div>
39
+ <div>
40
+ <span style="color:#64748b;font-size:12px;display:block;margin-bottom:8px;letter-spacing:1px">TOTAL</span>
41
+ <span style="font-size:36px;font-weight:700;color:#94a3b8">${results.length}</span>
42
+ </div>
43
+ </div>
44
+
45
+ <h2 style="font-size:16px;color:#94a3b8;margin-bottom:16px;text-transform:uppercase;letter-spacing:1px">Files Executed</h2>
46
+ <div style="margin-bottom:32px">
47
+ ${fileRows}
48
+ </div>
49
+
50
+ <div style="background:#0f172a;border:1px dashed #334155;border-radius:8px;padding:20px;text-align:center;color:#94a3b8;font-size:14px">
51
+ Detailed request and response logs are available in the <strong>attached CSV report</strong>.
52
+ </div>
53
+ </div>
54
+ </body>
55
+ </html>`;
56
+ }
57
+ // ─── Public API ───────────────────────────────────────────────────────────────
58
+ export async function sendMailReport(results, totalMs, opts) {
59
+ const passed = results.filter(r => r.result.success).length;
60
+ const failed = results.length - passed;
61
+ const transport = createTransport({
62
+ host: opts.smtpHost,
63
+ port: opts.smtpPort ?? (opts.smtpSecure ? 465 : 587),
64
+ secure: opts.smtpSecure ?? false,
65
+ auth: opts.smtpUser ? { user: opts.smtpUser, pass: opts.smtpPass ?? '' } : undefined,
66
+ });
67
+ const subject = opts.subject
68
+ ?? `voiden-runner: ${passed}/${results.length} passed${failed > 0 ? ` · ${failed} failed` : ' · all passed'}`;
69
+ const attachments = [];
70
+ if (opts.csvPath) {
71
+ attachments.push({
72
+ filename: opts.csvPath.split('/').pop() || 'report.csv',
73
+ path: opts.csvPath,
74
+ });
75
+ }
76
+ await transport.sendMail({
77
+ from: opts.from ?? opts.smtpUser ?? 'voiden-runner',
78
+ to: opts.to,
79
+ subject,
80
+ html: buildHtml(results, totalMs),
81
+ attachments,
82
+ });
83
+ }
84
+ //# sourceMappingURL=mail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mail.js","sourceRoot":"","sources":["../../src/report/mail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * voiden-runner — core runner
3
+ *
4
+ * Flow for each section in a .void file:
5
+ * 1. loadEnabledPlugins() — derives the list from @voiden/core-extensions registry
6
+ * a. Parser plugins (graphql, sockets, rest-api) load their runner.ts and
7
+ * call context.onBuildRequest() to register block→request builders with
8
+ * the shared RequestOrchestrator from @voiden/executors
9
+ * b. Hook plugins (scripting, faker, auth, assertions) load their plugin.ts and
10
+ * call context.pipeline.registerHook() to wire into the shared pipeline
11
+ * 2. For each section:
12
+ * a. normalizeBlocks() fills in default attr values from registered schemas
13
+ * b. Build a headless editor shim ({ getJSON() }) that returns the blocks
14
+ * c. requestOrchestrator.executeRequest(editor, cliElectron) runs the full
15
+ * chain — identical to how the Electron app uses requestOrchestrator
16
+ * 3. Map PipelineResponse → RunResult
17
+ */
18
+ import type { RunResult } from './types.js';
19
+ export interface RunOptions {
20
+ env?: Record<string, string>;
21
+ verbose?: boolean;
22
+ skipPlugins?: ReadonlySet<string>;
23
+ /** Shared in-memory runtime variables map ({{process.xxx}}). Mutated in place after each section. */
24
+ runtimeVars?: Record<string, any>;
25
+ /**
26
+ * Already-loaded plugin list from a prior loadEnabledPlugins() call.
27
+ * When provided, plugin loading is skipped — use this to load once per session
28
+ * when running multiple files.
29
+ */
30
+ activePlugins?: string[];
31
+ }
32
+ export interface SectionResult {
33
+ label?: string;
34
+ result: RunResult;
35
+ }
36
+ export interface RunFileResult {
37
+ results: SectionResult[];
38
+ activePlugins: string[];
39
+ }
40
+ export declare function runVoidFile(filePath: string, options?: RunOptions): Promise<RunFileResult>;
41
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAUH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AA6G3C,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAU,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,OAAO,CAAC,EAAM,OAAO,CAAA;IACrB,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,qGAAqG;IACrG,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACjC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,SAAS,CAAA;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAQ,aAAa,EAAE,CAAA;IAC9B,aAAa,EAAE,MAAM,EAAE,CAAA;CACxB;AAED,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,UAAe,GACvB,OAAO,CAAC,aAAa,CAAC,CA0GxB"}
package/dist/runner.js ADDED
@@ -0,0 +1,193 @@
1
+ /**
2
+ * voiden-runner — core runner
3
+ *
4
+ * Flow for each section in a .void file:
5
+ * 1. loadEnabledPlugins() — derives the list from @voiden/core-extensions registry
6
+ * a. Parser plugins (graphql, sockets, rest-api) load their runner.ts and
7
+ * call context.onBuildRequest() to register block→request builders with
8
+ * the shared RequestOrchestrator from @voiden/executors
9
+ * b. Hook plugins (scripting, faker, auth, assertions) load their plugin.ts and
10
+ * call context.pipeline.registerHook() to wire into the shared pipeline
11
+ * 2. For each section:
12
+ * a. normalizeBlocks() fills in default attr values from registered schemas
13
+ * b. Build a headless editor shim ({ getJSON() }) that returns the blocks
14
+ * c. requestOrchestrator.executeRequest(editor, cliElectron) runs the full
15
+ * chain — identical to how the Electron app uses requestOrchestrator
16
+ * 3. Map PipelineResponse → RunResult
17
+ */
18
+ import { readFileSync } from 'fs';
19
+ import { parseVoidFileSections } from './parser.js';
20
+ import { requestOrchestrator } from '@voiden/executors';
21
+ import { createCliElectron } from './cliElectron.js';
22
+ import { loadEnabledPlugins } from './plugins/loader.js';
23
+ import { normalizeBlocks } from './blockSchemaRegistry.js';
24
+ import { extractRuntimeVarRows, captureRuntimeVars } from './runtimeVars.js';
25
+ function extractRawRequest(blocks) {
26
+ const req = blocks.find((b) => b.type === 'request');
27
+ let url = '';
28
+ let method = 'GET';
29
+ if (req && Array.isArray(req.content)) {
30
+ for (const node of req.content) {
31
+ if (node.type === 'method' && typeof node.content === 'string')
32
+ method = node.content.trim();
33
+ if (node.type === 'url' && typeof node.content === 'string')
34
+ url = node.content.trim();
35
+ }
36
+ }
37
+ const headers = {};
38
+ const ht = blocks.find((b) => b.type === 'headers-table');
39
+ if (ht && Array.isArray(ht.content)) {
40
+ for (const child of ht.content) {
41
+ if (child.type === 'table' && Array.isArray(child.rows)) {
42
+ for (const r of child.rows) {
43
+ if (Array.isArray(r.row) && r.row.length >= 2) {
44
+ const k = String(r.row[0] ?? '').trim();
45
+ const v = String(r.row[1] ?? '').trim();
46
+ if (k)
47
+ headers[k] = v;
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ const jb = blocks.find((b) => b.type === 'json_body');
54
+ const body = jb?.attrs?.body ? String(jb.attrs.body) : undefined;
55
+ return { url, method, headers, body };
56
+ }
57
+ // ─── Block → document JSON (headless editor shim) ─────────────────────────────
58
+ //
59
+ // Converts the flat array of blocks for a section into a TipTap-like JSON
60
+ // document so that pipeline hooks (e.g. voiden-scripting's preProcessingHook)
61
+ // can call editor.getJSON() and find script blocks by traversing .content.
62
+ function blocksToDoc(blocks) {
63
+ return { type: 'doc', content: blocks };
64
+ }
65
+ // ─── PipelineResponse → RunResult ────────────────────────────────────────────
66
+ function toRunResult(response, url, startMs) {
67
+ const durationMs = response.elapsedTime ?? (Date.now() - startMs);
68
+ let body;
69
+ if (response.body) {
70
+ body = typeof response.body === 'string'
71
+ ? response.body
72
+ : JSON.stringify(response.body);
73
+ }
74
+ // Flatten header arrays → plain objects for CSV / mail report consumers
75
+ const requestHeaders = response.requestHeaders?.length
76
+ ? Object.fromEntries(response.requestHeaders.map(h => [h.key, h.value]))
77
+ : response.requestMeta?.headers?.length
78
+ ? Object.fromEntries(response.requestMeta.headers.map(h => [h.key, h.value]))
79
+ : undefined;
80
+ const responseHeaders = response.headers?.length
81
+ ? Object.fromEntries(response.headers.map(h => [h.key, h.value]))
82
+ : undefined;
83
+ const result = {
84
+ protocol: response.protocol ?? 'rest',
85
+ method: response.requestMeta?.method,
86
+ url: response.requestMeta?.url ?? response.url ?? url,
87
+ success: !response.error && response.statusCode > 0,
88
+ status: response.statusCode || undefined,
89
+ statusText: response.statusMessage || undefined,
90
+ durationMs,
91
+ size: response.bytesContent || undefined,
92
+ body,
93
+ error: response.error,
94
+ requestHeaders,
95
+ requestBody: response.requestBody,
96
+ responseHeaders,
97
+ };
98
+ if (response.metadata?.reportEntries) {
99
+ result.reportEntries = response.metadata.reportEntries;
100
+ }
101
+ return result;
102
+ }
103
+ export async function runVoidFile(filePath, options = {}) {
104
+ const env = options.env ?? {};
105
+ const verbose = options.verbose ?? false;
106
+ const skipPlugins = options.skipPlugins ?? new Set();
107
+ const runtimeVars = options.runtimeVars ?? {};
108
+ // Use pre-loaded plugins if provided (multi-file session), otherwise load fresh.
109
+ const activePlugins = options.activePlugins ?? await loadEnabledPlugins(verbose, skipPlugins);
110
+ const content = readFileSync(filePath, 'utf-8');
111
+ const sections = parseVoidFileSections(content);
112
+ if (sections.length === 0) {
113
+ return {
114
+ results: [{
115
+ result: {
116
+ protocol: 'unknown',
117
+ url: '',
118
+ success: false,
119
+ durationMs: 0,
120
+ error: `No void blocks found in ${filePath}`,
121
+ },
122
+ }],
123
+ activePlugins,
124
+ };
125
+ }
126
+ // CLI IPC adapter — pass runtimeVars so preSendProcess can substitute {{process.xxx}}
127
+ const ipcAdapter = createCliElectron(env, runtimeVars);
128
+ const results = [];
129
+ for (const section of sections) {
130
+ const { blocks } = section;
131
+ const startMs = Date.now();
132
+ // 1. Normalise blocks against registered schemas (headless equivalent of
133
+ // TipTap schema normalisation — fills missing attrs with declared defaults).
134
+ const normalizedBlocks = normalizeBlocks(blocks);
135
+ // 2. Headless editor shim so parser plugins and pipeline hooks can call
136
+ // editor.getJSON() and traverse the document like the Electron app does.
137
+ const doc = blocksToDoc(normalizedBlocks);
138
+ const editor = { getJSON: () => doc };
139
+ editor.__cliEnv = env;
140
+ editor.__cliVars = runtimeVars; // shared reference — mutations propagate
141
+ // Extract raw request info before executing — used to populate failure
142
+ // results when the pipeline catches the error internally (e.g. unresolved
143
+ // {{KEY}} → invalid URL → fetch fails before requestMeta is populated).
144
+ const raw = extractRawRequest(normalizedBlocks);
145
+ // 4. Run the full pipeline via the shared orchestrator.
146
+ // The pipeline executor catches network errors internally and returns a
147
+ // failed PipelineResponse rather than throwing, so we handle both paths.
148
+ let response;
149
+ try {
150
+ response = await requestOrchestrator.executeRequest(editor, ipcAdapter);
151
+ }
152
+ catch (err) {
153
+ results.push({
154
+ label: section.label,
155
+ result: {
156
+ protocol: 'rest',
157
+ method: raw.method,
158
+ url: raw.url,
159
+ success: false,
160
+ durationMs: Date.now() - startMs,
161
+ error: err?.message ?? String(err),
162
+ requestHeaders: Object.keys(raw.headers).length ? raw.headers : undefined,
163
+ requestBody: raw.body,
164
+ },
165
+ });
166
+ continue;
167
+ }
168
+ const runResult = toRunResult(response, response.url ?? '', startMs);
169
+ // If the request failed before it was sent (empty URL / no requestMeta),
170
+ // fill in the raw block values so the CLI can show what was attempted.
171
+ if (!runResult.success && !runResult.url && raw.url) {
172
+ runResult.url = raw.url;
173
+ runResult.method = runResult.method ?? raw.method;
174
+ if (!runResult.requestHeaders && Object.keys(raw.headers).length) {
175
+ runResult.requestHeaders = raw.headers;
176
+ }
177
+ if (!runResult.requestBody && raw.body) {
178
+ runResult.requestBody = raw.body;
179
+ }
180
+ }
181
+ results.push({ label: section.label, result: runResult });
182
+ // 5. Capture runtime variables from this section's blocks.
183
+ // Extracts {{$res.body.xxx}} / {{$req.headers.xxx}} expressions from
184
+ // runtime-variables blocks and writes the captured values into runtimeVars.
185
+ // These are immediately available to the next section via {{process.xxx}}.
186
+ const captureRows = extractRuntimeVarRows(normalizedBlocks);
187
+ if (captureRows.length > 0) {
188
+ captureRuntimeVars(captureRows, runResult, runResult, runtimeVars);
189
+ }
190
+ }
191
+ return { results, activePlugins };
192
+ }
193
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}