outlet-orm 5.0.0 → 5.5.2
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 +1325 -1312
- package/bin/init.js +397 -379
- package/bin/migrate.js +544 -440
- package/bin/reverse.js +602 -0
- package/package.json +88 -76
- package/src/DatabaseConnection.js +98 -46
- package/src/Migrations/MigrationManager.js +329 -326
- package/src/Model.js +1141 -1118
- package/src/QueryBuilder.js +134 -35
- package/src/RawExpression.js +11 -0
- package/src/Relations/BelongsToManyRelation.js +466 -466
- package/src/Schema/Schema.js +830 -790
- package/src/Seeders/Seeder.js +60 -0
- package/src/Seeders/SeederManager.js +105 -0
- package/src/index.js +55 -49
- package/types/index.d.ts +674 -660
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Seeder Class
|
|
3
|
+
* All seeders should extend this class
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
function assertTableName(table) {
|
|
7
|
+
if (typeof table !== 'string' || !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {
|
|
8
|
+
throw new Error(`Invalid table name: "${table}"`);
|
|
9
|
+
}
|
|
10
|
+
return table;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class Seeder {
|
|
14
|
+
constructor(connection, manager = null) {
|
|
15
|
+
this.connection = connection;
|
|
16
|
+
this.manager = manager;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async run() {
|
|
20
|
+
throw new Error('Seeder run() method must be implemented');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async call(seeder) {
|
|
24
|
+
if (!this.manager) {
|
|
25
|
+
throw new Error('Seeder manager is required to call nested seeders');
|
|
26
|
+
}
|
|
27
|
+
await this.manager.runSeeder(seeder);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async insert(table, rows) {
|
|
31
|
+
const safeTable = assertTableName(table);
|
|
32
|
+
|
|
33
|
+
if (Array.isArray(rows)) {
|
|
34
|
+
if (rows.length === 0) return { affectedRows: 0 };
|
|
35
|
+
return await this.connection.insertMany(safeTable, rows);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return await this.connection.insert(safeTable, rows);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async truncate(table) {
|
|
42
|
+
const safeTable = assertTableName(table);
|
|
43
|
+
const driver = this.connection?.config?.driver;
|
|
44
|
+
|
|
45
|
+
switch (driver) {
|
|
46
|
+
case 'mysql':
|
|
47
|
+
await this.connection.execute(`TRUNCATE TABLE ${safeTable}`);
|
|
48
|
+
break;
|
|
49
|
+
case 'postgres':
|
|
50
|
+
case 'postgresql':
|
|
51
|
+
case 'sqlite':
|
|
52
|
+
await this.connection.execute(`DELETE FROM ${safeTable}`);
|
|
53
|
+
break;
|
|
54
|
+
default:
|
|
55
|
+
throw new Error(`Unsupported driver for truncate: ${driver}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = Seeder;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
const fs = require('fs').promises;
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
class SeederManager {
|
|
5
|
+
constructor(connection, seedsPath = './database/seeds') {
|
|
6
|
+
this.connection = connection;
|
|
7
|
+
this.seedsPath = path.resolve(process.cwd(), seedsPath);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async run(target = null) {
|
|
11
|
+
const files = await this.getSeederFiles();
|
|
12
|
+
|
|
13
|
+
if (files.length === 0) {
|
|
14
|
+
console.log('✓ No seeders found');
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const toRun = this.filterTargetSeeders(files, target);
|
|
19
|
+
|
|
20
|
+
if (toRun.length === 0) {
|
|
21
|
+
throw new Error(`Seeder not found: ${target}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
console.log(`Running ${toRun.length} seeder(s)...\n`);
|
|
25
|
+
|
|
26
|
+
for (const file of toRun) {
|
|
27
|
+
await this.runSeeder(file);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log('\n✓ Seeding completed successfully');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
filterTargetSeeders(files, target) {
|
|
34
|
+
if (!target) {
|
|
35
|
+
const databaseSeeder = files.find(file => file.toLowerCase() === 'databaseseeder.js');
|
|
36
|
+
return databaseSeeder ? [databaseSeeder] : files;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const normalizedTarget = String(target).toLowerCase();
|
|
40
|
+
|
|
41
|
+
return files.filter((file) => {
|
|
42
|
+
const base = path.basename(file, '.js').toLowerCase();
|
|
43
|
+
return file.toLowerCase() === normalizedTarget
|
|
44
|
+
|| base === normalizedTarget
|
|
45
|
+
|| `${base}.js` === normalizedTarget;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async runSeeder(seederRef) {
|
|
50
|
+
const seederPath = this.resolveSeederPath(seederRef);
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
delete require.cache[require.resolve(seederPath)];
|
|
54
|
+
const ExportedSeeder = require(seederPath);
|
|
55
|
+
const SeederClass = ExportedSeeder?.default || ExportedSeeder;
|
|
56
|
+
|
|
57
|
+
if (typeof SeederClass !== 'function') {
|
|
58
|
+
throw new Error('Seeder module must export a class');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const seeder = new SeederClass(this.connection, this);
|
|
62
|
+
|
|
63
|
+
if (typeof seeder.run !== 'function') {
|
|
64
|
+
throw new Error('Seeder class must implement run()');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
await seeder.run();
|
|
68
|
+
console.log(`✓ ${path.basename(seederPath)}`);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error(`✗ Failed to run seeder: ${path.basename(seederPath)}`);
|
|
71
|
+
console.error(error.message);
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
resolveSeederPath(seederRef) {
|
|
77
|
+
if (typeof seederRef !== 'string') {
|
|
78
|
+
throw new Error('Seeder reference must be a file path or filename string');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (path.isAbsolute(seederRef)) {
|
|
82
|
+
return seederRef;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const hasExt = path.extname(seederRef) === '.js';
|
|
86
|
+
const fileName = hasExt ? seederRef : `${seederRef}.js`;
|
|
87
|
+
return path.join(this.seedsPath, fileName);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async getSeederFiles() {
|
|
91
|
+
try {
|
|
92
|
+
const files = await fs.readdir(this.seedsPath);
|
|
93
|
+
return files
|
|
94
|
+
.filter(file => file.endsWith('.js'))
|
|
95
|
+
.sort();
|
|
96
|
+
} catch (error) {
|
|
97
|
+
if (error.code === 'ENOENT') {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports = SeederManager;
|
package/src/index.js
CHANGED
|
@@ -1,49 +1,55 @@
|
|
|
1
|
-
const Model = require('./Model');
|
|
2
|
-
const QueryBuilder = require('./QueryBuilder');
|
|
3
|
-
const DatabaseConnection = require('./DatabaseConnection');
|
|
4
|
-
|
|
5
|
-
// Relations
|
|
6
|
-
const Relation = require('./Relations/Relation');
|
|
7
|
-
const HasOneRelation = require('./Relations/HasOneRelation');
|
|
8
|
-
const HasManyRelation = require('./Relations/HasManyRelation');
|
|
9
|
-
const BelongsToRelation = require('./Relations/BelongsToRelation');
|
|
10
|
-
const BelongsToManyRelation = require('./Relations/BelongsToManyRelation');
|
|
11
|
-
const HasManyThroughRelation = require('./Relations/HasManyThroughRelation');
|
|
12
|
-
const HasOneThroughRelation = require('./Relations/HasOneThroughRelation');
|
|
13
|
-
const MorphOneRelation = require('./Relations/MorphOneRelation');
|
|
14
|
-
const MorphManyRelation = require('./Relations/MorphManyRelation');
|
|
15
|
-
const MorphToRelation = require('./Relations/MorphToRelation');
|
|
16
|
-
|
|
17
|
-
// Schema & Migrations (v5.0.0 - moved from lib/)
|
|
18
|
-
const { Schema, Blueprint, ColumnDefinition, ForeignKeyDefinition } = require('./Schema/Schema');
|
|
19
|
-
const Migration = require('./Migrations/Migration');
|
|
20
|
-
const MigrationManager = require('./Migrations/MigrationManager');
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
1
|
+
const Model = require('./Model');
|
|
2
|
+
const QueryBuilder = require('./QueryBuilder');
|
|
3
|
+
const DatabaseConnection = require('./DatabaseConnection');
|
|
4
|
+
|
|
5
|
+
// Relations
|
|
6
|
+
const Relation = require('./Relations/Relation');
|
|
7
|
+
const HasOneRelation = require('./Relations/HasOneRelation');
|
|
8
|
+
const HasManyRelation = require('./Relations/HasManyRelation');
|
|
9
|
+
const BelongsToRelation = require('./Relations/BelongsToRelation');
|
|
10
|
+
const BelongsToManyRelation = require('./Relations/BelongsToManyRelation');
|
|
11
|
+
const HasManyThroughRelation = require('./Relations/HasManyThroughRelation');
|
|
12
|
+
const HasOneThroughRelation = require('./Relations/HasOneThroughRelation');
|
|
13
|
+
const MorphOneRelation = require('./Relations/MorphOneRelation');
|
|
14
|
+
const MorphManyRelation = require('./Relations/MorphManyRelation');
|
|
15
|
+
const MorphToRelation = require('./Relations/MorphToRelation');
|
|
16
|
+
|
|
17
|
+
// Schema & Migrations (v5.0.0 - moved from lib/)
|
|
18
|
+
const { Schema, Blueprint, ColumnDefinition, ForeignKeyDefinition } = require('./Schema/Schema');
|
|
19
|
+
const Migration = require('./Migrations/Migration');
|
|
20
|
+
const MigrationManager = require('./Migrations/MigrationManager');
|
|
21
|
+
const Seeder = require('./Seeders/Seeder');
|
|
22
|
+
const SeederManager = require('./Seeders/SeederManager');
|
|
23
|
+
|
|
24
|
+
module.exports = {
|
|
25
|
+
// Core
|
|
26
|
+
Model,
|
|
27
|
+
QueryBuilder,
|
|
28
|
+
DatabaseConnection,
|
|
29
|
+
|
|
30
|
+
// Relations
|
|
31
|
+
Relation,
|
|
32
|
+
HasOneRelation,
|
|
33
|
+
HasManyRelation,
|
|
34
|
+
BelongsToRelation,
|
|
35
|
+
BelongsToManyRelation,
|
|
36
|
+
HasManyThroughRelation,
|
|
37
|
+
HasOneThroughRelation,
|
|
38
|
+
MorphOneRelation,
|
|
39
|
+
MorphManyRelation,
|
|
40
|
+
MorphToRelation,
|
|
41
|
+
|
|
42
|
+
// Schema Builder (v5.0.0)
|
|
43
|
+
Schema,
|
|
44
|
+
Blueprint,
|
|
45
|
+
ColumnDefinition,
|
|
46
|
+
ForeignKeyDefinition,
|
|
47
|
+
|
|
48
|
+
// Migrations (v5.0.0)
|
|
49
|
+
Migration,
|
|
50
|
+
MigrationManager,
|
|
51
|
+
|
|
52
|
+
// Seeders
|
|
53
|
+
Seeder,
|
|
54
|
+
SeederManager
|
|
55
|
+
};
|