@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.
- package/bin/zerct.js +49 -3
- 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.
|
|
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
|
|