@volontariapp/domain-storage 0.8.0 → 0.9.0
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/CHANGELOG.md +14 -0
- package/dist/entities/file.entity.d.ts +41 -0
- package/dist/entities/file.entity.d.ts.map +1 -0
- package/dist/entities/file.entity.js +73 -0
- package/dist/entities/file.entity.js.map +1 -0
- package/dist/entities/index.d.ts +3 -0
- package/dist/entities/index.d.ts.map +1 -0
- package/dist/entities/index.js +3 -0
- package/dist/entities/index.js.map +1 -0
- package/dist/entities/released-entity.entity.d.ts +12 -0
- package/dist/entities/released-entity.entity.d.ts.map +1 -0
- package/dist/entities/released-entity.entity.js +21 -0
- package/dist/entities/released-entity.entity.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/models/index.d.ts +1 -0
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +3 -0
- package/dist/models/index.js.map +1 -1
- package/dist/models/mapper.d.ts +2 -0
- package/dist/models/mapper.d.ts.map +1 -0
- package/dist/models/mapper.js +12 -0
- package/dist/models/mapper.js.map +1 -0
- package/dist/repositories/file-repository.types.d.ts +2 -10
- package/dist/repositories/file-repository.types.d.ts.map +1 -1
- package/dist/repositories/index.d.ts +1 -0
- package/dist/repositories/index.d.ts.map +1 -1
- package/dist/repositories/index.js +1 -0
- package/dist/repositories/index.js.map +1 -1
- package/dist/repositories/interfaces/file.repository.d.ts +16 -0
- package/dist/repositories/interfaces/file.repository.d.ts.map +1 -0
- package/dist/repositories/interfaces/file.repository.js +2 -0
- package/dist/repositories/interfaces/file.repository.js.map +1 -0
- package/dist/repositories/interfaces/index.d.ts +2 -0
- package/dist/repositories/interfaces/index.d.ts.map +1 -0
- package/dist/repositories/interfaces/index.js +2 -0
- package/dist/repositories/interfaces/index.js.map +1 -0
- package/dist/repositories/postgres-file.repository.d.ts +12 -8
- package/dist/repositories/postgres-file.repository.d.ts.map +1 -1
- package/dist/repositories/postgres-file.repository.js +43 -22
- package/dist/repositories/postgres-file.repository.js.map +1 -1
- package/dist/test/factories/file-entity.factory.d.ts +6 -0
- package/dist/test/factories/file-entity.factory.d.ts.map +1 -0
- package/dist/test/factories/file-entity.factory.js +14 -0
- package/dist/test/factories/file-entity.factory.js.map +1 -0
- package/dist/test/file.entity.unit.spec.d.ts +2 -0
- package/dist/test/file.entity.unit.spec.d.ts.map +1 -0
- package/dist/test/file.entity.unit.spec.js +107 -0
- package/dist/test/file.entity.unit.spec.js.map +1 -0
- package/dist/test/integration/postgres-file.repository.int.spec.js +64 -14
- package/dist/test/integration/postgres-file.repository.int.spec.js.map +1 -1
- package/dist/test/integration/postgres-file.repository.reserve.int.spec.js +2 -1
- package/dist/test/integration/postgres-file.repository.reserve.int.spec.js.map +1 -1
- package/dist/test/mapper.unit.spec.d.ts +2 -0
- package/dist/test/mapper.unit.spec.d.ts.map +1 -0
- package/dist/test/mapper.unit.spec.js +131 -0
- package/dist/test/mapper.unit.spec.js.map +1 -0
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`3ef7b69`](https://github.com/Volontariapp/npm-packages/commit/3ef7b69ced4e5561c5dc6dcbeff8ec219aadbf29) Thanks [@VictorAgahi](https://github.com/VictorAgahi)! - Align the file repository on the `domain-user` pattern.
|
|
8
|
+
|
|
9
|
+
- Add `FileEntity` (pure domain class, exported by the root entry point) whose `FileEntity.create` holds the declaration invariants: allowed MIME type, validation mode resolved from the declared size, quarantine key, and `uploadExpiresAt` computed as creation + presigned URL lifetime + 5 minutes. Add `ReleasedEntityEntity` for the `released_entities` tombstone (used by ticket 1.11).
|
|
10
|
+
- Add `registerStorageMappings()` (sub-path `@volontariapp/domain-storage/models`, also run when that sub-path is imported) mapping `FileEntity`, `ReleasedEntityEntity` and the outbox entities to their models.
|
|
11
|
+
- Add `IFileRepository`, which returns entities. `PostgresFileRepository` now extends `BaseRepository<FileModel, FileEntity>`, is `@Injectable()` and writes `jobs_outbox` / `event_queue` through `JobsOutboxRepository` / `EventQueueRepository` of `@volontariapp/outbox`. Add `findByEntity`; `findById`, `findByIds` come from `BaseRepository`. Transitions (`confirmUpload`, `switchToAsync`, `resetToAwaitingUpload`, `completeScan`, `rejectScan`, `reserve`) stay single conditional `UPDATE ... RETURNING` statements.
|
|
12
|
+
|
|
13
|
+
BREAKING for direct users of the repository (none yet: `ms-storage` does not use it): the constructor takes a `Repository<FileModel>` (`@InjectRepository(FileModel)`) instead of a `DataSource`; `createPending` takes `{ ownerId, entityType, declaredMimeType, declaredSize, presignedUrlTtlSeconds, id?, now? }` (the quarantine key, validation mode and deadline are derived) and returns a `FileEntity`; `reserve` returns `FileEntity[]`. New dependencies: `@nestjs/common`, `@volontariapp/outbox`; dev: `@nestjs/typeorm`.
|
|
14
|
+
|
|
15
|
+
WARNING, unchanged: do not wire `completeScan` / `rejectScan` into `ms-storage` or `worker-storage` yet. `StorageStream` does not exist in `@volontariapp/shared` (ticket 1.14), so `FILE_SCAN_RESULT_TARGET_SERVICES` is still empty: the outbox pusher skips such an `event_queue` row without an error and the event is silently lost.
|
|
16
|
+
|
|
3
17
|
## 0.8.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { EntityType } from '../enums/entity-type.enum.js';
|
|
2
|
+
import { FileStatus } from '../enums/file-status.enum.js';
|
|
3
|
+
import type { RejectionReason } from '../enums/rejection-reason.enum.js';
|
|
4
|
+
import { ScanStatus } from '../enums/scan-status.enum.js';
|
|
5
|
+
import type { ValidationMode } from '../enums/validation-mode.enum.js';
|
|
6
|
+
export declare const UPLOAD_EXPIRY_GRACE_MS: number;
|
|
7
|
+
export interface NewFileData {
|
|
8
|
+
id?: string;
|
|
9
|
+
ownerId: string;
|
|
10
|
+
entityType: EntityType;
|
|
11
|
+
declaredMimeType: string;
|
|
12
|
+
declaredSize: number;
|
|
13
|
+
presignedUrlTtlSeconds: number;
|
|
14
|
+
now?: Date;
|
|
15
|
+
}
|
|
16
|
+
export declare class FileEntity {
|
|
17
|
+
id: string;
|
|
18
|
+
ownerId: string;
|
|
19
|
+
entityType: EntityType;
|
|
20
|
+
entityId: string | null;
|
|
21
|
+
status: FileStatus;
|
|
22
|
+
scanStatus: ScanStatus;
|
|
23
|
+
rejectionReason: RejectionReason | null;
|
|
24
|
+
declaredMimeType: string;
|
|
25
|
+
declaredSize: number;
|
|
26
|
+
actualSize: number | null;
|
|
27
|
+
quarantineKey: string;
|
|
28
|
+
publicKey: string | null;
|
|
29
|
+
scanAttempts: number;
|
|
30
|
+
rescanScheduledAt: Date | null;
|
|
31
|
+
validationMode: ValidationMode;
|
|
32
|
+
uploadExpiresAt: Date;
|
|
33
|
+
confirmedAt: Date | null;
|
|
34
|
+
scannedAt: Date | null;
|
|
35
|
+
reservedAt: Date | null;
|
|
36
|
+
attachedAt: Date | null;
|
|
37
|
+
createdAt: Date;
|
|
38
|
+
updatedAt: Date;
|
|
39
|
+
static create(data: NewFileData): FileEntity;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=file.entity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.entity.d.ts","sourceRoot":"","sources":["../../src/entities/file.entity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAWvE,eAAO,MAAM,sBAAsB,QAAgB,CAAC;AAGpD,MAAM,WAAW,WAAW;IAE1B,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,UAAU,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IAEzB,YAAY,EAAE,MAAM,CAAC;IAErB,sBAAsB,EAAE,MAAM,CAAC;IAE/B,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAWD,qBAAa,UAAU;IACrB,EAAE,EAAG,MAAM,CAAC;IACZ,OAAO,EAAG,MAAM,CAAC;IACjB,UAAU,EAAG,UAAU,CAAC;IACxB,QAAQ,EAAG,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAG,UAAU,CAAC;IACpB,UAAU,EAAG,UAAU,CAAC;IACxB,eAAe,EAAG,eAAe,GAAG,IAAI,CAAC;IACzC,gBAAgB,EAAG,MAAM,CAAC;IAC1B,YAAY,EAAG,MAAM,CAAC;IACtB,UAAU,EAAG,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAG,MAAM,CAAC;IACvB,SAAS,EAAG,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAG,MAAM,CAAC;IACtB,iBAAiB,EAAG,IAAI,GAAG,IAAI,CAAC;IAChC,cAAc,EAAG,cAAc,CAAC;IAChC,eAAe,EAAG,IAAI,CAAC;IACvB,WAAW,EAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAG,IAAI,GAAG,IAAI,CAAC;IACxB,UAAU,EAAG,IAAI,GAAG,IAAI,CAAC;IACzB,UAAU,EAAG,IAAI,GAAG,IAAI,CAAC;IACzB,SAAS,EAAG,IAAI,CAAC;IACjB,SAAS,EAAG,IAAI,CAAC;IAUjB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU;CAgD7C"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { BadRequestError } from '@volontariapp/errors';
|
|
2
|
+
import { FileStatus } from '../enums/file-status.enum.js';
|
|
3
|
+
import { ScanStatus } from '../enums/scan-status.enum.js';
|
|
4
|
+
import { buildQuarantineObjectKey } from '../helpers/object-key.helpers.js';
|
|
5
|
+
import { getValidationPolicy } from '../policies/get-validation-policy.js';
|
|
6
|
+
import { resolveValidationMode } from '../policies/resolve-validation-mode.js';
|
|
7
|
+
import { FileId } from '../value-objects/file-id.vo.js';
|
|
8
|
+
import { MimeType } from '../value-objects/mime-type.vo.js';
|
|
9
|
+
export const UPLOAD_EXPIRY_GRACE_MS = 5 * 60 * 1000;
|
|
10
|
+
export class FileEntity {
|
|
11
|
+
id;
|
|
12
|
+
ownerId;
|
|
13
|
+
entityType;
|
|
14
|
+
entityId;
|
|
15
|
+
status;
|
|
16
|
+
scanStatus;
|
|
17
|
+
rejectionReason;
|
|
18
|
+
declaredMimeType;
|
|
19
|
+
declaredSize;
|
|
20
|
+
actualSize;
|
|
21
|
+
quarantineKey;
|
|
22
|
+
publicKey;
|
|
23
|
+
scanAttempts;
|
|
24
|
+
rescanScheduledAt;
|
|
25
|
+
validationMode;
|
|
26
|
+
uploadExpiresAt;
|
|
27
|
+
confirmedAt;
|
|
28
|
+
scannedAt;
|
|
29
|
+
reservedAt;
|
|
30
|
+
attachedAt;
|
|
31
|
+
createdAt;
|
|
32
|
+
updatedAt;
|
|
33
|
+
static create(data) {
|
|
34
|
+
if (typeof data.ownerId !== 'string' || data.ownerId.trim() === '') {
|
|
35
|
+
throw new BadRequestError('File owner must not be empty', 'INVALID_FILE_OWNER', {
|
|
36
|
+
ownerId: data.ownerId,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (!Number.isFinite(data.presignedUrlTtlSeconds) || data.presignedUrlTtlSeconds <= 0) {
|
|
40
|
+
throw new BadRequestError('Presigned URL lifetime must be a positive number of seconds', 'INVALID_PRESIGNED_URL_TTL', { presignedUrlTtlSeconds: data.presignedUrlTtlSeconds });
|
|
41
|
+
}
|
|
42
|
+
getValidationPolicy(data.entityType);
|
|
43
|
+
const mimeType = MimeType.create(data.declaredMimeType, data.entityType);
|
|
44
|
+
const validationMode = resolveValidationMode(data.entityType, data.declaredSize);
|
|
45
|
+
const id = (data.id === undefined ? FileId.generate() : FileId.create(data.id)).getValue();
|
|
46
|
+
const now = data.now ?? new Date();
|
|
47
|
+
const file = new FileEntity();
|
|
48
|
+
file.id = id;
|
|
49
|
+
file.ownerId = data.ownerId;
|
|
50
|
+
file.entityType = data.entityType;
|
|
51
|
+
file.entityId = null;
|
|
52
|
+
file.status = FileStatus.PENDING;
|
|
53
|
+
file.scanStatus = ScanStatus.AWAITING_UPLOAD;
|
|
54
|
+
file.rejectionReason = null;
|
|
55
|
+
file.declaredMimeType = mimeType.getValue();
|
|
56
|
+
file.declaredSize = data.declaredSize;
|
|
57
|
+
file.actualSize = null;
|
|
58
|
+
file.quarantineKey = buildQuarantineObjectKey(id);
|
|
59
|
+
file.publicKey = null;
|
|
60
|
+
file.scanAttempts = 0;
|
|
61
|
+
file.rescanScheduledAt = null;
|
|
62
|
+
file.validationMode = validationMode;
|
|
63
|
+
file.uploadExpiresAt = new Date(now.getTime() + data.presignedUrlTtlSeconds * 1000 + UPLOAD_EXPIRY_GRACE_MS);
|
|
64
|
+
file.confirmedAt = null;
|
|
65
|
+
file.scannedAt = null;
|
|
66
|
+
file.reservedAt = null;
|
|
67
|
+
file.attachedAt = null;
|
|
68
|
+
file.createdAt = now;
|
|
69
|
+
file.updatedAt = now;
|
|
70
|
+
return file;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=file.entity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.entity.js","sourceRoot":"","sources":["../../src/entities/file.entity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/entities/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/entities/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EntityType } from '../enums/entity-type.enum.js';
|
|
2
|
+
export declare class ReleasedEntityEntity {
|
|
3
|
+
entityType: EntityType;
|
|
4
|
+
entityId: string;
|
|
5
|
+
releasedAt: Date;
|
|
6
|
+
static create(data: {
|
|
7
|
+
entityType: EntityType;
|
|
8
|
+
entityId: string;
|
|
9
|
+
releasedAt?: Date;
|
|
10
|
+
}): ReleasedEntityEntity;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=released-entity.entity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"released-entity.entity.d.ts","sourceRoot":"","sources":["../../src/entities/released-entity.entity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAQ/D,qBAAa,oBAAoB;IAC/B,UAAU,EAAG,UAAU,CAAC;IACxB,QAAQ,EAAG,MAAM,CAAC;IAClB,UAAU,EAAG,IAAI,CAAC;IAGlB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;QAClB,UAAU,EAAE,UAAU,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,IAAI,CAAC;KACnB,GAAG,oBAAoB;CAczB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BadRequestError } from '@volontariapp/errors';
|
|
2
|
+
import { getValidationPolicy } from '../policies/get-validation-policy.js';
|
|
3
|
+
export class ReleasedEntityEntity {
|
|
4
|
+
entityType;
|
|
5
|
+
entityId;
|
|
6
|
+
releasedAt;
|
|
7
|
+
static create(data) {
|
|
8
|
+
getValidationPolicy(data.entityType);
|
|
9
|
+
if (typeof data.entityId !== 'string' || data.entityId.trim() === '') {
|
|
10
|
+
throw new BadRequestError('Released entity id must not be empty', 'INVALID_ENTITY_ID', {
|
|
11
|
+
entityId: data.entityId,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
const released = new ReleasedEntityEntity();
|
|
15
|
+
released.entityType = data.entityType;
|
|
16
|
+
released.entityId = data.entityId;
|
|
17
|
+
released.releasedAt = data.releasedAt ?? new Date();
|
|
18
|
+
return released;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=released-entity.entity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"released-entity.entity.js","sourceRoot":"","sources":["../../src/entities/released-entity.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAO3E,MAAM,OAAO,oBAAoB;IAC/B,UAAU,CAAc;IACxB,QAAQ,CAAU;IAClB,UAAU,CAAQ;IAGlB,MAAM,CAAC,MAAM,CAAC,IAIb;QACC,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrC,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACrE,MAAM,IAAI,eAAe,CAAC,sCAAsC,EAAE,mBAAmB,EAAE;gBACrF,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB,CAAC,CAAC;QACL,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC5C,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACtC,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAClC,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,IAAI,EAAE,CAAC;QACpD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC"}
|
package/dist/models/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAEA,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,aAAa,CAAC"}
|
package/dist/models/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { registerStorageMappings } from './mapper.js';
|
|
1
2
|
export * from './file.model.js';
|
|
2
3
|
export * from './released-entity.model.js';
|
|
3
4
|
export * from './transformers/bigint-number.transformer.js';
|
|
5
|
+
export * from './mapper.js';
|
|
6
|
+
registerStorageMappings();
|
|
4
7
|
//# sourceMappingURL=index.js.map
|
package/dist/models/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6CAA6C,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEtD,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,aAAa,CAAC;AAG5B,uBAAuB,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapper.d.ts","sourceRoot":"","sources":["../../src/models/mapper.ts"],"names":[],"mappings":"AAoBA,wBAAgB,uBAAuB,IAAI,IAAI,CAK9C"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { databaseMapper, EventQueueEntity, EventQueueModel, JobsOutboxEntity, JobsOutboxModel, } from '@volontariapp/database';
|
|
2
|
+
import { FileEntity } from '../entities/file.entity.js';
|
|
3
|
+
import { ReleasedEntityEntity } from '../entities/released-entity.entity.js';
|
|
4
|
+
import { FileModel } from './file.model.js';
|
|
5
|
+
import { ReleasedEntityModel } from './released-entity.model.js';
|
|
6
|
+
export function registerStorageMappings() {
|
|
7
|
+
databaseMapper.registerBidirectional(FileEntity, FileModel);
|
|
8
|
+
databaseMapper.registerBidirectional(ReleasedEntityEntity, ReleasedEntityModel);
|
|
9
|
+
databaseMapper.registerBidirectional(EventQueueEntity, EventQueueModel);
|
|
10
|
+
databaseMapper.registerBidirectional(JobsOutboxEntity, JobsOutboxModel);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapper.js","sourceRoot":"","sources":["../../src/models/mapper.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,GAChB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAUjE,MAAM,UAAU,uBAAuB;IACrC,cAAc,CAAC,qBAAqB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAC5D,cAAc,CAAC,qBAAqB,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,CAAC;IAChF,cAAc,CAAC,qBAAqB,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;IACxE,cAAc,CAAC,qBAAqB,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -1,18 +1,10 @@
|
|
|
1
|
+
import type { NewFileData } from '../entities/file.entity.js';
|
|
1
2
|
import type { EntityType } from '../enums/entity-type.enum.js';
|
|
2
3
|
import type { FileStatus } from '../enums/file-status.enum.js';
|
|
3
4
|
import type { ScanStatus } from '../enums/scan-status.enum.js';
|
|
4
5
|
import type { RejectionReason } from '../enums/rejection-reason.enum.js';
|
|
5
6
|
import type { ValidationMode } from '../enums/validation-mode.enum.js';
|
|
6
|
-
export
|
|
7
|
-
id: string;
|
|
8
|
-
ownerId: string;
|
|
9
|
-
entityType: EntityType;
|
|
10
|
-
declaredMimeType: string;
|
|
11
|
-
declaredSize: number;
|
|
12
|
-
quarantineKey: string;
|
|
13
|
-
validationMode: ValidationMode;
|
|
14
|
-
uploadExpiresAt: Date;
|
|
15
|
-
}
|
|
7
|
+
export type CreatePendingFileInput = NewFileData;
|
|
16
8
|
export interface ConfirmUploadInput {
|
|
17
9
|
fileId: string;
|
|
18
10
|
ownerId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-repository.types.d.ts","sourceRoot":"","sources":["../../src/repositories/file-repository.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"file-repository.types.d.ts","sourceRoot":"","sources":["../../src/repositories/file-repository.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAGvE,MAAM,MAAM,sBAAsB,GAAG,WAAW,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAEhC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IAEjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAGD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,UAAU,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,eAAe,CAAC;CACzB;AAGD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IAEf,MAAM,EAAE,UAAU,CAAC;IAEnB,YAAY,EAAE,OAAO,CAAC;CACvB;AAGD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,UAAU,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repositories/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repositories/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/repositories/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/repositories/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FileEntity } from '../../entities/file.entity.js';
|
|
2
|
+
import type { EntityType } from '../../enums/entity-type.enum.js';
|
|
3
|
+
import type { CompleteScanInput, ConfirmUploadInput, ConfirmUploadResult, CreatePendingFileInput, RejectScanInput, ReserveFilesInput, ScanTransitionResult } from '../file-repository.types.js';
|
|
4
|
+
export interface IFileRepository {
|
|
5
|
+
createPending(input: CreatePendingFileInput): Promise<FileEntity>;
|
|
6
|
+
findById(id: string): Promise<FileEntity | null>;
|
|
7
|
+
findByIds(ids: string[]): Promise<FileEntity[]>;
|
|
8
|
+
findByEntity(entityType: EntityType, entityId: string): Promise<FileEntity[]>;
|
|
9
|
+
confirmUpload(input: ConfirmUploadInput): Promise<ConfirmUploadResult | null>;
|
|
10
|
+
switchToAsync(fileId: string): Promise<boolean>;
|
|
11
|
+
resetToAwaitingUpload(fileId: string): Promise<boolean>;
|
|
12
|
+
completeScan(input: CompleteScanInput): Promise<ScanTransitionResult | null>;
|
|
13
|
+
rejectScan(input: RejectScanInput): Promise<ScanTransitionResult | null>;
|
|
14
|
+
reserve(input: ReserveFilesInput): Promise<FileEntity[]>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=file.repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.repository.d.ts","sourceRoot":"","sources":["../../../src/repositories/interfaces/file.repository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,6BAA6B,CAAC;AASrC,MAAM,WAAW,eAAe;IAE9B,aAAa,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAElE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACjD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAChD,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAG9E,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IAE9E,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhD,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAExD,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;IAE7E,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;IAEzE,OAAO,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;CAC1D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.repository.js","sourceRoot":"","sources":["../../../src/repositories/interfaces/file.repository.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/repositories/interfaces/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/repositories/interfaces/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
|
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
1
|
+
import type { Repository } from '@volontariapp/database';
|
|
2
|
+
import { BaseRepository } from '@volontariapp/database';
|
|
3
|
+
import { FileEntity } from '../entities/file.entity.js';
|
|
4
|
+
import type { EntityType } from '../enums/entity-type.enum.js';
|
|
5
|
+
import { FileModel } from '../models/index.js';
|
|
6
|
+
import type { IFileRepository } from './interfaces/file.repository.js';
|
|
3
7
|
import type { CompleteScanInput, ConfirmUploadInput, ConfirmUploadResult, CreatePendingFileInput, RejectScanInput, ReserveFilesInput, ScanTransitionResult } from './file-repository.types.js';
|
|
4
8
|
export declare const RESET_UPLOAD_DELAY_MINUTES = 15;
|
|
5
|
-
export declare class PostgresFileRepository {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
createPending(input: CreatePendingFileInput): Promise<FileModel>;
|
|
9
|
+
export declare class PostgresFileRepository extends BaseRepository<FileModel, FileEntity> implements IFileRepository {
|
|
10
|
+
constructor(repository: Repository<FileModel>);
|
|
11
|
+
createPending(input: CreatePendingFileInput): Promise<FileEntity>;
|
|
12
|
+
findByEntity(entityType: EntityType, entityId: string): Promise<FileEntity[]>;
|
|
10
13
|
confirmUpload(input: ConfirmUploadInput): Promise<ConfirmUploadResult | null>;
|
|
11
14
|
switchToAsync(fileId: string): Promise<boolean>;
|
|
12
15
|
resetToAwaitingUpload(fileId: string): Promise<boolean>;
|
|
13
|
-
reserve(input: ReserveFilesInput): Promise<
|
|
16
|
+
reserve(input: ReserveFilesInput): Promise<FileEntity[]>;
|
|
14
17
|
completeScan(input: CompleteScanInput): Promise<ScanTransitionResult | null>;
|
|
15
18
|
rejectScan(input: RejectScanInput): Promise<ScanTransitionResult | null>;
|
|
16
19
|
private finishScan;
|
|
17
20
|
private runInTransaction;
|
|
18
21
|
private writeScanJob;
|
|
22
|
+
private eventQueueRepository;
|
|
19
23
|
private logTransition;
|
|
20
24
|
}
|
|
21
25
|
//# sourceMappingURL=postgres-file.repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-file.repository.d.ts","sourceRoot":"","sources":["../../src/repositories/postgres-file.repository.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"postgres-file.repository.d.ts","sourceRoot":"","sources":["../../src/repositories/postgres-file.repository.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAoC,MAAM,wBAAwB,CAAC;AAK1F,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAQ/D,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAS/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EAEf,iBAAiB,EACjB,oBAAoB,EAErB,MAAM,4BAA4B,CAAC;AAGpC,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAoB7C,qBACa,sBACX,SAAQ,cAAc,CAAC,SAAS,EAAE,UAAU,CAC5C,YAAW,eAAe;gBAEe,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC;IAQpE,aAAa,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC;IAUjE,YAAY,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAS7E,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAsC7E,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAyB/C,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA4BvD,OAAO,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IA2FxD,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAoB5E,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAgBhE,UAAU;YAmCV,gBAAgB;YAahB,YAAY;IAW1B,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,aAAa;CAOtB"}
|
|
@@ -1,34 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { Injectable } from '@nestjs/common';
|
|
14
|
+
import { InjectRepository } from '@nestjs/typeorm';
|
|
15
|
+
import { BaseRepository, EventQueueModel, JobsOutboxModel } from '@volontariapp/database';
|
|
16
|
+
import { EventQueueRepository, JobsOutboxRepository } from '@volontariapp/outbox';
|
|
3
17
|
import { In } from 'typeorm';
|
|
18
|
+
import { FileEntity } from '../entities/file.entity.js';
|
|
4
19
|
import { FileStatus } from '../enums/file-status.enum.js';
|
|
5
20
|
import { ScanStatus } from '../enums/scan-status.enum.js';
|
|
6
21
|
import { ValidationMode } from '../enums/validation-mode.enum.js';
|
|
7
22
|
import { FileAttachmentRefusedException } from '../exceptions/file-attachment-refused.exception.js';
|
|
8
23
|
import { FileNotFoundException } from '../exceptions/file-not-found.exception.js';
|
|
9
24
|
import { TooManyFilesException } from '../exceptions/too-many-files.exception.js';
|
|
10
|
-
import { FileModel } from '../models/
|
|
25
|
+
import { FileModel } from '../models/index.js';
|
|
11
26
|
import { classifyFileForAttachment } from '../policies/attachment-validation.rule.js';
|
|
12
27
|
import { getValidationPolicy } from '../policies/get-validation-policy.js';
|
|
13
28
|
import { buildFileRejectedEvent, buildFileScannedEvent, buildScanFileJob, } from './file-outbox.builders.js';
|
|
14
29
|
export const RESET_UPLOAD_DELAY_MINUTES = 15;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
constructor(dataSource) {
|
|
19
|
-
this.dataSource = dataSource;
|
|
30
|
+
let PostgresFileRepository = class PostgresFileRepository extends BaseRepository {
|
|
31
|
+
constructor(repository) {
|
|
32
|
+
super(repository, FileEntity, FileModel);
|
|
20
33
|
}
|
|
21
34
|
async createPending(input) {
|
|
22
|
-
const
|
|
23
|
-
await repository.insert(
|
|
24
|
-
|
|
25
|
-
status: FileStatus.PENDING,
|
|
26
|
-
scanStatus: ScanStatus.AWAITING_UPLOAD,
|
|
27
|
-
});
|
|
28
|
-
const saved = await repository.findOneByOrFail({ id: input.id });
|
|
35
|
+
const file = FileEntity.create(input);
|
|
36
|
+
await this.repository.insert(this.toModel(file));
|
|
37
|
+
const saved = await this.findOneOrFail({ id: file.id });
|
|
29
38
|
this.logger.log(`File ${saved.id} created, awaiting upload (${saved.validationMode})`);
|
|
30
39
|
return saved;
|
|
31
40
|
}
|
|
41
|
+
async findByEntity(entityType, entityId) {
|
|
42
|
+
return this.find({ where: { entityType, entityId }, order: { createdAt: 'ASC', id: 'ASC' } });
|
|
43
|
+
}
|
|
32
44
|
async confirmUpload(input) {
|
|
33
45
|
const result = await this.runInTransaction('confirmUpload', input.fileId, async (manager) => {
|
|
34
46
|
const [rows] = await manager.query(`UPDATE files
|
|
@@ -71,7 +83,7 @@ export class PostgresFileRepository {
|
|
|
71
83
|
return switched;
|
|
72
84
|
}
|
|
73
85
|
async resetToAwaitingUpload(fileId) {
|
|
74
|
-
const [rows] = await this.
|
|
86
|
+
const [rows] = await this.repository.manager.query(`UPDATE files
|
|
75
87
|
SET scan_status = $1,
|
|
76
88
|
upload_expires_at = GREATEST(upload_expires_at, now() + make_interval(mins => $2)),
|
|
77
89
|
updated_at = now()
|
|
@@ -140,14 +152,14 @@ export class PostgresFileRepository {
|
|
|
140
152
|
throw failure;
|
|
141
153
|
}
|
|
142
154
|
this.logger.log(`reserve applied for ${label}: ${String(outcome.files.length)} file(s)`);
|
|
143
|
-
return outcome.files;
|
|
155
|
+
return this.toEntities(outcome.files);
|
|
144
156
|
}
|
|
145
157
|
async completeScan(input) {
|
|
146
158
|
return this.finishScan({
|
|
147
159
|
assignments: `scan_status = $1, public_key = $2, scanned_at = now()`,
|
|
148
160
|
params: [ScanStatus.CLEAN, input.publicKey],
|
|
149
161
|
}, input.fileId, async (manager, row) => {
|
|
150
|
-
await manager.
|
|
162
|
+
await this.eventQueueRepository(manager).create(buildFileScannedEvent(row));
|
|
151
163
|
}, 'completeScan');
|
|
152
164
|
}
|
|
153
165
|
async rejectScan(input) {
|
|
@@ -155,7 +167,7 @@ export class PostgresFileRepository {
|
|
|
155
167
|
assignments: `scan_status = $1, rejection_reason = $2, scanned_at = now()`,
|
|
156
168
|
params: [ScanStatus.REJECTED, input.reason],
|
|
157
169
|
}, input.fileId, async (manager, row) => {
|
|
158
|
-
await manager.
|
|
170
|
+
await this.eventQueueRepository(manager).create(buildFileRejectedEvent(row, input.reason));
|
|
159
171
|
}, 'rejectScan');
|
|
160
172
|
}
|
|
161
173
|
async finishScan(update, fileId, writeEvent, transition) {
|
|
@@ -181,7 +193,7 @@ export class PostgresFileRepository {
|
|
|
181
193
|
}
|
|
182
194
|
async runInTransaction(transition, fileId, work) {
|
|
183
195
|
try {
|
|
184
|
-
return await this.
|
|
196
|
+
return await this.repository.manager.transaction(work);
|
|
185
197
|
}
|
|
186
198
|
catch (error) {
|
|
187
199
|
this.logger.error(`${transition} failed and was rolled back for file ${fileId}`, error);
|
|
@@ -189,7 +201,10 @@ export class PostgresFileRepository {
|
|
|
189
201
|
}
|
|
190
202
|
}
|
|
191
203
|
async writeScanJob(manager, fileId, ownerId) {
|
|
192
|
-
await manager.
|
|
204
|
+
await new JobsOutboxRepository(manager.getRepository(JobsOutboxModel)).create(buildScanFileJob(fileId, ownerId));
|
|
205
|
+
}
|
|
206
|
+
eventQueueRepository(manager) {
|
|
207
|
+
return new EventQueueRepository(manager.getRepository(EventQueueModel));
|
|
193
208
|
}
|
|
194
209
|
logTransition(transition, fileId, applied) {
|
|
195
210
|
if (applied) {
|
|
@@ -199,5 +214,11 @@ export class PostgresFileRepository {
|
|
|
199
214
|
this.logger.warn(`${transition} matched no row for file ${fileId}`);
|
|
200
215
|
}
|
|
201
216
|
}
|
|
202
|
-
}
|
|
217
|
+
};
|
|
218
|
+
PostgresFileRepository = __decorate([
|
|
219
|
+
Injectable(),
|
|
220
|
+
__param(0, InjectRepository(FileModel)),
|
|
221
|
+
__metadata("design:paramtypes", [Function])
|
|
222
|
+
], PostgresFileRepository);
|
|
223
|
+
export { PostgresFileRepository };
|
|
203
224
|
//# sourceMappingURL=postgres-file.repository.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-file.repository.js","sourceRoot":"","sources":["../../src/repositories/postgres-file.repository.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"postgres-file.repository.js","sourceRoot":"","sources":["../../src/repositories/postgres-file.repository.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE1F,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,8BAA8B,EAAE,MAAM,oDAAoD,CAAC;AACpG,OAAO,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAElF,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AAEtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AAenC,MAAM,CAAC,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAqBtC,IAAM,sBAAsB,GAA5B,MAAM,sBACX,SAAQ,cAAqC;IAG7C,YAAyC,UAAiC;QACxE,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IAC3C,CAAC;IAMD,KAAK,CAAC,aAAa,CAAC,KAA6B;QAC/C,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAGtC,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,KAAK,CAAC,EAAE,8BAA8B,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC;QACvF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,UAAsB,EAAE,QAAgB;QACzD,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IAChG,CAAC;IAOD,KAAK,CAAC,aAAa,CAAC,KAAyB;QAC3C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,eAAe,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC1F,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,KAAK,CAGhC;;;;;;iDAMyC,EACzC;gBACE,UAAU,CAAC,QAAQ;gBACnB,KAAK,CAAC,UAAU;gBAChB,KAAK,CAAC,MAAM;gBACZ,KAAK,CAAC,OAAO;gBACb,UAAU,CAAC,eAAe;aAC3B,CACF,CAAC;YACF,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC;YAEtB,IAAI,GAAG,CAAC,eAAe,KAAK,cAAc,CAAC,KAAK,EAAE,CAAC;gBACjD,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;YACzD,CAAC;YACD,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;QACnE,OAAO,MAAM,CAAC;IAChB,CAAC;IAOD,KAAK,CAAC,aAAa,CAAC,MAAc;QAChC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACtF,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,KAAK,CAChC;;;gCAGwB,EACxB,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,QAAQ,EAAE,cAAc,CAAC,IAAI,CAAC,CACzE,CAAC;YACF,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,CAAC,GAAG;gBAAE,OAAO,KAAK,CAAC;YAEvB,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;YACvD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACtD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAOD,KAAK,CAAC,qBAAqB,CAAC,MAAc;QACxC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAChD;;;;;oBAKc,EACd,CAAC,UAAU,CAAC,eAAe,EAAE,0BAA0B,EAAE,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CACtF,CAAC;QAEF,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,aAAa,CAAC,uBAAuB,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3D,OAAO,KAAK,CAAC;IACf,CAAC;IAcD,KAAK,CAAC,OAAO,CAAC,KAAwB;QACpC,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5C,MAAM,EAAE,YAAY,EAAE,GAAG,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC/D,IAAI,OAAO,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;YAClC,MAAM,IAAI,qBAAqB,CAAC,KAAK,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAClF,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAEpC,MAAM,KAAK,GAAG,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACtD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,CACzC,SAAS,EACT,KAAK,EACL,KAAK,EAAE,OAAO,EAAE,EAAE;YAChB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,CAC9B;;;;oBAIU,EACV,CAAC,OAAO,CAAC,CACV,CAAC;YACF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;YAE1D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAA+B,EAAE;gBACnE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAChC,OAAO;oBACL,MAAM;oBACN,yBAAyB,CACvB,GAAG;wBACD,CAAC,CAAC;4BACE,OAAO,EAAE,GAAG,CAAC,QAAQ;4BACrB,UAAU,EAAE,GAAG,CAAC,WAAW;4BAC3B,QAAQ,EAAE,GAAG,CAAC,SAAS;4BACvB,MAAM,EAAE,GAAG,CAAC,MAAM;4BAClB,UAAU,EAAE,GAAG,CAAC,WAAW;yBAC5B;wBACH,CAAC,CAAC,IAAI,EACR,KAAK,CACN;iBACF,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;YAC7E,IAAI,OAAO;gBAAE,OAAO,EAAE,OAAO,EAAE,IAAI,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAEvE,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzC,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC/B,OAAO;wBACL,OAAO,EAAE,IAAI,8BAA8B,CACzC,MAAM,EACN,OAAO,CAAC,MAAM,EACd,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,QAAQ,CACf;qBACF,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,MAAM,SAAS,GAAG,QAAQ;iBACvB,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC;iBACnD,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;YAC7B,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,OAAO,CAAC,KAAK,CACjB;;sDAE0C,EAC1C,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,OAAO,CAAC,CACrE,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5E,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;YAC/D,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QAC5E,CAAC,CACF,CAAC;QAEF,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;YACzB,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,KAAK,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YACrE,MAAM,OAAO,CAAC;QAChB,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,uBAAuB,KAAK,KAAK,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACzF,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAOD,KAAK,CAAC,YAAY,CAAC,KAAwB;QACzC,OAAO,IAAI,CAAC,UAAU,CACpB;YACE,WAAW,EAAE,uDAAuD;YACpE,MAAM,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;SAC5C,EACD,KAAK,CAAC,MAAM,EACZ,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;YACrB,MAAM,IAAI,CAAC,oBAAoB,CAAyC,OAAO,CAAC,CAAC,MAAM,CACrF,qBAAqB,CAAC,GAAG,CAAC,CAC3B,CAAC;QACJ,CAAC,EACD,cAAc,CACf,CAAC;IACJ,CAAC;IAMD,KAAK,CAAC,UAAU,CAAC,KAAsB;QACrC,OAAO,IAAI,CAAC,UAAU,CACpB;YACE,WAAW,EAAE,6DAA6D;YAC1E,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC;SAC5C,EACD,KAAK,CAAC,MAAM,EACZ,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;YACrB,MAAM,IAAI,CAAC,oBAAoB,CAA0C,OAAO,CAAC,CAAC,MAAM,CACtF,sBAAsB,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,CAC1C,CAAC;QACJ,CAAC,EACD,YAAY,CACb,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,UAAU,CACtB,MAA0D,EAC1D,MAAc,EACd,UAA2B,EAC3B,UAAkB;QAElB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC/E,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,KAAK,CAChC;eACO,MAAM,CAAC,WAAW;uBACV,MAAM,CAAC,OAAO,CAAC;gCACN,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;iCAClB,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC,MAAM,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;gEACb,EACxD,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,CACzF,CAAC;YACF,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC;YAEtB,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,QAAQ,CAAC;YACxD,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACjC,CAAC;YACD,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;QACxD,OAAO,MAAM,CAAC;IAChB,CAAC;IAMO,KAAK,CAAC,gBAAgB,CAC5B,UAAkB,EAClB,MAAc,EACd,IAA4C;QAE5C,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,UAAU,wCAAwC,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC;YACxF,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,YAAY,CACxB,OAAsB,EACtB,MAAc,EACd,OAAe;QAEf,MAAM,IAAI,oBAAoB,CAC5B,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,CACvC,CAAC,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9C,CAAC;IAGO,oBAAoB,CAC1B,OAAsB;QAEtB,OAAO,IAAI,oBAAoB,CAAI,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC;IAC7E,CAAC;IAEO,aAAa,CAAC,UAAkB,EAAE,MAAc,EAAE,OAAgB;QACxE,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,oBAAoB,MAAM,EAAE,CAAC,CAAC;QAC7D,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,UAAU,4BAA4B,MAAM,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;CACF,CAAA;AAjUY,sBAAsB;IADlC,UAAU,EAAE;IAKE,WAAA,gBAAgB,CAAC,SAAS,CAAC,CAAA;;GAJ7B,sBAAsB,CAiUlC"}
|