velocious 1.0.580 → 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.
Files changed (40) hide show
  1. package/README.md +1 -0
  2. package/build/cli/command-arguments.js +45 -0
  3. package/build/cli/index.js +10 -0
  4. package/build/configuration-types.js +1 -0
  5. package/build/database/generation-context.js +121 -0
  6. package/build/database/initializer-from-require-context.js +7 -0
  7. package/build/environment-handlers/node/cli/commands/db/schema/dump.js +25 -0
  8. package/build/environment-handlers/node/cli/commands/db/schema/load.js +37 -8
  9. package/build/environment-handlers/node/cli/commands/generate/base-models.js +82 -13
  10. package/build/src/cli/command-arguments.d.ts +27 -0
  11. package/build/src/cli/command-arguments.d.ts.map +1 -0
  12. package/build/src/cli/command-arguments.js +38 -0
  13. package/build/src/cli/index.d.ts.map +1 -1
  14. package/build/src/cli/index.js +9 -1
  15. package/build/src/configuration-types.d.ts +8 -0
  16. package/build/src/configuration-types.d.ts.map +1 -1
  17. package/build/src/configuration-types.js +2 -1
  18. package/build/src/database/generation-context.d.ts +62 -0
  19. package/build/src/database/generation-context.d.ts.map +1 -0
  20. package/build/src/database/generation-context.js +102 -0
  21. package/build/src/database/initializer-from-require-context.d.ts.map +1 -1
  22. package/build/src/database/initializer-from-require-context.js +6 -1
  23. package/build/src/environment-handlers/node/cli/commands/db/schema/dump.d.ts.map +1 -1
  24. package/build/src/environment-handlers/node/cli/commands/db/schema/dump.js +22 -1
  25. package/build/src/environment-handlers/node/cli/commands/db/schema/load.d.ts +11 -0
  26. package/build/src/environment-handlers/node/cli/commands/db/schema/load.d.ts.map +1 -1
  27. package/build/src/environment-handlers/node/cli/commands/db/schema/load.js +33 -7
  28. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts +14 -0
  29. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
  30. package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +371 -308
  31. package/build/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +1 -1
  33. package/src/cli/command-arguments.js +45 -0
  34. package/src/cli/index.js +10 -0
  35. package/src/configuration-types.js +1 -0
  36. package/src/database/generation-context.js +121 -0
  37. package/src/database/initializer-from-require-context.js +7 -0
  38. package/src/environment-handlers/node/cli/commands/db/schema/dump.js +25 -0
  39. package/src/environment-handlers/node/cli/commands/db/schema/load.js +37 -8
  40. package/src/environment-handlers/node/cli/commands/generate/base-models.js +82 -13
@@ -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
- const enforceTenantDatabaseScopes = this.getConfiguration().getEnforceTenantDatabaseScopes()
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 allowMissingTables = Boolean(this.processArgs?.includes("--allow-missing-tables"))
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
- this.getConfiguration().setEnforceTenantDatabaseScopes(false)
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
- const table = await modelClass.connection().getTableByName(modelClass.tableName(), {throwError: !allowMissingTables})
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(BASE_MODELS_REGENERATE_COMMAND)
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