First commit

This commit is contained in:
Elijah R 2024-07-25 21:14:56 -04:00
commit 13b1ce564a
18 changed files with 3575 additions and 0 deletions

10
.editorconfig Normal file
View file

@ -0,0 +1,10 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
[*.{js,json,yml}]
charset = utf-8
indent_style = space
indent_size = 2

4
.gitattributes vendored Normal file
View file

@ -0,0 +1,4 @@
/.yarn/** linguist-vendored
/.yarn/releases/* binary
/.yarn/plugins/**/* binary
/.pnp.* binary linguist-generated

17
.gitignore vendored Normal file
View file

@ -0,0 +1,17 @@
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# Swap the comments on the following lines if you wish to use zero-installs
# In that case, don't forget to run `yarn config set enableGlobalCache false`!
# Documentation here: https://yarnpkg.com/features/caching#zero-installs
#!.yarn/cache
.pnp.*
dist/
node_modules/
maxmind/
config.toml

1
.yarnrc.yml Normal file
View file

@ -0,0 +1 @@
nodeLinker: node-modules

5
LICENSE.txt Normal file
View file

@ -0,0 +1,5 @@
Copyright (C) 2024 Computernewb
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

1
README.md Normal file
View file

@ -0,0 +1 @@
# whitelister-eternal

1904
asn_blacklist Normal file

File diff suppressed because it is too large Load diff

25
package.json Normal file
View file

@ -0,0 +1,25 @@
{
"name": "whitelister-eternal",
"packageManager": "yarn@4.2.2",
"type": "module",
"author": "Computernewb",
"license": "0BSD",
"scripts": {
"build": "tsc",
"serve": "node dist/index.js",
"format": "prettier --write src/."
},
"devDependencies": {
"@types/node": "^20.14.12",
"prettier": "^3.3.3",
"typescript": "^5.5.4"
},
"dependencies": {
"@maxmind/geoip2-node": "^5.0.0",
"execa": "^9.3.0",
"fastify": "^4.28.1",
"mysql2": "^3.10.3",
"pino": "^9.3.2",
"toml": "^3.0.0"
}
}

137
src/GeoIPDownloader.ts Normal file
View file

@ -0,0 +1,137 @@
import { Reader, ReaderModel } from "@maxmind/geoip2-node";
import * as fs from "fs/promises";
import * as path from "node:path";
import { Readable } from "node:stream";
import { ReadableStream } from "node:stream/web";
import { finished } from "node:stream/promises";
import { execa } from "execa";
import pino from "pino";
export default class GeoIPDownloader {
private directory: string;
private accountID: string;
private licenseKey: string;
private dbType: string;
private logger = pino({ name: "WhitelisterEternal.GeoIPDownloader" });
constructor(
filename: string,
accountID: string,
licenseKey: string,
dbType: string = "GeoLite2-ASN",
) {
this.directory = filename;
if (!this.directory.endsWith("/")) this.directory += "/";
this.accountID = accountID;
this.licenseKey = licenseKey;
this.dbType = dbType;
}
private genAuthHeader(): string {
return `Basic ${Buffer.from(`${this.accountID}:${this.licenseKey}`).toString("base64")}`;
}
private async ensureDirectoryExists(): Promise<void> {
let stat;
try {
stat = await fs.stat(this.directory);
} catch (e) {
var error = e as NodeJS.ErrnoException;
if (error.code === "ENOTDIR") {
this.logger.warn("File exists at GeoIP directory path, unlinking...");
await fs.unlink(this.directory.substring(0, this.directory.length - 1));
} else if (error.code !== "ENOENT") {
this.logger.error(
"Failed to access GeoIP directory: %s",
error.message,
);
process.exit(1);
}
this.logger.info("Creating GeoIP directory: %s", this.directory);
await fs.mkdir(this.directory, { recursive: true });
return;
}
}
async getGeoIPReader(): Promise<ReaderModel> {
await this.ensureDirectoryExists();
let dbpath = path.join(
this.directory,
(await this.getLatestVersion()).replace(".tar.gz", ""),
`${this.dbType}.mmdb`,
);
try {
await fs.access(dbpath, fs.constants.F_OK | fs.constants.R_OK);
this.logger.info("Loading cached GeoIP database: %s", dbpath);
} catch (ex) {
var error = ex as NodeJS.ErrnoException;
if (error.code === "ENOENT") {
await this.downloadLatestDatabase();
} else {
this.logger.error("Failed to access GeoIP database: %s", error.message);
process.exit(1);
}
}
return await Reader.open(dbpath);
}
async getLatestVersion(): Promise<string> {
let res = await fetch(
`https://download.maxmind.com/geoip/databases/${this.dbType}/download?suffix=tar.gz`,
{
redirect: "follow",
method: "HEAD",
headers: {
Authorization: this.genAuthHeader(),
},
},
);
let disposition = res.headers.get("Content-Disposition");
if (!disposition) {
this.logger.error(
"Failed to get latest version of GeoIP database: No Content-Disposition header",
);
process.exit(1);
}
let filename = disposition.match(/filename=(.*)$/);
if (!filename) {
this.logger.error(
"Failed to get latest version of GeoIP database: Could not parse version from Content-Disposition header",
);
process.exit(1);
}
return filename[1];
}
async downloadLatestDatabase(): Promise<void> {
let filename = await this.getLatestVersion();
this.logger.info("Downloading latest GeoIP database: %s", filename);
let dbpath = path.join(this.directory, filename);
let file = await fs.open(
dbpath,
fs.constants.O_CREAT | fs.constants.O_TRUNC | fs.constants.O_WRONLY,
);
let stream = file.createWriteStream();
let res = await fetch(
`https://download.maxmind.com/geoip/databases/${this.dbType}/download?suffix=tar.gz`,
{
redirect: "follow",
headers: {
Authorization: this.genAuthHeader(),
},
},
);
await finished(
Readable.fromWeb(res.body as ReadableStream<any>).pipe(stream),
);
await file.close();
this.logger.info(
"Finished downloading latest GeoIP database: %s",
filename,
);
this.logger.info("Extracting GeoIP database: %s", filename);
// yeah whatever
await execa("tar", ["xzf", filename], { cwd: this.directory });
this.logger.info("Unlinking GeoIP tarball");
await fs.unlink(dbpath);
}
}

