@bgord/bun 1.4.23 → 1.4.24
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/file-etag.vo.d.ts +8 -0
- package/dist/file-etag.vo.d.ts.map +1 -0
- package/dist/file-etag.vo.js +9 -0
- package/dist/file-etag.vo.js.map +1 -0
- package/dist/file-hash-noop.adapter.d.ts +1 -1
- package/dist/file-hash-noop.adapter.d.ts.map +1 -1
- package/dist/file-hash-noop.adapter.js +2 -1
- package/dist/file-hash-noop.adapter.js.map +1 -1
- package/dist/file-hash-sha256-bun.adapter.d.ts +1 -1
- package/dist/file-hash-sha256-bun.adapter.d.ts.map +1 -1
- package/dist/file-hash-sha256-bun.adapter.js +2 -2
- package/dist/file-hash-sha256-bun.adapter.js.map +1 -1
- package/dist/file-hash.port.d.ts +2 -1
- package/dist/file-hash.port.d.ts.map +1 -1
- 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/mailer.vo.d.ts +0 -10
- package/dist/mailer.vo.d.ts.map +1 -1
- package/dist/mailer.vo.js +0 -4
- package/dist/mailer.vo.js.map +1 -1
- package/dist/prerequisites/outside-connectivity.d.ts +1 -1
- package/dist/prerequisites/outside-connectivity.d.ts.map +1 -1
- package/dist/prerequisites/outside-connectivity.js +2 -2
- package/dist/prerequisites/outside-connectivity.js.map +1 -1
- package/dist/remote-file-storage-noop.adapter.d.ts +4 -4
- package/dist/remote-file-storage-noop.adapter.d.ts.map +1 -1
- package/dist/remote-file-storage-noop.adapter.js +2 -1
- package/dist/remote-file-storage-noop.adapter.js.map +1 -1
- package/dist/shield-captcha-recaptcha.adapter.d.ts +1 -0
- package/dist/shield-captcha-recaptcha.adapter.d.ts.map +1 -1
- package/dist/shield-captcha-recaptcha.adapter.js +3 -1
- package/dist/shield-captcha-recaptcha.adapter.js.map +1 -1
- package/dist/timekeeper-google.adapter.d.ts +1 -1
- package/dist/timekeeper-google.adapter.d.ts.map +1 -1
- package/dist/timekeeper-google.adapter.js +1 -1
- package/dist/timekeeper-google.adapter.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/readme.md +1 -0
- package/src/file-etag.vo.ts +13 -0
- package/src/file-hash-noop.adapter.ts +2 -1
- package/src/file-hash-sha256-bun.adapter.ts +2 -2
- package/src/file-hash.port.ts +2 -1
- package/src/index.ts +1 -0
- package/src/mailer.vo.ts +0 -8
- package/src/prerequisites/outside-connectivity.ts +2 -2
- package/src/remote-file-storage-noop.adapter.ts +4 -2
- package/src/shield-captcha-recaptcha.adapter.ts +6 -1
- package/src/timekeeper-google.adapter.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bgord/bun",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.24",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Bartosz Gordon",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@axiomhq/winston": "1.3.1",
|
|
41
|
-
"@bgord/tools": "1.
|
|
41
|
+
"@bgord/tools": "1.2.0",
|
|
42
42
|
"@hono/ua-blocker": "0.1.21",
|
|
43
43
|
"better-auth": "1.4.7",
|
|
44
44
|
"croner": "9.1.0",
|
package/readme.md
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
|
|
3
|
+
export const FileEtagError = { Type: "file.etag.type", InvalidHex: "file.etag.invalid.hex" } as const;
|
|
4
|
+
|
|
5
|
+
// 64 hex chars allowed
|
|
6
|
+
const CHARS_WHITELIST = /^[a-fA-F0-9]{64}$/;
|
|
7
|
+
|
|
8
|
+
export const FileEtag = z
|
|
9
|
+
.string(FileEtagError.Type)
|
|
10
|
+
.regex(CHARS_WHITELIST, FileEtagError.InvalidHex)
|
|
11
|
+
.brand("FileEtag");
|
|
12
|
+
|
|
13
|
+
export type FileEtagType = z.infer<typeof FileEtag>;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as tools from "@bgord/tools";
|
|
2
|
+
import { FileEtag } from "./file-etag.vo";
|
|
2
3
|
import type { FileHashPort } from "./file-hash.port";
|
|
3
4
|
|
|
4
5
|
export class FileHashNoopAdapter implements FileHashPort {
|
|
5
6
|
async hash(_path: tools.FilePathAbsolute | tools.FilePathRelative) {
|
|
6
7
|
return {
|
|
7
|
-
etag: "
|
|
8
|
+
etag: FileEtag.parse("0000000000000000000000000000000000000000000000000000000000000000"),
|
|
8
9
|
size: tools.Size.fromBytes(10),
|
|
9
10
|
lastModified: tools.Timestamp.fromNumber(1000),
|
|
10
11
|
mime: tools.MIMES.text,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as tools from "@bgord/tools";
|
|
2
|
+
import { FileEtag } from "./file-etag.vo";
|
|
2
3
|
import type { FileHashPort } from "./file-hash.port";
|
|
3
4
|
|
|
4
5
|
export class FileHashSha256BunAdapter implements FileHashPort {
|
|
@@ -8,10 +9,9 @@ export class FileHashSha256BunAdapter implements FileHashPort {
|
|
|
8
9
|
|
|
9
10
|
const arrayBuffer = await file.arrayBuffer();
|
|
10
11
|
const digest = await crypto.subtle.digest("SHA-256", arrayBuffer);
|
|
11
|
-
const etag = Buffer.from(digest).toString("hex");
|
|
12
12
|
|
|
13
13
|
return {
|
|
14
|
-
etag,
|
|
14
|
+
etag: FileEtag.parse(Buffer.from(digest).toString("hex")),
|
|
15
15
|
size: tools.Size.fromBytes(arrayBuffer.byteLength),
|
|
16
16
|
lastModified: tools.Timestamp.fromNumber(file.lastModified),
|
|
17
17
|
mime: tools.Mime.fromExtension(extension),
|
package/src/file-hash.port.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -59,6 +59,7 @@ export * from "./file-cleaner-bun-forgiving.adapter";
|
|
|
59
59
|
export * from "./file-cleaner-noop.adapter";
|
|
60
60
|
export * from "./file-draft.service";
|
|
61
61
|
export * from "./file-draft-zip.service";
|
|
62
|
+
export * from "./file-etag.vo";
|
|
62
63
|
export * from "./file-hash.port";
|
|
63
64
|
export * from "./file-hash-noop.adapter";
|
|
64
65
|
export * from "./file-hash-sha256-bun.adapter";
|
package/src/mailer.vo.ts
CHANGED
|
@@ -27,12 +27,4 @@ export const EmailContentHtml = z
|
|
|
27
27
|
.max(10_000, EmailContentHtmlError.Invalid);
|
|
28
28
|
export type EmailContentHtmlType = z.infer<typeof EmailContentHtml>;
|
|
29
29
|
|
|
30
|
-
export const EmailFromError = { Invalid: "email.from.invalid" } as const;
|
|
31
|
-
export const EmailFrom = z.email(EmailFromError.Invalid);
|
|
32
|
-
export type EmailFromType = z.infer<typeof EmailFrom>;
|
|
33
|
-
|
|
34
|
-
export const EmailToError = { Invalid: "email.to.invalid" } as const;
|
|
35
|
-
export const EmailTo = z.email(EmailToError.Invalid);
|
|
36
|
-
export type EmailToType = z.infer<typeof EmailTo>;
|
|
37
|
-
|
|
38
30
|
export type EmailAttachmentType = { filename: string; path: string };
|
|
@@ -8,7 +8,7 @@ export class PrerequisiteOutsideConnectivity implements prereqs.Prerequisite {
|
|
|
8
8
|
readonly label: prereqs.PrerequisiteLabelType;
|
|
9
9
|
readonly enabled?: boolean = true;
|
|
10
10
|
|
|
11
|
-
private readonly
|
|
11
|
+
private static readonly URL = tools.UrlWithoutSlash.parse("https://google.com");
|
|
12
12
|
readonly timeout: tools.Duration;
|
|
13
13
|
|
|
14
14
|
constructor(config: prereqs.PrerequisiteConfigType & { timeout?: tools.Duration }) {
|
|
@@ -25,7 +25,7 @@ export class PrerequisiteOutsideConnectivity implements prereqs.Prerequisite {
|
|
|
25
25
|
if (!this.enabled) return prereqs.Verification.undetermined(stopwatch.stop());
|
|
26
26
|
|
|
27
27
|
const response = await Timeout.cancellable(
|
|
28
|
-
(signal: AbortSignal) => fetch(
|
|
28
|
+
(signal: AbortSignal) => fetch(PrerequisiteOutsideConnectivity.URL, { method: "HEAD", signal }),
|
|
29
29
|
this.timeout,
|
|
30
30
|
);
|
|
31
31
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as tools from "@bgord/tools";
|
|
2
2
|
import type { ClockPort } from "./clock.port";
|
|
3
|
+
import { FileEtag } from "./file-etag.vo";
|
|
3
4
|
import type { LoggerPort } from "./logger.port";
|
|
4
5
|
import type {
|
|
5
6
|
RemoteFileStoragePort,
|
|
@@ -8,9 +9,10 @@ import type {
|
|
|
8
9
|
RemotePutFromPathResult,
|
|
9
10
|
} from "./remote-file-storage.port";
|
|
10
11
|
|
|
11
|
-
type RemoteFileStorageNoopConfig = { root: tools.DirectoryPathAbsoluteType; publicBaseUrl?: string };
|
|
12
12
|
type Dependencies = { Logger: LoggerPort; Clock: ClockPort };
|
|
13
13
|
|
|
14
|
+
type RemoteFileStorageNoopConfig = { root: tools.DirectoryPathAbsoluteType; publicBaseUrl?: string };
|
|
15
|
+
|
|
14
16
|
export class RemoteFileStorageNoopAdapter implements RemoteFileStoragePort {
|
|
15
17
|
private readonly base = { component: "infra", operation: "RemoteFileStorageNoopAdapter" };
|
|
16
18
|
|
|
@@ -32,7 +34,7 @@ export class RemoteFileStorageNoopAdapter implements RemoteFileStoragePort {
|
|
|
32
34
|
});
|
|
33
35
|
|
|
34
36
|
return {
|
|
35
|
-
etag: "
|
|
37
|
+
etag: FileEtag.parse("0000000000000000000000000000000000000000000000000000000000000000"),
|
|
36
38
|
size: tools.Size.fromBytes(10),
|
|
37
39
|
lastModified: this.deps.Clock.now(),
|
|
38
40
|
mime: tools.MIMES.text,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as tools from "@bgord/tools";
|
|
1
2
|
import { createMiddleware } from "hono/factory";
|
|
2
3
|
import { HTTPException } from "hono/http-exception";
|
|
3
4
|
import type { RecaptchaSecretKeyType } from "./recaptcha-secret-key.vo";
|
|
@@ -9,6 +10,10 @@ export type RecaptchaResultType = { success: boolean; score: number };
|
|
|
9
10
|
export const AccessDeniedRecaptchaError = new HTTPException(403, { message: "access_denied_recaptcha" });
|
|
10
11
|
|
|
11
12
|
export class ShieldCaptchaRecaptchaAdapter implements ShieldPort {
|
|
13
|
+
private static readonly URL = tools.UrlWithoutSlash.parse(
|
|
14
|
+
"https://www.google.com/recaptcha/api/siteverify",
|
|
15
|
+
);
|
|
16
|
+
|
|
12
17
|
constructor(private readonly config: RecaptchaVerifierConfigType) {}
|
|
13
18
|
|
|
14
19
|
verify = createMiddleware(async (c, next) => {
|
|
@@ -26,7 +31,7 @@ export class ShieldCaptchaRecaptchaAdapter implements ShieldPort {
|
|
|
26
31
|
|
|
27
32
|
const params = new URLSearchParams({ secret: this.config.secretKey, response: token, remoteip });
|
|
28
33
|
|
|
29
|
-
const response = await fetch(
|
|
34
|
+
const response = await fetch(ShieldCaptchaRecaptchaAdapter.URL, {
|
|
30
35
|
method: "POST",
|
|
31
36
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
32
37
|
body: params,
|
|
@@ -2,7 +2,7 @@ import * as tools from "@bgord/tools";
|
|
|
2
2
|
import type { TimekeeperPort } from "./timekeeper.port";
|
|
3
3
|
|
|
4
4
|
export class TimekeeperGoogleAdapter implements TimekeeperPort {
|
|
5
|
-
static URL = "https://www.google.com/generate_204";
|
|
5
|
+
static URL = tools.UrlWithoutSlash.parse("https://www.google.com/generate_204");
|
|
6
6
|
|
|
7
7
|
async get(signal?: AbortSignal) {
|
|
8
8
|
try {
|