@everystack/cli 0.4.60 → 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 +7 -7
- 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 +6 -6
- 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 +26 -26
- 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 +3 -3
- 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
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
* runs it direct. A stage DRY-RUN (no `--apply`) reads through the `db:query` path.
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
|
-
import type { QueryRunner } from '../authz-contract
|
|
33
|
-
import type { SourceObject } from '../derived-source
|
|
34
|
-
import { introspectDerived } from '../derived-introspect
|
|
35
|
-
import { planReconcile, type ReconcilePlan, type ReconcileOptions } from '../derived-plan
|
|
32
|
+
import type { QueryRunner } from '../authz-contract';
|
|
33
|
+
import type { SourceObject } from '../derived-source';
|
|
34
|
+
import { introspectDerived } from '../derived-introspect';
|
|
35
|
+
import { planReconcile, type ReconcilePlan, type ReconcileOptions } from '../derived-plan';
|
|
36
36
|
import {
|
|
37
37
|
renderReconcileSql,
|
|
38
38
|
renderProvenanceUpsert,
|
|
@@ -49,16 +49,16 @@ import {
|
|
|
49
49
|
builderOwnerMode,
|
|
50
50
|
type OwnerApplyMode,
|
|
51
51
|
ENSURE_RECONCILER_SQL,
|
|
52
|
-
} from '../derived-apply
|
|
53
|
-
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source
|
|
54
|
-
import { borrowedSessionRunner, type SessionRunner } from '../session
|
|
55
|
-
import { resolveOperatorUrlViaStage } from '../direct-venue
|
|
56
|
-
import { withMutationLease, MutationLeaseError } from '../mutation-lease
|
|
57
|
-
import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived
|
|
58
|
-
import { currentGitRef } from '../state-apply
|
|
59
|
-
import { resolveConfig, opsFunction } from '../config
|
|
60
|
-
import { invokeAction, lambdaQueryRunner, lambdaSessionRunner } from '../aws
|
|
61
|
-
import { step, success, fail, info, warn } from '../output
|
|
52
|
+
} from '../derived-apply';
|
|
53
|
+
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source';
|
|
54
|
+
import { borrowedSessionRunner, type SessionRunner } from '../session';
|
|
55
|
+
import { resolveOperatorUrlViaStage } from '../direct-venue';
|
|
56
|
+
import { withMutationLease, MutationLeaseError } from '../mutation-lease';
|
|
57
|
+
import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived';
|
|
58
|
+
import { currentGitRef } from '../state-apply';
|
|
59
|
+
import { resolveConfig, opsFunction } from '../config';
|
|
60
|
+
import { invokeAction, lambdaQueryRunner, lambdaSessionRunner } from '../aws';
|
|
61
|
+
import { step, success, fail, info, warn } from '../output';
|
|
62
62
|
|
|
63
63
|
// ---------------------------------------------------------------------------
|
|
64
64
|
// The testable core.
|
|
@@ -23,13 +23,13 @@
|
|
|
23
23
|
* they did not choose.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source
|
|
27
|
-
import { loadDeclaredDerived } from '../declared-derived
|
|
28
|
-
import { executeRefresh, matviewIdentities, type RefreshRun } from '../refresh-execute
|
|
29
|
-
import { resolveConfig, opsFunction } from '../config
|
|
30
|
-
import { resolveOperatorUrlViaStage } from '../direct-venue
|
|
31
|
-
import { invokeAction } from '../aws
|
|
32
|
-
import { step, success, fail, info } from '../output
|
|
26
|
+
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source';
|
|
27
|
+
import { loadDeclaredDerived } from '../declared-derived';
|
|
28
|
+
import { executeRefresh, matviewIdentities, type RefreshRun } from '../refresh-execute';
|
|
29
|
+
import { resolveConfig, opsFunction } from '../config';
|
|
30
|
+
import { resolveOperatorUrlViaStage } from '../direct-venue';
|
|
31
|
+
import { invokeAction } from '../aws';
|
|
32
|
+
import { step, success, fail, info } from '../output';
|
|
33
33
|
|
|
34
34
|
export async function dbRefreshCommand(flags: Record<string, string>): Promise<void> {
|
|
35
35
|
// The declared matviews, in dependency order (a dependent matview reads its parents' fresh rows).
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
* docs/plans/db-backup-restore.md.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { resolveConfig, type CliConfig } from '../config
|
|
11
|
-
import { createRdsSnapshot, describeRdsSnapshots, type RdsSnapshotSummary } from '../aws
|
|
12
|
-
import { utcStamp } from '../backup
|
|
13
|
-
import { rdsSnapshotIdentifier } from '../rds-snapshot
|
|
14
|
-
import { step, success, fail, info } from '../output
|
|
10
|
+
import { resolveConfig, type CliConfig } from '../config';
|
|
11
|
+
import { createRdsSnapshot, describeRdsSnapshots, type RdsSnapshotSummary } from '../aws';
|
|
12
|
+
import { utcStamp } from '../backup';
|
|
13
|
+
import { rdsSnapshotIdentifier } from '../rds-snapshot';
|
|
14
|
+
import { step, success, fail, info } from '../output';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Resolve the RDS DB instance identifier: explicit `--instance` wins, else the deployed
|
|
@@ -22,32 +22,32 @@ import { Transform } from 'node:stream';
|
|
|
22
22
|
import { pipeline } from 'node:stream/promises';
|
|
23
23
|
import { Readable } from 'node:stream';
|
|
24
24
|
import type { ModelDescriptor } from '@everystack/model';
|
|
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 type { SourceObject } from '../derived-source
|
|
30
|
-
import { pairedDerivedSchemas, renderPairedDerivedBuild, renderSwapSchemaUsage, swapSchemaRoles, expectedIncomingObjects, renderPairedProvenance } from '../swap-pair
|
|
31
|
-
import { introspectDerived } from '../derived-introspect
|
|
32
|
-
import { legacyFunctionIdentity } from '../pg-argtypes
|
|
33
|
-
import { createUrlRunner } from '../db-source
|
|
34
|
-
import { borrowedSessionRunner, type SessionRunner } from '../session
|
|
35
|
-
import type { QueryRunner } from '../authz-contract
|
|
36
|
-
import { executeSwap, type SwapVerdict } from '../swap-execute
|
|
37
|
-
import { startHeartbeat, humanElapsed } from '../swap-heartbeat
|
|
38
|
-
import { formatBytes } from '../bundle-weight
|
|
39
|
-
import { rewriteStatementLine, opensCopyData, closesCopyData } from '../schema-rewrite
|
|
40
|
-
import { resolveOperatorUrlViaStage } from '../direct-venue
|
|
41
|
-
import { withMutationLease, MutationLeaseError } from '../mutation-lease
|
|
42
|
-
import { resolveConfig, opsFunction, type CliConfig } from '../config
|
|
43
|
-
import { invokeAction, presignGet, createRdsSnapshot, describeRdsSnapshots } from '../aws
|
|
44
|
-
import { keyForArtifactId, metaKey, utcStamp } from '../backup
|
|
45
|
-
import { rdsSnapshotIdentifier } from '../rds-snapshot
|
|
46
|
-
import { pollTaskUntilStopped } from '../task-poll
|
|
47
|
-
import { decideSnapshotMode, confirmPhysicalSnapshot, interpretBackupPoll, type SnapshotModeRequest } from '../swap-snapshot
|
|
48
|
-
import { runStageBackup, stageBackupDeps } from '../stage-backup
|
|
49
|
-
import { pgEnvFromUrl, pgKeepaliveConninfo } from './db
|
|
50
|
-
import { step, success, fail, warn, info } from '../output
|
|
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 type { SourceObject } from '../derived-source';
|
|
30
|
+
import { pairedDerivedSchemas, renderPairedDerivedBuild, renderSwapSchemaUsage, swapSchemaRoles, expectedIncomingObjects, renderPairedProvenance } from '../swap-pair';
|
|
31
|
+
import { introspectDerived } from '../derived-introspect';
|
|
32
|
+
import { legacyFunctionIdentity } from '../pg-argtypes';
|
|
33
|
+
import { createUrlRunner } from '../db-source';
|
|
34
|
+
import { borrowedSessionRunner, type SessionRunner } from '../session';
|
|
35
|
+
import type { QueryRunner } from '../authz-contract';
|
|
36
|
+
import { executeSwap, type SwapVerdict } from '../swap-execute';
|
|
37
|
+
import { startHeartbeat, humanElapsed } from '../swap-heartbeat';
|
|
38
|
+
import { formatBytes } from '../bundle-weight';
|
|
39
|
+
import { rewriteStatementLine, opensCopyData, closesCopyData } from '../schema-rewrite';
|
|
40
|
+
import { resolveOperatorUrlViaStage } from '../direct-venue';
|
|
41
|
+
import { withMutationLease, MutationLeaseError } from '../mutation-lease';
|
|
42
|
+
import { resolveConfig, opsFunction, type CliConfig } from '../config';
|
|
43
|
+
import { invokeAction, presignGet, createRdsSnapshot, describeRdsSnapshots } from '../aws';
|
|
44
|
+
import { keyForArtifactId, metaKey, utcStamp } from '../backup';
|
|
45
|
+
import { rdsSnapshotIdentifier } from '../rds-snapshot';
|
|
46
|
+
import { pollTaskUntilStopped } from '../task-poll';
|
|
47
|
+
import { decideSnapshotMode, confirmPhysicalSnapshot, interpretBackupPoll, type SnapshotModeRequest } from '../swap-snapshot';
|
|
48
|
+
import { runStageBackup, stageBackupDeps } from '../stage-backup';
|
|
49
|
+
import { pgEnvFromUrl, pgKeepaliveConninfo } from './db';
|
|
50
|
+
import { step, success, fail, warn, info } from '../output';
|
|
51
51
|
|
|
52
52
|
/** A COPY-aware line transform that rewrites the schema token on statement lines only. */
|
|
53
53
|
function schemaRewriteStream(from: string, to: string): Transform {
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
import fs from 'node:fs/promises';
|
|
31
31
|
import path from 'node:path';
|
|
32
32
|
import type { ModelDescriptor } from '@everystack/model';
|
|
33
|
-
import { introspectContract, type QueryRunner } from '../authz-contract
|
|
34
|
-
import { introspectSchema } from '../schema-introspect
|
|
35
|
-
import { FUNCTIONS_SQL, contractFunctionRow } from '../security-catalog
|
|
36
|
-
import { generateMigrationSql, unmodeledTables } from '../migration-generate
|
|
33
|
+
import { introspectContract, type QueryRunner } from '../authz-contract';
|
|
34
|
+
import { introspectSchema } from '../schema-introspect';
|
|
35
|
+
import { FUNCTIONS_SQL, contractFunctionRow } from '../security-catalog';
|
|
36
|
+
import { generateMigrationSql, unmodeledTables } from '../migration-generate';
|
|
37
37
|
import type { SequenceDescriptor } from '@everystack/model';
|
|
38
|
-
import type { SourceObject } from '../derived-source
|
|
38
|
+
import type { SourceObject } from '../derived-source';
|
|
39
39
|
import {
|
|
40
40
|
applyStateAndVerify,
|
|
41
41
|
classifyGeneratedStatements,
|
|
@@ -43,19 +43,19 @@ import {
|
|
|
43
43
|
currentGitRef,
|
|
44
44
|
type ClassifiedStatements,
|
|
45
45
|
type StateSyncOutcome,
|
|
46
|
-
} from '../state-apply
|
|
47
|
-
import { fingerprintModels } from '../schema-fingerprint
|
|
48
|
-
import { compileDrizzleSource } from '../schema-source
|
|
49
|
-
import type { SourceFile } from '../derived-source
|
|
50
|
-
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source
|
|
51
|
-
import { borrowedSessionRunner, type SessionRunner } from '../session
|
|
52
|
-
import { planBackfills, readBackfillLog } from '../backfill
|
|
53
|
-
import { resolveModelsPath } from '../models-path
|
|
54
|
-
import { executeReconcile, buildReconcileReport, type ReconcileRun } from './db-reconcile
|
|
55
|
-
import { loadModels } from './db-generate
|
|
56
|
-
import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived
|
|
57
|
-
import { reportPipelineLastRun } from './pipeline-run
|
|
58
|
-
import { step, success, fail, info, warn } from '../output
|
|
46
|
+
} from '../state-apply';
|
|
47
|
+
import { fingerprintModels } from '../schema-fingerprint';
|
|
48
|
+
import { compileDrizzleSource } from '../schema-source';
|
|
49
|
+
import type { SourceFile } from '../derived-source';
|
|
50
|
+
import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source';
|
|
51
|
+
import { borrowedSessionRunner, type SessionRunner } from '../session';
|
|
52
|
+
import { planBackfills, readBackfillLog } from '../backfill';
|
|
53
|
+
import { resolveModelsPath } from '../models-path';
|
|
54
|
+
import { executeReconcile, buildReconcileReport, type ReconcileRun } from './db-reconcile';
|
|
55
|
+
import { loadModels } from './db-generate';
|
|
56
|
+
import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived';
|
|
57
|
+
import { reportPipelineLastRun } from './pipeline-run';
|
|
58
|
+
import { step, success, fail, info, warn } from '../output';
|
|
59
59
|
|
|
60
60
|
const DEFAULT_SCHEMA_OUT = 'db/schema.generated.ts';
|
|
61
61
|
|
package/src/cli/commands/db.ts
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* No HTTP endpoints, no shared secrets — IAM is the authorization layer.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { resolveConfig, opsFunction } from '../config
|
|
9
|
-
import { invokeAction } from '../aws
|
|
10
|
-
import { step, success, fail, info, warn } from '../output
|
|
11
|
-
import { opsAdviceLines, IAM_ADVICE } from '../ops-advice
|
|
8
|
+
import { resolveConfig, opsFunction } from '../config';
|
|
9
|
+
import { invokeAction } from '../aws';
|
|
10
|
+
import { step, success, fail, info, warn } from '../output';
|
|
11
|
+
import { opsAdviceLines, IAM_ADVICE } from '../ops-advice';
|
|
12
12
|
|
|
13
13
|
/** Secret-store keys that may hold the privileged (operator) connection URL,
|
|
14
14
|
* in precedence order. Names vary by deployment; --secret-name overrides. */
|
|
@@ -488,8 +488,8 @@ export async function dbProvisionCommand(flags: Record<string, string>): Promise
|
|
|
488
488
|
|
|
489
489
|
// Load the stage secrets once — the direct venue reads the privileged URL from here (never
|
|
490
490
|
// from argv), and the writer below reuses them.
|
|
491
|
-
const { loadSstSecrets, putSstSecrets } = await import('../utils/secrets
|
|
492
|
-
const { parseAppName } = await import('../discover
|
|
491
|
+
const { loadSstSecrets, putSstSecrets } = await import('../utils/secrets');
|
|
492
|
+
const { parseAppName } = await import('../discover');
|
|
493
493
|
const secretsCtx = { appName: await parseAppName(), stage: flags.stage, region: config.region };
|
|
494
494
|
let stageSecrets: Record<string, string> = {};
|
|
495
495
|
try {
|
|
@@ -527,12 +527,12 @@ export async function dbProvisionCommand(flags: Record<string, string>): Promise
|
|
|
527
527
|
// all-public app sets no path (unchanged behavior).
|
|
528
528
|
let declaredSchemas: string[] = [];
|
|
529
529
|
try {
|
|
530
|
-
const { resolveModelsPath } = await import('../models-path
|
|
531
|
-
const { loadModels } = await import('./db-generate
|
|
530
|
+
const { resolveModelsPath } = await import('../models-path');
|
|
531
|
+
const { loadModels } = await import('./db-generate');
|
|
532
532
|
const models = await loadModels(resolveModelsPath(flags.models));
|
|
533
533
|
let derivedObjects: Array<{ schema: string }> = [];
|
|
534
534
|
try {
|
|
535
|
-
const { loadDeclaredDerived } = await import('../declared-derived
|
|
535
|
+
const { loadDeclaredDerived } = await import('../declared-derived');
|
|
536
536
|
const declared = await loadDeclaredDerived(flags.models);
|
|
537
537
|
if (declared) derivedObjects = declared.objects;
|
|
538
538
|
} catch {
|
|
@@ -555,7 +555,7 @@ export async function dbProvisionCommand(flags: Record<string, string>): Promise
|
|
|
555
555
|
// and the auto-fallback below.
|
|
556
556
|
const provisionDirect = async (url: string): Promise<any> => {
|
|
557
557
|
const { runProvision } = await loadServerProvision();
|
|
558
|
-
const { createUrlRunner } = await import('../db-source
|
|
558
|
+
const { createUrlRunner } = await import('../db-source');
|
|
559
559
|
const { runner, end } = await createUrlRunner(url);
|
|
560
560
|
try {
|
|
561
561
|
return await runProvision({ authPassword, adminPassword, searchPath }, {
|
|
@@ -746,7 +746,7 @@ function printDoctorReport(report: any): void {
|
|
|
746
746
|
*/
|
|
747
747
|
async function runDoctorDirect(apiUrl: string, adminUrl: string, sourceLabel: string): Promise<boolean> {
|
|
748
748
|
const { runDoctorProbe } = await loadServerDoctor();
|
|
749
|
-
const { createUrlRunner } = await import('../db-source
|
|
749
|
+
const { createUrlRunner } = await import('../db-source');
|
|
750
750
|
step('Probing database connections (api + operator)...');
|
|
751
751
|
const apiConn = await createUrlRunner(apiUrl);
|
|
752
752
|
const opsConn = await createUrlRunner(adminUrl);
|
|
@@ -797,8 +797,8 @@ export async function dbDoctorCommand(flags: Record<string, string>): Promise<vo
|
|
|
797
797
|
|
|
798
798
|
// Load the stage secrets once — the direct venue (--direct, and the no-Ops auto-fallback)
|
|
799
799
|
// reads DATABASE_URL + ADMIN_DATABASE_URL from here, never from argv.
|
|
800
|
-
const { loadSstSecrets } = await import('../utils/secrets
|
|
801
|
-
const { parseAppName } = await import('../discover
|
|
800
|
+
const { loadSstSecrets } = await import('../utils/secrets');
|
|
801
|
+
const { parseAppName } = await import('../discover');
|
|
802
802
|
let stageSecrets: Record<string, string> = {};
|
|
803
803
|
try {
|
|
804
804
|
stageSecrets = await loadSstSecrets({ appName: await parseAppName(), stage: flags.stage, region: config.region });
|
|
@@ -957,8 +957,8 @@ export async function dbPsqlCommand(flags: Record<string, string>): Promise<void
|
|
|
957
957
|
step('Resolving the admin connection from the secret store...');
|
|
958
958
|
let secrets: Record<string, string>;
|
|
959
959
|
try {
|
|
960
|
-
const { loadSstSecrets } = await import('../utils/secrets
|
|
961
|
-
const { parseAppName } = await import('../discover
|
|
960
|
+
const { loadSstSecrets } = await import('../utils/secrets');
|
|
961
|
+
const { parseAppName } = await import('../discover');
|
|
962
962
|
const appName = await parseAppName();
|
|
963
963
|
secrets = await loadSstSecrets({ appName, stage: flags.stage, region: config.region });
|
|
964
964
|
} catch (err: any) {
|
|
@@ -11,10 +11,11 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { spawn } from 'node:child_process';
|
|
14
|
-
import { step, success, fail, info, warn } from '../output
|
|
15
|
-
import { invalidateCachedConfig } from '../discover
|
|
16
|
-
import { resolveConfig } from '../config
|
|
17
|
-
import { probeDeployedFunctions } from '../deploy-probe
|
|
14
|
+
import { step, success, fail, info, warn } from '../output';
|
|
15
|
+
import { invalidateCachedConfig } from '../discover';
|
|
16
|
+
import { resolveConfig } from '../config';
|
|
17
|
+
import { probeDeployedFunctions } from '../deploy-probe';
|
|
18
|
+
import { getDistributionStatus } from '../aws';
|
|
18
19
|
|
|
19
20
|
/** The `sst` argv `everystack deploy` runs. Pure, so the mapping is unit-tested. */
|
|
20
21
|
export function buildDeployArgs(flags: Record<string, string>): string[] {
|
|
@@ -68,8 +69,9 @@ export async function deployCommand(flags: Record<string, string>): Promise<void
|
|
|
68
69
|
// `sst deploy` exiting 0 only proves the code UPLOADED — a bundle that crashes at INIT still
|
|
69
70
|
// deploys "green" and takes the whole ops plane down until the next verb trips over it. Probe
|
|
70
71
|
// the deployed functions now so the operator learns here, with the real cause attached.
|
|
72
|
+
let config: Awaited<ReturnType<typeof resolveConfig>> | undefined;
|
|
71
73
|
try {
|
|
72
|
-
|
|
74
|
+
config = await resolveConfig(stage);
|
|
73
75
|
const { fatal } = await probeDeployedFunctions(stage, config);
|
|
74
76
|
if (fatal) {
|
|
75
77
|
fail('Deploy landed, but a deployed function cannot serve — every --stage verb will fail until this is fixed and redeployed.');
|
|
@@ -81,8 +83,40 @@ export async function deployCommand(flags: Record<string, string>): Promise<void
|
|
|
81
83
|
info(`Skipped the post-deploy probe: ${err?.message ?? err}`);
|
|
82
84
|
}
|
|
83
85
|
|
|
86
|
+
// Wait for CloudFront distribution to finish propagating.
|
|
87
|
+
if (config?.distributionId) {
|
|
88
|
+
step('Waiting for CloudFront distribution...');
|
|
89
|
+
const deployed = await waitForDistribution(config.region, config.distributionId);
|
|
90
|
+
if (deployed) {
|
|
91
|
+
success('Distribution deployed.');
|
|
92
|
+
} else {
|
|
93
|
+
warn('Distribution did not reach Deployed within timeout. It may still be propagating.');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
84
97
|
// The 0.4 flow: schema changes ride db:plan → db:apply. Migration-based apps still have
|
|
85
98
|
// db:migrate, but the copy-paste hint must advertise the canonical path — this exact
|
|
86
99
|
// line got copied into consumer runbooks with the retired verb.
|
|
87
100
|
info('Next: schema changes via `everystack db:plan --stage ' + stage + '` → `db:apply`; `everystack update` to publish the app bundle.');
|
|
88
101
|
}
|
|
102
|
+
|
|
103
|
+
const DISTRIBUTION_POLL_MS = 10_000;
|
|
104
|
+
const DISTRIBUTION_TIMEOUT_MS = 300_000;
|
|
105
|
+
|
|
106
|
+
/** @internal Exported for testing. */
|
|
107
|
+
export async function waitForDistribution(
|
|
108
|
+
region: string,
|
|
109
|
+
distributionId: string,
|
|
110
|
+
): Promise<boolean> {
|
|
111
|
+
const deadline = Date.now() + DISTRIBUTION_TIMEOUT_MS;
|
|
112
|
+
while (Date.now() < deadline) {
|
|
113
|
+
try {
|
|
114
|
+
const status = await getDistributionStatus(region, distributionId);
|
|
115
|
+
if (status === 'Deployed') return true;
|
|
116
|
+
} catch {
|
|
117
|
+
// Permission error or transient — keep trying.
|
|
118
|
+
}
|
|
119
|
+
await new Promise((r) => setTimeout(r, DISTRIBUTION_POLL_MS));
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
}
|
package/src/cli/commands/diag.ts
CHANGED
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
* everystack diag [url] --hydration # Analyze SSR hydration issues
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import { resolveConfig } from '../config
|
|
17
|
-
import { getFromS3 } from '../aws
|
|
18
|
-
import { step, success, fail, info, warn } from '../output
|
|
19
|
-
import { analyzeHtml, generateHydrationReport } from '../hydration-analyzer
|
|
16
|
+
import { resolveConfig } from '../config';
|
|
17
|
+
import { getFromS3 } from '../aws';
|
|
18
|
+
import { step, success, fail, info, warn } from '../output';
|
|
19
|
+
import { analyzeHtml, generateHydrationReport } from '../hydration-analyzer';
|
|
20
20
|
|
|
21
21
|
interface DiagResult {
|
|
22
22
|
url: string;
|
|
@@ -20,9 +20,9 @@ import {
|
|
|
20
20
|
formatLighthouseReport,
|
|
21
21
|
type ExtractedRun,
|
|
22
22
|
type LhReport,
|
|
23
|
-
} from '../lighthouse
|
|
24
|
-
import { resolveConfig } from '../config
|
|
25
|
-
import { step, info, fail, warn } from '../output
|
|
23
|
+
} from '../lighthouse';
|
|
24
|
+
import { resolveConfig } from '../config';
|
|
25
|
+
import { step, info, fail, warn } from '../output';
|
|
26
26
|
|
|
27
27
|
function runLighthouse(url: string, outPath: string): LhReport {
|
|
28
28
|
// Warm the edge so we measure the real-user (cached-HTML) experience.
|
package/src/cli/commands/logs.ts
CHANGED
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
* immune to the Lambda hash rotating on redeploy.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { resolveConfig } from '../config
|
|
14
|
-
import { resolveLogGroup, fetchRecentLogEvents, importOptionalAws } from '../aws
|
|
15
|
-
import { summarizeRuntimeFailures } from '../ops-diagnostics
|
|
16
|
-
import { queryLogArchive, type ObservabilityQuery } from '../observability
|
|
17
|
-
import { step, success, fail, info } from '../output
|
|
13
|
+
import { resolveConfig } from '../config';
|
|
14
|
+
import { resolveLogGroup, fetchRecentLogEvents, importOptionalAws } from '../aws';
|
|
15
|
+
import { summarizeRuntimeFailures } from '../ops-diagnostics';
|
|
16
|
+
import { queryLogArchive, type ObservabilityQuery } from '../observability';
|
|
17
|
+
import { step, success, fail, info } from '../output';
|
|
18
18
|
|
|
19
19
|
/** Default S3 key prefix for the observability archive (loggingPlugin default). */
|
|
20
20
|
const DEFAULT_PREFIX = '_observability';
|
|
@@ -18,19 +18,19 @@ import { randomUUID } from 'node:crypto';
|
|
|
18
18
|
import { existsSync } from 'node:fs';
|
|
19
19
|
import path from 'node:path';
|
|
20
20
|
import { pathToFileURL } from 'node:url';
|
|
21
|
-
import { resolveDbSource, createUrlPipelineRunner, connectingVia, type DbSource } from '../db-source
|
|
22
|
-
import { resolvePipelinePath, PIPELINE_HOMES } from '../pipeline-path
|
|
23
|
-
import { resolveConfig, opsFunction } from '../config
|
|
24
|
-
import { invokeAction } from '../aws
|
|
25
|
-
import { currentGitRef } from '../state-apply
|
|
26
|
-
import { step, success, fail, info, warn } from '../output
|
|
21
|
+
import { resolveDbSource, createUrlPipelineRunner, connectingVia, type DbSource } from '../db-source';
|
|
22
|
+
import { resolvePipelinePath, PIPELINE_HOMES } from '../pipeline-path';
|
|
23
|
+
import { resolveConfig, opsFunction } from '../config';
|
|
24
|
+
import { invokeAction } from '../aws';
|
|
25
|
+
import { currentGitRef } from '../state-apply';
|
|
26
|
+
import { step, success, fail, info, warn } from '../output';
|
|
27
27
|
import {
|
|
28
28
|
loadServerPipeline,
|
|
29
29
|
type Pipeline,
|
|
30
30
|
type PipelineLane,
|
|
31
31
|
type RunPipelineOptions,
|
|
32
32
|
type PipelineRunOutcome,
|
|
33
|
-
} from '../pipeline-loader
|
|
33
|
+
} from '../pipeline-loader';
|
|
34
34
|
|
|
35
35
|
/** --rebuild → rebuild, --curate → curate, neither → all. Both is a contradiction. */
|
|
36
36
|
export function pipelineLaneFromFlags(flags: Record<string, string>): PipelineLane {
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
import fs from 'node:fs';
|
|
17
17
|
import path from 'node:path';
|
|
18
18
|
import { pathToFileURL } from 'node:url';
|
|
19
|
-
import { detectProjectReality } from '../runbook/detect
|
|
20
|
-
import { generateRunbook, type RunbookResult } from '../runbook/generate
|
|
21
|
-
import { renderDataModelSection } from '../runbook/model-section
|
|
22
|
-
import { parseRunbook, sha8 } from '../runbook/markers
|
|
23
|
-
import { fail, info, step, success, warn } from '../output
|
|
19
|
+
import { detectProjectReality } from '../runbook/detect';
|
|
20
|
+
import { generateRunbook, type RunbookResult } from '../runbook/generate';
|
|
21
|
+
import { renderDataModelSection } from '../runbook/model-section';
|
|
22
|
+
import { parseRunbook, sha8 } from '../runbook/markers';
|
|
23
|
+
import { fail, info, step, success, warn } from '../output';
|
|
24
24
|
|
|
25
25
|
const OUT_REL = path.join('docs', 'RUNBOOK.md');
|
|
26
26
|
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
|
|
16
16
|
import fs from 'node:fs/promises';
|
|
17
17
|
import path from 'node:path';
|
|
18
|
-
import { step, success, fail, info, warn } from '../output
|
|
19
|
-
import { loadSstSecrets, putSstSecrets } from '../utils/secrets
|
|
20
|
-
import { parseDotenv, serializeDotenv } from '../utils/dotenv
|
|
21
|
-
import { isMissingOptionalDependencyError } from '../aws
|
|
18
|
+
import { step, success, fail, info, warn } from '../output';
|
|
19
|
+
import { loadSstSecrets, putSstSecrets } from '../utils/secrets';
|
|
20
|
+
import { parseDotenv, serializeDotenv } from '../utils/dotenv';
|
|
21
|
+
import { isMissingOptionalDependencyError } from '../aws';
|
|
22
22
|
|
|
23
23
|
interface SecretsContext {
|
|
24
24
|
appName: string;
|
|
@@ -34,7 +34,7 @@ async function resolveContext(flags: Record<string, string>): Promise<SecretsCon
|
|
|
34
34
|
process.exit(1);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
const { parseAppName } = await import('../discover
|
|
37
|
+
const { parseAppName } = await import('../discover');
|
|
38
38
|
const appName = await parseAppName();
|
|
39
39
|
const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || 'us-east-1';
|
|
40
40
|
|
|
@@ -25,10 +25,10 @@ import {
|
|
|
25
25
|
type CatalogColumn,
|
|
26
26
|
type CatalogGrant,
|
|
27
27
|
type ProbeResult,
|
|
28
|
-
} from '../security-probe
|
|
29
|
-
import { resolveConfig, opsFunction } from '../config
|
|
30
|
-
import { invokeAction } from '../aws
|
|
31
|
-
import { step, info, fail, success, warn } from '../output
|
|
28
|
+
} from '../security-probe';
|
|
29
|
+
import { resolveConfig, opsFunction } from '../config';
|
|
30
|
+
import { invokeAction } from '../aws';
|
|
31
|
+
import { step, info, fail, success, warn } from '../output';
|
|
32
32
|
|
|
33
33
|
const SYS_SCHEMAS = "('pg_catalog','information_schema','pg_toast')";
|
|
34
34
|
|
|
@@ -22,17 +22,17 @@ import {
|
|
|
22
22
|
type AuditReport,
|
|
23
23
|
type FunctionDescriptor,
|
|
24
24
|
type ViewDescriptor,
|
|
25
|
-
} from '../security-audit
|
|
25
|
+
} from '../security-audit';
|
|
26
26
|
import {
|
|
27
27
|
FUNCTIONS_SQL,
|
|
28
28
|
RELATIONS_SQL,
|
|
29
29
|
catalogFunctionToDescriptor,
|
|
30
30
|
catalogRelationToDescriptor,
|
|
31
|
-
} from '../security-catalog
|
|
32
|
-
import { SCHEMA_ACL_SQL, parseSchemaAcl } from '../authz-contract
|
|
33
|
-
import { resolveConfig, opsFunction } from '../config
|
|
34
|
-
import { invokeAction } from '../aws
|
|
35
|
-
import { step, success, fail, info, warn } from '../output
|
|
31
|
+
} from '../security-catalog';
|
|
32
|
+
import { SCHEMA_ACL_SQL, parseSchemaAcl } from '../authz-contract';
|
|
33
|
+
import { resolveConfig, opsFunction } from '../config';
|
|
34
|
+
import { invokeAction } from '../aws';
|
|
35
|
+
import { step, success, fail, info, warn } from '../output';
|
|
36
36
|
|
|
37
37
|
const MIGRATION_DIRS = ['drizzle', 'db/migrations', 'migrations', 'db/drizzle'];
|
|
38
38
|
const WAIVER_FILES = ['security-audit.json', '.security-audit.json'];
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
* CDN and Lambda metrics still work with nothing but IAM credentials.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { resolveConfig, opsFunction, type CliConfig } from '../config
|
|
15
|
-
import { invokeAction, importOptionalAws } from '../aws
|
|
16
|
-
import { fail, info, step } from '../output
|
|
14
|
+
import { resolveConfig, opsFunction, type CliConfig } from '../config';
|
|
15
|
+
import { invokeAction, importOptionalAws } from '../aws';
|
|
16
|
+
import { fail, info, step } from '../output';
|
|
17
17
|
|
|
18
18
|
export interface MetricSpec {
|
|
19
19
|
namespace: string;
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
* run id so the operator can reconcile (the task_log row + ECS both carry it).
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { resolveConfig, opsFunction } from '../config
|
|
15
|
-
import { invokeAction } from '../aws
|
|
16
|
-
import { pollTaskUntilStopped } from '../task-poll
|
|
17
|
-
import { step, success, fail, info } from '../output
|
|
14
|
+
import { resolveConfig, opsFunction } from '../config';
|
|
15
|
+
import { invokeAction } from '../aws';
|
|
16
|
+
import { pollTaskUntilStopped } from '../task-poll';
|
|
17
|
+
import { step, success, fail, info } from '../output';
|
|
18
18
|
|
|
19
19
|
const DEADLINE_MS = 10 * 60_000; // 10 min — Fargate cold start + pull + handshake, with headroom.
|
|
20
20
|
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
|
|
15
15
|
import fs from 'node:fs';
|
|
16
16
|
import path from 'node:path';
|
|
17
|
-
import { discoverComponents } from '../component-model
|
|
18
|
-
import { auditComponents } from '../component-audit
|
|
19
|
-
import { resolveUiBloatBudget } from '../ui-bloat
|
|
20
|
-
import { summarize, type AuditFinding } from '../bundle-audit
|
|
21
|
-
import { fail, info, step, success, warn } from '../output
|
|
17
|
+
import { discoverComponents } from '../component-model';
|
|
18
|
+
import { auditComponents } from '../component-audit';
|
|
19
|
+
import { resolveUiBloatBudget } from '../ui-bloat';
|
|
20
|
+
import { summarize, type AuditFinding } from '../bundle-audit';
|
|
21
|
+
import { fail, info, step, success, warn } from '../output';
|
|
22
22
|
|
|
23
23
|
export interface UiAuditResult {
|
|
24
24
|
findings: AuditFinding[];
|