32
src/cloudflare.ts Normal file
View file

@ -0,0 +1,32 @@
import pino from "pino";
import { CloudflareConfig } from "./config.js";
const API_BASE = "https://api.cloudflare.com/client/v4";
export class CloudflareListClient {
config: CloudflareConfig;
logger = pino({ name: "WhitelisterEternal.CloudflareListClient" });
constructor(config: CloudflareConfig) {
this.config = config;
}
async AddIP(ip: string, comment: string) {
let res = await fetch(
`${API_BASE}/accounts/${this.config.accountID}/rules/lists/${this.config.listID}/items`,
{
method: "POST",
body: JSON.stringify([{ ip, comment }]),
headers: {
Authorization: `Bearer ${this.config.apiKey}`,
},
},
);
let json = await res.json();
if (!res.ok || !json.success) {
let error = json?.errors?.[0]?.message ?? res.statusText;
this.logger.error(`Failed to add IP ${ip} to Cloudflare list: ${error}`);
return false;
}
return true;
}
}

33
src/config.ts Normal file
View file

@ -0,0 +1,33 @@
import { ASNTestConfig } from "./tests/asn.js";
export interface Config {
http: {
host: string;
port: number;
};
whitelister: {
failOnWarn: boolean;
};
mysql: MySQLConfig;
cloudflare: CloudflareConfig;
tests: {
asn: ASNTestConfig;
spur: {
enabled: boolean;
};
};
}
export interface CloudflareConfig {
enabled: boolean;
apiKey: string;
accountID: string;
listID: string;
}
export interface MySQLConfig {
host: string;
user: string;
password: string;
database: string;
}

50
src/database.ts Normal file
View file

@ -0,0 +1,50 @@
import { MySQLConfig } from "./config.js";
import * as mysql from "mysql2/promise";
export enum IPLookupResult {
Unlisted,
Allowed,
Blocked,
}
export class Database {
private db: mysql.Pool;
constructor(config: MySQLConfig) {
this.db = mysql.createPool({
host: config.host,
user: config.user,
password: config.password,
database: config.database,
connectionLimit: 10,
multipleStatements: false,
});
}
async init() {
let conn = await this.db.getConnection();
await conn.execute(
"CREATE TABLE IF NOT EXISTS ips (ip VARCHAR(43) PRIMARY KEY NOT NULL, allowed BOOLEAN NOT NULL, reason TEXT DEFAULT NULL, timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP);",
);
conn.release();
}
async addIP(ip: string, allowed: boolean, reason: string | null) {
let conn = await this.db.getConnection();
await conn.execute(
"INSERT INTO ips (ip, allowed, reason) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE allowed = VALUES(allowed), reason = VALUES(reason);",
[ip, allowed, reason],
);
conn.release();
}
async lookupIP(ip: string): Promise<IPLookupResult> {
let conn = await this.db.getConnection();
let rows = (await conn.query("SELECT * FROM ips WHERE ip = ?", [
ip,
])) as mysql.RowDataPacket;
conn.release();
if (rows[0].length === 0) return IPLookupResult.Unlisted;
return rows[0][0].allowed ? IPLookupResult.Allowed : IPLookupResult.Blocked;
}
}

137
src/index.ts Normal file
View file

@ -0,0 +1,137 @@
import fastify from "fastify";
import { Config } from "./config.js";
import * as fs from "fs/promises";
import * as toml from "toml";
import pino from "pino";
import { Test, TestResult, TestResultStrings } from "./test.js";
import { ASNTest } from "./tests/asn.js";
import { SpurTest } from "./tests/spur.js";
import { isIP } from "net";
import { CloudflareListClient } from "./cloudflare.js";
import { Database, IPLookupResult } from "./database.js";
const logger = pino({ name: "WhitelisterEternal" });
// Load config file
let config: Config;
let configPath: string;
if (process.argv.length < 3) configPath = "./config.toml";
else configPath = process.argv[2];
try {
let configRaw = await fs.readFile("config.toml", "utf-8");
config = toml.parse(configRaw);
} catch (e) {
logger.error(
`Failed to read or parse the config file: ${(e as Error).message}`,
);
process.exit(1);
}
// Load tests
let tests: Test[] = [];
if (config.tests.asn.enabled) {
tests.push(await ASNTest.Create(config.tests.asn));
}
if (config.tests.spur.enabled) {
tests.push(new SpurTest());
}
for (let test of tests) {
logger.info(`Loaded test: ${test.name()}`);
}
// Database
const db = new Database(config.mysql);
await db.init();
// Cloudflare
let cloudflare: CloudflareListClient | undefined;
if (config.cloudflare.enabled) {
cloudflare = new CloudflareListClient(config.cloudflare);
}
// Map routes
const app = fastify();
app.get("/auth", async (req, res) => {
let ip: string;
if (req.headers["x-forwarded-for"] === undefined) {
logger.error(
`Warning: X-Forwarded-For not set! This is likely a misconfiguration of your reverse proxy.`,
);
res.statusCode = 500;
return;
}
let xff = req.headers["x-forwarded-for"];
if (xff instanceof Array) ip = xff[0];
else ip = xff;
if (!isIP(ip)) {
logger.error(
`Warning: X-Forwarded-For malformed! This is likely a misconfiguration of your reverse proxy.`,
);
res.statusCode = 500;
return;
}
let status = await db.lookupIP(ip);
switch (status) {
case IPLookupResult.Allowed: {
res.statusCode = 200;
logger.info(`${ip} is whitelisted.`);
return "PASS";
}
case IPLookupResult.Blocked: {
res.statusCode = 403;
logger.info(`${ip} is blocked.`);
return "FAIL";
}
case IPLookupResult.Unlisted: {
logger.info(`Testing ${ip}...`);
let pass = true;
let failedTest;
for (let test of tests) {
let result = await test.test(ip);
logger.info(
`${test.name()} returned ${TestResultStrings[result]} for ${ip}.`,
);
if (
result === TestResult.FAIL ||
(config.whitelister.failOnWarn && result === TestResult.WARN)
) {
pass = false;
failedTest = test.name();
break;
}
}
if (pass) {
logger.info(`${ip} passed all tests. Whitelisting.`);
await db.addIP(ip, true, null);
res.statusCode = 200;
return "PASS";
} else {
logger.info(`${ip} failed a test. Blocking.`);
await db.addIP(ip, false, `Failed ${failedTest}`);
if (cloudflare !== undefined) {
await cloudflare.AddIP(
ip,
`(WhitelisterEternal) Failed ${failedTest}`,
);
logger.info(`${ip} added to Cloudflare list.`);
}
res.statusCode = 403;
return "FAIL";
}
}
}
});
app.listen({
host: config.http.host,
port: config.http.port,
});

