@tstdl/base 0.92.136 → 0.92.138

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/document-management/api/document-management.api.d.ts +10 -4
  2. package/document-management/models/document.model.d.ts +4 -1
  3. package/document-management/models/document.model.js +20 -7
  4. package/document-management/models/index.d.ts +0 -1
  5. package/document-management/models/index.js +0 -1
  6. package/document-management/server/api/document-management.api.js +2 -2
  7. package/document-management/server/schemas.d.ts +1 -2
  8. package/document-management/server/schemas.js +1 -2
  9. package/document-management/server/services/document-file.service.d.ts +10 -7
  10. package/document-management/server/services/document-file.service.js +37 -47
  11. package/document-management/server/services/document-management-ai.service.js +9 -10
  12. package/document-management/server/services/document-management.service.js +2 -8
  13. package/document-management/server/services/document.service.js +22 -13
  14. package/document-management/service-models/document-management.view-model.d.ts +1 -2
  15. package/document-management/service-models/document-management.view-model.js +1 -6
  16. package/document-management/service-models/document.service-model.d.ts +5 -2
  17. package/document-management/service-models/document.service-model.js +2 -2
  18. package/document-management/service-models/enriched/enriched-document-management-data.view.d.ts +0 -1
  19. package/document-management/service-models/enriched/enriched-document-management-data.view.js +0 -1
  20. package/document-management/service-models/enriched/enriched-document.view.d.ts +5 -3
  21. package/document-management/service-models/enriched/enriched-document.view.js +8 -10
  22. package/document-management/service-models/enriched/index.d.ts +0 -1
  23. package/document-management/service-models/enriched/index.js +0 -1
  24. package/orm/sqls.d.ts +8 -6
  25. package/orm/sqls.js +9 -0
  26. package/package.json +2 -2
  27. package/document-management/models/document-file.model.d.ts +0 -7
  28. package/document-management/models/document-file.model.js +0 -38
  29. package/document-management/service-models/enriched/enriched-document-file.view.d.ts +0 -12
  30. package/document-management/service-models/enriched/enriched-document-file.view.js +0 -16
