@everystack/cli 0.4.59 → 0.4.61
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/package.json +2 -2
- package/src/backfill.ts +3 -3
- package/src/cli/alter-type-dependents.ts +1 -1
- package/src/cli/apply-authority.ts +1 -1
- package/src/cli/apply-execute.ts +10 -10
- package/src/cli/audit-api.ts +4 -4
- package/src/cli/audit-source-api.ts +2 -2
- package/src/cli/authz-adoption-class.ts +4 -4
- package/src/cli/authz-baseline.ts +2 -2
- package/src/cli/authz-canonical.ts +2 -2
- package/src/cli/authz-compile.ts +3 -3
- package/src/cli/authz-contract-io.ts +2 -2
- package/src/cli/authz-contract.ts +4 -4
- package/src/cli/authz-derive.ts +2 -2
- package/src/cli/authz-identity.ts +1 -1
- package/src/cli/authz-ownership.ts +1 -1
- package/src/cli/authz-reconcile.ts +4 -4
- package/src/cli/authz-redteam.ts +1 -1
- package/src/cli/authz-render.ts +2 -2
- package/src/cli/aws.ts +53 -4
- package/src/cli/backfill.ts +3 -3
- package/src/cli/branch-db.ts +5 -5
- package/src/cli/bundle-weight.ts +2 -2
- package/src/cli/commands/analyze.ts +2 -2
- package/src/cli/commands/audit.ts +10 -10
- package/src/cli/commands/bundle.ts +6 -6
- package/src/cli/commands/cache.ts +75 -3
- package/src/cli/commands/console.ts +6 -6
- package/src/cli/commands/db-apply.ts +25 -25
- package/src/cli/commands/db-approvers.ts +4 -4
- package/src/cli/commands/db-authz.ts +15 -15
- package/src/cli/commands/db-backfill.ts +10 -10
- package/src/cli/commands/db-backup.ts +25 -36
- package/src/cli/commands/db-branch.ts +8 -8
- package/src/cli/commands/db-build.ts +7 -7
- package/src/cli/commands/db-check.ts +16 -16
- package/src/cli/commands/db-diff.ts +6 -6
- package/src/cli/commands/db-exec.ts +8 -8
- package/src/cli/commands/db-export.ts +10 -10
- package/src/cli/commands/db-fingerprint.ts +14 -14
- package/src/cli/commands/db-fork.ts +15 -15
- package/src/cli/commands/db-generate.ts +19 -19
- package/src/cli/commands/db-plan.ts +25 -25
- package/src/cli/commands/db-pull.ts +18 -18
- package/src/cli/commands/db-reconcile.ts +14 -14
- package/src/cli/commands/db-refresh.ts +7 -7
- package/src/cli/commands/db-snapshot.ts +5 -5
- package/src/cli/commands/db-swap.ts +49 -37
- package/src/cli/commands/db-sync.ts +18 -18
- package/src/cli/commands/db.ts +15 -15
- package/src/cli/commands/deploy.ts +39 -5
- package/src/cli/commands/diag.ts +4 -4
- package/src/cli/commands/lighthouse.ts +3 -3
- package/src/cli/commands/logs.ts +5 -5
- package/src/cli/commands/pipeline-run.ts +7 -7
- package/src/cli/commands/runbook.ts +5 -5
- package/src/cli/commands/secrets.ts +5 -5
- package/src/cli/commands/security-probe.ts +4 -4
- package/src/cli/commands/security.ts +6 -6
- package/src/cli/commands/status.ts +3 -3
- package/src/cli/commands/task-probe.ts +4 -4
- package/src/cli/commands/ui-audit.ts +5 -5
- package/src/cli/commands/update.ts +64 -8
- package/src/cli/component-audit.ts +5 -5
- package/src/cli/config.ts +2 -2
- package/src/cli/db-build.ts +6 -6
- package/src/cli/db-source.ts +2 -2
- package/src/cli/declared-derived.ts +5 -5
- package/src/cli/declared-diff.ts +5 -5
- package/src/cli/deploy-probe.ts +3 -3
- package/src/cli/derived-apply.ts +5 -5
- package/src/cli/derived-compile.ts +4 -4
- package/src/cli/derived-grants.ts +1 -1
- package/src/cli/derived-introspect.ts +3 -3
- package/src/cli/derived-lint.ts +2 -2
- package/src/cli/derived-plan.ts +5 -5
- package/src/cli/derived-render.ts +6 -6
- package/src/cli/direct-venue.ts +2 -2
- package/src/cli/discover.ts +2 -2
- package/src/cli/edge-plan.ts +8 -8
- package/src/cli/exec-digest.ts +1 -1
- package/src/cli/exec-execute.ts +1 -1
- package/src/cli/exec-log.ts +1 -1
- package/src/cli/exec-run.ts +2 -2
- package/src/cli/git-descent.ts +5 -5
- package/src/cli/index.ts +46 -46
- package/src/cli/migration-compile.ts +7 -7
- package/src/cli/migration-generate.ts +6 -6
- package/src/cli/model-api.ts +16 -16
- package/src/cli/model-render.ts +6 -6
- package/src/cli/mutation-lease.ts +1 -1
- package/src/cli/observability.ts +1 -1
- package/src/cli/refresh-execute.ts +2 -2
- package/src/cli/runbook/generate.ts +3 -3
- package/src/cli/runbook/index.ts +7 -7
- package/src/cli/runbook/sections.ts +2 -2
- package/src/cli/schema-compile.ts +4 -4
- package/src/cli/schema-diff.ts +1 -1
- package/src/cli/schema-fingerprint.ts +7 -7
- package/src/cli/schema-introspect.ts +3 -3
- package/src/cli/schema-source.ts +1 -1
- package/src/cli/schema-swap.ts +4 -4
- package/src/cli/security-catalog.ts +1 -1
- package/src/cli/stage-backup.ts +229 -0
- package/src/cli/stage-read-consistency.ts +6 -6
- package/src/cli/state-apply.ts +7 -7
- package/src/cli/swap-execute.ts +3 -3
- package/src/cli/swap-heartbeat.ts +1 -1
- package/src/cli/swap-pair.ts +7 -7
- package/src/cli/task-poll.ts +2 -2
- package/src/cli/ui-bloat.ts +1 -1
- package/src/cli/utils/secrets.ts +1 -1
- package/src/exec.ts +7 -7
- package/src/reconcile.ts +2 -2
- package/src/refresh.ts +2 -2
- package/src/sst.ts +1 -1
|
@@ -30,33 +30,33 @@
|
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
32
|
import fs from 'node:fs/promises';
|
|
33
|
-
import { type QueryRunner } from '../authz-contract
|
|
34
|
-
import { currentGitRef } from '../state-apply
|
|
35
|
-
import { planHash, PLAN_VERSION, type EdgePlan } from '../edge-plan
|
|
36
|
-
import { verifyDescent, type DescentVerdict, type LiveState } from '../git-descent
|
|
37
|
-
import { checkDestructiveAuthority, readApproverParam, resolveCallerIdentity, type AuthorityVerdict } from '../apply-authority
|
|
38
|
-
import { resolveModelsPath } from '../models-path
|
|
39
|
-
import { loadModels } from './db-generate
|
|
40
|
-
import { loadDeclaredDerived } from '../declared-derived
|
|
41
|
-
import { compileTableContract } from '../authz-compile
|
|
42
|
-
import { governedRoleSet, ungovernedGrants } from '../authz-reconcile
|
|
43
|
-
import { readBaselineFile, checkAgainstBaseline, baselineRefusal } from '../authz-baseline
|
|
44
|
-
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source
|
|
45
|
-
import { borrowedSessionRunner, type SessionRunner } from '../session
|
|
46
|
-
import { resolveConfig, opsFunction } from '../config
|
|
47
|
-
import { invokeAction, lambdaQueryRunner, lambdaSessionRunner } from '../aws
|
|
48
|
-
import { executeApplyPlan, type ApplyPlanResult } from '../apply-execute
|
|
49
|
-
import { estimateOpsRuntimeFit } from '../ops-fit
|
|
50
|
-
import { resolveOperatorUrlViaStage } from '../direct-venue
|
|
51
|
-
import { withMutationLease, MutationLeaseError } from '../mutation-lease
|
|
52
|
-
import { readStageStateTwice, stageDestructiveRefusal } from '../stage-read-consistency
|
|
53
|
-
import { step, success, fail, info, warn } from '../output
|
|
33
|
+
import { type QueryRunner } from '../authz-contract';
|
|
34
|
+
import { currentGitRef } from '../state-apply';
|
|
35
|
+
import { planHash, PLAN_VERSION, type EdgePlan } from '../edge-plan';
|
|
36
|
+
import { verifyDescent, type DescentVerdict, type LiveState } from '../git-descent';
|
|
37
|
+
import { checkDestructiveAuthority, readApproverParam, resolveCallerIdentity, type AuthorityVerdict } from '../apply-authority';
|
|
38
|
+
import { resolveModelsPath } from '../models-path';
|
|
39
|
+
import { loadModels } from './db-generate';
|
|
40
|
+
import { loadDeclaredDerived } from '../declared-derived';
|
|
41
|
+
import { compileTableContract } from '../authz-compile';
|
|
42
|
+
import { governedRoleSet, ungovernedGrants } from '../authz-reconcile';
|
|
43
|
+
import { readBaselineFile, checkAgainstBaseline, baselineRefusal } from '../authz-baseline';
|
|
44
|
+
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source';
|
|
45
|
+
import { borrowedSessionRunner, type SessionRunner } from '../session';
|
|
46
|
+
import { resolveConfig, opsFunction } from '../config';
|
|
47
|
+
import { invokeAction, lambdaQueryRunner, lambdaSessionRunner } from '../aws';
|
|
48
|
+
import { executeApplyPlan, type ApplyPlanResult } from '../apply-execute';
|
|
49
|
+
import { estimateOpsRuntimeFit } from '../ops-fit';
|
|
50
|
+
import { resolveOperatorUrlViaStage } from '../direct-venue';
|
|
51
|
+
import { withMutationLease, MutationLeaseError } from '../mutation-lease';
|
|
52
|
+
import { readStageStateTwice, stageDestructiveRefusal } from '../stage-read-consistency';
|
|
53
|
+
import { step, success, fail, info, warn } from '../output';
|
|
54
54
|
|
|
55
55
|
// The apply core lives in apply-execute.ts (shared with the ops Lambda's
|
|
56
56
|
// db:apply action). Re-exported so the existing integration suites — and any
|
|
57
57
|
// other in-repo caller — keep importing it from this command module.
|
|
58
|
-
export { executeApplyPlan } from '../apply-execute
|
|
59
|
-
export type { ApplyPlanOptions, ApplyPlanResult } from '../apply-execute
|
|
58
|
+
export { executeApplyPlan } from '../apply-execute';
|
|
59
|
+
export type { ApplyPlanOptions, ApplyPlanResult } from '../apply-execute';
|
|
60
60
|
|
|
61
61
|
// ---------------------------------------------------------------------------
|
|
62
62
|
// The CLI shell.
|
|
@@ -210,7 +210,7 @@ async function applyPlanViaStage(
|
|
|
210
210
|
process.exit(1);
|
|
211
211
|
}
|
|
212
212
|
step(`Destructive authority: checking the approver set for stage ${flags.stage}...`);
|
|
213
|
-
const { parseAppName } = await import('../discover
|
|
213
|
+
const { parseAppName } = await import('../discover');
|
|
214
214
|
const appName = await parseAppName();
|
|
215
215
|
const approvers = await readApproverParam(region, appName, flags.stage);
|
|
216
216
|
const identity = approvers === null ? null : await resolveCallerIdentity(region);
|
|
@@ -368,7 +368,7 @@ export async function dbApplyCommand(flags: Record<string, string>): Promise<voi
|
|
|
368
368
|
}
|
|
369
369
|
if (flags.stage) {
|
|
370
370
|
const config = await resolveConfig(flags.stage);
|
|
371
|
-
const { parseAppName } = await import('../discover
|
|
371
|
+
const { parseAppName } = await import('../discover');
|
|
372
372
|
const appName = await parseAppName();
|
|
373
373
|
verifyAuthority = async () => {
|
|
374
374
|
step(`Destructive authority: checking the approver set for stage ${flags.stage}...`);
|
|
@@ -14,15 +14,15 @@
|
|
|
14
14
|
* path segments (`ty` matches `user/ty` and an assumed-role session `ty`).
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { resolveConfig } from '../config
|
|
17
|
+
import { resolveConfig } from '../config';
|
|
18
18
|
import {
|
|
19
19
|
approverParamName,
|
|
20
20
|
parseApproverValue,
|
|
21
21
|
readApproverParam,
|
|
22
22
|
writeApproverParam,
|
|
23
23
|
removeApproverParam,
|
|
24
|
-
} from '../apply-authority
|
|
25
|
-
import { step, success, fail, info, warn } from '../output
|
|
24
|
+
} from '../apply-authority';
|
|
25
|
+
import { step, success, fail, info, warn } from '../output';
|
|
26
26
|
|
|
27
27
|
export async function dbApproversCommand(flags: Record<string, string>): Promise<void> {
|
|
28
28
|
if (!flags.stage) {
|
|
@@ -32,7 +32,7 @@ export async function dbApproversCommand(flags: Record<string, string>): Promise
|
|
|
32
32
|
|
|
33
33
|
step('Resolving deployed config...');
|
|
34
34
|
const config = await resolveConfig(flags.stage);
|
|
35
|
-
const { parseAppName } = await import('../discover
|
|
35
|
+
const { parseAppName } = await import('../discover');
|
|
36
36
|
const appName = await parseAppName();
|
|
37
37
|
const paramName = approverParamName(appName, flags.stage);
|
|
38
38
|
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
diffContracts,
|
|
32
32
|
type QueryRunner,
|
|
33
33
|
type AuthzContract,
|
|
34
|
-
} from '../authz-contract
|
|
34
|
+
} from '../authz-contract';
|
|
35
35
|
import {
|
|
36
36
|
buildProbeSql,
|
|
37
37
|
PROBE_SELECT_SQL,
|
|
@@ -42,26 +42,26 @@ import {
|
|
|
42
42
|
toGrantGap,
|
|
43
43
|
buildInheritedPrivilegeSql,
|
|
44
44
|
toInheritedGrant,
|
|
45
|
-
} from '../authz-redteam
|
|
45
|
+
} from '../authz-redteam';
|
|
46
46
|
import {
|
|
47
47
|
buildOwnerProbeSql,
|
|
48
48
|
OWNER_PROBE_SELECT_SQL,
|
|
49
49
|
toOwnerProbeResult,
|
|
50
50
|
evaluateOwnerProbe,
|
|
51
51
|
type OwnerProbe,
|
|
52
|
-
} from '../authz-owner-probe
|
|
53
|
-
import { modelOwner } from '../authz-compile
|
|
54
|
-
import { writeContract, loadContract } from '../authz-contract-io
|
|
55
|
-
import { renderContractMarkdown } from '../authz-render
|
|
56
|
-
import { FUNCTIONS_SQL, contractFunctionRow } from '../security-catalog
|
|
57
|
-
import { resolveConfig, opsFunction } from '../config
|
|
58
|
-
import { resolveModelsPath } from '../models-path
|
|
59
|
-
import { resolveDbSource, connectingVia, createUrlProbeRunner } from '../db-source
|
|
60
|
-
import { borrowedSessionRunner, type SessionRunner } from '../session
|
|
61
|
-
import { invokeAction, lambdaQueryRunner, lambdaSessionRunner } from '../aws
|
|
62
|
-
import { step, success, fail, info, warn } from '../output
|
|
63
|
-
import { opsAdviceLines, IAM_ADVICE } from '../ops-advice
|
|
64
|
-
import { loadModels } from './db-generate
|
|
52
|
+
} from '../authz-owner-probe';
|
|
53
|
+
import { modelOwner } from '../authz-compile';
|
|
54
|
+
import { writeContract, loadContract } from '../authz-contract-io';
|
|
55
|
+
import { renderContractMarkdown } from '../authz-render';
|
|
56
|
+
import { FUNCTIONS_SQL, contractFunctionRow } from '../security-catalog';
|
|
57
|
+
import { resolveConfig, opsFunction } from '../config';
|
|
58
|
+
import { resolveModelsPath } from '../models-path';
|
|
59
|
+
import { resolveDbSource, connectingVia, createUrlProbeRunner } from '../db-source';
|
|
60
|
+
import { borrowedSessionRunner, type SessionRunner } from '../session';
|
|
61
|
+
import { invokeAction, lambdaQueryRunner, lambdaSessionRunner } from '../aws';
|
|
62
|
+
import { step, success, fail, info, warn } from '../output';
|
|
63
|
+
import { opsAdviceLines, IAM_ADVICE } from '../ops-advice';
|
|
64
|
+
import { loadModels } from './db-generate';
|
|
65
65
|
|
|
66
66
|
const DEFAULT_DIR = 'authz';
|
|
67
67
|
|
|
@@ -18,22 +18,22 @@
|
|
|
18
18
|
* reads and writes its own per-database record.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import type { QueryRunner } from '../authz-contract
|
|
21
|
+
import type { QueryRunner } from '../authz-contract';
|
|
22
22
|
import {
|
|
23
23
|
planBackfills,
|
|
24
24
|
readBackfillLog,
|
|
25
25
|
executeBackfills,
|
|
26
26
|
markBackfillApplied,
|
|
27
27
|
type BackfillPlan,
|
|
28
|
-
} from '../backfill
|
|
29
|
-
import { currentGitRef } from '../state-apply
|
|
30
|
-
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source
|
|
31
|
-
import { resolveOperatorUrlViaStage } from '../direct-venue
|
|
32
|
-
import { withMutationLease, MutationLeaseError } from '../mutation-lease
|
|
33
|
-
import { resolveConfig, opsFunction } from '../config
|
|
34
|
-
import { invokeAction } from '../aws
|
|
35
|
-
import { readSqlDirIfPresent } from './db-sync
|
|
36
|
-
import { step, success, fail, info, warn } from '../output
|
|
28
|
+
} from '../backfill';
|
|
29
|
+
import { currentGitRef } from '../state-apply';
|
|
30
|
+
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source';
|
|
31
|
+
import { resolveOperatorUrlViaStage } from '../direct-venue';
|
|
32
|
+
import { withMutationLease, MutationLeaseError } from '../mutation-lease';
|
|
33
|
+
import { resolveConfig, opsFunction } from '../config';
|
|
34
|
+
import { invokeAction } from '../aws';
|
|
35
|
+
import { readSqlDirIfPresent } from './db-sync';
|
|
36
|
+
import { step, success, fail, info, warn } from '../output';
|
|
37
37
|
|
|
38
38
|
const DEFAULT_DIR = 'db/backfills';
|
|
39
39
|
|
|
@@ -19,15 +19,16 @@ import { spawn } from 'node:child_process';
|
|
|
19
19
|
import { createGzip } from 'node:zlib';
|
|
20
20
|
import { pipeline } from 'node:stream/promises';
|
|
21
21
|
import { randomBytes } from 'node:crypto';
|
|
22
|
-
import { resolveConfig, opsFunction, type CliConfig } from '../config
|
|
23
|
-
import { invokeAction, presignGet, getS3 } from '../aws
|
|
22
|
+
import { resolveConfig, opsFunction, type CliConfig } from '../config';
|
|
23
|
+
import { invokeAction, presignGet, getS3 } from '../aws';
|
|
24
|
+
import { runStageBackup, stageBackupDeps } from '../stage-backup';
|
|
24
25
|
import {
|
|
25
26
|
parseBackupRef, keyForId, crossStageGuard, restoreTargetGuard,
|
|
26
27
|
backupKey, backupId, metaKey, utcStamp,
|
|
27
|
-
} from '../backup
|
|
28
|
-
import { pgEnvFromUrl, pgKeepaliveConninfo } from './db
|
|
29
|
-
import { pollTaskUntilStopped } from '../task-poll
|
|
30
|
-
import { step, success, fail, info, warn } from '../output
|
|
28
|
+
} from '../backup';
|
|
29
|
+
import { pgEnvFromUrl, pgKeepaliveConninfo } from './db';
|
|
30
|
+
import { pollTaskUntilStopped } from '../task-poll';
|
|
31
|
+
import { step, success, fail, info, warn } from '../output';
|
|
31
32
|
|
|
32
33
|
/** Which database db:backup dumps. LOCAL requires a target --stage (its bucket receives the upload
|
|
33
34
|
* AND names the backup id). Note this DIVERGES from db:export, where --database-url and --stage are
|
|
@@ -226,39 +227,27 @@ export async function dbBackupCommand(flags: Record<string, string>): Promise<vo
|
|
|
226
227
|
info(`Region: ${config.region}, Function: ${opsFunction(config)}`);
|
|
227
228
|
const fn = opsFunction(config);
|
|
228
229
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
if (dispatched?.error) {
|
|
238
|
-
fail(`Backup failed: ${dispatched.error}`);
|
|
239
|
-
process.exit(1);
|
|
240
|
-
}
|
|
241
|
-
const { runId, taskArn, id, warning } = dispatched as { runId: string; taskArn: string; id: string; warning?: string };
|
|
242
|
-
info(`backup ${id} — task ${taskArn}`);
|
|
243
|
-
info(`run id: ${runId} (everystack.task_log)`);
|
|
244
|
-
if (warning) info(`note: ${warning}`);
|
|
230
|
+
const result = await runStageBackup(stageBackupDeps(config, fn, flags.stage, {
|
|
231
|
+
onDispatch: (d) => {
|
|
232
|
+
info(`backup ${d.id} — task ${d.taskArn}`);
|
|
233
|
+
info(`run id: ${d.runId} (everystack.task_log)`);
|
|
234
|
+
// The dispatch warning is folded into result.warning and printed at the end, so printing it
|
|
235
|
+
// here too says the same thing twice.
|
|
236
|
+
},
|
|
237
|
+
}));
|
|
245
238
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
if (poll.outcome === 'error') {
|
|
253
|
-
fail(`task:status failed repeatedly: ${poll.status.error}. The backup may still be running — reconcile run id ${runId}.`);
|
|
254
|
-
process.exit(1);
|
|
255
|
-
}
|
|
256
|
-
if (poll.status.exitCode !== 0) {
|
|
257
|
-
fail(`Backup failed (exit ${poll.status.exitCode ?? 'unknown'})${poll.status.stoppedReason ? ` — ${poll.status.stoppedReason}` : ''}. Read the task logs (CloudWatch).`);
|
|
239
|
+
if (!result.ok) {
|
|
240
|
+
fail(`Backup failed: ${result.reason}`);
|
|
241
|
+
if (result.orphanKey) {
|
|
242
|
+
info(`The artifact is still in the bucket: s3://${config.backupsBucket ?? '<backups-bucket>'}/${result.orphanKey}`);
|
|
243
|
+
}
|
|
258
244
|
process.exit(1);
|
|
259
245
|
}
|
|
260
|
-
|
|
261
|
-
|
|
246
|
+
|
|
247
|
+
// Render it. The helper produced this and nothing printed it, so the one signal that an artifact
|
|
248
|
+
// was not verified against what the operator sent was invisible at the only moment it mattered.
|
|
249
|
+
if (result.warning) warn(result.warning);
|
|
250
|
+
success(`Backup ${result.id} (${fmtBytes(result.bytes)}). Restore with: everystack db:restore --from ${result.id} --confirm`);
|
|
262
251
|
}
|
|
263
252
|
|
|
264
253
|
/** db:backups — list a stage's logical backups. */
|
|
@@ -34,14 +34,14 @@ import {
|
|
|
34
34
|
templateName,
|
|
35
35
|
currentBranch,
|
|
36
36
|
localBranches,
|
|
37
|
-
} from '../branch-db
|
|
38
|
-
import { currentGitRef } from '../state-apply
|
|
39
|
-
import { fingerprintModels } from '../schema-fingerprint
|
|
40
|
-
import { resolveDbSource, type DbSource } from '../db-source
|
|
41
|
-
import { resolveModelsPath } from '../models-path
|
|
42
|
-
import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived
|
|
43
|
-
import { loadModels } from './db-generate
|
|
44
|
-
import { step, success, fail, info, warn } from '../output
|
|
37
|
+
} from '../branch-db';
|
|
38
|
+
import { currentGitRef } from '../state-apply';
|
|
39
|
+
import { fingerprintModels } from '../schema-fingerprint';
|
|
40
|
+
import { resolveDbSource, type DbSource } from '../db-source';
|
|
41
|
+
import { resolveModelsPath } from '../models-path';
|
|
42
|
+
import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived';
|
|
43
|
+
import { loadModels } from './db-generate';
|
|
44
|
+
import { step, success, fail, info, warn } from '../output';
|
|
45
45
|
|
|
46
46
|
function requireUrl(flags: Record<string, string>, verb: string): string {
|
|
47
47
|
let dbSource: DbSource;
|
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
import type { ModelDescriptor } from '@everystack/model';
|
|
28
|
-
import { buildIntoDatabase } from '../db-build
|
|
29
|
-
import { createUrlRunner } from '../db-source
|
|
30
|
-
import { resolveModelsPath } from '../models-path
|
|
31
|
-
import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived
|
|
32
|
-
import { loadModels } from './db-generate
|
|
33
|
-
import { currentGitRef } from '../state-apply
|
|
34
|
-
import { step, info, success, fail, warn } from '../output
|
|
28
|
+
import { buildIntoDatabase } from '../db-build';
|
|
29
|
+
import { createUrlRunner } from '../db-source';
|
|
30
|
+
import { resolveModelsPath } from '../models-path';
|
|
31
|
+
import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived';
|
|
32
|
+
import { loadModels } from './db-generate';
|
|
33
|
+
import { currentGitRef } from '../state-apply';
|
|
34
|
+
import { step, info, success, fail, warn } from '../output';
|
|
35
35
|
|
|
36
36
|
/** Tables already in the target, outside the schemas PostgreSQL owns. */
|
|
37
37
|
const OCCUPANCY_SQL = `
|
|
@@ -31,29 +31,29 @@
|
|
|
31
31
|
import fs from 'node:fs/promises';
|
|
32
32
|
import path from 'node:path';
|
|
33
33
|
import type { ModelDescriptor, DerivedDescriptor } from '@everystack/model';
|
|
34
|
-
import { compileDeclaredState } from '../declared-diff
|
|
35
|
-
import { compileMigration } from '../migration-compile
|
|
36
|
-
import { compileDrizzleSource } from '../schema-source
|
|
37
|
-
import { currentGitRef } from '../state-apply
|
|
38
|
-
import { createDatabase, dropDatabase, buildIntoDatabase, withDatabase } from '../db-build
|
|
39
|
-
import { resolveModelsPath } from '../models-path
|
|
40
|
-
import { loadModels, loadModules, readJournal, DEFAULT_MIGRATIONS } from './db-generate
|
|
41
|
-
import { resolveSchemaOut } from '../migration-generate
|
|
42
|
-
import { findUnexportedModels, scanModelDirectory, type ModelFileScan } from '../model-barrel-lint
|
|
43
|
-
import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived
|
|
34
|
+
import { compileDeclaredState } from '../declared-diff';
|
|
35
|
+
import { compileMigration } from '../migration-compile';
|
|
36
|
+
import { compileDrizzleSource } from '../schema-source';
|
|
37
|
+
import { currentGitRef } from '../state-apply';
|
|
38
|
+
import { createDatabase, dropDatabase, buildIntoDatabase, withDatabase } from '../db-build';
|
|
39
|
+
import { resolveModelsPath } from '../models-path';
|
|
40
|
+
import { loadModels, loadModules, readJournal, DEFAULT_MIGRATIONS } from './db-generate';
|
|
41
|
+
import { resolveSchemaOut } from '../migration-generate';
|
|
42
|
+
import { findUnexportedModels, scanModelDirectory, type ModelFileScan } from '../model-barrel-lint';
|
|
43
|
+
import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived';
|
|
44
44
|
import type { SequenceDescriptor } from '@everystack/model';
|
|
45
|
-
import type { SourceObject } from '../derived-source
|
|
46
|
-
import { findReadAuthzGaps, findNakedGrants } from '../authz-lint
|
|
47
|
-
import { parseBaseline, renderBaseline, BASELINE_FILE } from '../authz-baseline
|
|
45
|
+
import type { SourceObject } from '../derived-source';
|
|
46
|
+
import { findReadAuthzGaps, findNakedGrants } from '../authz-lint';
|
|
47
|
+
import { parseBaseline, renderBaseline, BASELINE_FILE } from '../authz-baseline';
|
|
48
48
|
import {
|
|
49
49
|
findDerivedReadGaps, findSecdefExecuteGaps, findMatviewSnapshotWarnings, findPublicExecutableSecdef,
|
|
50
50
|
findUnpinnedDefiners,
|
|
51
|
-
} from '../derived-lint
|
|
52
|
-
import { step, success, fail, info, warn } from '../output
|
|
51
|
+
} from '../derived-lint';
|
|
52
|
+
import { step, success, fail, info, warn } from '../output';
|
|
53
53
|
|
|
54
54
|
// The role derivation moved to the shared builder (db-build) with brick
|
|
55
55
|
// 5-remainder; re-exported here because db:check is where it grew up.
|
|
56
|
-
export { rolesFromContract } from '../db-build
|
|
56
|
+
export { rolesFromContract } from '../db-build';
|
|
57
57
|
|
|
58
58
|
const DEFAULT_SCHEMA_OUT = 'db/schema.generated.ts';
|
|
59
59
|
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import type { ModelDescriptor } from '@everystack/model';
|
|
27
|
-
import { diffDeclaredStates } from '../declared-diff
|
|
28
|
-
import { classifyGeneratedStatements } from '../state-apply
|
|
29
|
-
import { fingerprintModels } from '../schema-fingerprint
|
|
30
|
-
import { resolveModelsPath } from '../models-path
|
|
31
|
-
import { loadModels } from './db-generate
|
|
32
|
-
import { step, success, fail, info, warn } from '../output
|
|
27
|
+
import { diffDeclaredStates } from '../declared-diff';
|
|
28
|
+
import { classifyGeneratedStatements } from '../state-apply';
|
|
29
|
+
import { fingerprintModels } from '../schema-fingerprint';
|
|
30
|
+
import { resolveModelsPath } from '../models-path';
|
|
31
|
+
import { loadModels } from './db-generate';
|
|
32
|
+
import { step, success, fail, info, warn } from '../output';
|
|
33
33
|
|
|
34
34
|
export async function dbDiffCommand(flags: Record<string, string>): Promise<void> {
|
|
35
35
|
const fromPath = flags['from-models'];
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import fs from 'node:fs/promises';
|
|
19
|
-
import { resolveDbSource, sslDefaults } from '../db-source
|
|
20
|
-
import { resolveConfig, opsFunction } from '../config
|
|
21
|
-
import { invokeAction } from '../aws
|
|
22
|
-
import { isProductionTier } from '../backup
|
|
23
|
-
import { executeExec, assertNoTxnControl } from '../exec-execute
|
|
24
|
-
import { runExecInTx } from '../exec-run
|
|
25
|
-
import { ENSURE_EXEC_LOG_SQL, renderExecIntentInsert, renderExecOutcomeUpdate } from '../exec-log
|
|
26
|
-
import { step, success, fail, info } from '../output
|
|
19
|
+
import { resolveDbSource, sslDefaults } from '../db-source';
|
|
20
|
+
import { resolveConfig, opsFunction } from '../config';
|
|
21
|
+
import { invokeAction } from '../aws';
|
|
22
|
+
import { isProductionTier } from '../backup';
|
|
23
|
+
import { executeExec, assertNoTxnControl } from '../exec-execute';
|
|
24
|
+
import { runExecInTx } from '../exec-run';
|
|
25
|
+
import { ENSURE_EXEC_LOG_SQL, renderExecIntentInsert, renderExecOutcomeUpdate } from '../exec-log';
|
|
26
|
+
import { step, success, fail, info } from '../output';
|
|
27
27
|
|
|
28
28
|
async function readStdin(): Promise<string> {
|
|
29
29
|
const chunks: Buffer[] = [];
|
|
@@ -20,16 +20,16 @@ import path from 'node:path';
|
|
|
20
20
|
import { randomBytes } from 'node:crypto';
|
|
21
21
|
import { spawn } from 'node:child_process';
|
|
22
22
|
import type { ModelDescriptor } from '@everystack/model';
|
|
23
|
-
import { resolveConfig, opsFunction, type CliConfig } from '../config
|
|
24
|
-
import { invokeAction } from '../aws
|
|
25
|
-
import { fingerprintModels } from '../schema-fingerprint
|
|
26
|
-
import { resolveModelsPath } from '../models-path
|
|
27
|
-
import { loadModels } from './db-generate
|
|
28
|
-
import { loadDeclaredDerived } from '../declared-derived
|
|
29
|
-
import { pgEnvFromUrl, pgKeepaliveConninfo } from './db
|
|
30
|
-
import { utcStamp } from '../backup
|
|
31
|
-
import { pollTaskUntilStopped } from '../task-poll
|
|
32
|
-
import { step, success, fail, info } from '../output
|
|
23
|
+
import { resolveConfig, opsFunction, type CliConfig } from '../config';
|
|
24
|
+
import { invokeAction } from '../aws';
|
|
25
|
+
import { fingerprintModels } from '../schema-fingerprint';
|
|
26
|
+
import { resolveModelsPath } from '../models-path';
|
|
27
|
+
import { loadModels } from './db-generate';
|
|
28
|
+
import { loadDeclaredDerived } from '../declared-derived';
|
|
29
|
+
import { pgEnvFromUrl, pgKeepaliveConninfo } from './db';
|
|
30
|
+
import { utcStamp } from '../backup';
|
|
31
|
+
import { pollTaskUntilStopped } from '../task-poll';
|
|
32
|
+
import { step, success, fail, info } from '../output';
|
|
33
33
|
|
|
34
34
|
const fmtBytes = (b?: number): string =>
|
|
35
35
|
b == null ? '?' : b >= 1024 ** 3 ? `${(b / 1024 ** 3).toFixed(1)} GB` : b >= 1024 ** 2 ? `${(b / 1024 ** 2).toFixed(1)} MB` : `${(b / 1024).toFixed(0)} KB`;
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
import { existsSync } from 'node:fs';
|
|
16
16
|
import type { ModelDescriptor } from '@everystack/model';
|
|
17
|
-
import type { QueryRunner } from '../authz-contract
|
|
18
|
-
import { introspectSchema } from '../schema-introspect
|
|
19
|
-
import { introspectContract } from '../authz-contract
|
|
20
|
-
import { FUNCTIONS_SQL, contractFunctionRow } from '../security-catalog
|
|
17
|
+
import type { QueryRunner } from '../authz-contract';
|
|
18
|
+
import { introspectSchema } from '../schema-introspect';
|
|
19
|
+
import { introspectContract } from '../authz-contract';
|
|
20
|
+
import { FUNCTIONS_SQL, contractFunctionRow } from '../security-catalog';
|
|
21
21
|
import {
|
|
22
22
|
fingerprintLive,
|
|
23
23
|
fingerprintModels,
|
|
@@ -25,16 +25,16 @@ import {
|
|
|
25
25
|
mapUnfingerprintedRows,
|
|
26
26
|
UNFINGERPRINTED_SQL,
|
|
27
27
|
type UnfingerprintedObject,
|
|
28
|
-
} from '../schema-fingerprint
|
|
29
|
-
import { predictLiveFingerprint, governedLiveFingerprint } from '../edge-plan
|
|
30
|
-
import { resolveModelsPath } from '../models-path
|
|
31
|
-
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source
|
|
32
|
-
import { borrowedSessionRunner, INTROSPECTION_SESSION, type SessionRunner } from '../session
|
|
33
|
-
import { resolveConfig, opsFunction } from '../config
|
|
34
|
-
import { invokeAction, lambdaQueryRunner, lambdaSessionRunner } from '../aws
|
|
35
|
-
import { step, success, fail, info, warn } from '../output
|
|
36
|
-
import { loadModels } from './db-generate
|
|
37
|
-
import { loadDeclaredDerived } from '../declared-derived
|
|
28
|
+
} from '../schema-fingerprint';
|
|
29
|
+
import { predictLiveFingerprint, governedLiveFingerprint } from '../edge-plan';
|
|
30
|
+
import { resolveModelsPath } from '../models-path';
|
|
31
|
+
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source';
|
|
32
|
+
import { borrowedSessionRunner, INTROSPECTION_SESSION, type SessionRunner } from '../session';
|
|
33
|
+
import { resolveConfig, opsFunction } from '../config';
|
|
34
|
+
import { invokeAction, lambdaQueryRunner, lambdaSessionRunner } from '../aws';
|
|
35
|
+
import { step, success, fail, info, warn } from '../output';
|
|
36
|
+
import { loadModels } from './db-generate';
|
|
37
|
+
import { loadDeclaredDerived } from '../declared-derived';
|
|
38
38
|
import type { SequenceDescriptor } from '@everystack/model';
|
|
39
39
|
|
|
40
40
|
export interface FingerprintStatus {
|
|
@@ -19,11 +19,12 @@
|
|
|
19
19
|
* data-governance warning. Teardown is the stage's own: `sst remove`.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
import { resolveConfig, opsFunction, type CliConfig } from '../config
|
|
23
|
-
import { invokeAction, presignGet } from '../aws
|
|
24
|
-
import { keyForId, parseBackupRef, isProductionTier, crossStageGuard } from '../backup
|
|
25
|
-
import { pollTaskUntilStopped } from '../task-poll
|
|
26
|
-
import {
|
|
22
|
+
import { resolveConfig, opsFunction, type CliConfig } from '../config';
|
|
23
|
+
import { invokeAction, presignGet } from '../aws';
|
|
24
|
+
import { keyForId, parseBackupRef, isProductionTier, crossStageGuard } from '../backup';
|
|
25
|
+
import { pollTaskUntilStopped } from '../task-poll';
|
|
26
|
+
import { runStageBackup, stageBackupDeps } from '../stage-backup';
|
|
27
|
+
import { step, success, fail, info, warn } from '../output';
|
|
27
28
|
|
|
28
29
|
export type ForkGuardVerdict =
|
|
29
30
|
| { ok: true; piiWarning: string | null }
|
|
@@ -94,18 +95,17 @@ export async function dbForkCommand(flags: Record<string, string>): Promise<void
|
|
|
94
95
|
info(`Reusing backup ${backupId}.`);
|
|
95
96
|
} else {
|
|
96
97
|
step(`Backing up ${from} (pg_dump → S3 in the Task; may take a while for large databases)...`);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (poll.outcome !== 'stopped' || poll.status.exitCode !== 0) {
|
|
105
|
-
const why = poll.outcome === 'stopped' ? `exit ${poll.status.exitCode}${poll.status.stoppedReason ? ` — ${poll.status.stoppedReason}` : ''}` : poll.outcome;
|
|
106
|
-
fail(`Source backup failed (${why}). Reconcile run ${dispatched.runId}.`);
|
|
98
|
+
// The shared sandwich: a fork built from a dump that spans a migration copies a schema that
|
|
99
|
+
// never existed. Same helper db:backup and db:swap use, so all three agree on what a proven
|
|
100
|
+
// artifact is.
|
|
101
|
+
const backup = await runStageBackup(stageBackupDeps(source, opsFunction(source), from, { onStep: step }));
|
|
102
|
+
if (!backup.ok) {
|
|
103
|
+
fail(`Source backup failed: ${backup.reason} The fork was NOT created.`);
|
|
104
|
+
if (backup.orphanKey) info(`The artifact is still in the bucket: s3://${source.backupsBucket}/${backup.orphanKey}`);
|
|
107
105
|
process.exit(1);
|
|
108
106
|
}
|
|
107
|
+
backupId = backup.id;
|
|
108
|
+
if (backup.warning) warn(backup.warning);
|
|
109
109
|
info(`Backup ${backupId}.`);
|
|
110
110
|
}
|
|
111
111
|
|
|
@@ -23,25 +23,25 @@ import fs from 'node:fs/promises';
|
|
|
23
23
|
import path from 'node:path';
|
|
24
24
|
import { pathToFileURL } from 'node:url';
|
|
25
25
|
import type { ModelDescriptor, Module } from '@everystack/model';
|
|
26
|
-
import { introspectSchema } from '../schema-introspect
|
|
27
|
-
import { compileDrizzleSource } from '../schema-source
|
|
28
|
-
import { compileModuleMigration } from '../migration-compile
|
|
29
|
-
import { generateMigrationSql, unmodeledTables, formatMigrationFile, planMigrationFile, resolveSchemaOut, HELD_DROP_PREFIX, type Journal } from '../migration-generate
|
|
30
|
-
import { introspectContract, type QueryRunner, type AuthzContract } from '../authz-contract
|
|
31
|
-
import { compileTableContract } from '../authz-compile
|
|
32
|
-
import { governedRoleSet, ungovernedGrants, renderGrantExemptions } from '../authz-reconcile
|
|
33
|
-
import { classifyAdoption, renderAdoptionReport } from '../authz-adoption-class
|
|
34
|
-
import { introspectTableOwners, buildOwnershipReport, renderOwnershipReport, type TableOwner } from '../authz-ownership
|
|
35
|
-
import { FUNCTIONS_SQL, contractFunctionRow } from '../security-catalog
|
|
36
|
-
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source
|
|
37
|
-
import { borrowedSessionRunner, type SessionRunner } from '../session
|
|
38
|
-
import { resolveModelsPath } from '../models-path
|
|
39
|
-
import { loadDeclaredDerived, assertNoHoles, type DeclaredDerived } from '../declared-derived
|
|
40
|
-
import { asModelComposeError, opsAdviceLines } from '../ops-advice
|
|
41
|
-
import { applyStateAndVerify, classifyGeneratedStatements, renderStatementHistogram, currentGitRef, type StateSyncOutcome } from '../state-apply
|
|
42
|
-
import { resolveConfig, opsFunction } from '../config
|
|
43
|
-
import { invokeAction, lambdaQueryRunner, lambdaSessionRunner } from '../aws
|
|
44
|
-
import { step, success, fail, info, warn } from '../output
|
|
26
|
+
import { introspectSchema } from '../schema-introspect';
|
|
27
|
+
import { compileDrizzleSource } from '../schema-source';
|
|
28
|
+
import { compileModuleMigration } from '../migration-compile';
|
|
29
|
+
import { generateMigrationSql, unmodeledTables, formatMigrationFile, planMigrationFile, resolveSchemaOut, HELD_DROP_PREFIX, type Journal } from '../migration-generate';
|
|
30
|
+
import { introspectContract, type QueryRunner, type AuthzContract } from '../authz-contract';
|
|
31
|
+
import { compileTableContract } from '../authz-compile';
|
|
32
|
+
import { governedRoleSet, ungovernedGrants, renderGrantExemptions } from '../authz-reconcile';
|
|
33
|
+
import { classifyAdoption, renderAdoptionReport } from '../authz-adoption-class';
|
|
34
|
+
import { introspectTableOwners, buildOwnershipReport, renderOwnershipReport, type TableOwner } from '../authz-ownership';
|
|
35
|
+
import { FUNCTIONS_SQL, contractFunctionRow } from '../security-catalog';
|
|
36
|
+
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source';
|
|
37
|
+
import { borrowedSessionRunner, type SessionRunner } from '../session';
|
|
38
|
+
import { resolveModelsPath } from '../models-path';
|
|
39
|
+
import { loadDeclaredDerived, assertNoHoles, type DeclaredDerived } from '../declared-derived';
|
|
40
|
+
import { asModelComposeError, opsAdviceLines } from '../ops-advice';
|
|
41
|
+
import { applyStateAndVerify, classifyGeneratedStatements, renderStatementHistogram, currentGitRef, type StateSyncOutcome } from '../state-apply';
|
|
42
|
+
import { resolveConfig, opsFunction } from '../config';
|
|
43
|
+
import { invokeAction, lambdaQueryRunner, lambdaSessionRunner } from '../aws';
|
|
44
|
+
import { step, success, fail, info, warn } from '../output';
|
|
45
45
|
|
|
46
46
|
export const DEFAULT_MIGRATIONS = 'drizzle';
|
|
47
47
|
const DEFAULT_SCHEMA_OUT = 'db/schema.generated.ts';
|