@solidstarters/solid-core 1.2.200 → 1.2.201
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/dist/commands/fixtures/fixtures-setup.command.d.ts +15 -0
- package/dist/commands/fixtures/fixtures-setup.command.d.ts.map +1 -0
- package/dist/commands/fixtures/fixtures-setup.command.js +58 -0
- package/dist/commands/fixtures/fixtures-setup.command.js.map +1 -0
- package/dist/commands/fixtures/fixtures-tear-down.command.d.ts +16 -0
- package/dist/commands/fixtures/fixtures-tear-down.command.d.ts.map +1 -0
- package/dist/commands/fixtures/fixtures-tear-down.command.js +59 -0
- package/dist/commands/fixtures/fixtures-tear-down.command.js.map +1 -0
- package/dist/commands/refresh-model.command.d.ts.map +1 -1
- package/dist/commands/refresh-model.command.js +4 -0
- package/dist/commands/refresh-model.command.js.map +1 -1
- package/dist/constants/error-messages.d.ts +2 -0
- package/dist/constants/error-messages.d.ts.map +1 -1
- package/dist/constants/error-messages.js +4 -0
- package/dist/constants/error-messages.js.map +1 -1
- package/dist/controllers/model-sequence.controller.d.ts +43 -0
- package/dist/controllers/model-sequence.controller.d.ts.map +1 -0
- package/dist/controllers/model-sequence.controller.js +179 -0
- package/dist/controllers/model-sequence.controller.js.map +1 -0
- package/dist/controllers/setting.controller.d.ts +1 -0
- package/dist/controllers/setting.controller.d.ts.map +1 -1
- package/dist/controllers/setting.controller.js +15 -0
- package/dist/controllers/setting.controller.js.map +1 -1
- package/dist/dtos/basic-filters.dto.d.ts +3 -1
- package/dist/dtos/basic-filters.dto.d.ts.map +1 -1
- package/dist/dtos/basic-filters.dto.js +8 -2
- package/dist/dtos/basic-filters.dto.js.map +1 -1
- package/dist/dtos/basic-group-filters.dto.d.ts +6 -0
- package/dist/dtos/basic-group-filters.dto.d.ts.map +1 -0
- package/dist/dtos/basic-group-filters.dto.js +46 -0
- package/dist/dtos/basic-group-filters.dto.js.map +1 -0
- package/dist/dtos/create-field-metadata.dto.js +2 -2
- package/dist/dtos/create-field-metadata.dto.js.map +1 -1
- package/dist/dtos/create-model-sequence.dto.d.ts +14 -0
- package/dist/dtos/create-model-sequence.dto.d.ts.map +1 -0
- package/dist/dtos/create-model-sequence.dto.js +90 -0
- package/dist/dtos/create-model-sequence.dto.js.map +1 -0
- package/dist/dtos/create-role-metadata.dto.d.ts.map +1 -1
- package/dist/dtos/create-role-metadata.dto.js +1 -0
- package/dist/dtos/create-role-metadata.dto.js.map +1 -1
- package/dist/dtos/get-mcp-url.dto.d.ts +5 -0
- package/dist/dtos/get-mcp-url.dto.d.ts.map +1 -0
- package/dist/dtos/get-mcp-url.dto.js +31 -0
- package/dist/dtos/get-mcp-url.dto.js.map +1 -0
- package/dist/dtos/resolve-s3-url.dto.d.ts +5 -5
- package/dist/dtos/resolve-s3-url.dto.d.ts.map +1 -1
- package/dist/dtos/resolve-s3-url.dto.js +7 -7
- package/dist/dtos/resolve-s3-url.dto.js.map +1 -1
- package/dist/dtos/update-model-sequence.dto.d.ts +15 -0
- package/dist/dtos/update-model-sequence.dto.d.ts.map +1 -0
- package/dist/dtos/update-model-sequence.dto.js +94 -0
- package/dist/dtos/update-model-sequence.dto.js.map +1 -0
- package/dist/entities/common.entity.d.ts.map +1 -1
- package/dist/entities/common.entity.js +1 -0
- package/dist/entities/common.entity.js.map +1 -1
- package/dist/entities/legacy-common.entity.d.ts.map +1 -1
- package/dist/entities/legacy-common.entity.js +1 -0
- package/dist/entities/legacy-common.entity.js.map +1 -1
- package/dist/entities/model-sequence.entity.d.ts +15 -0
- package/dist/entities/model-sequence.entity.d.ts.map +1 -0
- package/dist/entities/model-sequence.entity.js +67 -0
- package/dist/entities/model-sequence.entity.js.map +1 -0
- package/dist/helpers/field-crud-managers/BigIntFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/BigIntFieldCrudManager.js +13 -2
- package/dist/helpers/field-crud-managers/BigIntFieldCrudManager.js.map +1 -1
- package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.d.ts +0 -1
- package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.js +4 -9
- package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.js.map +1 -1
- package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.d.ts +0 -1
- package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.js +7 -8
- package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.js.map +1 -1
- package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.d.ts +0 -1
- package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.js +4 -9
- package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.js.map +1 -1
- package/dist/helpers/model-metadata-helper.service.d.ts.map +1 -1
- package/dist/helpers/model-metadata-helper.service.js +6 -2
- package/dist/helpers/model-metadata-helper.service.js.map +1 -1
- package/dist/helpers/module-metadata-helper.service.d.ts +1 -0
- package/dist/helpers/module-metadata-helper.service.d.ts.map +1 -1
- package/dist/helpers/module-metadata-helper.service.js +9 -0
- package/dist/helpers/module-metadata-helper.service.js.map +1 -1
- package/dist/helpers/module.helper.d.ts +1 -0
- package/dist/helpers/module.helper.d.ts.map +1 -1
- package/dist/helpers/module.helper.js +29 -3
- package/dist/helpers/module.helper.js.map +1 -1
- package/dist/helpers/solid-registry.d.ts +11 -0
- package/dist/helpers/solid-registry.d.ts.map +1 -1
- package/dist/helpers/solid-registry.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/jobs/computed-field-evaluation-subscriber.service.d.ts +1 -0
- package/dist/jobs/computed-field-evaluation-subscriber.service.d.ts.map +1 -1
- package/dist/jobs/computed-field-evaluation-subscriber.service.js +16 -4
- package/dist/jobs/computed-field-evaluation-subscriber.service.js.map +1 -1
- package/dist/repository/media.repository.d.ts.map +1 -1
- package/dist/repository/media.repository.js +4 -0
- package/dist/repository/media.repository.js.map +1 -1
- package/dist/repository/model-sequence.repository.d.ts +14 -0
- package/dist/repository/model-sequence.repository.d.ts.map +1 -0
- package/dist/repository/model-sequence.repository.js +103 -0
- package/dist/repository/model-sequence.repository.js.map +1 -0
- package/dist/seeders/module-metadata-seeder.service.d.ts +7 -12
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +64 -26
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +343 -27
- package/dist/seeders/system-fields-seeder.service.d.ts +1 -0
- package/dist/seeders/system-fields-seeder.service.d.ts.map +1 -1
- package/dist/seeders/system-fields-seeder.service.js +11 -2
- package/dist/seeders/system-fields-seeder.service.js.map +1 -1
- package/dist/services/action-metadata.service.d.ts.map +1 -1
- package/dist/services/action-metadata.service.js +1 -0
- package/dist/services/action-metadata.service.js.map +1 -1
- package/dist/services/ai-interaction.service.d.ts.map +1 -1
- package/dist/services/ai-interaction.service.js +1 -0
- package/dist/services/ai-interaction.service.js.map +1 -1
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +22 -14
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/chatter-message-details.service.d.ts.map +1 -1
- package/dist/services/chatter-message-details.service.js +1 -0
- package/dist/services/chatter-message-details.service.js.map +1 -1
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +7 -3
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.d.ts.map +1 -1
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js +7 -5
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js.map +1 -1
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts +15 -0
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts.map +1 -0
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js +72 -0
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js.map +1 -0
- package/dist/services/crud-helper.service.d.ts +23 -6
- package/dist/services/crud-helper.service.d.ts.map +1 -1
- package/dist/services/crud-helper.service.js +257 -45
- package/dist/services/crud-helper.service.js.map +1 -1
- package/dist/services/crud.service.d.ts +3 -1
- package/dist/services/crud.service.d.ts.map +1 -1
- package/dist/services/crud.service.js +53 -24
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/database/database-bootstrap.service.d.ts +12 -0
- package/dist/services/database/database-bootstrap.service.d.ts.map +1 -0
- package/dist/services/database/database-bootstrap.service.js +115 -0
- package/dist/services/database/database-bootstrap.service.js.map +1 -0
- package/dist/services/email-template.service.d.ts +7 -7
- package/dist/services/email-template.service.d.ts.map +1 -1
- package/dist/services/email-template.service.js +8 -7
- package/dist/services/email-template.service.js.map +1 -1
- package/dist/services/excel.service.d.ts +10 -0
- package/dist/services/excel.service.d.ts.map +1 -1
- package/dist/services/excel.service.js +100 -0
- package/dist/services/excel.service.js.map +1 -1
- package/dist/services/field-metadata.service.d.ts +4 -1
- package/dist/services/field-metadata.service.d.ts.map +1 -1
- package/dist/services/field-metadata.service.js +35 -30
- package/dist/services/field-metadata.service.js.map +1 -1
- package/dist/services/file.service.d.ts +1 -0
- package/dist/services/file.service.d.ts.map +1 -1
- package/dist/services/file.service.js +9 -0
- package/dist/services/file.service.js.map +1 -1
- package/dist/services/fixtures.service.d.ts +13 -0
- package/dist/services/fixtures.service.d.ts.map +1 -0
- package/dist/services/fixtures.service.js +95 -0
- package/dist/services/fixtures.service.js.map +1 -0
- package/dist/services/genai/ingest-metadata.service.d.ts.map +1 -1
- package/dist/services/genai/ingest-metadata.service.js +1 -1
- package/dist/services/genai/ingest-metadata.service.js.map +1 -1
- package/dist/services/import-transaction-error-log.service.d.ts.map +1 -1
- package/dist/services/import-transaction-error-log.service.js +1 -0
- package/dist/services/import-transaction-error-log.service.js.map +1 -1
- package/dist/services/import-transaction.service.d.ts.map +1 -1
- package/dist/services/import-transaction.service.js +7 -1
- package/dist/services/import-transaction.service.js.map +1 -1
- package/dist/services/list-of-values.service.d.ts +2 -2
- package/dist/services/list-of-values.service.d.ts.map +1 -1
- package/dist/services/list-of-values.service.js +2 -1
- package/dist/services/list-of-values.service.js.map +1 -1
- package/dist/services/locale.service.d.ts.map +1 -1
- package/dist/services/locale.service.js +1 -0
- package/dist/services/locale.service.js.map +1 -1
- package/dist/services/mail/smtp-email.service.js +0 -1
- package/dist/services/mail/smtp-email.service.js.map +1 -1
- package/dist/services/media.service.d.ts +3 -3
- package/dist/services/media.service.d.ts.map +1 -1
- package/dist/services/media.service.js +6 -4
- package/dist/services/media.service.js.map +1 -1
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.d.ts.map +1 -1
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.js +17 -6
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.js.map +1 -1
- package/dist/services/mediaStorageProviders/file-storage-provider.d.ts.map +1 -1
- package/dist/services/mediaStorageProviders/file-storage-provider.js +0 -13
- package/dist/services/mediaStorageProviders/file-storage-provider.js.map +1 -1
- package/dist/services/menu-item-metadata.service.d.ts.map +1 -1
- package/dist/services/menu-item-metadata.service.js +4 -0
- package/dist/services/menu-item-metadata.service.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +2 -42
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/model-sequence.service.d.ts +23 -0
- package/dist/services/model-sequence.service.d.ts.map +1 -0
- package/dist/services/model-sequence.service.js +55 -0
- package/dist/services/model-sequence.service.js.map +1 -0
- package/dist/services/module-metadata.service.d.ts +1 -0
- package/dist/services/module-metadata.service.d.ts.map +1 -1
- package/dist/services/module-metadata.service.js +35 -1
- package/dist/services/module-metadata.service.js.map +1 -1
- package/dist/services/permission-metadata.service.d.ts +5 -5
- package/dist/services/permission-metadata.service.d.ts.map +1 -1
- package/dist/services/permission-metadata.service.js +6 -5
- package/dist/services/permission-metadata.service.js.map +1 -1
- package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/database-subscriber.service.js +2 -1
- package/dist/services/queues/database-subscriber.service.js.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.js +2 -2
- package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
- package/dist/services/role-metadata.service.d.ts.map +1 -1
- package/dist/services/role-metadata.service.js +1 -0
- package/dist/services/role-metadata.service.js.map +1 -1
- package/dist/services/scheduled-job.service.d.ts +6 -6
- package/dist/services/scheduled-job.service.d.ts.map +1 -1
- package/dist/services/scheduled-job.service.js +8 -8
- package/dist/services/scheduled-job.service.js.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.service.js +4 -0
- package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
- package/dist/services/security-rule.service.d.ts.map +1 -1
- package/dist/services/security-rule.service.js +1 -0
- package/dist/services/security-rule.service.js.map +1 -1
- package/dist/services/selection-providers/list-of-models-selection-provider.service.d.ts.map +1 -1
- package/dist/services/selection-providers/list-of-models-selection-provider.service.js +4 -0
- package/dist/services/selection-providers/list-of-models-selection-provider.service.js.map +1 -1
- package/dist/services/setting.service.d.ts +7 -5
- package/dist/services/setting.service.d.ts.map +1 -1
- package/dist/services/setting.service.js +26 -4
- package/dist/services/setting.service.js.map +1 -1
- package/dist/services/sms-template.service.d.ts +7 -7
- package/dist/services/sms-template.service.d.ts.map +1 -1
- package/dist/services/sms-template.service.js +8 -7
- package/dist/services/sms-template.service.js.map +1 -1
- package/dist/services/solid-introspect.service.d.ts +4 -13
- package/dist/services/solid-introspect.service.d.ts.map +1 -1
- package/dist/services/solid-introspect.service.js +4 -22
- package/dist/services/solid-introspect.service.js.map +1 -1
- package/dist/services/solid-ts-morph.service.js +2 -2
- package/dist/services/solid-ts-morph.service.js.map +1 -1
- package/dist/services/user-activity-history.service.d.ts.map +1 -1
- package/dist/services/user-activity-history.service.js +1 -0
- package/dist/services/user-activity-history.service.js.map +1 -1
- package/dist/services/user-view-metadata.service.d.ts.map +1 -1
- package/dist/services/user-view-metadata.service.js +3 -2
- package/dist/services/user-view-metadata.service.js.map +1 -1
- package/dist/services/user.service.d.ts.map +1 -1
- package/dist/services/user.service.js +1 -0
- package/dist/services/user.service.js.map +1 -1
- package/dist/services/view-metadata.service.d.ts +1 -1
- package/dist/services/view-metadata.service.d.ts.map +1 -1
- package/dist/services/view-metadata.service.js +3 -1
- package/dist/services/view-metadata.service.js.map +1 -1
- package/dist/solid-core-cli-db.module.d.ts.map +1 -1
- package/dist/solid-core-cli-db.module.js +5 -2
- package/dist/solid-core-cli-db.module.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +18 -0
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
- package/dist/subscribers/audit.subscriber.js +5 -1
- package/dist/subscribers/audit.subscriber.js.map +1 -1
- package/dist/subscribers/computed-entity-field.subscriber.d.ts +4 -2
- package/dist/subscribers/computed-entity-field.subscriber.d.ts.map +1 -1
- package/dist/subscribers/computed-entity-field.subscriber.js +53 -12
- package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
- package/dist/transformers/typeorm/local-date-time-transformer.d.ts +5 -0
- package/dist/transformers/typeorm/local-date-time-transformer.d.ts.map +1 -0
- package/dist/transformers/typeorm/local-date-time-transformer.js +26 -0
- package/dist/transformers/typeorm/local-date-time-transformer.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/grouping-enhancements.md +89 -0
- package/package.json +1 -1
- package/src/commands/fixtures/fixtures-setup.command.ts +44 -0
- package/src/commands/fixtures/fixtures-tear-down.command.ts +45 -0
- package/src/commands/refresh-model.command.ts +3 -1
- package/src/constants/error-messages.ts +7 -1
- package/src/controllers/model-sequence.controller.ts +93 -0
- package/src/controllers/setting.controller.ts +33 -21
- package/src/dtos/basic-filters.dto.ts +6 -1
- package/src/dtos/basic-group-filters.dto.ts +23 -0
- package/src/dtos/create-field-metadata.dto.ts +1 -1
- package/src/dtos/create-model-sequence.dto.ts +51 -0
- package/src/dtos/create-role-metadata.dto.ts +16 -3
- package/src/dtos/get-mcp-url.dto.ts +13 -0
- package/src/dtos/resolve-s3-url.dto.ts +9 -11
- package/src/dtos/update-model-sequence.dto.ts +53 -0
- package/src/entities/common.entity.ts +2 -2
- package/src/entities/legacy-common.entity.ts +2 -1
- package/src/entities/model-sequence.entity.ts +32 -0
- package/src/helpers/field-crud-managers/BigIntFieldCrudManager.ts +18 -5
- package/src/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.ts +9 -9
- package/src/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.ts +16 -8
- package/src/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.ts +9 -9
- package/src/helpers/model-metadata-helper.service.ts +6 -4
- package/src/helpers/module-metadata-helper.service.ts +18 -1
- package/src/helpers/module.helper.ts +40 -5
- package/src/helpers/solid-registry.ts +14 -0
- package/src/index.ts +3 -1
- package/src/jobs/computed-field-evaluation-subscriber.service.ts +15 -4
- package/src/repository/media.repository.ts +3 -2
- package/src/repository/model-sequence.repository.ts +97 -0
- package/src/seeders/module-metadata-seeder.service.ts +103 -29
- package/src/seeders/seed-data/solid-core-metadata.json +343 -27
- package/src/seeders/system-fields-seeder.service.ts +6 -2
- package/src/services/action-metadata.service.ts +3 -2
- package/src/services/ai-interaction.service.ts +2 -1
- package/src/services/authentication.service.ts +46 -14
- package/src/services/chatter-message-details.service.ts +2 -1
- package/src/services/chatter-message.service.ts +10 -4
- package/src/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.ts +8 -7
- package/src/services/computed-fields/entity/sequence-num-computed-field-provider.ts +86 -0
- package/src/services/crud-helper.service.ts +287 -49
- package/src/services/crud.service.ts +83 -32
- package/src/services/database/database-bootstrap.service.ts +91 -0
- package/src/services/email-template.service.ts +11 -13
- package/src/services/excel.service.ts +146 -3
- package/src/services/field-metadata.service.ts +102 -55
- package/src/services/file.service.ts +9 -0
- package/src/services/fixtures.service.ts +108 -0
- package/src/services/genai/ingest-metadata.service.ts +4 -3
- package/src/services/import-transaction-error-log.service.ts +2 -1
- package/src/services/import-transaction.service.ts +8 -4
- package/src/services/list-of-values.service.ts +4 -4
- package/src/services/locale.service.ts +2 -1
- package/src/services/mail/smtp-email.service.ts +1 -1
- package/src/services/media.service.ts +10 -11
- package/src/services/mediaStorageProviders/file-s3-storage-provider.ts +22 -7
- package/src/services/mediaStorageProviders/file-storage-provider.ts +18 -13
- package/src/services/menu-item-metadata.service.ts +6 -2
- package/src/services/model-metadata.service.ts +50 -44
- package/src/services/model-sequence.service.ts +33 -0
- package/src/services/module-metadata.service.ts +49 -2
- package/src/services/permission-metadata.service.ts +8 -9
- package/src/services/queues/database-subscriber.service.ts +3 -1
- package/src/services/queues/rabbitmq-subscriber.service.ts +4 -2
- package/src/services/role-metadata.service.ts +1 -0
- package/src/services/scheduled-job.service.ts +9 -9
- package/src/services/scheduled-jobs/scheduler.service.ts +5 -0
- package/src/services/security-rule.service.ts +1 -0
- package/src/services/selection-providers/list-of-models-selection-provider.service.ts +5 -2
- package/src/services/setting.service.ts +33 -6
- package/src/services/sms-template.service.ts +11 -13
- package/src/services/solid-introspect.service.ts +6 -19
- package/src/services/solid-ts-morph.service.ts +2 -2
- package/src/services/user-activity-history.service.ts +3 -2
- package/src/services/user-view-metadata.service.ts +4 -3
- package/src/services/user.service.ts +2 -1
- package/src/services/view-metadata.service.ts +5 -4
- package/src/solid-core-cli-db.module.ts +5 -4
- package/src/solid-core.module.ts +18 -0
- package/src/subscribers/audit.subscriber.ts +3 -2
- package/src/subscribers/computed-entity-field.subscriber.ts +60 -17
- package/src/transformers/typeorm/local-date-time-transformer.ts +30 -0
- /package/sql/{mssql → default/mssql}/proc_CleanupModelMetadata.sql +0 -0
- /package/sql/{mssql → default/mssql}/proc_CleanupModuleMetadata.sql +0 -0
- /package/sql/{mssql/scratchpad.sql → default/mssql/scratchpad.sql.txt} +0 -0
- /package/sql/{postgres → default/postgres}/proc_CleanupModelMetadata.sql +0 -0
- /package/sql/{postgres → default/postgres}/proc_CleanupModuleMetadata.sql +0 -0
- /package/sql/{postgres/scratchpad.sql → default/postgres/scratchpad.sql.txt} +0 -0
|
@@ -7,24 +7,22 @@ export class ResolveS3UrlDto {
|
|
|
7
7
|
@IsNotEmpty()
|
|
8
8
|
fieldName: string;
|
|
9
9
|
|
|
10
|
-
@IsNotEmpty()
|
|
11
|
-
s3KeyFieldName: string;
|
|
12
10
|
|
|
13
11
|
@IsNotEmpty()
|
|
14
|
-
|
|
12
|
+
fileType?: string;
|
|
15
13
|
|
|
16
14
|
@IsNotEmpty()
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@IsNotEmpty()
|
|
20
|
-
bucketName: string;
|
|
21
|
-
|
|
22
|
-
@IsNotEmpty()
|
|
23
|
-
isPrivate: string;
|
|
24
|
-
}
|
|
15
|
+
s3Key?: string;
|
|
25
16
|
|
|
17
|
+
@IsOptional()
|
|
18
|
+
bucketName?: string;
|
|
26
19
|
|
|
20
|
+
@IsOptional()
|
|
21
|
+
mediaStorageProviderUserKey?: string;
|
|
27
22
|
|
|
23
|
+
@IsNotEmpty()
|
|
24
|
+
isPrivate?: string;
|
|
25
|
+
}
|
|
28
26
|
|
|
29
27
|
|
|
30
28
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { IsInt,IsOptional, IsString, IsNotEmpty } from 'class-validator';
|
|
2
|
+
import { ApiProperty } from '@nestjs/swagger';
|
|
3
|
+
|
|
4
|
+
export class UpdateModelSequenceDto {
|
|
5
|
+
@IsOptional()
|
|
6
|
+
@IsInt()
|
|
7
|
+
id: number;
|
|
8
|
+
@IsOptional()
|
|
9
|
+
@IsInt()
|
|
10
|
+
@ApiProperty()
|
|
11
|
+
moduleId: number;
|
|
12
|
+
@IsString()
|
|
13
|
+
@IsOptional()
|
|
14
|
+
@ApiProperty()
|
|
15
|
+
moduleUserKey: string;
|
|
16
|
+
@IsOptional()
|
|
17
|
+
@IsInt()
|
|
18
|
+
@ApiProperty()
|
|
19
|
+
modelId: number;
|
|
20
|
+
@IsString()
|
|
21
|
+
@IsOptional()
|
|
22
|
+
@ApiProperty()
|
|
23
|
+
modelUserKey: string;
|
|
24
|
+
@IsOptional()
|
|
25
|
+
@IsInt()
|
|
26
|
+
@ApiProperty()
|
|
27
|
+
fieldId: number;
|
|
28
|
+
@IsString()
|
|
29
|
+
@IsOptional()
|
|
30
|
+
@ApiProperty()
|
|
31
|
+
fieldUserKey: string;
|
|
32
|
+
@IsNotEmpty()
|
|
33
|
+
@IsOptional()
|
|
34
|
+
@IsString()
|
|
35
|
+
@ApiProperty()
|
|
36
|
+
sequenceName: string;
|
|
37
|
+
@IsOptional()
|
|
38
|
+
@IsInt()
|
|
39
|
+
@ApiProperty()
|
|
40
|
+
currentValue: number;
|
|
41
|
+
@IsOptional()
|
|
42
|
+
@IsString()
|
|
43
|
+
@ApiProperty()
|
|
44
|
+
prefix: string;
|
|
45
|
+
@IsOptional()
|
|
46
|
+
@IsInt()
|
|
47
|
+
@ApiProperty()
|
|
48
|
+
padding: number;
|
|
49
|
+
@IsOptional()
|
|
50
|
+
@IsString()
|
|
51
|
+
@ApiProperty()
|
|
52
|
+
separator: string;
|
|
53
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Column, CreateDateColumn, DeleteDateColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
|
|
1
|
+
import { Column, CreateDateColumn, DeleteDateColumn, Index, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
|
|
2
2
|
import type { User } from "./user.entity";
|
|
3
3
|
import { Exclude, Expose, Type } from "class-transformer";
|
|
4
4
|
|
|
@@ -15,6 +15,7 @@ export abstract class CommonEntity {
|
|
|
15
15
|
updatedAt: Date;
|
|
16
16
|
|
|
17
17
|
@DeleteDateColumn({ name: "deleted_at" })
|
|
18
|
+
@Index()
|
|
18
19
|
deletedAt: Date;
|
|
19
20
|
|
|
20
21
|
@Column({ name: "deletedTracker", default: "not-deleted" })
|
|
@@ -49,5 +50,4 @@ export abstract class CommonEntity {
|
|
|
49
50
|
@Expose()
|
|
50
51
|
@Column({ name: `updated_by_id`, nullable: true })
|
|
51
52
|
updatedBy: number;
|
|
52
|
-
|
|
53
53
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Exclude, Expose, Type } from "class-transformer";
|
|
2
|
-
import { Column, CreateDateColumn, DeleteDateColumn, JoinColumn, ManyToOne, UpdateDateColumn } from "typeorm";
|
|
2
|
+
import { Column, CreateDateColumn, DeleteDateColumn, Index, JoinColumn, ManyToOne, UpdateDateColumn } from "typeorm";
|
|
3
3
|
import type { User } from "./user.entity";
|
|
4
4
|
|
|
5
5
|
export const LEGACY_TABLE_FIELDS_PREFIX = 'ss';
|
|
@@ -18,6 +18,7 @@ export abstract class LegacyCommonEntity {
|
|
|
18
18
|
updatedAt: Date;
|
|
19
19
|
|
|
20
20
|
@DeleteDateColumn({ name: `${LEGACY_TABLE_FIELDS_PREFIX}_deleted_at` })
|
|
21
|
+
@Index()
|
|
21
22
|
deletedAt: Date;
|
|
22
23
|
|
|
23
24
|
@Column({ name: `${LEGACY_TABLE_FIELDS_PREFIX}_deleted_tracker`, default: "not-deleted" })
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { CommonEntity } from "src/entities/common.entity"
|
|
2
|
+
import { Entity, JoinColumn, ManyToOne, Index, Column } from 'typeorm';
|
|
3
|
+
import { ModuleMetadata } from 'src/entities/module-metadata.entity';
|
|
4
|
+
import { ModelMetadata } from 'src/entities/model-metadata.entity';
|
|
5
|
+
import { FieldMetadata } from 'src/entities/field-metadata.entity'
|
|
6
|
+
|
|
7
|
+
@Entity('ss_model_sequence')
|
|
8
|
+
export class ModelSequence extends CommonEntity {
|
|
9
|
+
@Index()
|
|
10
|
+
@ManyToOne(() => ModuleMetadata, { nullable: false })
|
|
11
|
+
@JoinColumn()
|
|
12
|
+
module: ModuleMetadata;
|
|
13
|
+
@Index()
|
|
14
|
+
@ManyToOne(() => ModelMetadata, { nullable: false })
|
|
15
|
+
@JoinColumn()
|
|
16
|
+
model: ModelMetadata;
|
|
17
|
+
@Index()
|
|
18
|
+
@ManyToOne(() => FieldMetadata, { nullable: false })
|
|
19
|
+
@JoinColumn()
|
|
20
|
+
field: FieldMetadata;
|
|
21
|
+
@Index({ unique: true })
|
|
22
|
+
@Column({ type: "varchar" })
|
|
23
|
+
sequenceName: string;
|
|
24
|
+
@Column({ type: "integer", default: 1 })
|
|
25
|
+
currentValue: number;
|
|
26
|
+
@Column({ type: "varchar", nullable: true })
|
|
27
|
+
prefix: string;
|
|
28
|
+
@Column({ type: "integer", default: 5 })
|
|
29
|
+
padding: number;
|
|
30
|
+
@Column({ type: "varchar", default: "" })
|
|
31
|
+
separator: string;
|
|
32
|
+
}
|
|
@@ -14,13 +14,22 @@ export class BigIntFieldCrudManager implements FieldCrudManager {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
validate(createDto: any): ValidationError[] {
|
|
17
|
-
|
|
17
|
+
let fieldValue: any = createDto[this.options.fieldName];
|
|
18
|
+
if (fieldValue !== undefined && fieldValue !== null) {
|
|
19
|
+
try {
|
|
20
|
+
if (typeof fieldValue === 'string' || typeof fieldValue === 'number') {
|
|
21
|
+
fieldValue = BigInt(fieldValue);
|
|
22
|
+
}
|
|
23
|
+
} catch (err) {
|
|
24
|
+
return [{ field: this.options.fieldName, error: 'Invalid numeric value' }];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
18
27
|
return this.applyValidations(fieldValue);
|
|
19
28
|
}
|
|
20
29
|
|
|
21
30
|
private applyValidations(fieldValue: any): ValidationError[] {
|
|
22
31
|
const errors: ValidationError[] = [];
|
|
23
|
-
this.isApplyRequiredValidation() && isEmpty(fieldValue) ? errors.push({ field: this.options.fieldName, error: `Field: ${this.options.fieldName} is required` }): "no errors";
|
|
32
|
+
this.isApplyRequiredValidation() && isEmpty(fieldValue) ? errors.push({ field: this.options.fieldName, error: `Field: ${this.options.fieldName} is required` }) : "no errors";
|
|
24
33
|
if (isNotEmpty(fieldValue)) {
|
|
25
34
|
errors.push(...this.applyFormatValidations(fieldValue));
|
|
26
35
|
}
|
|
@@ -29,7 +38,7 @@ export class BigIntFieldCrudManager implements FieldCrudManager {
|
|
|
29
38
|
|
|
30
39
|
private applyFormatValidations(fieldValue: any): ValidationError[] {
|
|
31
40
|
const errors: ValidationError[] = [];
|
|
32
|
-
!this.isBigInt(fieldValue) ? errors.push({ field: this.options.fieldName, error: 'Field is not a bigint' }): "no errors";
|
|
41
|
+
!this.isBigInt(fieldValue) ? errors.push({ field: this.options.fieldName, error: 'Field is not a bigint' }) : "no errors";
|
|
33
42
|
this.isApplyMinValidation() && !min(fieldValue, this.options.min) ? errors.push({ field: this.options.fieldName, error: 'Field value is lesser than minimum required' }) : "no errors"; //FIXME min length to be handled
|
|
34
43
|
this.isApplyMaxValidation() && !max(fieldValue, this.options.max) ? errors.push({ field: this.options.fieldName, error: 'Field value is greater than maximum required' }) : "no errors";
|
|
35
44
|
return errors;
|
|
@@ -43,13 +52,17 @@ export class BigIntFieldCrudManager implements FieldCrudManager {
|
|
|
43
52
|
private isApplyMinValidation(): boolean {
|
|
44
53
|
return this.options.min > 0;
|
|
45
54
|
}
|
|
55
|
+
|
|
46
56
|
private isApplyMaxValidation(): boolean {
|
|
47
57
|
return this.options.max > 0;
|
|
48
58
|
}
|
|
59
|
+
|
|
49
60
|
private isApplyRequiredValidation(): boolean {
|
|
50
61
|
return this.options.required;
|
|
51
62
|
}
|
|
63
|
+
|
|
52
64
|
private isBigInt(value: any): boolean {
|
|
53
|
-
|
|
54
|
-
|
|
65
|
+
const valueType = typeof value;
|
|
66
|
+
return valueType === 'bigint' || (valueType === 'number' && Number.isFinite(value));
|
|
67
|
+
}
|
|
55
68
|
}
|
|
@@ -68,11 +68,11 @@ export class ManyToManyRelationFieldCrudManager implements FieldCrudManager {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
async transformForCreate(dto: any): Promise<any> {
|
|
71
|
-
const
|
|
72
|
-
const currentEntityRepository = this.options.entityManager.getRepository(
|
|
71
|
+
const currentEntityName = classify(this.options.modelSingularName);
|
|
72
|
+
const currentEntityRepository = this.options.entityManager.getRepository(currentEntityName);
|
|
73
73
|
|
|
74
|
-
const
|
|
75
|
-
const relatedEntityRepository = this.options.entityManager.getRepository(
|
|
74
|
+
const relatedEntityName = classify(this.options.relationCoModelSingularName);
|
|
75
|
+
const relatedEntityRepository = this.options.entityManager.getRepository(relatedEntityName)
|
|
76
76
|
|
|
77
77
|
dto[this.valueFieldName] = await this.transformByCommand(dto, relatedEntityRepository, currentEntityRepository);
|
|
78
78
|
return dto;
|
|
@@ -192,9 +192,9 @@ export class ManyToManyRelationFieldCrudManager implements FieldCrudManager {
|
|
|
192
192
|
|
|
193
193
|
// TODO: We have moved this to SolidRegistry service, refactor to use that service.
|
|
194
194
|
// Returns the entity target class from the entity name
|
|
195
|
-
private getEntityTarget(entityName: string): any { //TODO Can be refactored to use this function from crud helper service
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
195
|
+
// private getEntityTarget(entityName: string): any { //TODO Can be refactored to use this function from crud helper service
|
|
196
|
+
// const entityMetadatas = this.options.entityManager.connection.entityMetadatas;
|
|
197
|
+
// const entityMetadata = entityMetadatas.find(em => em.name === entityName);
|
|
198
|
+
// return entityMetadata.target;
|
|
199
|
+
// }
|
|
200
200
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { classify } from "@angular-devkit/core/src/utils/strings";
|
|
2
|
+
import { BadRequestException } from "@nestjs/common";
|
|
2
3
|
import { isEmpty, isNotEmpty, isString } from "class-validator";
|
|
3
4
|
import { FieldCrudManager, ValidationError } from "src/interfaces";
|
|
4
5
|
import { IsParsableInt } from "src/validators/is-parsable-int";
|
|
@@ -64,16 +65,23 @@ export class ManyToOneRelationFieldCrudManager implements FieldCrudManager {
|
|
|
64
65
|
// Avoid transforming if both fieldId and fieldUserKey is empty
|
|
65
66
|
if ((isEmpty(fieldId)) && isEmpty(fieldUserKeyValue)) return dto;
|
|
66
67
|
|
|
68
|
+
if (!this.options.relationCoModelSingularName) {
|
|
69
|
+
throw new BadRequestException(`ManyToOneRelationFieldCrudManager: relationCoModelSingularName is not defined in the field: ${this.options.fieldName}`);
|
|
70
|
+
}
|
|
67
71
|
// // Load the related entity from the database, using the repository of the related entity
|
|
68
|
-
const entityTarget = this.getRelatedEntityTarget(classify(this.options.relationCoModelSingularName));
|
|
72
|
+
//const entityTarget = this.getRelatedEntityTarget(classify(this.options.relationCoModelSingularName));
|
|
73
|
+
const coModelEntityName = classify(this.options.relationCoModelSingularName);
|
|
74
|
+
|
|
75
|
+
//Load the related entity from the database, using the repository of the related entity
|
|
76
|
+
//const entityTarget = this.getRelatedEntityTarget(classify(this.options.relationCoModelSingularName));
|
|
69
77
|
if (isNotEmpty(fieldId)) {
|
|
70
|
-
dto[this.options.fieldName] = await this.options.entityManager.getRepository(
|
|
78
|
+
dto[this.options.fieldName] = await this.options.entityManager.getRepository(coModelEntityName).findOneBy({ id: fieldId });
|
|
71
79
|
if (this.options.required && isEmpty(dto[this.options.fieldName])) {
|
|
72
80
|
throw new Error(`ManyToOneRelationFieldCrudManager: Record with id: ${fieldId} not found in ${this.options.relationCoModelSingularName}`);
|
|
73
81
|
}
|
|
74
82
|
}
|
|
75
83
|
else {
|
|
76
|
-
dto[this.options.fieldName] = await this.options.entityManager.getRepository(
|
|
84
|
+
dto[this.options.fieldName] = await this.options.entityManager.getRepository(coModelEntityName).findOneBy({ [this.options.relationCoModelUserKeyFieldName]: fieldUserKeyValue });
|
|
77
85
|
if (this.options.required && isEmpty(dto[this.options.fieldName])) {
|
|
78
86
|
throw new Error(`ManyToOneRelationFieldCrudManager: Record with userKey: ${this.options.relationCoModelUserKeyFieldName}: ${fieldUserKeyValue} not found in ${this.options.relationCoModelSingularName}`);
|
|
79
87
|
}
|
|
@@ -88,10 +96,10 @@ export class ManyToOneRelationFieldCrudManager implements FieldCrudManager {
|
|
|
88
96
|
}
|
|
89
97
|
|
|
90
98
|
// Returns the entity target class from the entity name
|
|
91
|
-
private getRelatedEntityTarget(relatedEntityName: string): any {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
99
|
+
// private getRelatedEntityTarget(relatedEntityName: string): any {
|
|
100
|
+
// const entityMetadatas = this.options.entityManager.connection.entityMetadatas;
|
|
101
|
+
// const relatedEntityMetadata = entityMetadatas.find(em => em.name === relatedEntityName);
|
|
102
|
+
// return relatedEntityMetadata.target;
|
|
103
|
+
// }
|
|
96
104
|
|
|
97
105
|
}
|
|
@@ -75,11 +75,11 @@ export class OneToManyRelationFieldCrudManager implements FieldCrudManager {
|
|
|
75
75
|
|
|
76
76
|
async transformForCreate(dto: any): Promise<any> {
|
|
77
77
|
// const relatedFieldData: any[] = dto[this.fieldName()];
|
|
78
|
-
const
|
|
79
|
-
const currentEntityRepository = this.options.entityManager.getRepository(
|
|
78
|
+
const currentEntityName = classify(this.options.modelSingularName);
|
|
79
|
+
const currentEntityRepository = this.options.entityManager.getRepository(currentEntityName);
|
|
80
80
|
|
|
81
|
-
const
|
|
82
|
-
const relatedEntityRepository = this.options.entityManager.getRepository(
|
|
81
|
+
const relatedEntityName = classify(this.options.relationCoModelSingularName);
|
|
82
|
+
const relatedEntityRepository = this.options.entityManager.getRepository(relatedEntityName);
|
|
83
83
|
|
|
84
84
|
dto[this.valueFieldName] = await this.transformByCommand(dto, relatedEntityRepository, currentEntityRepository);
|
|
85
85
|
return dto;
|
|
@@ -197,9 +197,9 @@ export class OneToManyRelationFieldCrudManager implements FieldCrudManager {
|
|
|
197
197
|
|
|
198
198
|
// TODO: We have moved this to SolidRegistry service, refactor to use that service.
|
|
199
199
|
// Returns the entity target class from the entity name
|
|
200
|
-
private getEntityTarget(entityName: string): any { //TODO Can be refactored to use this function from crud helper service
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
200
|
+
// private getEntityTarget(entityName: string): any { //TODO Can be refactored to use this function from crud helper service
|
|
201
|
+
// const entityMetadatas = this.options.entityManager.connection.entityMetadatas;
|
|
202
|
+
// const entityMetadata = entityMetadatas.find(em => em.name === entityName);
|
|
203
|
+
// return entityMetadata.target;
|
|
204
|
+
// }
|
|
205
205
|
}
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
// Return the system fields metadata for a model
|
|
2
2
|
|
|
3
|
-
import { Injectable, Logger } from "@nestjs/common";
|
|
3
|
+
import { forwardRef, Inject, Injectable, Logger } from "@nestjs/common";
|
|
4
|
+
import { _ } from "lodash";
|
|
5
|
+
import { LEGACY_TABLE_FIELDS_PREFIX } from "src/entities/legacy-common.entity";
|
|
4
6
|
import { ModelMetadataRepository } from "src/repository/model-metadata.repository";
|
|
5
7
|
import { SolidRegistry } from "./solid-registry";
|
|
6
|
-
import {_ } from "lodash";
|
|
7
|
-
import { LEGACY_TABLE_FIELDS_PREFIX } from "src/entities/legacy-common.entity";
|
|
8
8
|
|
|
9
9
|
@Injectable()
|
|
10
10
|
export class ModelMetadataHelperService {
|
|
11
11
|
private readonly logger = new Logger(ModelMetadataHelperService.name);
|
|
12
12
|
|
|
13
|
-
constructor(
|
|
13
|
+
constructor(
|
|
14
|
+
private readonly registry: SolidRegistry,
|
|
14
15
|
// @InjectRepository(ModelMetadata)
|
|
15
16
|
// private readonly modelMetadataRepo: Repository<ModelMetadata>,
|
|
17
|
+
@Inject(forwardRef(() => ModelMetadataRepository))
|
|
16
18
|
private readonly modelMetadataRepo: ModelMetadataRepository,
|
|
17
19
|
) {
|
|
18
20
|
}
|
|
@@ -57,4 +57,21 @@ export class ModuleMetadataHelperService {
|
|
|
57
57
|
}
|
|
58
58
|
return filePath;
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
async getModuleMetadataFolderPath(moduleName: string): Promise<string> {
|
|
61
|
+
if (!moduleName) {
|
|
62
|
+
return '';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const dashModuleName = dasherize(moduleName);
|
|
66
|
+
|
|
67
|
+
const folderPath = path.resolve(
|
|
68
|
+
process.cwd(),
|
|
69
|
+
'module-metadata',
|
|
70
|
+
dashModuleName,
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const exists = await this.fileService.pathExists(folderPath);
|
|
74
|
+
return exists ? folderPath : '';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { Logger } from '@nestjs/common';
|
|
1
2
|
import * as fs from 'fs'; // Use the Promise-based version of fs for async/await
|
|
2
3
|
import * as path from 'path'; // To handle file paths
|
|
3
4
|
|
|
5
|
+
const logger = new Logger('module.helper');
|
|
4
6
|
|
|
5
7
|
export const getDynamicModuleNames = (): string[] => {
|
|
6
8
|
const dynamicModulesToExclude = process.env.SOLID_DYNAMIC_MODULES_TO_EXCLUDE?.split(',') || [];
|
|
@@ -21,15 +23,48 @@ export const getDynamicModuleNames = (): string[] => {
|
|
|
21
23
|
|
|
22
24
|
if (!isValidDirectory) return false;
|
|
23
25
|
|
|
24
|
-
return true
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
// return true
|
|
27
|
+
const fullPath = path.join(srcPath, dirent.name);
|
|
28
|
+
const files = fs.readdirSync(fullPath);
|
|
27
29
|
// skip if empty directory
|
|
28
|
-
|
|
30
|
+
return files.length > 0;
|
|
29
31
|
})
|
|
30
32
|
.map(dirent => dirent.name);
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
// logger.debug(`Enabled dynamic modules:`, enabledModules);
|
|
35
|
+
return enabledModules;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const getDynamicModuleNamesBasedOnMetadata = (): string[] => {
|
|
39
|
+
const dynamicModulesToExclude = process.env.SOLID_DYNAMIC_MODULES_TO_EXCLUDE?.split(',') || [];
|
|
40
|
+
|
|
41
|
+
// Find a path that is ../${srcPath}/module-metadata save it in a variable.
|
|
42
|
+
// const srcPath = path.join(process.cwd(), 'src');
|
|
43
|
+
const moduleMetadataPath = path.join(process.cwd(), 'module-metadata');
|
|
44
|
+
const coreModuleNames = getCoreModuleNames();
|
|
45
|
+
const allExcludedModules = [...new Set([...coreModuleNames, ...dynamicModulesToExclude])];
|
|
46
|
+
|
|
47
|
+
// if module-metadata path does not exist, return empty array
|
|
48
|
+
if (!fs.existsSync(moduleMetadataPath)) {
|
|
49
|
+
logger.warn(`Module metadata path does not exist: ${moduleMetadataPath}`);
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const moduleMetadataDirectories = fs.readdirSync(moduleMetadataPath, { withFileTypes: true });
|
|
54
|
+
const enabledModules = moduleMetadataDirectories
|
|
55
|
+
.filter(dirent => {
|
|
56
|
+
const isValidDirectory = dirent.isDirectory() && !allExcludedModules.includes(dirent.name);
|
|
57
|
+
|
|
58
|
+
if (!isValidDirectory) return false;
|
|
59
|
+
|
|
60
|
+
const fullPath = path.join(moduleMetadataPath, dirent.name, `${dirent.name}-metadata.json`);
|
|
61
|
+
|
|
62
|
+
const stats = fs.statSync(fullPath, { throwIfNoEntry: false });
|
|
63
|
+
return !!stats && stats.isFile();
|
|
64
|
+
})
|
|
65
|
+
.map(dirent => dirent.name);
|
|
66
|
+
|
|
67
|
+
// logger.debug(`Enabled dynamic modules basis src:`, enabledModules);
|
|
33
68
|
return enabledModules;
|
|
34
69
|
}
|
|
35
70
|
|
|
@@ -7,6 +7,9 @@ import { SecurityRule } from 'src/entities/security-rule.entity';
|
|
|
7
7
|
import { IScheduledJob } from 'src/services/scheduled-jobs/scheduled-job.interface';
|
|
8
8
|
import { IDashboardQuestionDataProvider, IDashboardVariableSelectionProvider, IErrorCodeProvider, ISecurityRuleConfigProvider, ISelectionProvider, ISelectionProviderContext, ISolidDatabaseModule } from "../interfaces";
|
|
9
9
|
import { DatasourceType } from 'src/dtos/create-model-metadata.dto';
|
|
10
|
+
import { ObjectLiteral } from 'typeorm';
|
|
11
|
+
import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
|
|
12
|
+
import { RelationMetadata } from 'typeorm/metadata/RelationMetadata';
|
|
10
13
|
|
|
11
14
|
type ControllerMetadata = {
|
|
12
15
|
name: string;
|
|
@@ -39,6 +42,16 @@ export enum RESERVED_SOLID_KEYWORDS {
|
|
|
39
42
|
locale = "locale"
|
|
40
43
|
}
|
|
41
44
|
|
|
45
|
+
export interface TypeOrmEventContext {
|
|
46
|
+
eventType?: string;
|
|
47
|
+
entity?: ObjectLiteral | undefined;
|
|
48
|
+
databaseEntity?: any;
|
|
49
|
+
entityId?: any;
|
|
50
|
+
metadataName?: string;
|
|
51
|
+
updatedColumns?: string[];
|
|
52
|
+
updatedRelations?: string[];
|
|
53
|
+
}
|
|
54
|
+
|
|
42
55
|
export interface ComputedFieldMetadata<TContext = any> {
|
|
43
56
|
moduleName: string; // Name of the module where the computed field is defined
|
|
44
57
|
modelName: string; // Name of the model where the computed field is defined
|
|
@@ -49,6 +62,7 @@ export interface ComputedFieldMetadata<TContext = any> {
|
|
|
49
62
|
computedFieldValueProviderName: string; // Name of the provider that computes the field value
|
|
50
63
|
// Example: '{"contextKey": "contextValue"}'
|
|
51
64
|
computedFieldValueProviderCtxt: TContext; // Context for the computed field value
|
|
65
|
+
eventContext: TypeOrmEventContext;
|
|
52
66
|
}
|
|
53
67
|
|
|
54
68
|
@Injectable()
|
package/src/index.ts
CHANGED
|
@@ -137,6 +137,7 @@ export * from './entities/dashboard-variable.entity'
|
|
|
137
137
|
export * from './entities/dashboard-question.entity'
|
|
138
138
|
export * from './entities/dashboard-question-sql-dataset-config.entity'
|
|
139
139
|
export * from './entities/ai-interaction.entity'
|
|
140
|
+
export * from './entities/model-sequence.entity'
|
|
140
141
|
|
|
141
142
|
export * from './enums/auth-type.enum'
|
|
142
143
|
export * from './decorators/disallow-in-production.decorator'
|
|
@@ -299,6 +300,8 @@ export * from './subscribers/audit.subscriber'
|
|
|
299
300
|
export * from './transformers/array-transformer'
|
|
300
301
|
export * from './transformers/boolean-transformer'
|
|
301
302
|
export * from './transformers/integer-transformer'
|
|
303
|
+
export { default as datetimeTransformer } from './transformers/datetime-transformer'
|
|
304
|
+
export * from './transformers/typeorm/local-date-time-transformer'
|
|
302
305
|
|
|
303
306
|
export * from './validators/is-parsable-int'
|
|
304
307
|
|
|
@@ -307,6 +310,5 @@ export * from './interfaces'
|
|
|
307
310
|
export * from './solid-core.module'
|
|
308
311
|
|
|
309
312
|
export * from './winston.logger'
|
|
310
|
-
export { default as datetimeTransformer } from './transformers/datetime-transformer'
|
|
311
313
|
|
|
312
314
|
export { ERROR_MESSAGES } from './constants/error-messages'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Injectable } from "@nestjs/common";
|
|
1
|
+
import { Injectable, Logger } from "@nestjs/common";
|
|
2
2
|
import { SolidRegistry } from "src/helpers/solid-registry";
|
|
3
3
|
import { IEntityPostComputeFieldProvider, QueuesModuleOptions } from "src/interfaces";
|
|
4
4
|
import { QueueMessage } from "src/interfaces/mq";
|
|
@@ -11,6 +11,7 @@ import computedFieldEvaluationQueueOptions from "./computed-field-evaluation-que
|
|
|
11
11
|
|
|
12
12
|
@Injectable()
|
|
13
13
|
export class ComputedFieldEvaluationSubscriberRabbitmq extends RabbitMqSubscriber<ComputedFieldEvaluationPayload> {
|
|
14
|
+
private readonly _logger = new Logger(ComputedFieldEvaluationSubscriberRabbitmq.name);
|
|
14
15
|
constructor(
|
|
15
16
|
readonly mqMessageService: MqMessageService,
|
|
16
17
|
readonly mqMessageQueueService: MqMessageQueueService,
|
|
@@ -30,9 +31,19 @@ export class ComputedFieldEvaluationSubscriberRabbitmq extends RabbitMqSubscribe
|
|
|
30
31
|
// It will then call the corresponding provider computeAndSave method to perform the evaluation
|
|
31
32
|
async subscribe(message: QueueMessage<ComputedFieldEvaluationPayload>) {
|
|
32
33
|
const { databaseEntity, ...computedFieldMetadata } = message.payload;
|
|
33
|
-
const
|
|
34
|
+
const { computedFieldValueProviderName } = computedFieldMetadata;
|
|
35
|
+
const provider = this.solidRegistry.getComputedFieldProvider(computedFieldValueProviderName);
|
|
34
36
|
// Get the instance of the provider and assert it is of type IEntityComputedFieldProvider
|
|
35
37
|
const providerInstance = provider.instance as IEntityPostComputeFieldProvider<any, any>; // IEntityComputedFieldProvider
|
|
36
|
-
|
|
38
|
+
if (typeof providerInstance.postComputeAndSaveValue !== 'function') {
|
|
39
|
+
this._logger.warn(`Provider "${computedFieldValueProviderName}" does not implement postComputeAndSaveValue; skipping post-compute.`);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
await providerInstance.postComputeAndSaveValue(databaseEntity, {
|
|
43
|
+
...computedFieldMetadata,
|
|
44
|
+
computedFieldValueProviderCtxt: {
|
|
45
|
+
...(computedFieldMetadata.computedFieldValueProviderCtxt || {}),
|
|
46
|
+
},
|
|
47
|
+
}); //FIXME There should some way to check/assert if the provider actually has a postComputeAndSaveValue
|
|
37
48
|
}
|
|
38
|
-
}
|
|
49
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Injectable } from '@nestjs/common';
|
|
1
|
+
import { forwardRef, Inject, Injectable } from '@nestjs/common';
|
|
2
2
|
import { Media } from 'src/entities/media.entity';
|
|
3
3
|
import { RequestContextService } from 'src/services/request-context.service';
|
|
4
|
-
import { DataSource } from 'typeorm';
|
|
4
|
+
import { DataSource, In } from 'typeorm';
|
|
5
5
|
import { FieldMetadataRepository } from './field-metadata.repository';
|
|
6
6
|
import { MediaStorageProviderMetadataRepository } from './media-storage-provider-metadata.repository';
|
|
7
7
|
import { ModelMetadataRepository } from './model-metadata.repository';
|
|
@@ -21,6 +21,7 @@ export class MediaRepository extends SolidBaseRepository<Media> {
|
|
|
21
21
|
// @InjectRepository(MediaStorageProviderMetadata)
|
|
22
22
|
// private readonly mediaStorageProviderMetadataRepo: Repository<MediaStorageProviderMetadata>,
|
|
23
23
|
private readonly fieldMetadataRepo: FieldMetadataRepository,
|
|
24
|
+
@Inject(forwardRef(() => ModelMetadataRepository))
|
|
24
25
|
private readonly modelMetadataRepo: ModelMetadataRepository,
|
|
25
26
|
private readonly mediaStorageProviderMetadataRepo: MediaStorageProviderMetadataRepository,
|
|
26
27
|
) {
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { ModelSequence } from 'src/entities/model-sequence.entity';
|
|
3
|
+
import { RequestContextService } from 'src/services/request-context.service';
|
|
4
|
+
import { DataSource } from 'typeorm';
|
|
5
|
+
import { SecurityRuleRepository } from './security-rule.repository';
|
|
6
|
+
import { SolidBaseRepository } from './solid-base.repository';
|
|
7
|
+
import { CreateModelSequenceDto } from 'src/dtos/create-model-sequence.dto';
|
|
8
|
+
import { ModuleMetadata } from 'src/entities/module-metadata.entity';
|
|
9
|
+
import { ModelMetadata } from 'src/entities/model-metadata.entity';
|
|
10
|
+
import { FieldMetadata } from 'src/entities/field-metadata.entity';
|
|
11
|
+
|
|
12
|
+
@Injectable()
|
|
13
|
+
export class ModelSequenceRepository extends SolidBaseRepository<ModelSequence> {
|
|
14
|
+
constructor(
|
|
15
|
+
readonly dataSource: DataSource,
|
|
16
|
+
readonly requestContextService: RequestContextService,
|
|
17
|
+
readonly securityRuleRepository: SecurityRuleRepository,
|
|
18
|
+
) {
|
|
19
|
+
super(ModelSequence, dataSource, requestContextService, securityRuleRepository);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async upsertWithDto(createDto: CreateModelSequenceDto) {
|
|
23
|
+
// Populate the module from moduleId or moduleUserKey
|
|
24
|
+
const moduleRepository = this.dataSource.getRepository(ModuleMetadata);
|
|
25
|
+
if (createDto.moduleId) {
|
|
26
|
+
const module = await moduleRepository.findOne({
|
|
27
|
+
where: {
|
|
28
|
+
id: createDto.moduleId,
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
createDto['module'] = module;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (createDto.moduleUserKey) {
|
|
35
|
+
const module = await moduleRepository.findOne({
|
|
36
|
+
where: {
|
|
37
|
+
name: createDto.moduleUserKey,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
createDto['module'] = module;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Populate the model from modelId or modelUserKey
|
|
44
|
+
const modelRepository = this.dataSource.getRepository(ModelMetadata);
|
|
45
|
+
if (createDto.modelId) {
|
|
46
|
+
const model = await modelRepository.findOne({
|
|
47
|
+
where: {
|
|
48
|
+
id: createDto.modelId,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
createDto['model'] = model;
|
|
52
|
+
}
|
|
53
|
+
if (createDto.modelUserKey) {
|
|
54
|
+
const model = await modelRepository.findOne({
|
|
55
|
+
where: {
|
|
56
|
+
singularName: createDto.modelUserKey,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
createDto['model'] = model;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Populate the field from fieldId or fieldUserKey
|
|
63
|
+
const fieldRepository = this.dataSource.getRepository(FieldMetadata);
|
|
64
|
+
if (createDto.fieldId) {
|
|
65
|
+
const field = await fieldRepository.findOne({
|
|
66
|
+
where: {
|
|
67
|
+
id: createDto.fieldId,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
createDto['field'] = field;
|
|
71
|
+
}
|
|
72
|
+
if (createDto.fieldUserKey) {
|
|
73
|
+
const field = await fieldRepository.findOne({
|
|
74
|
+
where: {
|
|
75
|
+
name: createDto.fieldUserKey,
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
createDto['field'] = field;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// First check if sequence already exists using name
|
|
82
|
+
const existingModelSequence = await this.findOne({
|
|
83
|
+
where: {
|
|
84
|
+
sequenceName: createDto.sequenceName,
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
if (existingModelSequence) {
|
|
89
|
+
const updatedModelSequence = this.merge(existingModelSequence, createDto);
|
|
90
|
+
return this.save(updatedModelSequence);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const modelSequence = this.create(createDto);
|
|
94
|
+
return this.save(modelSequence);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|