@bgord/bun 1.5.1 → 1.5.2
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/dist/basic-auth-password.vo.d.ts +3 -3
- package/dist/basic-auth-password.vo.d.ts.map +1 -1
- package/dist/basic-auth-password.vo.js.map +1 -1
- package/dist/basic-auth-username.vo.d.ts +3 -3
- package/dist/basic-auth-username.vo.d.ts.map +1 -1
- package/dist/basic-auth-username.vo.js.map +1 -1
- package/dist/binary.vo.d.ts +4 -4
- package/dist/binary.vo.d.ts.map +1 -1
- package/dist/binary.vo.js.map +1 -1
- package/dist/crypto-key-provider-file.adapter.d.ts +11 -0
- package/dist/crypto-key-provider-file.adapter.d.ts.map +1 -0
- package/dist/crypto-key-provider-file.adapter.js +19 -0
- package/dist/crypto-key-provider-file.adapter.js.map +1 -0
- package/dist/crypto-key-provider-memory.adapter.d.ts +8 -0
- package/dist/crypto-key-provider-memory.adapter.d.ts.map +1 -0
- package/dist/crypto-key-provider-memory.adapter.js +11 -0
- package/dist/crypto-key-provider-memory.adapter.js.map +1 -0
- package/dist/encryption-bun.adapter.d.ts +3 -0
- package/dist/encryption-bun.adapter.d.ts.map +1 -1
- package/dist/encryption-bun.adapter.js +21 -14
- package/dist/encryption-bun.adapter.js.map +1 -1
- package/dist/encryption-key-value.vo.d.ts +8 -0
- package/dist/encryption-key-value.vo.d.ts.map +1 -0
- package/dist/encryption-key-value.vo.js +12 -0
- package/dist/encryption-key-value.vo.js.map +1 -0
- package/dist/encryption-key.vo.d.ts +13 -5
- package/dist/encryption-key.vo.d.ts.map +1 -1
- package/dist/encryption-key.vo.js +38 -11
- package/dist/encryption-key.vo.js.map +1 -1
- package/dist/encryption-noop.adapter.d.ts +2 -0
- package/dist/encryption-noop.adapter.d.ts.map +1 -1
- package/dist/encryption-noop.adapter.js +5 -1
- package/dist/encryption-noop.adapter.js.map +1 -1
- package/dist/environment-loader-encrypted.adapter.d.ts +22 -0
- package/dist/environment-loader-encrypted.adapter.d.ts.map +1 -0
- package/dist/environment-loader-encrypted.adapter.js +17 -0
- package/dist/environment-loader-encrypted.adapter.js.map +1 -0
- package/dist/environment-loader-process.adapter.d.ts +15 -0
- package/dist/environment-loader-process.adapter.d.ts.map +1 -0
- package/dist/environment-loader-process.adapter.js +16 -0
- package/dist/environment-loader-process.adapter.js.map +1 -0
- package/dist/event-stream.vo.d.ts +3 -3
- package/dist/event-stream.vo.d.ts.map +1 -1
- package/dist/event-stream.vo.js.map +1 -1
- package/dist/hcaptcha-secret-key.vo.d.ts +2 -2
- package/dist/hcaptcha-secret-key.vo.d.ts.map +1 -1
- package/dist/hcaptcha-secret-key.vo.js.map +1 -1
- package/dist/hcaptcha-site-key.vo.d.ts +2 -2
- package/dist/hcaptcha-site-key.vo.d.ts.map +1 -1
- package/dist/hcaptcha-site-key.vo.js +1 -4
- package/dist/hcaptcha-site-key.vo.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/recaptcha-secret-key.vo.d.ts +2 -2
- package/dist/recaptcha-secret-key.vo.d.ts.map +1 -1
- package/dist/recaptcha-secret-key.vo.js.map +1 -1
- package/dist/recaptcha-site-key.vo.d.ts +2 -2
- package/dist/recaptcha-site-key.vo.d.ts.map +1 -1
- package/dist/recaptcha-site-key.vo.js +1 -4
- package/dist/recaptcha-site-key.vo.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/visitor-id.vo.d.ts +3 -3
- package/dist/visitor-id.vo.d.ts.map +1 -1
- package/dist/visitor-id.vo.js.map +1 -1
- package/package.json +8 -6
- package/readme.md +5 -2
- package/src/basic-auth-password.vo.ts +1 -1
- package/src/basic-auth-username.vo.ts +1 -1
- package/src/binary.vo.ts +1 -1
- package/src/crypto-key-provider-file.adapter.ts +28 -0
- package/src/crypto-key-provider-memory.adapter.ts +17 -0
- package/src/encryption-bun.adapter.ts +28 -24
- package/src/encryption-key-value.vo.ts +16 -0
- package/src/encryption-key.vo.ts +43 -12
- package/src/encryption-noop.adapter.ts +3 -1
- package/src/environment-loader-encrypted.adapter.ts +25 -0
- package/src/environment-loader-process.adapter.ts +22 -0
- package/src/event-stream.vo.ts +1 -1
- package/src/hcaptcha-secret-key.vo.ts +1 -1
- package/src/hcaptcha-site-key.vo.ts +1 -4
- package/src/index.ts +5 -2
- package/src/recaptcha-secret-key.vo.ts +1 -1
- package/src/recaptcha-site-key.vo.ts +1 -4
- package/src/visitor-id.vo.ts +1 -1
- package/dist/crypto-key-provider-env.adapter.d.ts +0 -8
- package/dist/crypto-key-provider-env.adapter.d.ts.map +0 -1
- package/dist/crypto-key-provider-env.adapter.js +0 -14
- package/dist/crypto-key-provider-env.adapter.js.map +0 -1
- package/dist/environment-loader-process-env.adapter.d.ts +0 -16
- package/dist/environment-loader-process-env.adapter.d.ts.map +0 -1
- package/dist/environment-loader-process-env.adapter.js +0 -15
- package/dist/environment-loader-process-env.adapter.js.map +0 -1
- package/src/crypto-key-provider-env.adapter.ts +0 -16
- package/src/environment-loader-process-env.adapter.ts +0 -22
package/dist/visitor-id.vo.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { z } from "zod/v4";
|
|
2
2
|
export declare const VisitorIdError: {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Type: string;
|
|
4
|
+
Empty: string;
|
|
5
|
+
TooLong: string;
|
|
6
6
|
};
|
|
7
7
|
export declare const VisitorId: z.core.$ZodBranded<z.ZodString, "VisitorId">;
|
|
8
8
|
export type VisitorIdType = z.infer<typeof VisitorId>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"visitor-id.vo.d.ts","sourceRoot":"","sources":["../src/visitor-id.vo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,eAAO,MAAM,cAAc;;;;
|
|
1
|
+
{"version":3,"file":"visitor-id.vo.d.ts","sourceRoot":"","sources":["../src/visitor-id.vo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,eAAO,MAAM,cAAc;;;;CAI1B,CAAC;AAEF,eAAO,MAAM,SAAS,8CAID,CAAC;AAEtB,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"visitor-id.vo.js","sourceRoot":"","sources":["../src/visitor-id.vo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,iBAAiB;IACvB,KAAK,EAAE,kBAAkB;IACzB,OAAO,EAAE,qBAAqB;
|
|
1
|
+
{"version":3,"file":"visitor-id.vo.js","sourceRoot":"","sources":["../src/visitor-id.vo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,iBAAiB;IACvB,KAAK,EAAE,kBAAkB;IACzB,OAAO,EAAE,qBAAqB;CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC;KACvB,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC;KAC3B,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC;KAC5B,GAAG,CAAC,EAAE,EAAE,cAAc,CAAC,OAAO,CAAC;KAC/B,KAAK,CAAC,WAAW,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bgord/bun",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Bartosz Gordon",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"preinstall": "bunx only-allow bun"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@biomejs/biome": "2.3.
|
|
23
|
+
"@biomejs/biome": "2.3.9",
|
|
24
24
|
"@commitlint/cli": "20.2.0",
|
|
25
25
|
"@commitlint/config-conventional": "20.2.0",
|
|
26
26
|
"@types/bun": "1.3.4",
|
|
@@ -28,21 +28,23 @@
|
|
|
28
28
|
"@types/nodemailer": "7.0.4",
|
|
29
29
|
"@types/yazl": "3.3.0",
|
|
30
30
|
"cspell": "9.4.0",
|
|
31
|
-
"knip": "5.
|
|
31
|
+
"knip": "5.74.0",
|
|
32
32
|
"lefthook": "2.0.12",
|
|
33
|
+
"lockfile-lint": "4.14.1",
|
|
33
34
|
"only-allow": "1.2.2",
|
|
34
35
|
"sharp": "0.34.5",
|
|
35
36
|
"shellcheck": "4.1.0",
|
|
36
37
|
"typescript": "5.9.3",
|
|
37
|
-
"zod": "4.2.
|
|
38
|
+
"zod": "4.2.1"
|
|
38
39
|
},
|
|
39
40
|
"dependencies": {
|
|
40
41
|
"@axiomhq/winston": "1.3.1",
|
|
41
42
|
"@bgord/tools": "1.2.1",
|
|
42
|
-
"@hono/ua-blocker": "0.1.
|
|
43
|
+
"@hono/ua-blocker": "0.1.22",
|
|
43
44
|
"better-auth": "1.4.7",
|
|
44
45
|
"croner": "9.1.0",
|
|
45
46
|
"csv": "6.4.1",
|
|
47
|
+
"dotenv": "17.2.3",
|
|
46
48
|
"hcaptcha": "0.2.0",
|
|
47
49
|
"hono": "4.11.1",
|
|
48
50
|
"isomorphic-dompurify": "2.34.0",
|
|
@@ -54,7 +56,7 @@
|
|
|
54
56
|
"yazl": "3.3.1"
|
|
55
57
|
},
|
|
56
58
|
"peerDependencies": {
|
|
57
|
-
"zod": "4.2.
|
|
59
|
+
"zod": "4.2.1",
|
|
58
60
|
"sharp": "0.34.5"
|
|
59
61
|
},
|
|
60
62
|
"peerDependenciesMeta": {
|
package/readme.md
CHANGED
|
@@ -56,7 +56,8 @@ src/
|
|
|
56
56
|
├── context.middleware.ts
|
|
57
57
|
├── correlation-id.vo.ts
|
|
58
58
|
├── correlation-storage.service.ts
|
|
59
|
-
├── crypto-key-provider-
|
|
59
|
+
├── crypto-key-provider-file.adapter.ts
|
|
60
|
+
├── crypto-key-provider-memory.adapter.ts
|
|
60
61
|
├── crypto-key-provider-noop.adapter.ts
|
|
61
62
|
├── crypto-key-provider.port.ts
|
|
62
63
|
├── csv-stringifier.adapter.ts
|
|
@@ -68,10 +69,12 @@ src/
|
|
|
68
69
|
├── dispatching-event-store.ts
|
|
69
70
|
├── encryption-bun.adapter.ts
|
|
70
71
|
├── encryption-iv.vo.ts
|
|
72
|
+
├── encryption-key-value.vo.ts
|
|
71
73
|
├── encryption-key.vo.ts
|
|
72
74
|
├── encryption-noop.adapter.ts
|
|
73
75
|
├── encryption.port.ts
|
|
74
|
-
├── environment-loader-
|
|
76
|
+
├── environment-loader-encrypted.adapter.ts
|
|
77
|
+
├── environment-loader-process.adapter.ts
|
|
75
78
|
├── environment-loader.port.ts
|
|
76
79
|
├── etag-extractor.middleware.ts
|
|
77
80
|
├── event-bus-like.types.ts
|
package/src/binary.vo.ts
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import type { CryptoKeyProviderPort } from "./crypto-key-provider.port";
|
|
3
|
+
import { EncryptionKey } from "./encryption-key.vo";
|
|
4
|
+
|
|
5
|
+
export const CryptoKeyProviderFileAdapterError = {
|
|
6
|
+
MissingFile: "crypto.key.provider.file.adapter.missing.file",
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export class CryptoKeyProviderFileAdapter implements CryptoKeyProviderPort {
|
|
10
|
+
constructor(private readonly path: tools.FilePathAbsolute) {}
|
|
11
|
+
|
|
12
|
+
async get() {
|
|
13
|
+
const file = Bun.file(this.path.get());
|
|
14
|
+
const exists = await file.exists();
|
|
15
|
+
|
|
16
|
+
if (!exists) throw new Error(CryptoKeyProviderFileAdapterError.MissingFile);
|
|
17
|
+
|
|
18
|
+
const encryptionKey = EncryptionKey.fromString(await file.text());
|
|
19
|
+
|
|
20
|
+
return crypto.subtle.importKey(
|
|
21
|
+
"raw",
|
|
22
|
+
encryptionKey.toBuffer() as BufferSource,
|
|
23
|
+
{ name: "AES-GCM" },
|
|
24
|
+
false,
|
|
25
|
+
["encrypt", "decrypt"],
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CryptoKeyProviderPort } from "./crypto-key-provider.port";
|
|
2
|
+
import { EncryptionKey } from "./encryption-key.vo";
|
|
3
|
+
import type { EncryptionKeyValueType } from "./encryption-key-value.vo";
|
|
4
|
+
|
|
5
|
+
export class CryptoKeyProviderMemoryAdapter implements CryptoKeyProviderPort {
|
|
6
|
+
constructor(private readonly ENCRYPTION_KEY_VALUE: EncryptionKeyValueType) {}
|
|
7
|
+
|
|
8
|
+
async get(): Promise<CryptoKey> {
|
|
9
|
+
return crypto.subtle.importKey(
|
|
10
|
+
"raw",
|
|
11
|
+
EncryptionKey.fromString(this.ENCRYPTION_KEY_VALUE).toBuffer() as BufferSource,
|
|
12
|
+
{ name: "AES-GCM" },
|
|
13
|
+
false,
|
|
14
|
+
["encrypt", "decrypt"],
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -3,26 +3,35 @@ import type { CryptoKeyProviderPort } from "./crypto-key-provider.port";
|
|
|
3
3
|
import type { EncryptionPort, EncryptionRecipe } from "./encryption.port";
|
|
4
4
|
import { EncryptionIV } from "./encryption-iv.vo";
|
|
5
5
|
|
|
6
|
-
export const EncryptionBunAdapterError = {
|
|
6
|
+
export const EncryptionBunAdapterError = {
|
|
7
|
+
InvalidPayload: "encryption.bun.adapter.invalid.payload",
|
|
8
|
+
MissingFile: "encryption.bun.adapter.missing.file",
|
|
9
|
+
};
|
|
7
10
|
|
|
8
11
|
type Dependencies = { CryptoKeyProvider: CryptoKeyProviderPort };
|
|
9
12
|
|
|
10
13
|
export class EncryptionBunAdapter implements EncryptionPort {
|
|
14
|
+
private static ALGORITHM = "AES-GCM";
|
|
15
|
+
|
|
11
16
|
constructor(private readonly deps: Dependencies) {}
|
|
12
17
|
|
|
13
18
|
async encrypt(recipe: EncryptionRecipe) {
|
|
14
19
|
const key = await this.deps.CryptoKeyProvider.get();
|
|
15
20
|
const iv = EncryptionIV.generate();
|
|
16
21
|
|
|
17
|
-
const
|
|
22
|
+
const file = Bun.file(recipe.input.get());
|
|
23
|
+
if (!(await file.exists())) throw new Error(EncryptionBunAdapterError.MissingFile);
|
|
24
|
+
|
|
25
|
+
const plaintext = await file.arrayBuffer();
|
|
18
26
|
|
|
19
27
|
const encrypted = await crypto.subtle.encrypt(
|
|
20
|
-
{ name:
|
|
28
|
+
{ name: EncryptionBunAdapter.ALGORITHM, iv: iv.buffer as ArrayBuffer },
|
|
21
29
|
key,
|
|
22
30
|
plaintext,
|
|
23
31
|
);
|
|
24
32
|
|
|
25
33
|
const ciphertext = new Uint8Array(encrypted);
|
|
34
|
+
// Combine IV + Ciphertext
|
|
26
35
|
const output = new Uint8Array(iv.length + ciphertext.length);
|
|
27
36
|
output.set(iv, 0);
|
|
28
37
|
output.set(ciphertext, iv.length);
|
|
@@ -33,44 +42,39 @@ export class EncryptionBunAdapter implements EncryptionPort {
|
|
|
33
42
|
}
|
|
34
43
|
|
|
35
44
|
async decrypt(recipe: EncryptionRecipe) {
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
const bytes = new Uint8Array(await Bun.file(recipe.input.get()).arrayBuffer());
|
|
39
|
-
if (bytes.length < EncryptionIV.LENGTH + 1) throw new Error(EncryptionBunAdapterError.InvalidPayload);
|
|
40
|
-
|
|
41
|
-
const iv = bytes.subarray(0, EncryptionIV.LENGTH);
|
|
42
|
-
const ivBuffer = iv.buffer.slice(iv.byteOffset, iv.byteOffset + iv.byteLength);
|
|
43
|
-
|
|
44
|
-
const ciphertext = bytes.subarray(EncryptionIV.LENGTH);
|
|
45
|
-
|
|
46
|
-
const ciphertextBuffer = ciphertext.buffer.slice(
|
|
47
|
-
ciphertext.byteOffset,
|
|
48
|
-
ciphertext.byteOffset + ciphertext.byteLength,
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
const decrypted = await crypto.subtle.decrypt({ name: "AES-GCM", iv: ivBuffer }, key, ciphertextBuffer);
|
|
52
|
-
|
|
45
|
+
const decrypted = await this.decryptFile(recipe.input);
|
|
53
46
|
await Bun.write(recipe.output.get(), new Uint8Array(decrypted));
|
|
54
|
-
|
|
55
47
|
return recipe.output;
|
|
56
48
|
}
|
|
57
49
|
|
|
58
50
|
async view(input: tools.FilePathRelative | tools.FilePathAbsolute) {
|
|
51
|
+
return this.decryptFile(input);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private async decryptFile(input: tools.FilePathRelative | tools.FilePathAbsolute): Promise<ArrayBuffer> {
|
|
59
55
|
const key = await this.deps.CryptoKeyProvider.get();
|
|
60
56
|
|
|
61
|
-
const
|
|
57
|
+
const file = Bun.file(input.get());
|
|
58
|
+
if (!(await file.exists())) throw new Error(EncryptionBunAdapterError.MissingFile);
|
|
59
|
+
|
|
60
|
+
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
61
|
+
|
|
62
|
+
// Payload must be at least IV length + 1 byte of content/tag
|
|
62
63
|
if (bytes.length < EncryptionIV.LENGTH + 1) throw new Error(EncryptionBunAdapterError.InvalidPayload);
|
|
63
64
|
|
|
64
65
|
const iv = bytes.subarray(0, EncryptionIV.LENGTH);
|
|
65
66
|
const ivBuffer = iv.buffer.slice(iv.byteOffset, iv.byteOffset + iv.byteLength);
|
|
66
67
|
|
|
67
68
|
const ciphertext = bytes.subarray(EncryptionIV.LENGTH);
|
|
68
|
-
|
|
69
69
|
const ciphertextBuffer = ciphertext.buffer.slice(
|
|
70
70
|
ciphertext.byteOffset,
|
|
71
71
|
ciphertext.byteOffset + ciphertext.byteLength,
|
|
72
72
|
);
|
|
73
73
|
|
|
74
|
-
return crypto.subtle.decrypt(
|
|
74
|
+
return crypto.subtle.decrypt(
|
|
75
|
+
{ name: EncryptionBunAdapter.ALGORITHM, iv: ivBuffer },
|
|
76
|
+
key,
|
|
77
|
+
ciphertextBuffer,
|
|
78
|
+
);
|
|
75
79
|
}
|
|
76
80
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
|
|
3
|
+
export const EncryptionKeyValueError = {
|
|
4
|
+
Type: "encryption.key.value.type",
|
|
5
|
+
InvalidHex: "encryption.key.value.invalid.hex",
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// 64 hex chars allowed
|
|
9
|
+
const CHARS_WHITELIST = /^[a-fA-F0-9]{64}$/;
|
|
10
|
+
|
|
11
|
+
export const EncryptionKeyValue = z
|
|
12
|
+
.string(EncryptionKeyValueError.Type)
|
|
13
|
+
.regex(CHARS_WHITELIST, EncryptionKeyValueError.InvalidHex)
|
|
14
|
+
.brand("EncryptionKeyValue");
|
|
15
|
+
|
|
16
|
+
export type EncryptionKeyValueType = z.infer<typeof EncryptionKeyValue>;
|
package/src/encryption-key.vo.ts
CHANGED
|
@@ -1,16 +1,47 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EncryptionKeyValue, type EncryptionKeyValueType } from "./encryption-key-value.vo";
|
|
2
2
|
|
|
3
|
-
export const EncryptionKeyError = {
|
|
4
|
-
Type: "encryption.key.type",
|
|
5
|
-
InvalidHex: "encryption.key.invalid.hex",
|
|
6
|
-
} as const;
|
|
3
|
+
export const EncryptionKeyError = { InvalidBuffer: "encryption.key.invalid.buffer" };
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
export class EncryptionKey {
|
|
6
|
+
private constructor(private readonly value: EncryptionKeyValueType) {}
|
|
10
7
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
.brand("EncryptionKey");
|
|
8
|
+
static fromStringSafe(value: EncryptionKeyValueType): EncryptionKey {
|
|
9
|
+
return new EncryptionKey(value);
|
|
10
|
+
}
|
|
15
11
|
|
|
16
|
-
|
|
12
|
+
static fromString(candidate: string): EncryptionKey {
|
|
13
|
+
return new EncryptionKey(EncryptionKeyValue.parse(candidate));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static fromBuffer(buffer: Uint8Array): EncryptionKey {
|
|
17
|
+
if (buffer.length !== 32) throw new Error(EncryptionKeyError.InvalidBuffer);
|
|
18
|
+
|
|
19
|
+
const hex = Array.from(buffer)
|
|
20
|
+
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
21
|
+
.join("");
|
|
22
|
+
|
|
23
|
+
return EncryptionKey.fromString(hex);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
equals(another: EncryptionKey): boolean {
|
|
27
|
+
return this.value === another.value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
toBuffer(): Uint8Array {
|
|
31
|
+
const bytes = new Uint8Array(32);
|
|
32
|
+
|
|
33
|
+
for (let i = 0; i < 32; i++) {
|
|
34
|
+
bytes[i] = Number.parseInt(this.value.slice(i * 2, i * 2 + 2), 16);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return bytes;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
toString(): string {
|
|
41
|
+
return "EncryptionKey";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
toJSON(): string {
|
|
45
|
+
return "EncryptionKey";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -2,6 +2,8 @@ import type * as tools from "@bgord/tools";
|
|
|
2
2
|
import type { EncryptionPort, EncryptionRecipe } from "./encryption.port";
|
|
3
3
|
|
|
4
4
|
export class EncryptionNoopAdapter implements EncryptionPort {
|
|
5
|
+
constructor(private readonly buffer: ArrayBuffer = new TextEncoder().encode("noop").buffer) {}
|
|
6
|
+
|
|
5
7
|
async encrypt(recipe: EncryptionRecipe) {
|
|
6
8
|
return recipe.output;
|
|
7
9
|
}
|
|
@@ -11,6 +13,6 @@ export class EncryptionNoopAdapter implements EncryptionPort {
|
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
async view(_input: tools.FilePathRelative | tools.FilePathAbsolute) {
|
|
14
|
-
return
|
|
16
|
+
return this.buffer;
|
|
15
17
|
}
|
|
16
18
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import { parse } from "dotenv";
|
|
3
|
+
import type { z } from "zod/v4";
|
|
4
|
+
import type { NodeEnvironmentEnum } from "../src/node-env.vo";
|
|
5
|
+
import type { EncryptionPort } from "./encryption.port";
|
|
6
|
+
import type { EnvironmentLoaderPort } from "./environment-loader.port";
|
|
7
|
+
|
|
8
|
+
type Dependencies = { Encryption: EncryptionPort };
|
|
9
|
+
|
|
10
|
+
export class EnvironmentLoaderEncryptedAdapter<Schema extends z.ZodObject<any>>
|
|
11
|
+
implements EnvironmentLoaderPort<Schema>
|
|
12
|
+
{
|
|
13
|
+
constructor(
|
|
14
|
+
private readonly config: { type: NodeEnvironmentEnum; Schema: Schema },
|
|
15
|
+
private path: tools.FilePathRelative,
|
|
16
|
+
private readonly deps: Dependencies,
|
|
17
|
+
) {}
|
|
18
|
+
|
|
19
|
+
async load() {
|
|
20
|
+
const file = await this.deps.Encryption.view(this.path);
|
|
21
|
+
const content = new TextDecoder().decode(file);
|
|
22
|
+
|
|
23
|
+
return Object.freeze({ ...this.config.Schema.parse(parse(content)), type: this.config.type });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { z } from "zod/v4";
|
|
2
|
+
import type { NodeEnvironmentEnum } from "../src/node-env.vo";
|
|
3
|
+
import type { EnvironmentLoaderPort } from "./environment-loader.port";
|
|
4
|
+
|
|
5
|
+
export class EnvironmentLoaderProcessAdapter<Schema extends z.ZodObject<any>>
|
|
6
|
+
implements EnvironmentLoaderPort<Schema>
|
|
7
|
+
{
|
|
8
|
+
constructor(
|
|
9
|
+
private readonly config: { type: NodeEnvironmentEnum; Schema: Schema },
|
|
10
|
+
private env: NodeJS.ProcessEnv,
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
async load() {
|
|
14
|
+
const result = this.config.Schema.parse(this.env);
|
|
15
|
+
|
|
16
|
+
for (const key of Object.keys(result)) {
|
|
17
|
+
delete process.env[key];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return Object.freeze({ ...result, type: this.config.type });
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/event-stream.vo.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { z } from "zod/v4";
|
|
2
2
|
|
|
3
|
-
export const HCaptchaSiteKeyError = {
|
|
4
|
-
Type: "hcaptcha.site.key.type",
|
|
5
|
-
Length: "hcaptcha.site.key.length",
|
|
6
|
-
} as const;
|
|
3
|
+
export const HCaptchaSiteKeyError = { Type: "hcaptcha.site.key.type", Length: "hcaptcha.site.key.length" };
|
|
7
4
|
|
|
8
5
|
export const HCaptchaSiteKey = z
|
|
9
6
|
.string(HCaptchaSiteKeyError.Type)
|
package/src/index.ts
CHANGED
|
@@ -30,7 +30,8 @@ export * from "./context.middleware";
|
|
|
30
30
|
export * from "./correlation-id.vo";
|
|
31
31
|
export * from "./correlation-storage.service";
|
|
32
32
|
export * from "./crypto-key-provider.port";
|
|
33
|
-
export * from "./crypto-key-provider-
|
|
33
|
+
export * from "./crypto-key-provider-file.adapter";
|
|
34
|
+
export * from "./crypto-key-provider-memory.adapter";
|
|
34
35
|
export * from "./crypto-key-provider-noop.adapter";
|
|
35
36
|
export * from "./csv-stringifier.adapter";
|
|
36
37
|
export * from "./csv-stringifier.port";
|
|
@@ -42,9 +43,11 @@ export * from "./dispatching-event-store";
|
|
|
42
43
|
export * from "./encryption.port";
|
|
43
44
|
export * from "./encryption-bun.adapter";
|
|
44
45
|
export * from "./encryption-key.vo";
|
|
46
|
+
export * from "./encryption-key-value.vo";
|
|
45
47
|
export * from "./encryption-noop.adapter";
|
|
46
48
|
export * from "./environment-loader.port";
|
|
47
|
-
export * from "./environment-loader-
|
|
49
|
+
export * from "./environment-loader-encrypted.adapter";
|
|
50
|
+
export * from "./environment-loader-process.adapter";
|
|
48
51
|
export * from "./etag-extractor.middleware";
|
|
49
52
|
export * from "./event.types";
|
|
50
53
|
export * from "./event-bus-like.types";
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { z } from "zod/v4";
|
|
2
2
|
|
|
3
|
-
export const RecaptchaSiteKeyError = {
|
|
4
|
-
Type: "recaptcha.site.key.type",
|
|
5
|
-
Length: "recaptcha.site.key.length",
|
|
6
|
-
} as const;
|
|
3
|
+
export const RecaptchaSiteKeyError = { Type: "recaptcha.site.key.type", Length: "recaptcha.site.key.length" };
|
|
7
4
|
|
|
8
5
|
export const RecaptchaSiteKey = z
|
|
9
6
|
.string(RecaptchaSiteKeyError.Type)
|
package/src/visitor-id.vo.ts
CHANGED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { CryptoKeyProviderPort } from "./crypto-key-provider.port";
|
|
2
|
-
import type { EncryptionKeyType } from "./encryption-key.vo";
|
|
3
|
-
export declare class CryptoKeyProviderEnvAdapter implements CryptoKeyProviderPort {
|
|
4
|
-
private readonly ENCRYPTION_KEY;
|
|
5
|
-
constructor(ENCRYPTION_KEY: EncryptionKeyType);
|
|
6
|
-
get(): Promise<CryptoKey>;
|
|
7
|
-
}
|
|
8
|
-
//# sourceMappingURL=crypto-key-provider-env.adapter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-key-provider-env.adapter.d.ts","sourceRoot":"","sources":["../src/crypto-key-provider-env.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,qBAAa,2BAA4B,YAAW,qBAAqB;IAC3D,OAAO,CAAC,QAAQ,CAAC,cAAc;gBAAd,cAAc,EAAE,iBAAiB;IAExD,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;CAShC"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export class CryptoKeyProviderEnvAdapter {
|
|
2
|
-
ENCRYPTION_KEY;
|
|
3
|
-
constructor(ENCRYPTION_KEY) {
|
|
4
|
-
this.ENCRYPTION_KEY = ENCRYPTION_KEY;
|
|
5
|
-
}
|
|
6
|
-
async get() {
|
|
7
|
-
const bytes = new Uint8Array(32);
|
|
8
|
-
for (let i = 0; i < 32; i++) {
|
|
9
|
-
bytes[i] = Number.parseInt(this.ENCRYPTION_KEY.slice(i * 2, i * 2 + 2), 16);
|
|
10
|
-
}
|
|
11
|
-
return crypto.subtle.importKey("raw", bytes, { name: "AES-GCM" }, false, ["encrypt", "decrypt"]);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=crypto-key-provider-env.adapter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-key-provider-env.adapter.js","sourceRoot":"","sources":["../src/crypto-key-provider-env.adapter.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,2BAA2B;IACT;IAA7B,YAA6B,cAAiC;QAAjC,mBAAc,GAAd,cAAc,CAAmB;IAAG,CAAC;IAElE,KAAK,CAAC,GAAG;QACP,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;QAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9E,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;IACnG,CAAC;CACF"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { z } from "zod/v4";
|
|
2
|
-
import { type NodeEnvironmentEnum } from "../src/node-env.vo";
|
|
3
|
-
import type { EnvironmentLoaderPort } from "./environment-loader.port";
|
|
4
|
-
export declare class EnvironmentLoaderProcessEnvAdapter<Schema extends z.ZodObject<any>> implements EnvironmentLoaderPort<Schema> {
|
|
5
|
-
private env;
|
|
6
|
-
private readonly type;
|
|
7
|
-
private readonly schema;
|
|
8
|
-
constructor(config: {
|
|
9
|
-
type: typeof process.env.NODE_ENV;
|
|
10
|
-
schema: Schema;
|
|
11
|
-
}, env: NodeJS.ProcessEnv);
|
|
12
|
-
load(): Promise<Readonly<z.core.output<Schema> & {
|
|
13
|
-
type: NodeEnvironmentEnum;
|
|
14
|
-
}>>;
|
|
15
|
-
}
|
|
16
|
-
//# sourceMappingURL=environment-loader-process-env.adapter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"environment-loader-process-env.adapter.d.ts","sourceRoot":"","sources":["../src/environment-loader-process-env.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAEvE,qBAAa,kCAAkC,CAAC,MAAM,SAAS,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAC7E,YAAW,qBAAqB,CAAC,MAAM,CAAC;IAOtC,OAAO,CAAC,GAAG;IALb,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAsB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAG9B,MAAM,EAAE;QAAE,IAAI,EAAE,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EACrD,GAAG,EAAE,MAAM,CAAC,UAAU;IAM1B,IAAI;;;CAGX"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { NodeEnvironment } from "../src/node-env.vo";
|
|
2
|
-
export class EnvironmentLoaderProcessEnvAdapter {
|
|
3
|
-
env;
|
|
4
|
-
type;
|
|
5
|
-
schema;
|
|
6
|
-
constructor(config, env) {
|
|
7
|
-
this.env = env;
|
|
8
|
-
this.schema = config.schema;
|
|
9
|
-
this.type = NodeEnvironment.parse(config.type);
|
|
10
|
-
}
|
|
11
|
-
async load() {
|
|
12
|
-
return Object.freeze({ ...this.schema.parse(this.env), type: this.type });
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
//# sourceMappingURL=environment-loader-process-env.adapter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"environment-loader-process-env.adapter.js","sourceRoot":"","sources":["../src/environment-loader-process-env.adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAA4B,MAAM,oBAAoB,CAAC;AAG/E,MAAM,OAAO,kCAAkC;IAQnC;IALO,IAAI,CAAsB;IAC1B,MAAM,CAAS;IAEhC,YACE,MAA6D,EACrD,GAAsB;QAAtB,QAAG,GAAH,GAAG,CAAmB;QAE9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5E,CAAC;CACF"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { CryptoKeyProviderPort } from "./crypto-key-provider.port";
|
|
2
|
-
import type { EncryptionKeyType } from "./encryption-key.vo";
|
|
3
|
-
|
|
4
|
-
export class CryptoKeyProviderEnvAdapter implements CryptoKeyProviderPort {
|
|
5
|
-
constructor(private readonly ENCRYPTION_KEY: EncryptionKeyType) {}
|
|
6
|
-
|
|
7
|
-
async get(): Promise<CryptoKey> {
|
|
8
|
-
const bytes = new Uint8Array(32);
|
|
9
|
-
|
|
10
|
-
for (let i = 0; i < 32; i++) {
|
|
11
|
-
bytes[i] = Number.parseInt(this.ENCRYPTION_KEY.slice(i * 2, i * 2 + 2), 16);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return crypto.subtle.importKey("raw", bytes, { name: "AES-GCM" }, false, ["encrypt", "decrypt"]);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { z } from "zod/v4";
|
|
2
|
-
import { NodeEnvironment, type NodeEnvironmentEnum } from "../src/node-env.vo";
|
|
3
|
-
import type { EnvironmentLoaderPort } from "./environment-loader.port";
|
|
4
|
-
|
|
5
|
-
export class EnvironmentLoaderProcessEnvAdapter<Schema extends z.ZodObject<any>>
|
|
6
|
-
implements EnvironmentLoaderPort<Schema>
|
|
7
|
-
{
|
|
8
|
-
private readonly type: NodeEnvironmentEnum;
|
|
9
|
-
private readonly schema: Schema;
|
|
10
|
-
|
|
11
|
-
constructor(
|
|
12
|
-
config: { type: typeof process.env.NODE_ENV; schema: Schema },
|
|
13
|
-
private env: NodeJS.ProcessEnv,
|
|
14
|
-
) {
|
|
15
|
-
this.schema = config.schema;
|
|
16
|
-
this.type = NodeEnvironment.parse(config.type);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async load() {
|
|
20
|
-
return Object.freeze({ ...this.schema.parse(this.env), type: this.type });
|
|
21
|
-
}
|
|
22
|
-
}
|