@celsian/vura-cli 0.5.4 → 0.5.5

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.
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import { renderToString as builtinRenderToString } from 'what-framework/server';
16
16
  import { importRouteModule } from './shared.js';
17
- import { buildManifest, compilePageRoutes, matchPageRoute, compileRoutes, matchApiPath, getLogger, wrapDocument, escapeHtml, parseNodeBody, reportError, getMimeType, createApiApp, createWsUpgradeHandler, createNoServerWebSocketServer, GLOBAL_HOOKS_FILENAMES, nodeToWebRequest, writeWebResponse, generateClientPageEntry, } from '@celsian/vura-core';
17
+ import { buildManifest, compilePageRoutes, matchPageRoute, compileRoutes, matchApiPath, getLogger, wrapDocument, escapeHtml, parseNodeBody, reportError, getMimeType, runTaskOnce, buildTaskEnvelope, createApiApp, createWsUpgradeHandler, createNoServerWebSocketServer, GLOBAL_HOOKS_FILENAMES, nodeToWebRequest, writeWebResponse, generateClientPageEntry, } from '@celsian/vura-core';
18
18
  export function parseDevOptions(args, projectRoot = process.cwd()) {
19
19
  const portArg = args.find((_, i) => args[i - 1] === '--port');
20
20
  const hostArg = args.find((_, i) => args[i - 1] === '--host');
@@ -375,14 +375,39 @@ export async function startStandaloneServer(manifest, opts) {
375
375
  }
376
376
  try {
377
377
  const mod = await loadHandler(taskRoute.filePath);
378
+ if (typeof mod.POST !== 'function') {
379
+ res.writeHead(400, { 'Content-Type': 'application/json' });
380
+ res.end(JSON.stringify({ error: 'Task must export POST handler' }));
381
+ return;
382
+ }
378
383
  const body = await parseNodeBody(req);
379
- const result = await mod.POST({
380
- taskId: String(Date.now()),
381
- input: body?.input,
382
- attempt: 1,
383
- });
384
+ // Accept both `{ input: ... }` (legacy admin convention + the platform's
385
+ // `{ taskId, input, attempt }` wrapper) and a raw payload posted directly
386
+ // as the body (enqueue()'s local fallback).
387
+ const input = body && typeof body === 'object' && 'input' in body
388
+ ? body.input
389
+ : body;
390
+ // Platform cron/synthetic dispatches (X-Vura-Cron: true) skip input
391
+ // validation, mirroring the standalone server + in-process cron.
392
+ const isCronDispatch = String(req.headers['x-vura-cron'] ?? '').toLowerCase() === 'true';
393
+ const runResult = await runTaskOnce({
394
+ name: taskName,
395
+ config: {
396
+ retries: typeof taskRoute.config.retries === 'number' ? taskRoute.config.retries : 0,
397
+ timeout: typeof taskRoute.config.timeout === 'number' ? taskRoute.config.timeout : 30_000,
398
+ },
399
+ handler: mod.POST,
400
+ inputSchema: isCronDispatch ? undefined : mod.input,
401
+ }, { input });
402
+ if (runResult.validationError) {
403
+ res.writeHead(runResult.validationError.statusCode, { 'Content-Type': 'application/json' });
404
+ res.end(JSON.stringify(runResult.validationError.body));
405
+ return;
406
+ }
407
+ // Additive envelope + legacy status/result for backward compatibility.
408
+ const envelope = buildTaskEnvelope(taskName, runResult);
384
409
  res.writeHead(200, { 'Content-Type': 'application/json' });
385
- res.end(JSON.stringify({ status: 'completed', result }));
410
+ res.end(JSON.stringify({ ...envelope, status: runResult.status, ...(runResult.error !== undefined ? { error: runResult.error } : {}) }));
386
411
  }
387
412
  catch (err) {
388
413
  reportError(err instanceof Error ? err : new Error(String(err.message)), { method, path: url.pathname, requestId: reqCtx.requestId }, logger);
@@ -10,7 +10,7 @@
10
10
  * process.exit() directly. This lets vitest keep running while still signalling
11
11
  * the right exit code to the shell via the CLI entry point.
12
12
  */
13
- import { buildManifest, runTaskOnce } from '@celsian/vura-core';
13
+ import { buildManifest, runTaskOnce, buildTaskEnvelope } from '@celsian/vura-core';
14
14
  import { importRouteModule } from './shared.js';
15
15
  // ─── Name helpers ────────────────────────────────────────────────────────────
16
16
  /**
@@ -82,8 +82,23 @@ async function runTask(projectRoot, taskName, rawInput) {
82
82
  timeout: typeof route.config.timeout === 'number' ? route.config.timeout : 30_000,
83
83
  },
84
84
  handler: mod.POST,
85
+ // Phase 1: validate --input against the task's optional `input` schema.
86
+ inputSchema: mod.input,
85
87
  }, { input });
86
- console.log(JSON.stringify(result, null, 2));
88
+ // A schema validation failure never ran the handler — print the standard
89
+ // validation error body and exit 1.
90
+ if (result.validationError) {
91
+ console.error(JSON.stringify(result.validationError.body, null, 2));
92
+ process.exitCode = 1;
93
+ return;
94
+ }
95
+ // Print the additive run envelope ({ ok, taskName, attempts, result? }) plus
96
+ // the legacy status/error fields so existing consumers keep working.
97
+ const envelope = buildTaskEnvelope(taskName, result);
98
+ const output = { ...envelope, status: result.status };
99
+ if (result.error !== undefined)
100
+ output.error = result.error;
101
+ console.log(JSON.stringify(output, null, 2));
87
102
  if (result.status === 'failed') {
88
103
  process.exitCode = 1;
89
104
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celsian/vura-cli",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "Vura CLI — build and deploy full-stack apps",
5
5
  "type": "module",
6
6
  "bin": {
@@ -15,12 +15,12 @@
15
15
  "!dist/**/*.map"
16
16
  ],
17
17
  "dependencies": {
18
- "@celsian/vura-core": "0.5.4",
18
+ "@celsian/vura-core": "0.5.5",
19
19
  "esbuild": "^0.28.1",
20
20
  "what-framework": "^0.11.1"
21
21
  },
22
22
  "peerDependencies": {
23
- "@celsian/vura-adapter-vura": "0.5.4",
23
+ "@celsian/vura-adapter-vura": "0.5.5",
24
24
  "ws": "^8.0.0"
25
25
  },
26
26
  "peerDependenciesMeta": {
@@ -32,7 +32,7 @@
32
32
  }
33
33
  },
34
34
  "devDependencies": {
35
- "@celsian/vura-adapter-vura": "0.5.4",
35
+ "@celsian/vura-adapter-vura": "0.5.5",
36
36
  "@types/ws": "^8.18.1",
37
37
  "ws": "^8.21.0"
38
38
  },