@bgord/bun 0.5.0 → 0.6.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/dist/api-key-shield.d.ts +2 -2
- package/dist/api-key-shield.d.ts.map +1 -1
- package/dist/api-version.d.ts.map +1 -1
- package/dist/api-version.js +2 -2
- package/dist/api-version.js.map +1 -1
- package/dist/auth-shield.d.ts +11 -10
- package/dist/auth-shield.d.ts.map +1 -1
- package/dist/auth-shield.js +6 -13
- package/dist/auth-shield.js.map +1 -1
- package/dist/build-info-repository.d.ts +5 -3
- package/dist/build-info-repository.d.ts.map +1 -0
- package/dist/build-info-repository.js +18 -0
- package/dist/build-info-repository.js.map +1 -0
- package/dist/cache-resolver.d.ts +46 -0
- package/dist/cache-resolver.d.ts.map +1 -0
- package/dist/cache-resolver.js +44 -0
- package/dist/cache-resolver.js.map +1 -0
- package/dist/cache-response.d.ts +0 -4
- package/dist/cache-response.d.ts.map +1 -1
- package/dist/cache-response.js +2 -6
- package/dist/cache-response.js.map +1 -1
- package/dist/cache-static-files.js +3 -3
- package/dist/cache-static-files.js.map +1 -1
- package/dist/context.d.ts +7 -3
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js.map +1 -1
- package/dist/correlation-id.d.ts +4 -0
- package/dist/correlation-id.d.ts.map +1 -0
- package/dist/correlation-id.js +3 -0
- package/dist/correlation-id.js.map +1 -0
- package/dist/download-file.d.ts +5 -4
- package/dist/download-file.d.ts.map +1 -1
- package/dist/etag-extractor.d.ts +3 -8
- package/dist/etag-extractor.d.ts.map +1 -1
- package/dist/etag-extractor.js +3 -18
- package/dist/etag-extractor.js.map +1 -1
- package/dist/file-uploader.d.ts +2 -2
- package/dist/file-uploader.d.ts.map +1 -1
- package/dist/file-uploader.js +3 -3
- package/dist/file-uploader.js.map +1 -1
- package/dist/graceful-shutdown.d.ts.map +1 -1
- package/dist/graceful-shutdown.js +3 -3
- package/dist/graceful-shutdown.js.map +1 -1
- package/dist/healthcheck.d.ts +12 -11
- package/dist/healthcheck.d.ts.map +1 -1
- package/dist/healthcheck.js +15 -11
- package/dist/healthcheck.js.map +1 -1
- package/dist/http-logger.d.ts +2 -2
- package/dist/http-logger.d.ts.map +1 -1
- package/dist/http-logger.js +4 -3
- package/dist/http-logger.js.map +1 -1
- package/dist/i18n.d.ts +10 -15
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +10 -25
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts +26 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -7
- package/dist/index.js.map +1 -1
- package/dist/jobs.d.ts +1 -0
- package/dist/jobs.d.ts.map +1 -0
- package/dist/jobs.js +72 -0
- package/dist/jobs.js.map +1 -0
- package/dist/logger.d.ts +23 -7
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +87 -0
- package/dist/logger.js.map +1 -0
- package/dist/mailer.d.ts +10 -1
- package/dist/mailer.d.ts.map +1 -0
- package/dist/mailer.js +27 -0
- package/dist/mailer.js.map +1 -0
- package/dist/memory-consumption.d.ts +3 -2
- package/dist/memory-consumption.d.ts.map +1 -0
- package/dist/memory-consumption.js +8 -0
- package/dist/memory-consumption.js.map +1 -0
- package/dist/new-uuid.d.ts +4 -0
- package/dist/new-uuid.d.ts.map +1 -0
- package/dist/new-uuid.js +6 -0
- package/dist/new-uuid.js.map +1 -0
- package/dist/node-env.vo.d.ts +9 -0
- package/dist/node-env.vo.d.ts.map +1 -0
- package/dist/node-env.vo.js +10 -0
- package/dist/node-env.vo.js.map +1 -0
- package/dist/passwords.d.ts +21 -0
- package/dist/passwords.d.ts.map +1 -0
- package/dist/passwords.js +42 -0
- package/dist/passwords.js.map +1 -0
- package/dist/path.d.ts +4 -0
- package/dist/path.d.ts.map +1 -0
- package/dist/path.js +3 -0
- package/dist/path.js.map +1 -0
- package/dist/port.d.ts +4 -0
- package/dist/port.d.ts.map +1 -0
- package/dist/port.js +3 -0
- package/dist/port.js.map +1 -0
- package/dist/prerequisites/binary.d.ts +4 -3
- package/dist/prerequisites/binary.d.ts.map +1 -0
- package/dist/prerequisites/binary.js +29 -0
- package/dist/prerequisites/binary.js.map +1 -0
- package/dist/prerequisites/bun.d.ts +7 -4
- package/dist/prerequisites/bun.d.ts.map +1 -0
- package/dist/prerequisites/bun.js +18 -0
- package/dist/prerequisites/bun.js.map +1 -0
- package/dist/prerequisites/index.d.ts +17 -0
- package/dist/prerequisites/index.d.ts.map +1 -0
- package/dist/prerequisites/index.js +17 -0
- package/dist/prerequisites/index.js.map +1 -0
- package/dist/prerequisites/jobs.d.ts +4 -2
- package/dist/prerequisites/jobs.d.ts.map +1 -0
- package/dist/prerequisites/jobs.js +16 -0
- package/dist/prerequisites/jobs.js.map +1 -0
- package/dist/prerequisites/log-file.d.ts +15 -0
- package/dist/prerequisites/log-file.d.ts.map +1 -0
- package/dist/prerequisites/log-file.js +22 -0
- package/dist/prerequisites/log-file.js.map +1 -0
- package/dist/prerequisites/mailer.d.ts +4 -2
- package/dist/prerequisites/mailer.d.ts.map +1 -0
- package/dist/prerequisites/mailer.js +21 -0
- package/dist/prerequisites/mailer.js.map +1 -0
- package/dist/prerequisites/memory.d.ts +6 -4
- package/dist/prerequisites/memory.d.ts.map +1 -0
- package/dist/prerequisites/memory.js +20 -0
- package/dist/prerequisites/memory.js.map +1 -0
- package/dist/prerequisites/node.d.ts +6 -4
- package/dist/prerequisites/node.d.ts.map +1 -0
- package/dist/prerequisites/node.js +23 -0
- package/dist/prerequisites/node.js.map +1 -0
- package/dist/prerequisites/outside-connectivity.d.ts +4 -2
- package/dist/prerequisites/outside-connectivity.d.ts.map +1 -0
- package/dist/prerequisites/outside-connectivity.js +21 -0
- package/dist/prerequisites/outside-connectivity.js.map +1 -0
- package/dist/prerequisites/path.d.ts +4 -2
- package/dist/prerequisites/path.d.ts.map +1 -0
- package/dist/prerequisites/path.js +26 -0
- package/dist/prerequisites/path.js.map +1 -0
- package/dist/prerequisites/port.d.ts +6 -4
- package/dist/prerequisites/port.d.ts.map +1 -0
- package/dist/prerequisites/port.js +26 -0
- package/dist/prerequisites/port.js.map +1 -0
- package/dist/prerequisites/ram.d.ts +6 -4
- package/dist/prerequisites/ram.d.ts.map +1 -0
- package/dist/prerequisites/ram.js +23 -0
- package/dist/prerequisites/ram.js.map +1 -0
- package/dist/prerequisites/self.d.ts +4 -2
- package/dist/prerequisites/self.d.ts.map +1 -0
- package/dist/prerequisites/self.js +15 -0
- package/dist/prerequisites/self.js.map +1 -0
- package/dist/prerequisites/space.d.ts +6 -4
- package/dist/prerequisites/space.d.ts.map +1 -0
- package/dist/prerequisites/space.js +26 -0
- package/dist/prerequisites/space.js.map +1 -0
- package/dist/prerequisites/ssl-certificate-expiry.d.ts +4 -2
- package/dist/prerequisites/ssl-certificate-expiry.d.ts.map +1 -0
- package/dist/prerequisites/ssl-certificate-expiry.js +24 -0
- package/dist/prerequisites/ssl-certificate-expiry.js.map +1 -0
- package/dist/prerequisites/timezone-utc.d.ts +6 -4
- package/dist/prerequisites/timezone-utc.d.ts.map +1 -0
- package/dist/prerequisites/timezone-utc.js +22 -0
- package/dist/prerequisites/timezone-utc.js.map +1 -0
- package/dist/prerequisites/translations.d.ts +4 -2
- package/dist/prerequisites/translations.d.ts.map +1 -0
- package/dist/prerequisites/translations.js +59 -0
- package/dist/prerequisites/translations.js.map +1 -0
- package/dist/prerequisites.d.ts +2 -0
- package/dist/prerequisites.d.ts.map +1 -0
- package/dist/prerequisites.js +83 -0
- package/dist/prerequisites.js.map +1 -0
- package/dist/rate-limit-shield.d.ts +2 -2
- package/dist/rate-limit-shield.d.ts.map +1 -1
- package/dist/rate-limit-shield.js +2 -2
- package/dist/rate-limit-shield.js.map +1 -1
- package/dist/session-id.d.ts +7 -0
- package/dist/session-id.d.ts.map +1 -0
- package/dist/session-id.js +10 -0
- package/dist/session-id.js.map +1 -0
- package/dist/setup.d.ts +3 -2
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +11 -6
- package/dist/setup.js.map +1 -1
- package/dist/time-zone-offset.d.ts +6 -6
- package/dist/time-zone-offset.d.ts.map +1 -1
- package/dist/time-zone-offset.js +4 -4
- package/dist/time-zone-offset.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/uptime.d.ts +4 -4
- package/dist/uptime.d.ts.map +1 -0
- package/dist/uptime.js +10 -0
- package/dist/uptime.js.map +1 -0
- package/dist/username.d.ts +11 -0
- package/dist/username.d.ts.map +1 -0
- package/dist/username.js +13 -0
- package/dist/username.js.map +1 -0
- package/dist/uuid.d.ts +4 -3
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +4 -0
- package/dist/uuid.js.map +1 -0
- package/dist/weak-etag-extractor.d.ts +7 -0
- package/dist/weak-etag-extractor.d.ts.map +1 -0
- package/dist/weak-etag-extractor.js +18 -0
- package/dist/weak-etag-extractor.js.map +1 -0
- package/package.json +20 -13
- package/src/api-key-shield.ts +2 -2
- package/src/api-version.ts +3 -2
- package/src/auth-shield.ts +14 -23
- package/src/build-info-repository.ts +26 -0
- package/src/cache-resolver.ts +93 -0
- package/src/cache-response.ts +2 -5
- package/src/cache-static-files.ts +3 -3
- package/src/context.ts +9 -4
- package/src/correlation-id.ts +6 -0
- package/src/download-file.ts +2 -2
- package/src/etag-extractor.ts +5 -20
- package/src/file-uploader.ts +4 -4
- package/src/graceful-shutdown.ts +3 -3
- package/src/healthcheck.ts +30 -20
- package/src/http-logger.ts +9 -5
- package/src/i18n.ts +13 -48
- package/src/index.ts +26 -7
- package/src/jobs.ts +91 -0
- package/src/logger.ts +156 -0
- package/src/mailer.ts +48 -0
- package/src/memory-consumption.ts +9 -0
- package/src/new-uuid.ts +5 -0
- package/src/node-env.vo.ts +9 -0
- package/src/passwords.ts +55 -0
- package/src/path.ts +4 -0
- package/src/port.ts +4 -0
- package/src/prerequisites/binary.ts +44 -0
- package/src/prerequisites/bun.ts +32 -0
- package/src/prerequisites/index.ts +16 -0
- package/src/prerequisites/jobs.ts +28 -0
- package/src/prerequisites/log-file.ts +35 -0
- package/src/prerequisites/mailer.ts +32 -0
- package/src/prerequisites/memory.ts +34 -0
- package/src/prerequisites/node.ts +36 -0
- package/src/prerequisites/outside-connectivity.ts +31 -0
- package/src/prerequisites/path.ts +41 -0
- package/src/prerequisites/port.ts +44 -0
- package/src/prerequisites/ram.ts +35 -0
- package/src/prerequisites/self.ts +24 -0
- package/src/prerequisites/space.ts +39 -0
- package/src/prerequisites/ssl-certificate-expiry.ts +37 -0
- package/src/prerequisites/timezone-utc.ts +34 -0
- package/src/prerequisites/translations.ts +92 -0
- package/src/prerequisites.ts +105 -0
- package/src/rate-limit-shield.ts +3 -3
- package/src/session-id.ts +13 -0
- package/src/setup.ts +14 -7
- package/src/time-zone-offset.ts +11 -14
- package/src/uptime.ts +16 -0
- package/src/username.ts +20 -0
- package/src/uuid.ts +6 -0
- package/src/weak-etag-extractor.ts +19 -0
- package/src/image-processor.ts +0 -5
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Logger } from "../logger";
|
|
2
|
+
import {
|
|
3
|
+
AbstractPrerequisite,
|
|
4
|
+
PrerequisiteLabelType,
|
|
5
|
+
PrerequisiteStatusEnum,
|
|
6
|
+
PrerequisiteStrategyEnum,
|
|
7
|
+
} from "../prerequisites";
|
|
8
|
+
|
|
9
|
+
type PrerequisiteLogFileConfigType = {
|
|
10
|
+
logger: Logger;
|
|
11
|
+
label: PrerequisiteLabelType;
|
|
12
|
+
enabled?: boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export class PrerequisiteLogFile extends AbstractPrerequisite<PrerequisiteLogFileConfigType> {
|
|
16
|
+
readonly strategy = PrerequisiteStrategyEnum.logFile;
|
|
17
|
+
|
|
18
|
+
constructor(readonly config: PrerequisiteLogFileConfigType) {
|
|
19
|
+
super(config);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async verify(): Promise<PrerequisiteStatusEnum> {
|
|
23
|
+
if (!this.enabled) return PrerequisiteStatusEnum.undetermined;
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const path = this.config.logger.getProductionLogFilePath();
|
|
27
|
+
|
|
28
|
+
const result = await Bun.file(path).exists();
|
|
29
|
+
|
|
30
|
+
return result ? this.pass() : this.reject();
|
|
31
|
+
} catch (error) {
|
|
32
|
+
return this.reject();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Mailer } from "../mailer";
|
|
2
|
+
import {
|
|
3
|
+
AbstractPrerequisite,
|
|
4
|
+
PrerequisiteLabelType,
|
|
5
|
+
PrerequisiteStatusEnum,
|
|
6
|
+
PrerequisiteStrategyEnum,
|
|
7
|
+
} from "../prerequisites";
|
|
8
|
+
|
|
9
|
+
type PrerequisiteMailerConfigType = {
|
|
10
|
+
mailer: Mailer;
|
|
11
|
+
label: PrerequisiteLabelType;
|
|
12
|
+
enabled?: boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export class PrerequisiteMailer extends AbstractPrerequisite<PrerequisiteMailerConfigType> {
|
|
16
|
+
readonly strategy = PrerequisiteStrategyEnum.mailer;
|
|
17
|
+
|
|
18
|
+
constructor(readonly config: PrerequisiteMailerConfigType) {
|
|
19
|
+
super(config);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async verify(): Promise<PrerequisiteStatusEnum> {
|
|
23
|
+
if (!this.enabled) return PrerequisiteStatusEnum.undetermined;
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
await this.config.mailer.verify();
|
|
27
|
+
return this.pass();
|
|
28
|
+
} catch (error) {
|
|
29
|
+
return this.reject();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as tools from "@bgord/tools";
|
|
2
|
+
import { MemoryConsumption } from "../memory-consumption";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
AbstractPrerequisite,
|
|
6
|
+
PrerequisiteLabelType,
|
|
7
|
+
PrerequisiteStatusEnum,
|
|
8
|
+
PrerequisiteStrategyEnum,
|
|
9
|
+
} from "../prerequisites";
|
|
10
|
+
|
|
11
|
+
type PrerequisiteMemoryConfigType = {
|
|
12
|
+
maximum: tools.Size;
|
|
13
|
+
label: PrerequisiteLabelType;
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export class PrerequisiteMemory extends AbstractPrerequisite<PrerequisiteMemoryConfigType> {
|
|
18
|
+
readonly strategy = PrerequisiteStrategyEnum.memory;
|
|
19
|
+
|
|
20
|
+
constructor(readonly config: PrerequisiteMemoryConfigType) {
|
|
21
|
+
super(config);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async verify(): Promise<PrerequisiteStatusEnum> {
|
|
25
|
+
if (!this.enabled) return PrerequisiteStatusEnum.undetermined;
|
|
26
|
+
|
|
27
|
+
const memoryConsumption = MemoryConsumption.get();
|
|
28
|
+
|
|
29
|
+
if (memoryConsumption.isGreaterThan(this.config.maximum)) {
|
|
30
|
+
return this.reject();
|
|
31
|
+
}
|
|
32
|
+
return this.pass();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as tools from "@bgord/tools";
|
|
2
|
+
import bun from "bun";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
AbstractPrerequisite,
|
|
6
|
+
PrerequisiteLabelType,
|
|
7
|
+
PrerequisiteStatusEnum,
|
|
8
|
+
PrerequisiteStrategyEnum,
|
|
9
|
+
} from "../prerequisites";
|
|
10
|
+
|
|
11
|
+
type PrerequisiteNodeConfigType = {
|
|
12
|
+
version: tools.PackageVersion;
|
|
13
|
+
label: PrerequisiteLabelType;
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export class PrerequisiteNode extends AbstractPrerequisite<PrerequisiteNodeConfigType> {
|
|
18
|
+
readonly strategy = PrerequisiteStrategyEnum.node;
|
|
19
|
+
|
|
20
|
+
constructor(readonly config: PrerequisiteNodeConfigType) {
|
|
21
|
+
super(config);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async verify(): Promise<PrerequisiteStatusEnum> {
|
|
25
|
+
if (!this.enabled) return PrerequisiteStatusEnum.undetermined;
|
|
26
|
+
|
|
27
|
+
const { stdout } = await bun.$`node -v`;
|
|
28
|
+
const version = stdout.toString().trim();
|
|
29
|
+
const current = tools.PackageVersion.fromStringWithV(version);
|
|
30
|
+
|
|
31
|
+
if (current.isGreaterThanOrEqual(this.config.version)) {
|
|
32
|
+
return this.pass();
|
|
33
|
+
}
|
|
34
|
+
return this.reject();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AbstractPrerequisite,
|
|
3
|
+
PrerequisiteLabelType,
|
|
4
|
+
PrerequisiteStatusEnum,
|
|
5
|
+
PrerequisiteStrategyEnum,
|
|
6
|
+
} from "../prerequisites";
|
|
7
|
+
|
|
8
|
+
type PrerequisiteOutsideConnectivityConfigType = {
|
|
9
|
+
label: PrerequisiteLabelType;
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export class PrerequisiteOutsideConnectivity extends AbstractPrerequisite<PrerequisiteOutsideConnectivityConfigType> {
|
|
14
|
+
readonly strategy = PrerequisiteStrategyEnum.outsideConnectivity;
|
|
15
|
+
|
|
16
|
+
constructor(readonly config: PrerequisiteOutsideConnectivityConfigType) {
|
|
17
|
+
super(config);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async verify(): Promise<PrerequisiteStatusEnum> {
|
|
21
|
+
if (!this.enabled) return PrerequisiteStatusEnum.undetermined;
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const result = await fetch("https://google.com");
|
|
25
|
+
|
|
26
|
+
return result.ok ? this.pass() : this.reject();
|
|
27
|
+
} catch (error) {
|
|
28
|
+
return this.reject();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import fsp from "node:fs/promises";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
AbstractPrerequisite,
|
|
6
|
+
PrerequisiteLabelType,
|
|
7
|
+
PrerequisiteStatusEnum,
|
|
8
|
+
PrerequisiteStrategyEnum,
|
|
9
|
+
} from "../prerequisites";
|
|
10
|
+
|
|
11
|
+
type PrerequisitePathConfigType = {
|
|
12
|
+
path: string;
|
|
13
|
+
access?: { write?: boolean; execute?: boolean };
|
|
14
|
+
label: PrerequisiteLabelType;
|
|
15
|
+
enabled?: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export class PrerequisitePath extends AbstractPrerequisite<PrerequisitePathConfigType> {
|
|
19
|
+
readonly strategy = PrerequisiteStrategyEnum.path;
|
|
20
|
+
|
|
21
|
+
constructor(readonly config: PrerequisitePathConfigType) {
|
|
22
|
+
super(config);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async verify(): Promise<PrerequisiteStatusEnum> {
|
|
26
|
+
if (!this.enabled) return PrerequisiteStatusEnum.undetermined;
|
|
27
|
+
|
|
28
|
+
const write = this.config.access?.write ?? false;
|
|
29
|
+
const execute = this.config.access?.execute ?? false;
|
|
30
|
+
|
|
31
|
+
const flags = constants.R_OK | (write ? constants.W_OK : 0) | (execute ? constants.X_OK : 0);
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
await fsp.access(this.config.path, flags);
|
|
35
|
+
|
|
36
|
+
return this.pass();
|
|
37
|
+
} catch (error) {
|
|
38
|
+
return this.reject();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import net from "node:net";
|
|
2
|
+
|
|
3
|
+
import type { PortType } from "../port";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
AbstractPrerequisite,
|
|
7
|
+
PrerequisiteLabelType,
|
|
8
|
+
PrerequisiteStatusEnum,
|
|
9
|
+
PrerequisiteStrategyEnum,
|
|
10
|
+
} from "../prerequisites";
|
|
11
|
+
|
|
12
|
+
type PrerequisitePortConfigType = {
|
|
13
|
+
port: PortType;
|
|
14
|
+
label: PrerequisiteLabelType;
|
|
15
|
+
enabled?: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export class PrerequisitePort extends AbstractPrerequisite<PrerequisitePortConfigType> {
|
|
19
|
+
readonly strategy = PrerequisiteStrategyEnum.port;
|
|
20
|
+
|
|
21
|
+
constructor(readonly config: PrerequisitePortConfigType) {
|
|
22
|
+
super(config);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async verify(): Promise<PrerequisiteStatusEnum> {
|
|
26
|
+
if (!this.enabled) return PrerequisiteStatusEnum.undetermined;
|
|
27
|
+
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
const server = net.createServer();
|
|
30
|
+
|
|
31
|
+
server.listen(this.config.port, () =>
|
|
32
|
+
server.close(() => {
|
|
33
|
+
this.pass();
|
|
34
|
+
return resolve(PrerequisiteStatusEnum.success);
|
|
35
|
+
}),
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
server.on("error", () => {
|
|
39
|
+
this.reject();
|
|
40
|
+
return resolve(PrerequisiteStatusEnum.failure);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import os from "node:os";
|
|
2
|
+
import * as tools from "@bgord/tools";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
AbstractPrerequisite,
|
|
6
|
+
PrerequisiteLabelType,
|
|
7
|
+
PrerequisiteStatusEnum,
|
|
8
|
+
PrerequisiteStrategyEnum,
|
|
9
|
+
} from "../prerequisites";
|
|
10
|
+
|
|
11
|
+
type PrerequisiteRAMConfigType = {
|
|
12
|
+
minimum: tools.Size;
|
|
13
|
+
label: PrerequisiteLabelType;
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export class PrerequisiteRAM extends AbstractPrerequisite<PrerequisiteRAMConfigType> {
|
|
18
|
+
readonly strategy = PrerequisiteStrategyEnum.RAM;
|
|
19
|
+
|
|
20
|
+
constructor(readonly config: PrerequisiteRAMConfigType) {
|
|
21
|
+
super(config);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async verify(): Promise<PrerequisiteStatusEnum> {
|
|
25
|
+
if (!this.enabled) return PrerequisiteStatusEnum.undetermined;
|
|
26
|
+
|
|
27
|
+
const freeRAM = new tools.Size({
|
|
28
|
+
unit: tools.SizeUnit.b,
|
|
29
|
+
value: os.freemem(),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (freeRAM.isGreaterThan(this.config.minimum)) return this.pass();
|
|
33
|
+
return this.reject();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AbstractPrerequisite,
|
|
3
|
+
PrerequisiteLabelType,
|
|
4
|
+
PrerequisiteStatusEnum,
|
|
5
|
+
PrerequisiteStrategyEnum,
|
|
6
|
+
} from "../prerequisites";
|
|
7
|
+
|
|
8
|
+
type PrerequisiteSelfConfigType = {
|
|
9
|
+
label: PrerequisiteLabelType;
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export class PrerequisiteSelf extends AbstractPrerequisite<PrerequisiteSelfConfigType> {
|
|
14
|
+
readonly strategy = PrerequisiteStrategyEnum.self;
|
|
15
|
+
|
|
16
|
+
constructor(readonly config: PrerequisiteSelfConfigType) {
|
|
17
|
+
super(config);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async verify(): Promise<PrerequisiteStatusEnum> {
|
|
21
|
+
if (!this.enabled) return PrerequisiteStatusEnum.undetermined;
|
|
22
|
+
return this.pass();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import * as tools from "@bgord/tools";
|
|
3
|
+
import checkDiskSpace from "check-disk-space";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
AbstractPrerequisite,
|
|
7
|
+
PrerequisiteLabelType,
|
|
8
|
+
PrerequisiteStatusEnum,
|
|
9
|
+
PrerequisiteStrategyEnum,
|
|
10
|
+
} from "../prerequisites";
|
|
11
|
+
|
|
12
|
+
type PrerequisiteSpaceConfigType = {
|
|
13
|
+
minimum: tools.Size;
|
|
14
|
+
label: PrerequisiteLabelType;
|
|
15
|
+
enabled?: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export class PrerequisiteSpace extends AbstractPrerequisite<PrerequisiteSpaceConfigType> {
|
|
19
|
+
readonly strategy = PrerequisiteStrategyEnum.space;
|
|
20
|
+
|
|
21
|
+
constructor(readonly config: PrerequisiteSpaceConfigType) {
|
|
22
|
+
super(config);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async verify(): Promise<PrerequisiteStatusEnum> {
|
|
26
|
+
if (!this.enabled) return PrerequisiteStatusEnum.undetermined;
|
|
27
|
+
|
|
28
|
+
const fsRoot = path.sep;
|
|
29
|
+
const bytes = await checkDiskSpace(fsRoot);
|
|
30
|
+
|
|
31
|
+
const freeDiskSpace = new tools.Size({
|
|
32
|
+
unit: tools.SizeUnit.b,
|
|
33
|
+
value: bytes.free,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (freeDiskSpace.isGreaterThan(this.config.minimum)) return this.pass();
|
|
37
|
+
return this.reject();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import sslChecker from "ssl-checker";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
AbstractPrerequisite,
|
|
5
|
+
PrerequisiteLabelType,
|
|
6
|
+
PrerequisiteStatusEnum,
|
|
7
|
+
PrerequisiteStrategyEnum,
|
|
8
|
+
} from "../prerequisites";
|
|
9
|
+
|
|
10
|
+
type PrerequisiteSSLCertificateExpiryConfigType = {
|
|
11
|
+
host: string;
|
|
12
|
+
validDaysMinimum: number;
|
|
13
|
+
label: PrerequisiteLabelType;
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export class PrerequisiteSSLCertificateExpiry extends AbstractPrerequisite<PrerequisiteSSLCertificateExpiryConfigType> {
|
|
18
|
+
readonly strategy = PrerequisiteStrategyEnum.sslCertificateExpiry;
|
|
19
|
+
|
|
20
|
+
constructor(readonly config: PrerequisiteSSLCertificateExpiryConfigType) {
|
|
21
|
+
super(config);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async verify(): Promise<PrerequisiteStatusEnum> {
|
|
25
|
+
if (!this.enabled) return PrerequisiteStatusEnum.undetermined;
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const result = await sslChecker(this.config.host);
|
|
29
|
+
|
|
30
|
+
if (!result.valid) return PrerequisiteStatusEnum.failure;
|
|
31
|
+
|
|
32
|
+
return result.daysRemaining <= this.config.validDaysMinimum ? this.reject() : this.pass();
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return this.reject();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as tools from "@bgord/tools";
|
|
2
|
+
import { z } from "zod/v4";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
AbstractPrerequisite,
|
|
6
|
+
PrerequisiteLabelType,
|
|
7
|
+
PrerequisiteStatusEnum,
|
|
8
|
+
PrerequisiteStrategyEnum,
|
|
9
|
+
} from "../prerequisites";
|
|
10
|
+
|
|
11
|
+
type PrerequisiteTimezoneUtcConfigType = {
|
|
12
|
+
timezone: tools.TimezoneType;
|
|
13
|
+
label: PrerequisiteLabelType;
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export class PrerequisiteTimezoneUTC extends AbstractPrerequisite<PrerequisiteTimezoneUtcConfigType> {
|
|
18
|
+
readonly strategy = PrerequisiteStrategyEnum.timezoneUTC;
|
|
19
|
+
|
|
20
|
+
constructor(readonly config: PrerequisiteTimezoneUtcConfigType) {
|
|
21
|
+
super(config);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async verify(): Promise<PrerequisiteStatusEnum> {
|
|
25
|
+
if (!this.enabled) return PrerequisiteStatusEnum.undetermined;
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
z.literal("UTC").parse(this.config.timezone);
|
|
29
|
+
return this.pass();
|
|
30
|
+
} catch (error) {
|
|
31
|
+
return this.reject();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import fsp from "node:fs/promises";
|
|
3
|
+
import * as tools from "@bgord/tools";
|
|
4
|
+
|
|
5
|
+
import { I18n, I18nConfigType, TranslationsKeyType } from "../i18n";
|
|
6
|
+
import {
|
|
7
|
+
AbstractPrerequisite,
|
|
8
|
+
PrerequisiteLabelType,
|
|
9
|
+
PrerequisiteStatusEnum,
|
|
10
|
+
PrerequisiteStrategyEnum,
|
|
11
|
+
} from "../prerequisites";
|
|
12
|
+
|
|
13
|
+
type PrerequisiteTranslationsConfigType = {
|
|
14
|
+
translationsPath?: typeof I18n.DEFAULT_TRANSLATIONS_PATH;
|
|
15
|
+
supportedLanguages: I18nConfigType["supportedLanguages"];
|
|
16
|
+
label: PrerequisiteLabelType;
|
|
17
|
+
enabled?: boolean;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type PrerequisiteTranslationsProblemType = {
|
|
21
|
+
translationKey: TranslationsKeyType;
|
|
22
|
+
existsInLanguage: tools.LanguageType;
|
|
23
|
+
missingInLanguage: tools.LanguageType;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export class PrerequisiteTranslations extends AbstractPrerequisite<PrerequisiteTranslationsConfigType> {
|
|
27
|
+
readonly strategy = PrerequisiteStrategyEnum.translations;
|
|
28
|
+
|
|
29
|
+
constructor(readonly config: PrerequisiteTranslationsConfigType) {
|
|
30
|
+
super(config);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async verify(): Promise<PrerequisiteStatusEnum> {
|
|
34
|
+
if (!this.enabled) return PrerequisiteStatusEnum.undetermined;
|
|
35
|
+
|
|
36
|
+
const translationsPath = this.config.translationsPath ?? I18n.DEFAULT_TRANSLATIONS_PATH;
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
await fsp.access(translationsPath, constants.R_OK);
|
|
40
|
+
|
|
41
|
+
for (const language in this.config.supportedLanguages) {
|
|
42
|
+
await fsp.access(new I18n().getTranslationPathForLanguage(language), constants.R_OK);
|
|
43
|
+
}
|
|
44
|
+
} catch (error) {
|
|
45
|
+
return this.reject();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const supportedLanguages = Object.keys(this.config.supportedLanguages);
|
|
49
|
+
|
|
50
|
+
if (supportedLanguages.length === 1) return this.pass();
|
|
51
|
+
|
|
52
|
+
const languageToTranslationKeys: Record<tools.LanguageType, TranslationsKeyType[]> = {};
|
|
53
|
+
|
|
54
|
+
const problems: PrerequisiteTranslationsProblemType[] = [];
|
|
55
|
+
|
|
56
|
+
for (const language of supportedLanguages) {
|
|
57
|
+
const translations = await new I18n().getTranslations(language);
|
|
58
|
+
const translationKeys = Object.keys(translations);
|
|
59
|
+
|
|
60
|
+
languageToTranslationKeys[language] = translationKeys;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
for (const currentLanguage in languageToTranslationKeys) {
|
|
64
|
+
const translationKeys = languageToTranslationKeys[currentLanguage] ?? [];
|
|
65
|
+
|
|
66
|
+
for (const translationKey of translationKeys) {
|
|
67
|
+
for (const supportedLanguage of supportedLanguages) {
|
|
68
|
+
if (supportedLanguage === currentLanguage) continue;
|
|
69
|
+
|
|
70
|
+
const translationKeyExists = languageToTranslationKeys[supportedLanguage]?.some(
|
|
71
|
+
(key) => translationKey === key,
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
if (!translationKeyExists) {
|
|
75
|
+
problems.push({
|
|
76
|
+
translationKey,
|
|
77
|
+
existsInLanguage: currentLanguage,
|
|
78
|
+
missingInLanguage: supportedLanguage,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (problems.length === 0) return this.pass();
|
|
86
|
+
|
|
87
|
+
// biome-ignore lint: lint/suspicious/noConsoleLog
|
|
88
|
+
console.log(problems);
|
|
89
|
+
|
|
90
|
+
return this.reject();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export type PrerequisiteLabelType = string;
|
|
2
|
+
|
|
3
|
+
export enum PrerequisiteStrategyEnum {
|
|
4
|
+
binary = "binary",
|
|
5
|
+
mailer = "mailer",
|
|
6
|
+
self = "self",
|
|
7
|
+
timezoneUTC = "timezoneUTC",
|
|
8
|
+
path = "path",
|
|
9
|
+
node = "node",
|
|
10
|
+
bun = "bun",
|
|
11
|
+
RAM = "RAM",
|
|
12
|
+
space = "space",
|
|
13
|
+
translations = "translations",
|
|
14
|
+
port = "port",
|
|
15
|
+
jobs = "jobs",
|
|
16
|
+
memory = "memory",
|
|
17
|
+
outsideConnectivity = "outsideConnectivity",
|
|
18
|
+
sslCertificateExpiry = "sslCertificateExpiry",
|
|
19
|
+
logFile = "logFile",
|
|
20
|
+
/** @public */
|
|
21
|
+
custom = "custom",
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export enum PrerequisiteStatusEnum {
|
|
25
|
+
success = "success",
|
|
26
|
+
failure = "failure",
|
|
27
|
+
undetermined = "undetermined",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type BasePrerequisiteConfig = {
|
|
31
|
+
label: PrerequisiteLabelType;
|
|
32
|
+
enabled?: boolean;
|
|
33
|
+
} & Record<string, unknown>;
|
|
34
|
+
|
|
35
|
+
export abstract class AbstractPrerequisite<T extends BasePrerequisiteConfig> {
|
|
36
|
+
readonly label: PrerequisiteLabelType;
|
|
37
|
+
readonly enabled: boolean = true;
|
|
38
|
+
abstract readonly strategy: PrerequisiteStrategyEnum;
|
|
39
|
+
abstract readonly config: T;
|
|
40
|
+
|
|
41
|
+
status: PrerequisiteStatusEnum = PrerequisiteStatusEnum.undetermined;
|
|
42
|
+
|
|
43
|
+
constructor(config: T) {
|
|
44
|
+
this.label = config.label;
|
|
45
|
+
this.enabled = config.enabled ?? true;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
abstract verify(): Promise<PrerequisiteStatusEnum>;
|
|
49
|
+
|
|
50
|
+
protected pass(): PrerequisiteStatusEnum.success {
|
|
51
|
+
this.status = PrerequisiteStatusEnum.success;
|
|
52
|
+
return PrerequisiteStatusEnum.success;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
protected reject(): PrerequisiteStatusEnum.failure {
|
|
56
|
+
this.status = PrerequisiteStatusEnum.failure;
|
|
57
|
+
return PrerequisiteStatusEnum.failure;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
report() {
|
|
61
|
+
if (this.status === PrerequisiteStatusEnum.success) {
|
|
62
|
+
// biome-ignore lint: lint/suspicious/noConsoleLog
|
|
63
|
+
console.log(`[x] ${this.config.label} verified correctly with ${this.strategy} strategy`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (this.status === PrerequisiteStatusEnum.failure) {
|
|
67
|
+
// biome-ignore lint: lint/suspicious/noConsoleLog
|
|
68
|
+
console.log(`[-] ${this.config.label} not verified correctly with ${this.strategy} strategy`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (this.status === PrerequisiteStatusEnum.undetermined) {
|
|
72
|
+
// biome-ignore lint: lint/suspicious/noConsoleLog
|
|
73
|
+
console.log(`[?] ${this.config.label} not enabled with ${this.strategy} strategy`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export class Prerequisites {
|
|
79
|
+
static async check(prerequisites: AbstractPrerequisite<BasePrerequisiteConfig>[]) {
|
|
80
|
+
try {
|
|
81
|
+
const failedPrerequisiteLabels: PrerequisiteLabelType[] = [];
|
|
82
|
+
|
|
83
|
+
for (const prerequisite of prerequisites) {
|
|
84
|
+
await prerequisite.verify();
|
|
85
|
+
prerequisite.report();
|
|
86
|
+
|
|
87
|
+
if (prerequisite.status === PrerequisiteStatusEnum.failure) {
|
|
88
|
+
failedPrerequisiteLabels.push(prerequisite.label);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (failedPrerequisiteLabels.length > 0) {
|
|
93
|
+
const failedPrerequisiteLabelsFormatted = failedPrerequisiteLabels.join(", ");
|
|
94
|
+
|
|
95
|
+
// biome-ignore lint: lint/suspicious/noConsoleLog
|
|
96
|
+
console.log(`Prerequisites failed: ${failedPrerequisiteLabelsFormatted}, quitting...`);
|
|
97
|
+
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
} catch (error) {
|
|
101
|
+
// biome-ignore lint: lint/suspicious/noConsoleLog
|
|
102
|
+
console.log("Prerequisites error", String(error));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
package/src/rate-limit-shield.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as tools from "@bgord/tools";
|
|
2
2
|
import { createMiddleware } from "hono/factory";
|
|
3
3
|
import { HTTPException } from "hono/http-exception";
|
|
4
4
|
|
|
5
|
-
type RateLimitShieldOptionsType = { ms:
|
|
5
|
+
type RateLimitShieldOptionsType = { ms: tools.TimestampType };
|
|
6
6
|
|
|
7
7
|
export const TooManyRequestsError = new HTTPException(429, {
|
|
8
8
|
message: "app.too_many_requests",
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
export const rateLimitShield = (options: RateLimitShieldOptionsType) => {
|
|
12
|
-
const rateLimiter = new
|
|
12
|
+
const rateLimiter = new tools.RateLimiter(options);
|
|
13
13
|
|
|
14
14
|
return createMiddleware(async (_c, next) => {
|
|
15
15
|
const currentTimestampMs = Date.now();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Lucia } from "lucia";
|
|
2
|
+
|
|
3
|
+
export class SessionId {
|
|
4
|
+
private value: string | null;
|
|
5
|
+
|
|
6
|
+
constructor(cookie: string | undefined, lucia: Lucia) {
|
|
7
|
+
this.value = lucia.readSessionCookie(cookie ?? "");
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
get(): SessionId["value"] {
|
|
11
|
+
return this.value;
|
|
12
|
+
}
|
|
13
|
+
}
|