velocious 1.0.579 → 1.0.581
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 +25 -0
- package/build/cli/command-arguments.js +45 -0
- package/build/cli/index.js +10 -0
- package/build/configuration-types.js +3 -0
- package/build/database/drivers/base.js +92 -2
- package/build/database/drivers/sqlite/base.js +7 -2
- package/build/database/generation-context.js +121 -0
- package/build/database/initializer-from-require-context.js +7 -0
- package/build/environment-handlers/node/cli/commands/db/schema/dump.js +25 -0
- package/build/environment-handlers/node/cli/commands/db/schema/load.js +37 -8
- package/build/environment-handlers/node/cli/commands/generate/base-models.js +82 -13
- package/build/src/cli/command-arguments.d.ts +27 -0
- package/build/src/cli/command-arguments.d.ts.map +1 -0
- package/build/src/cli/command-arguments.js +38 -0
- package/build/src/cli/index.d.ts.map +1 -1
- package/build/src/cli/index.js +9 -1
- package/build/src/configuration-types.d.ts +18 -0
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +4 -1
- package/build/src/database/drivers/base.d.ts +38 -0
- package/build/src/database/drivers/base.d.ts.map +1 -1
- package/build/src/database/drivers/base.js +82 -3
- package/build/src/database/drivers/sqlite/base.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/base.js +6 -3
- package/build/src/database/generation-context.d.ts +62 -0
- package/build/src/database/generation-context.d.ts.map +1 -0
- package/build/src/database/generation-context.js +102 -0
- package/build/src/database/initializer-from-require-context.d.ts.map +1 -1
- package/build/src/database/initializer-from-require-context.js +6 -1
- package/build/src/environment-handlers/node/cli/commands/db/schema/dump.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/db/schema/dump.js +22 -1
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.d.ts +11 -0
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.js +33 -7
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts +14 -0
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +371 -308
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/cli/command-arguments.js +45 -0
- package/src/cli/index.js +10 -0
- package/src/configuration-types.js +3 -0
- package/src/database/drivers/base.js +92 -2
- package/src/database/drivers/sqlite/base.js +7 -2
- package/src/database/generation-context.js +121 -0
- package/src/database/initializer-from-require-context.js +7 -0
- package/src/environment-handlers/node/cli/commands/db/schema/dump.js +25 -0
- package/src/environment-handlers/node/cli/commands/db/schema/load.js +37 -8
- package/src/environment-handlers/node/cli/commands/generate/base-models.js +82 -13
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import BaseCommand from "../../../../../../cli/base-command.js"
|
|
2
|
+
import commandArguments from "../../../../../../cli/command-arguments.js"
|
|
3
|
+
import DatabaseGenerationContext from "../../../../../../database/generation-context.js"
|
|
2
4
|
import fileExists from "../../../../../../utils/file-exists.js"
|
|
3
5
|
import path from "path"
|
|
4
6
|
|
|
@@ -8,6 +10,29 @@ export default class DbSchemaDump extends BaseCommand {
|
|
|
8
10
|
* Runs execute.
|
|
9
11
|
* @returns {Promise<void>} */
|
|
10
12
|
async execute() {
|
|
13
|
+
const parsedArguments = commandArguments({
|
|
14
|
+
definition: {valueOptions: ["--tenant"]},
|
|
15
|
+
processArgs: this.processArgs || []
|
|
16
|
+
})
|
|
17
|
+
const tenantDatabaseIdentifier = parsedArguments.tenant
|
|
18
|
+
|
|
19
|
+
if (typeof tenantDatabaseIdentifier === "string") {
|
|
20
|
+
const context = await DatabaseGenerationContext.resolve({
|
|
21
|
+
configuration: this.getConfiguration(),
|
|
22
|
+
databaseIdentifier: tenantDatabaseIdentifier
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
await context.run({name: "DB selected tenant schema dump", callback: async (db) => {
|
|
26
|
+
const dbs = {[context.databaseIdentifier()]: db}
|
|
27
|
+
const shouldGenerate = await this.shouldGenerateStructureSql({dbs})
|
|
28
|
+
|
|
29
|
+
if (!shouldGenerate) return
|
|
30
|
+
|
|
31
|
+
await this.getEnvironmentHandler().afterMigrations({dbs, reason: "schemaDump"})
|
|
32
|
+
}})
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
|
|
11
36
|
await this.getConfiguration().ensureConnections({name: "DB schema dump"}, async (dbs) => {
|
|
12
37
|
const shouldGenerate = await this.shouldGenerateStructureSql({dbs})
|
|
13
38
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import BaseCommand from "../../../../../../cli/base-command.js"
|
|
2
|
+
import commandArguments from "../../../../../../cli/command-arguments.js"
|
|
3
|
+
import DatabaseGenerationContext from "../../../../../../database/generation-context.js"
|
|
2
4
|
import fs from "fs/promises"
|
|
3
5
|
import path from "path"
|
|
4
6
|
import StructureSqlLoader from "../../../../../../database/structure-sql-loader.js"
|
|
@@ -9,17 +11,44 @@ export default class DbSchemaLoad extends BaseCommand {
|
|
|
9
11
|
* Runs execute.
|
|
10
12
|
* @returns {Promise<void>} */
|
|
11
13
|
async execute() {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
const parsedArguments = commandArguments({
|
|
15
|
+
definition: {valueOptions: ["--tenant"]},
|
|
16
|
+
processArgs: this.processArgs || []
|
|
17
|
+
})
|
|
18
|
+
const tenantDatabaseIdentifier = parsedArguments.tenant
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
if (typeof tenantDatabaseIdentifier === "string") {
|
|
21
|
+
const context = await DatabaseGenerationContext.resolve({
|
|
22
|
+
configuration: this.getConfiguration(),
|
|
23
|
+
databaseIdentifier: tenantDatabaseIdentifier
|
|
24
|
+
})
|
|
20
25
|
|
|
21
|
-
|
|
26
|
+
await context.run({name: "DB selected tenant schema load", callback: async (db) => {
|
|
27
|
+
await this.loadStructureSql({db, identifier: context.databaseIdentifier()})
|
|
28
|
+
}})
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
await this.getConfiguration().ensureConnections({name: "DB schema load"}, async (dbs) => {
|
|
33
|
+
for (const identifier of Object.keys(dbs)) {
|
|
34
|
+
await this.loadStructureSql({db: dbs[identifier], identifier})
|
|
22
35
|
}
|
|
23
36
|
})
|
|
24
37
|
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Loads one identifier's explicit structure file into one selected connection.
|
|
41
|
+
* @param {object} args - Load arguments.
|
|
42
|
+
* @param {import("../../../../../../database/drivers/base.js").default} args.db - Target connection.
|
|
43
|
+
* @param {string} args.identifier - Logical database identifier used in the file name.
|
|
44
|
+
* @returns {Promise<void>} - Resolves after loading.
|
|
45
|
+
*/
|
|
46
|
+
async loadStructureSql({db, identifier}) {
|
|
47
|
+
const dbDir = path.join(this.directory(), "db")
|
|
48
|
+
const loader = new StructureSqlLoader()
|
|
49
|
+
const structureFilePath = path.join(dbDir, `structure-${identifier}.sql`)
|
|
50
|
+
const structureSql = await fs.readFile(structureFilePath, "utf8")
|
|
51
|
+
|
|
52
|
+
await loader.load({db, structureSql})
|
|
53
|
+
}
|
|
25
54
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
3
|
import BaseCommand from "../../../../../cli/base-command.js"
|
|
4
|
+
import commandArguments from "../../../../../cli/command-arguments.js"
|
|
5
|
+
import DatabaseGenerationContext from "../../../../../database/generation-context.js"
|
|
4
6
|
import deburrColumnName from "../../../../../utils/deburr-column-name.js"
|
|
5
7
|
import fileExists from "../../../../../utils/file-exists.js"
|
|
6
8
|
import fs from "fs/promises"
|
|
@@ -62,15 +64,64 @@ function generatedRelationshipMethod({abstract = false, body, name, param, retur
|
|
|
62
64
|
|
|
63
65
|
export default class DbGenerateModel extends BaseCommand {
|
|
64
66
|
async execute() {
|
|
67
|
+
const parsedArguments = commandArguments({
|
|
68
|
+
definition: {
|
|
69
|
+
booleanOptions: ["--allow-missing-tables"],
|
|
70
|
+
valueOptions: ["--tenant"]
|
|
71
|
+
},
|
|
72
|
+
processArgs: this.processArgs || []
|
|
73
|
+
})
|
|
74
|
+
const allowMissingTables = parsedArguments["allow-missing-tables"] === true
|
|
75
|
+
const tenantDatabaseIdentifier = parsedArguments.tenant
|
|
76
|
+
|
|
77
|
+
if (typeof tenantDatabaseIdentifier === "string") {
|
|
78
|
+
const context = await DatabaseGenerationContext.resolve({
|
|
79
|
+
configuration: this.getConfiguration(),
|
|
80
|
+
databaseIdentifier: tenantDatabaseIdentifier
|
|
81
|
+
})
|
|
82
|
+
const selectedModelClasses = Object.values(this.getConfiguration().getModelClasses()).filter((modelClass) => {
|
|
83
|
+
const databaseIdentifier = modelClass.getDatabaseIdentifier({
|
|
84
|
+
enforceTenantDatabaseScope: false,
|
|
85
|
+
tenant: context.tenant()
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
if (databaseIdentifier !== context.databaseIdentifier()) return false
|
|
89
|
+
|
|
90
|
+
return modelClass.getDatabaseIdentifier({tenant: context.tenant()}) === context.databaseIdentifier()
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
return await context.run({name: "Generate selected tenant base models", callback: async (connection) => {
|
|
95
|
+
await this.generateBaseModels({allowMissingTables, connections: {[context.databaseIdentifier()]: connection}, context})
|
|
96
|
+
}})
|
|
97
|
+
} finally {
|
|
98
|
+
for (const modelClass of selectedModelClasses) modelClass.resetRecordMetadata()
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
65
102
|
await this.getConfiguration().initializeModels()
|
|
66
103
|
|
|
67
|
-
|
|
104
|
+
return await this.getConfiguration().ensureConnections({name: "Generate base models"}, async (connections) => {
|
|
105
|
+
await this.generateBaseModels({allowMissingTables, connections})
|
|
106
|
+
})
|
|
107
|
+
}
|
|
68
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Generates model bases from explicit connections.
|
|
111
|
+
* @param {object} args - Generation arguments.
|
|
112
|
+
* @param {boolean} args.allowMissingTables - Whether absent tables are skipped.
|
|
113
|
+
* @param {Record<string, import("../../../../../database/drivers/base.js").default>} args.connections - Connections keyed by logical identifier.
|
|
114
|
+
* @param {DatabaseGenerationContext} [args.context] - Selected tenant database context.
|
|
115
|
+
* @returns {Promise<void>} - Resolves after writing generated bases.
|
|
116
|
+
*/
|
|
117
|
+
async generateBaseModels({allowMissingTables, connections, context}) {
|
|
69
118
|
const rootDirectory = this.directory()
|
|
70
119
|
const modelsDir = `${rootDirectory}/src/models`
|
|
71
120
|
const baseModelsDir = `${rootDirectory}/src/model-bases`
|
|
72
121
|
const modelClasses = this.getConfiguration().getModelClasses()
|
|
73
|
-
const
|
|
122
|
+
const regenerateCommand = context
|
|
123
|
+
? `${BASE_MODELS_REGENERATE_COMMAND} --tenant ${context.databaseIdentifier()}`
|
|
124
|
+
: BASE_MODELS_REGENERATE_COMMAND
|
|
74
125
|
let devMode = false
|
|
75
126
|
|
|
76
127
|
if (baseModelsDir.includes("/spec/dummy/src/model-bases")) {
|
|
@@ -81,13 +132,33 @@ export default class DbGenerateModel extends BaseCommand {
|
|
|
81
132
|
await fs.mkdir(baseModelsDir, {recursive: true})
|
|
82
133
|
}
|
|
83
134
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
try {
|
|
87
|
-
await this.getConfiguration().ensureConnections({name: "Generate base models"}, async () => {
|
|
88
|
-
for (const modelClassName in modelClasses) {
|
|
135
|
+
for (const modelClassName in modelClasses) {
|
|
89
136
|
const modelClass = modelClasses[modelClassName]
|
|
90
|
-
|
|
137
|
+
let databaseIdentifier
|
|
138
|
+
|
|
139
|
+
if (context) {
|
|
140
|
+
databaseIdentifier = modelClass.getDatabaseIdentifier({
|
|
141
|
+
enforceTenantDatabaseScope: false,
|
|
142
|
+
tenant: context.tenant()
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
if (databaseIdentifier !== context.databaseIdentifier()) continue
|
|
146
|
+
|
|
147
|
+
databaseIdentifier = modelClass.getDatabaseIdentifier({tenant: context.tenant()})
|
|
148
|
+
} else {
|
|
149
|
+
databaseIdentifier = modelClass.getConfiguredDatabaseIdentifier()
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (context && databaseIdentifier !== context.databaseIdentifier()) continue
|
|
153
|
+
|
|
154
|
+
const connection = connections[databaseIdentifier]
|
|
155
|
+
|
|
156
|
+
// Default generation continues to ignore inactive tenant-only identifiers.
|
|
157
|
+
if (!connection) continue
|
|
158
|
+
|
|
159
|
+
if (context) modelClass.resetRecordMetadata()
|
|
160
|
+
|
|
161
|
+
const table = await connection.getTableByName(modelClass.tableName(), {throwError: !allowMissingTables})
|
|
91
162
|
|
|
92
163
|
if (!table) {
|
|
93
164
|
console.warn(`Skipping base model for '${modelClass.name}': table '${modelClass.tableName()}' was not found (--allow-missing-tables). Keeping any existing base model.`)
|
|
@@ -95,6 +166,8 @@ export default class DbGenerateModel extends BaseCommand {
|
|
|
95
166
|
continue
|
|
96
167
|
}
|
|
97
168
|
|
|
169
|
+
await modelClass.ensureInitialized({configuration: this.getConfiguration(), connection})
|
|
170
|
+
|
|
98
171
|
const modelName = inflection.dasherize(modelClassName)
|
|
99
172
|
const modelNameCamelized = inflection.camelize(modelName.replaceAll("-", "_"))
|
|
100
173
|
const modelBaseFileName = `${inflection.dasherize(inflection.underscore(modelName))}.js`
|
|
@@ -111,7 +184,7 @@ export default class DbGenerateModel extends BaseCommand {
|
|
|
111
184
|
sourceModelFilePath = "velocious/build/src/database/record/index.js"
|
|
112
185
|
}
|
|
113
186
|
|
|
114
|
-
let fileContent = generatedFileBanner(
|
|
187
|
+
let fileContent = generatedFileBanner(regenerateCommand)
|
|
115
188
|
let velociousPath
|
|
116
189
|
|
|
117
190
|
if (devMode) {
|
|
@@ -454,10 +527,6 @@ export default class DbGenerateModel extends BaseCommand {
|
|
|
454
527
|
fileContent += "}\n"
|
|
455
528
|
|
|
456
529
|
await fs.writeFile(modelPath, fileContent)
|
|
457
|
-
}
|
|
458
|
-
})
|
|
459
|
-
} finally {
|
|
460
|
-
this.getConfiguration().setEnforceTenantDatabaseScopes(enforceTenantDatabaseScopes)
|
|
461
530
|
}
|
|
462
531
|
}
|
|
463
532
|
|