18
src/test.ts Normal file
View file

@ -0,0 +1,18 @@
export interface Test {
name(): string;
test(ip: string): Promise<TestResult>;
}
export enum TestResult {
PASS,
FAIL,
WARN,
ERROR,
}
export const TestResultStrings = {
[TestResult.PASS]: "PASS",
[TestResult.FAIL]: "FAIL",
[TestResult.WARN]: "WARN",
[TestResult.ERROR]: "ERROR",
};

56
src/tests/asn.ts Normal file
View file

@ -0,0 +1,56 @@
import { ReaderModel } from "@maxmind/geoip2-node";
import { Test, TestResult } from "../test.js";
import * as fs from "fs/promises";
import GeoIPDownloader from "../GeoIPDownloader.js";
import pino from "pino";
export interface ASNTestConfig {
enabled: boolean;
blacklistFile: string;
maxmindDirectory: string;
maxmindAccountID: string;
maxmindLicenseKey: string;
}
export class ASNTest implements Test {
private blacklist: string[];
private reader: ReaderModel;
private logger = pino({ name: "WhitelisterEternal.ASNTest" });
constructor(blacklist: string[], reader: ReaderModel) {
this.blacklist = blacklist;
this.reader = reader;
this.logger.info(`Loaded ASN blacklist with ${blacklist.length} entries`);
}
static async Create(config: ASNTestConfig) {
let file = await fs.readFile(config.blacklistFile, "utf-8");
let blacklist = file
.split("\n")
.filter((line) => !line.startsWith("#"))
.map((line) => line.trim());
let reader = await new GeoIPDownloader(
config.maxmindDirectory,
config.maxmindAccountID,
config.maxmindLicenseKey,
).getGeoIPReader();
return new ASNTest(blacklist, reader);
}
name() {
return "ASN Test";
}
async test(ip: string): Promise<TestResult> {
let asn;
try {
asn = this.reader.asn(ip).autonomousSystemNumber!;
} catch (e) {
return TestResult.ERROR;
}
if (this.blacklist.indexOf(asn?.toString()) !== -1) {
return TestResult.FAIL;
}
return TestResult.PASS;
}
}

45
src/tests/spur.ts Normal file
View file

@ -0,0 +1,45 @@
import { Test, TestResult } from "../test.js";
export class SpurTest implements Test {
name() {
return "Spur Test";
}
async test(ip: string): Promise<TestResult> {
// Totally TOS-compliantly scrape the IP address from spur.us
let f = await fetch(`https://spur.us/context/${ip}`, {
// Hey Guys, Its Me, A Browser!
headers: {
"User-Agent":
"Mozilla/5.0 (X11; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0",
Accept:
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate, br, zstd",
DNT: "1",
"Alt-Used": "spur.us",
Connection: "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "cross-site",
Priority: "u=1",
Pragma: "no-cache",
"Cache-Control": "no-cache",
TE: "trailers",
},
});
let res = await f.text();
if (res.includes("Rate Limit Exceeded")) {
return TestResult.ERROR;
}
if (
res.includes("fa-question") ||
res.includes("circleimg") ||
res.includes("fa-key")
) {
return TestResult.FAIL;
}
return TestResult.PASS;
}
}

108
tsconfig.json Normal file
View file

@ -0,0 +1,108 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "es2022", /* Specify what module code is generated. */
"rootDir": "./src", /* Specify the root folder within your source files. */
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
"outDir": "./dist", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}

992
yarn.lock Normal file
View file

