@tstdl/base 0.92.134 → 0.92.135
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/api/response.js +6 -6
- package/document-management/server/services/document-file.service.js +4 -4
- package/document-management/server/services/document-management-ai.service.js +1 -1
- package/document-management/server/services/document-management.service.js +23 -11
- package/document-management/server/services/document-workflow.service.d.ts +1 -0
- package/document-management/server/services/document-workflow.service.js +15 -4
- package/document-management/server/services/document.service.js +1 -1
- package/document-management/service-models/document-management.view-model.d.ts +15 -4
- package/document-management/service-models/document-management.view-model.js +42 -12
- package/document-management/service-models/enriched/enriched-document-assignment.view.d.ts +13 -4
- package/document-management/service-models/enriched/enriched-document-assignment.view.js +29 -7
- package/document-management/service-models/enriched/enriched-document-collection.view.js +1 -1
- package/document-management/service-models/enriched/enriched-document-request.view.d.ts +1 -1
- package/document-management/service-models/enriched/enriched-document.view.d.ts +2 -2
- package/document-management/service-models/enriched/enriched-document.view.js +2 -6
- package/examples/document-management/main.js +4 -1
- package/object-storage/object-storage.d.ts +1 -0
- package/object-storage/s3/s3.object-storage.d.ts +1 -1
- package/object-storage/s3/s3.object-storage.js +7 -5
- package/orm/server/repository.js +37 -37
- package/package.json +1 -1
- package/schema/schema.error.js +4 -7
package/api/response.js
CHANGED
|
@@ -35,8 +35,8 @@ export function createErrorResponse(errorOrName, message = '', details) {
|
|
|
35
35
|
name: errorOrName.name,
|
|
36
36
|
message: errorOrName.message,
|
|
37
37
|
details,
|
|
38
|
-
data
|
|
39
|
-
}
|
|
38
|
+
data,
|
|
39
|
+
},
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
else {
|
|
@@ -44,8 +44,8 @@ export function createErrorResponse(errorOrName, message = '', details) {
|
|
|
44
44
|
error: {
|
|
45
45
|
name: errorOrName.name,
|
|
46
46
|
message: errorOrName.message,
|
|
47
|
-
details
|
|
48
|
-
}
|
|
47
|
+
details,
|
|
48
|
+
},
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -54,8 +54,8 @@ export function createErrorResponse(errorOrName, message = '', details) {
|
|
|
54
54
|
error: {
|
|
55
55
|
name: errorOrName,
|
|
56
56
|
message,
|
|
57
|
-
details
|
|
58
|
-
}
|
|
57
|
+
details,
|
|
58
|
+
},
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
61
|
return response;
|
|
@@ -102,7 +102,7 @@ let DocumentFileService = DocumentFileService_1 = class DocumentFileService exte
|
|
|
102
102
|
*/
|
|
103
103
|
async initiateUpload({ key }) {
|
|
104
104
|
const id = getRandomString(64, Alphabet.LowerUpperCaseNumbers);
|
|
105
|
-
const url = await this.#fileUploadObjectStorage.getUploadUrl(id, currentTimestamp() + (5 * millisecondsPerMinute), { metadata: {
|
|
105
|
+
const url = await this.#fileUploadObjectStorage.getUploadUrl(id, currentTimestamp() + (5 * millisecondsPerMinute), { metadata: { 'upload-key': key } });
|
|
106
106
|
return { uploadId: id, uploadUrl: url };
|
|
107
107
|
}
|
|
108
108
|
async create(content, originalFileName) {
|
|
@@ -110,7 +110,7 @@ let DocumentFileService = DocumentFileService_1 = class DocumentFileService exte
|
|
|
110
110
|
if (isUpload) {
|
|
111
111
|
const object = await this.#fileUploadObjectStorage.getObject(content.uploadId);
|
|
112
112
|
const objectMetadata = await object.getMetadata();
|
|
113
|
-
if (content.uploadKey != objectMetadata['
|
|
113
|
+
if (content.uploadKey != objectMetadata['upload-key']) {
|
|
114
114
|
throw new ForbiddenError(`Invalid upload key`);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
@@ -133,7 +133,7 @@ let DocumentFileService = DocumentFileService_1 = class DocumentFileService exte
|
|
|
133
133
|
await this.#fileUploadObjectStorage.moveObject(content.uploadId, [this.#fileObjectStorage, objectKey]);
|
|
134
134
|
return [documentFile, contentAsUint8Array];
|
|
135
135
|
}
|
|
136
|
-
await this.#fileObjectStorage.uploadObject(objectKey, contentAsUint8Array);
|
|
136
|
+
await this.#fileObjectStorage.uploadObject(objectKey, contentAsUint8Array, { contentLength: contentAsUint8Array.length, contentType: mimeType });
|
|
137
137
|
return documentFile;
|
|
138
138
|
});
|
|
139
139
|
}
|
|
@@ -209,7 +209,7 @@ let DocumentFileService = DocumentFileService_1 = class DocumentFileService exte
|
|
|
209
209
|
})
|
|
210
210
|
.with('image/*', async () => await imageToPreview(content))
|
|
211
211
|
.otherwise(() => { throw new NotImplementedError('Preview generation is not implemented for this file type.'); });
|
|
212
|
-
await this.#filePreviewObjectStorage.uploadObject(key, image, { contentLength: image.length,
|
|
212
|
+
await this.#filePreviewObjectStorage.uploadObject(key, image, { contentLength: image.length, contentType: 'image/jpeg' });
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
215
|
async getDocumentFileContentObjectUrl(title, file, download) {
|
|
@@ -93,7 +93,7 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
|
|
|
93
93
|
try {
|
|
94
94
|
const document = await this.#documentRepository.load(documentId);
|
|
95
95
|
const file = await this.#documentFileService.load(document.fileId);
|
|
96
|
-
const fileContentStream = this.#documentFileService.getContentStream(document.
|
|
96
|
+
const fileContentStream = this.#documentFileService.getContentStream(document.fileId);
|
|
97
97
|
const tmpFile = __addDisposableResource(env_1, await TemporaryFile.from(fileContentStream), true);
|
|
98
98
|
const filePart = await this.#aiService.processFile({ path: tmpFile.path, mimeType: file.mimeType });
|
|
99
99
|
const categories = await this.#documentCategoryTypeService.loadCategoryViews();
|
|
@@ -6,14 +6,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { Enumerable } from '../../../enumerable/index.js';
|
|
8
8
|
import { inject } from '../../../injector/index.js';
|
|
9
|
-
import { getEntityMap } from '../../../orm/index.js';
|
|
10
9
|
import { Transactional, injectRepository } from '../../../orm/server/index.js';
|
|
11
10
|
import { distinct } from '../../../utils/array/index.js';
|
|
12
11
|
import { compareByValueSelectionToOrder } from '../../../utils/comparison.js';
|
|
13
12
|
import { groupToMap, groupToSingleMap } from '../../../utils/iterable-helpers/index.js';
|
|
14
13
|
import { fromEntries, objectEntries } from '../../../utils/object/index.js';
|
|
15
|
-
import { assertDefinedPass, isNotNull, isNotNullOrUndefined, isNull, isUndefined } from '../../../utils/type-guards.js';
|
|
16
|
-
import { DocumentApproval, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentFile, DocumentRequest, DocumentRequestCollectionAssignment, DocumentRequestTemplate, DocumentRequestsTemplate, DocumentType, DocumentValidationExecution, DocumentWorkflowStep } from '../../models/index.js';
|
|
14
|
+
import { assertDefinedPass, isDefined, isNotNull, isNotNullOrUndefined, isNull, isUndefined } from '../../../utils/type-guards.js';
|
|
15
|
+
import { DocumentApproval, DocumentAssignmentScope, DocumentAssignmentTask, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentFile, DocumentRequest, DocumentRequestCollectionAssignment, DocumentRequestTemplate, DocumentRequestsTemplate, DocumentType, DocumentValidationExecution, DocumentWorkflowStep } from '../../models/index.js';
|
|
17
16
|
import { DocumentCategoryTypeService, enumTypeKey } from './document-category-type.service.js';
|
|
18
17
|
import { DocumentManagementAncillaryService } from './document-management-ancillary.service.js';
|
|
19
18
|
import { DocumentPropertyService } from './document-property.service.js';
|
|
@@ -30,6 +29,8 @@ let DocumentManagementService = class DocumentManagementService extends Transact
|
|
|
30
29
|
#documentService = inject(DocumentService);
|
|
31
30
|
#documentPropertyService = inject(DocumentPropertyService);
|
|
32
31
|
#documentRequestCollectionAssignmentRepository = injectRepository(DocumentRequestCollectionAssignment);
|
|
32
|
+
#documentAssignmentTaskRepository = injectRepository(DocumentAssignmentTask);
|
|
33
|
+
#documentAssignmentScopeRepository = injectRepository(DocumentAssignmentScope);
|
|
33
34
|
#documentRequestRepository = injectRepository(DocumentRequest);
|
|
34
35
|
#documentRequestsTemplateRepository = injectRepository(DocumentRequestsTemplate);
|
|
35
36
|
#documentRequestTemplateRepository = injectRepository(DocumentRequestTemplate);
|
|
@@ -38,19 +39,25 @@ let DocumentManagementService = class DocumentManagementService extends Transact
|
|
|
38
39
|
#documentValidationExecutionRepository = injectRepository(DocumentValidationExecution);
|
|
39
40
|
async loadData(collectionIds) {
|
|
40
41
|
return await this.transaction(async (tx) => {
|
|
41
|
-
const [collections, collectionsMetadataMap,
|
|
42
|
+
const [collections, collectionsMetadataMap, documentCollectionAssignments, requestAssignments, assignmentScopes, categories, types] = await Promise.all([
|
|
42
43
|
this.#documentCollectionRepository.withTransaction(tx).loadMany(collectionIds),
|
|
43
44
|
this.#ancillaryService.resolveMetadataMap(...collectionIds),
|
|
44
45
|
this.#documentCollectionAssignmentRepository.withTransaction(tx).loadManyByQuery({ collectionId: { $in: collectionIds } }),
|
|
45
46
|
this.#documentRequestCollectionAssignmentRepository.withTransaction(tx).loadManyByQuery({ collectionId: { $in: collectionIds } }),
|
|
47
|
+
this.#documentAssignmentScopeRepository.withTransaction(tx).loadManyByQuery({ collectionId: { $in: collectionIds } }),
|
|
46
48
|
this.#documentCategoryRepository.withTransaction(tx).loadManyByQuery({}, { order: 'label' }),
|
|
47
49
|
this.#documentTypeRepository.withTransaction(tx).loadManyByQuery({}, { order: 'label' }),
|
|
48
50
|
]);
|
|
49
51
|
const requestIds = requestAssignments.map((requestCollection) => requestCollection.requestId);
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
+
const taskIds = assignmentScopes.map((scope) => scope.taskId);
|
|
53
|
+
const [requests, assignmentTasks] = await Promise.all([
|
|
54
|
+
this.#documentRequestRepository.withTransaction(tx).loadManyByQuery({ id: { $in: requestIds } }, { order: { 'metadata.createTimestamp': 'desc' } }),
|
|
55
|
+
this.#documentAssignmentTaskRepository.withTransaction(tx).loadMany(taskIds),
|
|
56
|
+
]);
|
|
57
|
+
const assignmentDocumentIds = documentCollectionAssignments.map((assignment) => assignment.documentId);
|
|
52
58
|
const requestDocumentIds = requests.map((request) => request.documentId).filter(isNotNull);
|
|
53
|
-
const
|
|
59
|
+
const assignmentTaskDocumentIds = assignmentTasks.map((task) => task.documentId);
|
|
60
|
+
const documentIds = distinct([...assignmentDocumentIds, ...requestDocumentIds, ...assignmentTaskDocumentIds]);
|
|
54
61
|
const [documents, propertyValues] = await Promise.all([
|
|
55
62
|
this.#documentService.withTransaction(tx).repository.loadManyByQuery({ id: { $in: documentIds } }, { order: { 'metadata.createTimestamp': 'desc' } }),
|
|
56
63
|
this.#documentPropertyService.withTransaction(tx).loadDocumentProperties(documentIds),
|
|
@@ -61,7 +68,6 @@ let DocumentManagementService = class DocumentManagementService extends Transact
|
|
|
61
68
|
this.#documentFileRepository.withTransaction(tx).loadManyByQuery({ id: { $in: documentFileIds } }, { order: { 'metadata.createTimestamp': 'desc' } }),
|
|
62
69
|
this.#documentWorkflowService.loadLatestWorkflows(workflowRelevantDocumentIds),
|
|
63
70
|
]);
|
|
64
|
-
const documentIdMap = getEntityMap(documents);
|
|
65
71
|
const documentWorkflowMap = groupToSingleMap(currentWorkflows, (workflow) => workflow.documentId);
|
|
66
72
|
const valuesMap = Enumerable.from(propertyValues).groupToMap((value) => value.documentId);
|
|
67
73
|
const validationWorkflowIds = currentWorkflows.map((workflow) => (workflow.step == DocumentWorkflowStep.Validation) ? workflow.id : null).filter(isNotNull);
|
|
@@ -78,9 +84,16 @@ let DocumentManagementService = class DocumentManagementService extends Transact
|
|
|
78
84
|
const documentViews = documents.map((document) => {
|
|
79
85
|
const currentWorkflow = documentWorkflowMap.get(document.id) ?? null;
|
|
80
86
|
const validations = (isNotNull(currentWorkflow) && (currentWorkflow.step == DocumentWorkflowStep.Validation)) ? workflowValidationMap.get(currentWorkflow.id) ?? [] : null;
|
|
87
|
+
const assignmentTask = assignmentTasks.find((task) => task.documentId == document.id);
|
|
88
|
+
const assignmentTaskScope = isDefined(assignmentTask) ? assignmentScopes.filter((scope) => scope.taskId == assignmentTask.id).map((scope) => scope.collectionId) : [];
|
|
81
89
|
return {
|
|
82
90
|
...document,
|
|
83
|
-
|
|
91
|
+
assignment: {
|
|
92
|
+
collections: documentCollectionAssignments.filter((collectionDocument) => collectionDocument.documentId == document.id),
|
|
93
|
+
assignmentTask: isDefined(assignmentTask)
|
|
94
|
+
? { target: assignmentTask.target, scope: assignmentTaskScope }
|
|
95
|
+
: null,
|
|
96
|
+
},
|
|
84
97
|
properties: valuesMap.get(document.id) ?? [],
|
|
85
98
|
currentWorkflow,
|
|
86
99
|
validations,
|
|
@@ -88,8 +101,7 @@ let DocumentManagementService = class DocumentManagementService extends Transact
|
|
|
88
101
|
});
|
|
89
102
|
const requestViews = requests.map((request) => ({
|
|
90
103
|
...request,
|
|
91
|
-
collectionIds: requestAssignments.filter((requestCollection) => requestCollection.requestId == request.id).map((requestCollection) => requestCollection.collectionId)
|
|
92
|
-
document: isNull(request.documentId) ? null : documentIdMap.get(request.documentId) ?? null,
|
|
104
|
+
collectionIds: requestAssignments.filter((requestCollection) => requestCollection.requestId == request.id).map((requestCollection) => requestCollection.collectionId)
|
|
93
105
|
}));
|
|
94
106
|
return {
|
|
95
107
|
collections: collectionViews,
|
|
@@ -4,6 +4,7 @@ import { afterResolve } from '../../../injector/interfaces.js';
|
|
|
4
4
|
import { Transactional } from '../../../orm/server/transactional.js';
|
|
5
5
|
export declare class DocumentWorkflowService extends Transactional {
|
|
6
6
|
#private;
|
|
7
|
+
private readonly documentService;
|
|
7
8
|
readonly repository: import("../../../orm/server/repository.js").EntityRepository<DocumentWorkflow>;
|
|
8
9
|
[afterResolve](_: unknown, { cancellationSignal }: AfterResolveContext<any>): void;
|
|
9
10
|
loadLatestWorkflow(documentId: string): Promise<DocumentWorkflow>;
|
|
@@ -21,6 +21,8 @@ import { Transactional } from '../../../orm/server/transactional.js';
|
|
|
21
21
|
import { Queue } from '../../../queue/queue.js';
|
|
22
22
|
import { _throw } from '../../../utils/throw.js';
|
|
23
23
|
import { isNotNull, isNull } from '../../../utils/type-guards.js';
|
|
24
|
+
import { desc, inArray } from 'drizzle-orm';
|
|
25
|
+
import { documentWorkflow } from '../schemas.js';
|
|
24
26
|
import { DocumentCollectionService } from './document-collection.service.js';
|
|
25
27
|
import { DocumentManagementAiService } from './document-management-ai.service.js';
|
|
26
28
|
import { DocumentRequestService } from './document-request.service.js';
|
|
@@ -28,13 +30,13 @@ import { DocumentService } from './document.service.js';
|
|
|
28
30
|
import { DocumentManagementSingleton } from './singleton.js';
|
|
29
31
|
let DocumentWorkflowService = DocumentWorkflowService_1 = class DocumentWorkflowService extends Transactional {
|
|
30
32
|
#documentManagementAiService = inject(DocumentManagementAiService);
|
|
31
|
-
#documentService = inject(DocumentService);
|
|
32
33
|
#documentCollectionService = inject(DocumentCollectionService);
|
|
33
34
|
#documentRequestService = inject(DocumentRequestService);
|
|
34
35
|
#documentAssignmentTaskRepository = injectRepository(DocumentAssignmentTask);
|
|
35
36
|
#documentAssignmentScopeRepository = injectRepository(DocumentAssignmentScope);
|
|
36
37
|
#queue = inject((Queue), { name: 'DocumentWorkflow', processTimeout: 5 * 60 * 1000, maxTries: 3 });
|
|
37
38
|
#logger = inject(Logger, DocumentWorkflowService_1.name);
|
|
39
|
+
documentService = inject(DocumentService, undefined, { forwardRef: true });
|
|
38
40
|
repository = injectRepository(DocumentWorkflow).withSession(this.session);
|
|
39
41
|
[afterResolve](_, { cancellationSignal }) {
|
|
40
42
|
if (this.isInTransaction) {
|
|
@@ -49,7 +51,16 @@ let DocumentWorkflowService = DocumentWorkflowService_1 = class DocumentWorkflow
|
|
|
49
51
|
return await this.repository.tryLoadByQuery({ documentId }, { order: { 'metadata.createTimestamp': 'desc' } });
|
|
50
52
|
}
|
|
51
53
|
async loadLatestWorkflows(documentIds) {
|
|
52
|
-
|
|
54
|
+
const orderedDocumentWorkflows = this.repository.session.$with('orderedDocumentWorkflows').as((qb) => qb
|
|
55
|
+
.select()
|
|
56
|
+
.from(documentWorkflow)
|
|
57
|
+
.where(inArray(documentWorkflow.documentId, documentIds))
|
|
58
|
+
.orderBy(desc(documentWorkflow.createTimestamp)));
|
|
59
|
+
const latestWorkflows = await this.repository.session
|
|
60
|
+
.with(orderedDocumentWorkflows)
|
|
61
|
+
.selectDistinctOn([orderedDocumentWorkflows.documentId])
|
|
62
|
+
.from(orderedDocumentWorkflows);
|
|
63
|
+
return await this.repository.mapManyToEntity(latestWorkflows);
|
|
53
64
|
}
|
|
54
65
|
async proceedWorkflow(documentId, userId) {
|
|
55
66
|
await this.transaction(async (tx) => {
|
|
@@ -104,11 +115,11 @@ let DocumentWorkflowService = DocumentWorkflowService_1 = class DocumentWorkflow
|
|
|
104
115
|
}
|
|
105
116
|
async processClassificationWorkflow(workflow) {
|
|
106
117
|
const typeId = await this.#documentManagementAiService.classifyDocumentType(workflow.documentId);
|
|
107
|
-
await this
|
|
118
|
+
await this.documentService.repository.update(workflow.documentId, { typeId, approval: DocumentApproval.Pending });
|
|
108
119
|
}
|
|
109
120
|
async processExtractionWorkflow(workflow) {
|
|
110
121
|
const extraction = await this.#documentManagementAiService.extractDocumentInformation(workflow.documentId);
|
|
111
|
-
await this
|
|
122
|
+
await this.documentService.update(workflow.documentId, extraction);
|
|
112
123
|
}
|
|
113
124
|
async processAssignmentWorkflow(workflow) {
|
|
114
125
|
const assignmentTask = await this.#documentAssignmentTaskRepository.loadByQuery({ documentId: workflow.documentId });
|
|
@@ -29,7 +29,7 @@ import { DocumentManagementSingleton } from './singleton.js';
|
|
|
29
29
|
let DocumentService = DocumentService_1 = class DocumentService extends Transactional {
|
|
30
30
|
#documentFileService = inject(DocumentFileService);
|
|
31
31
|
#requestService = inject(DocumentRequestService);
|
|
32
|
-
#workflowService = inject(DocumentWorkflowService
|
|
32
|
+
#workflowService = inject(DocumentWorkflowService);
|
|
33
33
|
#documentPropertyService = inject(DocumentPropertyService);
|
|
34
34
|
#documentCollectionService = inject(DocumentCollectionService);
|
|
35
35
|
#documentAssignmentTaskRepository = injectRepository(DocumentAssignmentTask);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { TypedOmit } from '../../types.js';
|
|
2
|
+
import { Document, DocumentAssignmentTarget, DocumentAssignmentTask, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentFile, DocumentPropertyDataType, DocumentRequest, DocumentType, DocumentValidationExecution, DocumentWorkflow } from '../models/index.js';
|
|
2
3
|
export declare class DocumentCollectionView extends DocumentCollection {
|
|
3
4
|
name: string;
|
|
4
5
|
group: string | null;
|
|
@@ -10,8 +11,20 @@ export declare class DocumentPropertyValueView {
|
|
|
10
11
|
dataType: DocumentPropertyDataType;
|
|
11
12
|
value: string | number | boolean | null;
|
|
12
13
|
}
|
|
14
|
+
export declare class DocumentCollectionAssignmentView implements TypedOmit<DocumentCollectionAssignment, 'id' | 'documentId' | 'metadata'> {
|
|
15
|
+
collectionId: string;
|
|
16
|
+
archiveTimestamp: number | null;
|
|
17
|
+
}
|
|
18
|
+
export declare class DocumentAssignmentTaskView implements TypedOmit<DocumentAssignmentTask, 'id' | 'documentId' | 'metadata'> {
|
|
19
|
+
target: DocumentAssignmentTarget;
|
|
20
|
+
scope: string[];
|
|
21
|
+
}
|
|
22
|
+
export declare class DocumentAssignmentView {
|
|
23
|
+
collections: DocumentCollectionAssignmentView[];
|
|
24
|
+
assignmentTask: DocumentAssignmentTaskView | null;
|
|
25
|
+
}
|
|
13
26
|
export declare class DocumentView extends Document {
|
|
14
|
-
|
|
27
|
+
assignment: DocumentAssignmentView;
|
|
15
28
|
properties: DocumentPropertyValueView[];
|
|
16
29
|
/** available as long as the document is neither approved nor rejected */
|
|
17
30
|
currentWorkflow: DocumentWorkflow | null;
|
|
@@ -19,8 +32,6 @@ export declare class DocumentView extends Document {
|
|
|
19
32
|
}
|
|
20
33
|
export declare class DocumentRequestView extends DocumentRequest {
|
|
21
34
|
collectionIds: string[];
|
|
22
|
-
/** current approval-pending or approved document */
|
|
23
|
-
document: Document | null;
|
|
24
35
|
}
|
|
25
36
|
export declare class DocumentManagementData {
|
|
26
37
|
collections: DocumentCollectionView[];
|
|
@@ -7,8 +7,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
9
|
};
|
|
10
|
-
import { Array, Enumeration, Property, StringProperty, Union } from '../../schema/index.js';
|
|
11
|
-
import { Document, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentFile, DocumentPropertyDataType, DocumentRequest, DocumentType, DocumentValidationExecution, DocumentWorkflow } from '../models/index.js';
|
|
10
|
+
import { Array, Enumeration, Property, string, StringProperty, Union } from '../../schema/index.js';
|
|
11
|
+
import { Document, DocumentAssignmentTarget, DocumentAssignmentTask, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentFile, DocumentPropertyDataType, DocumentRequest, DocumentType, DocumentValidationExecution, DocumentWorkflow } from '../models/index.js';
|
|
12
12
|
export class DocumentCollectionView extends DocumentCollection {
|
|
13
13
|
name;
|
|
14
14
|
group;
|
|
@@ -48,17 +48,53 @@ __decorate([
|
|
|
48
48
|
Union(String, Number, Boolean, { nullable: true }),
|
|
49
49
|
__metadata("design:type", Object)
|
|
50
50
|
], DocumentPropertyValueView.prototype, "value", void 0);
|
|
51
|
+
export class DocumentCollectionAssignmentView {
|
|
52
|
+
collectionId;
|
|
53
|
+
archiveTimestamp;
|
|
54
|
+
}
|
|
55
|
+
__decorate([
|
|
56
|
+
StringProperty(),
|
|
57
|
+
__metadata("design:type", String)
|
|
58
|
+
], DocumentCollectionAssignmentView.prototype, "collectionId", void 0);
|
|
59
|
+
__decorate([
|
|
60
|
+
StringProperty({ nullable: true }),
|
|
61
|
+
__metadata("design:type", Object)
|
|
62
|
+
], DocumentCollectionAssignmentView.prototype, "archiveTimestamp", void 0);
|
|
63
|
+
export class DocumentAssignmentTaskView {
|
|
64
|
+
target;
|
|
65
|
+
scope;
|
|
66
|
+
}
|
|
67
|
+
__decorate([
|
|
68
|
+
Enumeration(DocumentAssignmentTarget),
|
|
69
|
+
__metadata("design:type", String)
|
|
70
|
+
], DocumentAssignmentTaskView.prototype, "target", void 0);
|
|
71
|
+
__decorate([
|
|
72
|
+
Array(string()),
|
|
73
|
+
__metadata("design:type", Array)
|
|
74
|
+
], DocumentAssignmentTaskView.prototype, "scope", void 0);
|
|
75
|
+
export class DocumentAssignmentView {
|
|
76
|
+
collections;
|
|
77
|
+
assignmentTask;
|
|
78
|
+
}
|
|
79
|
+
__decorate([
|
|
80
|
+
Array(DocumentCollectionAssignmentView),
|
|
81
|
+
__metadata("design:type", Array)
|
|
82
|
+
], DocumentAssignmentView.prototype, "collections", void 0);
|
|
83
|
+
__decorate([
|
|
84
|
+
Property(DocumentAssignmentTaskView, { nullable: true }),
|
|
85
|
+
__metadata("design:type", Object)
|
|
86
|
+
], DocumentAssignmentView.prototype, "assignmentTask", void 0);
|
|
51
87
|
export class DocumentView extends Document {
|
|
52
|
-
|
|
88
|
+
assignment;
|
|
53
89
|
properties;
|
|
54
90
|
/** available as long as the document is neither approved nor rejected */
|
|
55
91
|
currentWorkflow;
|
|
56
92
|
validations;
|
|
57
93
|
}
|
|
58
94
|
__decorate([
|
|
59
|
-
|
|
60
|
-
__metadata("design:type",
|
|
61
|
-
], DocumentView.prototype, "
|
|
95
|
+
Property(DocumentAssignmentView),
|
|
96
|
+
__metadata("design:type", DocumentAssignmentView)
|
|
97
|
+
], DocumentView.prototype, "assignment", void 0);
|
|
62
98
|
__decorate([
|
|
63
99
|
Array(DocumentPropertyValueView),
|
|
64
100
|
__metadata("design:type", Array)
|
|
@@ -73,17 +109,11 @@ __decorate([
|
|
|
73
109
|
], DocumentView.prototype, "validations", void 0);
|
|
74
110
|
export class DocumentRequestView extends DocumentRequest {
|
|
75
111
|
collectionIds;
|
|
76
|
-
/** current approval-pending or approved document */
|
|
77
|
-
document;
|
|
78
112
|
}
|
|
79
113
|
__decorate([
|
|
80
114
|
Array(String),
|
|
81
115
|
__metadata("design:type", Array)
|
|
82
116
|
], DocumentRequestView.prototype, "collectionIds", void 0);
|
|
83
|
-
__decorate([
|
|
84
|
-
Property(Document, { nullable: true }),
|
|
85
|
-
__metadata("design:type", Object)
|
|
86
|
-
], DocumentRequestView.prototype, "document", void 0);
|
|
87
117
|
export class DocumentManagementData {
|
|
88
118
|
collections;
|
|
89
119
|
documents;
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import type { TypedOmit } from '../../../types.js';
|
|
2
2
|
import type { DocumentCollectionAssignment } from '../../models/index.js';
|
|
3
|
+
import type { DocumentAssignmentTaskView, DocumentAssignmentView, DocumentCollectionAssignmentView } from '../document-management.view-model.js';
|
|
3
4
|
import type { EnrichedDocumentCollection } from './enriched-document-collection.view.js';
|
|
5
|
+
import type { EnrichedDocumentManagementData } from './enriched-document-management-data.view.js';
|
|
4
6
|
import type { EnrichedDocument } from './enriched-document.view.js';
|
|
5
|
-
export declare class
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
export declare class EnrichedDocumentCollectionAssignment implements TypedOmit<DocumentCollectionAssignment, 'id' | 'collectionId' | 'documentId' | 'metadata'> {
|
|
8
|
+
#private;
|
|
9
|
+
get collection(): EnrichedDocumentCollection;
|
|
8
10
|
readonly document: EnrichedDocument;
|
|
9
11
|
readonly archiveTimestamp: number | null;
|
|
10
|
-
constructor(
|
|
12
|
+
constructor(data: EnrichedDocumentManagementData, assignment: DocumentCollectionAssignmentView, document: EnrichedDocument);
|
|
13
|
+
}
|
|
14
|
+
export declare class EnrichedDocumentAssignment implements TypedOmit<DocumentAssignmentView, 'collections' | 'assignmentTask'> {
|
|
15
|
+
#private;
|
|
16
|
+
get collections(): EnrichedDocumentCollectionAssignment[];
|
|
17
|
+
get document(): EnrichedDocument;
|
|
18
|
+
readonly assignmentTask: DocumentAssignmentTaskView | null;
|
|
19
|
+
constructor(data: EnrichedDocumentManagementData, document: EnrichedDocument, assignment: DocumentAssignmentView);
|
|
11
20
|
}
|
|
@@ -1,12 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { assertDefinedPass } from '../../../utils/type-guards.js';
|
|
2
|
+
export class EnrichedDocumentCollectionAssignment {
|
|
3
|
+
#data;
|
|
4
|
+
#assignment;
|
|
5
|
+
get collection() {
|
|
6
|
+
return assertDefinedPass(this.#data.maps.collections.get(this.#assignment.collectionId));
|
|
7
|
+
}
|
|
4
8
|
document;
|
|
5
9
|
archiveTimestamp;
|
|
6
|
-
constructor(
|
|
7
|
-
this
|
|
8
|
-
this
|
|
10
|
+
constructor(data, assignment, document) {
|
|
11
|
+
this.#data = data;
|
|
12
|
+
this.#assignment = assignment;
|
|
9
13
|
this.document = document;
|
|
10
|
-
this.archiveTimestamp = archiveTimestamp;
|
|
14
|
+
this.archiveTimestamp = assignment.archiveTimestamp;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class EnrichedDocumentAssignment {
|
|
18
|
+
#data;
|
|
19
|
+
#collections;
|
|
20
|
+
#document;
|
|
21
|
+
get collections() {
|
|
22
|
+
return this.#collections;
|
|
23
|
+
}
|
|
24
|
+
get document() {
|
|
25
|
+
return this.#document;
|
|
26
|
+
}
|
|
27
|
+
assignmentTask;
|
|
28
|
+
constructor(data, document, assignment) {
|
|
29
|
+
this.#data = data;
|
|
30
|
+
this.#document = document;
|
|
31
|
+
this.#collections = assignment.collections.map((assignment) => new EnrichedDocumentCollectionAssignment(data, assignment, document));
|
|
32
|
+
this.assignmentTask = assignment.assignmentTask;
|
|
11
33
|
}
|
|
12
34
|
}
|
|
@@ -22,7 +22,7 @@ export class EnrichedDocumentCollection {
|
|
|
22
22
|
return this.children.flatMap((child) => [child, ...child.childrenDeep]);
|
|
23
23
|
}
|
|
24
24
|
get documents() {
|
|
25
|
-
return this.#data.documents.filter((document) => document.assignments.some((assignment) => assignment.collection.id == this.id));
|
|
25
|
+
return this.#data.documents.filter((document) => document.assignments.collections.some((assignment) => assignment.collection.id == this.id));
|
|
26
26
|
}
|
|
27
27
|
get documentsDeep() {
|
|
28
28
|
return [...this.documents, ...this.children.flatMap((child) => child.documentsDeep)];
|
|
@@ -5,7 +5,7 @@ import type { EnrichedDocumentCollection } from './enriched-document-collection.
|
|
|
5
5
|
import type { EnrichedDocumentManagementData } from './enriched-document-management-data.view.js';
|
|
6
6
|
import type { EnrichedDocumentType } from './enriched-document-type.view.js';
|
|
7
7
|
import type { EnrichedDocument } from './enriched-document.view.js';
|
|
8
|
-
export declare class EnrichedDocumentRequest implements TypedOmit<DocumentRequestView, 'typeId' | 'documentId' | '
|
|
8
|
+
export declare class EnrichedDocumentRequest implements TypedOmit<DocumentRequestView, 'typeId' | 'documentId' | 'collectionIds' | 'metadata'> {
|
|
9
9
|
#private;
|
|
10
10
|
readonly id: string;
|
|
11
11
|
readonly comment: string | null;
|
|
@@ -5,7 +5,7 @@ import { EnrichedDocumentAssignment } from './enriched-document-assignment.view.
|
|
|
5
5
|
import { EnrichedDocumentFile } from './enriched-document-file.view.js';
|
|
6
6
|
import type { EnrichedDocumentManagementData } from './enriched-document-management-data.view.js';
|
|
7
7
|
import type { EnrichedDocumentType } from './enriched-document-type.view.js';
|
|
8
|
-
export declare class EnrichedDocument implements TypedOmit<DocumentView, 'typeId' | 'fileId' | '
|
|
8
|
+
export declare class EnrichedDocument implements TypedOmit<DocumentView, 'typeId' | 'fileId' | 'assignment' | 'createUserId' | 'metadata'> {
|
|
9
9
|
#private;
|
|
10
10
|
readonly id: string;
|
|
11
11
|
readonly title: string | null;
|
|
@@ -21,6 +21,6 @@ export declare class EnrichedDocument implements TypedOmit<DocumentView, 'typeId
|
|
|
21
21
|
readonly validations: DocumentValidationExecution[] | null;
|
|
22
22
|
get type(): EnrichedDocumentType | null;
|
|
23
23
|
get file(): EnrichedDocumentFile;
|
|
24
|
-
get assignments(): EnrichedDocumentAssignment
|
|
24
|
+
get assignments(): EnrichedDocumentAssignment;
|
|
25
25
|
constructor(data: EnrichedDocumentManagementData, document: DocumentView);
|
|
26
26
|
}
|
|
@@ -37,11 +37,7 @@ export class EnrichedDocument {
|
|
|
37
37
|
return new EnrichedDocumentFile(file, this);
|
|
38
38
|
}
|
|
39
39
|
get assignments() {
|
|
40
|
-
return this.#documentView.
|
|
41
|
-
.map((assignment) => {
|
|
42
|
-
const collection = assertDefinedPass(this.#data.collections.find((collection) => collection.id == assignment.collectionId));
|
|
43
|
-
return new EnrichedDocumentAssignment(assignment.id, collection, assertDefinedPass(this.#data.documents.find((document) => document.id == this.#documentView.id)), assignment.archiveTimestamp);
|
|
44
|
-
});
|
|
40
|
+
return new EnrichedDocumentAssignment(this.#data, this, this.#documentView.assignment);
|
|
45
41
|
}
|
|
46
42
|
constructor(data, document) {
|
|
47
43
|
this.#data = data;
|
|
@@ -72,6 +68,6 @@ __decorate([
|
|
|
72
68
|
], EnrichedDocument.prototype, "file", null);
|
|
73
69
|
__decorate([
|
|
74
70
|
Memoize(),
|
|
75
|
-
__metadata("design:type",
|
|
71
|
+
__metadata("design:type", EnrichedDocumentAssignment),
|
|
76
72
|
__metadata("design:paramtypes", [])
|
|
77
73
|
], EnrichedDocument.prototype, "assignments", null);
|
|
@@ -22,6 +22,7 @@ import { configureOrm } from '../../orm/server/index.js';
|
|
|
22
22
|
import { configurePostgresQueue, migratePostgresQueueSchema } from '../../queue/postgres/index.js';
|
|
23
23
|
import { boolean, positiveInteger, string } from '../../utils/config-parser.js';
|
|
24
24
|
import { TstdlCategoryParents, TstdlDocumentCategoryLabels, TstdlDocumentTypeCategories, TstdlDocumentTypeLabels } from './categories-and-types.js';
|
|
25
|
+
import { configureTstdl } from '../../core.js';
|
|
25
26
|
const config = {
|
|
26
27
|
database: {
|
|
27
28
|
host: string('DATABASE_HOST', '127.0.0.1'),
|
|
@@ -47,11 +48,12 @@ const config = {
|
|
|
47
48
|
bucketPerModule: boolean('S3_BUCKET_PER_MODULE', true),
|
|
48
49
|
},
|
|
49
50
|
};
|
|
51
|
+
const userId = crypto.randomUUID();
|
|
50
52
|
let ExampleDocumentManagementAncillaryService = class ExampleDocumentManagementAncillaryService extends DocumentManagementAncillaryService {
|
|
51
53
|
_resolveMetadata(collections) {
|
|
52
54
|
return collections.map((collection) => ({ name: collection.id.split('-')[0], group: null }));
|
|
53
55
|
}
|
|
54
|
-
getSubject(_token) { return
|
|
56
|
+
getSubject(_token) { return userId; }
|
|
55
57
|
canCreateDocuments(_collectionId, _token) { return true; }
|
|
56
58
|
canUpdateDocuments(_collectionId, _token) { return true; }
|
|
57
59
|
canDeleteDocuments(_collectionId, _token) { return true; }
|
|
@@ -72,6 +74,7 @@ ExampleDocumentManagementAncillaryService = __decorate([
|
|
|
72
74
|
export { ExampleDocumentManagementAncillaryService };
|
|
73
75
|
async function bootstrap() {
|
|
74
76
|
const injector = inject(Injector);
|
|
77
|
+
configureTstdl();
|
|
75
78
|
configureNodeHttpServer();
|
|
76
79
|
configurePostgresQueue();
|
|
77
80
|
configureLocalMessageBus();
|
|
@@ -2,6 +2,7 @@ import { resolveArgumentType, type Resolvable } from '../injector/interfaces.js'
|
|
|
2
2
|
import type { ObjectMetadata, ObjectStorageObject } from './object.js';
|
|
3
3
|
export type UploadObjectOptions = {
|
|
4
4
|
contentLength?: number;
|
|
5
|
+
contentType?: string;
|
|
5
6
|
metadata?: ObjectMetadata;
|
|
6
7
|
};
|
|
7
8
|
export type UploadUrlOptions = {
|
|
@@ -13,7 +13,7 @@ export declare class S3ObjectStorage extends ObjectStorage {
|
|
|
13
13
|
exists(key: string): Promise<boolean>;
|
|
14
14
|
statObject(key: string): Promise<BucketItemStat>;
|
|
15
15
|
uploadObject(key: string, content: Uint8Array | ReadableStream<Uint8Array>, options?: UploadObjectOptions): Promise<void>;
|
|
16
|
-
copyObject(
|
|
16
|
+
copyObject(source: string, destination: string | [ObjectStorage, string], options?: CopyObjectOptions): Promise<void>;
|
|
17
17
|
moveObject(sourceKey: string, destinationKey: string | [ObjectStorage, string], options?: MoveObjectOptions): Promise<void>;
|
|
18
18
|
getContent(key: string): Promise<Uint8Array>;
|
|
19
19
|
getContentStream(key: string): ReadableStream<Uint8Array>;
|
|
@@ -120,11 +120,12 @@ let S3ObjectStorage = S3ObjectStorage_1 = class S3ObjectStorage extends ObjectSt
|
|
|
120
120
|
]);
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
|
-
async copyObject(
|
|
124
|
-
const sourceBucketKey = this.getBucketKey(
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
const
|
|
123
|
+
async copyObject(source, destination, options) {
|
|
124
|
+
const sourceBucketKey = this.getBucketKey(source);
|
|
125
|
+
const [destinationObjectStorage, destinationKey] = isString(destination) ? [this, destination] : [assertInstanceOfPass(destination[0], S3ObjectStorage_1, 'Destination storage is not an S3ObjectStorage'), destination[1]];
|
|
126
|
+
const destinationBucket = destinationObjectStorage.bucket;
|
|
127
|
+
const destinationBucketKey = destinationObjectStorage.getBucketKey(destinationKey);
|
|
128
|
+
const sourceObject = await this.getObject(source);
|
|
128
129
|
const sourceMetadata = await sourceObject.getMetadata();
|
|
129
130
|
await this.client.copyObject(new CopySourceOptions({ Bucket: this.bucket, Object: sourceBucketKey }), new CopyDestinationOptions({
|
|
130
131
|
Bucket: destinationBucket,
|
|
@@ -202,6 +203,7 @@ S3ObjectStorage = S3ObjectStorage_1 = __decorate([
|
|
|
202
203
|
return context.resolve(S3ObjectStorageProvider).get(module);
|
|
203
204
|
},
|
|
204
205
|
},
|
|
206
|
+
argumentIdentityProvider: JSON.stringify,
|
|
205
207
|
}),
|
|
206
208
|
__metadata("design:paramtypes", [Function, String, String, String])
|
|
207
209
|
], S3ObjectStorage);
|
package/orm/server/repository.js
CHANGED
|
@@ -84,7 +84,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
84
84
|
* @returns A promise that resolves to the loaded entity or `undefined` if not found.
|
|
85
85
|
*/
|
|
86
86
|
async tryLoad(id) {
|
|
87
|
-
return this.tryLoadByQuery(eq(this.#table.id, id));
|
|
87
|
+
return await this.tryLoadByQuery(eq(this.#table.id, id));
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
90
90
|
* Loads a single entity based on a query.
|
|
@@ -122,7 +122,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
122
122
|
if (isUndefined(row)) {
|
|
123
123
|
return undefined;
|
|
124
124
|
}
|
|
125
|
-
return this.mapToEntity(row);
|
|
125
|
+
return await this.mapToEntity(row);
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
128
|
* Loads multiple entities by their IDs.
|
|
@@ -131,7 +131,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
131
131
|
* @returns A promise that resolves to an array of loaded entities.
|
|
132
132
|
*/
|
|
133
133
|
async loadMany(ids, options) {
|
|
134
|
-
return this.loadManyByQuery(inArray(this.#table.id, ids), options);
|
|
134
|
+
return await this.loadManyByQuery(inArray(this.#table.id, ids), options);
|
|
135
135
|
}
|
|
136
136
|
/**
|
|
137
137
|
* Loads multiple entities by their IDs and returns them as an async iterable cursor.
|
|
@@ -168,7 +168,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
168
168
|
dbQuery = dbQuery.orderBy(...this.convertOrderBy(options.order));
|
|
169
169
|
}
|
|
170
170
|
const rows = await dbQuery;
|
|
171
|
-
return this.mapManyToEntity(rows);
|
|
171
|
+
return await this.mapManyToEntity(rows);
|
|
172
172
|
}
|
|
173
173
|
/**
|
|
174
174
|
* Loads multiple entities based on a query and returns them as an async iterable cursor.
|
|
@@ -186,7 +186,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
186
186
|
* @returns A promise that resolves to an array of all entities.
|
|
187
187
|
*/
|
|
188
188
|
async loadAll(options) {
|
|
189
|
-
return this.loadManyByQuery({}, options);
|
|
189
|
+
return await this.loadManyByQuery({}, options);
|
|
190
190
|
}
|
|
191
191
|
/**
|
|
192
192
|
* Loads all entities of the repository's type and returns them as an async iterable cursor.
|
|
@@ -230,7 +230,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
230
230
|
* @returns A promise that resolves to `true` if the entity exists, `false` otherwise.
|
|
231
231
|
*/
|
|
232
232
|
async has(id) {
|
|
233
|
-
return this.hasByQuery(eq(this.#table.id, id));
|
|
233
|
+
return await this.hasByQuery(eq(this.#table.id, id));
|
|
234
234
|
}
|
|
235
235
|
/**
|
|
236
236
|
* Checks if any entity matches the given query.
|
|
@@ -273,7 +273,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
273
273
|
if (isUndefined(row)) {
|
|
274
274
|
return undefined;
|
|
275
275
|
}
|
|
276
|
-
return this.mapToEntity(row);
|
|
276
|
+
return await this.mapToEntity(row);
|
|
277
277
|
}
|
|
278
278
|
/**
|
|
279
279
|
* Inserts a new entity into the database.
|
|
@@ -286,7 +286,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
286
286
|
.insert(this.#table)
|
|
287
287
|
.values(columns)
|
|
288
288
|
.returning();
|
|
289
|
-
return this.mapToEntity(row);
|
|
289
|
+
return await this.mapToEntity(row);
|
|
290
290
|
}
|
|
291
291
|
/**
|
|
292
292
|
* Inserts multiple new entities into the database.
|
|
@@ -296,7 +296,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
296
296
|
async insertMany(entities) {
|
|
297
297
|
const columns = await this.mapManyToInsertColumns(entities);
|
|
298
298
|
const rows = await this.session.insert(this.#table).values(columns).returning();
|
|
299
|
-
return this.mapManyToEntity(rows);
|
|
299
|
+
return await this.mapManyToEntity(rows);
|
|
300
300
|
}
|
|
301
301
|
/**
|
|
302
302
|
* Inserts an entity or updates it if a conflict occurs based on the target columns.
|
|
@@ -317,7 +317,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
317
317
|
set: mappedUpdate,
|
|
318
318
|
})
|
|
319
319
|
.returning();
|
|
320
|
-
return this.mapToEntity(row);
|
|
320
|
+
return await this.mapToEntity(row);
|
|
321
321
|
}
|
|
322
322
|
/**
|
|
323
323
|
* Inserts multiple entities or updates them if a conflict occurs based on the target columns.
|
|
@@ -343,7 +343,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
343
343
|
set: mappedUpdate,
|
|
344
344
|
})
|
|
345
345
|
.returning();
|
|
346
|
-
return this.mapManyToEntity(rows);
|
|
346
|
+
return await this.mapManyToEntity(rows);
|
|
347
347
|
}
|
|
348
348
|
/**
|
|
349
349
|
* Updates an entity by its ID.
|
|
@@ -378,7 +378,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
378
378
|
if (isUndefined(row)) {
|
|
379
379
|
return undefined;
|
|
380
380
|
}
|
|
381
|
-
return this.mapToEntity(row);
|
|
381
|
+
return await this.mapToEntity(row);
|
|
382
382
|
}
|
|
383
383
|
/**
|
|
384
384
|
* Updates a single entity matching a query.
|
|
@@ -413,7 +413,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
413
413
|
if (isUndefined(row)) {
|
|
414
414
|
return undefined;
|
|
415
415
|
}
|
|
416
|
-
return this.mapToEntity(row);
|
|
416
|
+
return await this.mapToEntity(row);
|
|
417
417
|
}
|
|
418
418
|
/**
|
|
419
419
|
* Updates multiple entities by their IDs.
|
|
@@ -422,7 +422,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
422
422
|
* @returns A promise that resolves to an array of the updated entities.
|
|
423
423
|
*/
|
|
424
424
|
async updateMany(ids, update) {
|
|
425
|
-
return this.updateManyByQuery(inArray(this.#table.id, ids), update);
|
|
425
|
+
return await this.updateManyByQuery(inArray(this.#table.id, ids), update);
|
|
426
426
|
}
|
|
427
427
|
/**
|
|
428
428
|
* Updates multiple entities matching a query.
|
|
@@ -438,7 +438,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
438
438
|
.set(mappedUpdate)
|
|
439
439
|
.where(sqlQuery)
|
|
440
440
|
.returning();
|
|
441
|
-
return this.mapManyToEntity(rows);
|
|
441
|
+
return await this.mapManyToEntity(rows);
|
|
442
442
|
}
|
|
443
443
|
/**
|
|
444
444
|
* Deletes an entity by its ID (soft delete if metadata is available).
|
|
@@ -464,7 +464,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
464
464
|
*/
|
|
465
465
|
async tryDelete(id, metadataUpdate) {
|
|
466
466
|
if (!this.hasMetadata) {
|
|
467
|
-
return this.tryHardDelete(id);
|
|
467
|
+
return await this.tryHardDelete(id);
|
|
468
468
|
}
|
|
469
469
|
const sqlQuery = this.convertQuery(eq(this.#table.id, id));
|
|
470
470
|
const [row] = await this.session
|
|
@@ -478,7 +478,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
478
478
|
if (isUndefined(row)) {
|
|
479
479
|
return undefined;
|
|
480
480
|
}
|
|
481
|
-
return this.mapToEntity(row);
|
|
481
|
+
return await this.mapToEntity(row);
|
|
482
482
|
}
|
|
483
483
|
/**
|
|
484
484
|
* Deletes a single entity matching a query (soft delete if metadata is available).
|
|
@@ -504,7 +504,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
504
504
|
*/
|
|
505
505
|
async tryDeleteByQuery(query, metadataUpdate) {
|
|
506
506
|
if (!this.hasMetadata) {
|
|
507
|
-
return this.tryHardDeleteByQuery(query);
|
|
507
|
+
return await this.tryHardDeleteByQuery(query);
|
|
508
508
|
}
|
|
509
509
|
const idQuery = this.getIdLimitSelect(query);
|
|
510
510
|
const [row] = await this.session
|
|
@@ -518,7 +518,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
518
518
|
if (isUndefined(row)) {
|
|
519
519
|
return undefined;
|
|
520
520
|
}
|
|
521
|
-
return this.mapToEntity(row);
|
|
521
|
+
return await this.mapToEntity(row);
|
|
522
522
|
}
|
|
523
523
|
/**
|
|
524
524
|
* Deletes multiple entities by their IDs (soft delete if metadata is available).
|
|
@@ -527,7 +527,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
527
527
|
* @returns A promise that resolves to an array of the deleted entities.
|
|
528
528
|
*/
|
|
529
529
|
async deleteMany(ids, metadataUpdate) {
|
|
530
|
-
return this.deleteManyByQuery(inArray(this.#table.id, ids), metadataUpdate);
|
|
530
|
+
return await this.deleteManyByQuery(inArray(this.#table.id, ids), metadataUpdate);
|
|
531
531
|
}
|
|
532
532
|
/**
|
|
533
533
|
* Deletes multiple entities matching a query (soft delete if metadata is available).
|
|
@@ -537,7 +537,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
537
537
|
*/
|
|
538
538
|
async deleteManyByQuery(query, metadataUpdate) {
|
|
539
539
|
if (!this.hasMetadata) {
|
|
540
|
-
return this.hardDeleteManyByQuery(query);
|
|
540
|
+
return await this.hardDeleteManyByQuery(query);
|
|
541
541
|
}
|
|
542
542
|
const sqlQuery = this.convertQuery(query);
|
|
543
543
|
const rows = await this.session
|
|
@@ -548,7 +548,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
548
548
|
})
|
|
549
549
|
.where(sqlQuery)
|
|
550
550
|
.returning();
|
|
551
|
-
return this.mapManyToEntity(rows);
|
|
551
|
+
return await this.mapManyToEntity(rows);
|
|
552
552
|
}
|
|
553
553
|
/**
|
|
554
554
|
* Hard deletes an entity by its ID (removes from the database).
|
|
@@ -579,7 +579,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
579
579
|
if (isUndefined(row)) {
|
|
580
580
|
return undefined;
|
|
581
581
|
}
|
|
582
|
-
return this.mapToEntity(row);
|
|
582
|
+
return await this.mapToEntity(row);
|
|
583
583
|
}
|
|
584
584
|
/**
|
|
585
585
|
* Hard deletes a single entity matching a query (removes from the database).
|
|
@@ -610,7 +610,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
610
610
|
if (isUndefined(row)) {
|
|
611
611
|
return undefined;
|
|
612
612
|
}
|
|
613
|
-
return this.mapToEntity(row);
|
|
613
|
+
return await this.mapToEntity(row);
|
|
614
614
|
}
|
|
615
615
|
/**
|
|
616
616
|
* Hard deletes multiple entities by their IDs (removes from the database).
|
|
@@ -618,7 +618,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
618
618
|
* @returns A promise that resolves to an array of the hard deleted entities.
|
|
619
619
|
*/
|
|
620
620
|
async hardDeleteMany(ids) {
|
|
621
|
-
return this.hardDeleteManyByQuery(inArray(this.#table.id, ids));
|
|
621
|
+
return await this.hardDeleteManyByQuery(inArray(this.#table.id, ids));
|
|
622
622
|
}
|
|
623
623
|
/**
|
|
624
624
|
* Hard deletes multiple entities matching a query (removes from the database).
|
|
@@ -631,7 +631,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
631
631
|
.delete(this.#table)
|
|
632
632
|
.where(sqlQuery)
|
|
633
633
|
.returning();
|
|
634
|
-
return this.mapManyToEntity(rows);
|
|
634
|
+
return await this.mapManyToEntity(rows);
|
|
635
635
|
}
|
|
636
636
|
/**
|
|
637
637
|
* Retrieves the Drizzle PgColumn for a given object path or column definition.
|
|
@@ -693,7 +693,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
693
693
|
*/
|
|
694
694
|
async mapManyToEntity(columns) {
|
|
695
695
|
const transformContext = await this.getTransformContext();
|
|
696
|
-
return this._mapManyToEntity(columns, transformContext);
|
|
696
|
+
return await this._mapManyToEntity(columns, transformContext);
|
|
697
697
|
}
|
|
698
698
|
/**
|
|
699
699
|
* Maps a single database row to an entity.
|
|
@@ -702,7 +702,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
702
702
|
*/
|
|
703
703
|
async mapToEntity(columns) {
|
|
704
704
|
const transformContext = await this.getTransformContext();
|
|
705
|
-
return this._mapToEntity(columns, transformContext);
|
|
705
|
+
return await this._mapToEntity(columns, transformContext);
|
|
706
706
|
}
|
|
707
707
|
/**
|
|
708
708
|
* Maps multiple entity-like objects to database column values for insertion or update.
|
|
@@ -711,7 +711,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
711
711
|
*/
|
|
712
712
|
async mapManyToColumns(objects) {
|
|
713
713
|
const transformContext = await this.getTransformContext();
|
|
714
|
-
return this._mapManyToColumns(objects, transformContext);
|
|
714
|
+
return await this._mapManyToColumns(objects, transformContext);
|
|
715
715
|
}
|
|
716
716
|
/**
|
|
717
717
|
* Maps a single entity-like object to database column values for insertion or update.
|
|
@@ -720,7 +720,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
720
720
|
*/
|
|
721
721
|
async mapToColumns(obj) {
|
|
722
722
|
const transformContext = await this.getTransformContext();
|
|
723
|
-
return this._mapToColumns(obj, transformContext);
|
|
723
|
+
return await this._mapToColumns(obj, transformContext);
|
|
724
724
|
}
|
|
725
725
|
/**
|
|
726
726
|
* Maps multiple new entity objects to database column values for insertion.
|
|
@@ -729,7 +729,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
729
729
|
*/
|
|
730
730
|
async mapManyToInsertColumns(objects) {
|
|
731
731
|
const transformContext = await this.getTransformContext();
|
|
732
|
-
return this._mapManyToInsertColumns(objects, transformContext);
|
|
732
|
+
return await this._mapManyToInsertColumns(objects, transformContext);
|
|
733
733
|
}
|
|
734
734
|
/**
|
|
735
735
|
* Maps a new entity object to database column values for insertion.
|
|
@@ -738,7 +738,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
738
738
|
*/
|
|
739
739
|
async mapToInsertColumns(obj) {
|
|
740
740
|
const transformContext = await this.getTransformContext();
|
|
741
|
-
return this._mapToInsertColumns(obj, transformContext);
|
|
741
|
+
return await this._mapToInsertColumns(obj, transformContext);
|
|
742
742
|
}
|
|
743
743
|
/**
|
|
744
744
|
* Maps an entity update object to database column values for updating.
|
|
@@ -747,7 +747,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
747
747
|
*/
|
|
748
748
|
async mapUpdate(update) {
|
|
749
749
|
const transformContext = await this.getTransformContext();
|
|
750
|
-
return this._mapUpdate(update, transformContext);
|
|
750
|
+
return await this._mapUpdate(update, transformContext);
|
|
751
751
|
}
|
|
752
752
|
/**
|
|
753
753
|
* Gets a Drizzle select query for the ID of a single entity matching the provided query, limited to 1 result.
|
|
@@ -768,7 +768,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
768
768
|
return sql `${this.#tableWithMetadata.attributes} || ${JSON.stringify(attributes)}::jsonb`;
|
|
769
769
|
}
|
|
770
770
|
async _mapManyToEntity(columns, transformContext) {
|
|
771
|
-
return toArrayAsync(mapAsync(columns, async (column) => this._mapToEntity(column, transformContext)));
|
|
771
|
+
return await toArrayAsync(mapAsync(columns, async (column) => await this._mapToEntity(column, transformContext)));
|
|
772
772
|
}
|
|
773
773
|
async _mapToEntity(columns, transformContext) {
|
|
774
774
|
const entries = [];
|
|
@@ -781,7 +781,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
781
781
|
return Schema.parse(this.type, obj);
|
|
782
782
|
}
|
|
783
783
|
async _mapManyToColumns(objects, transformContext) {
|
|
784
|
-
return toArrayAsync(mapAsync(objects, async (obj) => this._mapToColumns(obj, transformContext)));
|
|
784
|
+
return await toArrayAsync(mapAsync(objects, async (obj) => await this._mapToColumns(obj, transformContext)));
|
|
785
785
|
}
|
|
786
786
|
async _mapToColumns(obj, transformContext) {
|
|
787
787
|
const columns = {};
|
|
@@ -792,7 +792,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
792
792
|
return columns;
|
|
793
793
|
}
|
|
794
794
|
async _mapManyToInsertColumns(objects, transformContext) {
|
|
795
|
-
return toArrayAsync(mapAsync(objects, async (obj) => this._mapToInsertColumns(obj, transformContext)));
|
|
795
|
+
return await toArrayAsync(mapAsync(objects, async (obj) => await this._mapToInsertColumns(obj, transformContext)));
|
|
796
796
|
}
|
|
797
797
|
async _mapToInsertColumns(obj, transformContext) {
|
|
798
798
|
const mapped = await this._mapToColumns(obj, transformContext);
|
|
@@ -847,7 +847,7 @@ let EntityRepository = class EntityRepository extends Transactional {
|
|
|
847
847
|
const transformContext = await this.#transformContext;
|
|
848
848
|
this.#transformContext = transformContext;
|
|
849
849
|
}
|
|
850
|
-
return this.#transformContext;
|
|
850
|
+
return await this.#transformContext;
|
|
851
851
|
}
|
|
852
852
|
};
|
|
853
853
|
EntityRepository = __decorate([
|
package/package.json
CHANGED
package/schema/schema.error.js
CHANGED
|
@@ -8,8 +8,9 @@ export class SchemaError extends CustomError {
|
|
|
8
8
|
inner;
|
|
9
9
|
innerMessages;
|
|
10
10
|
constructor(message, options, cause) {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const path = isString(options.path) ? options.path : options.path.path;
|
|
12
|
+
super({ message: `${path}: ${message}`, cause: cause ?? options.cause, fast: options.fast });
|
|
13
|
+
this.path = path;
|
|
13
14
|
if (isDefined(options.inner) && (!isArray(options.inner) || (options.inner.length > 0))) {
|
|
14
15
|
this.inner = isArray(options.inner)
|
|
15
16
|
? (options.inner.length == 1)
|
|
@@ -22,7 +23,6 @@ export class SchemaError extends CustomError {
|
|
|
22
23
|
this.details = options.details;
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
|
-
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
26
26
|
static expectedButGot(expected, got, path, options) {
|
|
27
27
|
const expectedNames = toArray(expected).map((e) => isFunction(e) ? e.name : e);
|
|
28
28
|
const expectedString = expectedNames.length == 1
|
|
@@ -32,7 +32,6 @@ export class SchemaError extends CustomError {
|
|
|
32
32
|
const message = `Expected ${expectedString} but got ${got}${customMessage}`;
|
|
33
33
|
return new SchemaError(message, { path, ...options });
|
|
34
34
|
}
|
|
35
|
-
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
36
35
|
static couldNotCoerce(expected, got, path, options) {
|
|
37
36
|
const expectedNames = toArray(expected).map((e) => isFunction(e) ? e.name : e);
|
|
38
37
|
const expectedString = expectedNames.length == 1
|
|
@@ -43,9 +42,7 @@ export class SchemaError extends CustomError {
|
|
|
43
42
|
return new SchemaError(errorMessage, { path, ...options });
|
|
44
43
|
}
|
|
45
44
|
getExtraInfo(includeMessage = false) {
|
|
46
|
-
const obj = {
|
|
47
|
-
path: this.path
|
|
48
|
-
};
|
|
45
|
+
const obj = { path: this.path };
|
|
49
46
|
if (includeMessage) {
|
|
50
47
|
obj['message'] = this.message;
|
|
51
48
|
}
|