@zerct/zerct 0.1.9 → 0.1.10

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 (2) hide show
  1. package/bin/zerct.js +49 -3
  2. package/package.json +1 -1
package/bin/zerct.js CHANGED
@@ -4,7 +4,7 @@ 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.9'
7
+ const VERSION = '0.1.10'
8
8
  const DEFAULT_API_URL = 'https://api.zerct.com'
9
9
  const ARCHIVE_LIMIT_BYTES = 48 * 1024 * 1024
10
10
  const SESSION_DIR = '.zerct'
@@ -448,12 +448,14 @@ async function deploy(projectDir, cli) {
448
448
  throw agentError('invalid_database_target', 'Static frontends cannot attach managed Postgres directly.', 'Deploy a Rust backend with managed Postgres and call it from the frontend.', cli.json)
449
449
  }
450
450
  const token = await readOrLoginToken(project.dir, cli)
451
+ await preflightDeployLimits([project], cli, token, cli.database)
451
452
  const result = await deployProject(project.dir, cli, token, cli.database)
452
453
  printDeployResult(result, cli)
453
454
  return
454
455
  }
455
456
 
456
457
  const token = await readOrLoginToken(projectDir, cli)
458
+ await preflightDeployLimits(projects, cli, token, cli.database)
457
459
  const results = []
458
460
  if (!cli.json) {
459
461
  console.log(`deploying ${projects.length} projects`)
@@ -475,6 +477,50 @@ async function deploy(projectDir, cli) {
475
477
  printWorkspaceDeployResults(projectDir, results, cli)
476
478
  }
477
479
 
480
+ async function preflightDeployLimits(projects, cli, token, databaseRequested) {
481
+ const [usageResponse, appsResponse] = await Promise.all([
482
+ apiRequest(cli, 'GET', '/v1/usage', token, null),
483
+ apiRequest(cli, 'GET', '/v1/apps', token, null)
484
+ ])
485
+ const usage = usageResponse?.usage || {}
486
+ const limits = usageResponse?.limits || {}
487
+ const apps = Array.isArray(appsResponse?.apps) ? appsResponse.apps : []
488
+ const existingApps = new Map(apps.map((app) => [app.name, app]))
489
+ let newProjects = 0
490
+ let newDatabases = 0
491
+
492
+ for (const project of projects) {
493
+ if (!project.name || project.kind === 'unknown') {
494
+ continue
495
+ }
496
+ const existing = existingApps.get(project.name)
497
+ if (!existing) {
498
+ newProjects += 1
499
+ }
500
+ if (databaseRequested && project.kind === 'rust_backend' && !existing?.databaseStorageMib) {
501
+ newDatabases += 1
502
+ }
503
+ }
504
+
505
+ if (newProjects > 0 && Number(usage.appCount) + newProjects > Number(limits.projects)) {
506
+ throw agentError(
507
+ 'payment_required',
508
+ `Project limit reached: ${usage.appCount}/${limits.projects} projects are already used.`,
509
+ 'Redeploy an existing app by reusing its `name` in zerct.toml, or run `npx @zerct/zerct billing` to open Stripe Checkout before creating another project.',
510
+ cli.json
511
+ )
512
+ }
513
+
514
+ if (newDatabases > 0 && Number(usage.databaseCount) + newDatabases > Number(limits.managedDatabases)) {
515
+ throw agentError(
516
+ 'payment_required',
517
+ `Managed Postgres limit reached: ${usage.databaseCount}/${limits.managedDatabases} databases are already used.`,
518
+ 'Redeploy an app that already has managed Postgres, deploy without `--database`, or run `npx @zerct/zerct billing` to open Stripe Checkout.',
519
+ cli.json
520
+ )
521
+ }
522
+ }
523
+
478
524
  async function deployProject(projectDir, cli, token, wantsDatabase) {
479
525
  const report = runDoctor(projectDir)
480
526
  if (!report.ok) {
@@ -1289,9 +1335,9 @@ function deployProjectInfo(dir, rootDir) {
1289
1335
  const relative = path.relative(rootDir, dir).replace(/\\/gu, '/') || '.'
1290
1336
  try {
1291
1337
  const config = parseZerctToml(readFileSync(path.join(dir, 'zerct.toml'), 'utf8'), dir)
1292
- return { dir, relative, kind: config.kind }
1338
+ return { dir, relative, name: config.name || '', kind: config.kind }
1293
1339
  } catch (_error) {
1294
- return { dir, relative, kind: 'unknown' }
1340
+ return { dir, relative, name: '', kind: 'unknown' }
1295
1341
  }
1296
1342
  }
1297
1343
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerct/zerct",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Deploy Rust backends and static frontends to Zerct.",
5
5
  "type": "module",
6
6
  "bin": {