@ -0,0 +1,992 @@
# This file is generated by running "yarn install" inside your project.
# Manual changes might be lost - proceed with caution!
__metadata:
version: 8
cacheKey: 10c0
"@fastify/ajv-compiler@npm:^3.5.0":
version: 3.6.0
resolution: "@fastify/ajv-compiler@npm:3.6.0"
dependencies:
ajv: "npm:^8.11.0"
ajv-formats: "npm:^2.1.1"
fast-uri: "npm:^2.0.0"
checksum: 10c0/f0be2ca1f75833492829c52c5f5ef0ec118bdd010614e002a6366952c27297c0f6a7dafb5917a0f9c4aaa84aa32a39e520c6d837fa251748717d58590cfc8177
languageName: node
linkType: hard
"@fastify/error@npm:^3.3.0, @fastify/error@npm:^3.4.0":
version: 3.4.1
resolution: "@fastify/error@npm:3.4.1"
checksum: 10c0/1f1a0faa8c86639afb6f4bd47a9cdc1f0f20ce0d6944340fbdec8218aaba91dc9cae9ed78e24e61bceb782a867efda2b9a6320091f00dcbb896d9c8a9bdf5f96
languageName: node
linkType: hard
"@fastify/fast-json-stringify-compiler@npm:^4.3.0":
version: 4.3.0
resolution: "@fastify/fast-json-stringify-compiler@npm:4.3.0"
dependencies:
fast-json-stringify: "npm:^5.7.0"
checksum: 10c0/513ef296f5ed682f7a460cfa6c5fb917a32fc540111b873c9937f944558e021492b18f30f9fd8dd20db252381a4428adbcc9f03a077f16c86d02f081eb490c7b
languageName: node
linkType: hard
"@fastify/merge-json-schemas@npm:^0.1.0":
version: 0.1.1
resolution: "@fastify/merge-json-schemas@npm:0.1.1"
dependencies:
fast-deep-equal: "npm:^3.1.3"
checksum: 10c0/7979ce12724f7b98aea06f0bb9afb20dd869f0ff6fc697517135cbb54e0a36b062cbb38ec176fe43d1fc455576839240df8f33533939ace2d64a6218a6e6b9c1
languageName: node
linkType: hard
"@maxmind/geoip2-node@npm:^5.0.0":
version: 5.0.0
resolution: "@maxmind/geoip2-node@npm:5.0.0"
dependencies:
ip6addr: "npm:^0.2.5"
maxmind: "npm:^4.2.0"
checksum: 10c0/10f6c936b45632210210750b839578c610a3ceba06aff5db2a3d9da68b51b986caa7e700c78ab2ea02524b3793e4f21daee7ecfde1dc242241291e43833b7087
languageName: node
linkType: hard
"@sec-ant/readable-stream@npm:^0.4.1":
version: 0.4.1
resolution: "@sec-ant/readable-stream@npm:0.4.1"
checksum: 10c0/64e9e9cf161e848067a5bf60cdc04d18495dc28bb63a8d9f8993e4dd99b91ad34e4b563c85de17d91ffb177ec17a0664991d2e115f6543e73236a906068987af
languageName: node
linkType: hard
"@sindresorhus/merge-streams@npm:^4.0.0":
version: 4.0.0
resolution: "@sindresorhus/merge-streams@npm:4.0.0"
checksum: 10c0/482ee543629aa1933b332f811a1ae805a213681ecdd98c042b1c1b89387df63e7812248bb4df3910b02b3cc5589d3d73e4393f30e197c9dde18046ccd471fc6b
languageName: node
linkType: hard
"@types/node@npm:^20.14.12":
version: 20.14.12
resolution: "@types/node@npm:20.14.12"
dependencies:
undici-types: "npm:~5.26.4"
checksum: 10c0/59bc5fa11fdd23fd517f859063118f54a1ab53d3399ef63c926f8902429d7453abc0db22ef4b0a6110026b6ab81b6472fee894e1d235c24b01a0b3e10cfae0bb
languageName: node
linkType: hard
"abort-controller@npm:^3.0.0":
version: 3.0.0
resolution: "abort-controller@npm:3.0.0"
dependencies:
event-target-shim: "npm:^5.0.0"
checksum: 10c0/90ccc50f010250152509a344eb2e71977fbf8db0ab8f1061197e3275ddf6c61a41a6edfd7b9409c664513131dd96e962065415325ef23efa5db931b382d24ca5
languageName: node
linkType: hard
"abstract-logging@npm:^2.0.1":
version: 2.0.1
resolution: "abstract-logging@npm:2.0.1"
checksum: 10c0/304879d9babcf6772260e5ddde632e6428e1f42f7a7a116d4689e97ad813a20e0ec2dd1e0a122f3617557f40091b9ca85735de4b48c17a2041268cb47b3f8ef1
languageName: node
linkType: hard
"ajv-formats@npm:^2.1.1":
version: 2.1.1
resolution: "ajv-formats@npm:2.1.1"
dependencies:
ajv: "npm:^8.0.0"
peerDependencies:
ajv: ^8.0.0
peerDependenciesMeta:
ajv:
optional: true
checksum: 10c0/e43ba22e91b6a48d96224b83d260d3a3a561b42d391f8d3c6d2c1559f9aa5b253bfb306bc94bbeca1d967c014e15a6efe9a207309e95b3eaae07fcbcdc2af662
languageName: node
linkType: hard
"ajv-formats@npm:^3.0.1":
version: 3.0.1
resolution: "ajv-formats@npm:3.0.1"
dependencies:
ajv: "npm:^8.0.0"
peerDependencies:
ajv: ^8.0.0
peerDependenciesMeta:
ajv:
optional: true
checksum: 10c0/168d6bca1ea9f163b41c8147bae537e67bd963357a5488a1eaf3abe8baa8eec806d4e45f15b10767e6020679315c7e1e5e6803088dfb84efa2b4e9353b83dd0a
languageName: node
linkType: hard
"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0":
version: 8.17.1
resolution: "ajv@npm:8.17.1"
dependencies:
fast-deep-equal: "npm:^3.1.3"
fast-uri: "npm:^3.0.1"
json-schema-traverse: "npm:^1.0.0"
require-from-string: "npm:^2.0.2"
checksum: 10c0/ec3ba10a573c6b60f94639ffc53526275917a2df6810e4ab5a6b959d87459f9ef3f00d5e7865b82677cb7d21590355b34da14d1d0b9c32d75f95a187e76fff35
languageName: node
linkType: hard
"assert-plus@npm:1.0.0, assert-plus@npm:^1.0.0":
version: 1.0.0
resolution: "assert-plus@npm:1.0.0"
checksum: 10c0/b194b9d50c3a8f872ee85ab110784911e696a4d49f7ee6fc5fb63216dedbefd2c55999c70cb2eaeb4cf4a0e0338b44e9ace3627117b5bf0d42460e9132f21b91
languageName: node
linkType: hard
"atomic-sleep@npm:^1.0.0":
version: 1.0.0
resolution: "atomic-sleep@npm:1.0.0"
checksum: 10c0/e329a6665512736a9bbb073e1761b4ec102f7926cce35037753146a9db9c8104f5044c1662e4a863576ce544fb8be27cd2be6bc8c1a40147d03f31eb1cfb6e8a
languageName: node
linkType: hard
"avvio@npm:^8.3.0":
version: 8.3.2
resolution: "avvio@npm:8.3.2"
dependencies:
"@fastify/error": "npm:^3.3.0"
fastq: "npm:^1.17.1"
checksum: 10c0/280767ca1259cac1e78fc75ee4f1f6a735914e045015b1ac4c0ce9c5b0933edcb7e9a31fb286a479e51e56562b352dcfa35941e6f555edd341ed5d355e36e4ac
languageName: node
linkType: hard
"aws-ssl-profiles@npm:^1.1.1":
version: 1.1.1
resolution: "aws-ssl-profiles@npm:1.1.1"
checksum: 10c0/a2889bae943fed1629350cbe7979e9da507c89c57b554b159844f369fa92bd9b0a344e63540f40770a0957d4f58f80a98a83c300cd86b163d3f30cbdc7edb8bd
languageName: node
linkType: hard
"base64-js@npm:^1.3.1":
version: 1.5.1
resolution: "base64-js@npm:1.5.1"
checksum: 10c0/f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf
languageName: node
linkType: hard
"buffer@npm:^6.0.3":
version: 6.0.3
resolution: "buffer@npm:6.0.3"
dependencies:
base64-js: "npm:^1.3.1"
ieee754: "npm:^1.2.1"
checksum: 10c0/2a905fbbcde73cc5d8bd18d1caa23715d5f83a5935867c2329f0ac06104204ba7947be098fe1317fbd8830e26090ff8e764f08cd14fefc977bb248c3487bcbd0
languageName: node
linkType: hard
"cookie@npm:^0.6.0":
version: 0.6.0
resolution: "cookie@npm:0.6.0"
checksum: 10c0/f2318b31af7a31b4ddb4a678d024514df5e705f9be5909a192d7f116cfb6d45cbacf96a473fa733faa95050e7cff26e7832bb3ef94751592f1387b71c8956686
languageName: node
linkType: hard
"core-util-is@npm:1.0.2":
version: 1.0.2
resolution: "core-util-is@npm:1.0.2"
checksum: 10c0/980a37a93956d0de8a828ce508f9b9e3317039d68922ca79995421944146700e4aaf490a6dbfebcb1c5292a7184600c7710b957d724be1e37b8254c6bc0fe246
languageName: node
linkType: hard
"cross-spawn@npm:^7.0.3":
version: 7.0.3
resolution: "cross-spawn@npm:7.0.3"
dependencies:
path-key: "npm:^3.1.0"
shebang-command: "npm:^2.0.0"
which: "npm:^2.0.1"
checksum: 10c0/5738c312387081c98d69c98e105b6327b069197f864a60593245d64c8089c8a0a744e16349281210d56835bb9274130d825a78b2ad6853ca13cfbeffc0c31750
languageName: node
linkType: hard
"denque@npm:^2.1.0":
version: 2.1.0
resolution: "denque@npm:2.1.0"
checksum: 10c0/f9ef81aa0af9c6c614a727cb3bd13c5d7db2af1abf9e6352045b86e85873e629690f6222f4edd49d10e4ccf8f078bbeec0794fafaf61b659c0589d0c511ec363
languageName: node
linkType: hard
"event-target-shim@npm:^5.0.0":
version: 5.0.1
resolution: "event-target-shim@npm:5.0.1"
checksum: 10c0/0255d9f936215fd206156fd4caa9e8d35e62075d720dc7d847e89b417e5e62cf1ce6c9b4e0a1633a9256de0efefaf9f8d26924b1f3c8620cffb9db78e7d3076b
languageName: node
linkType: hard
"events@npm:^3.3.0":
version: 3.3.0
resolution: "events@npm:3.3.0"
checksum: 10c0/d6b6f2adbccbcda74ddbab52ed07db727ef52e31a61ed26db9feb7dc62af7fc8e060defa65e5f8af9449b86b52cc1a1f6a79f2eafcf4e62add2b7a1fa4a432f6
languageName: node
linkType: hard
"execa@npm:^9.3.0":
version: 9.3.0
resolution: "execa@npm:9.3.0"
dependencies:
"@sindresorhus/merge-streams": "npm:^4.0.0"
cross-spawn: "npm:^7.0.3"
figures: "npm:^6.1.0"
get-stream: "npm:^9.0.0"
human-signals: "npm:^7.0.0"
is-plain-obj: "npm:^4.1.0"
is-stream: "npm:^4.0.1"
npm-run-path: "npm:^5.2.0"
pretty-ms: "npm:^9.0.0"
signal-exit: "npm:^4.1.0"
strip-final-newline: "npm:^4.0.0"
yoctocolors: "npm:^2.0.0"
checksum: 10c0/99ae08e7fb9172d25c453c2a9c414b54c7689e72f68263f6da7bc94c7011720dc8129cc64c2e3be44fb0c6ae8e37a08d346a61dbcfe9f1e79ad24364da2c48ce
languageName: node
linkType: hard
"extsprintf@npm:1.3.0":
version: 1.3.0
resolution: "extsprintf@npm:1.3.0"
checksum: 10c0/f75114a8388f0cbce68e277b6495dc3930db4dde1611072e4a140c24e204affd77320d004b947a132e9a3b97b8253017b2b62dce661975fb0adced707abf1ab5
languageName: node
linkType: hard
"extsprintf@npm:^1.2.0":
version: 1.4.1
resolution: "extsprintf@npm:1.4.1"
checksum: 10c0/e10e2769985d0e9b6c7199b053a9957589d02e84de42832c295798cb422a025e6d4a92e0259c1fb4d07090f5bfde6b55fd9f880ac5855bd61d775f8ab75a7ab0
languageName: node
linkType: hard
"fast-content-type-parse@npm:^1.1.0":
version: 1.1.0
resolution: "fast-content-type-parse@npm:1.1.0"
checksum: 10c0/882bf990fa5d64be1825ce183818db43900ece0d7ef184cb9409bae8ed1001acbe536a657b1496382cb3e308e71ab39cc399bbdae70cba1745eecaeca4e55384
languageName: node
linkType: hard
"fast-decode-uri-component@npm:^1.0.1":
version: 1.0.1
resolution: "fast-decode-uri-component@npm:1.0.1"
checksum: 10c0/039d50c2e99d64f999c3f2126c23fbf75a04a4117e218a149ca0b1d2aeb8c834b7b19d643b9d35d4eabce357189a6a94085f78cf48869e6e26cc59b036284bc3
languageName: node
linkType: hard
"fast-deep-equal@npm:^3.1.3":
version: 3.1.3
resolution: "fast-deep-equal@npm:3.1.3"
checksum: 10c0/40dedc862eb8992c54579c66d914635afbec43350afbbe991235fdcb4e3a8d5af1b23ae7e79bef7d4882d0ecee06c3197488026998fb19f72dc95acff1d1b1d0
languageName: node
linkType: hard
"fast-json-stringify@npm:^5.7.0, fast-json-stringify@npm:^5.8.0":
version: 5.16.1
resolution: "fast-json-stringify@npm:5.16.1"
dependencies:
"@fastify/merge-json-schemas": "npm:^0.1.0"
ajv: "npm:^8.10.0"
ajv-formats: "npm:^3.0.1"
fast-deep-equal: "npm:^3.1.3"
fast-uri: "npm:^2.1.0"
json-schema-ref-resolver: "npm:^1.0.1"
rfdc: "npm:^1.2.0"
checksum: 10c0/bbf955d9912fb827dff0e097fdbff3c11aec540ea8019a19593a16224cac70d49d0cebd98e412843fc72259184f73a78a45e63040d3c44349f4735a492f2f1a4
languageName: node
linkType: hard
"fast-querystring@npm:^1.0.0":
version: 1.1.2
resolution: "fast-querystring@npm:1.1.2"
dependencies:
fast-decode-uri-component: "npm:^1.0.1"
checksum: 10c0/e8223273a9b199722f760f5a047a77ad049a14bd444b821502cb8218f5925e3a5fffb56b64389bca73ab2ac6f1aa7aebbe4e203e5f6e53ff5978de97c0fde4e3
languageName: node
linkType: hard
"fast-redact@npm:^3.1.1":
version: 3.5.0
resolution: "fast-redact@npm:3.5.0"
checksum: 10c0/7e2ce4aad6e7535e0775bf12bd3e4f2e53d8051d8b630e0fa9e67f68cb0b0e6070d2f7a94b1d0522ef07e32f7c7cda5755e2b677a6538f1e9070ca053c42343a
languageName: node
linkType: hard
"fast-uri@npm:^2.0.0, fast-uri@npm:^2.1.0":
version: 2.4.0
resolution: "fast-uri@npm:2.4.0"
checksum: 10c0/300453cfe2f7d5ec16be0f2c8dc5b280edbaca59440b2deb4ab56ac0f584637179e9ee7539d0b70ef0fce9608245ebfa75307c84fa4829b1065c3b7ef7dcf706
languageName: node
linkType: hard
"fast-uri@npm:^3.0.1":
version: 3.0.1
resolution: "fast-uri@npm:3.0.1"
checksum: 10c0/3cd46d6006083b14ca61ffe9a05b8eef75ef87e9574b6f68f2e17ecf4daa7aaadeff44e3f0f7a0ef4e0f7e7c20fc07beec49ff14dc72d0b500f00386592f2d10
languageName: node
linkType: hard
"fastify@npm:^4.28.1":
version: 4.28.1
resolution: "fastify@npm:4.28.1"
dependencies:
"@fastify/ajv-compiler": "npm:^3.5.0"
"@fastify/error": "npm:^3.4.0"
"@fastify/fast-json-stringify-compiler": "npm:^4.3.0"
abstract-logging: "npm:^2.0.1"
avvio: "npm:^8.3.0"
fast-content-type-parse: "npm:^1.1.0"
fast-json-stringify: "npm:^5.8.0"
find-my-way: "npm:^8.0.0"
light-my-request: "npm:^5.11.0"
pino: "npm:^9.0.0"
process-warning: "npm:^3.0.0"
proxy-addr: "npm:^2.0.7"
rfdc: "npm:^1.3.0"
secure-json-parse: "npm:^2.7.0"
semver: "npm:^7.5.4"
toad-cache: "npm:^3.3.0"
checksum: 10c0/9c212e9a72c42a27ebc9b0bc7fda8f94ff208250158093374942b0e156a3f55fa848c926921f99bdf7f38f6f8103ac28ecc72cc507f33893cd121ce4f3eda069
languageName: node
linkType: hard
"fastq@npm:^1.17.1":
version: 1.17.1
resolution: "fastq@npm:1.17.1"
dependencies:
reusify: "npm:^1.0.4"
checksum: 10c0/1095f16cea45fb3beff558bb3afa74ca7a9250f5a670b65db7ed585f92b4b48381445cd328b3d87323da81e43232b5d5978a8201bde84e0cd514310f1ea6da34
languageName: node
linkType: hard
"figures@npm:^6.1.0":
version: 6.1.0
resolution: "figures@npm:6.1.0"
dependencies:
is-unicode-supported: "npm:^2.0.0"
checksum: 10c0/9159df4264d62ef447a3931537de92f5012210cf5135c35c010df50a2169377581378149abfe1eb238bd6acbba1c0d547b1f18e0af6eee49e30363cedaffcfe4
languageName: node
linkType: hard
"find-my-way@npm:^8.0.0":
version: 8.2.0
resolution: "find-my-way@npm:8.2.0"
dependencies:
fast-deep-equal: "npm:^3.1.3"
fast-querystring: "npm:^1.0.0"
safe-regex2: "npm:^3.1.0"
checksum: 10c0/f0f0370215f7b693729483481cd8c642a2e42e7ec7296f099faf46c523a3cac2bcafc24229dc971f87def36c5fa1fdf7f08a7238144affd2ab3c57f75b9aaca6
languageName: node
linkType: hard
"forwarded@npm:0.2.0":
version: 0.2.0
resolution: "forwarded@npm:0.2.0"
checksum: 10c0/9b67c3fac86acdbc9ae47ba1ddd5f2f81526fa4c8226863ede5600a3f7c7416ef451f6f1e240a3cc32d0fd79fcfe6beb08fd0da454f360032bde70bf80afbb33
languageName: node
linkType: hard
"generate-function@npm:^2.3.1":
version: 2.3.1
resolution: "generate-function@npm:2.3.1"
dependencies:
is-property: "npm:^1.0.2"
checksum: 10c0/4645cf1da90375e46a6f1dc51abc9933e5eafa4cd1a44c2f7e3909a30a4e9a1a08c14cd7d5b32da039da2dba2a085e1ed4597b580c196c3245b2d35d8bc0de5d
languageName: node
linkType: hard
"get-stream@npm:^9.0.0":
version: 9.0.1
resolution: "get-stream@npm:9.0.1"
dependencies:
"@sec-ant/readable-stream": "npm:^0.4.1"
is-stream: "npm:^4.0.1"
checksum: 10c0/d70e73857f2eea1826ac570c3a912757dcfbe8a718a033fa0c23e12ac8e7d633195b01710e0559af574cbb5af101009b42df7b6f6b29ceec8dbdf7291931b948
languageName: node
linkType: hard
"human-signals@npm:^7.0.0":
version: 7.0.0
resolution: "human-signals@npm:7.0.0"
checksum: 10c0/ce0c6d62d2e9bfe529d48f7c7fdf4b8c70fce950eef7850719b4e3f5bc71795ae7d61a3699ce13262bed7847705822601cc81f1921ea6a2906852e16228a94ab
languageName: node
linkType: hard
"iconv-lite@npm:^0.6.3":
version: 0.6.3
resolution: "iconv-lite@npm:0.6.3"
dependencies:
safer-buffer: "npm:>= 2.1.2 < 3.0.0"
checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1
languageName: node
linkType: hard
"ieee754@npm:^1.2.1":
version: 1.2.1
resolution: "ieee754@npm:1.2.1"
checksum: 10c0/b0782ef5e0935b9f12883a2e2aa37baa75da6e66ce6515c168697b42160807d9330de9a32ec1ed73149aea02e0d822e572bca6f1e22bdcbd2149e13b050b17bb
languageName: node
linkType: hard
"ip6addr@npm:^0.2.5":
version: 0.2.5
resolution: "ip6addr@npm:0.2.5"
dependencies:
assert-plus: "npm:^1.0.0"
jsprim: "npm:^2.0.2"
checksum: 10c0/aaa16f844d57d2c8afca375dabb42a62e6990ea044e397bf50e18bea8b445ae0978df6fae5898c898edfd6b58cc3d3c557f405a34792739be912cd303563a916
languageName: node
linkType: hard
"ipaddr.js@npm:1.9.1":
version: 1.9.1
resolution: "ipaddr.js@npm:1.9.1"
checksum: 10c0/0486e775047971d3fdb5fb4f063829bac45af299ae0b82dcf3afa2145338e08290563a2a70f34b732d795ecc8311902e541a8530eeb30d75860a78ff4e94ce2a
languageName: node
linkType: hard
"is-plain-obj@npm:^4.1.0":
version: 4.1.0
resolution: "is-plain-obj@npm:4.1.0"
checksum: 10c0/32130d651d71d9564dc88ba7e6fda0e91a1010a3694648e9f4f47bb6080438140696d3e3e15c741411d712e47ac9edc1a8a9de1fe76f3487b0d90be06ac9975e
languageName: node
linkType: hard
"is-property@npm:^1.0.2":
version: 1.0.2
resolution: "is-property@npm:1.0.2"
checksum: 10c0/33ab65a136e4ba3f74d4f7d9d2a013f1bd207082e11cedb160698e8d5394644e873c39668d112a402175ccbc58a087cef87198ed46829dbddb479115a0257283
languageName: node
linkType: hard
"is-stream@npm:^4.0.1":
version: 4.0.1
resolution: "is-stream@npm:4.0.1"
checksum: 10c0/2706c7f19b851327ba374687bc4a3940805e14ca496dc672b9629e744d143b1ad9c6f1b162dece81c7bfbc0f83b32b61ccc19ad2e05aad2dd7af347408f60c7f
languageName: node
linkType: hard
"is-unicode-supported@npm:^2.0.0":
version: 2.0.0
resolution: "is-unicode-supported@npm:2.0.0"
checksum: 10c0/3013dfb8265fe9f9a0d1e9433fc4e766595631a8d85d60876c457b4bedc066768dab1477c553d02e2f626d88a4e019162706e04263c94d74994ef636a33b5f94
languageName: node
linkType: hard
"isexe@npm:^2.0.0":
version: 2.0.0
resolution: "isexe@npm:2.0.0"
checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d
languageName: node
linkType: hard
"json-schema-ref-resolver@npm:^1.0.1":
version: 1.0.1
resolution: "json-schema-ref-resolver@npm:1.0.1"
dependencies:
fast-deep-equal: "npm:^3.1.3"
checksum: 10c0/aa89d88108c0109ae35b913c89c132fb50c00f3b99fc8a8309b524b9e3a6a77414f19a6a35a1253871462984cbabc74279ebbd9bf103c6629fb7b37c9fb59bcf
languageName: node
linkType: hard
"json-schema-traverse@npm:^1.0.0":
version: 1.0.0
resolution: "json-schema-traverse@npm:1.0.0"
checksum: 10c0/71e30015d7f3d6dc1c316d6298047c8ef98a06d31ad064919976583eb61e1018a60a0067338f0f79cabc00d84af3fcc489bd48ce8a46ea165d9541ba17fb30c6
languageName: node
linkType: hard
"json-schema@npm:0.4.0":
version: 0.4.0
resolution: "json-schema@npm:0.4.0"
checksum: 10c0/d4a637ec1d83544857c1c163232f3da46912e971d5bf054ba44fdb88f07d8d359a462b4aec46f2745efbc57053365608d88bc1d7b1729f7b4fc3369765639ed3
languageName: node
linkType: hard
"jsprim@npm:^2.0.2":
version: 2.0.2
resolution: "jsprim@npm:2.0.2"
dependencies:
assert-plus: "npm:1.0.0"
extsprintf: "npm:1.3.0"
json-schema: "npm:0.4.0"
verror: "npm:1.10.0"
checksum: 10c0/677be2d41df536c92c6d0114a492ef197084018cfbb1a3e10b1fa1aad889564b2e3a7baa6af7949cc2d73678f42368b0be165a26bd4e4de6883a30dd6a24e98d
languageName: node
linkType: hard
"light-my-request@npm:^5.11.0":
version: 5.13.0
resolution: "light-my-request@npm:5.13.0"
dependencies:
cookie: "npm:^0.6.0"
process-warning: "npm:^3.0.0"
set-cookie-parser: "npm:^2.4.1"
checksum: 10c0/460117f30e09c2eec3a62e6ba4264111a28b881fdd0ea79493ed889ebf69a56482d603f0685a0e2930b5ec53205d28c46f3cdf13d7888914852eb7c4dac83285
languageName: node
linkType: hard
"long@npm:^5.2.1":
version: 5.2.3
resolution: "long@npm:5.2.3"
checksum: 10c0/6a0da658f5ef683b90330b1af76f06790c623e148222da9d75b60e266bbf88f803232dd21464575681638894a84091616e7f89557aa087fd14116c0f4e0e43d9
languageName: node
linkType: hard
"lru-cache@npm:^7.14.1":
version: 7.18.3
resolution: "lru-cache@npm:7.18.3"
checksum: 10c0/b3a452b491433db885beed95041eb104c157ef7794b9c9b4d647be503be91769d11206bb573849a16b4cc0d03cbd15ffd22df7960997788b74c1d399ac7a4fed
languageName: node
linkType: hard
"lru-cache@npm:^8.0.0":
version: 8.0.5
resolution: "lru-cache@npm:8.0.5"
checksum: 10c0/cd95a9c38497611c5a6453de39a881f6eb5865851a2a01b5f14104ff3fee515362a7b1e7de28606028f423802910ba05bdb8ae1aa7b0d54eae70c92f0cec10b2
languageName: node
linkType: hard
"maxmind@npm:^4.2.0":
version: 4.3.20
resolution: "maxmind@npm:4.3.20"
dependencies:
mmdb-lib: "npm:2.1.1"
tiny-lru: "npm:11.2.6"
checksum: 10c0/f21b366f7c2bf7f6853eeea52478e53dd1052ad75f6f45c270258d5ff023c5f4a85c577d6b1ebdb0a8734073e24df5ed66375cdac0c3159a8f8ae30c6535149d
languageName: node
linkType: hard
"mmdb-lib@npm:2.1.1":
version: 2.1.1
resolution: "mmdb-lib@npm:2.1.1"
checksum: 10c0/675817303af64c21be02e9550ce885b6ffcc6fbbeae7959a189493ccf68c6b7bac74afa00376fd7a421ff2acd8f74f44fc7fd25aeed0675fc21dbc1a9d5df9f9
languageName: node
linkType: hard
"mysql2@npm:^3.10.3":
version: 3.10.3
resolution: "mysql2@npm:3.10.3"
dependencies:
aws-ssl-profiles: "npm:^1.1.1"
denque: "npm:^2.1.0"
generate-function: "npm:^2.3.1"
iconv-lite: "npm:^0.6.3"
long: "npm:^5.2.1"
lru-cache: "npm:^8.0.0"
named-placeholders: "npm:^1.1.3"
seq-queue: "npm:^0.0.5"
sqlstring: "npm:^2.3.2"
checksum: 10c0/20fd51c1f7998e10bf670ba9440e656652b6286d9504a2fd65f2181543867823ca4f1d720a783db0d8cf37eddb7addb9fce4ab421a9054114a97f59a1ddadd7d
languageName: node
linkType: hard
"named-placeholders@npm:^1.1.3":
version: 1.1.3
resolution: "named-placeholders@npm:1.1.3"
dependencies:
lru-cache: "npm:^7.14.1"
checksum: 10c0/cd83b4bbdf358b2285e3c51260fac2039c9d0546632b8a856b3eeabd3bfb3d5b597507ab319b97c281a4a70d748f38bc66fa218a61cb44f55ad997ad5d9c9935
languageName: node
linkType: hard
"npm-run-path@npm:^5.2.0":
version: 5.3.0
resolution: "npm-run-path@npm:5.3.0"
dependencies:
path-key: "npm:^4.0.0"
checksum: 10c0/124df74820c40c2eb9a8612a254ea1d557ddfab1581c3e751f825e3e366d9f00b0d76a3c94ecd8398e7f3eee193018622677e95816e8491f0797b21e30b2deba
languageName: node
linkType: hard
"on-exit-leak-free@npm:^2.1.0":
version: 2.1.2
resolution: "on-exit-leak-free@npm:2.1.2"
checksum: 10c0/faea2e1c9d696ecee919026c32be8d6a633a7ac1240b3b87e944a380e8a11dc9c95c4a1f8fb0568de7ab8db3823e790f12bda45296b1d111e341aad3922a0570
languageName: node
linkType: hard
"parse-ms@npm:^4.0.0":
version: 4.0.0
resolution: "parse-ms@npm:4.0.0"
checksum: 10c0/a7900f4f1ebac24cbf5e9708c16fb2fd482517fad353aecd7aefb8c2ba2f85ce017913ccb8925d231770404780df46244ea6fec598b3bde6490882358b4d2d16
languageName: node
linkType: hard
"path-key@npm:^3.1.0":
version: 3.1.1
resolution: "path-key@npm:3.1.1"
checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c
languageName: node
linkType: hard
"path-key@npm:^4.0.0":
version: 4.0.0
resolution: "path-key@npm:4.0.0"
checksum: 10c0/794efeef32863a65ac312f3c0b0a99f921f3e827ff63afa5cb09a377e202c262b671f7b3832a4e64731003fa94af0263713962d317b9887bd1e0c48a342efba3
languageName: node
linkType: hard
"pino-abstract-transport@npm:^1.2.0":
version: 1.2.0
resolution: "pino-abstract-transport@npm:1.2.0"
dependencies:
readable-stream: "npm:^4.0.0"
split2: "npm:^4.0.0"
checksum: 10c0/b4ab59529b7a91f488440147fc58ee0827a6c1c5ca3627292339354b1381072c1a6bfa9b46d03ad27872589e8477ecf74da12cf286e1e6b665ac64a3b806bf07
languageName: node
linkType: hard
"pino-std-serializers@npm:^7.0.0":
version: 7.0.0
resolution: "pino-std-serializers@npm:7.0.0"
checksum: 10c0/73e694d542e8de94445a03a98396cf383306de41fd75ecc07085d57ed7a57896198508a0dec6eefad8d701044af21eb27253ccc352586a03cf0d4a0bd25b4133