@celsian/vura-cli 0.5.12 → 0.5.14

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.
@@ -13,10 +13,43 @@
13
13
  * --api-url <url> API base URL (else VURA_API_URL, else https://api.vura.io)
14
14
  * --project-id <id> Project id (else VURA_PROJECT_ID, else .vura/project.json)
15
15
  */
16
- import { readFile } from 'node:fs/promises';
17
16
  import { existsSync } from 'node:fs';
17
+ import { readFile } from 'node:fs/promises';
18
18
  import { join } from 'node:path';
19
19
  import { resolveApiUrl, resolveProjectId, resolveToken } from '../vura-client.js';
20
+ function isRecord(value) {
21
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
22
+ }
23
+ function invalidManifest(manifestPath, detail) {
24
+ return new Error(`Build manifest at ${manifestPath} is invalid (${detail}). ` +
25
+ 'Run `vura build` again before deploying.');
26
+ }
27
+ async function readDeployManifest(manifestPath) {
28
+ let parsed;
29
+ try {
30
+ parsed = JSON.parse(await readFile(manifestPath, 'utf8'));
31
+ }
32
+ catch {
33
+ throw invalidManifest(manifestPath, 'malformed JSON');
34
+ }
35
+ if (!isRecord(parsed))
36
+ throw invalidManifest(manifestPath, 'expected a JSON object');
37
+ if (!Array.isArray(parsed.api))
38
+ throw invalidManifest(manifestPath, 'api must be an array');
39
+ if (!Array.isArray(parsed.pages))
40
+ throw invalidManifest(manifestPath, 'pages must be an array');
41
+ for (const [index, route] of parsed.api.entries()) {
42
+ if (!isRecord(route) || !['serverless', 'hot', 'task'].includes(String(route.kind))) {
43
+ throw invalidManifest(manifestPath, `api[${index}] must have a supported kind`);
44
+ }
45
+ }
46
+ for (const [index, page] of parsed.pages.entries()) {
47
+ if (!isRecord(page) || !['static', 'server', 'client', 'hybrid'].includes(String(page.mode))) {
48
+ throw invalidManifest(manifestPath, `pages[${index}] must have a supported mode`);
49
+ }
50
+ }
51
+ return parsed;
52
+ }
20
53
  function parseFlags(args) {
21
54
  const flags = { production: false };
22
55
  for (let i = 0; i < args.length; i++) {
@@ -70,16 +103,18 @@ export async function deployCommand(args) {
70
103
  return;
71
104
  }
72
105
  const apiUrl = resolveApiUrl(flags.apiUrl);
73
- // Attach the built manifest so the platform can classify routes without
74
- // re-scanning the artifact.
106
+ // 4. Refuse stale/corrupt build output before loading or calling the adapter.
75
107
  let manifest;
76
108
  try {
77
- manifest = JSON.parse(await readFile(manifestPath, 'utf-8'));
109
+ manifest = await readDeployManifest(manifestPath);
78
110
  }
79
- catch {
80
- manifest = undefined;
111
+ catch (err) {
112
+ const message = err instanceof Error ? err.message : String(err);
113
+ console.error(` ${message}`);
114
+ process.exitCode = 1;
115
+ return;
81
116
  }
82
- // 4. Deploy via the shared adapter flow.
117
+ // 5. Deploy via the adapter's independently validated shared flow.
83
118
  let deployToVura;
84
119
  try {
85
120
  ({ deployToVura } = await import('@celsian/vura-adapter-vura'));
@@ -52,7 +52,9 @@ function computeDetails(route) {
52
52
  timeout,
53
53
  providerRecommendation: 'serverless-function',
54
54
  confidence: 'medium',
55
- reasons: ['Stateless endpoints and tasks default to scale-to-zero Function compute at 1gb.'],
55
+ reasons: [memory && memory !== '1gb'
56
+ ? `The route explicitly selects ${memory} of scale-to-zero Function memory.`
57
+ : 'Stateless endpoints and tasks default to scale-to-zero Function compute at 1gb.'],
56
58
  };
57
59
  }
58
60
  function prefersHotTask(config) {
package/dist/index.js CHANGED
@@ -40,6 +40,10 @@ export async function run(args) {
40
40
  printHelp();
41
41
  process.exit(1);
42
42
  }
43
+ if (args.slice(1).some((arg) => arg === '--help' || arg === '-h')) {
44
+ printHelp();
45
+ return;
46
+ }
43
47
  await handler(args.slice(1));
44
48
  }
45
49
  function printHelp() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celsian/vura-cli",
3
- "version": "0.5.12",
3
+ "version": "0.5.14",
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.12",
18
+ "@celsian/vura-core": "0.5.14",
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.12",
23
+ "@celsian/vura-adapter-vura": "0.5.14",
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.12",
35
+ "@celsian/vura-adapter-vura": "0.5.14",
36
36
  "@types/ws": "^8.18.1",
37
37
  "ws": "^8.21.0"
38
38
  },