@solidxai/core 0.1.14 → 0.1.15-beta.1

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 (42) hide show
  1. package/CHANGELOG.md +1197 -0
  2. package/CLAUDE.md +26 -0
  3. package/dist/constants/media-file-types.d.ts +1 -0
  4. package/dist/constants/media-file-types.d.ts.map +1 -1
  5. package/dist/constants/media-file-types.js +10 -1
  6. package/dist/constants/media-file-types.js.map +1 -1
  7. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
  8. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +5 -5
  9. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js.map +1 -1
  10. package/dist/helpers/user-helper.d.ts.map +1 -1
  11. package/dist/helpers/user-helper.js +2 -0
  12. package/dist/helpers/user-helper.js.map +1 -1
  13. package/dist/seeders/seed-data/solid-core-metadata.json +0 -2
  14. package/dist/services/import-transaction.service.d.ts +1 -0
  15. package/dist/services/import-transaction.service.d.ts.map +1 -1
  16. package/dist/services/import-transaction.service.js +21 -0
  17. package/dist/services/import-transaction.service.js.map +1 -1
  18. package/dist/services/model-metadata.service.d.ts +0 -1
  19. package/dist/services/model-metadata.service.d.ts.map +1 -1
  20. package/dist/services/model-metadata.service.js +0 -13
  21. package/dist/services/model-metadata.service.js.map +1 -1
  22. package/dist/solid-core.module.d.ts.map +1 -1
  23. package/dist/solid-core.module.js +0 -4
  24. package/dist/solid-core.module.js.map +1 -1
  25. package/package.json +1 -1
  26. package/src/constants/media-file-types.ts +18 -2
  27. package/src/helpers/field-crud-managers/MediaFieldCrudManager.ts +14 -6
  28. package/src/helpers/user-helper.ts +2 -0
  29. package/src/seeders/seed-data/solid-core-metadata.json +0 -2
  30. package/src/services/import-transaction.service.ts +35 -0
  31. package/src/services/model-metadata.service.ts +0 -25
  32. package/src/solid-core.module.ts +0 -4
  33. package/dist/commands/migrate-removed-fields.command.d.ts +0 -19
  34. package/dist/commands/migrate-removed-fields.command.d.ts.map +0 -1
  35. package/dist/commands/migrate-removed-fields.command.js +0 -77
  36. package/dist/commands/migrate-removed-fields.command.js.map +0 -1
  37. package/dist/services/removed-field-migration.service.d.ts +0 -30
  38. package/dist/services/removed-field-migration.service.d.ts.map +0 -1
  39. package/dist/services/removed-field-migration.service.js +0 -319
  40. package/dist/services/removed-field-migration.service.js.map +0 -1
  41. package/src/commands/migrate-removed-fields.command.ts +0 -81
  42. package/src/services/removed-field-migration.service.ts +0 -334
