@zerct/zerct 0.1.10 → 0.1.12

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/README.md CHANGED
@@ -20,6 +20,10 @@ on `0.0.0.0:$PORT` and expose the configured health endpoint.
20
20
  From a full-stack repo root, the same deploy command discovers nested
21
21
  `zerct.toml` files and deploys the whole workspace in one command.
22
22
 
23
+ Managed Postgres apps receive `DATABASE_URL`, `ZERCT_DATABASE_URL`, and
24
+ `ZERCT_DATABASE_CONNECTION_LIMIT`. Use that limit as the max size for your
25
+ database pool.
26
+
23
27
  Agents can also inspect API capabilities, account identity, usage, account
24
28
  activity, apps, complete app overviews, deploys, builds, app/deploy/build logs,
25
29
  env metadata, custom domains, domain verification, and billing portal links
package/bin/zerct.js CHANGED
@@ -4,9 +4,10 @@ import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSy
4
4
  import { homedir } from 'node:os'
5
5
  import path from 'node:path'
6
6
 
7
- const VERSION = '0.1.10'
7
+ const VERSION = '0.1.12'
8
8
  const DEFAULT_API_URL = 'https://api.zerct.com'
9
9
  const ARCHIVE_LIMIT_BYTES = 48 * 1024 * 1024
10
+ const DEFAULT_DEPLOY_WAIT_TIMEOUT_SECONDS = 900
10
11
  const SESSION_DIR = '.zerct'
11
12
  const SESSION_FILE = 'session-token'
12
13
  const SESSION_SERVICE = 'com.zerct.cli'
@@ -64,7 +65,7 @@ Usage:
64
65
  zerct install [path]
65
66
  zerct doctor [path] [--json]
66
67
  zerct login [--token <token>] [--api <url>]
67
- zerct deploy [path] [--database] [--api <url>] [--json]
68
+ zerct deploy [path] [--database] [--wait] [--wait-timeout <seconds>] [--api <url>] [--json]
68
69
  zerct capabilities [--api <url>] [--json]
69
70
  zerct me [--api <url>] [--json]
70
71
  zerct usage [--api <url>] [--json]
@@ -184,8 +185,10 @@ function parseArgs(argv) {
184
185
  limit: '',
185
186
  cursor: '',
186
187
  token: '',
188
+ waitTimeoutSeconds: DEFAULT_DEPLOY_WAIT_TIMEOUT_SECONDS,
187
189
  json: false,
188
190
  database: false,
191
+ wait: false,
189
192
  help: false,
190
193
  version: false
191
194
  }
@@ -203,6 +206,11 @@ function parseArgs(argv) {
203
206
  cli.database = true
204
207
  } else if (arg === '--no-database') {
205
208
  cli.database = false
209
+ } else if (arg === '--wait') {
210
+ cli.wait = true
211
+ } else if (arg === '--wait-timeout') {
212
+ cli.waitTimeoutSeconds = parsePositiveInteger(requireValue(argv, index, '--wait-timeout'), '--wait-timeout')
213
+ index += 1
206
214
  } else if (arg === '--api') {
207
215
  cli.apiUrl = requireValue(argv, index, '--api')
208
216
  index += 1
@@ -238,6 +246,14 @@ function parseArgs(argv) {
238
246
  return cli
239
247
  }
240
248
 
249
+ function parsePositiveInteger(value, name) {
250
+ const parsed = Number.parseInt(value, 10)
251
+ if (!Number.isInteger(parsed) || parsed <= 0) {
252
+ throw agentError('invalid_argument', `${name} must be a positive integer.`, `Pass ${name} as seconds, for example ${name} 900.`, false)
253
+ }
254
+ return parsed
255
+ }
256
+
241
257
  function requireValue(argv, index, name) {
242
258
  const value = argv[index + 1]
243
259
  if (!value || value.startsWith('--')) {
@@ -450,6 +466,9 @@ async function deploy(projectDir, cli) {
450
466
  const token = await readOrLoginToken(project.dir, cli)
451
467
  await preflightDeployLimits([project], cli, token, cli.database)
452
468
  const result = await deployProject(project.dir, cli, token, cli.database)
469
+ if (cli.wait) {
470
+ result.final_build = await waitForBuild(cli, token, result.build_job.id)
471
+ }
453
472
  printDeployResult(result, cli)
454
473
  return
455
474
  }
@@ -474,6 +493,10 @@ async function deploy(projectDir, cli) {
474
493
  }
475
494
  }
476
495
 
496
+ if (cli.wait) {
497
+ await waitForWorkspaceBuilds(cli, token, results)
498
+ }
499
+
477
500
  printWorkspaceDeployResults(projectDir, results, cli)
478
501
  }
479
502
 
@@ -561,7 +584,8 @@ function printWorkspaceDeployResults(projectDir, results, cli) {
561
584
  kind: result.project.kind,
562
585
  wants_database: result.wantsDatabase,
563
586
  app: result.response.app,
564
- build_job: result.response.build_job
587
+ build_job: result.response.build_job,
588
+ final_build: result.finalBuild || null
565
589
  }))
566
590
  }, null, 2))
567
591
  return
@@ -573,6 +597,41 @@ function printWorkspaceDeployResults(projectDir, results, cli) {
573
597
  }
574
598
  }
575
599
 
600
+ async function waitForWorkspaceBuilds(cli, token, results) {
601
+ await Promise.all(results.map(async (result) => {
602
+ result.finalBuild = await waitForBuild(cli, token, result.response.build_job.id)
603
+ }))
604
+ }
605
+
606
+ async function waitForBuild(cli, token, buildId) {
607
+ const deadline = Date.now() + cli.waitTimeoutSeconds * 1000
608
+ let lastStatus = ''
609
+
610
+ while (Date.now() <= deadline) {
611
+ const response = await apiRequest(cli, 'GET', `/v1/builds/${encodeURIComponent(buildId)}`, token, null)
612
+ const build = response.build
613
+ if (!build?.status) {
614
+ throw agentError('build_status_unavailable', 'Build status is unavailable.', `Retry with \`npx @zerct/zerct logs --build ${buildId}\`.`, cli.json)
615
+ }
616
+
617
+ if (build.status !== lastStatus) {
618
+ progress(cli, `build ${build.id} ${build.status}`)
619
+ lastStatus = build.status
620
+ }
621
+ if (['succeeded', 'failed', 'canceled'].includes(build.status)) {
622
+ return build
623
+ }
624
+ await sleep(3000)
625
+ }
626
+
627
+ throw agentError(
628
+ 'build_wait_timeout',
629
+ `Timed out waiting for build ${buildId}.`,
630
+ `Run \`npx @zerct/zerct logs --build ${buildId}\` to continue watching.`,
631
+ cli.json
632
+ )
633
+ }
634
+
576
635
  async function logs(cli) {
577
636
  const token = await readOrLoginToken(process.cwd(), cli)
578
637
  const page = pageQuery(cli)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerct/zerct",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Deploy Rust backends and static frontends to Zerct.",
5
5
  "type": "module",
6
6
  "bin": {