@happyvertical/smrt-cli 0.40.31 → 0.40.32
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 +11 -8
- package/dist/{commands-gjGWLmwD.js → commands-DA3gTMzR.js} +16 -5
- package/dist/index.js +8 -8
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -67,14 +67,17 @@ smrt db:migrate --postgres-timestamp-legacy-timezone UTC
|
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
The option has no default and rejects every value other than `UTC`. On
|
|
70
|
-
PostgreSQL,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
PostgreSQL, `db:migrate` first converts framework-owned `_smrt_*` timestamp
|
|
71
|
+
columns before migration-tracker bootstrap, then converts manifest-owned
|
|
72
|
+
columns to `timestamptz` with `USING column AT TIME ZONE 'UTC'`. This preserves
|
|
73
|
+
the proven UTC instants. It is not safe for a database with any local-time
|
|
74
|
+
writer; use an application-owned, provenance-aware migration in that case.
|
|
75
|
+
Rehearse against a restored clone and keep a verified backup because type
|
|
76
|
+
upgrades have no automatic down migration. `smrt db:diff
|
|
77
|
+
--postgres-timestamp-legacy-timezone UTC` previews manifest-owned changes;
|
|
78
|
+
`smrt db:migrate --dry-run --postgres-timestamp-legacy-timezone UTC` also
|
|
79
|
+
queries and prints the read-only `_smrt_*` conversion plan without initializing
|
|
80
|
+
the tracker or writing to the database.
|
|
78
81
|
|
|
79
82
|
### Code Generation
|
|
80
83
|
|
|
@@ -5,7 +5,7 @@ import { existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, writeFile
|
|
|
5
5
|
import * as path from "node:path";
|
|
6
6
|
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
7
7
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
|
-
import { ObjectRegistry, SchemaComparer, createQualifiedName, generateDDLForEngine, getClassName, isQualifiedName, parseQualifiedName } from "@happyvertical/smrt-core";
|
|
8
|
+
import { ObjectRegistry, SchemaComparer, createQualifiedName, generateDDLForEngine, getClassName, isQualifiedName, migratePostgresSystemTimestamps, parseQualifiedName, planPostgresSystemTimestampMigrations } from "@happyvertical/smrt-core";
|
|
9
9
|
import { loadExternalManifestSync } from "@happyvertical/smrt-core/manifest";
|
|
10
10
|
import { access, cp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
11
11
|
import { createLogger } from "@happyvertical/logger";
|
|
@@ -7187,6 +7187,7 @@ export default testManifest;
|
|
|
7187
7187
|
try {
|
|
7188
7188
|
const forceSelection = resolveForceMigrationSelection(options.force, options["force-migration"]);
|
|
7189
7189
|
const postgresTimestampMigration = resolvePostgresTimestampMigration(options["postgres-timestamp-legacy-timezone"]);
|
|
7190
|
+
const isDryRun = options["dry-run"] ?? false;
|
|
7190
7191
|
const { getPackageConfig } = await import("@happyvertical/smrt-config");
|
|
7191
7192
|
const { DEFAULT_CLI_CONFIG } = await import("./config-BwrFRL8L.js");
|
|
7192
7193
|
const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
|
|
@@ -7264,22 +7265,23 @@ export default testManifest;
|
|
|
7264
7265
|
return;
|
|
7265
7266
|
}
|
|
7266
7267
|
console.log(`✓ Connected to ${formatDatabaseDisplayUrl(dbType, dbUrl)}\n`);
|
|
7268
|
+
const systemTimestampPreview = postgresTimestampMigration && isDryRun ? await planPostgresSystemTimestampMigrations(db, postgresTimestampMigration, dbType) : [];
|
|
7269
|
+
if (postgresTimestampMigration && !isDryRun) await migratePostgresSystemTimestamps(db, postgresTimestampMigration, dbType);
|
|
7267
7270
|
const { MigrationTracker, shortChecksum } = await import("@happyvertical/smrt-core/migrations");
|
|
7268
7271
|
const tracker = new MigrationTracker({
|
|
7269
7272
|
db,
|
|
7270
7273
|
useConcurrentIndexes: options["postgres-safe"] ?? false
|
|
7271
7274
|
});
|
|
7272
|
-
await tracker.initialize();
|
|
7275
|
+
if (!isDryRun) await tracker.initialize();
|
|
7273
7276
|
if (options.verbose) {
|
|
7274
7277
|
const engine = tracker.getEngine();
|
|
7275
|
-
console.log(`Migration tracker initialized (engine: ${engine})`);
|
|
7278
|
+
console.log(isDryRun ? `Migration tracker preview configured (engine: ${engine})` : `Migration tracker initialized (engine: ${engine})`);
|
|
7276
7279
|
if (options["postgres-safe"] && engine === "postgres") console.log("PostgreSQL-safe mode enabled (CONCURRENTLY, lock_timeout)");
|
|
7277
7280
|
console.log();
|
|
7278
7281
|
}
|
|
7279
7282
|
const migrations = [];
|
|
7280
7283
|
const manualInterventions = [];
|
|
7281
7284
|
const tableErrorCount = 0;
|
|
7282
|
-
const isDryRun = options["dry-run"] ?? false;
|
|
7283
7285
|
const applySchemaMigrations = shouldApplySchemaMigrations({ dryRun: isDryRun });
|
|
7284
7286
|
const repairData = Boolean(options["repair-data"] || options["upgrade-sti"]);
|
|
7285
7287
|
if (options["upgrade-sti"]) {
|
|
@@ -7323,7 +7325,7 @@ export default testManifest;
|
|
|
7323
7325
|
console.log(" Manual migration required (backup, recreate, restore as needed).\n");
|
|
7324
7326
|
}
|
|
7325
7327
|
const tablesCreated = diff.added_tables.length > 0;
|
|
7326
|
-
const schemaUpToDate = migrations.length === 0 && manualInterventions.length === 0 && !tablesCreated;
|
|
7328
|
+
const schemaUpToDate = migrations.length === 0 && manualInterventions.length === 0 && !tablesCreated && systemTimestampPreview.length === 0;
|
|
7327
7329
|
if (isDryRun) {
|
|
7328
7330
|
if (schemaUpToDate && !repairData) {
|
|
7329
7331
|
console.log("✅ Database schema is up to date - no migrations needed\n");
|
|
@@ -7332,6 +7334,11 @@ export default testManifest;
|
|
|
7332
7334
|
if (schemaUpToDate) console.log("✅ Database schema is up to date - no schema migrations needed\n");
|
|
7333
7335
|
else {
|
|
7334
7336
|
console.log("📋 Migration Preview (not executed):\n");
|
|
7337
|
+
if (systemTimestampPreview.length > 0) {
|
|
7338
|
+
console.log(` 🕰️ SMRT system timestamp columns to convert: ${systemTimestampPreview.length}`);
|
|
7339
|
+
for (const migration of systemTimestampPreview) console.log(migration.kind === "column" ? ` ${migration.tableName}.${migration.columnName}` : " _smrt_changes append function signature");
|
|
7340
|
+
console.log();
|
|
7341
|
+
}
|
|
7335
7342
|
const columnMigrations = migrations.filter((m) => m.type === "add_column");
|
|
7336
7343
|
const indexMigrations = migrations.filter((m) => m.type === "add_index");
|
|
7337
7344
|
const indexDrops = migrations.filter((m) => m.type === "drop_index");
|
|
@@ -7351,6 +7358,10 @@ export default testManifest;
|
|
|
7351
7358
|
console.log();
|
|
7352
7359
|
}
|
|
7353
7360
|
console.log(" SQL Statements:\n");
|
|
7361
|
+
for (const migration of systemTimestampPreview) {
|
|
7362
|
+
const terminator = migration.sql.trimEnd().endsWith(";") ? "" : ";";
|
|
7363
|
+
console.log(` ${migration.sql}${terminator}`);
|
|
7364
|
+
}
|
|
7354
7365
|
for (const m of migrations) {
|
|
7355
7366
|
const sqlStatements = m.sqlStatements ?? (m.sql ? [m.sql] : []);
|
|
7356
7367
|
for (const sql of sqlStatements) console.log(` ${sql};`);
|
package/dist/index.js
CHANGED
|
@@ -48,56 +48,56 @@ var _docsCommands = null;
|
|
|
48
48
|
var _playgroundCommands = null;
|
|
49
49
|
async function getGnodeCommands() {
|
|
50
50
|
if (!_gnodeCommands) {
|
|
51
|
-
const { gnodeCommands } = await import("./commands-
|
|
51
|
+
const { gnodeCommands } = await import("./commands-DA3gTMzR.js");
|
|
52
52
|
_gnodeCommands = gnodeCommands;
|
|
53
53
|
}
|
|
54
54
|
return _gnodeCommands;
|
|
55
55
|
}
|
|
56
56
|
async function getGitCommands() {
|
|
57
57
|
if (!_gitCommands) {
|
|
58
|
-
const { gitCommands } = await import("./commands-
|
|
58
|
+
const { gitCommands } = await import("./commands-DA3gTMzR.js");
|
|
59
59
|
_gitCommands = gitCommands;
|
|
60
60
|
}
|
|
61
61
|
return _gitCommands;
|
|
62
62
|
}
|
|
63
63
|
async function getGenerateCommands() {
|
|
64
64
|
if (!_generateCommands) {
|
|
65
|
-
const { generateCommands } = await import("./commands-
|
|
65
|
+
const { generateCommands } = await import("./commands-DA3gTMzR.js");
|
|
66
66
|
_generateCommands = generateCommands;
|
|
67
67
|
}
|
|
68
68
|
return _generateCommands;
|
|
69
69
|
}
|
|
70
70
|
async function getInitCommands() {
|
|
71
71
|
if (!_initCommands) {
|
|
72
|
-
const { initCommands } = await import("./commands-
|
|
72
|
+
const { initCommands } = await import("./commands-DA3gTMzR.js");
|
|
73
73
|
_initCommands = initCommands;
|
|
74
74
|
}
|
|
75
75
|
return _initCommands;
|
|
76
76
|
}
|
|
77
77
|
async function getUtilityCommands() {
|
|
78
78
|
if (!_utilityCommands) {
|
|
79
|
-
const { utilityCommands } = await import("./commands-
|
|
79
|
+
const { utilityCommands } = await import("./commands-DA3gTMzR.js");
|
|
80
80
|
_utilityCommands = utilityCommands;
|
|
81
81
|
}
|
|
82
82
|
return _utilityCommands;
|
|
83
83
|
}
|
|
84
84
|
async function getDispatchCommands() {
|
|
85
85
|
if (!_dispatchCommands) {
|
|
86
|
-
const { dispatchCommands } = await import("./commands-
|
|
86
|
+
const { dispatchCommands } = await import("./commands-DA3gTMzR.js");
|
|
87
87
|
_dispatchCommands = dispatchCommands;
|
|
88
88
|
}
|
|
89
89
|
return _dispatchCommands;
|
|
90
90
|
}
|
|
91
91
|
async function getDocsCommands() {
|
|
92
92
|
if (!_docsCommands) {
|
|
93
|
-
const { docsCommands } = await import("./commands-
|
|
93
|
+
const { docsCommands } = await import("./commands-DA3gTMzR.js");
|
|
94
94
|
_docsCommands = docsCommands;
|
|
95
95
|
}
|
|
96
96
|
return _docsCommands;
|
|
97
97
|
}
|
|
98
98
|
async function getPlaygroundCommands() {
|
|
99
99
|
if (!_playgroundCommands) {
|
|
100
|
-
const { playgroundCommands } = await import("./commands-
|
|
100
|
+
const { playgroundCommands } = await import("./commands-DA3gTMzR.js");
|
|
101
101
|
_playgroundCommands = playgroundCommands;
|
|
102
102
|
}
|
|
103
103
|
return _playgroundCommands;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-cli",
|
|
3
|
-
"version": "0.40.
|
|
3
|
+
"version": "0.40.32",
|
|
4
4
|
"description": "Developer CLI for SMRT framework - introspection, testing, and project management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"acorn": "^8.17.0",
|
|
33
33
|
"fast-glob": "3.3.3",
|
|
34
34
|
"tar": "^7.5.19",
|
|
35
|
-
"@happyvertical/smrt-agents": "0.40.
|
|
36
|
-
"@happyvertical/smrt-
|
|
37
|
-
"@happyvertical/smrt-
|
|
38
|
-
"@happyvertical/smrt-types": "0.40.
|
|
39
|
-
"@happyvertical/smrt-
|
|
40
|
-
"@happyvertical/smrt-config": "0.40.
|
|
35
|
+
"@happyvertical/smrt-agents": "0.40.32",
|
|
36
|
+
"@happyvertical/smrt-core": "0.40.32",
|
|
37
|
+
"@happyvertical/smrt-playground": "0.40.32",
|
|
38
|
+
"@happyvertical/smrt-types": "0.40.32",
|
|
39
|
+
"@happyvertical/smrt-dev-mcp": "0.40.32",
|
|
40
|
+
"@happyvertical/smrt-config": "0.40.32"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "24.13.2",
|