masterrecord 0.2.11 → 0.2.13

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/cli.js CHANGED
@@ -83,9 +83,8 @@ program.option('-V', 'output the version');
83
83
  contextFileName = contextFileName.toLowerCase();
84
84
  var migration = new Migration();
85
85
  try{
86
- var search = `${executedLocation}/**/*${contextFileName}_contextSnapShot.json`;
87
- var files = globSearch.sync(search, executedLocation);
88
- var file = files && files[0];
86
+ var files = globSearch.sync(`**/*${contextFileName}_contextSnapShot.json`, { cwd: executedLocation, dot: true, windowsPathsNoEscape: true, nocase: true });
87
+ var file = files && files[0] ? path.resolve(executedLocation, files[0]) : null;
89
88
  if(!file){
90
89
  console.log(`Error - Cannot read or find Context snapshot '${contextFileName}_contextSnapShot.json' in '${executedLocation}'.`);
91
90
  return;
@@ -98,8 +97,8 @@ program.option('-V', 'output the version');
98
97
  return;
99
98
  }
100
99
  // Find latest migration file (so we can use its class which extends schema)
101
- var searchMigration = `${contextSnapshot.migrationFolder}/**/*_migration.js`;
102
- var migrationFiles = globSearch.sync(searchMigration, contextSnapshot.migrationFolder);
100
+ var migrationFiles = globSearch.sync(`**/*_migration.js`, { cwd: contextSnapshot.migrationFolder, dot: true, windowsPathsNoEscape: true });
101
+ migrationFiles = (migrationFiles || []).map(f => path.resolve(contextSnapshot.migrationFolder, f));
103
102
  if(!(migrationFiles && migrationFiles.length)){
104
103
  console.log("Error - Cannot read or find migration file");
105
104
  return;
@@ -178,9 +177,8 @@ program.option('-V', 'output the version');
178
177
  var migration = new Migration();
179
178
  try{
180
179
  // find context file from main folder location
181
- var search = `${executedLocation}/**/*${contextFileName}_contextSnapShot.json`;
182
- var files = globSearch.sync(search, executedLocation);
183
- var file = files && files[0];
180
+ var files = globSearch.sync(`**/*${contextFileName}_contextSnapShot.json`, { cwd: executedLocation, dot: true, windowsPathsNoEscape: true, nocase: true });
181
+ var file = files && files[0] ? path.resolve(executedLocation, files[0]) : null;
184
182
  if(!file){
185
183
  console.log(`Error - Cannot read or find Context snapshot '${contextFileName}_contextSnapShot.json' in '${executedLocation}'. Run 'masterrecord enable-migrations ${contextFileName}'.`);
186
184
  return;
@@ -229,14 +227,13 @@ program.option('-V', 'output the version');
229
227
  contextFileName = contextFileName.toLowerCase();
230
228
  var migration = new Migration();
231
229
  try{
232
- // find context file from main folder location
233
- var search = `${executedLocation}/**/*${contextFileName}_contextSnapShot.json`;
234
- var files = globSearch.sync(search, executedLocation);
235
- var file = files[0];
230
+ // find context snapshot (cwd-based glob)
231
+ var files = globSearch.sync(`**/*${contextFileName}_contextSnapShot.json`, { cwd: executedLocation, dot: true, windowsPathsNoEscape: true, nocase: true });
232
+ var file = files && files[0] ? path.resolve(executedLocation, files[0]) : null;
236
233
  if(file){
237
234
  var contextSnapshot = require(file);
238
- var searchMigration = `${contextSnapshot.migrationFolder}/**/*_migration.js`;
239
- var migrationFiles = globSearch.sync(searchMigration, contextSnapshot.migrationFolder);
235
+ var migrationFiles = globSearch.sync(`**/*_migration.js`, { cwd: contextSnapshot.migrationFolder, dot: true, windowsPathsNoEscape: true });
236
+ migrationFiles = (migrationFiles || []).map(f => path.resolve(contextSnapshot.migrationFolder, f));
240
237
  if( migrationFiles && migrationFiles.length){
241
238
  // sort by timestamp prefix or file mtime as fallback
242
239
  var mFiles = migrationFiles.slice().sort(function(a, b){
@@ -287,9 +284,8 @@ program.option('-V', 'output the version');
287
284
  contextFileName = contextFileName.toLowerCase();
288
285
  var migration = new Migration();
289
286
  try{
290
- var search = `${executedLocation}/**/*${contextFileName}_contextSnapShot.json`;
291
- var files = globSearch.sync(search, executedLocation);
292
- var file = files && files[0];
287
+ var files = globSearch.sync(`**/*${contextFileName}_contextSnapShot.json`, { cwd: executedLocation, dot: true, windowsPathsNoEscape: true, nocase: true });
288
+ var file = files && files[0] ? path.resolve(executedLocation, files[0]) : null;
293
289
  if(!file){
294
290
  console.log(`Error - Cannot read or find Context snapshot '${contextFileName}_contextSnapShot.json' in '${executedLocation}'.`);
295
291
  return;
@@ -301,8 +297,8 @@ program.option('-V', 'output the version');
301
297
  console.log(`Error - Cannot read context snapshot at '${file}'.`);
302
298
  return;
303
299
  }
304
- var searchMigration = `${contextSnapshot.migrationFolder}/**/*_migration.js`;
305
- var migrationFiles = globSearch.sync(searchMigration, contextSnapshot.migrationFolder);
300
+ var migrationFiles = globSearch.sync(`**/*_migration.js`, { cwd: contextSnapshot.migrationFolder, dot: true, windowsPathsNoEscape: true });
301
+ migrationFiles = (migrationFiles || []).map(f => path.resolve(contextSnapshot.migrationFolder, f));
306
302
  if(!(migrationFiles && migrationFiles.length)){
307
303
  console.log("Error - Cannot read or find migration file");
308
304
  return;
@@ -365,10 +361,9 @@ program.option('-V', 'output the version');
365
361
  contextFileName = contextFileName.toLowerCase();
366
362
  var migration = new Migration();
367
363
  try{
368
- // find context file from main folder location
369
- var search = `${executedLocation}/**/*${contextFileName}_contextSnapShot.json`;
370
- var files = globSearch.sync(search, executedLocation);
371
- var file = files[0];
364
+ // find context snapshot (cwd-based glob)
365
+ var files = globSearch.sync(`**/*${contextFileName}_contextSnapShot.json`, { cwd: executedLocation, dot: true, windowsPathsNoEscape: true, nocase: true });
366
+ var file = files && files[0] ? path.resolve(executedLocation, files[0]) : null;
372
367
  if(!file){
373
368
  console.log(`Error - Cannot read or find Context snapshot '${contextFileName}_contextSnapShot.json' in '${executedLocation}'.`);
374
369
  return;
@@ -380,8 +375,8 @@ program.option('-V', 'output the version');
380
375
  console.log(`Error - Cannot read context snapshot at '${file}'.`);
381
376
  return;
382
377
  }
383
- var searchMigration = `${contextSnapshot.migrationFolder}/**/*_migration.js`;
384
- var migrationFiles = globSearch.sync(searchMigration, contextSnapshot.migrationFolder);
378
+ var migrationFiles = globSearch.sync(`**/*_migration.js`, { cwd: contextSnapshot.migrationFolder, dot: true, windowsPathsNoEscape: true });
379
+ migrationFiles = (migrationFiles || []).map(f => path.resolve(contextSnapshot.migrationFolder, f));
385
380
  if(!(migrationFiles && migrationFiles.length)){
386
381
  console.log("Error - Cannot read or find migration file");
387
382
  return;
@@ -437,9 +432,8 @@ program.option('-V', 'output the version');
437
432
  .action(function(contextFileName){
438
433
  var executedLocation = process.cwd();
439
434
  contextFileName = contextFileName.toLowerCase();
440
- var search = `${executedLocation}/**/*${contextFileName}_contextSnapShot.json`;
441
- var files = globSearch.sync(search, executedLocation);
442
- var file = files[0];
435
+ var files = globSearch.sync(`**/*${contextFileName}_contextSnapShot.json`, { cwd: executedLocation, dot: true, windowsPathsNoEscape: true, nocase: true });
436
+ var file = files && files[0] ? path.resolve(executedLocation, files[0]) : null;
443
437
  if(!file){
444
438
  console.log(`Error - Cannot read or find Context snapshot '${contextFileName}_contextSnapShot.json' in '${executedLocation}'.`);
445
439
  return;
@@ -451,13 +445,12 @@ program.option('-V', 'output the version');
451
445
  console.log(`Error - Cannot read context snapshot at '${file}'.`);
452
446
  return;
453
447
  }
454
- var searchMigration = `${contextSnapshot.migrationFolder}/**/*_migration.js`;
455
- var migrationFiles = globSearch.sync(searchMigration, contextSnapshot.migrationFolder);
448
+ var migrationFiles = globSearch.sync(`**/*_migration.js`, { cwd: contextSnapshot.migrationFolder, dot: true, windowsPathsNoEscape: true });
456
449
  if(!(migrationFiles && migrationFiles.length)){
457
450
  console.log("No migration files found.");
458
451
  return;
459
452
  }
460
- var sorted = migrationFiles.slice().sort((a,b) => __getMigrationTimestamp(a) - __getMigrationTimestamp(b));
453
+ var sorted = migrationFiles.slice().sort((a,b) => __getMigrationTimestamp(path.resolve(contextSnapshot.migrationFolder, a)) - __getMigrationTimestamp(path.resolve(contextSnapshot.migrationFolder, b)));
461
454
  // Print relative names for readability
462
455
  for(const f of sorted){
463
456
  console.log(path.basename(f));
@@ -478,18 +471,17 @@ program.option('-V', 'output the version');
478
471
  var targetName = path.basename(migrationFileName);
479
472
 
480
473
  // Locate the target migration file anywhere under the current folder
481
- var searchTarget = `${executedLocation}/**/${targetName}`;
482
- var targetMatches = globSearch.sync(searchTarget, executedLocation);
474
+ var targetMatches = globSearch.sync(`**/${targetName}`, { cwd: executedLocation, dot: true, windowsPathsNoEscape: true });
483
475
  if(!(targetMatches && targetMatches.length)){
484
476
  console.log(`Error - Cannot read or find migration file '${targetName}' in '${executedLocation}'.`);
485
477
  return;
486
478
  }
487
- var targetFilePath = targetMatches[0];
479
+ var targetFilePath = path.resolve(executedLocation, targetMatches[0]);
488
480
  var migrationFolder = path.dirname(targetFilePath);
489
481
 
490
482
  // Find the context snapshot within the same migrations folder
491
- var snapshotMatches = globSearch.sync(`${migrationFolder}/**/*_contextSnapShot.json`, migrationFolder);
492
- var snapshotFile = snapshotMatches && snapshotMatches[0];
483
+ var snapshotMatches = globSearch.sync(`**/*_contextSnapShot.json`, { cwd: migrationFolder, dot: true, windowsPathsNoEscape: true });
484
+ var snapshotFile = snapshotMatches && snapshotMatches[0] ? path.resolve(migrationFolder, snapshotMatches[0]) : null;
493
485
  if(!snapshotFile){
494
486
  console.log("Error - Cannot read or find Context snapshot in migration folder.");
495
487
  return;
@@ -504,7 +496,7 @@ program.option('-V', 'output the version');
504
496
  }
505
497
 
506
498
  // Get all migration files in this folder
507
- var allMigrationFiles = globSearch.sync(`${migrationFolder}/**/*_migration.js`, migrationFolder);
499
+ var allMigrationFiles = globSearch.sync(`**/*_migration.js`, { cwd: migrationFolder, dot: true, windowsPathsNoEscape: true });
508
500
  if(!(allMigrationFiles && allMigrationFiles.length)){
509
501
  console.log("Error - Cannot read or find migration file");
510
502
  return;
@@ -512,7 +504,7 @@ program.option('-V', 'output the version');
512
504
 
513
505
  // Sort chronologically
514
506
  var sorted = allMigrationFiles.slice().sort(function(a, b){
515
- return __getMigrationTimestamp(a) - __getMigrationTimestamp(b);
507
+ return __getMigrationTimestamp(path.resolve(migrationFolder, a)) - __getMigrationTimestamp(path.resolve(migrationFolder, b));
516
508
  });
517
509
 
518
510
  // Find target index by basename match
@@ -542,7 +534,7 @@ program.option('-V', 'output the version');
542
534
 
543
535
  // Roll back (down) all migrations newer than the target (i.e., strictly after targetIndex)
544
536
  for (var i = sorted.length - 1; i > targetIndex; i--) {
545
- var migFile = sorted[i];
537
+ var migFile = path.resolve(migrationFolder, sorted[i]);
546
538
  var MigCtor = require(migFile);
547
539
  var migInstance = new MigCtor(ContextCtor);
548
540
  if(typeof migInstance.down === 'function'){
@@ -576,79 +568,69 @@ program.option('-V', 'output the version');
576
568
  .action(function(){
577
569
  var executedLocation = process.cwd();
578
570
  try{
579
- // Find all Context files (e.g., chatContext.js)
580
- var allFiles = globSearch.sync(`${executedLocation}/**/*Context.js`, executedLocation);
581
- if(!(allFiles && allFiles.length)){
582
- console.log('No Context files found.');
571
+ // Find all context snapshots and run update per snapshot (avoids unrelated framework contexts)
572
+ var snapshotFiles = globSearch.sync(`**/*_contextSnapShot.json`, { cwd: executedLocation, dot: true, windowsPathsNoEscape: true });
573
+ if(!(snapshotFiles && snapshotFiles.length)){
574
+ console.log('No context snapshots found. Run enable-migrations for each context first.');
583
575
  return;
584
576
  }
585
- // Deduplicate by basename (case-insensitive)
586
- var seen = new Set();
587
- var contextFiles = [];
588
- for(const f of allFiles){
589
- var name = path.basename(f).toLowerCase();
590
- if(!seen.has(name)){
591
- seen.add(name);
592
- contextFiles.push(f);
593
- }
577
+ // Group snapshots by context name (case-insensitive) and pick best per group
578
+ var groups = {};
579
+ for(const snapRel of snapshotFiles){
580
+ const snapFile = path.resolve(executedLocation, snapRel);
581
+ let cs;
582
+ try{ cs = require(snapFile); }catch(_){ continue; }
583
+ const nameFromPath = path.basename(snapFile).replace(/_contextSnapShot\.json$/i, '').toLowerCase();
584
+ const ctxName = (cs && cs.contextLocation)
585
+ ? path.basename(cs.contextLocation).replace(/\.js$/i, '').toLowerCase()
586
+ : nameFromPath;
587
+ const migsRel = globSearch.sync(`**/*_migration.js`, { cwd: cs.migrationFolder, dot: true, windowsPathsNoEscape: true }) || [];
588
+ const migs = migsRel.map(f => path.resolve(cs.migrationFolder, f));
589
+ if(!groups[ctxName]) groups[ctxName] = [];
590
+ groups[ctxName].push({ snapFile, cs, ctxName, migs });
594
591
  }
592
+
595
593
  var migration = new Migration();
596
- // Process each context independently
597
- for(const ctxFile of contextFiles){
594
+ var ctxNames = Object.keys(groups);
595
+ for(const name of ctxNames){
598
596
  try{
599
- var base = path.basename(ctxFile);
600
- var ctxName = base.replace(/\.js$/i, '').toLowerCase();
601
- // Locate snapshot for this context
602
- var snapMatches = globSearch.sync(`${executedLocation}/**/*${ctxName}_contextSnapShot.json`, executedLocation);
603
- var snapFile = snapMatches && snapMatches[0];
604
- if(!snapFile){
605
- console.log(`Skipping ${ctxName}: snapshot not found. Run 'masterrecord enable-migrations ${ctxName}'.`);
606
- continue;
607
- }
608
- var contextSnapshot;
609
- try{ contextSnapshot = require(snapFile); }catch(_){
610
- console.log(`Skipping ${ctxName}: cannot read context snapshot at '${snapFile}'.`);
611
- continue;
612
- }
613
- // Get migration files for this snapshot folder
614
- var searchMigration = `${contextSnapshot.migrationFolder}/**/*_migration.js`;
615
- var migrationFiles = globSearch.sync(searchMigration, contextSnapshot.migrationFolder);
616
- if(!(migrationFiles && migrationFiles.length)){
617
- console.log(`Skipping ${ctxName}: no migration files found.`);
597
+ var list = groups[name];
598
+ // Prefer entries that actually have migration files
599
+ var withMigs = list.filter(e => e.migs && e.migs.length > 0);
600
+ var entry = withMigs.length ? withMigs[withMigs.length - 1] : list[0];
601
+ if(!(entry.migs && entry.migs.length)){
602
+ console.log(`Skipping ${entry.ctxName}: no migration files found.`);
618
603
  continue;
619
604
  }
620
- // Pick latest
621
- var mFiles = migrationFiles.slice().sort(function(a, b){
605
+ var mFiles = entry.migs.slice().sort(function(a, b){
622
606
  return __getMigrationTimestamp(a) - __getMigrationTimestamp(b);
623
607
  });
624
608
  var mFile = mFiles[mFiles.length - 1];
625
609
 
626
610
  var ContextCtor;
627
- try{ ContextCtor = require(contextSnapshot.contextLocation); }catch(_){
628
- console.log(`Skipping ${ctxName}: cannot load Context at '${contextSnapshot.contextLocation}'.`);
611
+ try{ ContextCtor = require(entry.cs.contextLocation); }catch(_){
612
+ console.log(`Skipping ${entry.ctxName}: cannot load Context at '${entry.cs.contextLocation}'.`);
629
613
  continue;
630
614
  }
631
615
  var contextInstance;
632
616
  try{ contextInstance = new ContextCtor(); }catch(_){
633
- console.log(`Skipping ${ctxName}: failed to construct Context.`);
617
+ console.log(`Skipping ${entry.ctxName}: failed to construct Context.`);
634
618
  continue;
635
619
  }
636
620
  var migrationProjectFile = require(mFile);
637
621
  var newMigrationProjectInstance = new migrationProjectFile(ContextCtor);
638
622
  var cleanEntities = migration.cleanEntities(contextInstance.__entities);
639
- var tableObj = migration.buildUpObject(contextSnapshot.schema, cleanEntities);
640
- // Run up for this context
623
+ var tableObj = migration.buildUpObject(entry.cs.schema, cleanEntities);
641
624
  newMigrationProjectInstance.up(tableObj);
642
- // Update snapshot
643
625
  var snap = {
644
- file : contextSnapshot.contextLocation,
626
+ file : entry.cs.contextLocation,
645
627
  executedLocation : executedLocation,
646
628
  context : contextInstance,
647
629
  contextEntities : cleanEntities,
648
- contextFileName: ctxName
630
+ contextFileName: entry.ctxName
649
631
  }
650
632
  migration.createSnapShot(snap);
651
- console.log(`database updated for ${ctxName}`);
633
+ console.log(`database updated for ${entry.ctxName}`);
652
634
  }catch(errCtx){
653
635
  console.log('Error updating context: ', errCtx);
654
636
  }
@@ -15,7 +15,7 @@ class migrationMySQLQuery {
15
15
  }
16
16
  // Map belongsTo to its foreignKey name
17
17
  var name = (col.relationshipType === 'belongsTo' && col.foreignKey) ? col.foreignKey : col.name;
18
- columnList.push(name);
18
+ columnList.push(`\`${name}\``);
19
19
  }
20
20
  }
21
21
  return columnList.join(',');
@@ -63,7 +63,7 @@ class migrationMySQLQuery {
63
63
  }
64
64
  }
65
65
 
66
- return `${tableName} ${type}${nullName}${defaultValue}${unique}${primaryKey}${auto}`;
66
+ return `\`${tableName}\` ${type}${nullName}${defaultValue}${unique}${primaryKey}${auto}`;
67
67
  }
68
68
 
69
69
  boolType(type){
@@ -135,7 +135,7 @@ class migrationMySQLQuery {
135
135
 
136
136
  if(table){
137
137
 
138
- return `ALTER TABLE ${table.tableName} MODIFY COLUMN ${this.#columnMapping(table.table)} `;
138
+ return `ALTER TABLE \`${table.tableName}\` MODIFY COLUMN ${this.#columnMapping(table.table)} `;
139
139
  }
140
140
  else{
141
141
  console.log("table information is null");
@@ -152,8 +152,8 @@ class migrationMySQLQuery {
152
152
 
153
153
 
154
154
  addColum(table){
155
- return `ALTER TABLE ${table.tableName}
156
- ADD ${table.name} ${table.realDataType}`;
155
+ return `ALTER TABLE \`${table.tableName}\`
156
+ ADD \`${table.name}\` ${table.realDataType}`;
157
157
 
158
158
  /*
159
159
  column definations
@@ -172,7 +172,7 @@ class migrationMySQLQuery {
172
172
  is indexed
173
173
  appears in a view
174
174
  */
175
- return `ALTER TABLE ${table.tableName} DROP COLUMN ${table.name}`;
175
+ return `ALTER TABLE \`${table.tableName}\` DROP COLUMN \`${table.name}\``;
176
176
  }
177
177
 
178
178
  insertInto(name, table){
@@ -193,7 +193,7 @@ class migrationMySQLQuery {
193
193
  }
194
194
  }
195
195
 
196
- var completeQuery = `CREATE TABLE IF NOT EXISTS ${table.__name} (${queryVar.replace(/,\s*$/, "")});`;
196
+ var completeQuery = `CREATE TABLE IF NOT EXISTS \`${table.__name}\` (${queryVar.replace(/,\s*$/, "")});`;
197
197
  return completeQuery;
198
198
 
199
199
  /*
@@ -213,15 +213,15 @@ class migrationMySQLQuery {
213
213
 
214
214
 
215
215
  dropTable(name){
216
- return `DROP TABLE ${name}`
216
+ return `DROP TABLE \`${name}\``
217
217
  }
218
218
 
219
219
  renameTable(table){
220
- return `ALTER TABLE ${table.tableName} RENAME TO ${table.newName}`;
220
+ return `ALTER TABLE \`${table.tableName}\` RENAME TO \`${table.newName}\``;
221
221
  }
222
222
 
223
223
  renameColumn(table){
224
- return `ALTER TABLE ${table.tableName} RENAME COLUMN ${table.name} TO ${table.newName}`
224
+ return `ALTER TABLE \`${table.tableName}\` RENAME COLUMN \`${table.name}\` TO \`${table.newName}\``
225
225
  }
226
226
 
227
227
 
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "app-root-path": "^3.1.0",
10
10
  "better-sqlite3": "^12.4.1"
11
11
  },
12
- "version": "0.2.11",
12
+ "version": "0.2.13",
13
13
  "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 ",
14
14
  "homepage": "https://github.com/Tailor/MasterRecord#readme",
15
15
  "repository": {