@tstdl/base 0.91.49 → 0.91.51
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/ai/data-extracting.d.ts +1 -0
- package/ai/data-extracting.js +62 -0
- package/authentication/server/authentication.api-controller.js +4 -4
- package/cancellation/token.d.ts +1 -2
- package/cancellation/token.js +1 -1
- package/core.d.ts +1 -1
- package/core.js +1 -1
- package/document-management/api/document-management.api.d.ts +376 -0
- package/document-management/api/document-management.api.js +208 -0
- package/document-management/api/index.d.ts +1 -0
- package/document-management/api/index.js +1 -0
- package/document-management/drizzle/0000_wakeful_firebrand.sql +228 -0
- package/document-management/drizzle/meta/0000_snapshot.json +1538 -0
- package/document-management/drizzle/meta/_journal.json +13 -0
- package/document-management/drizzle.config.d.ts +2 -0
- package/document-management/drizzle.config.js +11 -0
- package/document-management/index.d.ts +2 -0
- package/document-management/index.js +2 -0
- package/document-management/localizations/english.d.ts +2 -0
- package/document-management/localizations/english.js +9 -0
- package/document-management/localizations/german.d.ts +2 -0
- package/document-management/localizations/german.js +9 -0
- package/document-management/localizations/index.d.ts +5 -0
- package/document-management/localizations/index.js +9 -0
- package/document-management/localizations/localization.d.ts +9 -0
- package/document-management/localizations/localization.js +2 -0
- package/document-management/models/document-category.model.d.ts +4 -0
- package/document-management/models/document-category.model.js +18 -0
- package/document-management/models/document-collection-document.model.d.ts +7 -0
- package/document-management/models/document-collection-document.model.js +33 -0
- package/document-management/models/document-collection.model.d.ts +3 -0
- package/document-management/models/document-collection.model.js +14 -0
- package/document-management/models/document-file.model.d.ts +7 -0
- package/document-management/models/document-file.model.js +33 -0
- package/document-management/models/document-property-value.model.d.ts +21 -0
- package/document-management/models/document-property-value.model.js +58 -0
- package/document-management/models/document-property.model.d.ts +11 -0
- package/document-management/models/document-property.model.js +30 -0
- package/document-management/models/document-request-collection.model.d.ts +6 -0
- package/document-management/models/document-request-collection.model.js +28 -0
- package/document-management/models/document-request-file.model.d.ts +11 -0
- package/document-management/models/document-request-file.model.js +56 -0
- package/document-management/models/document-request-template.d.ts +10 -0
- package/document-management/models/document-request-template.js +39 -0
- package/document-management/models/document-request.model.d.ts +9 -0
- package/document-management/models/document-request.model.js +37 -0
- package/document-management/models/document-requests-template.d.ts +5 -0
- package/document-management/models/document-requests-template.js +23 -0
- package/document-management/models/document-type-property.model.d.ts +6 -0
- package/document-management/models/document-type-property.model.js +28 -0
- package/document-management/models/document-type.model.d.ts +7 -0
- package/document-management/models/document-type.model.js +32 -0
- package/document-management/models/document.model.d.ts +9 -0
- package/document-management/models/document.model.js +44 -0
- package/document-management/models/index.d.ts +15 -0
- package/document-management/models/index.js +15 -0
- package/document-management/models/schemas.d.ts +33 -0
- package/document-management/models/schemas.js +34 -0
- package/document-management/models/service-models/categories-and-types.view-model.d.ts +6 -0
- package/document-management/models/service-models/categories-and-types.view-model.js +24 -0
- package/document-management/models/service-models/document-folders.view-model.d.ts +22 -0
- package/document-management/models/service-models/document-folders.view-model.js +56 -0
- package/document-management/models/service-models/document-requests-template.view-model.d.ts +8 -0
- package/document-management/models/service-models/document-requests-template.view-model.js +26 -0
- package/document-management/models/service-models/document.service-model.d.ts +262 -0
- package/document-management/models/service-models/document.service-model.js +50 -0
- package/document-management/models/service-models/document.view-model.d.ts +33 -0
- package/document-management/models/service-models/document.view-model.js +99 -0
- package/document-management/models/service-models/index.d.ts +8 -0
- package/document-management/models/service-models/index.js +8 -0
- package/document-management/models/service-models/normalized-document-collection-view.model.d.ts +73 -0
- package/document-management/models/service-models/normalized-document-collection-view.model.js +110 -0
- package/document-management/models/service-models/normalized-requests-template-data.model.d.ts +16 -0
- package/document-management/models/service-models/normalized-requests-template-data.model.js +13 -0
- package/document-management/models/service-models/stats.view-model.d.ts +6 -0
- package/document-management/models/service-models/stats.view-model.js +32 -0
- package/document-management/module.d.ts +11 -0
- package/document-management/module.js +27 -0
- package/document-management/services/document-management.service.d.ts +65 -0
- package/document-management/services/document-management.service.js +376 -0
- package/document-management/services/index.d.ts +1 -0
- package/document-management/services/index.js +1 -0
- package/examples/document-management/main.d.ts +1 -0
- package/examples/document-management/main.js +30 -0
- package/examples/orm/drizzle.config.js +2 -1
- package/examples/orm/schemas.d.ts +1 -1
- package/examples/orm/user.model.d.ts +1 -2
- package/examples/orm/user.model.js +0 -1
- package/http/server/node/node-http-server.js +5 -5
- package/injector/injector.d.ts +4 -1
- package/injector/injector.js +4 -1
- package/injector/interfaces.d.ts +3 -3
- package/json-path/json-path.d.ts +2 -0
- package/json-path/json-path.js +7 -0
- package/message-bus/message-bus.d.ts +4 -6
- package/orm/database-schema.d.ts +3 -0
- package/orm/database-schema.js +6 -2
- package/orm/database.d.ts +6 -0
- package/orm/database.js +14 -0
- package/orm/decorators.d.ts +25 -2
- package/orm/decorators.js +15 -0
- package/orm/drizzle/index.d.ts +1 -0
- package/orm/drizzle/index.js +1 -0
- package/orm/drizzle/schema-converter.d.ts +37 -8
- package/orm/drizzle/schema-converter.js +121 -40
- package/orm/entity.d.ts +15 -12
- package/orm/entity.js +24 -11
- package/orm/index.d.ts +3 -2
- package/orm/index.js +3 -2
- package/orm/module.d.ts +6 -0
- package/orm/module.js +15 -0
- package/orm/query-converter.d.ts +5 -0
- package/orm/query-converter.js +114 -0
- package/orm/query.d.ts +15 -13
- package/orm/repository.d.ts +90 -31
- package/orm/repository.js +357 -55
- package/orm/schemas/index.d.ts +3 -0
- package/orm/schemas/index.js +3 -0
- package/orm/schemas/json.d.ts +9 -0
- package/orm/schemas/json.js +19 -0
- package/orm/schemas/numeric-date.d.ts +8 -0
- package/orm/schemas/numeric-date.js +13 -0
- package/orm/schemas/timestamp.d.ts +10 -0
- package/orm/schemas/timestamp.js +20 -0
- package/orm/transaction.d.ts +29 -0
- package/orm/transaction.js +73 -0
- package/orm/types.d.ts +15 -8
- package/orm/types.js +3 -2
- package/package.json +22 -12
- package/{rxjs → rxjs-utils}/reject-error.d.ts +1 -1
- package/{rxjs → rxjs-utils}/retry-backoff.d.ts +2 -2
- package/{rxjs → rxjs-utils}/slow-array.d.ts +7 -7
- package/{rxjs → rxjs-utils}/slow-array.js +2 -2
- package/{rxjs → rxjs-utils}/start-with-provider.d.ts +1 -1
- package/{rxjs → rxjs-utils}/teardown.d.ts +1 -1
- package/{rxjs → rxjs-utils}/untrack.d.ts +1 -1
- package/schema/decorators/types.d.ts +2 -2
- package/schema/schemas/number.d.ts +1 -1
- package/signals/pipe.d.ts +1 -1
- package/signals/pipe.js +1 -2
- package/sse/server-sent-events.d.ts +54 -0
- package/sse/server-sent-events.js +54 -0
- package/types.d.ts +6 -2
- package/utils/comparison.d.ts +2 -1
- package/utils/comparison.js +4 -3
- package/utils/compression.d.ts +4 -4
- package/utils/compression.js +35 -43
- package/utils/object/dereference.d.ts +6 -4
- package/utils/object/dereference.js +20 -8
- package/utils/object/object.d.ts +2 -0
- package/utils/object/object.js +20 -0
- /package/{rxjs → rxjs-utils}/cast.d.ts +0 -0
- /package/{rxjs → rxjs-utils}/cast.js +0 -0
- /package/{rxjs → rxjs-utils}/index.d.ts +0 -0
- /package/{rxjs → rxjs-utils}/index.js +0 -0
- /package/{rxjs → rxjs-utils}/noop.d.ts +0 -0
- /package/{rxjs → rxjs-utils}/noop.js +0 -0
- /package/{rxjs → rxjs-utils}/reject-error.js +0 -0
- /package/{rxjs → rxjs-utils}/retry-backoff.js +0 -0
- /package/{rxjs → rxjs-utils}/start-with-provider.js +0 -0
- /package/{rxjs → rxjs-utils}/teardown.js +0 -0
- /package/{rxjs → rxjs-utils}/timing.d.ts +0 -0
- /package/{rxjs → rxjs-utils}/timing.js +0 -0
- /package/{rxjs → rxjs-utils}/untrack.js +0 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { getEntityMap } from '../../database/index.js';
|
|
8
|
+
import { Enumerable } from '../../enumerable/index.js';
|
|
9
|
+
import { BadRequestError } from '../../errors/index.js';
|
|
10
|
+
import { getMimeType, getMimeTypeExtensions } from '../../file/index.js';
|
|
11
|
+
import { Singleton, inject, injectArgument, provide } from '../../injector/index.js';
|
|
12
|
+
import { ObjectStorage } from '../../object-storage/index.js';
|
|
13
|
+
import { DATABASE_CONFIG, EntityRepositoryConfig, injectRepository } from '../../orm/index.js';
|
|
14
|
+
import { toArray } from '../../utils/array/index.js';
|
|
15
|
+
import { assertDefinedPass, compareByValueSelectionToOrder, currentTimestamp, digest, isBoolean, isDefined, isNotNull, isNull, isNumber, isString, isUint8Array, millisecondsPerMinute } from '../../utils/index.js';
|
|
16
|
+
import { groupToMap } from '../../utils/iterable-helpers/index.js';
|
|
17
|
+
import { readBinaryStream } from '../../utils/stream/index.js';
|
|
18
|
+
import { Document, DocumentCategory, DocumentCollection, DocumentCollectionDocument, DocumentFile, DocumentProperty, DocumentPropertyBooleanValue, DocumentPropertyDataType, DocumentPropertyDecimalValue, DocumentPropertyIntegerValue, DocumentPropertyTextValue, DocumentRequest, DocumentRequestCollection, DocumentRequestFile, DocumentRequestTemplate, DocumentRequestsTemplate, DocumentType, DocumentTypeProperty } from '../models/index.js';
|
|
19
|
+
import { DocumentManagementConfig } from '../module.js';
|
|
20
|
+
let DocumentManagementService = class DocumentManagementService {
|
|
21
|
+
documentService = injectRepository(Document);
|
|
22
|
+
documentFileService = injectRepository(DocumentFile);
|
|
23
|
+
documentCollectionService = injectRepository(DocumentCollection);
|
|
24
|
+
documentCategoryService = injectRepository(DocumentCategory);
|
|
25
|
+
documentTypeService = injectRepository(DocumentType);
|
|
26
|
+
documentRequestService = injectRepository(DocumentRequest);
|
|
27
|
+
documentRequestsTemplateService = injectRepository(DocumentRequestsTemplate);
|
|
28
|
+
documentRequestTemplateService = injectRepository(DocumentRequestTemplate);
|
|
29
|
+
documentRequestCollectionService = injectRepository(DocumentRequestCollection);
|
|
30
|
+
documentRequestFileService = injectRepository(DocumentRequestFile);
|
|
31
|
+
documentPropertyService = injectRepository(DocumentProperty);
|
|
32
|
+
documentTypePropertyService = injectRepository(DocumentTypeProperty);
|
|
33
|
+
documentPropertyTextValueService = injectRepository(DocumentPropertyTextValue);
|
|
34
|
+
documentPropertyIntegerValueService = injectRepository(DocumentPropertyIntegerValue);
|
|
35
|
+
documentPropertyDecimalValueService = injectRepository(DocumentPropertyDecimalValue);
|
|
36
|
+
documentPropertyBooleanValueService = injectRepository(DocumentPropertyBooleanValue);
|
|
37
|
+
documentCollectionDocumentService = injectRepository(DocumentCollectionDocument);
|
|
38
|
+
fileObjectStorage = inject(ObjectStorage, (injectArgument(this, { optional: true }) ?? inject(DocumentManagementConfig)).fileObjectStorageModule);
|
|
39
|
+
async loadData(collectionIds, collectionsMetadata) {
|
|
40
|
+
return this.documentCollectionService.transaction(async (_, transaction) => {
|
|
41
|
+
const [collections, collectionDocuments, requestCollections, categories, types] = await Promise.all([
|
|
42
|
+
this.documentCollectionService.withTransaction(transaction).loadMany(collectionIds),
|
|
43
|
+
this.documentCollectionDocumentService.withTransaction(transaction).loadManyByQuery({ collectionId: { $in: collectionIds } }),
|
|
44
|
+
this.documentRequestCollectionService.withTransaction(transaction).loadManyByQuery({ collectionId: { $in: collectionIds } }),
|
|
45
|
+
this.documentCategoryService.withTransaction(transaction).loadManyByQuery({}, { order: { label: 1 } }),
|
|
46
|
+
this.documentTypeService.withTransaction(transaction).loadManyByQuery({}, { order: { label: 1 } })
|
|
47
|
+
]);
|
|
48
|
+
const documentIds = collectionDocuments.map((document) => document.documentId);
|
|
49
|
+
const requestIds = requestCollections.map((requestCollection) => requestCollection.requestId);
|
|
50
|
+
const [documents, requests, requestFiles, textValues, integerValues, decimalValues, booleanValues] = await Promise.all([
|
|
51
|
+
this.documentService.withTransaction(transaction).loadManyByQuery({ id: { $in: documentIds } }, { order: { 'metadata.createTimestamp': 'desc' } }),
|
|
52
|
+
this.documentRequestService.withTransaction(transaction).loadManyByQuery({ id: { $in: requestIds } }, { order: { 'metadata.createTimestamp': 'desc' } }),
|
|
53
|
+
this.documentRequestFileService.withTransaction(transaction).loadManyByQuery({ requestId: { $in: requestIds } }, { order: { 'metadata.createTimestamp': 'desc' } }),
|
|
54
|
+
this.documentPropertyTextValueService.withTransaction(transaction).loadManyByQuery({ documentId: { $in: documentIds } }),
|
|
55
|
+
this.documentPropertyIntegerValueService.withTransaction(transaction).loadManyByQuery({ documentId: { $in: documentIds } }),
|
|
56
|
+
this.documentPropertyDecimalValueService.withTransaction(transaction).loadManyByQuery({ documentId: { $in: documentIds } }),
|
|
57
|
+
this.documentPropertyBooleanValueService.withTransaction(transaction).loadManyByQuery({ documentId: { $in: documentIds } })
|
|
58
|
+
]);
|
|
59
|
+
const documentFileIds = documents.map((document) => document.fileId);
|
|
60
|
+
const requestFileIds = requestFiles.map((requestFile) => requestFile.fileId);
|
|
61
|
+
const files = await this.documentFileService.withTransaction(transaction).loadManyByQuery({ id: { $in: [...documentFileIds, ...requestFileIds] } }, { order: { 'metadata.createTimestamp': 'desc' } });
|
|
62
|
+
const requestsFilesMap = groupToMap(requestFiles, (requestFile) => requestFile.requestId);
|
|
63
|
+
const valuesMap = Enumerable.from(textValues).concat(integerValues).concat(decimalValues).concat(booleanValues).groupToMap((value) => value.documentId);
|
|
64
|
+
const collectionViews = collections.toSorted(compareByValueSelectionToOrder(collectionIds, (collection) => collection.id)).map((collection) => ({
|
|
65
|
+
...collection,
|
|
66
|
+
name: collectionsMetadata?.[collection.id]?.name ?? null,
|
|
67
|
+
group: collectionsMetadata?.[collection.id]?.group ?? null
|
|
68
|
+
}));
|
|
69
|
+
const documentViews = documents.map((document) => ({
|
|
70
|
+
...document,
|
|
71
|
+
collectionAssignments: collectionDocuments.filter((collectionDocument) => collectionDocument.documentId == document.id).map(({ collectionId, archiveTimestamp }) => ({ collectionId, archiveTimestamp })),
|
|
72
|
+
properties: valuesMap.get(document.id) ?? []
|
|
73
|
+
}));
|
|
74
|
+
const requestViews = requests.map((request) => ({
|
|
75
|
+
...request,
|
|
76
|
+
collectionIds: requestCollections.filter((requestCollection) => requestCollection.requestId == request.id).map((requestCollection) => requestCollection.collectionId),
|
|
77
|
+
requestFiles: requestsFilesMap.get(request.id) ?? []
|
|
78
|
+
}));
|
|
79
|
+
return {
|
|
80
|
+
collections: collectionViews,
|
|
81
|
+
documents: documentViews,
|
|
82
|
+
requests: requestViews,
|
|
83
|
+
files,
|
|
84
|
+
categories,
|
|
85
|
+
types
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async loadDocumentRequestsTemplateData() {
|
|
90
|
+
const [requestsTemplates, requestTemplates] = await Promise.all([
|
|
91
|
+
this.documentRequestsTemplateService.loadManyByQuery({}, { order: { label: 'asc' } }),
|
|
92
|
+
this.documentRequestTemplateService.loadManyByQuery({})
|
|
93
|
+
]);
|
|
94
|
+
const templates = requestsTemplates.map((requestsTemplate) => ({
|
|
95
|
+
...requestsTemplate,
|
|
96
|
+
requestTemplates: requestTemplates.filter((requestTemplate) => requestTemplate.requestsTemplateId == requestsTemplate.id)
|
|
97
|
+
}));
|
|
98
|
+
return { templates };
|
|
99
|
+
}
|
|
100
|
+
async loadCategoriesAndTypes() {
|
|
101
|
+
const [categories, types] = await Promise.all([
|
|
102
|
+
this.documentCategoryService.loadManyByQuery({}, { order: { label: 1 } }),
|
|
103
|
+
this.documentTypeService.loadManyByQuery({}, { order: { label: 1 } })
|
|
104
|
+
]);
|
|
105
|
+
return { categories, types };
|
|
106
|
+
}
|
|
107
|
+
async loadDocument(id) {
|
|
108
|
+
return this.documentService.load(id);
|
|
109
|
+
}
|
|
110
|
+
async loadDocumentFile(id) {
|
|
111
|
+
return this.documentFileService.load(id);
|
|
112
|
+
}
|
|
113
|
+
async loadType(id) {
|
|
114
|
+
return this.documentTypeService.load(id);
|
|
115
|
+
}
|
|
116
|
+
async getFileContentUrl(fileId, title, download = false) {
|
|
117
|
+
const file = await this.documentFileService.load(fileId);
|
|
118
|
+
return this.getDocumentFileContentObjectUrl(title ?? fileId, file, download);
|
|
119
|
+
}
|
|
120
|
+
async createCategory(parameters) {
|
|
121
|
+
return this.documentCategoryService.insert(parameters);
|
|
122
|
+
}
|
|
123
|
+
async createType(parameters) {
|
|
124
|
+
return this.documentTypeService.insert(parameters);
|
|
125
|
+
}
|
|
126
|
+
async createCollection(parameters) {
|
|
127
|
+
return this.documentCollectionService.insert(parameters ?? {});
|
|
128
|
+
}
|
|
129
|
+
async collectionHasDocumentByFilter(collectionId, filter) {
|
|
130
|
+
const collectionDocuments = await this.documentCollectionDocumentService.loadManyByQuery({ collectionId });
|
|
131
|
+
const documentIds = collectionDocuments.map((cd) => cd.documentId);
|
|
132
|
+
return this.documentService.hasByQuery({ $and: [{ id: { $in: documentIds } }, filter] });
|
|
133
|
+
}
|
|
134
|
+
async getRequestFilesStats(collectionIds) {
|
|
135
|
+
const collectionRequests = await this.documentRequestCollectionService.loadManyByQuery({ collectionId: { $in: toArray(collectionIds) } });
|
|
136
|
+
const requestIds = collectionRequests.map((collectionRequest) => collectionRequest.requestId);
|
|
137
|
+
const filteredRequests = await this.documentRequestService.loadManyByQuery({ id: { $in: requestIds }, completed: false });
|
|
138
|
+
const filteredRequestIds = filteredRequests.map((request) => request.id);
|
|
139
|
+
const requiredFilesCount = filteredRequests.reduce((sum, request) => sum + request.requiredFilesCount, 0);
|
|
140
|
+
const [pendingFilesCount, approvedFilesCount] = await Promise.all([
|
|
141
|
+
this.documentRequestFileService.countByQuery({ requestId: { $in: filteredRequestIds }, approval: null }),
|
|
142
|
+
this.documentRequestFileService.countByQuery({ requestId: { $in: filteredRequestIds }, approval: true })
|
|
143
|
+
]);
|
|
144
|
+
return { requiredFilesCount, requiredFilesLeft: Math.max(0, requiredFilesCount - approvedFilesCount), pendingFilesCount, approvedFilesCount };
|
|
145
|
+
}
|
|
146
|
+
async createDocumentRequestsTemplate(parameters) {
|
|
147
|
+
return this.documentRequestsTemplateService.insert(parameters);
|
|
148
|
+
}
|
|
149
|
+
async updateDocumentRequestsTemplate({ id, label, metadata }) {
|
|
150
|
+
return this.documentRequestsTemplateService.update(id, { label, metadata });
|
|
151
|
+
}
|
|
152
|
+
async applyDocumentRequestsTemplate({ id, collectionIds, metadata }) {
|
|
153
|
+
const requestTemplates = await this.documentRequestTemplateService.loadManyByQuery({ requestsTemplateId: id });
|
|
154
|
+
await this.documentRequestService.transaction(async (_, transaction) => {
|
|
155
|
+
for (const { typeId, requiredFilesCount, comment } of requestTemplates) {
|
|
156
|
+
await this.createDocumentRequest({ typeId, requiredFilesCount, comment, collectionIds, metadata }, transaction);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
async deleteDocumentRequestsTemplate(parameters) {
|
|
161
|
+
return this.documentRequestsTemplateService.delete(parameters.id);
|
|
162
|
+
}
|
|
163
|
+
async createDocumentRequestTemplate(parameters) {
|
|
164
|
+
return this.documentRequestTemplateService.insert(parameters);
|
|
165
|
+
}
|
|
166
|
+
async updateDocumentRequestTemplate({ id, typeId, requiredFilesCount, comment, metadata }) {
|
|
167
|
+
return this.documentRequestTemplateService.update(id, { typeId, requiredFilesCount, comment, metadata });
|
|
168
|
+
}
|
|
169
|
+
async deleteDocumentRequestTemplate(parameters) {
|
|
170
|
+
return this.documentRequestTemplateService.delete(parameters.id);
|
|
171
|
+
}
|
|
172
|
+
async createDocument({ typeId, addition, date, expiration, originalFileName, collectionIds, properties, metadata }, content) {
|
|
173
|
+
return this.documentService.transaction(async (_, transaction) => {
|
|
174
|
+
const documentFile = await this.createDocumentFile(content, originalFileName, transaction);
|
|
175
|
+
const document = await this.documentService.withTransaction(transaction).insert({ fileId: documentFile.id, typeId, addition, date, expiration, metadata });
|
|
176
|
+
if (isDefined(collectionIds)) {
|
|
177
|
+
for (const collectionId of toArray(collectionIds)) {
|
|
178
|
+
await this.documentCollectionDocumentService.withTransaction(transaction).insert({ collectionId, documentId: document.id, archiveTimestamp: null });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (isDefined(properties)) {
|
|
182
|
+
const mappedProperties = properties.map((property) => ({ ...property, documentId: document.id }));
|
|
183
|
+
await this.setDocumentProperties(mappedProperties, transaction);
|
|
184
|
+
}
|
|
185
|
+
return document;
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
async approveDocumentRequestFile({ id, approvalComment, documentMetadata, requestFileMetadata }) {
|
|
189
|
+
return this.documentRequestFileService.transaction(async (_, transaction) => {
|
|
190
|
+
const requestFile = await this.documentRequestFileService.withTransaction(transaction).load(id);
|
|
191
|
+
const requestCollections = await this.documentRequestCollectionService.withTransaction(transaction).loadManyByQuery({ requestId: requestFile.requestId });
|
|
192
|
+
if (requestFile.approval == true) {
|
|
193
|
+
throw new BadRequestError('Document request file already accepted.');
|
|
194
|
+
}
|
|
195
|
+
const request = await this.documentRequestService.withTransaction(transaction).load(requestFile.requestId);
|
|
196
|
+
const document = await this.documentService.withTransaction(transaction).insert({
|
|
197
|
+
fileId: requestFile.fileId,
|
|
198
|
+
typeId: request.typeId,
|
|
199
|
+
addition: requestFile.addition,
|
|
200
|
+
date: null,
|
|
201
|
+
expiration: null,
|
|
202
|
+
metadata: documentMetadata
|
|
203
|
+
});
|
|
204
|
+
for (const { collectionId } of requestCollections) {
|
|
205
|
+
await this.addDocumentToCollection({ collectionId, documentId: document.id }, transaction);
|
|
206
|
+
}
|
|
207
|
+
await this.documentRequestFileService.withTransaction(transaction).update(id, { approval: true, approvalComment, approvalTimestamp: currentTimestamp(), createdDocumentId: document.id, metadata: requestFileMetadata });
|
|
208
|
+
return document;
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
async rejectDocumentRequestFile({ id, approvalComment, metadata }) {
|
|
212
|
+
return this.documentRequestFileService.transaction(async (_, transaction) => {
|
|
213
|
+
const requestFile = await this.documentRequestFileService.withTransaction(transaction).load(id);
|
|
214
|
+
if (requestFile.approval == true) {
|
|
215
|
+
throw new BadRequestError('Document request file already accepted.');
|
|
216
|
+
}
|
|
217
|
+
await this.documentRequestFileService.withTransaction(transaction).update(id, { approval: false, approvalComment, approvalTimestamp: currentTimestamp(), metadata });
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
async updateDocumentRequestFile({ id, addition, approvalComment, metadata }) {
|
|
221
|
+
return this.documentRequestFileService.update(id, { addition, approvalComment, metadata });
|
|
222
|
+
}
|
|
223
|
+
async deleteDocumentRequestFile({ id, metadata }) {
|
|
224
|
+
const requestFile = await this.documentRequestFileService.load(id);
|
|
225
|
+
if (isNotNull(requestFile.approval)) {
|
|
226
|
+
throw new BadRequestError('Only pending request files can be deleted.');
|
|
227
|
+
}
|
|
228
|
+
await this.documentRequestFileService.delete(id, metadata);
|
|
229
|
+
}
|
|
230
|
+
async createDocumentFile(content, originalFileName, dbTransaction) {
|
|
231
|
+
return this.documentFileService.useTransaction(dbTransaction, async (_, transaction) => {
|
|
232
|
+
const contentAsUint8Array = isUint8Array(content) ? content : await readBinaryStream(content);
|
|
233
|
+
const hash = await digest('SHA-256', contentAsUint8Array).toHex();
|
|
234
|
+
const mimeType = await getMimeType(contentAsUint8Array);
|
|
235
|
+
const documentFile = await this.documentFileService.withTransaction(transaction).insert({
|
|
236
|
+
originalFileName,
|
|
237
|
+
mimeType,
|
|
238
|
+
hash,
|
|
239
|
+
size: contentAsUint8Array.length
|
|
240
|
+
});
|
|
241
|
+
const key = getDocumentFileKey(documentFile.id);
|
|
242
|
+
await this.fileObjectStorage.uploadObject(key, contentAsUint8Array);
|
|
243
|
+
return documentFile;
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
async createDocumentRequestFile({ requestId, addition, originalFileName, metadata }, content) {
|
|
247
|
+
return this.documentRequestFileService.transaction(async (_, transaction) => {
|
|
248
|
+
const [request, existingRequestFiles] = await Promise.all([
|
|
249
|
+
this.documentRequestService.withTransaction(transaction).load(requestId),
|
|
250
|
+
this.documentRequestFileService.withTransaction(transaction).loadManyByQuery({ requestId })
|
|
251
|
+
]);
|
|
252
|
+
const filesCountLeft = (request.completed ? 0 : request.requiredFilesCount) - existingRequestFiles.reduce((sum, requestFile) => sum + ((requestFile.approval != false) ? 1 : 0), 0);
|
|
253
|
+
if (filesCountLeft <= 0) {
|
|
254
|
+
throw new BadRequestError('Maximum amount of allowed files reached.');
|
|
255
|
+
}
|
|
256
|
+
const file = await this.createDocumentFile(content, originalFileName, transaction);
|
|
257
|
+
return this.documentRequestFileService.withTransaction(transaction).insert({ requestId, fileId: file.id, addition, createdDocumentId: null, approval: null, approvalComment: null, approvalTimestamp: null, metadata });
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
async createDocumentRequest(parameters, transaction) {
|
|
261
|
+
if (parameters.collectionIds.length == 0) {
|
|
262
|
+
throw new BadRequestError('No target collectionId specified.');
|
|
263
|
+
}
|
|
264
|
+
return this.documentRequestService.useTransaction(transaction, async (_, tx) => {
|
|
265
|
+
const request = await this.documentRequestService.withTransaction(tx).insert({ ...parameters, completed: false });
|
|
266
|
+
const newDocumentRequestCollections = parameters.collectionIds.map((collectionId) => ({ requestId: request.id, collectionId }));
|
|
267
|
+
await this.documentRequestCollectionService.withTransaction(tx).insertMany(newDocumentRequestCollections);
|
|
268
|
+
return request;
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
async updateDocument(parameters, transaction) {
|
|
272
|
+
const { id: documentId, properties: propertyUpdates, ...update } = parameters;
|
|
273
|
+
await this.documentService.useTransaction(transaction, async (repository, tx) => {
|
|
274
|
+
await repository.update(documentId, update);
|
|
275
|
+
if (isDefined(propertyUpdates)) {
|
|
276
|
+
const mappedPropertyUpdates = propertyUpdates.map((property) => ({ documentId, ...property }));
|
|
277
|
+
await this.setDocumentProperties(mappedPropertyUpdates, tx);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
async updateDocumentRequest(parameters, transaction) {
|
|
282
|
+
const { id: documentRequestId, ...update } = parameters;
|
|
283
|
+
const requestFiles = await this.documentRequestFileService.withOptionalTransaction(transaction).loadManyByQuery({ requestId: parameters.id });
|
|
284
|
+
if (parameters.completed == true) {
|
|
285
|
+
const hasCreatedDocument = requestFiles.some((requestFile) => isNotNull(requestFile.createdDocumentId));
|
|
286
|
+
if (!hasCreatedDocument) {
|
|
287
|
+
throw new BadRequestError('Cannot complete requests which has no approved files.');
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
await this.documentRequestService.withOptionalTransaction(transaction).update(documentRequestId, update);
|
|
291
|
+
}
|
|
292
|
+
async deleteDocumentRequest({ id, metadata }, transaction) {
|
|
293
|
+
const requestFiles = await this.documentRequestFileService.loadManyByQuery({ requestId: id });
|
|
294
|
+
const hasCreatedDocument = requestFiles.some((requestFile) => isNotNull(requestFile.createdDocumentId));
|
|
295
|
+
if (hasCreatedDocument) {
|
|
296
|
+
throw new BadRequestError('Cannot delete requests which has approved files.');
|
|
297
|
+
}
|
|
298
|
+
await this.documentRequestService.withOptionalTransaction(transaction).delete(id, metadata);
|
|
299
|
+
}
|
|
300
|
+
async setDocumentProperties(setDocumentPropertyItems, transaction) {
|
|
301
|
+
if ((setDocumentPropertyItems.length == 0)) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
await this.documentPropertyService.useTransaction(transaction, async (_, tx) => {
|
|
305
|
+
const propertyIds = setDocumentPropertyItems.map((property) => property.propertyId);
|
|
306
|
+
const properties = await this.documentPropertyService.withTransaction(tx).loadManyByQuery({ id: { $in: propertyIds } });
|
|
307
|
+
const propertiesMap = getEntityMap(properties);
|
|
308
|
+
for (const { documentId, propertyId, value, metadata } of setDocumentPropertyItems) {
|
|
309
|
+
const property = assertDefinedPass(propertiesMap.get(propertyId));
|
|
310
|
+
validatePropertyValue(propertyId, property.dataType, value);
|
|
311
|
+
const propertyValueService = this.getDocumentPropertyValueService(property.dataType);
|
|
312
|
+
await propertyValueService.withTransaction(tx).upsert(['documentId', 'propertyId'], { documentId, propertyId, value: value, metadata }, undefined);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
async addDocumentToCollection(parameters, transaction) {
|
|
317
|
+
await this.documentCollectionDocumentService.withOptionalTransaction(transaction).upsert(['collectionId', 'documentId'], { ...parameters, archiveTimestamp: null });
|
|
318
|
+
}
|
|
319
|
+
async archiveDocument({ collectionId, documentId, metadata }) {
|
|
320
|
+
await this.documentCollectionDocumentService.updateByQuery({ collectionId, documentId }, { archiveTimestamp: currentTimestamp(), metadata });
|
|
321
|
+
}
|
|
322
|
+
async createProperty(parameters) {
|
|
323
|
+
return this.documentPropertyService.insert(parameters);
|
|
324
|
+
}
|
|
325
|
+
async assignPropertyToType(parameters) {
|
|
326
|
+
await this.documentTypePropertyService.insert(parameters);
|
|
327
|
+
}
|
|
328
|
+
getDocumentPropertyValueService(dataType) {
|
|
329
|
+
switch (dataType) {
|
|
330
|
+
case DocumentPropertyDataType.Text:
|
|
331
|
+
return this.documentPropertyTextValueService;
|
|
332
|
+
case DocumentPropertyDataType.Integer:
|
|
333
|
+
return this.documentPropertyIntegerValueService;
|
|
334
|
+
case DocumentPropertyDataType.Decimal:
|
|
335
|
+
return this.documentPropertyDecimalValueService;
|
|
336
|
+
case DocumentPropertyDataType.Boolean:
|
|
337
|
+
return this.documentPropertyBooleanValueService;
|
|
338
|
+
default:
|
|
339
|
+
throw new BadRequestError('Unknown property data type.');
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
async getDocumentFileContentObjectUrl(title, file, download) {
|
|
343
|
+
const key = getDocumentFileKey(file.id);
|
|
344
|
+
const fileExtension = getMimeTypeExtensions(file.mimeType)[0] ?? 'bin';
|
|
345
|
+
const disposition = download ? 'attachment' : 'inline';
|
|
346
|
+
const filename = `${title}.${fileExtension}`;
|
|
347
|
+
return this.fileObjectStorage.getDownloadUrl(key, currentTimestamp() + (5 * millisecondsPerMinute), {
|
|
348
|
+
'Response-Content-Type': file.mimeType,
|
|
349
|
+
'Response-Content-Disposition': `${disposition}; filename="${encodeURIComponent(filename)}"`
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
DocumentManagementService = __decorate([
|
|
354
|
+
Singleton({
|
|
355
|
+
providers: [
|
|
356
|
+
provide(EntityRepositoryConfig, { useValue: { schema: 'document_management' } }),
|
|
357
|
+
{ provide: DATABASE_CONFIG, useFactory: (_, context) => context.resolve(DocumentManagementConfig).database }
|
|
358
|
+
]
|
|
359
|
+
})
|
|
360
|
+
], DocumentManagementService);
|
|
361
|
+
export { DocumentManagementService };
|
|
362
|
+
function getDocumentFileKey(id) {
|
|
363
|
+
return `${id.slice(0, 2)}/${id.slice(0, 4)}/${id}`;
|
|
364
|
+
}
|
|
365
|
+
const validators = {
|
|
366
|
+
[DocumentPropertyDataType.Text]: (value) => isString(value) || isNull(value),
|
|
367
|
+
[DocumentPropertyDataType.Integer]: (value) => isNumber(value) || isNull(value),
|
|
368
|
+
[DocumentPropertyDataType.Decimal]: (value) => isNumber(value) || isNull(value),
|
|
369
|
+
[DocumentPropertyDataType.Boolean]: (value) => isBoolean(value) || isNull(value)
|
|
370
|
+
};
|
|
371
|
+
function validatePropertyValue(propertyId, dataType, value) {
|
|
372
|
+
const valid = validators[dataType](value);
|
|
373
|
+
if (!valid) {
|
|
374
|
+
throw new BadRequestError(`Invalid value for data type ${DocumentPropertyDataType[dataType]} for property ${propertyId}.`);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './document-management.service.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './document-management.service.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '../../polyfills.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import '../../polyfills.js';
|
|
2
|
+
import { Application } from '../../application/application.js';
|
|
3
|
+
import { configureDocumentManagement, migrateDocumentManagementSchema } from '../../document-management/module.js';
|
|
4
|
+
import { DocumentManagementService } from '../../document-management/services/document-management.service.js';
|
|
5
|
+
import { injectAsync } from '../../injector/inject.js';
|
|
6
|
+
import { configureS3ObjectStorage } from '../../object-storage/index.js';
|
|
7
|
+
async function bootstrap() {
|
|
8
|
+
configureDocumentManagement({
|
|
9
|
+
database: {
|
|
10
|
+
connection: {
|
|
11
|
+
database: 'xxx',
|
|
12
|
+
user: 'xxx',
|
|
13
|
+
password: 'xxx'
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
fileObjectStorageModule: 'documents'
|
|
17
|
+
});
|
|
18
|
+
configureS3ObjectStorage({ endpoint: 'http://localhost:10000', accessKey: 'tstdl-dev', secretKey: 'tstdl-dev', bucketPerModule: true });
|
|
19
|
+
await migrateDocumentManagementSchema();
|
|
20
|
+
}
|
|
21
|
+
async function main() {
|
|
22
|
+
const documentManagementService = await injectAsync(DocumentManagementService);
|
|
23
|
+
const collection = await documentManagementService.createCollection();
|
|
24
|
+
const category = await documentManagementService.createCategory({ label: 'Testkategorie' });
|
|
25
|
+
const type = await documentManagementService.createType({ categoryId: category.id, group: null, label: 'Testtyp' });
|
|
26
|
+
const request = await documentManagementService.createDocumentRequest({ typeId: type.id, requiredFilesCount: 1, comment: null, collectionIds: [collection.id] });
|
|
27
|
+
const data = await documentManagementService.loadData([collection.id]);
|
|
28
|
+
console.log(data);
|
|
29
|
+
}
|
|
30
|
+
Application.run({ bootstrap }, main);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { User } from './user.model.js';
|
|
2
2
|
export declare const mySchema: import("../../orm/database-schema.js").DatabaseSchema<"my_application">;
|
|
3
|
-
export declare const user: import("../../orm/
|
|
3
|
+
export declare const user: import("../../orm/drizzle/schema-converter.js").PgTableFromType<"my_application", typeof User>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Entity,
|
|
1
|
+
import { Entity, Integer } from '../../orm/index.js';
|
|
2
2
|
export declare enum Foo {
|
|
3
3
|
Bar = 0,
|
|
4
4
|
Baz = 1
|
|
@@ -10,5 +10,4 @@ export declare class User extends Entity {
|
|
|
10
10
|
age: Integer | null;
|
|
11
11
|
hasAge: boolean;
|
|
12
12
|
mail: string;
|
|
13
|
-
foo: Enum<typeof Foo>;
|
|
14
13
|
}
|
|
@@ -11,6 +11,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
11
11
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
12
|
};
|
|
13
13
|
import * as Http from 'node:http';
|
|
14
|
+
import { Writable } from 'node:stream';
|
|
15
|
+
import { bindNodeCallback, share } from 'rxjs';
|
|
14
16
|
import { CancellationToken } from '../../../cancellation/index.js';
|
|
15
17
|
import { disposeAsync } from '../../../disposable/index.js';
|
|
16
18
|
import { HttpHeaders } from '../../../http/http-headers.js';
|
|
@@ -19,11 +21,9 @@ import { ResolveArg, Singleton } from '../../../injector/index.js';
|
|
|
19
21
|
import { Logger } from '../../../logger/index.js';
|
|
20
22
|
import { encodeUtf8 } from '../../../utils/encoding.js';
|
|
21
23
|
import { FeedableAsyncIterable } from '../../../utils/feedable-async-iterable.js';
|
|
22
|
-
import { getReadableStreamIterable } from '../../../utils/stream/readable-stream-adapter.js';
|
|
23
24
|
import { Timer } from '../../../utils/timer.js';
|
|
24
25
|
import { cancelableTimeout } from '../../../utils/timing.js';
|
|
25
26
|
import { isDefined, isNullOrUndefined, isString } from '../../../utils/type-guards.js';
|
|
26
|
-
import { bindNodeCallback, share } from 'rxjs';
|
|
27
27
|
import { HttpServerRequest } from '../http-server-request.js';
|
|
28
28
|
import { HttpServer } from '../http-server.js';
|
|
29
29
|
let NodeHttpServer = class NodeHttpServer extends HttpServer {
|
|
@@ -167,12 +167,12 @@ async function writeResponseBody(response, httpResponse) {
|
|
|
167
167
|
if (!httpResponse.hasHeader('Content-Length')) {
|
|
168
168
|
httpResponse.setHeader('Content-Length', bytes.byteLength);
|
|
169
169
|
}
|
|
170
|
+
null.getWriter().closed;
|
|
170
171
|
await write(httpResponse, bytes);
|
|
171
172
|
}
|
|
172
173
|
else if (isDefined(streamData)) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
174
|
+
const responseStream = Writable.toWeb(httpResponse);
|
|
175
|
+
await streamData.pipeTo(responseStream);
|
|
176
176
|
}
|
|
177
177
|
return new Promise((resolve) => {
|
|
178
178
|
httpResponse.end(resolve);
|
package/injector/injector.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export declare class Injector implements AsyncDisposable {
|
|
|
49
49
|
* @param provider provider used to resolve the token
|
|
50
50
|
* @param options registration options
|
|
51
51
|
*/
|
|
52
|
-
static registerSingleton<T, A =
|
|
52
|
+
static registerSingleton<T, A = ResolveArgument<T, any>, C extends Record = Record>(token: InjectionToken<T, A>, providers: OneOrMany<Provider<T, A, C>>, options?: TypedOmit<RegistrationOptions<T, A, C>, 'lifecycle'>): void;
|
|
53
53
|
dispose(): Promise<void>;
|
|
54
54
|
[Symbol.asyncDispose](): Promise<void>;
|
|
55
55
|
fork(name: string): Injector;
|
|
@@ -108,3 +108,6 @@ export declare class Injector implements AsyncDisposable {
|
|
|
108
108
|
private getInjectionContext;
|
|
109
109
|
private assertNotDisposed;
|
|
110
110
|
}
|
|
111
|
+
export declare function provide<T = any, A = any, D extends Record = Record>(token: InjectionToken<T, A>, provider: Provider<T, A, D> & {
|
|
112
|
+
multi?: boolean;
|
|
113
|
+
}): ProvidersItem<T, A, D>;
|
package/injector/injector.js
CHANGED
|
@@ -260,7 +260,7 @@ export class Injector {
|
|
|
260
260
|
const { token, providers } = registration;
|
|
261
261
|
const injector = (providers.length > 0) ? this.fork('LocalProvidersInjector') : this;
|
|
262
262
|
for (const nestedProvider of providers) {
|
|
263
|
-
injector.
|
|
263
|
+
injector.registerSingleton(nestedProvider.provide, nestedProvider, { multi: nestedProvider.multi });
|
|
264
264
|
}
|
|
265
265
|
const injectionContext = injector.getInjectionContext(context, argument, chain);
|
|
266
266
|
const previousInjectionContext = setCurrentInjectionContext(injectionContext);
|
|
@@ -442,6 +442,9 @@ export class Injector {
|
|
|
442
442
|
}
|
|
443
443
|
}
|
|
444
444
|
}
|
|
445
|
+
export function provide(token, provider) {
|
|
446
|
+
return { provide: token, ...provider };
|
|
447
|
+
}
|
|
445
448
|
function addRegistration(registrations, registration) {
|
|
446
449
|
if (isClassProvider(registration.provider)) {
|
|
447
450
|
const injectable = reflectionRegistry.getMetadata(registration.provider.useClass)?.data.has(injectableMetadataSymbol) ?? false;
|
package/injector/interfaces.d.ts
CHANGED
|
@@ -4,13 +4,13 @@ import type { AfterResolveContext } from './types.js';
|
|
|
4
4
|
export declare const resolveArgumentType: unique symbol;
|
|
5
5
|
export declare const afterResolve: unique symbol;
|
|
6
6
|
export type ResolveArgumentType = typeof resolveArgumentType;
|
|
7
|
-
export type ResolveArgument<T, Fallback = undefined> = undefined | (T extends Resolvable<infer U> ? U : T extends Type<Resolvable<infer U>> ? U : T extends (ArgumentedInjectionToken<any, any> | ReifyingInjectionToken) ? InjectionTokenArgument<T> : Fallback);
|
|
7
|
+
export type ResolveArgument<T, Fallback = undefined> = undefined | (T extends Resolvable<infer U> ? (U | undefined) : T extends Type<Resolvable<infer U>> ? (U | undefined) : T extends (ArgumentedInjectionToken<any, any> | ReifyingInjectionToken) ? InjectionTokenArgument<T> : Fallback);
|
|
8
8
|
export interface Resolvable<A = unknown, D extends Record = Record> extends Partial<AfterResolve<A, D>> {
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Type of resolve argument
|
|
11
11
|
* @deprecated only used for type inference
|
|
12
12
|
*/
|
|
13
|
-
readonly [resolveArgumentType]
|
|
13
|
+
readonly [resolveArgumentType]?: A;
|
|
14
14
|
}
|
|
15
15
|
export interface AfterResolve<A = unknown, D extends Record = Record> {
|
|
16
16
|
[afterResolve](argument: A, context: AfterResolveContext<D>): void | Promise<void>;
|
package/json-path/json-path.d.ts
CHANGED
|
@@ -14,12 +14,14 @@ export declare class JsonPath<T = any> implements Iterable<JsonPathNode> {
|
|
|
14
14
|
static from(options?: JsonPathOptions): JsonPath;
|
|
15
15
|
static from(path: JsonPathInput, options?: JsonPathOptions): JsonPath;
|
|
16
16
|
static isJsonPath(path: string): boolean;
|
|
17
|
+
toString(): string;
|
|
17
18
|
/**
|
|
18
19
|
* Add a property or index to current path
|
|
19
20
|
* @param key
|
|
20
21
|
* @returns new JsonPath instance
|
|
21
22
|
*/
|
|
22
23
|
add<K extends keyof T>(key: K): JsonPath<T[K]>;
|
|
24
|
+
slice(start: number, end?: number): JsonPath;
|
|
23
25
|
/**
|
|
24
26
|
* Updates options
|
|
25
27
|
* @param options
|
package/json-path/json-path.js
CHANGED
|
@@ -40,6 +40,7 @@ export class JsonPath {
|
|
|
40
40
|
}
|
|
41
41
|
else {
|
|
42
42
|
this._options = pathOrNodesOrOptions;
|
|
43
|
+
this._nodes = [];
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
static from(pathOrNodesOrOptions = [], options = {}) {
|
|
@@ -48,6 +49,9 @@ export class JsonPath {
|
|
|
48
49
|
static isJsonPath(path) {
|
|
49
50
|
return isJsonPath(path);
|
|
50
51
|
}
|
|
52
|
+
toString() {
|
|
53
|
+
return this.path;
|
|
54
|
+
}
|
|
51
55
|
/**
|
|
52
56
|
* Add a property or index to current path
|
|
53
57
|
* @param key
|
|
@@ -56,6 +60,9 @@ export class JsonPath {
|
|
|
56
60
|
add(key) {
|
|
57
61
|
return new JsonPath([...this.nodes, key], this._options);
|
|
58
62
|
}
|
|
63
|
+
slice(start, end) {
|
|
64
|
+
return new JsonPath(this.nodes.slice(start, end), this._options);
|
|
65
|
+
}
|
|
59
66
|
/**
|
|
60
67
|
* Updates options
|
|
61
68
|
* @param options
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import type { Observable } from 'rxjs';
|
|
2
|
-
import type
|
|
3
|
-
import {
|
|
4
|
-
import type { AsyncDisposable } from '../disposable/disposable.js';
|
|
5
|
-
import { disposeAsync } from '../disposable/disposable.js';
|
|
2
|
+
import { type Resolvable, resolveArgumentType } from '../injector/interfaces.js';
|
|
3
|
+
import { type AsyncDisposable, disposeAsync } from '../disposable/disposable.js';
|
|
6
4
|
export type MessageBusArgument = string;
|
|
7
5
|
export declare abstract class MessageBus<T> implements AsyncDisposable, Resolvable<MessageBusArgument> {
|
|
8
6
|
readonly [resolveArgumentType]: string;
|
|
9
|
-
/**
|
|
7
|
+
/** Messages from other instances */
|
|
10
8
|
abstract readonly messages$: Observable<T>;
|
|
11
|
-
/**
|
|
9
|
+
/** Messages from other instances and itself */
|
|
12
10
|
abstract readonly allMessages$: Observable<T>;
|
|
13
11
|
dispose(): Promise<void>;
|
|
14
12
|
abstract publish(message: T): Promise<void>;
|
package/orm/database-schema.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import type { PgEnum } from 'drizzle-orm/pg-core';
|
|
2
|
+
import type { Enumeration, EnumerationValue, UnionToTuple } from '../types.js';
|
|
1
3
|
import { type PgTableFromType } from './drizzle/schema-converter.js';
|
|
2
4
|
import type { EntityType } from './entity.js';
|
|
3
5
|
export declare class DatabaseSchema<Name extends string> {
|
|
4
6
|
readonly name: Name;
|
|
5
7
|
constructor(name: Name);
|
|
6
8
|
getTable<T extends EntityType>(type: T): PgTableFromType<Name, T>;
|
|
9
|
+
getEnum<T extends Enumeration>(enumeration: T, name: string): PgEnum<UnionToTuple<`${EnumerationValue<T>}`> extends [string, ...string[]] ? UnionToTuple<`${EnumerationValue<T>}`> : never>;
|
|
7
10
|
}
|
|
8
11
|
export declare function databaseSchema<Name extends string>(name: Name): DatabaseSchema<Name>;
|
package/orm/database-schema.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { getDrizzleTableFromType } from './drizzle/schema-converter.js';
|
|
1
|
+
import { getDrizzleTableFromType, getPgEnum, registerEnum } from './drizzle/schema-converter.js';
|
|
2
2
|
export class DatabaseSchema {
|
|
3
3
|
name;
|
|
4
4
|
constructor(name) {
|
|
5
5
|
this.name = name;
|
|
6
6
|
}
|
|
7
7
|
getTable(type) {
|
|
8
|
-
return getDrizzleTableFromType(this.name
|
|
8
|
+
return getDrizzleTableFromType(type, this.name);
|
|
9
|
+
}
|
|
10
|
+
getEnum(enumeration, name) {
|
|
11
|
+
registerEnum(enumeration, name);
|
|
12
|
+
return getPgEnum(this.name, enumeration); // eslint-disable-line @typescript-eslint/no-unsafe-return
|
|
9
13
|
}
|
|
10
14
|
}
|
|
11
15
|
export function databaseSchema(name) {
|