@solidxai/core 0.1.13-beta.7 → 0.1.13-beta.9
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/.claude/settings.local.json +16 -0
- package/CHANGELOG.md +1651 -0
- package/CLAUDE.md +26 -0
- package/dist/constants/draft-publish-fields.d.ts +2 -0
- package/dist/constants/draft-publish-fields.d.ts.map +1 -0
- package/dist/constants/draft-publish-fields.js +5 -0
- package/dist/constants/draft-publish-fields.js.map +1 -0
- package/dist/constants/media-file-types.d.ts +9 -0
- package/dist/constants/media-file-types.d.ts.map +1 -1
- package/dist/constants/media-file-types.js +27 -1
- package/dist/constants/media-file-types.js.map +1 -1
- package/dist/controllers/action-metadata.controller.d.ts +1 -1
- package/dist/controllers/action-metadata.controller.js +1 -1
- package/dist/controllers/agent-event.controller.d.ts +1 -1
- package/dist/controllers/agent-event.controller.js +1 -1
- package/dist/controllers/agent-session.controller.d.ts +1 -1
- package/dist/controllers/agent-session.controller.js +1 -1
- package/dist/controllers/dashboard-user-layout.controller.d.ts +1 -1
- package/dist/controllers/dashboard-user-layout.controller.js +1 -1
- package/dist/controllers/email-template.controller.d.ts +1 -1
- package/dist/controllers/email-template.controller.js +1 -1
- package/dist/controllers/export-template.controller.d.ts +1 -1
- package/dist/controllers/export-template.controller.d.ts.map +1 -1
- package/dist/controllers/export-template.controller.js +6 -4
- package/dist/controllers/export-template.controller.js.map +1 -1
- package/dist/controllers/export-transaction.controller.d.ts +1 -1
- package/dist/controllers/export-transaction.controller.js +1 -1
- package/dist/controllers/import-transaction-error-log.controller.d.ts +1 -1
- package/dist/controllers/import-transaction-error-log.controller.js +1 -1
- package/dist/controllers/import-transaction.controller.d.ts +1 -1
- package/dist/controllers/import-transaction.controller.d.ts.map +1 -1
- package/dist/controllers/import-transaction.controller.js +7 -7
- package/dist/controllers/import-transaction.controller.js.map +1 -1
- package/dist/controllers/list-of-values.controller.d.ts +1 -1
- package/dist/controllers/list-of-values.controller.js +1 -1
- package/dist/controllers/locale.controller.d.ts +1 -1
- package/dist/controllers/locale.controller.js +1 -1
- package/dist/controllers/mcp-audit-log.controller.d.ts +1 -1
- package/dist/controllers/mcp-audit-log.controller.js +1 -1
- package/dist/controllers/media.controller.d.ts +1 -1
- package/dist/controllers/media.controller.d.ts.map +1 -1
- package/dist/controllers/media.controller.js +12 -7
- package/dist/controllers/media.controller.js.map +1 -1
- package/dist/controllers/menu-item-metadata.controller.d.ts +1 -1
- package/dist/controllers/menu-item-metadata.controller.js +1 -1
- package/dist/controllers/model-sequence.controller.d.ts +1 -1
- package/dist/controllers/model-sequence.controller.js +1 -1
- package/dist/controllers/module-package.controller.d.ts.map +1 -1
- package/dist/controllers/module-package.controller.js +2 -3
- package/dist/controllers/module-package.controller.js.map +1 -1
- package/dist/controllers/mq-message-queue.controller.d.ts +1 -1
- package/dist/controllers/mq-message-queue.controller.js +1 -1
- package/dist/controllers/mq-message.controller.d.ts +1 -1
- package/dist/controllers/mq-message.controller.js +1 -1
- package/dist/controllers/permission-metadata.controller.d.ts +1 -1
- package/dist/controllers/permission-metadata.controller.js +1 -1
- package/dist/controllers/role-metadata.controller.d.ts +1 -1
- package/dist/controllers/role-metadata.controller.js +1 -1
- package/dist/controllers/saved-filters.controller.d.ts +1 -1
- package/dist/controllers/saved-filters.controller.js +1 -1
- package/dist/controllers/scheduled-job.controller.d.ts +1 -1
- package/dist/controllers/scheduled-job.controller.js +1 -1
- package/dist/controllers/security-rule.controller.d.ts +1 -1
- package/dist/controllers/security-rule.controller.js +1 -1
- package/dist/controllers/sms-template.controller.d.ts +1 -1
- package/dist/controllers/sms-template.controller.js +1 -1
- package/dist/controllers/user-activity-history.controller.d.ts +1 -1
- package/dist/controllers/user-activity-history.controller.js +1 -1
- package/dist/controllers/user-view-metadata.controller.d.ts +1 -1
- package/dist/controllers/user-view-metadata.controller.js +1 -1
- package/dist/controllers/user.controller.d.ts +2 -2
- package/dist/controllers/user.controller.js +2 -2
- package/dist/controllers/view-metadata.controller.d.ts +2 -2
- package/dist/controllers/view-metadata.controller.js +1 -1
- package/dist/controllers/workflow-definition.controller.d.ts +1 -1
- package/dist/controllers/workflow-definition.controller.js +1 -1
- package/dist/controllers/workflow-execution-artifact.controller.d.ts +1 -1
- package/dist/controllers/workflow-execution-artifact.controller.js +1 -1
- package/dist/controllers/workflow-execution-log.controller.d.ts +1 -1
- package/dist/controllers/workflow-execution-log.controller.js +1 -1
- package/dist/controllers/workflow-execution.controller.d.ts +1 -1
- package/dist/controllers/workflow-execution.controller.js +1 -1
- package/dist/controllers/workflow-secret.controller.d.ts +1 -1
- package/dist/controllers/workflow-secret.controller.js +1 -1
- package/dist/controllers/workflow-step-execution.controller.d.ts +1 -1
- package/dist/controllers/workflow-step-execution.controller.js +1 -1
- package/dist/controllers/workflow-trigger-execution.controller.d.ts +1 -1
- package/dist/controllers/workflow-trigger-execution.controller.js +1 -1
- package/dist/dtos/basic-filters.dto.d.ts +0 -1
- package/dist/dtos/basic-filters.dto.d.ts.map +1 -1
- package/dist/dtos/basic-filters.dto.js +1 -6
- package/dist/dtos/basic-filters.dto.js.map +1 -1
- package/dist/entities/common.entity.d.ts +4 -0
- package/dist/entities/common.entity.d.ts.map +1 -1
- package/dist/entities/common.entity.js +25 -1
- package/dist/entities/common.entity.js.map +1 -1
- package/dist/entities/user.entity.js +2 -2
- package/dist/entities/user.entity.js.map +1 -1
- package/dist/factories/mail.factory.d.ts.map +1 -1
- package/dist/factories/mail.factory.js +4 -0
- package/dist/factories/mail.factory.js.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts +1 -0
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +18 -11
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js.map +1 -1
- package/dist/helpers/file-download.helper.d.ts +9 -0
- package/dist/helpers/file-download.helper.d.ts.map +1 -0
- package/dist/helpers/file-download.helper.js +14 -0
- package/dist/helpers/file-download.helper.js.map +1 -0
- package/dist/helpers/model-metadata-helper.service.d.ts.map +1 -1
- package/dist/helpers/model-metadata-helper.service.js +30 -1
- package/dist/helpers/model-metadata-helper.service.js.map +1 -1
- package/dist/helpers/solid-registry.js +1 -1
- package/dist/helpers/solid-registry.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/seeders/module-test-data.service.d.ts +3 -1
- package/dist/seeders/module-test-data.service.d.ts.map +1 -1
- package/dist/seeders/module-test-data.service.js +8 -2
- package/dist/seeders/module-test-data.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +2 -0
- package/dist/services/authentication.service.d.ts +4 -1
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +52 -4
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/chatter-message.service.d.ts +1 -0
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +8 -0
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/crud-helper.service.d.ts +5 -2
- package/dist/services/crud-helper.service.d.ts.map +1 -1
- package/dist/services/crud-helper.service.js +30 -32
- package/dist/services/crud-helper.service.js.map +1 -1
- package/dist/services/crud.service.d.ts +11 -1
- package/dist/services/crud.service.d.ts.map +1 -1
- package/dist/services/crud.service.js +79 -66
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/datasource-introspection.service.d.ts.map +1 -1
- package/dist/services/datasource-introspection.service.js.map +1 -1
- package/dist/services/draft-publish-helper.service.d.ts +52 -0
- package/dist/services/draft-publish-helper.service.d.ts.map +1 -0
- package/dist/services/draft-publish-helper.service.js +368 -0
- package/dist/services/draft-publish-helper.service.js.map +1 -0
- package/dist/services/internationalisation-helper.service.d.ts +19 -0
- package/dist/services/internationalisation-helper.service.d.ts.map +1 -0
- package/dist/services/internationalisation-helper.service.js +107 -0
- package/dist/services/internationalisation-helper.service.js.map +1 -0
- package/dist/services/locale.service.d.ts +1 -1
- package/dist/services/media.service.d.ts +2 -1
- package/dist/services/media.service.d.ts.map +1 -1
- package/dist/services/media.service.js +28 -2
- package/dist/services/media.service.js.map +1 -1
- package/dist/services/metadata-validation.service.d.ts +7 -0
- package/dist/services/metadata-validation.service.d.ts.map +1 -0
- package/dist/services/metadata-validation.service.js +42 -0
- package/dist/services/metadata-validation.service.js.map +1 -0
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +2 -1
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/object.utils.d.ts +2 -0
- package/dist/services/object.utils.d.ts.map +1 -0
- package/dist/services/object.utils.js +11 -0
- package/dist/services/object.utils.js.map +1 -0
- package/dist/services/settings/default-settings-provider.service.d.ts +10 -10
- package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
- package/dist/services/settings/default-settings-provider.service.js +9 -5
- package/dist/services/settings/default-settings-provider.service.js.map +1 -1
- package/dist/services/user.service.d.ts +2 -2
- package/dist/services/user.service.d.ts.map +1 -1
- package/dist/services/user.service.js +9 -3
- package/dist/services/user.service.js.map +1 -1
- package/dist/services/view-metadata.service.d.ts +1 -2
- package/dist/services/view-metadata.service.d.ts.map +1 -1
- package/dist/services/view-metadata.service.js +3 -55
- package/dist/services/view-metadata.service.js.map +1 -1
- package/dist/services/workflow-definition.service.d.ts +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +10 -1
- package/dist/solid-core.module.js.map +1 -1
- package/package.json +1 -1
- package/src/constants/draft-publish-fields.ts +5 -0
- package/src/constants/media-file-types.ts +50 -0
- package/src/controllers/export-template.controller.ts +5 -3
- package/src/controllers/import-transaction.controller.ts +6 -6
- package/src/controllers/media.controller.ts +17 -6
- package/src/controllers/module-package.controller.ts +2 -3
- package/src/dtos/basic-filters.dto.ts +0 -4
- package/src/entities/common.entity.ts +24 -0
- package/src/entities/user.entity.ts +2 -2
- package/src/factories/mail.factory.ts +7 -1
- package/src/helpers/field-crud-managers/MediaFieldCrudManager.ts +26 -12
- package/src/helpers/file-download.helper.ts +31 -0
- package/src/helpers/model-metadata-helper.service.ts +32 -1
- package/src/helpers/solid-registry.ts +1 -1
- package/src/index.ts +2 -0
- package/src/seeders/module-test-data.service.ts +6 -0
- package/src/seeders/seed-data/solid-core-metadata.json +2 -0
- package/src/services/1.js +6 -0
- package/src/services/authentication.service.ts +76 -5
- package/src/services/chatter-message.service.ts +16 -0
- package/src/services/crud-helper.service.ts +16 -34
- package/src/services/crud.service.ts +98 -103
- package/src/services/datasource-introspection.service.ts +5 -0
- package/src/services/draft-publish-helper.service.ts +529 -0
- package/src/services/internationalisation-helper.service.ts +148 -0
- package/src/services/media.service.ts +48 -3
- package/src/services/metadata-validation.service.ts +39 -0
- package/src/services/model-metadata.service.ts +4 -1
- package/src/services/object.utils.ts +10 -0
- package/src/services/settings/default-settings-provider.service.ts +15 -5
- package/src/services/user.service.ts +18 -3
- package/src/services/view-metadata.service.ts +5 -145
- package/src/solid-core.module.ts +16 -3
- package/src/testing/README.md +9 -0
- package/dist-tests/api/authenticate.spec.js +0 -119
- package/dist-tests/api/authenticate.spec.js.map +0 -1
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +0 -97
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +0 -1
- package/dist-tests/api/ping.spec.js +0 -21
- package/dist-tests/api/ping.spec.js.map +0 -1
- package/dist-tests/helpers/auth.js +0 -41
- package/dist-tests/helpers/auth.js.map +0 -1
- package/dist-tests/helpers/env.js +0 -11
- package/dist-tests/helpers/env.js.map +0 -1
- package/docs/agent-builder/notebook-lm-prompt-for-agent-builder.md +0 -136
- package/docs/agent-builder/team-ready-note-agent-builder.md +0 -305
- package/docs/agent-hub-grooming.md +0 -301
- package/docs/dashboards/AGENTIC_DASHBOARD_IMPLEMENTATION_PLAN.md +0 -438
- package/docs/dashboards/dashboard-curl-smoke-tests.txt +0 -146
- package/docs/dashboards/delete-legacy-dashboard-metadata.sql +0 -172
- package/docs/datasource-introspection-ddl-analysis.md +0 -326
- package/docs/datasource-introspection-implementation-plan.md +0 -306
- package/docs/grouping-enhancements.md +0 -89
- package/docs/java-spring/README.md +0 -3
- package/docs/java-spring/solid-core-module-deep-dive-report.md +0 -1317
- package/docs/module-package-import-handoff.md +0 -691
- package/docs/seed-changes.md +0 -65
- package/docs/test-data-workflow.md +0 -200
- package/docs/type-declaration-import-issue.md +0 -24
- package/docs/workflow/business-automation-example-notes.md +0 -309
- package/docs/workflow/control-flow-node-addition-sop.md +0 -324
- package/docs/workflow/data-engineering-pipeline-example-notes.md +0 -330
- package/docs/workflow/foreach-example-notes.md +0 -187
- package/docs/workflow/hello-world-example-notes.md +0 -271
- package/docs/workflow/kestra-concepts-plugins-blueprints.md +0 -315
- package/docs/workflow/loop-until-example-notes.md +0 -198
- package/docs/workflow/microservices-and-apis-example-notes.md +0 -264
- package/docs/workflow/samples.md +0 -25
- package/docs/workflow/what-is-kestra.md +0 -79
- package/docs/workflow/workflow-core-module-handoff-summary.md +0 -191
- package/docs/workflow/workflow-module-brd.md +0 -185
- package/docs/workflow/workflow-module-domain-model.md +0 -252
- package/docs/workflow/workflow-module-metadata-dsl.md +0 -302
- package/docs/workflow/workflow-module-technical-spec.md +0 -293
- package/docs/workflow/workflow-node-type-contracts.md +0 -635
- package/docs/workflow/workflow-node-ui-metadata-contract.md +0 -1262
- package/docs/workflow/workflow-solidx-model-field-spec.md +0 -284
|
@@ -37,6 +37,8 @@ import { ShortTextFieldCrudManager } from "../helpers/field-crud-managers/ShortT
|
|
|
37
37
|
import { UUIDFieldCrudManager } from "../helpers/field-crud-managers/UUIDFieldCrudManager";
|
|
38
38
|
import { ModelMetadataHelperService } from "src/helpers/model-metadata-helper.service";
|
|
39
39
|
import { FieldCrudManager, MediaWithFullUrl } from "../interfaces";
|
|
40
|
+
import { DraftPublishHelperService } from "./draft-publish-helper.service";
|
|
41
|
+
import { InternationalisationHelperService } from "./internationalisation-helper.service";
|
|
40
42
|
import { CrudHelperService, FilterCombinator, UserIdFields } from "./crud-helper.service";
|
|
41
43
|
import { HashingService } from "./hashing.service";
|
|
42
44
|
import { SolidRegistry } from "src/helpers/solid-registry";
|
|
@@ -50,6 +52,8 @@ export class CRUDService<T extends CommonEntity> { // Add two generic value i.e
|
|
|
50
52
|
|
|
51
53
|
private _modelMetadataService: ModelMetadataService;
|
|
52
54
|
private _crudHelperService: CrudHelperService;
|
|
55
|
+
private _draftPublishHelperService: DraftPublishHelperService;
|
|
56
|
+
private _internationalisationHelperService: InternationalisationHelperService;
|
|
53
57
|
private _discoveryService: DiscoveryService;
|
|
54
58
|
private _settingService: SettingService;
|
|
55
59
|
|
|
@@ -70,6 +74,14 @@ export class CRUDService<T extends CommonEntity> { // Add two generic value i.e
|
|
|
70
74
|
return this._crudHelperService ??= this.moduleRef.get(CrudHelperService, { strict: false });
|
|
71
75
|
}
|
|
72
76
|
|
|
77
|
+
protected get draftPublishHelperService(): DraftPublishHelperService {
|
|
78
|
+
return this._draftPublishHelperService ??= this.moduleRef.get(DraftPublishHelperService, { strict: false });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
protected get internationalisationHelperService(): InternationalisationHelperService {
|
|
82
|
+
return this._internationalisationHelperService ??= this.moduleRef.get(InternationalisationHelperService, { strict: false });
|
|
83
|
+
}
|
|
84
|
+
|
|
73
85
|
protected get discoveryService(): DiscoveryService {
|
|
74
86
|
return this._discoveryService ??= this.moduleRef.get(DiscoveryService, { strict: false });
|
|
75
87
|
}
|
|
@@ -78,6 +90,19 @@ export class CRUDService<T extends CommonEntity> { // Add two generic value i.e
|
|
|
78
90
|
return this._settingService ??= this.moduleRef.get(SettingService, { strict: false });
|
|
79
91
|
}
|
|
80
92
|
|
|
93
|
+
private getDraftPublishCrudContext() {
|
|
94
|
+
return {
|
|
95
|
+
repo: this.repo,
|
|
96
|
+
modelName: this.modelName,
|
|
97
|
+
moduleName: this.moduleName,
|
|
98
|
+
validateAndTransformDto: this.validateAndTransformDto.bind(this),
|
|
99
|
+
saveMedia: this.saveMedia.bind(this),
|
|
100
|
+
getDatasourceDefaultEntityManager: this.getDatasourceDefaultEntityManager.bind(this),
|
|
101
|
+
getColumnDatabaseName: this.getColumnDatabaseName.bind(this),
|
|
102
|
+
escapeDatabaseName: this.escapeDatabaseName.bind(this),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
81
106
|
private async tryCreateAsExtensionUser(createDto: any): Promise<T | null> {
|
|
82
107
|
if (this.repo.metadata?.parentEntityMetadata?.target !== User) return null;
|
|
83
108
|
const registry = this.moduleRef.get(SolidRegistry, { strict: false });
|
|
@@ -123,8 +148,11 @@ export class CRUDService<T extends CommonEntity> { // Add two generic value i.e
|
|
|
123
148
|
try {
|
|
124
149
|
// 5. Save the entity
|
|
125
150
|
// For media, we need to use a storage provider and save the media, then save the associated uri against the entity or media table
|
|
151
|
+
this.draftPublishHelperService.applyCreateDefaults(model, createDto);
|
|
152
|
+
this.internationalisationHelperService.applyCreateDefaults(model, createDto, this.moduleRef.get(SolidRegistry, { strict: false }));
|
|
126
153
|
const entity = this.repo.create(createDto);
|
|
127
|
-
|
|
154
|
+
let savedEntity = await this.repo.save(entity) as unknown as T;
|
|
155
|
+
savedEntity = await this.draftPublishHelperService.ensureInitialEntityVersionId(model, this.repo, savedEntity);
|
|
128
156
|
|
|
129
157
|
// 6. Save the media
|
|
130
158
|
if (hasMediaFields) {
|
|
@@ -211,9 +239,10 @@ export class CRUDService<T extends CommonEntity> { // Add two generic value i.e
|
|
|
211
239
|
throw new Error(`Entity [${this.moduleName}.${this.modelName}] with id ${id} not found`);
|
|
212
240
|
}
|
|
213
241
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
242
|
+
this.draftPublishHelperService.assertUpdateAllowed(model, entity, this.modelName);
|
|
243
|
+
|
|
244
|
+
if (this.draftPublishHelperService.shouldCopyPublishedVersionForUpdate(model, entity)) {
|
|
245
|
+
return this.draftPublishHelperService.copyPublishedVersionAndUpdate(this.getDraftPublishCrudContext(), id, updateDto, files, isPartialUpdate, model);
|
|
217
246
|
}
|
|
218
247
|
|
|
219
248
|
// Capture pre-update many-to-many relation state for audit tracking
|
|
@@ -245,6 +274,18 @@ export class CRUDService<T extends CommonEntity> { // Add two generic value i.e
|
|
|
245
274
|
return savedEntity;
|
|
246
275
|
}
|
|
247
276
|
|
|
277
|
+
private getColumnDatabaseName(propertyName: string): string {
|
|
278
|
+
const column = this.repo.metadata.findColumnWithPropertyName(propertyName);
|
|
279
|
+
if (!column) {
|
|
280
|
+
throw new Error(`Column ${propertyName} not found in entity ${this.repo.metadata.name}`);
|
|
281
|
+
}
|
|
282
|
+
return column.databaseName;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
private escapeDatabaseName(databaseName: string): string {
|
|
286
|
+
return this.repo.manager.connection.driver.escape(databaseName);
|
|
287
|
+
}
|
|
288
|
+
|
|
248
289
|
/**
|
|
249
290
|
* Captures the current state of audit-enabled many-to-many relations
|
|
250
291
|
* before the entity is updated. The snapshot is attached to the entity
|
|
@@ -307,32 +348,37 @@ private async prepareManyToManyAuditSnapshot(entity: T,id: number,modelSingularN
|
|
|
307
348
|
throw new Error(`Entity [${this.moduleName}.${this.modelName}] with id ${id} not found`);
|
|
308
349
|
}
|
|
309
350
|
|
|
310
|
-
|
|
311
|
-
|
|
351
|
+
const entitiesToDelete: T[] = [entity];
|
|
352
|
+
if (this.draftPublishHelperService.isDraftPublishEnabled(model)) {
|
|
353
|
+
this.draftPublishHelperService.assertDraftPublishDeleteAllowed(this.modelName, entitiesToDelete);
|
|
312
354
|
}
|
|
313
355
|
|
|
314
|
-
|
|
315
|
-
if (model.internationalisation) {
|
|
316
|
-
// Find all child entities where defaultEntityLocaleId === this entity's id
|
|
317
|
-
const childEntities = await this.repo.find({
|
|
318
|
-
where: { defaultEntityLocaleId: id } as any
|
|
319
|
-
});
|
|
356
|
+
await this.internationalisationHelperService.deleteChildLocaleEntities(this.repo, model, [id]);
|
|
320
357
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
358
|
+
return this.deleteEntitiesAndPromote(model, entitiesToDelete);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
private async deleteEntitiesAndPromote(model: ModelMetadata, entitiesToDelete: T[]): Promise<T[]> {
|
|
362
|
+
const isDraftPublishEnabled = this.draftPublishHelperService.isDraftPublishEnabled(model);
|
|
363
|
+
const deletedLatestChainIds = isDraftPublishEnabled
|
|
364
|
+
? this.draftPublishHelperService.getLatestDraftPublishChainIds(entitiesToDelete)
|
|
365
|
+
: [];
|
|
329
366
|
|
|
367
|
+
let deleteResult: T[];
|
|
330
368
|
if (model.enableSoftDelete === true) {
|
|
331
|
-
|
|
332
|
-
|
|
369
|
+
this.draftPublishHelperService.markDeletedDraftPublishVersionsAsNotLatest(model, entitiesToDelete);
|
|
370
|
+
await this.repo.softRemove(entitiesToDelete);
|
|
371
|
+
deleteResult = await this.repo.save(entitiesToDelete);
|
|
333
372
|
} else {
|
|
334
|
-
|
|
373
|
+
deleteResult = await this.repo.remove(entitiesToDelete);
|
|
335
374
|
}
|
|
375
|
+
|
|
376
|
+
if (isDraftPublishEnabled) {
|
|
377
|
+
const deletedEntityIds = this.draftPublishHelperService.getEntityIds(entitiesToDelete);
|
|
378
|
+
await this.draftPublishHelperService.promoteLatestDraftPublishVersionAfterDelete(this.repo, deletedLatestChainIds, deletedEntityIds);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
return deleteResult;
|
|
336
382
|
}
|
|
337
383
|
|
|
338
384
|
private async fieldCrudManager(fieldMetadata: FieldMetadata, entityManager: EntityManager, isPartialUpdate: boolean = false, isUpdate: boolean = false, entityId?: number) {
|
|
@@ -529,9 +575,7 @@ private async prepareManyToManyAuditSnapshot(entity: T,id: number,modelSingularN
|
|
|
529
575
|
var qb: SelectQueryBuilder<T> = await this.repo.createSecurityRuleAwareQueryBuilder(alias)
|
|
530
576
|
|
|
531
577
|
if (basicFilterDto.groupBy?.length) {
|
|
532
|
-
const groupFilterQb = (internationalisation
|
|
533
|
-
? this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias, internationalisation, draftPublishWorkflow, this.moduleRef, FilterCombinator.AND, false, false)
|
|
534
|
-
: this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias, undefined, undefined, undefined, FilterCombinator.AND, false, false);
|
|
578
|
+
const groupFilterQb = this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias, internationalisation, draftPublishWorkflow, this.moduleRef, FilterCombinator.AND, false, false);
|
|
535
579
|
|
|
536
580
|
return this.crudHelperService.executeGroupPipeline(
|
|
537
581
|
groupFilterQb, basicFilterDto, alias,
|
|
@@ -543,9 +587,7 @@ private async prepareManyToManyAuditSnapshot(entity: T,id: number,modelSingularN
|
|
|
543
587
|
);
|
|
544
588
|
}
|
|
545
589
|
else {
|
|
546
|
-
qb = (internationalisation
|
|
547
|
-
? this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias, internationalisation, draftPublishWorkflow, this.moduleRef)
|
|
548
|
-
: this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias);
|
|
590
|
+
qb = this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias, internationalisation, draftPublishWorkflow, this.moduleRef);
|
|
549
591
|
const { meta, records } = await this.handleNonGroupFind(qb, populateUserIdFields, populateMedia, offset, limit, alias);
|
|
550
592
|
return {
|
|
551
593
|
meta,
|
|
@@ -795,6 +837,7 @@ private async prepareManyToManyAuditSnapshot(entity: T,id: number,modelSingularN
|
|
|
795
837
|
module: true,
|
|
796
838
|
});
|
|
797
839
|
|
|
840
|
+
const solidRegistry = this.moduleRef.get(SolidRegistry, { strict: false });
|
|
798
841
|
const entitiesForSave: T[] = [];
|
|
799
842
|
for (const createDto of createDtos) {
|
|
800
843
|
// Validate and transform each createDto sequentially
|
|
@@ -807,6 +850,7 @@ private async prepareManyToManyAuditSnapshot(entity: T,id: number,modelSingularN
|
|
|
807
850
|
}
|
|
808
851
|
transformedDto = await fieldManager.transformForCreate(createDto);
|
|
809
852
|
}
|
|
853
|
+
this.internationalisationHelperService.applyCreateDefaults(model, transformedDto, solidRegistry);
|
|
810
854
|
const entity = this.repo.create(transformedDto);
|
|
811
855
|
entitiesForSave.push(entity as unknown as T);
|
|
812
856
|
}
|
|
@@ -844,7 +888,7 @@ private async prepareManyToManyAuditSnapshot(entity: T,id: number,modelSingularN
|
|
|
844
888
|
|
|
845
889
|
|
|
846
890
|
|
|
847
|
-
const removedEntities = [];
|
|
891
|
+
const removedEntities: T[] = [];
|
|
848
892
|
for (let i = 0; i < ids.length; i++) {
|
|
849
893
|
const id = ids[i]
|
|
850
894
|
const entity = await this.repo.findOne({
|
|
@@ -853,36 +897,21 @@ private async prepareManyToManyAuditSnapshot(entity: T,id: number,modelSingularN
|
|
|
853
897
|
} as unknown as FindOptionsWhere<T>,
|
|
854
898
|
});
|
|
855
899
|
|
|
900
|
+
if (!entity) {
|
|
901
|
+
throw new Error(`Entity [${this.moduleName}.${this.modelName}] with id ${id} not found`);
|
|
902
|
+
}
|
|
903
|
+
|
|
856
904
|
removedEntities.push(entity);
|
|
857
905
|
}
|
|
858
906
|
|
|
859
907
|
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
let publishedEntitiesExists: T[] = [];
|
|
864
|
-
|
|
865
|
-
if (isDraftPublishEnabled) {
|
|
866
|
-
publishedEntitiesExists = removedEntities.filter(
|
|
867
|
-
(x) => !!x?.publishedAt
|
|
868
|
-
);
|
|
908
|
+
if (this.draftPublishHelperService.isDraftPublishEnabled(model)) {
|
|
909
|
+
this.draftPublishHelperService.assertDraftPublishDeleteAllowed(this.modelName, removedEntities);
|
|
869
910
|
}
|
|
870
911
|
|
|
871
|
-
|
|
872
|
-
const publishedEntitiesExistsID = publishedEntitiesExists.map(x => x.id);
|
|
912
|
+
await this.internationalisationHelperService.deleteChildLocaleEntities(this.repo, model, ids);
|
|
873
913
|
|
|
874
|
-
|
|
875
|
-
`Cannot delete published record(s) for model ${this.modelName} with Ids ${publishedEntitiesExistsID.join(', ')}. Unpublish them first.`
|
|
876
|
-
);
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
if (model.enableSoftDelete === true) {
|
|
880
|
-
await this.repo.softRemove(removedEntities);
|
|
881
|
-
return this.repo.save(removedEntities);
|
|
882
|
-
} else {
|
|
883
|
-
return this.repo.remove(removedEntities);
|
|
884
|
-
}
|
|
885
|
-
// return removedEntities
|
|
914
|
+
return this.deleteEntitiesAndPromote(model, removedEntities);
|
|
886
915
|
}
|
|
887
916
|
|
|
888
917
|
async recover(id: number, solidRequestContext: any = {}) {
|
|
@@ -912,6 +941,10 @@ private async prepareManyToManyAuditSnapshot(entity: T,id: number,modelSingularN
|
|
|
912
941
|
} as unknown as QueryDeepPartialEntity<T>
|
|
913
942
|
);
|
|
914
943
|
|
|
944
|
+
if (this.draftPublishHelperService.isDraftPublishEnabled(loadedmodel)) {
|
|
945
|
+
await this.draftPublishHelperService.promoteRecoveredDraftPublishVersion(this.repo, softDeletedRows);
|
|
946
|
+
}
|
|
947
|
+
|
|
915
948
|
return { message: SUCCESS_MESSAGES.RECORD_RECOVERED, data: softDeletedRows };
|
|
916
949
|
} catch (error: any) {
|
|
917
950
|
if (error instanceof QueryFailedError && (error as any).code === '23505') {
|
|
@@ -958,6 +991,14 @@ private async prepareManyToManyAuditSnapshot(entity: T,id: number,modelSingularN
|
|
|
958
991
|
{ deletedAt: null, deletedTracker: "not-deleted" } as unknown as QueryDeepPartialEntity<T>
|
|
959
992
|
);
|
|
960
993
|
|
|
994
|
+
if (this.draftPublishHelperService.isDraftPublishEnabled(loadedmodel)) {
|
|
995
|
+
// Sequential: two ids in the same batch could belong to the same version
|
|
996
|
+
// chain, and each promotion clears isLatest across the whole chain first.
|
|
997
|
+
for (const entity of softDeletedRows) {
|
|
998
|
+
await this.draftPublishHelperService.promoteRecoveredDraftPublishVersion(this.repo, entity);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
|
|
961
1002
|
return { message: SUCCESS_MESSAGES.SELECTED_RECORDS_RECOVERED, recoveredIds: ids };
|
|
962
1003
|
} catch (error: any) {
|
|
963
1004
|
if (error instanceof QueryFailedError && (error as any).code === "23505") {
|
|
@@ -1012,18 +1053,11 @@ private async prepareManyToManyAuditSnapshot(entity: T,id: number,modelSingularN
|
|
|
1012
1053
|
return model.userKeyField?.name || '';
|
|
1013
1054
|
}
|
|
1014
1055
|
|
|
1015
|
-
/* Publish a record -
|
|
1056
|
+
/* Publish a record - marks the selected version as the active published version. */
|
|
1016
1057
|
async publishRecord(id: number, solidRequestContext: any = {}): Promise<T> {
|
|
1017
1058
|
|
|
1018
1059
|
const model = await this.loadModel();
|
|
1019
1060
|
|
|
1020
|
-
// Check if publish workflow is enabled for this model
|
|
1021
|
-
if (!model.draftPublishWorkflow) {
|
|
1022
|
-
throw new BadRequestException(
|
|
1023
|
-
`Publish workflow is not enabled for ${this.modelName}`
|
|
1024
|
-
);
|
|
1025
|
-
}
|
|
1026
|
-
|
|
1027
1061
|
// Check user permissions
|
|
1028
1062
|
if (solidRequestContext.activeUser) {
|
|
1029
1063
|
const hasPermission = this.crudHelperService.hasPublishPermissionOnModel(
|
|
@@ -1035,37 +1069,14 @@ private async prepareManyToManyAuditSnapshot(entity: T,id: number,modelSingularN
|
|
|
1035
1069
|
}
|
|
1036
1070
|
}
|
|
1037
1071
|
|
|
1038
|
-
|
|
1039
|
-
const entity = await this.repo.findOne({ where: { id } as any });
|
|
1040
|
-
if (!entity) {
|
|
1041
|
-
throw new NotFoundException(`${this.modelName} with id ${id} not found`);
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
// Check if already published
|
|
1045
|
-
if (entity.publishedAt) {
|
|
1046
|
-
throw new BadRequestException(
|
|
1047
|
-
`${this.modelName} with id ${id} is already published`
|
|
1048
|
-
);
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
// Update publish status
|
|
1052
|
-
const updatedEntity = await this.repo.save({ ...entity, publishedAt: new Date() });
|
|
1053
|
-
|
|
1054
|
-
return updatedEntity
|
|
1072
|
+
return this.draftPublishHelperService.publishRecord(this.repo, model, this.modelName, id, solidRequestContext.activeUser);
|
|
1055
1073
|
}
|
|
1056
1074
|
|
|
1057
|
-
/* Unpublish a record -
|
|
1075
|
+
/* Unpublish a record - marks the selected version as not currently published. */
|
|
1058
1076
|
async unpublishRecord(id: number, solidRequestContext: any = {}): Promise<T> {
|
|
1059
1077
|
|
|
1060
1078
|
const model = await this.loadModel();
|
|
1061
1079
|
|
|
1062
|
-
// Check if publish workflow is enabled for this model
|
|
1063
|
-
if (!model.draftPublishWorkflow) {
|
|
1064
|
-
throw new BadRequestException(
|
|
1065
|
-
`Publish workflow is not enabled for ${this.modelName}`
|
|
1066
|
-
);
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
1080
|
// Check user permissions
|
|
1070
1081
|
if (solidRequestContext.activeUser) {
|
|
1071
1082
|
const hasPermission = this.crudHelperService.hasUnpublishPermissionOnModel(
|
|
@@ -1077,23 +1088,7 @@ private async prepareManyToManyAuditSnapshot(entity: T,id: number,modelSingularN
|
|
|
1077
1088
|
}
|
|
1078
1089
|
}
|
|
1079
1090
|
|
|
1080
|
-
|
|
1081
|
-
const entity = await this.repo.findOne({ where: { id } as any });
|
|
1082
|
-
if (!entity) {
|
|
1083
|
-
throw new NotFoundException(`${this.modelName} with id ${id} not found`);
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
// Check if already unpublished
|
|
1087
|
-
if (!entity.publishedAt) {
|
|
1088
|
-
throw new BadRequestException(
|
|
1089
|
-
`${this.modelName} with id ${id} is already unpublished`
|
|
1090
|
-
);
|
|
1091
|
-
}
|
|
1092
|
-
|
|
1093
|
-
// Update unpublish status
|
|
1094
|
-
const updatedEntity = await this.repo.save({ ...entity, publishedAt: null });
|
|
1095
|
-
|
|
1096
|
-
return updatedEntity
|
|
1091
|
+
return this.draftPublishHelperService.unpublishRecord(this.repo, model, this.modelName, id, solidRequestContext.activeUser);
|
|
1097
1092
|
}
|
|
1098
1093
|
|
|
1099
1094
|
private getDatasourceDefaultEntityManager() {
|
|
@@ -1680,6 +1680,11 @@ export class DatasourceIntrospectionService {
|
|
|
1680
1680
|
|
|
1681
1681
|
private getLegacySuperclassFieldName(columnName: string, legacyTableType: LegacyTableType) {
|
|
1682
1682
|
const normalized = columnName.toLowerCase();
|
|
1683
|
+
// LegacyCommonEntityWithExistingId doesn't declare the draft/publish versioning
|
|
1684
|
+
// columns (see DRAFT_PUBLISH_VERSIONING_FIELD_NAMES), so their ss_-prefixed column
|
|
1685
|
+
// names must not appear here — otherwise a table that still physically has one of
|
|
1686
|
+
// those columns would have it silently treated as superclass-handled and dropped
|
|
1687
|
+
// from introspection instead of being surfaced as a real column.
|
|
1683
1688
|
const legacyFieldMap: Record<string, string> = {
|
|
1684
1689
|
ss_created_at: "createdAt",
|
|
1685
1690
|
ss_updated_at: "updatedAt",
|