@@ -95,7 +95,7 @@ export declare const documentManagementApiDefinition: {
95
95
  tags?: string[] | null | undefined;
96
96
  comment?: string | null | undefined;
97
97
  approval?: import("../models/document.model.js").DocumentApproval | undefined;
98
- originalFileName: string | null;
98
+ originalFileName?: string | null | undefined;
99
99
  assignment: {
100
100
  collections: string | string[];
101
101
  } | {
@@ -285,15 +285,18 @@ export declare const documentManagementApiDefinition: {
285
285
  parameters: import("../../schema/index.js").ObjectSchema<{
286
286
  id: import("../../orm/types.js").IsPrimaryKey<import("../../orm/types.js").HasDefault<import("../../orm/schemas/uuid.js").Uuid>>;
287
287
  date?: import("../../orm/types.js").NumericDate | null | undefined;
288
+ size?: number | undefined;
289
+ hash?: string | undefined;
288
290
  summary?: string | null | undefined;
289
291
  title?: string | null | undefined;
292
+ mimeType?: string | undefined;
290
293
  typeId?: import("../../orm/types.js").Uuid | null | undefined;
291
294
  subtitle?: string | null | undefined;
292
295
  tags?: string[] | null | undefined;
293
296
  comment?: string | null | undefined;
294
- fileId?: import("../../orm/types.js").Uuid | undefined;
295
297
  pages?: number | null | undefined;
296
298
  approval?: import("../models/document.model.js").DocumentApproval | undefined;
299
+ originalFileName?: string | null | undefined;
297
300
  createUserId?: import("../../orm/types.js").Uuid | null | undefined;
298
301
  properties?: {
299
302
  propertyId: import("../../orm/schemas/uuid.js").Uuid;
@@ -405,7 +408,7 @@ declare const _DocumentManagementApi: import("../../api/client/index.js").ApiCli
405
408
  tags?: string[] | null | undefined;
406
409
  comment?: string | null | undefined;
407
410
  approval?: import("../models/document.model.js").DocumentApproval | undefined;
408
- originalFileName: string | null;
411
+ originalFileName?: string | null | undefined;
409
412
  assignment: {
410
413
  collections: string | string[];
411
414
  } | {
@@ -595,15 +598,18 @@ declare const _DocumentManagementApi: import("../../api/client/index.js").ApiCli
595
598
  parameters: import("../../schema/index.js").ObjectSchema<{
596
599
  id: import("../../orm/types.js").IsPrimaryKey<import("../../orm/types.js").HasDefault<import("../../orm/schemas/uuid.js").Uuid>>;
597
600
  date?: import("../../orm/types.js").NumericDate | null | undefined;
601
+ size?: number | undefined;
602
+ hash?: string | undefined;
598
603
  summary?: string | null | undefined;
599
604
  title?: string | null | undefined;
605
+ mimeType?: string | undefined;
600
606
  typeId?: import("../../orm/types.js").Uuid | null | undefined;
601
607
  subtitle?: string | null | undefined;
602
608
  tags?: string[] | null | undefined;
603
609
  comment?: string | null | undefined;
604
- fileId?: import("../../orm/types.js").Uuid | undefined;
605
610
  pages?: number | null | undefined;
606
611
  approval?: import("../models/document.model.js").DocumentApproval | undefined;
612
+ originalFileName?: string | null | undefined;
607
613
  createUserId?: import("../../orm/types.js").Uuid | null | undefined;
608
614
  properties?: {
609
615
  propertyId: import("../../orm/schemas/uuid.js").Uuid;
@@ -10,7 +10,6 @@ export type DocumentApproval = EnumType<typeof DocumentApproval>;
10
10
  export type UpdatableDocumentProperties = keyof Pick<Document, 'typeId' | 'title' | 'subtitle' | 'date' | 'summary' | 'tags' | 'comment'>;
11
11
  export declare class Document extends Entity {
12
12
  static readonly entityName: 'Document';
13
- fileId: Uuid;
14
13
  typeId: Uuid | null;
15
14
  title: string | null;
16
15
  subtitle: string | null;
@@ -20,5 +19,9 @@ export declare class Document extends Entity {
20
19
  tags: string[] | null;
21
20
  approval: DocumentApproval;
22
21
  comment: string | null;
22
+ originalFileName: string | null;
23
+ mimeType: string;
24
+ hash: string;
25
+ size: number;
23
26
  createUserId: Uuid | null;
24
27
  }
@@ -12,7 +12,6 @@ import { References } from '../../orm/decorators.js';
12
12
  import { Entity } from '../../orm/entity.js';
13
13
  import { NumericDate, Uuid } from '../../orm/types.js';
14
14
  import { Array, Enumeration, Integer, string, StringProperty } from '../../schema/index.js';
15
- import { DocumentFile } from './document-file.model.js';
16
15
  import { DocumentManagementTable } from './document-management-table.js';
17
16
  import { DocumentType } from './document-type.model.js';
18
17
  export const DocumentApproval = defineEnum('DocumentApproval', {
@@ -21,7 +20,6 @@ export const DocumentApproval = defineEnum('DocumentApproval', {
21
20
  Rejected: 'rejected',
22
21
  });
23
22
  let Document = class Document extends Entity {
24
- fileId;
25
23
  typeId;
26
24
  title;
27
25
  subtitle;
@@ -31,13 +29,12 @@ let Document = class Document extends Entity {
31
29
  tags;
32
30
  approval;
33
31
  comment;
32
+ originalFileName;
33
+ mimeType;
34
+ hash;
35
+ size;
34
36
  createUserId;
35
37
  };
36
- __decorate([
37
- Uuid(),
38
- References(() => DocumentFile),
39
- __metadata("design:type", String)
40
- ], Document.prototype, "fileId", void 0);
41
38
  __decorate([
42
39
  Uuid({ nullable: true }),
43
40
  References(() => DocumentType),
@@ -75,6 +72,22 @@ __decorate([
75
72
  StringProperty({ nullable: true }),
76
73
  __metadata("design:type", Object)
77
74
  ], Document.prototype, "comment", void 0);
75
+ __decorate([
76
+ StringProperty({ nullable: true }),
77
+ __metadata("design:type", Object)
78
+ ], Document.prototype, "originalFileName", void 0);
79
+ __decorate([
80
+ StringProperty(),
81
+ __metadata("design:type", String)
82
+ ], Document.prototype, "mimeType", void 0);
83
+ __decorate([
84
+ StringProperty(),
85
+ __metadata("design:type", String)
86
+ ], Document.prototype, "hash", void 0);
87
+ __decorate([
88
+ Integer(),
89
+ __metadata("design:type", Number)
90
+ ], Document.prototype, "size", void 0);
78
91
  __decorate([
79
92
  Uuid({ nullable: true }),
80
93
  __metadata("design:type", Object)
@@ -3,7 +3,6 @@ export * from './document-assignment-task.model.js';
3
3
  export * from './document-category.model.js';
4
4
  export * from './document-collection-assignment.model.js';
5
5
  export * from './document-collection.model.js';
6
- export * from './document-file.model.js';
7
6
  export * from './document-management-table.js';
8
7
  export * from './document-property-value.model.js';
9
8
  export * from './document-property.model.js';
@@ -3,7 +3,6 @@ export * from './document-assignment-task.model.js';
3
3
  export * from './document-category.model.js';
4
4
  export * from './document-collection-assignment.model.js';
5
5
  export * from './document-collection.model.js';
6
- export * from './document-file.model.js';
7
6
  export * from './document-management-table.js';
8
7
  export * from './document-property-value.model.js';
9
8
  export * from './document-property.model.js';
@@ -58,7 +58,7 @@ let DocumentManagementApiController = DocumentManagementApiController_1 = class
58
58
  const token = await context.getToken();
59
59
  const allowed = await this.#documentManagementAncillaryService.canReadDocument(context.parameters.id, token);
60
60
  if (!allowed) {
61
- throw new ForbiddenError(`You are not allowed to load content for file ${context.parameters.id}.`);
61
+ throw new ForbiddenError(`You are not allowed to load content for document ${context.parameters.id}.`);
62
62
  }
63
63
  const url = await this.#documentService.getContentUrl(context.parameters.id, context.parameters.download);
64
64
  return HttpServerResponse.fromObject({
@@ -72,7 +72,7 @@ let DocumentManagementApiController = DocumentManagementApiController_1 = class
72
72
  const token = await context.getToken();
73
73
  const allowed = await this.#documentManagementAncillaryService.canReadDocument(context.parameters.id, token);
74
74
  if (!allowed) {
75
- throw new ForbiddenError(`You are not allowed to get content URL for file ${context.parameters.id}.`);
75
+ throw new ForbiddenError(`You are not allowed to get content URL for document ${context.parameters.id}.`);
76
76
  }
77
77
  return await this.#documentService.getContentUrl(context.parameters.id, context.parameters.download);
78
78
  }
@@ -1,4 +1,4 @@
1
- import { Document, DocumentAssignmentScope, DocumentAssignmentTask, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentFile, DocumentProperty, DocumentPropertyValue, DocumentRequest, DocumentRequestCollectionAssignment, DocumentRequestsTemplate, DocumentRequestSubmission, DocumentRequestTemplate, DocumentType, DocumentTypeProperty, DocumentTypeValidation, DocumentValidationDefinition, DocumentValidationExecution, DocumentValidationExecutionRelatedDocument, DocumentWorkflow } from '../models/index.js';
1
+ import { Document, DocumentAssignmentScope, DocumentAssignmentTask, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentProperty, DocumentPropertyValue, DocumentRequest, DocumentRequestCollectionAssignment, DocumentRequestsTemplate, DocumentRequestSubmission, DocumentRequestTemplate, DocumentType, DocumentTypeProperty, DocumentTypeValidation, DocumentValidationDefinition, DocumentValidationExecution, DocumentValidationExecutionRelatedDocument, DocumentWorkflow } from '../models/index.js';
2
2
  export declare const documentManagementSchema: import("../../orm/server/database-schema.js").DatabaseSchema<"document_management">;
3
3
  export declare const aocumentApproval: import("drizzle-orm/pg-core").PgEnum<["pending", "approved", "rejected"]>;
4
4
  export declare const documentAssignmentCollectionTarget: import("drizzle-orm/pg-core").PgEnum<["request", "collection"]>;
@@ -15,7 +15,6 @@ export declare const documentAssignmentTask: import("../../orm/server/types.js")
15
15
  export declare const documentCategory: import("../../orm/server/types.js").PgTableFromType<typeof DocumentCategory, "document_management">;
16
16
  export declare const documentCollection: import("../../orm/server/types.js").PgTableFromType<typeof DocumentCollection, "document_management">;
17
17
  export declare const documentCollectionAssignment: import("../../orm/server/types.js").PgTableFromType<typeof DocumentCollectionAssignment, "document_management">;
18
- export declare const documentFile: import("../../orm/server/types.js").PgTableFromType<typeof DocumentFile, "document_management">;
19
18
  export declare const documentProperty: import("../../orm/server/types.js").PgTableFromType<typeof DocumentProperty, "document_management">;
20
19
  export declare const documentPropertyValue: import("../../orm/server/types.js").PgTableFromType<typeof DocumentPropertyValue, "document_management">;
21
20
  export declare const documentRequest: import("../../orm/server/types.js").PgTableFromType<typeof DocumentRequest, "document_management">;
@@ -1,5 +1,5 @@
1
1
  import { databaseSchema } from '../../orm/server/database-schema.js';
2
- import { Document, DocumentApproval, DocumentAssignmentScope, DocumentAssignmentTarget, DocumentAssignmentTask, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentFile, DocumentProperty, DocumentPropertyDataType, DocumentPropertyValue, DocumentRequest, DocumentRequestCollectionAssignment, DocumentRequestState, DocumentRequestsTemplate, DocumentRequestSubmission, DocumentRequestTemplate, DocumentType, DocumentTypeProperty, DocumentTypeValidation, DocumentValidationDefinition, DocumentValidationExecution, DocumentValidationExecutionRelatedDocument, DocumentValidationExecutionState, DocumentValidationResultStatus, DocumentWorkflow, DocumentWorkflowFailReason, DocumentWorkflowState, DocumentWorkflowStep } from '../models/index.js';
2
+ import { Document, DocumentApproval, DocumentAssignmentScope, DocumentAssignmentTarget, DocumentAssignmentTask, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentProperty, DocumentPropertyDataType, DocumentPropertyValue, DocumentRequest, DocumentRequestCollectionAssignment, DocumentRequestState, DocumentRequestsTemplate, DocumentRequestSubmission, DocumentRequestTemplate, DocumentType, DocumentTypeProperty, DocumentTypeValidation, DocumentValidationDefinition, DocumentValidationExecution, DocumentValidationExecutionRelatedDocument, DocumentValidationExecutionState, DocumentValidationResultStatus, DocumentWorkflow, DocumentWorkflowFailReason, DocumentWorkflowState, DocumentWorkflowStep } from '../models/index.js';
3
3
  export const documentManagementSchema = databaseSchema('document_management');
4
4
  export const aocumentApproval = documentManagementSchema.getEnum(DocumentApproval);
5
5
  export const documentAssignmentCollectionTarget = documentManagementSchema.getEnum(DocumentAssignmentTarget);
@@ -16,7 +16,6 @@ export const documentAssignmentTask = documentManagementSchema.getTable(Document
16
16
  export const documentCategory = documentManagementSchema.getTable(DocumentCategory);
17
17
  export const documentCollection = documentManagementSchema.getTable(DocumentCollection);
18
18
  export const documentCollectionAssignment = documentManagementSchema.getTable(DocumentCollectionAssignment);
19
- export const documentFile = documentManagementSchema.getTable(DocumentFile);
20
19
  export const documentProperty = documentManagementSchema.getTable(DocumentProperty);
21
20
  export const documentPropertyValue = documentManagementSchema.getTable(DocumentPropertyValue);
22
21
  export const documentRequest = documentManagementSchema.getTable(DocumentRequest);
@@ -1,12 +1,15 @@
1
1
  import type { FileContentPart } from '../../../ai/types.js';
2
2
  import { Transactional } from '../../../orm/server/index.js';
3
- import { DocumentFile } from '../../models/index.js';
3
+ export type DocumentFileMetadata = {
4
+ mimeType: string;
5
+ size: number;
6
+ hash: string;
7
+ };
4
8
  export declare class DocumentFileService extends Transactional {
5
9
  #private;
6
- load(id: string): Promise<DocumentFile>;
7
10
  /**
8
11
  * Initiates a file upload
9
- * @param key - key which can be used to authorize the creation of the file. Same key must be provided to {@link create} method, or it will throw an error.
12
+ * @param key - key which can be used to authorize the creation of the file. Same key must be provided to {@link store} method, or it will throw an error.
10
13
  * The key could be the user id from the request token. This ensures that the file can only be created by the user who initiated the upload.
11
14
  * @returns upload information
12
15
  */
@@ -17,14 +20,14 @@ export declare class DocumentFileService extends Transactional {
17
20
  uploadId: string;
18
21
  uploadUrl: string;
19
22
  }>;
20
- create(content: Uint8Array | ReadableStream<Uint8Array>, originalFileName: string | null): Promise<DocumentFile>;
21
- create(content: {
23
+ store(documentId: string, content: Uint8Array | ReadableStream<Uint8Array>): Promise<DocumentFileMetadata>;
24
+ store(documentId: string, content: {
22
25
  uploadId: string;
23
26
  uploadKey: string;
24
- }, originalFileName: string | null): Promise<[DocumentFile, Uint8Array]>;
27
+ }): Promise<[DocumentFileMetadata, Uint8Array]>;
25
28
  getContent(fileId: string): Promise<Uint8Array>;
26
29
  getContentStream(fileId: string): ReadableStream<Uint8Array>;
27
- getContentUrl(fileId: string, title: string | null, download?: boolean): Promise<string>;
30
+ getContentUrl(documentId: string, title: string | null, download?: boolean): Promise<string>;
28
31
  getPreview(fileId: string, page?: number): Promise<Uint8Array>;
29
32
  getPreviewStream(fileId: string, page?: number): ReadableStream<Uint8Array>;
30
33
  getPreviewUrl(fileId: string, page?: number): Promise<string>;
@@ -78,12 +78,11 @@ import { getRandomString } from '../../../utils/random.js';
78
78
  import { readableStreamFromPromise, readBinaryStream } from '../../../utils/stream/index.js';
79
79
  import { isDefined, isNotReadableStream, isNotUint8Array, isUint8Array } from '../../../utils/type-guards.js';
80
80
  import { millisecondsPerMinute, secondsPerMinute } from '../../../utils/units.js';
81
- import { Document, DocumentFile } from '../../models/index.js';
81
+ import { Document } from '../../models/index.js';
82
82
  import { DocumentManagementConfig } from '../module.js';
83
83
  import { DocumentManagementSingleton } from './singleton.js';
84
84
  let DocumentFileService = DocumentFileService_1 = class DocumentFileService extends Transactional {
85
85
  #config = inject(DocumentManagementConfig);
86
- #documentFileRepository = injectRepository(DocumentFile);
87
86
  #documentRepository = injectRepository(Document);
88
87
  #aiService = inject(AiService);
89
88
  #fileObjectStorage = inject(ObjectStorage, this.#config.fileObjectStorageModule);
@@ -91,12 +90,9 @@ let DocumentFileService = DocumentFileService_1 = class DocumentFileService exte
91
90
  #fileUploadObjectStorage = inject(ObjectStorage, { module: this.#config.fileUploadObjectStorageModule, configuration: { lifecycle: { expiration: { after: 5 * secondsPerMinute } } } });
92
91
  #logger = inject(Logger, DocumentFileService_1.name);
93
92
  #aiFilePartCache = new Map();
94
- async load(id) {
95
- return await this.#documentFileRepository.load(id);
96
- }
97
93
  /**
98
94
  * Initiates a file upload
99
- * @param key - key which can be used to authorize the creation of the file. Same key must be provided to {@link create} method, or it will throw an error.
95
+ * @param key - key which can be used to authorize the creation of the file. Same key must be provided to {@link store} method, or it will throw an error.
100
96
  * The key could be the user id from the request token. This ensures that the file can only be created by the user who initiated the upload.
101
97
  * @returns upload information
102
98
  */
@@ -108,7 +104,7 @@ let DocumentFileService = DocumentFileService_1 = class DocumentFileService exte
108
104
  const url = await this.#fileUploadObjectStorage.getUploadUrl(id, currentTimestamp() + (5 * millisecondsPerMinute), { contentLength, metadata: { 'upload-key': key } });
109
105
  return { uploadId: id, uploadUrl: url };
110
106
  }
111
- async create(content, originalFileName) {
107
+ async store(documentId, content) {
112
108
  const isUpload = isNotUint8Array(content) && isNotReadableStream(content);
113
109
  if (isUpload) {
114
110
  const object = await this.#fileUploadObjectStorage.getObject(content.uploadId);
@@ -127,50 +123,45 @@ let DocumentFileService = DocumentFileService_1 = class DocumentFileService exte
127
123
  : (isUint8Array(content) ? content : await readBinaryStream(content));
128
124
  const hash = await digest('SHA-256', contentAsUint8Array).toHex();
129
125
  const mimeType = await getMimeType(contentAsUint8Array);
130
- return await this.transaction(async (tx) => {
131
- const documentFile = await this.#documentFileRepository
132
- .withTransaction(tx)
133
- .insert({
134
- originalFileName,
135
- mimeType,
136
- hash,
137
- size: contentAsUint8Array.length,
138
- });
139
- const objectKey = getDocumentFileKey(documentFile.id);
140
- if (isUpload) {
141
- await this.#fileUploadObjectStorage.moveObject(content.uploadId, [this.#fileObjectStorage, objectKey]);
142
- return [documentFile, contentAsUint8Array];
143
- }
144
- await this.#fileObjectStorage.uploadObject(objectKey, contentAsUint8Array, { contentLength: contentAsUint8Array.length, contentType: mimeType });
145
- return documentFile;
146
- });
126
+ const metadata = {
127
+ mimeType,
128
+ size: contentAsUint8Array.length,
129
+ hash,
130
+ };
131
+ const objectKey = getObjectKey(documentId);
132
+ if (isUpload) {
133
+ await this.#fileUploadObjectStorage.moveObject(content.uploadId, [this.#fileObjectStorage, objectKey]);
134
+ return [metadata, contentAsUint8Array];
135
+ }
136
+ await this.#fileObjectStorage.uploadObject(objectKey, contentAsUint8Array, { contentLength: contentAsUint8Array.length, contentType: mimeType });
137
+ return metadata;
147
138
  }
148
139
  async getContent(fileId) {
149
- const objectKey = getDocumentFileKey(fileId);
140
+ const objectKey = getObjectKey(fileId);
150
141
  return await this.#fileObjectStorage.getContent(objectKey);
151
142
  }
152
143
  getContentStream(fileId) {
153
- const objectKey = getDocumentFileKey(fileId);
144
+ const objectKey = getObjectKey(fileId);
154
145
  return this.#fileObjectStorage.getContentStream(objectKey);
155
146
  }
156
- async getContentUrl(fileId, title, download = false) {
157
- const file = await this.#documentFileRepository.load(fileId);
158
- return await this.getDocumentFileContentObjectUrl(title ?? fileId, file, download);
147
+ async getContentUrl(documentId, title, download = false) {
148
+ const document = await this.#documentRepository.load(documentId);
149
+ return await this.getDocumentFileContentObjectUrl(document, title ?? documentId, download);
159
150
  }
160
151
  async getPreview(fileId, page = 1) {
161
- const objectKey = getDocumentFileKey(fileId);
152
+ const objectKey = getObjectKey(fileId);
162
153
  await this.createPreviewIfNotExists(fileId, page);
163
154
  return await this.#filePreviewObjectStorage.getContent(objectKey);
164
155
  }
165
156
  getPreviewStream(fileId, page = 1) {
166
157
  return readableStreamFromPromise(async () => {
167
- const objectKey = getDocumentFileKey(fileId);
158
+ const objectKey = getObjectKey(fileId);
168
159
  await this.createPreviewIfNotExists(fileId, page);
169
160
  return this.#filePreviewObjectStorage.getContentStream(objectKey);
170
161
  });
171
162
  }
172
163
  async getPreviewUrl(fileId, page = 1) {
173
- const objectKey = getDocumentFileKey(fileId);
164
+ const objectKey = getObjectKey(fileId);
174
165
  await this.createPreviewIfNotExists(fileId, page);
175
166
  return await this.#filePreviewObjectStorage.getDownloadUrl(objectKey, currentTimestamp() + (5 * millisecondsPerMinute), {
176
167
  'Response-Content-Type': 'image/jpeg',
@@ -180,18 +171,17 @@ let DocumentFileService = DocumentFileService_1 = class DocumentFileService exte
180
171
  const env_1 = { stack: [], error: void 0, hasError: false };
181
172
  try {
182
173
  const document = await this.#documentRepository.load(documentId);
183
- const cachedAiFilePart = this.#aiFilePartCache.get(document.fileId);
174
+ const cachedAiFilePart = this.#aiFilePartCache.get(document.id);
184
175
  if (isDefined(cachedAiFilePart)) {
185
176
  if (cachedAiFilePart.timestamp > (currentTimestamp() - (5 * millisecondsPerMinute))) {
186
177
  return cachedAiFilePart.part;
187
178
  }
188
- this.#aiFilePartCache.delete(documentId);
179
+ this.#aiFilePartCache.delete(document.id);
189
180
  }
190
- const file = await this.load(document.fileId);
191
181
  const fileContentStream = this.getContentStream(document.id);
192
182
  const tmpFile = __addDisposableResource(env_1, await TemporaryFile.from(fileContentStream), true);
193
- const filePart = await this.#aiService.processFile({ path: tmpFile.path, mimeType: file.mimeType });
194
- this.#aiFilePartCache.set(document.fileId, { part: filePart, timestamp: currentTimestamp() });
183
+ const filePart = await this.#aiService.processFile({ path: tmpFile.path, mimeType: document.mimeType });
184
+ this.#aiFilePartCache.set(document.id, { part: filePart, timestamp: currentTimestamp() });
195
185
  return filePart;
196
186
  }
197
187
  catch (e_1) {
@@ -204,13 +194,13 @@ let DocumentFileService = DocumentFileService_1 = class DocumentFileService exte
204
194
  await result_1;
205
195
  }
206
196
  }
207
- async createPreviewIfNotExists(fileId, page = 1) {
208
- const key = getDocumentFileKey(fileId);
197
+ async createPreviewIfNotExists(documentId, page = 1) {
198
+ const key = getObjectKey(documentId);
209
199
  const hasPreview = await this.#filePreviewObjectStorage.exists(key);
210
200
  if (!hasPreview) {
211
- const file = await this.#documentFileRepository.load(fileId);
201
+ const document = await this.#documentRepository.load(documentId);
212
202
  const content = await this.#fileObjectStorage.getContent(key);
213
- const image = await match(file.mimeType)
203
+ const image = await match(document.mimeType)
214
204
  .with('application/pdf', async () => {
215
205
  const imageBytes = await pdfToImage(content, page, 768, 'jpeg');
216
206
  return await imageToPreview(imageBytes);
@@ -220,13 +210,13 @@ let DocumentFileService = DocumentFileService_1 = class DocumentFileService exte
220
210
  await this.#filePreviewObjectStorage.uploadObject(key, image, { contentLength: image.length, contentType: 'image/jpeg' });
221
211
  }
222
212
  }
223
- async getDocumentFileContentObjectUrl(title, file, download) {
224
- const key = getDocumentFileKey(file.id);
225
- const fileExtension = getMimeTypeExtensions(file.mimeType)[0] ?? 'bin';
213
+ async getDocumentFileContentObjectUrl(document, title, download) {
214
+ const key = getObjectKey(document.id);
215
+ const fileExtension = getMimeTypeExtensions(document.mimeType)[0] ?? 'bin';
226
216
  const disposition = download ? 'attachment' : 'inline';
227
217
  const filename = `${title}.${fileExtension}`;
228
218
  return await this.#fileObjectStorage.getDownloadUrl(key, currentTimestamp() + (5 * millisecondsPerMinute), {
229
- 'Response-Content-Type': file.mimeType,
219
+ 'Response-Content-Type': document.mimeType,
230
220
  'Response-Content-Disposition': `${disposition}; filename = "${encodeURIComponent(filename)}"`,
231
221
  });
232
222
  }
@@ -235,8 +225,8 @@ DocumentFileService = DocumentFileService_1 = __decorate([
235
225
  DocumentManagementSingleton()
236
226
  ], DocumentFileService);
237
227
  export { DocumentFileService };
238
- function getDocumentFileKey(id) {
239
- return `${id.slice(0, 2)}/${id.slice(0, 4)}/${id}`;
228
+ function getObjectKey(documentId) {
229
+ return `${documentId.slice(0, 2)}/${documentId.slice(0, 4)}/${documentId}`;
240
230
  }
241
231
  async function imageToPreview(input) {
242
232
  return await sharp(input)
@@ -78,6 +78,7 @@ import { DocumentFileService } from './document-file.service.js';
78
78
  import { DocumentManagementAncillaryService } from './document-management-ancillary.service.js';
79
79
  import { DocumentPropertyService } from './document-property.service.js';
80
80
  import { DocumentManagementSingleton } from './singleton.js';
81
+ const MODEL = 'gemini-2.5-flash-preview-05-20';
81
82
  let DocumentManagementAiService = DocumentManagementAiService_1 = class DocumentManagementAiService {
82
83
  #documentManagementAncillaryService = inject(DocumentManagementAncillaryService);
83
84
  #documentCategoryTypeService = inject(DocumentCategoryTypeService);
@@ -92,16 +93,15 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
92
93
  const env_1 = { stack: [], error: void 0, hasError: false };
93
94
  try {
94
95
  const document = await this.#documentRepository.load(documentId);
95
- const file = await this.#documentFileService.load(document.fileId);
96
- const fileContentStream = this.#documentFileService.getContentStream(document.fileId);
96
+ const fileContentStream = this.#documentFileService.getContentStream(document.id);
97
97
  const tmpFile = __addDisposableResource(env_1, await TemporaryFile.from(fileContentStream), true);
98
- const filePart = await this.#aiService.processFile({ path: tmpFile.path, mimeType: file.mimeType });
98
+ const filePart = await this.#aiService.processFile({ path: tmpFile.path, mimeType: document.mimeType });
99
99
  const categories = await this.#documentCategoryTypeService.loadCategoryViews();
100
100
  const typeLabelEntries = getDescriptiveTypeLabels(categories);
101
101
  const typeLabels = typeLabelEntries.map(({ label }) => label);
102
102
  this.#logger.trace(`Classifying document ${document.id}`);
103
103
  const documentTypeGeneration = await this.#aiService.generate({
104
- model: 'gemini-2.5-flash-preview-04-17',
104
+ model: MODEL,
105
105
  generationOptions: {
106
106
  maxOutputTokens: 128,
107
107
  temperature: 0.1,
@@ -140,10 +140,9 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
140
140
  const env_2 = { stack: [], error: void 0, hasError: false };
141
141
  try {
142
142
  const document = await this.#documentRepository.load(documentId);
143
- const file = await this.#documentFileService.load(document.fileId);
144
- const fileContentStream = this.#documentFileService.getContentStream(document.fileId);
143
+ const fileContentStream = this.#documentFileService.getContentStream(document.id);
145
144
  const tmpFile = __addDisposableResource(env_2, await TemporaryFile.from(fileContentStream), true);
146
- const filePart = await this.#aiService.processFile({ path: tmpFile.path, mimeType: file.mimeType });
145
+ const filePart = await this.#aiService.processFile({ path: tmpFile.path, mimeType: document.mimeType });
147
146
  if (isNull(document.typeId)) {
148
147
  throw new Error(`Document ${document.id} has no type`);
149
148
  }
@@ -172,7 +171,7 @@ let DocumentManagementAiService = DocumentManagementAiService_1 = class Document
172
171
  });
173
172
  this.#logger.trace(`Extracting document ${document.id}`);
174
173
  const { json: extraction } = await this.#aiService.generate({
175
- model: 'gemini-2.5-flash-preview-04-17',
174
+ model: MODEL,
176
175
  generationOptions: {
177
176
  maxOutputTokens: 2048,
178
177
  temperature: 0.2,
@@ -254,7 +253,7 @@ Antworte auf deutsch.`,
254
253
  collections,
255
254
  };
256
255
  const result = await this.#aiService.generate({
257
- model: 'gemini-2.5-flash-preview-04-17',
256
+ model: MODEL,
258
257
  generationOptions: {
259
258
  maxOutputTokens: 100,
260
259
  temperature: 0,
@@ -317,7 +316,7 @@ Ordne das Dokument unter "document" einer oder mehreren passenden Collection unt
317
316
  requests,
318
317
  };
319
318
  const result = await this.#aiService.generate({
320
- model: 'gemini-2.5-flash-preview-04-17',
319
+ model: MODEL,
321
320
  generationOptions: {
322
321
  maxOutputTokens: 100,
323
322
  temperature: 0,
@@ -12,7 +12,7 @@ import { compareByValueSelectionToOrder } from '../../../utils/comparison.js';
12
12
  import { groupToMap, groupToSingleMap } from '../../../utils/iterable-helpers/index.js';
13
13
  import { fromEntries, objectEntries } from '../../../utils/object/index.js';
14
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';
15
+ import { DocumentApproval, DocumentAssignmentScope, DocumentAssignmentTask, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentRequest, DocumentRequestCollectionAssignment, DocumentRequestTemplate, DocumentRequestsTemplate, DocumentType, DocumentValidationExecution, DocumentWorkflowStep } from '../../models/index.js';
16
16
  import { DocumentCategoryTypeService, enumTypeKey } from './document-category-type.service.js';
17
17
  import { DocumentManagementAncillaryService } from './document-management-ancillary.service.js';
18
18
  import { DocumentPropertyService } from './document-property.service.js';
@@ -25,7 +25,6 @@ let DocumentManagementService = class DocumentManagementService extends Transact
25
25
  #documentCollectionRepository = injectRepository(DocumentCollection);
26
26
  #documentCategoryRepository = injectRepository(DocumentCategory);
27
27
  #documentCollectionAssignmentRepository = injectRepository(DocumentCollectionAssignment);
28
- #documentFileRepository = injectRepository(DocumentFile);
29
28
  #documentService = inject(DocumentService);
30
29
  #documentPropertyService = inject(DocumentPropertyService);
31
30
  #documentRequestCollectionAssignmentRepository = injectRepository(DocumentRequestCollectionAssignment);
@@ -62,12 +61,8 @@ let DocumentManagementService = class DocumentManagementService extends Transact
62
61
  this.#documentService.withTransaction(tx).repository.loadManyByQuery({ id: { $in: documentIds } }, { order: { 'metadata.createTimestamp': 'desc' } }),
63
62
  this.#documentPropertyService.withTransaction(tx).loadDocumentProperties(documentIds),
64
63
  ]);
65
- const documentFileIds = documents.map((document) => document.fileId);
66
64
  const workflowRelevantDocumentIds = documents.map((document) => (document.approval == DocumentApproval.Pending) ? document.id : null).filter(isNotNull);
67
- const [files, currentWorkflows] = await Promise.all([
68
- this.#documentFileRepository.withTransaction(tx).loadManyByQuery({ id: { $in: documentFileIds } }, { order: { 'metadata.createTimestamp': 'desc' } }),
69
- this.#documentWorkflowService.loadLatestWorkflows(workflowRelevantDocumentIds),
70
- ]);
65
+ const currentWorkflows = await this.#documentWorkflowService.loadLatestWorkflows(workflowRelevantDocumentIds);
71
66
  const documentWorkflowMap = groupToSingleMap(currentWorkflows, (workflow) => workflow.documentId);
72
67
  const valuesMap = Enumerable.from(propertyValues).groupToMap((value) => value.documentId);
73
68
  const validationWorkflowIds = currentWorkflows.map((workflow) => (workflow.step == DocumentWorkflowStep.Validation) ? workflow.id : null).filter(isNotNull);
@@ -107,7 +102,6 @@ let DocumentManagementService = class DocumentManagementService extends Transact
107
102
  collections: collectionViews,
108
103
  documents: documentViews,
109
104
  requests: requestViews,
110
- files,
111
105
  categories,
112
106
  types,
113
107
  };
@@ -39,24 +39,33 @@ let DocumentService = DocumentService_1 = class DocumentService extends Transact
39
39
  async create({ typeId, title, subtitle, date, summary, tags, approval, comment, originalFileName, assignment, properties, metadata }, contentSource, { createUserId }) {
40
40
  const document = await this.transaction(async (tx) => {
41
41
  const isUpload = isNotUint8Array(contentSource) && isNotReadableStream(contentSource);
42
- const [documentFile, content] = isUpload
43
- ? await this.#documentFileService.withTransaction(tx).create(contentSource, originalFileName)
44
- : [await this.#documentFileService.withTransaction(tx).create(contentSource, originalFileName), contentSource];
45
- const pages = documentFile.mimeType.includes('pdf') ? await tryIgnoreLogAsync(this.#logger, async () => await getPdfPageCount(content), null) : null;
46
42
  const document = await this.repository.withTransaction(tx).insert({
47
- fileId: documentFile.id,
48
43
  typeId: typeId ?? null,
49
44
  title: title ?? null,
50
45
  subtitle: subtitle ?? null,
51
- pages,
46
+ pages: -1,
52
47
  date: date ?? null,
53
48
  summary: summary ?? null,
54
49
  tags: tags ?? null,
55
50
  approval: approval ?? DocumentApproval.Pending,
56
51
  comment: comment ?? null,
57
52
  createUserId: createUserId ?? null,
53
+ originalFileName: originalFileName ?? null,
54
+ mimeType: 'pending',
55
+ hash: 'pending',
56
+ size: -1,
58
57
  metadata,
59
58
  });
59
+ const [documentMetadata, content] = isUpload
60
+ ? await this.#documentFileService.withTransaction(tx).store(document.id, contentSource)
61
+ : [await this.#documentFileService.withTransaction(tx).store(document.id, contentSource), contentSource];
62
+ const pages = documentMetadata.mimeType.includes('pdf') ? await tryIgnoreLogAsync(this.#logger, async () => await getPdfPageCount(content), null) : null;
63
+ await this.repository.withTransaction(tx).update(document.id, {
64
+ mimeType: documentMetadata.mimeType,
65
+ hash: documentMetadata.hash,
66
+ size: documentMetadata.size,
67
+ pages,
68
+ });
60
69
  if (isDefined(properties)) {
61
70
  await this.#documentPropertyService.withTransaction(tx).setPropertyValues(document.id, properties);
62
71
  }
@@ -83,37 +92,37 @@ let DocumentService = DocumentService_1 = class DocumentService extends Transact
83
92
  }
84
93
  async getContent(documentOrId) {
85
94
  const document = isString(documentOrId) ? await this.repository.load(documentOrId) : documentOrId;
86
- return await this.#documentFileService.getContent(document.fileId);
95
+ return await this.#documentFileService.getContent(document.id);
87
96
  }
88
97
  getContentStream(documentOrId) {
89
98
  return readableStreamFromPromise(async () => {
90
99
  const document = isString(documentOrId) ? await this.repository.load(documentOrId) : documentOrId;
91
- return this.#documentFileService.getContentStream(document.fileId);
100
+ return this.#documentFileService.getContentStream(document.id);
92
101
  });
93
102
  }
94
103
  async getContentUrl(documentOrId, download = false) {
95
104
  const document = isString(documentOrId) ? await this.repository.load(documentOrId) : documentOrId;
96
- return await this.#documentFileService.getContentUrl(document.fileId, document.title, download);
105
+ return await this.#documentFileService.getContentUrl(document.id, document.title, download);
97
106
  }
98
107
  async getPreview(documentOrId, page = 1) {
99
108
  const document = isString(documentOrId) ? await this.repository.load(documentOrId) : documentOrId;
100
- return await this.#documentFileService.getPreview(document.fileId, page);
109
+ return await this.#documentFileService.getPreview(document.id, page);
101
110
  }
102
111
  getPreviewStream(documentOrId, page = 1) {
103
112
  return readableStreamFromPromise(async () => {
104
113
  const document = isString(documentOrId) ? await this.repository.load(documentOrId) : documentOrId;
105
- return this.#documentFileService.getPreviewStream(document.fileId, page);
114
+ return this.#documentFileService.getPreviewStream(document.id, page);
106
115
  });
107
116
  }
108
117
  async getPreviewUrl(documentOrId, page = 1) {
109
118
  const document = isString(documentOrId) ? await this.repository.load(documentOrId) : documentOrId;
110
- return await this.#documentFileService.getPreviewUrl(document.fileId, page);
119
+ return await this.#documentFileService.getPreviewUrl(document.id, page);
111
120
  }
112
121
  /**
113
122
  * @returns collectionIds from either direct assignment or automatic assignment scope
114
123
  */
115
124
  async createAssignment(documentId, assignment, transaction) {
116
- return await match(assignment)
125
+ await match(assignment)
117
126
  .with({ collections: P.select() }, async (collectionIds) => {
118
127
  const collectionIdsArray = toArray(collectionIds);
119
128
  await this.#documentCollectionService.withTransaction(transaction).assignDocument(documentId, collectionIdsArray);
@@ -1,5 +1,5 @@
1
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
+ import { Document, DocumentAssignmentTarget, DocumentAssignmentTask, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentPropertyDataType, DocumentRequest, DocumentType, DocumentValidationExecution, DocumentWorkflow } from '../models/index.js';
3
3
  export declare class DocumentCollectionView extends DocumentCollection {
4
4
  name: string;
5
5
  group: string | null;
@@ -37,7 +37,6 @@ export declare class DocumentManagementData {
37
37
  collections: DocumentCollectionView[];
38
38
  documents: DocumentView[];
39
39
  requests: DocumentRequestView[];
40
- files: DocumentFile[];
41
40
  categories: DocumentCategory[];
42
41
  types: DocumentType[];
43
42
  }
@@ -8,7 +8,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
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';
11
+ import { Document, DocumentAssignmentTarget, DocumentAssignmentTask, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentPropertyDataType, DocumentRequest, DocumentType, DocumentValidationExecution, DocumentWorkflow } from '../models/index.js';
12
12
  export class DocumentCollectionView extends DocumentCollection {
13
13
  name;
14
14
  group;
@@ -118,7 +118,6 @@ export class DocumentManagementData {
118
118
  collections;
119
119
  documents;
120
120
  requests;
121
- files;
122
121
  categories;
123
122
  types;
124
123
  }
@@ -134,10 +133,6 @@ __decorate([
134
133
  Array(DocumentRequestView),
135
134
  __metadata("design:type", Array)
136
135
  ], DocumentManagementData.prototype, "requests", void 0);
137
- __decorate([
138
- Array(DocumentFile),
139
- __metadata("design:type", Array)
140
- ], DocumentManagementData.prototype, "files", void 0);
141
136
  __decorate([
142
137
  Array(DocumentCategory),
143
138
  __metadata("design:type", Array)
@@ -23,7 +23,7 @@ export declare const createDocumentParametersSchema: import("../../schema/index.
23
23
  tags?: string[] | null | undefined;
24
24
  comment?: string | null | undefined;
25
25
  approval?: import("../models/document.model.js").DocumentApproval | undefined;
26
- originalFileName: string | null;
26
+ originalFileName?: string | null | undefined;
27
27
  assignment: {
28
28
  collections: string | string[];
29
29
  } | {
@@ -49,15 +49,18 @@ export declare const createDocumentParametersSchema: import("../../schema/index.
49
49
  export declare const updateDocumentParametersSchema: import("../../schema/index.js").ObjectSchema<{
50
50
  id: import("../../orm/types.js").IsPrimaryKey<import("../../orm/types.js").HasDefault<import("../../orm/schemas/uuid.js").Uuid>>;
51
51
  date?: import("../../orm/types.js").NumericDate | null | undefined;
52
+ size?: number | undefined;
53
+ hash?: string | undefined;
52
54
  summary?: string | null | undefined;
53
55
  title?: string | null | undefined;
56
+ mimeType?: string | undefined;
54
57
  typeId?: import("../../orm/types.js").Uuid | null | undefined;
55
58
  subtitle?: string | null | undefined;
56
59
  tags?: string[] | null | undefined;
57
60
  comment?: string | null | undefined;
58
- fileId?: import("../../orm/types.js").Uuid | undefined;
59
61
  pages?: number | null | undefined;
60
62
  approval?: import("../models/document.model.js").DocumentApproval | undefined;
63
+ originalFileName?: string | null | undefined;
61
64
  createUserId?: import("../../orm/types.js").Uuid | null | undefined;
62
65
  properties?: {
63
66
  propertyId: import("../../orm/schemas/uuid.js").Uuid;
@@ -1,10 +1,10 @@
1
1
  import { EntityMetadata } from '../../orm/entity.js';
2
2
  import { array, assign, boolean, enumeration, never, nullable, number, object, omit, oneOrMany, optional, partial, pick, string, union } from '../../schema/index.js';
3
- import { Document, DocumentAssignmentTarget, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentFile, DocumentProperty, DocumentPropertyValue, DocumentRequest, DocumentRequestsTemplate, DocumentRequestTemplate, DocumentType, DocumentTypeProperty } from '../models/index.js';
3
+ import { Document, DocumentAssignmentTarget, DocumentCategory, DocumentCollection, DocumentCollectionAssignment, DocumentProperty, DocumentPropertyValue, DocumentRequest, DocumentRequestsTemplate, DocumentRequestTemplate, DocumentType, DocumentTypeProperty } from '../models/index.js';
4
4
  export const metadataParameterSchema = optional(partial(pick(EntityMetadata, 'attributes')));
5
5
  export const metadataParameterObjectSchema = object({ metadata: metadataParameterSchema });
6
6
  export const setDocumentPropertyParametersSchema = assign(pick(DocumentPropertyValue, ['propertyId']), object({ value: union(string(), number(), boolean(), nullable(never())) }), metadataParameterObjectSchema);
7
- export const createDocumentParametersSchema = assign(partial(pick(Document, ['typeId', 'title', 'subtitle', 'date', 'summary', 'tags', 'approval', 'comment'])), pick(DocumentFile, ['originalFileName']), object({
7
+ export const createDocumentParametersSchema = assign(partial(pick(Document, ['typeId', 'title', 'subtitle', 'date', 'summary', 'tags', 'approval', 'comment', 'originalFileName'])), object({
8
8
  uploadId: string(),
9
9
  assignment: union(object({ collections: oneOrMany(string(), { minimum: 1 }) }), object({ request: string() }), object({
10
10
  automatic: object({
@@ -17,7 +17,6 @@ export declare class EnrichedDocumentManagementData {
17
17
  collections: Map<string, import("../document-management.view-model.js").DocumentCollectionView>;
18
18
  documents: Map<string, import("../document-management.view-model.js").DocumentView>;
19
19
  requests: Map<string, import("../document-management.view-model.js").DocumentRequestView>;
20
- files: Map<string, import("../../index.js").DocumentFile>;
21
20
  categories: Map<string, import("../../index.js").DocumentCategory>;
22
21
  types: Map<string, import("../../index.js").DocumentType>;
23
22
  };
@@ -40,7 +40,6 @@ export class EnrichedDocumentManagementData {
40
40
  collections: () => getEntityMap(this.rawData.collections),
41
41
  documents: () => getEntityMap(this.rawData.documents),
42
42
  requests: () => getEntityMap(this.rawData.requests),
43
- files: () => getEntityMap(this.rawData.files),
44
43
  categories: () => getEntityMap(this.rawData.categories),
45
44
  types: () => getEntityMap(this.rawData.types),
46
45
  });
@@ -2,10 +2,9 @@ import type { TypedOmit } from '../../../types.js';
2
2
  import type { DocumentApproval, DocumentValidationExecution, DocumentWorkflow } from '../../models/index.js';
3
3
  import type { DocumentPropertyValueView, DocumentView } from '../document-management.view-model.js';
4
4
  import { EnrichedDocumentAssignment } from './enriched-document-assignment.view.js';
5
- import { EnrichedDocumentFile } from './enriched-document-file.view.js';
6
5
  import type { EnrichedDocumentManagementData } from './enriched-document-management-data.view.js';
7
6
  import type { EnrichedDocumentType } from './enriched-document-type.view.js';
8
- export declare class EnrichedDocument implements TypedOmit<DocumentView, 'typeId' | 'fileId' | 'assignment' | 'createUserId' | 'metadata'> {
7
+ export declare class EnrichedDocument implements TypedOmit<DocumentView, 'typeId' | 'assignment' | 'createUserId' | 'metadata'> {
9
8
  #private;
10
9
  readonly id: string;
11
10
  readonly title: string | null;
@@ -16,11 +15,14 @@ export declare class EnrichedDocument implements TypedOmit<DocumentView, 'typeId
16
15
  readonly tags: string[] | null;
17
16
  readonly approval: DocumentApproval;
18
17
  readonly comment: string | null;
18
+ readonly originalFileName: string | null;
19
+ readonly mimeType: string;
20
+ readonly hash: string;
21
+ readonly size: number;
19
22
  readonly properties: DocumentPropertyValueView[];
20
23
  readonly currentWorkflow: DocumentWorkflow | null;
21
24
  readonly validations: DocumentValidationExecution[] | null;
22
25
  get type(): EnrichedDocumentType | null;
23
- get file(): EnrichedDocumentFile;
24
26
  get assignments(): EnrichedDocumentAssignment;
25
27
  constructor(data: EnrichedDocumentManagementData, document: DocumentView);
26
28
  }
@@ -10,7 +10,6 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  import { Memoize } from '../../../utils/function/memoize.js';
11
11
  import { assertDefinedPass, isNull } from '../../../utils/type-guards.js';
12
12
  import { EnrichedDocumentAssignment } from './enriched-document-assignment.view.js';
13
- import { EnrichedDocumentFile } from './enriched-document-file.view.js';
14
13
  export class EnrichedDocument {
15
14
  #data;
16
15
  #documentView;
@@ -23,6 +22,10 @@ export class EnrichedDocument {
23
22
  tags;
24
23
  approval;
25
24
  comment;
25
+ originalFileName;
26
+ mimeType;
27
+ hash;
28
+ size;
26
29
  properties;
27
30
  currentWorkflow;
28
31
  validations;
@@ -32,10 +35,6 @@ export class EnrichedDocument {
32
35
  }
33
36
  return assertDefinedPass(this.#data.maps.types.get(this.#documentView.typeId));
34
37
  }
35
- get file() {
36
- const file = assertDefinedPass(this.#data.rawDataMaps.files.get(this.#documentView.fileId));
37
- return new EnrichedDocumentFile(file, this);
38
- }
39
38
  get assignments() {
40
39
  return new EnrichedDocumentAssignment(this.#data, this, this.#documentView.assignment);
41
40
  }
@@ -51,6 +50,10 @@ export class EnrichedDocument {
51
50
  this.tags = document.tags;
52
51
  this.approval = document.approval;
53
52
  this.comment = document.comment;
53
+ this.originalFileName = document.originalFileName;
54
+ this.mimeType = document.mimeType;
55
+ this.hash = document.hash;
56
+ this.size = document.size;
54
57
  this.properties = document.properties;
55
58
  this.currentWorkflow = document.currentWorkflow;
56
59
  this.validations = document.validations;
@@ -61,11 +64,6 @@ __decorate([
61
64
  __metadata("design:type", Object),
62
65
  __metadata("design:paramtypes", [])
63
66
  ], EnrichedDocument.prototype, "type", null);
64
- __decorate([
65
- Memoize(),
66
- __metadata("design:type", EnrichedDocumentFile),
67
- __metadata("design:paramtypes", [])
68
- ], EnrichedDocument.prototype, "file", null);
69
67
  __decorate([
70
68
  Memoize(),
71
69
  __metadata("design:type", EnrichedDocumentAssignment),
@@ -1,7 +1,6 @@
1
1
  export * from './enriched-document-assignment.view.js';
2
2
  export * from './enriched-document-category.view.js';
3
3
  export * from './enriched-document-collection.view.js';
4
- export * from './enriched-document-file.view.js';
5
4
  export * from './enriched-document-management-data.view.js';
6
5
  export * from './enriched-document-request.view.js';
7
6
  export * from './enriched-document-type.view.js';
@@ -1,7 +1,6 @@
1
1
  export * from './enriched-document-assignment.view.js';
2
2
  export * from './enriched-document-category.view.js';
3
3
  export * from './enriched-document-collection.view.js';
4
- export * from './enriched-document-file.view.js';
5
4
  export * from './enriched-document-management-data.view.js';
6
5
  export * from './enriched-document-request.view.js';
7
6
  export * from './enriched-document-type.view.js';
package/orm/sqls.d.ts CHANGED
@@ -1,9 +1,3 @@
1
- /**
2
- * @module
3
- * Provides utility SQL functions and constants for use with Drizzle ORM,
4
- * simplifying common SQL operations like generating UUIDs, working with intervals,
5
- * and aggregating data.
6
- */
7
1
  import { type AnyColumn, type Column, type SQL } from 'drizzle-orm';
8
2
  import type { GetSelectTableSelection, SelectResultField, TableLike } from 'drizzle-orm/query-builders/select.types';
9
3
  import type { Uuid } from './types.js';
@@ -72,3 +66,11 @@ export declare function numNulls(...columns: Column[]): SQL<number>;
72
66
  * @returns A Drizzle SQL object representing the count of non-nulls.
73
67
  */
74
68
  export declare function numNonNulls(...columns: Column[]): SQL<number>;
69
+ export declare function least<T extends (Column | SQL | number)[]>(...values: T): SQL<SelectResultField<{
70
+ [P in keyof T]: T[P] extends number ? Exclude<T[P], number> | SQL<number> : T[P];
71
+ }[number]>>;
72
+ export declare function least<T>(...values: T[]): SQL<SelectResultField<T>>;
73
+ export declare function greatest<T extends (Column | SQL | number)[]>(...values: T): SQL<SelectResultField<{
74
+ [P in keyof T]: T[P] extends number ? Exclude<T[P], number> | SQL<number> : T[P];
75
+ }[number]>>;
76
+ export declare function greatest<T>(...values: T[]): SQL<SelectResultField<T>>;
package/orm/sqls.js CHANGED
@@ -4,6 +4,7 @@
4
4
  * simplifying common SQL operations like generating UUIDs, working with intervals,
5
5
  * and aggregating data.
6
6
  */
7
+ import { isNumber } from '../utils/type-guards.js';
7
8
  import { sql, Table } from 'drizzle-orm';
8
9
  /** Drizzle SQL helper for getting the current transaction's timestamp. Returns a Date object. */
9
10
  export const TRANSACTION_TIMESTAMP = sql `transaction_timestamp()`;
@@ -86,3 +87,11 @@ export function numNulls(...columns) {
86
87
  export function numNonNulls(...columns) {
87
88
  return sql `num_nonnulls(${sql.join(columns, sql.raw(', '))})`;
88
89
  }
90
+ export function least(...values) {
91
+ const sqlValues = values.map((value) => isNumber(value) ? sql.raw(String(value)) : value);
92
+ return sql `least(${sql.join(sqlValues, sql.raw(', '))})`;
93
+ }
94
+ export function greatest(...values) {
95
+ const sqlValues = values.map((value) => isNumber(value) ? sql.raw(String(value)) : value);
96
+ return sql `greatest(${sql.join(sqlValues, sql.raw(', '))})`;
97
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.92.136",
3
+ "version": "0.92.138",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -171,7 +171,7 @@
171
171
  }
172
172
  },
173
173
  "devDependencies": {
174
- "@stylistic/eslint-plugin": "4.2",
174
+ "@stylistic/eslint-plugin": "4.4",
175
175
  "@types/chroma-js": "2.4",
176
176
  "@types/koa__router": "12.0",
177
177
  "@types/luxon": "3.6",
@@ -1,7 +0,0 @@
1
- import { Entity } from '../../orm/entity.js';
2
- export declare class DocumentFile extends Entity {
3
- originalFileName: string | null;
4
- mimeType: string;
5
- hash: string;
6
- size: number;
7
- }
@@ -1,38 +0,0 @@
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
- var __metadata = (this && this.__metadata) || function (k, v) {
8
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
- };
10
- import { Entity } from '../../orm/entity.js';
11
- import { Integer, StringProperty } from '../../schema/index.js';
12
- import { DocumentManagementTable } from './document-management-table.js';
13
- let DocumentFile = class DocumentFile extends Entity {
14
- originalFileName;
15
- mimeType;
16
- hash;
17
- size;
18
- };
19
- __decorate([
20
- StringProperty({ nullable: true }),
21
- __metadata("design:type", Object)
22
- ], DocumentFile.prototype, "originalFileName", void 0);
23
- __decorate([
24
- StringProperty(),
25
- __metadata("design:type", String)
26
- ], DocumentFile.prototype, "mimeType", void 0);
27
- __decorate([
28
- StringProperty(),
29
- __metadata("design:type", String)
30
- ], DocumentFile.prototype, "hash", void 0);
31
- __decorate([
32
- Integer(),
33
- __metadata("design:type", Number)
34
- ], DocumentFile.prototype, "size", void 0);
35
- DocumentFile = __decorate([
36
- DocumentManagementTable()
37
- ], DocumentFile);
38
- export { DocumentFile };
@@ -1,12 +0,0 @@
1
- import type { TypedOmit } from '../../../types.js';
2
- import type { DocumentFile } from '../../models/index.js';
3
- import type { EnrichedDocument } from './enriched-document.view.js';
4
- export declare class EnrichedDocumentFile implements TypedOmit<DocumentFile, 'metadata'> {
5
- readonly id: string;
6
- readonly originalFileName: string | null;
7
- readonly mimeType: string;
8
- readonly hash: string;
9
- readonly size: number;
10
- readonly document: EnrichedDocument;
11
- constructor(file: DocumentFile, document: EnrichedDocument);
12
- }
@@ -1,16 +0,0 @@
1
- export class EnrichedDocumentFile {
2
- id;
3
- originalFileName;
4
- mimeType;
5
- hash;
6
- size;
7
- document;
8
- constructor(file, document) {
9
- this.id = file.id;
10
- this.originalFileName = file.originalFileName;
11
- this.mimeType = file.mimeType;
12
- this.hash = file.hash;
13
- this.size = file.size;
14
- this.document = document;
15
- }
16
- }