@volontariapp/domain-storage 0.1.0 → 0.2.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 +6 -1
- package/dist/enums/entity-type.enum.d.ts +7 -0
- package/dist/enums/entity-type.enum.d.ts.map +1 -0
- package/dist/enums/entity-type.enum.js +8 -0
- package/dist/enums/entity-type.enum.js.map +1 -0
- package/dist/enums/file-status.enum.d.ts +7 -0
- package/dist/enums/file-status.enum.d.ts.map +1 -0
- package/dist/enums/file-status.enum.js +8 -0
- package/dist/enums/file-status.enum.js.map +1 -0
- package/dist/enums/index.d.ts +3 -0
- package/dist/enums/index.d.ts.map +1 -0
- package/dist/enums/index.js +3 -0
- package/dist/enums/index.js.map +1 -0
- package/dist/exceptions/file-not-found.exception.d.ts +5 -0
- package/dist/exceptions/file-not-found.exception.d.ts.map +1 -0
- package/dist/exceptions/file-not-found.exception.js +7 -0
- package/dist/exceptions/file-not-found.exception.js.map +1 -0
- package/dist/exceptions/index.d.ts +3 -0
- package/dist/exceptions/index.d.ts.map +1 -0
- package/dist/exceptions/index.js +3 -0
- package/dist/exceptions/index.js.map +1 -0
- package/dist/exceptions/invalid-file-extension.exception.d.ts +6 -0
- package/dist/exceptions/invalid-file-extension.exception.d.ts.map +1 -0
- package/dist/exceptions/invalid-file-extension.exception.js +10 -0
- package/dist/exceptions/invalid-file-extension.exception.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/test/domain-storage.unit.spec.d.ts +2 -0
- package/dist/test/domain-storage.unit.spec.d.ts.map +1 -0
- package/dist/test/domain-storage.unit.spec.js +89 -0
- package/dist/test/domain-storage.unit.spec.js.map +1 -0
- package/dist/value-objects/file-id.vo.d.ts +9 -0
- package/dist/value-objects/file-id.vo.d.ts.map +1 -0
- package/dist/value-objects/file-id.vo.js +27 -0
- package/dist/value-objects/file-id.vo.js.map +1 -0
- package/dist/value-objects/index.d.ts +4 -0
- package/dist/value-objects/index.d.ts.map +1 -0
- package/dist/value-objects/index.js +4 -0
- package/dist/value-objects/index.js.map +1 -0
- package/dist/value-objects/mime-type.constants.d.ts +6 -0
- package/dist/value-objects/mime-type.constants.d.ts.map +1 -0
- package/dist/value-objects/mime-type.constants.js +14 -0
- package/dist/value-objects/mime-type.constants.js.map +1 -0
- package/dist/value-objects/mime-type.vo.d.ts +9 -0
- package/dist/value-objects/mime-type.vo.d.ts.map +1 -0
- package/dist/value-objects/mime-type.vo.js +36 -0
- package/dist/value-objects/mime-type.vo.js.map +1 -0
- package/package.json +11 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- feat(domain-storage): implement FileStatus & EntityType enums, FileId & MimeType value objects, and domain exceptions
|
|
8
|
+
|
|
3
9
|
All notable changes to this project will be documented in this file.
|
|
4
10
|
|
|
5
11
|
## 0.1.0
|
|
@@ -7,4 +13,3 @@ All notable changes to this project will be documented in this file.
|
|
|
7
13
|
### Minor Changes
|
|
8
14
|
|
|
9
15
|
- Initial package scaffold.
|
|
10
|
-
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-type.enum.d.ts","sourceRoot":"","sources":["../../src/enums/entity-type.enum.ts"],"names":[],"mappings":"AAAA,oBAAY,UAAU;IACpB,IAAI,SAAS;IACb,WAAW,gBAAgB;IAC3B,UAAU,eAAe;IACzB,WAAW,gBAAgB;CAC5B"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export var EntityType;
|
|
2
|
+
(function (EntityType) {
|
|
3
|
+
EntityType["POST"] = "POST";
|
|
4
|
+
EntityType["USER_AVATAR"] = "USER_AVATAR";
|
|
5
|
+
EntityType["BADGE_ICON"] = "BADGE_ICON";
|
|
6
|
+
EntityType["EVENT_COVER"] = "EVENT_COVER";
|
|
7
|
+
})(EntityType || (EntityType = {}));
|
|
8
|
+
//# sourceMappingURL=entity-type.enum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entity-type.enum.js","sourceRoot":"","sources":["../../src/enums/entity-type.enum.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,UAKX;AALD,WAAY,UAAU;IACpB,2BAAa,CAAA;IACb,yCAA2B,CAAA;IAC3B,uCAAyB,CAAA;IACzB,yCAA2B,CAAA;AAC7B,CAAC,EALW,UAAU,KAAV,UAAU,QAKrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-status.enum.d.ts","sourceRoot":"","sources":["../../src/enums/file-status.enum.ts"],"names":[],"mappings":"AAAA,oBAAY,UAAU;IACpB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,QAAQ,aAAa;IACrB,OAAO,YAAY;CACpB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export var FileStatus;
|
|
2
|
+
(function (FileStatus) {
|
|
3
|
+
FileStatus["PENDING"] = "PENDING";
|
|
4
|
+
FileStatus["ATTACHED"] = "ATTACHED";
|
|
5
|
+
FileStatus["ORPHANED"] = "ORPHANED";
|
|
6
|
+
FileStatus["DELETED"] = "DELETED";
|
|
7
|
+
})(FileStatus || (FileStatus = {}));
|
|
8
|
+
//# sourceMappingURL=file-status.enum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-status.enum.js","sourceRoot":"","sources":["../../src/enums/file-status.enum.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,UAKX;AALD,WAAY,UAAU;IACpB,iCAAmB,CAAA;IACnB,mCAAqB,CAAA;IACrB,mCAAqB,CAAA;IACrB,iCAAmB,CAAA;AACrB,CAAC,EALW,UAAU,KAAV,UAAU,QAKrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/enums/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/enums/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-not-found.exception.d.ts","sourceRoot":"","sources":["../../src/exceptions/file-not-found.exception.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,qBAAa,qBAAsB,SAAQ,aAAa;gBAC1C,MAAM,EAAE,MAAM;CAG3B"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NotFoundError } from '@volontariapp/errors';
|
|
2
|
+
export class FileNotFoundException extends NotFoundError {
|
|
3
|
+
constructor(fileId) {
|
|
4
|
+
super(`File with ID '${fileId}' was not found.`, 'FILE_NOT_FOUND', { fileId });
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=file-not-found.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-not-found.exception.js","sourceRoot":"","sources":["../../src/exceptions/file-not-found.exception.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,OAAO,qBAAsB,SAAQ,aAAa;IACtD,YAAY,MAAc;QACxB,KAAK,CAAC,iBAAiB,MAAM,kBAAkB,EAAE,gBAAgB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACjF,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/exceptions/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/exceptions/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { BadRequestError } from '@volontariapp/errors';
|
|
2
|
+
import { EntityType } from '../enums/entity-type.enum.js';
|
|
3
|
+
export declare class InvalidFileExtensionException extends BadRequestError {
|
|
4
|
+
constructor(mimeType: string, entityType?: EntityType | string);
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=invalid-file-extension.exception.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invalid-file-extension.exception.d.ts","sourceRoot":"","sources":["../../src/exceptions/invalid-file-extension.exception.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,qBAAa,6BAA8B,SAAQ,eAAe;gBACpD,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,MAAM;CAO/D"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BadRequestError } from '@volontariapp/errors';
|
|
2
|
+
export class InvalidFileExtensionException extends BadRequestError {
|
|
3
|
+
constructor(mimeType, entityType) {
|
|
4
|
+
const message = entityType
|
|
5
|
+
? `MIME type '${mimeType}' is not allowed for entity type '${entityType}'.`
|
|
6
|
+
: `MIME type '${mimeType}' is not allowed.`;
|
|
7
|
+
super(message, 'INVALID_FILE_EXTENSION', { mimeType, entityType });
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=invalid-file-extension.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invalid-file-extension.exception.js","sourceRoot":"","sources":["../../src/exceptions/invalid-file-extension.exception.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,MAAM,OAAO,6BAA8B,SAAQ,eAAe;IAChE,YAAY,QAAgB,EAAE,UAAgC;QAC5D,MAAM,OAAO,GAAG,UAAU;YACxB,CAAC,CAAC,cAAc,QAAQ,qCAAqC,UAAU,IAAI;YAC3E,CAAC,CAAC,cAAc,QAAQ,mBAAmB,CAAC;QAE9C,KAAK,CAAC,OAAO,EAAE,wBAAwB,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;IACrE,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,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,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":""}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-storage.unit.spec.d.ts","sourceRoot":"","sources":["../../src/test/domain-storage.unit.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { describe, expect, it } from '@jest/globals';
|
|
2
|
+
import { EntityType, FileId, FileNotFoundException, FileStatus, InvalidFileExtensionException, MimeType, COMMON_ALLOWED_MIME_TYPES, GLOBAL_ALLOWED_MIME_TYPES, ALLOWED_MIME_TYPES_BY_ENTITY, } from '../index.js';
|
|
3
|
+
describe('Domain Storage Unit Tests', () => {
|
|
4
|
+
describe('Enums', () => {
|
|
5
|
+
it('should contain expected FileStatus values', () => {
|
|
6
|
+
expect(FileStatus.PENDING).toBe('PENDING');
|
|
7
|
+
expect(FileStatus.ATTACHED).toBe('ATTACHED');
|
|
8
|
+
expect(FileStatus.ORPHANED).toBe('ORPHANED');
|
|
9
|
+
expect(FileStatus.DELETED).toBe('DELETED');
|
|
10
|
+
});
|
|
11
|
+
it('should contain expected EntityType values', () => {
|
|
12
|
+
expect(EntityType.POST).toBe('POST');
|
|
13
|
+
expect(EntityType.USER_AVATAR).toBe('USER_AVATAR');
|
|
14
|
+
expect(EntityType.BADGE_ICON).toBe('BADGE_ICON');
|
|
15
|
+
expect(EntityType.EVENT_COVER).toBe('EVENT_COVER');
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe('FileId Value Object', () => {
|
|
19
|
+
it('should create a valid FileId from UUID v4 string', () => {
|
|
20
|
+
const validUuid = '123e4567-e89b-42d3-a456-426614174000';
|
|
21
|
+
const fileId = FileId.create(validUuid);
|
|
22
|
+
expect(fileId.getValue()).toBe(validUuid);
|
|
23
|
+
});
|
|
24
|
+
it('should generate a valid FileId', () => {
|
|
25
|
+
const fileId = FileId.generate();
|
|
26
|
+
expect(fileId.getValue()).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i);
|
|
27
|
+
});
|
|
28
|
+
it('should throw error for invalid UUID v4 format', () => {
|
|
29
|
+
expect(() => FileId.create('invalid-uuid')).toThrow();
|
|
30
|
+
expect(() => FileId.create('')).toThrow();
|
|
31
|
+
});
|
|
32
|
+
it('should verify equality of FileId instances', () => {
|
|
33
|
+
const uuid = '123e4567-e89b-42d3-a456-426614174000';
|
|
34
|
+
const fileId1 = FileId.create(uuid);
|
|
35
|
+
const fileId2 = FileId.create(uuid);
|
|
36
|
+
const fileId3 = FileId.generate();
|
|
37
|
+
expect(fileId1.equals(fileId2)).toBe(true);
|
|
38
|
+
expect(fileId1.equals(fileId3)).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe('MimeType Value Object & Constants', () => {
|
|
42
|
+
it('should define correct common and entity allowed MIME types', () => {
|
|
43
|
+
expect(COMMON_ALLOWED_MIME_TYPES).toContain('image/jpeg');
|
|
44
|
+
expect(COMMON_ALLOWED_MIME_TYPES).toContain('image/png');
|
|
45
|
+
expect(COMMON_ALLOWED_MIME_TYPES).toContain('image/webp');
|
|
46
|
+
expect(ALLOWED_MIME_TYPES_BY_ENTITY.BADGE_ICON).toContain('image/svg+xml');
|
|
47
|
+
expect(ALLOWED_MIME_TYPES_BY_ENTITY.USER_AVATAR).not.toContain('image/svg+xml');
|
|
48
|
+
expect(GLOBAL_ALLOWED_MIME_TYPES).toContain('image/svg+xml');
|
|
49
|
+
});
|
|
50
|
+
it('should create valid MimeType without entityType', () => {
|
|
51
|
+
const mime = MimeType.create('IMAGE/JPEG ');
|
|
52
|
+
expect(mime.getValue()).toBe('image/jpeg');
|
|
53
|
+
});
|
|
54
|
+
it('should create valid MimeType for entityType', () => {
|
|
55
|
+
const mime = MimeType.create('image/svg+xml', EntityType.BADGE_ICON);
|
|
56
|
+
expect(mime.getValue()).toBe('image/svg+xml');
|
|
57
|
+
});
|
|
58
|
+
it('should throw InvalidFileExtensionException when MIME type is not allowed for entity', () => {
|
|
59
|
+
expect(() => MimeType.create('image/svg+xml', EntityType.USER_AVATAR)).toThrow(InvalidFileExtensionException);
|
|
60
|
+
});
|
|
61
|
+
it('should throw InvalidFileExtensionException for unsupported global MIME type', () => {
|
|
62
|
+
expect(() => MimeType.create('application/exe')).toThrow(InvalidFileExtensionException);
|
|
63
|
+
});
|
|
64
|
+
it('should verify equality of MimeType instances', () => {
|
|
65
|
+
const mime1 = MimeType.create('image/png');
|
|
66
|
+
const mime2 = MimeType.create('IMAGE/PNG');
|
|
67
|
+
const mime3 = MimeType.create('image/webp');
|
|
68
|
+
expect(mime1.equals(mime2)).toBe(true);
|
|
69
|
+
expect(mime1.equals(mime3)).toBe(false);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('Exceptions', () => {
|
|
73
|
+
it('should create FileNotFoundException with correct properties', () => {
|
|
74
|
+
const fileId = '123e4567-e89b-42d3-a456-426614174000';
|
|
75
|
+
const exc = new FileNotFoundException(fileId);
|
|
76
|
+
expect(exc.statusCode).toBe(404);
|
|
77
|
+
expect(exc.code).toBe('FILE_NOT_FOUND');
|
|
78
|
+
expect(exc.message).toContain(fileId);
|
|
79
|
+
});
|
|
80
|
+
it('should create InvalidFileExtensionException with correct properties', () => {
|
|
81
|
+
const exc = new InvalidFileExtensionException('application/x-sh', EntityType.POST);
|
|
82
|
+
expect(exc.statusCode).toBe(400);
|
|
83
|
+
expect(exc.code).toBe('INVALID_FILE_EXTENSION');
|
|
84
|
+
expect(exc.message).toContain('application/x-sh');
|
|
85
|
+
expect(exc.message).toContain('POST');
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=domain-storage.unit.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-storage.unit.spec.js","sourceRoot":"","sources":["../../src/test/domain-storage.unit.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EACL,UAAU,EACV,MAAM,EACN,qBAAqB,EACrB,UAAU,EACV,6BAA6B,EAC7B,QAAQ,EACR,yBAAyB,EACzB,yBAAyB,EACzB,4BAA4B,GAC7B,MAAM,aAAa,CAAC;AAErB,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;QACrB,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3C,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC7C,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC7C,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrC,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACnD,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACjD,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;QACnC,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,SAAS,GAAG,sCAAsC,CAAC;YACzD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;YACjC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAC/B,wEAAwE,CACzE,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YACtD,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,IAAI,GAAG,sCAAsC,CAAC;YACpD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;YAElC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;QACjD,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,MAAM,CAAC,yBAAyB,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YAC1D,MAAM,CAAC,yBAAyB,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YACzD,MAAM,CAAC,yBAAyB,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;YAE1D,MAAM,CAAC,4BAA4B,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;YAC3E,MAAM,CAAC,4BAA4B,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;YAChF,MAAM,CAAC,yBAAyB,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;YACzD,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YAC5C,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;YACrE,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qFAAqF,EAAE,GAAG,EAAE;YAC7F,MAAM,CAAC,GAAG,EAAE,CACV,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,UAAU,CAAC,WAAW,CAAC,CACzD,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;YACrF,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,CACtD,6BAA6B,CAC9B,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAE5C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;YACrE,MAAM,MAAM,GAAG,sCAAsC,CAAC;YACtD,MAAM,GAAG,GAAG,IAAI,qBAAqB,CAAC,MAAM,CAAC,CAAC;YAE9C,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACxC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;YAC7E,MAAM,GAAG,GAAG,IAAI,6BAA6B,CAAC,kBAAkB,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;YAEnF,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YAChD,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;YAClD,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-id.vo.d.ts","sourceRoot":"","sources":["../../src/value-objects/file-id.vo.ts"],"names":[],"mappings":"AAKA,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,OAAO;WAIO,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;WAO1B,QAAQ,IAAI,MAAM;IAIzB,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAMtC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BadRequestError } from '@volontariapp/errors';
|
|
2
|
+
const UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
3
|
+
export class FileId {
|
|
4
|
+
value;
|
|
5
|
+
constructor(value) {
|
|
6
|
+
this.value = value;
|
|
7
|
+
}
|
|
8
|
+
static create(id) {
|
|
9
|
+
if (!id || typeof id !== 'string' || !UUID_V4_REGEX.test(id)) {
|
|
10
|
+
throw new BadRequestError(`Invalid FileId UUID v4 format: '${id}'`, 'INVALID_FILE_ID', { id });
|
|
11
|
+
}
|
|
12
|
+
return new FileId(id);
|
|
13
|
+
}
|
|
14
|
+
static generate() {
|
|
15
|
+
return new FileId(crypto.randomUUID());
|
|
16
|
+
}
|
|
17
|
+
getValue() {
|
|
18
|
+
return this.value;
|
|
19
|
+
}
|
|
20
|
+
equals(other) {
|
|
21
|
+
if (!other || !(other instanceof FileId)) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return this.value === other.getValue();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=file-id.vo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-id.vo.js","sourceRoot":"","sources":["../../src/value-objects/file-id.vo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,aAAa,GACjB,wEAAwE,CAAC;AAE3E,MAAM,OAAO,MAAM;IACA,KAAK,CAAS;IAE/B,YAAoB,KAAa;QAC/B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAEM,MAAM,CAAC,MAAM,CAAC,EAAU;QAC7B,IAAI,CAAC,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,eAAe,CAAC,mCAAmC,EAAE,GAAG,EAAE,iBAAiB,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACjG,CAAC;QACD,OAAO,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAEM,MAAM,CAAC,QAAQ;QACpB,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IACzC,CAAC;IAEM,QAAQ;QACb,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAEM,MAAM,CAAC,KAAa;QACzB,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,YAAY,MAAM,CAAC,EAAE,CAAC;YACzC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,QAAQ,EAAE,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/value-objects/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/value-objects/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { EntityType } from '../enums/entity-type.enum.js';
|
|
2
|
+
export declare const COMMON_ALLOWED_MIME_TYPES: readonly ["image/jpeg", "image/png", "image/webp"];
|
|
3
|
+
export declare const ALLOWED_MIME_TYPES_BY_ENTITY: Record<EntityType, readonly string[]>;
|
|
4
|
+
export declare const GLOBAL_ALLOWED_MIME_TYPES: readonly string[];
|
|
5
|
+
export type AllowedMimeType = (typeof GLOBAL_ALLOWED_MIME_TYPES)[number];
|
|
6
|
+
//# sourceMappingURL=mime-type.constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime-type.constants.d.ts","sourceRoot":"","sources":["../../src/value-objects/mime-type.constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,eAAO,MAAM,yBAAyB,oDAI5B,CAAC;AAEX,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAKrE,CAAC;AAEX,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAEtD,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { EntityType } from '../enums/entity-type.enum.js';
|
|
2
|
+
export const COMMON_ALLOWED_MIME_TYPES = [
|
|
3
|
+
'image/jpeg',
|
|
4
|
+
'image/png',
|
|
5
|
+
'image/webp',
|
|
6
|
+
];
|
|
7
|
+
export const ALLOWED_MIME_TYPES_BY_ENTITY = {
|
|
8
|
+
[EntityType.USER_AVATAR]: [...COMMON_ALLOWED_MIME_TYPES],
|
|
9
|
+
[EntityType.POST]: [...COMMON_ALLOWED_MIME_TYPES],
|
|
10
|
+
[EntityType.EVENT_COVER]: [...COMMON_ALLOWED_MIME_TYPES],
|
|
11
|
+
[EntityType.BADGE_ICON]: [...COMMON_ALLOWED_MIME_TYPES, 'image/svg+xml'],
|
|
12
|
+
};
|
|
13
|
+
export const GLOBAL_ALLOWED_MIME_TYPES = Array.from(new Set(Object.values(ALLOWED_MIME_TYPES_BY_ENTITY).flat()));
|
|
14
|
+
//# sourceMappingURL=mime-type.constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime-type.constants.js","sourceRoot":"","sources":["../../src/value-objects/mime-type.constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE1D,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,YAAY;IACZ,WAAW;IACX,YAAY;CACJ,CAAC;AAEX,MAAM,CAAC,MAAM,4BAA4B,GAA0C;IACjF,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,yBAAyB,CAAC;IACxD,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,yBAAyB,CAAC;IACjD,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,yBAAyB,CAAC;IACxD,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,yBAAyB,EAAE,eAAe,CAAC;CAChE,CAAC;AAEX,MAAM,CAAC,MAAM,yBAAyB,GAAsB,KAAK,CAAC,IAAI,CACpE,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,IAAI,EAAE,CAAC,CAC5D,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EntityType } from '../enums/entity-type.enum.js';
|
|
2
|
+
export declare class MimeType {
|
|
3
|
+
private readonly value;
|
|
4
|
+
private constructor();
|
|
5
|
+
static create(value: string, entityType?: EntityType | string): MimeType;
|
|
6
|
+
getValue(): string;
|
|
7
|
+
equals(other: MimeType): boolean;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=mime-type.vo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime-type.vo.d.ts","sourceRoot":"","sources":["../../src/value-objects/mime-type.vo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAO1D,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,OAAO;WAIO,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ;IAqBxE,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO;CAMxC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { InvalidFileExtensionException } from '../exceptions/invalid-file-extension.exception.js';
|
|
2
|
+
import { ALLOWED_MIME_TYPES_BY_ENTITY, GLOBAL_ALLOWED_MIME_TYPES, } from './mime-type.constants.js';
|
|
3
|
+
export class MimeType {
|
|
4
|
+
value;
|
|
5
|
+
constructor(value) {
|
|
6
|
+
this.value = value.toLowerCase().trim();
|
|
7
|
+
}
|
|
8
|
+
static create(value, entityType) {
|
|
9
|
+
if (!value || typeof value !== 'string') {
|
|
10
|
+
throw new InvalidFileExtensionException(String(value), entityType);
|
|
11
|
+
}
|
|
12
|
+
const normalized = value.toLowerCase().trim();
|
|
13
|
+
if (entityType && entityType in ALLOWED_MIME_TYPES_BY_ENTITY) {
|
|
14
|
+
const allowedForEntity = ALLOWED_MIME_TYPES_BY_ENTITY[entityType];
|
|
15
|
+
if (!allowedForEntity.includes(normalized)) {
|
|
16
|
+
throw new InvalidFileExtensionException(normalized, entityType);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
if (!GLOBAL_ALLOWED_MIME_TYPES.includes(normalized)) {
|
|
21
|
+
throw new InvalidFileExtensionException(normalized, entityType);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return new MimeType(normalized);
|
|
25
|
+
}
|
|
26
|
+
getValue() {
|
|
27
|
+
return this.value;
|
|
28
|
+
}
|
|
29
|
+
equals(other) {
|
|
30
|
+
if (!other || !(other instanceof MimeType)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
return this.value === other.getValue();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=mime-type.vo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime-type.vo.js","sourceRoot":"","sources":["../../src/value-objects/mime-type.vo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,mDAAmD,CAAC;AAClG,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAElC,MAAM,OAAO,QAAQ;IACF,KAAK,CAAS;IAE/B,YAAoB,KAAa;QAC/B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAC1C,CAAC;IAEM,MAAM,CAAC,MAAM,CAAC,KAAa,EAAE,UAAgC;QAClE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,IAAI,6BAA6B,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC;QACrE,CAAC;QAED,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QAE9C,IAAI,UAAU,IAAI,UAAU,IAAI,4BAA4B,EAAE,CAAC;YAC7D,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,UAAwB,CAAC,CAAC;YAChF,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC3C,MAAM,IAAI,6BAA6B,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,yBAAyB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBACpD,MAAM,IAAI,6BAA6B,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QAED,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAEM,QAAQ;QACb,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAEM,MAAM,CAAC,KAAe;QAC3B,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,YAAY,QAAQ,CAAC,EAAE,CAAC;YAC3C,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,QAAQ,EAAE,CAAC;IACzC,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volontariapp/domain-storage",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"provenance": true
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"type": "git",
|
|
10
10
|
"url": "git+https://github.com/Volontariapp/npm-packages.git"
|
|
11
11
|
},
|
|
12
|
-
"description": "",
|
|
12
|
+
"description": "Domain storage definitions, value objects, enums and exceptions for Volontariapp",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"type": "module",
|
|
15
15
|
"main": "./dist/index.js",
|
|
@@ -30,9 +30,17 @@
|
|
|
30
30
|
"prepublishOnly": "yarn build",
|
|
31
31
|
"build": "tsc -p tsconfig.json",
|
|
32
32
|
"lint": "eslint src/",
|
|
33
|
-
"test": "
|
|
33
|
+
"test": "node --experimental-vm-modules ../../node_modules/.bin/jest"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@volontariapp/errors": "0.6.2"
|
|
34
37
|
},
|
|
35
38
|
"devDependencies": {
|
|
39
|
+
"@jest/globals": "^30.3.0",
|
|
40
|
+
"@types/jest": "^30.0.0",
|
|
41
|
+
"@types/node": "^22.10.7",
|
|
42
|
+
"jest": "^30.3.0",
|
|
43
|
+
"ts-jest": "^29.4.6",
|
|
36
44
|
"typescript": "5.7.3"
|
|
37
45
|
}
|
|
38
46
|
}
|