masterrecord 0.3.41 → 0.3.43
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/Migrations/migrationTemplate.js +2 -2
- package/Migrations/schema.js +19 -3
- package/context.js +6 -2
- package/package.json +1 -1
- package/readme.md +15 -9
|
@@ -24,12 +24,12 @@ class ${this.name} extends masterrecord.schema {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
async up(table){
|
|
27
|
-
this.init(table);
|
|
27
|
+
await this.init(table);
|
|
28
28
|
${this.#up}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
async down(table){
|
|
32
|
-
this.init(table);
|
|
32
|
+
await this.init(table);
|
|
33
33
|
${this.#down}
|
|
34
34
|
}
|
|
35
35
|
}
|
package/Migrations/schema.js
CHANGED
|
@@ -6,14 +6,27 @@ class schema{
|
|
|
6
6
|
this._dbEnsured = false;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Wait for async database initialization (MySQL/PostgreSQL) to complete.
|
|
11
|
+
* The context constructor fires off an async pool init that may not have
|
|
12
|
+
* finished by the time migration methods run. This must be awaited before
|
|
13
|
+
* accessing this.context._SQLEngine or this.context.db.
|
|
14
|
+
*/
|
|
15
|
+
async _ensureReady(){
|
|
16
|
+
if(this.context && this.context._initPromise){
|
|
17
|
+
await this.context._initPromise;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
9
20
|
|
|
10
|
-
init(table){
|
|
21
|
+
async init(table){
|
|
22
|
+
// Wait for async DB init (MySQL/PostgreSQL) before any operations
|
|
23
|
+
await this._ensureReady();
|
|
11
24
|
if(table){
|
|
12
25
|
this.fullTable = table.___table;
|
|
13
26
|
}
|
|
14
27
|
// Ensure backing database exists for MySQL before running any DDL
|
|
15
28
|
if(this.context && this.context.isMySQL && this._dbEnsured !== true){
|
|
16
|
-
try{ this.createDatabase(); }catch(_){ /* best-effort */ }
|
|
29
|
+
try{ await this.createDatabase(); }catch(_){ /* best-effort */ }
|
|
17
30
|
}
|
|
18
31
|
}
|
|
19
32
|
|
|
@@ -83,6 +96,9 @@ class schema{
|
|
|
83
96
|
}
|
|
84
97
|
|
|
85
98
|
async createTable(table){
|
|
99
|
+
// Ensure async DB init is complete (safety net for older migrations
|
|
100
|
+
// that call this.init(table) without await)
|
|
101
|
+
await this._ensureReady();
|
|
86
102
|
|
|
87
103
|
if(table){
|
|
88
104
|
// If table exists, run sync instead of blind create
|
|
@@ -327,7 +343,7 @@ class schema{
|
|
|
327
343
|
async createDatabase(){
|
|
328
344
|
try{
|
|
329
345
|
if(!(this.context && this.context.isMySQL)){ return; }
|
|
330
|
-
const MySQLAsyncClient = require('masterrecord/
|
|
346
|
+
const MySQLAsyncClient = require('masterrecord/mySQLConnect');
|
|
331
347
|
const client = this.context.db; // main client (may not be connected yet)
|
|
332
348
|
if(!client || !client.config || !client.config.database){ return; }
|
|
333
349
|
const dbName = client.config.database;
|
package/context.js
CHANGED
|
@@ -712,11 +712,13 @@ class context {
|
|
|
712
712
|
this.isPostgres = false;
|
|
713
713
|
|
|
714
714
|
// MySQL is async - caller must await env()
|
|
715
|
-
|
|
715
|
+
// Store promise so migration schema can await it
|
|
716
|
+
this._initPromise = (async () => {
|
|
716
717
|
this.db = await this.__mysqlInit(options, 'mysql2');
|
|
717
718
|
// Note: engine is already set in __mysqlInit
|
|
718
719
|
return this;
|
|
719
720
|
})();
|
|
721
|
+
return this._initPromise;
|
|
720
722
|
}
|
|
721
723
|
|
|
722
724
|
// PostgreSQL initialization (async)
|
|
@@ -726,11 +728,13 @@ class context {
|
|
|
726
728
|
this.isSQLite = false;
|
|
727
729
|
|
|
728
730
|
// PostgreSQL is async - caller must await env()
|
|
729
|
-
|
|
731
|
+
// Store promise so migration schema can await it
|
|
732
|
+
this._initPromise = (async () => {
|
|
730
733
|
this.db = await this.__postgresInit(options, 'pg');
|
|
731
734
|
// Note: engine is already set in __postgresInit
|
|
732
735
|
return this;
|
|
733
736
|
})();
|
|
737
|
+
return this._initPromise;
|
|
734
738
|
}
|
|
735
739
|
|
|
736
740
|
throw new ConfigurationError(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "masterrecord",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.43",
|
|
4
4
|
"description": "An Object-relational mapping for the Master framework. Master Record connects classes to relational database tables to establish a database with almost zero-configuration ",
|
|
5
5
|
"main": "MasterRecord.js",
|
|
6
6
|
"bin": {
|
package/readme.md
CHANGED
|
@@ -3369,19 +3369,25 @@ user.name = null; // Error if name is { nullable: false }
|
|
|
3369
3369
|
|
|
3370
3370
|
## Changelog
|
|
3371
3371
|
|
|
3372
|
-
### Version 0.3.
|
|
3372
|
+
### Version 0.3.42 (2026-02-20) - FIX: Migration System + add-migration Improvements
|
|
3373
3373
|
|
|
3374
|
-
#### Bug Fixed: `
|
|
3374
|
+
#### Bug Fixed: `update-database` failing for MySQL/PostgreSQL with "Cannot read properties of null"
|
|
3375
|
+
- **FIXED**: Running `masterrecord update-database` with MySQL or PostgreSQL would crash with `Cannot read properties of null (reading 'tableExists')`
|
|
3376
|
+
- **Root Cause**: The migration `schema.js` constructor creates a new context instance, but MySQL/PostgreSQL database initialization is async. The `_SQLEngine` property was still `null` when `createTable` tried to use it because the async pool init hadn't completed yet.
|
|
3377
|
+
- **Solution**: Store the async init promise as `_initPromise` on the context instance. Added `_ensureReady()` method to `schema.js` that awaits it. Called in both `init()` and `createTable()` (safety net for existing migrations).
|
|
3378
|
+
- **Also fixed**: Typo in `schema.js` — `require('masterrecord/mySQLAsyncConnect')` corrected to `require('masterrecord/mySQLConnect')`
|
|
3379
|
+
- **Also fixed**: `init()` now properly `await`s `createDatabase()` instead of fire-and-forget
|
|
3380
|
+
|
|
3381
|
+
#### Bug Fixed: `add-migration` creating unnecessary database connections
|
|
3375
3382
|
- **FIXED**: Running `masterrecord add-migration` would open a real database connection (creating SQLite files on disk, or connecting to MySQL/PostgreSQL) even though it only needs entity schemas and seed data to generate migration files
|
|
3376
|
-
- **
|
|
3377
|
-
- **Root Cause**: The context constructor calls `env()` which initializes a full database connection; `add-migration` only needs entity metadata
|
|
3378
|
-
- **Solution**: Added schema-only mode (`MASTERRECORD_SCHEMA_ONLY` env var) that sets database type flags for correct entity registration but skips all database initialization (no file creation, no connections)
|
|
3379
|
-
- **Impact**: `add-migration` is now faster, creates no side effects, and works safely on production servers
|
|
3383
|
+
- **Solution**: Added schema-only mode (`MASTERRECORD_SCHEMA_ONLY` env var) that sets database type flags but skips all DB initialization
|
|
3380
3384
|
|
|
3381
3385
|
#### Files Modified
|
|
3382
|
-
1. **`Migrations/
|
|
3383
|
-
2. **`
|
|
3384
|
-
3. **`
|
|
3386
|
+
1. **`Migrations/schema.js`** - Added `_ensureReady()`, made `init()` async with proper awaits, fixed `mySQLConnect` require
|
|
3387
|
+
2. **`Migrations/migrationTemplate.js`** - New migrations now `await this.init(table)`
|
|
3388
|
+
3. **`Migrations/cli.js`** - Schema-only mode for `add-migration`
|
|
3389
|
+
4. **`context.js`** - Store `_initPromise` for MySQL/PostgreSQL async init, schema-only mode in `env()`
|
|
3390
|
+
5. **`package.json`** - Updated to v0.3.42
|
|
3385
3391
|
|
|
3386
3392
|
### Version 0.3.39 (2026-02-09) - CRITICAL BUG FIX: Foreign Key String Values
|
|
3387
3393
|
|