@@ -1541,7 +1541,6 @@ export class ModelMetadataService {
1541
1541
  //Filter out the fields by id
1542
1542
  const fieldsForRemoval = model.fields.filter((field) => options.fieldIdsForRemoval.includes(+field.id));
1543
1543
  const removeOutput = await this.executeRemoveFieldsCommand(model, fieldsForRemoval, options.dryRun);
1544
- const migrationOutput = await this.executeMigrationRemoveFieldsCommand(model, fieldsForRemoval, options.dryRun);
1545
1544
  // Remove the fields from the database as well. This also checks, if the field is marked for removal
1546
1545
  for (const field of fieldsForRemoval) {
1547
1546
  if (field.isMarkedForRemoval) {
@@ -1578,14 +1577,6 @@ export class ModelMetadataService {
1578
1577
 
1579
1578
  return removeOutput;
1580
1579
  }
1581
- // model-metadata.service.ts mein naya method add karo
1582
- // async executeRemoveFieldsWithModel(model: ModelMetadata, fieldNames: string[], dryRun = false,) {
1583
- // const fieldsForRemoval = model.fields.filter(
1584
- // field => fieldNames.includes(field.name)
1585
- // );
1586
- // return this.executeRemoveFieldsCommand(model, fieldsForRemoval, dryRun);
1587
- // }
1588
-
1589
1580
  async generateModelCode(options: CodeGenerationOptions): Promise<string> {
1590
1581
  if (!options.modelId && !options.modelUserKey) {
1591
1582
  throw new BadRequestException(ERROR_MESSAGES.MODEL_REQUIRED_FOR_CODE_GENERATION);
@@ -1633,22 +1624,6 @@ export class ModelMetadataService {
1633
1624
  return output;
1634
1625
  }
1635
1626
 
1636
- private async executeMigrationRemoveFieldsCommand(model: ModelMetadata, fieldsForRemoval: FieldMetadata[], dryRun: boolean = false,): Promise<string> {
1637
- if (!fieldsForRemoval || fieldsForRemoval.length === 0) {
1638
- return "";
1639
- }
1640
-
1641
- const output = await this.commandService.executeCommandWithArgs({
1642
- command: 'npx',
1643
- args: ['@solidxai/solidctl@latest', 'migration', '-n', model.singularName, 'remove-field', ...(dryRun ? [] : ['--apply'])],
1644
- cwd: path.join(process.cwd(), '..'),
1645
- });
1646
-
1647
- this.logger.debug(`Schematic output : ${output}`);
1648
- return output;
1649
- }
1650
-
1651
-
1652
1627
  async updateUserKey(data: any) {
1653
1628
  const { modelName, fieldName } = data;
1654
1629
 
@@ -12,7 +12,6 @@ import {
12
12
  import { MulterModule } from "@nestjs/platform-express";
13
13
  import { TypeOrmModule } from "@nestjs/typeorm";
14
14
  import { RemoveFieldsCommand } from "./commands/remove-fields.command";
15
- import { MigrateRemovedFieldsCommand } from "./commands/migrate-removed-fields.command";
16
15
  import { FieldMetadataController } from "./controllers/field-metadata.controller";
17
16
  import { DashboardController } from "./controllers/dashboard.controller";
18
17
  import { MediaStorageProviderMetadataController } from "./controllers/media-storage-provider-metadata.controller";
@@ -50,7 +49,6 @@ import { MediaStorageProviderMetadataService } from "./services/media-storage-pr
50
49
  import { MediaService } from "./services/media.service";
51
50
  import { MediaDownloadUrlService } from "./services/media-download-url.service";
52
51
  import { ModelMetadataService } from "./services/model-metadata.service";
53
- import { RemovedFieldMigrationService } from "./services/removed-field-migration.service";
54
52
  import { ModuleMetadataExplorerService } from "./services/module-metadata-explorer.service";
55
53
  import { ModuleMetadataService } from "./services/module-metadata.service";
56
54
  import { ModulePackageService } from "./services/module-package.service";
@@ -675,7 +673,6 @@ import { SwitchNode } from './services/workflow/nodes/switch.node';
675
673
  FieldMetadataService,
676
674
  DashboardRuntimeService,
677
675
  RemoveFieldsCommand,
678
- MigrateRemovedFieldsCommand,
679
676
  RefreshModelCommand,
680
677
  RefreshModuleCommand,
681
678
  InfoCommand,
@@ -942,7 +939,6 @@ import { SwitchNode } from './services/workflow/nodes/switch.node';
942
939
  UserViewMetadataRepository,
943
940
  ModelMetadataRepository,
944
941
  ModuleMetadataRepository,
945
- RemovedFieldMigrationService,
946
942
  ActionMetadataRepository,
947
943
  MediaStorageProviderMetadataRepository,
948
944
  FixturesService,
@@ -1,19 +0,0 @@
1
- import { CommandRunner } from "nest-commander";
2
- import { RemovedFieldMigrationService } from "../services/removed-field-migration.service";
3
- import { ModelMetadataService } from "../services/model-metadata.service";
4
- interface CommandOptions {
5
- name: string;
6
- dryRun?: boolean;
7
- }
8
- export declare class MigrateRemovedFieldsCommand extends CommandRunner {
9
- private readonly removedFieldMigrationService;
10
- private readonly modelMetadataService;
11
- constructor(removedFieldMigrationService: RemovedFieldMigrationService, modelMetadataService: ModelMetadataService);
12
- private readonly logger;
13
- run(_passedParam: string[], options?: CommandOptions): Promise<void>;
14
- parseName(val: string): string;
15
- parseDryRun(val: string): boolean;
16
- private validate;
17
- }
18
- export {};
19
- //# sourceMappingURL=migrate-removed-fields.command.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"migrate-removed-fields.command.d.ts","sourceRoot":"","sources":["../../src/commands/migrate-removed-fields.command.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,aAAa,EAAU,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,4BAA4B,EAAE,MAAM,8CAA8C,CAAC;AAE5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,UAAU,cAAc;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,qBAIa,2BAA4B,SAAQ,aAAa;IAEtD,OAAO,CAAC,QAAQ,CAAC,4BAA4B;IAC7C,OAAO,CAAC,QAAQ,CAAC,oBAAoB;gBADpB,4BAA4B,EAAE,4BAA4B,EAC1D,oBAAoB,EAAE,oBAAoB;IAM/D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgD;IAEjE,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAmC1E,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAQ9B,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAKjC,OAAO,CAAC,QAAQ;CAMnB"}
@@ -1,77 +0,0 @@
1
- "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
11
- var MigrateRemovedFieldsCommand_1;
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.MigrateRemovedFieldsCommand = void 0;
14
- const common_1 = require("@nestjs/common");
15
- const nest_commander_1 = require("nest-commander");
16
- const removed_field_migration_service_1 = require("../services/removed-field-migration.service");
17
- const helper_1 = require("./helper");
18
- const model_metadata_service_1 = require("../services/model-metadata.service");
19
- let MigrateRemovedFieldsCommand = MigrateRemovedFieldsCommand_1 = class MigrateRemovedFieldsCommand extends nest_commander_1.CommandRunner {
20
- constructor(removedFieldMigrationService, modelMetadataService) {
21
- super();
22
- this.removedFieldMigrationService = removedFieldMigrationService;
23
- this.modelMetadataService = modelMetadataService;
24
- this.logger = new common_1.Logger(MigrateRemovedFieldsCommand_1.name);
25
- }
26
- async run(_passedParam, options) {
27
- const errors = this.validate(options);
28
- if (errors.length) {
29
- errors.forEach((error) => this.logger.error(error));
30
- return;
31
- }
32
- const dryRun = options?.dryRun ?? true;
33
- const result = await this.removedFieldMigrationService.migrateMarkedFields(options.name, dryRun);
34
- result.operations.forEach((operation) => this.logger.log(operation));
35
- }
36
- parseName(val) {
37
- return val;
38
- }
39
- parseDryRun(val) {
40
- this.logger.debug(`Dry run : ${val}`);
41
- return val === "false" ? false : true;
42
- }
43
- validate(options) {
44
- if (!options?.name) {
45
- return [new helper_1.CommandError("Model Name is required")];
46
- }
47
- return [];
48
- }
49
- };
50
- exports.MigrateRemovedFieldsCommand = MigrateRemovedFieldsCommand;
51
- __decorate([
52
- (0, nest_commander_1.Option)({
53
- flags: "-n, --name <model name>",
54
- description: "Model name (singularName) from the ss_model_metadata table",
55
- }),
56
- __metadata("design:type", Function),
57
- __metadata("design:paramtypes", [String]),
58
- __metadata("design:returntype", String)
59
- ], MigrateRemovedFieldsCommand.prototype, "parseName", null);
60
- __decorate([
61
- (0, nest_commander_1.Option)({
62
- flags: "-d, --dryRun [dry run]",
63
- description: "Dry run the command",
64
- }),
65
- __metadata("design:type", Function),
66
- __metadata("design:paramtypes", [String]),
67
- __metadata("design:returntype", Boolean)
68
- ], MigrateRemovedFieldsCommand.prototype, "parseDryRun", null);
69
- exports.MigrateRemovedFieldsCommand = MigrateRemovedFieldsCommand = MigrateRemovedFieldsCommand_1 = __decorate([
70
- (0, nest_commander_1.Command)({
71
- name: "migrate-removed-fields",
72
- description: "Drops live database artifacts for fields marked for removal and cleans the related metadata.",
73
- }),
74
- __metadata("design:paramtypes", [removed_field_migration_service_1.RemovedFieldMigrationService,
75
- model_metadata_service_1.ModelMetadataService])
76
- ], MigrateRemovedFieldsCommand);
77
- //# sourceMappingURL=migrate-removed-fields.command.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"migrate-removed-fields.command.js","sourceRoot":"","sources":["../../src/commands/migrate-removed-fields.command.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAwC;AACxC,mDAAgE;AAChE,iGAA4F;AAC5F,qCAAwC;AACxC,+EAA2E;AAWpE,IAAM,2BAA2B,mCAAjC,MAAM,2BAA4B,SAAQ,8BAAa;IAC1D,YACqB,4BAA0D,EAC1D,oBAA0C;QAG3D,KAAK,EAAE,CAAC;QAJS,iCAA4B,GAA5B,4BAA4B,CAA8B;QAC1D,yBAAoB,GAApB,oBAAoB,CAAsB;QAM9C,WAAM,GAAG,IAAI,eAAM,CAAC,6BAA2B,CAAC,IAAI,CAAC,CAAC;IAFvE,CAAC;IAID,KAAK,CAAC,GAAG,CAAC,YAAsB,EAAE,OAAwB;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YACpD,OAAO;QACX,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,IAAI,CAAC;QAmBvC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,4BAA4B,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAE,CAAC;QAElG,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IACzE,CAAC;IAMD,SAAS,CAAC,GAAW;QACjB,OAAO,GAAG,CAAC;IACf,CAAC;IAMD,WAAW,CAAC,GAAW;QACnB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC;QACtC,OAAO,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1C,CAAC;IAEO,QAAQ,CAAC,OAAuB;QACpC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,qBAAY,CAAC,wBAAwB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,EAAE,CAAC;IACd,CAAC;CACJ,CAAA;AAjEY,kEAA2B;AA8CpC;IAJC,IAAA,uBAAM,EAAC;QACJ,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE,4DAA4D;KAC5E,CAAC;;;;4DAGD;AAMD;IAJC,IAAA,uBAAM,EAAC;QACJ,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EAAE,qBAAqB;KACrC,CAAC;;;;8DAID;sCAzDQ,2BAA2B;IAJvC,IAAA,wBAAO,EAAC;QACL,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,8FAA8F;KAC9G,CAAC;qCAGqD,8DAA4B;QACpC,6CAAoB;GAHtD,2BAA2B,CAiEvC","sourcesContent":["import { Logger } from \"@nestjs/common\";\nimport { Command, CommandRunner, Option } from \"nest-commander\";\nimport { RemovedFieldMigrationService } from \"src/services/removed-field-migration.service\";\nimport { CommandError } from \"./helper\";\nimport { ModelMetadataService } from \"src/services/model-metadata.service\";\n\ninterface CommandOptions {\n name: string;\n dryRun?: boolean;\n}\n\n@Command({\n name: \"migrate-removed-fields\",\n description: \"Drops live database artifacts for fields marked for removal and cleans the related metadata.\",\n})\nexport class MigrateRemovedFieldsCommand extends CommandRunner {\n constructor(\n private readonly removedFieldMigrationService: RemovedFieldMigrationService,\n private readonly modelMetadataService: ModelMetadataService,\n\n ) {\n super();\n }\n\n private readonly logger = new Logger(MigrateRemovedFieldsCommand.name);\n\n async run(_passedParam: string[], options?: CommandOptions): Promise<void> {\n const errors = this.validate(options);\n if (errors.length) {\n errors.forEach((error) => this.logger.error(error));\n return;\n }\n\n const dryRun = options?.dryRun ?? true;\n\n // STEP 1: Capture fields BEFORE migration deletes metadata\n // const model = await this.modelMetadataService.findOneByUserKey(\n // options.name,\n // [\"module\", \"fields\"],\n // );\n\n // const fieldsForRemoval = model.fields.filter(\n // field => field.isMarkedForRemoval,\n // );\n\n // // STEP 2: Run remove-fields schematic first\n // if (!dryRun && fieldsForRemoval.length > 0) {\n // // await this.modelMetadataService.executeRemoveFieldsOnly(options.name,fieldsForRemoval.map(f => f.name),false,);\n // await this.modelMetadataService.executeRemoveFieldsWithModel(model, fieldsForRemoval.map(f => f.name),false,);\n // }\n\n // STEP 3: Then perform DB + metadata cleanup\n const result = await this.removedFieldMigrationService.migrateMarkedFields(options.name, dryRun,);\n\n result.operations.forEach((operation) => this.logger.log(operation));\n }\n\n @Option({\n flags: \"-n, --name <model name>\",\n description: \"Model name (singularName) from the ss_model_metadata table\",\n })\n parseName(val: string): string {\n return val;\n }\n\n @Option({\n flags: \"-d, --dryRun [dry run]\",\n description: \"Dry run the command\",\n })\n parseDryRun(val: string): boolean {\n this.logger.debug(`Dry run : ${val}`);\n return val === \"false\" ? false : true;\n }\n\n private validate(options: CommandOptions): CommandError[] {\n if (!options?.name) {\n return [new CommandError(\"Model Name is required\")];\n }\n return [];\n }\n}\n"]}
@@ -1,30 +0,0 @@
1
- import { ModuleRef } from "@nestjs/core";
2
- import { ModuleMetadataHelperService } from "../helpers/module-metadata-helper.service";
3
- import { FieldMetadataRepository } from "../repository/field-metadata.repository";
4
- import { ModelMetadataRepository } from "../repository/model-metadata.repository";
5
- export interface RemovedFieldMigrationResult {
6
- dryRun: boolean;
7
- modelName: string;
8
- operations: string[];
9
- removedFieldNames: string[];
10
- }
11
- export declare class RemovedFieldMigrationService {
12
- private readonly modelMetadataRepo;
13
- private readonly fieldMetadataRepo;
14
- private readonly moduleMetadataHelperService;
15
- private readonly moduleRef;
16
- constructor(modelMetadataRepo: ModelMetadataRepository, fieldMetadataRepo: FieldMetadataRepository, moduleMetadataHelperService: ModuleMetadataHelperService, moduleRef: ModuleRef);
17
- private readonly logger;
18
- migrateMarkedFields(modelUserKey: string, dryRun?: boolean): Promise<RemovedFieldMigrationResult>;
19
- private cleanupMarkedField;
20
- private dropColumnsForField;
21
- private dropColumnArtifacts;
22
- private dropJoinTable;
23
- private buildColumnCandidates;
24
- private resolveDataSource;
25
- private resolveEntityMetadata;
26
- private resolveMetadataFilePath;
27
- private fileExists;
28
- private loadTable;
29
- }
30
- //# sourceMappingURL=removed-field-migration.service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"removed-field-migration.service.d.ts","sourceRoot":"","sources":["../../src/services/removed-field-migration.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAQzC,OAAO,EAAE,2BAA2B,EAAE,MAAM,4CAA4C,CAAC;AAEzF,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AACnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AAGnF,MAAM,WAAW,2BAA2B;IACxC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,qBACa,4BAA4B;IAEjC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,2BAA2B;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAHT,iBAAiB,EAAE,uBAAuB,EAC1C,iBAAiB,EAAE,uBAAuB,EAC1C,2BAA2B,EAAE,2BAA2B,EACxD,SAAS,EAAE,SAAS;IAGzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiD;IAGlE,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,GAAE,OAAe,GAAG,OAAO,CAAC,2BAA2B,CAAC;YAuEhG,kBAAkB;YAsClB,mBAAmB;YAoCnB,mBAAmB;YA4BnB,aAAa;IAa3B,OAAO,CAAC,qBAAqB;YAkCf,iBAAiB;IAsB/B,OAAO,CAAC,qBAAqB;YAcf,uBAAuB;YAqBvB,UAAU;YASV,SAAS;CAY1B"}
@@ -1,319 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
- return c > 3 && r && Object.defineProperty(target, key, r), r;
23
- };
24
- var __importStar = (this && this.__importStar) || (function () {
25
- var ownKeys = function(o) {
26
- ownKeys = Object.getOwnPropertyNames || function (o) {
27
- var ar = [];
28
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
- return ar;
30
- };
31
- return ownKeys(o);
32
- };
33
- return function (mod) {
34
- if (mod && mod.__esModule) return mod;
35
- var result = {};
36
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
- __setModuleDefault(result, mod);
38
- return result;
39
- };
40
- })();
41
- var __metadata = (this && this.__metadata) || function (k, v) {
42
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
- };
44
- var RemovedFieldMigrationService_1;
45
- Object.defineProperty(exports, "__esModule", { value: true });
46
- exports.RemovedFieldMigrationService = void 0;
47
- const fs = __importStar(require("fs/promises"));
48
- const common_1 = require("@nestjs/common");
49
- const core_1 = require("@nestjs/core");
50
- const typeorm_1 = require("@nestjs/typeorm");
51
- const lodash_1 = require("lodash");
52
- const path = __importStar(require("path"));
53
- const error_messages_1 = require("../constants/error-messages");
54
- const create_field_metadata_dto_1 = require("../dtos/create-field-metadata.dto");
55
- const module_metadata_helper_service_1 = require("../helpers/module-metadata-helper.service");
56
- const string_helper_1 = require("../helpers/string.helper");
57
- const field_metadata_repository_1 = require("../repository/field-metadata.repository");
58
- const model_metadata_repository_1 = require("../repository/model-metadata.repository");
59
- let RemovedFieldMigrationService = RemovedFieldMigrationService_1 = class RemovedFieldMigrationService {
60
- constructor(modelMetadataRepo, fieldMetadataRepo, moduleMetadataHelperService, moduleRef) {
61
- this.modelMetadataRepo = modelMetadataRepo;
62
- this.fieldMetadataRepo = fieldMetadataRepo;
63
- this.moduleMetadataHelperService = moduleMetadataHelperService;
64
- this.moduleRef = moduleRef;
65
- this.logger = new common_1.Logger(RemovedFieldMigrationService_1.name);
66
- }
67
- async migrateMarkedFields(modelUserKey, dryRun = false) {
68
- if (!modelUserKey) {
69
- throw new common_1.BadRequestException("Model name is required");
70
- }
71
- const model = await this.modelMetadataRepo.findOne({
72
- where: { singularName: modelUserKey },
73
- relations: { fields: true, module: true },
74
- });
75
- if (!model) {
76
- throw new common_1.NotFoundException(error_messages_1.ERROR_MESSAGES.MODEL_NOT_FOUND(modelUserKey));
77
- }
78
- const fieldsForRemoval = model.fields.filter((field) => field.isMarkedForRemoval);
79
- const operations = [];
80
- if (fieldsForRemoval.length === 0) {
81
- const message = `No fields marked for removal were found for model "${model.singularName}".`;
82
- this.logger.log(message);
83
- operations.push(message);
84
- return {
85
- dryRun,
86
- modelName: model.singularName,
87
- operations,
88
- removedFieldNames: [],
89
- };
90
- }
91
- const dataSource = await this.resolveDataSource(model.dataSource);
92
- const entityMetadata = this.resolveEntityMetadata(dataSource, model);
93
- const queryRunner = dataSource.createQueryRunner();
94
- try {
95
- await queryRunner.connect();
96
- if (!dryRun) {
97
- await queryRunner.startTransaction();
98
- }
99
- for (const field of fieldsForRemoval) {
100
- await this.cleanupMarkedField({
101
- field,
102
- model,
103
- entityMetadata,
104
- queryRunner,
105
- dryRun,
106
- operations,
107
- });
108
- }
109
- if (!dryRun) {
110
- await queryRunner.commitTransaction();
111
- }
112
- }
113
- catch (error) {
114
- if (!dryRun && queryRunner.isTransactionActive) {
115
- await queryRunner.rollbackTransaction();
116
- }
117
- throw error;
118
- }
119
- finally {
120
- await queryRunner.release();
121
- }
122
- return {
123
- dryRun,
124
- modelName: model.singularName,
125
- operations,
126
- removedFieldNames: fieldsForRemoval.map((field) => field.name),
127
- };
128
- }
129
- async cleanupMarkedField(params) {
130
- const { field, model, entityMetadata, queryRunner, dryRun, operations } = params;
131
- const relationMetadata = entityMetadata?.relations.find((relation) => relation.propertyName === field.name);
132
- const resolvedTableName = entityMetadata?.tableName || model.tableName;
133
- if (field.type !== create_field_metadata_dto_1.SolidFieldType.relation) {
134
- const columnCandidates = this.buildColumnCandidates(field, entityMetadata, relationMetadata);
135
- await this.dropColumnsForField(resolvedTableName, field, columnCandidates, queryRunner, dryRun, operations);
136
- return;
137
- }
138
- if (field.relationType === create_field_metadata_dto_1.RelationType.manyToOne) {
139
- const columnCandidates = this.buildColumnCandidates(field, entityMetadata, relationMetadata);
140
- await this.dropColumnsForField(resolvedTableName, field, columnCandidates, queryRunner, dryRun, operations);
141
- return;
142
- }
143
- if (field.relationType === create_field_metadata_dto_1.RelationType.manyTomany) {
144
- const joinTableName = relationMetadata?.junctionEntityMetadata?.tableName || field.relationJoinTableName;
145
- const ownsJoinTable = relationMetadata?.isOwning || field.isRelationManyToManyOwner;
146
- if (!ownsJoinTable) {
147
- operations.push(`No direct database cleanup required for inverse many-to-many field "${field.name}".`);
148
- return;
149
- }
150
- if (!joinTableName) {
151
- operations.push(`Skipping join-table cleanup for "${field.name}" because no join table name could be resolved.`);
152
- return;
153
- }
154
- await this.dropJoinTable(joinTableName, field, queryRunner, dryRun, operations);
155
- return;
156
- }
157
- operations.push(`No direct database cleanup required for relation field "${field.name}" with type "${field.relationType}".`);
158
- }
159
- async dropColumnsForField(tableName, field, columnCandidates, queryRunner, dryRun, operations) {
160
- if (!tableName) {
161
- operations.push(`Skipping field "${field.name}" because the model table name could not be resolved.`);
162
- return;
163
- }
164
- if (columnCandidates.length === 0) {
165
- operations.push(`Skipping field "${field.name}" because no column candidates could be resolved.`);
166
- return;
167
- }
168
- const handledColumns = new Set();
169
- let droppedAnyColumn = false;
170
- for (const columnName of columnCandidates) {
171
- if (!columnName || handledColumns.has(columnName)) {
172
- continue;
173
- }
174
- handledColumns.add(columnName);
175
- const table = await this.loadTable(queryRunner, tableName);
176
- const column = table?.columns.find((tableColumn) => tableColumn.name === columnName);
177
- if (!column) {
178
- continue;
179
- }
180
- droppedAnyColumn = true;
181
- await this.dropColumnArtifacts(table, columnName, queryRunner, dryRun, operations);
182
- }
183
- if (!droppedAnyColumn) {
184
- operations.push(`No database column found for field "${field.name}" on table "${tableName}". Metadata cleanup will still proceed.`);
185
- }
186
- }
187
- async dropColumnArtifacts(table, columnName, queryRunner, dryRun, operations) {
188
- for (const foreignKey of table.foreignKeys.filter((item) => item.columnNames.includes(columnName))) {
189
- operations.push(`Drop foreign key "${foreignKey.name}" on "${table.name}.${columnName}"`);
190
- if (!dryRun) {
191
- await queryRunner.dropForeignKey(table, foreignKey);
192
- }
193
- }
194
- for (const uniqueConstraint of table.uniques.filter((item) => item.columnNames.includes(columnName))) {
195
- operations.push(`Drop unique constraint "${uniqueConstraint.name}" on "${table.name}.${columnName}"`);
196
- if (!dryRun) {
197
- await queryRunner.dropUniqueConstraint(table, uniqueConstraint);
198
- }
199
- }
200
- for (const index of table.indices.filter((item) => item.columnNames.includes(columnName))) {
201
- operations.push(`Drop index "${index.name}" on "${table.name}.${columnName}"`);
202
- if (!dryRun) {
203
- await queryRunner.dropIndex(table, index);
204
- }
205
- }
206
- operations.push(`Drop column "${table.name}.${columnName}"`);
207
- if (!dryRun) {
208
- await queryRunner.dropColumn(table, columnName);
209
- }
210
- }
211
- async dropJoinTable(joinTableName, field, queryRunner, dryRun, operations) {
212
- const table = await this.loadTable(queryRunner, joinTableName);
213
- if (!table) {
214
- operations.push(`Join table "${joinTableName}" for field "${field.name}" does not exist. Metadata cleanup will still proceed.`);
215
- return;
216
- }
217
- operations.push(`Drop join table "${joinTableName}" for field "${field.name}"`);
218
- if (!dryRun) {
219
- await queryRunner.dropTable(joinTableName);
220
- }
221
- }
222
- buildColumnCandidates(field, entityMetadata, relationMetadata) {
223
- const columnCandidates = new Set();
224
- relationMetadata?.joinColumns?.forEach((column) => {
225
- if (column.databaseName) {
226
- columnCandidates.add(column.databaseName);
227
- }
228
- });
229
- entityMetadata?.columns
230
- .filter((column) => column.propertyName === field.name)
231
- .forEach((column) => {
232
- if (column.databaseName) {
233
- columnCandidates.add(column.databaseName);
234
- }
235
- });
236
- if (field.columnName) {
237
- columnCandidates.add(field.columnName);
238
- }
239
- if (field.relationCoModelColumnName) {
240
- columnCandidates.add(field.relationCoModelColumnName);
241
- }
242
- if (field.type === create_field_metadata_dto_1.SolidFieldType.relation && field.relationType === create_field_metadata_dto_1.RelationType.manyToOne) {
243
- columnCandidates.add(`${(0, lodash_1.snakeCase)(field.name)}_id`);
244
- }
245
- else {
246
- columnCandidates.add((0, lodash_1.snakeCase)(field.name));
247
- }
248
- return [...columnCandidates].filter(Boolean);
249
- }
250
- async resolveDataSource(dataSourceName) {
251
- const normalizedDataSourceName = dataSourceName && dataSourceName !== "default" ? dataSourceName : undefined;
252
- const token = normalizedDataSourceName ? (0, typeorm_1.getDataSourceToken)(normalizedDataSourceName) : (0, typeorm_1.getDataSourceToken)();
253
- let dataSource;
254
- try {
255
- dataSource = this.moduleRef.get(token, { strict: false });
256
- }
257
- catch (error) {
258
- throw new common_1.NotFoundException(`Datasource "${normalizedDataSourceName ?? "default"}" could not be resolved: ${error?.message ?? error}`);
259
- }
260
- if (!dataSource) {
261
- throw new common_1.NotFoundException(`Datasource "${normalizedDataSourceName ?? "default"}" could not be resolved.`);
262
- }
263
- if (!dataSource.isInitialized) {
264
- await dataSource.initialize();
265
- }
266
- return dataSource;
267
- }
268
- resolveEntityMetadata(dataSource, model) {
269
- const candidates = [(0, string_helper_1.classify)(model.singularName), model.singularName, model.tableName].filter(Boolean);
270
- for (const candidate of candidates) {
271
- try {
272
- return dataSource.getMetadata(candidate);
273
- }
274
- catch {
275
- }
276
- }
277
- return dataSource.entityMetadatas.find((metadata) => metadata.tableName === model.tableName);
278
- }
279
- async resolveMetadataFilePath(moduleName) {
280
- const defaultPath = await this.moduleMetadataHelperService.getModuleMetadataFilePath(moduleName);
281
- if (await this.fileExists(defaultPath)) {
282
- return defaultPath;
283
- }
284
- const dashModuleName = (0, lodash_1.kebabCase)(moduleName);
285
- const moduleMetadataFilePath = path.resolve(process.cwd(), "module-metadata", dashModuleName, `${dashModuleName}-metadata.json`);
286
- if (await this.fileExists(moduleMetadataFilePath)) {
287
- return moduleMetadataFilePath;
288
- }
289
- return defaultPath;
290
- }
291
- async fileExists(filePath) {
292
- try {
293
- await fs.access(filePath);
294
- return true;
295
- }
296
- catch {
297
- return false;
298
- }
299
- }
300
- async loadTable(queryRunner, tableName) {
301
- if (!tableName) {
302
- return undefined;
303
- }
304
- const hasTable = await queryRunner.hasTable(tableName);
305
- if (!hasTable) {
306
- return undefined;
307
- }
308
- return queryRunner.getTable(tableName) ?? undefined;
309
- }
310
- };
311
- exports.RemovedFieldMigrationService = RemovedFieldMigrationService;
312
- exports.RemovedFieldMigrationService = RemovedFieldMigrationService = RemovedFieldMigrationService_1 = __decorate([
313
- (0, common_1.Injectable)(),
314
- __metadata("design:paramtypes", [model_metadata_repository_1.ModelMetadataRepository,
315
- field_metadata_repository_1.FieldMetadataRepository,
316
- module_metadata_helper_service_1.ModuleMetadataHelperService,
317
- core_1.ModuleRef])
318
- ], RemovedFieldMigrationService);
319
- //# sourceMappingURL=removed-field-migration.service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"removed-field-migration.service.js","sourceRoot":"","sources":["../../src/services/removed-field-migration.service.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from \"fs/promises\";\nimport { BadRequestException, Injectable, Logger, NotFoundException } from \"@nestjs/common\";\nimport { ModuleRef } from \"@nestjs/core\";\nimport { getDataSourceToken } from \"@nestjs/typeorm\";\nimport { kebabCase, snakeCase } from \"lodash\";\nimport * as path from \"path\";\nimport { ERROR_MESSAGES } from \"src/constants/error-messages\";\nimport { RelationType, SolidFieldType } from \"src/dtos/create-field-metadata.dto\";\nimport { FieldMetadata } from \"src/entities/field-metadata.entity\";\nimport { ModelMetadata } from \"src/entities/model-metadata.entity\";\nimport { ModuleMetadataHelperService } from \"src/helpers/module-metadata-helper.service\";\nimport { classify } from \"src/helpers/string.helper\";\nimport { FieldMetadataRepository } from \"src/repository/field-metadata.repository\";\nimport { ModelMetadataRepository } from \"src/repository/model-metadata.repository\";\nimport { DataSource, EntityMetadata, QueryRunner, Table } from \"typeorm\";\n\nexport interface RemovedFieldMigrationResult {\n dryRun: boolean;\n modelName: string;\n operations: string[];\n removedFieldNames: string[];\n}\n\n@Injectable()\nexport class RemovedFieldMigrationService {\n constructor(\n private readonly modelMetadataRepo: ModelMetadataRepository,\n private readonly fieldMetadataRepo: FieldMetadataRepository,\n private readonly moduleMetadataHelperService: ModuleMetadataHelperService,\n private readonly moduleRef: ModuleRef,\n ) { }\n\n private readonly logger = new Logger(RemovedFieldMigrationService.name);\n\n // Cleans fields marked for removal by updating schema state and metadata for a single model.\n async migrateMarkedFields(modelUserKey: string, dryRun: boolean = false): Promise<RemovedFieldMigrationResult> {\n if (!modelUserKey) {\n throw new BadRequestException(\"Model name is required\");\n }\n\n const model = await this.modelMetadataRepo.findOne({\n where: { singularName: modelUserKey },\n relations: { fields: true, module: true },\n });\n\n if (!model) {\n throw new NotFoundException(ERROR_MESSAGES.MODEL_NOT_FOUND(modelUserKey));\n }\n\n const fieldsForRemoval = model.fields.filter((field) => field.isMarkedForRemoval);\n const operations: string[] = [];\n\n if (fieldsForRemoval.length === 0) {\n const message = `No fields marked for removal were found for model \"${model.singularName}\".`;\n this.logger.log(message);\n operations.push(message);\n return {\n dryRun,\n modelName: model.singularName,\n operations,\n removedFieldNames: [],\n };\n }\n\n const dataSource = await this.resolveDataSource(model.dataSource);\n const entityMetadata = this.resolveEntityMetadata(dataSource, model);\n const queryRunner = dataSource.createQueryRunner();\n\n try {\n await queryRunner.connect();\n\n if (!dryRun) {\n await queryRunner.startTransaction();\n }\n\n for (const field of fieldsForRemoval) {\n await this.cleanupMarkedField({\n field,\n model,\n entityMetadata,\n queryRunner,\n dryRun,\n operations,\n });\n }\n\n if (!dryRun) {\n await queryRunner.commitTransaction();\n }\n } catch (error) {\n if (!dryRun && queryRunner.isTransactionActive) {\n await queryRunner.rollbackTransaction();\n }\n throw error;\n } finally {\n await queryRunner.release();\n }\n\n return {\n dryRun,\n modelName: model.singularName,\n operations,\n removedFieldNames: fieldsForRemoval.map((field) => field.name),\n };\n }\n\n private async cleanupMarkedField(params: { field: FieldMetadata; model: ModelMetadata; entityMetadata?: EntityMetadata; queryRunner: QueryRunner; dryRun: boolean; operations: string[]; }): Promise<void> {\n const { field, model, entityMetadata, queryRunner, dryRun, operations } = params;\n const relationMetadata = entityMetadata?.relations.find((relation) => relation.propertyName === field.name);\n const resolvedTableName = entityMetadata?.tableName || model.tableName;\n\n if (field.type !== SolidFieldType.relation) {\n const columnCandidates = this.buildColumnCandidates(field, entityMetadata, relationMetadata);\n await this.dropColumnsForField(resolvedTableName, field, columnCandidates, queryRunner, dryRun, operations);\n return;\n }\n\n if (field.relationType === RelationType.manyToOne) {\n const columnCandidates = this.buildColumnCandidates(field, entityMetadata, relationMetadata);\n await this.dropColumnsForField(resolvedTableName, field, columnCandidates, queryRunner, dryRun, operations);\n return;\n }\n\n if (field.relationType === RelationType.manyTomany) {\n const joinTableName = relationMetadata?.junctionEntityMetadata?.tableName || field.relationJoinTableName;\n const ownsJoinTable = relationMetadata?.isOwning || field.isRelationManyToManyOwner;\n\n if (!ownsJoinTable) {\n operations.push(`No direct database cleanup required for inverse many-to-many field \"${field.name}\".`);\n return;\n }\n\n if (!joinTableName) {\n operations.push(`Skipping join-table cleanup for \"${field.name}\" because no join table name could be resolved.`);\n return;\n }\n\n await this.dropJoinTable(joinTableName, field, queryRunner, dryRun, operations);\n return;\n }\n\n operations.push(`No direct database cleanup required for relation field \"${field.name}\" with type \"${field.relationType}\".`);\n }\n\n private async dropColumnsForField(tableName: string, field: FieldMetadata, columnCandidates: string[], queryRunner: QueryRunner, dryRun: boolean, operations: string[],): Promise<void> {\n if (!tableName) {\n operations.push(`Skipping field \"${field.name}\" because the model table name could not be resolved.`);\n return;\n }\n\n if (columnCandidates.length === 0) {\n operations.push(`Skipping field \"${field.name}\" because no column candidates could be resolved.`);\n return;\n }\n\n const handledColumns = new Set<string>();\n let droppedAnyColumn = false;\n\n for (const columnName of columnCandidates) {\n if (!columnName || handledColumns.has(columnName)) {\n continue;\n }\n\n handledColumns.add(columnName);\n const table = await this.loadTable(queryRunner, tableName);\n const column = table?.columns.find((tableColumn) => tableColumn.name === columnName);\n\n if (!column) {\n continue;\n }\n\n droppedAnyColumn = true;\n await this.dropColumnArtifacts(table, columnName, queryRunner, dryRun, operations);\n }\n\n if (!droppedAnyColumn) {\n operations.push(`No database column found for field \"${field.name}\" on table \"${tableName}\". Metadata cleanup will still proceed.`);\n }\n }\n\n private async dropColumnArtifacts(table: Table, columnName: string, queryRunner: QueryRunner, dryRun: boolean, operations: string[],): Promise<void> {\n for (const foreignKey of table.foreignKeys.filter((item) => item.columnNames.includes(columnName))) {\n operations.push(`Drop foreign key \"${foreignKey.name}\" on \"${table.name}.${columnName}\"`);\n if (!dryRun) {\n await queryRunner.dropForeignKey(table, foreignKey);\n }\n }\n\n for (const uniqueConstraint of table.uniques.filter((item) => item.columnNames.includes(columnName))) {\n operations.push(`Drop unique constraint \"${uniqueConstraint.name}\" on \"${table.name}.${columnName}\"`);\n if (!dryRun) {\n await queryRunner.dropUniqueConstraint(table, uniqueConstraint);\n }\n }\n\n for (const index of table.indices.filter((item) => item.columnNames.includes(columnName))) {\n operations.push(`Drop index \"${index.name}\" on \"${table.name}.${columnName}\"`);\n if (!dryRun) {\n await queryRunner.dropIndex(table, index);\n }\n }\n\n operations.push(`Drop column \"${table.name}.${columnName}\"`);\n if (!dryRun) {\n await queryRunner.dropColumn(table, columnName);\n }\n }\n\n private async dropJoinTable(joinTableName: string, field: FieldMetadata, queryRunner: QueryRunner, dryRun: boolean, operations: string[]): Promise<void> {\n const table = await this.loadTable(queryRunner, joinTableName);\n if (!table) {\n operations.push(`Join table \"${joinTableName}\" for field \"${field.name}\" does not exist. Metadata cleanup will still proceed.`);\n return;\n }\n\n operations.push(`Drop join table \"${joinTableName}\" for field \"${field.name}\"`);\n if (!dryRun) {\n await queryRunner.dropTable(joinTableName);\n }\n }\n\n private buildColumnCandidates(field: FieldMetadata, entityMetadata?: EntityMetadata, relationMetadata?: EntityMetadata[\"relations\"][number]): string[] {\n const columnCandidates = new Set<string>();\n\n relationMetadata?.joinColumns?.forEach((column) => {\n if (column.databaseName) {\n columnCandidates.add(column.databaseName);\n }\n });\n\n entityMetadata?.columns\n .filter((column) => column.propertyName === field.name)\n .forEach((column) => {\n if (column.databaseName) {\n columnCandidates.add(column.databaseName);\n }\n });\n\n if (field.columnName) {\n columnCandidates.add(field.columnName);\n }\n\n if (field.relationCoModelColumnName) {\n columnCandidates.add(field.relationCoModelColumnName);\n }\n\n if (field.type === SolidFieldType.relation && field.relationType === RelationType.manyToOne) {\n columnCandidates.add(`${snakeCase(field.name)}_id`);\n } else {\n columnCandidates.add(snakeCase(field.name));\n }\n\n return [...columnCandidates].filter(Boolean);\n }\n\n private async resolveDataSource(dataSourceName?: string): Promise<DataSource> {\n const normalizedDataSourceName = dataSourceName && dataSourceName !== \"default\" ? dataSourceName : undefined;\n const token = normalizedDataSourceName ? getDataSourceToken(normalizedDataSourceName) : getDataSourceToken();\n let dataSource: DataSource | undefined;\n\n try {\n dataSource = this.moduleRef.get<DataSource>(token, { strict: false });\n } catch (error: any) {\n throw new NotFoundException(`Datasource \"${normalizedDataSourceName ?? \"default\"}\" could not be resolved: ${error?.message ?? error}`);\n }\n\n if (!dataSource) {\n throw new NotFoundException(`Datasource \"${normalizedDataSourceName ?? \"default\"}\" could not be resolved.`);\n }\n\n if (!dataSource.isInitialized) {\n await dataSource.initialize();\n }\n\n return dataSource;\n }\n\n private resolveEntityMetadata(dataSource: DataSource, model: ModelMetadata): EntityMetadata | undefined {\n const candidates = [classify(model.singularName), model.singularName, model.tableName].filter(Boolean);\n\n for (const candidate of candidates) {\n try {\n return dataSource.getMetadata(candidate);\n } catch {\n // Try the next candidate.\n }\n }\n\n return dataSource.entityMetadatas.find((metadata) => metadata.tableName === model.tableName);\n }\n\n private async resolveMetadataFilePath(moduleName: string): Promise<string> {\n const defaultPath = await this.moduleMetadataHelperService.getModuleMetadataFilePath(moduleName);\n if (await this.fileExists(defaultPath)) {\n return defaultPath;\n }\n\n const dashModuleName = kebabCase(moduleName);\n const moduleMetadataFilePath = path.resolve(\n process.cwd(),\n \"module-metadata\",\n dashModuleName,\n `${dashModuleName}-metadata.json`,\n );\n\n if (await this.fileExists(moduleMetadataFilePath)) {\n return moduleMetadataFilePath;\n }\n\n return defaultPath;\n }\n\n private async fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n private async loadTable(queryRunner: QueryRunner, tableName: string): Promise<Table | undefined> {\n if (!tableName) {\n return undefined;\n }\n\n const hasTable = await queryRunner.hasTable(tableName);\n if (!hasTable) {\n return undefined;\n }\n\n return queryRunner.getTable(tableName) ?? undefined;\n }\n}"]}