equipped 5.3.0 → 5.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/cjs/cache/adapters/in-memory/index.cjs +155 -155
- package/dist/cjs/cache/adapters/in-memory/index.cjs.map +1 -1
- package/dist/cjs/cache/adapters/in-memory/index.min.cjs +3 -3
- package/dist/cjs/cache/adapters/in-memory/index.min.cjs.map +1 -1
- package/dist/cjs/dbs/adapters/mongodb/index.cjs.map +1 -1
- package/dist/cjs/dbs/adapters/mongodb/index.min.cjs +2 -2
- package/dist/cjs/dbs/adapters/mongodb/index.min.cjs.map +1 -1
- package/dist/cjs/dbs/index.cjs +181 -179
- package/dist/cjs/dbs/index.cjs.map +1 -1
- package/dist/cjs/dbs/index.min.cjs +3 -3
- package/dist/cjs/dbs/index.min.cjs.map +1 -1
- package/dist/cjs/events/adapters/kafka/index.cjs.map +1 -1
- package/dist/cjs/events/adapters/kafka/index.min.cjs +2 -2
- package/dist/cjs/events/adapters/kafka/index.min.cjs.map +1 -1
- package/dist/cjs/events/adapters/rabbitmq/index.cjs +179 -179
- package/dist/cjs/events/adapters/rabbitmq/index.cjs.map +1 -1
- package/dist/cjs/events/adapters/rabbitmq/index.min.cjs +3 -3
- package/dist/cjs/events/adapters/rabbitmq/index.min.cjs.map +1 -1
- package/dist/cjs/orm/adapters/mongodb/index.cjs +144 -144
- package/dist/cjs/orm/adapters/mongodb/index.cjs.map +1 -1
- package/dist/cjs/orm/adapters/mongodb/index.min.cjs +1 -1
- package/dist/cjs/orm/adapters/mongodb/index.min.cjs.map +1 -1
- package/dist/cjs/orm/adapters/postgresql/index.cjs +144 -215
- package/dist/cjs/orm/adapters/postgresql/index.cjs.map +1 -1
- package/dist/cjs/orm/adapters/postgresql/index.min.cjs +11 -11
- package/dist/cjs/orm/adapters/postgresql/index.min.cjs.map +1 -1
- package/dist/cjs/server/adapters/express/index.cjs +338 -226
- package/dist/cjs/server/adapters/express/index.cjs.map +1 -1
- package/dist/cjs/server/adapters/express/index.min.cjs +7 -7
- package/dist/cjs/server/adapters/express/index.min.cjs.map +1 -1
- package/dist/cjs/server/adapters/fastify/index.cjs +323 -211
- package/dist/cjs/server/adapters/fastify/index.cjs.map +1 -1
- package/dist/cjs/server/adapters/fastify/index.min.cjs +7 -7
- package/dist/cjs/server/adapters/fastify/index.min.cjs.map +1 -1
- package/dist/cjs/server/index.cjs +128 -16
- package/dist/cjs/server/index.cjs.map +1 -1
- package/dist/cjs/server/index.min.cjs +6 -6
- package/dist/cjs/server/index.min.cjs.map +1 -1
- package/dist/cjs/utilities/index.cjs +0 -5
- package/dist/cjs/utilities/index.cjs.map +1 -1
- package/dist/cjs/utilities/index.min.cjs +2 -2
- package/dist/cjs/utilities/index.min.cjs.map +1 -1
- package/dist/esm/cache/adapters/in-memory/index.min.mjs +1 -1
- package/dist/esm/cache/adapters/in-memory/index.min.mjs.map +1 -1
- package/dist/esm/cache/adapters/in-memory/index.mjs +6 -3
- package/dist/esm/cache/adapters/in-memory/index.mjs.map +1 -1
- package/dist/esm/cache/adapters/redis/index.min.mjs +1 -1
- package/dist/esm/cache/adapters/redis/index.mjs +5 -3
- package/dist/esm/cache/index.min.mjs +1 -1
- package/dist/esm/cache/index.mjs +2 -2
- package/dist/esm/{chunk-PNZNNUMN.mjs → chunk-26BOI6IL.mjs} +7 -5
- package/dist/esm/{chunk-PNZNNUMN.mjs.map → chunk-26BOI6IL.mjs.map} +1 -1
- package/dist/esm/{chunk-4JLDXF7T.min.mjs → chunk-AODOD22O.min.mjs} +2 -2
- package/dist/esm/chunk-APSDCRY5.min.mjs +32 -0
- package/dist/esm/chunk-APSDCRY5.min.mjs.map +1 -0
- package/dist/esm/{chunk-MDQKODYQ.mjs → chunk-CEYT5YBA.mjs} +204 -348
- package/dist/esm/chunk-CEYT5YBA.mjs.map +1 -0
- package/dist/esm/chunk-CU2HU5UE.min.mjs +2 -0
- package/dist/esm/chunk-CU2HU5UE.min.mjs.map +1 -0
- package/dist/esm/chunk-DAK7OKSH.min.mjs +2 -0
- package/dist/esm/{chunk-SGZNOYC3.min.mjs.map → chunk-DAK7OKSH.min.mjs.map} +1 -1
- package/dist/esm/{chunk-PCAUXBAG.min.mjs → chunk-DAUQA32Q.min.mjs} +2 -2
- package/dist/esm/{chunk-JH6EBXY4.mjs → chunk-FQYRVHQT.mjs} +2 -2
- package/dist/esm/chunk-NEF3UYFA.mjs +144 -0
- package/dist/esm/chunk-NEF3UYFA.mjs.map +1 -0
- package/dist/esm/chunk-NNFUYHQ7.mjs +135 -0
- package/dist/esm/chunk-NNFUYHQ7.mjs.map +1 -0
- package/dist/esm/{chunk-4MXYZS5R.mjs → chunk-PCEHFZ6G.mjs} +9 -5
- package/dist/esm/{chunk-4MXYZS5R.mjs.map → chunk-PCEHFZ6G.mjs.map} +1 -1
- package/dist/esm/{chunk-B5QQ32YY.min.mjs → chunk-QCCDJLBH.min.mjs} +2 -2
- package/dist/esm/{chunk-PQCBVQL6.mjs → chunk-RIXTQQUU.mjs} +2 -2
- package/dist/esm/{chunk-Z2TZ3KR7.mjs → chunk-RPPYCWXW.mjs} +2 -2
- package/dist/esm/{chunk-AKQBDYUO.mjs → chunk-T2O72JBW.mjs} +3 -3
- package/dist/esm/{chunk-TVTYDU2D.mjs → chunk-VQO4MSEC.mjs} +5 -5
- package/dist/esm/{chunk-ZGMFFK6Y.min.mjs → chunk-X7VNAGLR.min.mjs} +2 -2
- package/dist/esm/chunk-XTXAEBXY.min.mjs +2 -0
- package/dist/esm/{chunk-5VW3JAFR.min.mjs.map → chunk-XTXAEBXY.min.mjs.map} +1 -1
- package/dist/esm/{chunk-QHLKB47N.min.mjs → chunk-YDQW6ETS.min.mjs} +2 -2
- package/dist/esm/chunk-ZDBDR3IB.min.mjs +2 -0
- package/dist/esm/chunk-ZDBDR3IB.min.mjs.map +1 -0
- package/dist/esm/dbs/adapters/mongodb/index.min.mjs +1 -1
- package/dist/esm/dbs/adapters/mongodb/index.min.mjs.map +1 -1
- package/dist/esm/dbs/adapters/mongodb/index.mjs +8 -5
- package/dist/esm/dbs/adapters/mongodb/index.mjs.map +1 -1
- package/dist/esm/dbs/index.min.mjs +1 -1
- package/dist/esm/dbs/index.mjs +5 -3
- package/dist/esm/errors/index.min.mjs +1 -1
- package/dist/esm/errors/index.mjs +1 -1
- package/dist/esm/events/adapters/kafka/index.min.mjs +1 -1
- package/dist/esm/events/adapters/kafka/index.mjs +4 -2
- package/dist/esm/events/adapters/rabbitmq/index.min.mjs +1 -1
- package/dist/esm/events/adapters/rabbitmq/index.min.mjs.map +1 -1
- package/dist/esm/events/adapters/rabbitmq/index.mjs +7 -3
- package/dist/esm/events/adapters/rabbitmq/index.mjs.map +1 -1
- package/dist/esm/index.min.mjs +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/instance/index.min.mjs +1 -1
- package/dist/esm/instance/index.mjs +1 -1
- package/dist/esm/{introspection-32BRYKYY.mjs → introspection-FGDVYTPP.mjs} +3 -3
- package/dist/esm/introspection-UDWDS6DV.min.mjs +2 -0
- package/dist/esm/jobs/adapters/redis/index.min.mjs +1 -1
- package/dist/esm/jobs/adapters/redis/index.min.mjs.map +1 -1
- package/dist/esm/jobs/adapters/redis/index.mjs +10 -6
- package/dist/esm/jobs/adapters/redis/index.mjs.map +1 -1
- package/dist/esm/orm/adapters/in-memory/index.min.mjs +1 -1
- package/dist/esm/orm/adapters/in-memory/index.mjs +4 -3
- package/dist/esm/orm/adapters/json/index.min.mjs +1 -1
- package/dist/esm/orm/adapters/json/index.min.mjs.map +1 -1
- package/dist/esm/orm/adapters/json/index.mjs +6 -5
- package/dist/esm/orm/adapters/json/index.mjs.map +1 -1
- package/dist/esm/orm/adapters/mongodb/index.min.mjs +1 -1
- package/dist/esm/orm/adapters/mongodb/index.min.mjs.map +1 -1
- package/dist/esm/orm/adapters/mongodb/index.mjs +6 -4
- package/dist/esm/orm/adapters/mongodb/index.mjs.map +1 -1
- package/dist/esm/orm/adapters/postgresql/index.min.mjs +2 -2
- package/dist/esm/orm/adapters/postgresql/index.min.mjs.map +1 -1
- package/dist/esm/orm/adapters/postgresql/index.mjs +8 -5
- package/dist/esm/orm/adapters/postgresql/index.mjs.map +1 -1
- package/dist/esm/orm/index.min.mjs +1 -1
- package/dist/esm/orm/index.mjs +3 -3
- package/dist/esm/server/adapters/express/index.min.mjs +1 -1
- package/dist/esm/server/adapters/express/index.min.mjs.map +1 -1
- package/dist/esm/server/adapters/express/index.mjs +7 -3
- package/dist/esm/server/adapters/express/index.mjs.map +1 -1
- package/dist/esm/server/adapters/fastify/index.min.mjs +1 -1
- package/dist/esm/server/adapters/fastify/index.min.mjs.map +1 -1
- package/dist/esm/server/adapters/fastify/index.mjs +7 -3
- package/dist/esm/server/adapters/fastify/index.mjs.map +1 -1
- package/dist/esm/server/index.min.mjs +1 -1
- package/dist/esm/server/index.mjs +1 -1
- package/dist/esm/utilities/index.min.mjs +1 -1
- package/dist/esm/utilities/index.mjs +5 -4
- package/dist/esm/validations/index.min.mjs +1 -1
- package/dist/esm/validations/index.mjs +1 -1
- package/dist/types/{base-DVr0fHil.d.ts → base-qDndMBf8.d.ts} +9 -3
- package/dist/types/cache/adapters/in-memory/index.js +7 -4
- package/dist/types/cache/adapters/redis/index.js +5 -3
- package/dist/types/cache/index.js +2 -2
- package/dist/types/{chunk-NJ2FHI3U.js → chunk-35CDCTLR.js} +4 -4
- package/dist/types/{chunk-XGGGAEET.js → chunk-4YQA5GPT.js} +8 -4
- package/dist/types/{chunk-65EHKCDZ.js → chunk-AQIV47BY.js} +6 -4
- package/dist/types/{chunk-YTY3EFNB.js → chunk-BKDWUJRG.js} +203 -347
- package/dist/types/{chunk-JQ2FWX4W.js → chunk-DA2VYP7D.js} +1 -1
- package/dist/types/{chunk-3TKJGSCZ.js → chunk-GDMGPX4C.js} +1 -1
- package/dist/types/chunk-H5V6ADFD.js +134 -0
- package/dist/types/{chunk-3M4PBZAQ.js → chunk-OOKJEMQI.js} +2 -2
- package/dist/types/chunk-PPD4WDG6.js +143 -0
- package/dist/types/{chunk-OHFTQGQG.js → chunk-T7K7PO6G.js} +1 -1
- package/dist/types/dbs/adapters/mongodb/index.js +8 -5
- package/dist/types/dbs/index.js +5 -3
- package/dist/types/errors/index.js +1 -1
- package/dist/types/events/adapters/kafka/index.js +4 -2
- package/dist/types/events/adapters/rabbitmq/index.js +7 -3
- package/dist/types/index.js +1 -1
- package/dist/types/instance/index.js +1 -1
- package/dist/types/{introspection-VOIU3XE6.js → introspection-FSNS33CQ.js} +2 -2
- package/dist/types/jobs/adapters/redis/index.js +10 -6
- package/dist/types/orm/adapters/in-memory/index.js +4 -3
- package/dist/types/orm/adapters/json/index.js +6 -5
- package/dist/types/orm/adapters/mongodb/index.js +6 -4
- package/dist/types/orm/adapters/postgresql/index.js +8 -5
- package/dist/types/orm/index.js +3 -3
- package/dist/types/server/adapters/express/index.d.ts +1 -1
- package/dist/types/server/adapters/express/index.js +7 -3
- package/dist/types/server/adapters/fastify/index.d.ts +1 -1
- package/dist/types/server/adapters/fastify/index.js +7 -3
- package/dist/types/server/index.d.ts +2 -2
- package/dist/types/server/index.js +1 -1
- package/dist/types/utilities/index.d.ts +1 -2
- package/dist/types/utilities/index.js +5 -4
- package/dist/types/validations/index.js +1 -1
- package/package.json +1 -1
- package/dist/esm/chunk-5VW3JAFR.min.mjs +0 -2
- package/dist/esm/chunk-FLAPYQUT.min.mjs +0 -32
- package/dist/esm/chunk-FLAPYQUT.min.mjs.map +0 -1
- package/dist/esm/chunk-MDQKODYQ.mjs.map +0 -1
- package/dist/esm/chunk-SGZNOYC3.min.mjs +0 -2
- package/dist/esm/introspection-A72WMWE3.min.mjs +0 -2
- /package/dist/esm/{chunk-4JLDXF7T.min.mjs.map → chunk-AODOD22O.min.mjs.map} +0 -0
- /package/dist/esm/{chunk-PCAUXBAG.min.mjs.map → chunk-DAUQA32Q.min.mjs.map} +0 -0
- /package/dist/esm/{chunk-JH6EBXY4.mjs.map → chunk-FQYRVHQT.mjs.map} +0 -0
- /package/dist/esm/{chunk-B5QQ32YY.min.mjs.map → chunk-QCCDJLBH.min.mjs.map} +0 -0
- /package/dist/esm/{chunk-PQCBVQL6.mjs.map → chunk-RIXTQQUU.mjs.map} +0 -0
- /package/dist/esm/{chunk-Z2TZ3KR7.mjs.map → chunk-RPPYCWXW.mjs.map} +0 -0
- /package/dist/esm/{chunk-AKQBDYUO.mjs.map → chunk-T2O72JBW.mjs.map} +0 -0
- /package/dist/esm/{chunk-TVTYDU2D.mjs.map → chunk-VQO4MSEC.mjs.map} +0 -0
- /package/dist/esm/{chunk-ZGMFFK6Y.min.mjs.map → chunk-X7VNAGLR.min.mjs.map} +0 -0
- /package/dist/esm/{chunk-QHLKB47N.min.mjs.map → chunk-YDQW6ETS.min.mjs.map} +0 -0
- /package/dist/esm/{introspection-32BRYKYY.mjs.map → introspection-FGDVYTPP.mjs.map} +0 -0
- /package/dist/esm/{introspection-A72WMWE3.min.mjs.map → introspection-UDWDS6DV.min.mjs.map} +0 -0
|
@@ -19,12 +19,12 @@ __export(valleyed_exports, {
|
|
|
19
19
|
withResponse: () => withResponse
|
|
20
20
|
});
|
|
21
21
|
import { AsyncLocalStorage } from "async_hooks";
|
|
22
|
-
import { PipeError as PipeError2, v as
|
|
22
|
+
import { PipeError as PipeError2, v as v5 } from "valleyed";
|
|
23
23
|
|
|
24
24
|
// src/instance/index.ts
|
|
25
25
|
import pino from "pino";
|
|
26
26
|
import { ulid } from "ulid";
|
|
27
|
-
import { v as
|
|
27
|
+
import { v as v4 } from "valleyed";
|
|
28
28
|
|
|
29
29
|
// src/errors/equippedError.ts
|
|
30
30
|
var EquippedError = class extends Error {
|
|
@@ -51,7 +51,7 @@ import "@fastify/cors";
|
|
|
51
51
|
import "cors";
|
|
52
52
|
import { Server as SocketServer } from "socket.io";
|
|
53
53
|
import supertest from "supertest";
|
|
54
|
-
import { PipeError, v as
|
|
54
|
+
import { PipeError, v as v2 } from "valleyed";
|
|
55
55
|
|
|
56
56
|
// src/server/openapi.ts
|
|
57
57
|
import { convert } from "@openapi-contrib/json-schema-to-openapi-schema";
|
|
@@ -337,266 +337,6 @@ var openapi = (config) => {
|
|
|
337
337
|
};
|
|
338
338
|
};
|
|
339
339
|
|
|
340
|
-
// src/utilities/authProviders.ts
|
|
341
|
-
var authProviders_exports = {};
|
|
342
|
-
__export(authProviders_exports, {
|
|
343
|
-
signinWithApple: () => signinWithApple,
|
|
344
|
-
signinWithFacebook: () => signinWithFacebook,
|
|
345
|
-
signinWithGoogle: () => signinWithGoogle
|
|
346
|
-
});
|
|
347
|
-
import axios from "axios";
|
|
348
|
-
import jwt from "jsonwebtoken";
|
|
349
|
-
import jwksClient from "jwks-rsa";
|
|
350
|
-
var signinWithGoogle = async (idToken) => {
|
|
351
|
-
const authUrl = `https://oauth2.googleapis.com/tokeninfo?id_token=${idToken}`;
|
|
352
|
-
const { data } = await axios.get(authUrl).catch((err) => {
|
|
353
|
-
throw new EquippedError("Failed to sign in with google", { idToken }, err);
|
|
354
|
-
});
|
|
355
|
-
data.first_name = data.given_name;
|
|
356
|
-
data.last_name = data.family_name;
|
|
357
|
-
return data;
|
|
358
|
-
};
|
|
359
|
-
var signinWithApple = async (idToken) => {
|
|
360
|
-
try {
|
|
361
|
-
const APPLE_BASE = "https://appleid.apple.com";
|
|
362
|
-
const json = jwt.decode(idToken, { complete: true });
|
|
363
|
-
if (!json?.header) throw new EquippedError("Missing JWT header", { idToken, json });
|
|
364
|
-
const { kid, alg } = json.header;
|
|
365
|
-
const publicKey = await jwksClient({ jwksUri: `${APPLE_BASE}/auth/keys`, cache: true }).getSigningKey(kid).then((key) => key.getPublicKey()).catch(() => null);
|
|
366
|
-
if (!publicKey) throw new EquippedError("no publicKey", { idToken, publicKey, json });
|
|
367
|
-
const data = jwt.verify(idToken, publicKey, { algorithms: [alg] });
|
|
368
|
-
if (!data) throw new EquippedError("no data", { idToken, data });
|
|
369
|
-
if (data.iss !== APPLE_BASE) throw new EquippedError("iss doesnt match", { idToken, data });
|
|
370
|
-
if (data.exp * 1e3 < Date.now()) throw new EquippedError("expired idToken", { idToken, data });
|
|
371
|
-
return data;
|
|
372
|
-
} catch (err) {
|
|
373
|
-
throw new EquippedError("Failed to sign in with apple", { idToken }, err);
|
|
374
|
-
}
|
|
375
|
-
};
|
|
376
|
-
var signinWithFacebook = async (accessToken, fields = []) => {
|
|
377
|
-
fields = [.../* @__PURE__ */ new Set([...fields, "name", "picture", "email"])];
|
|
378
|
-
const { data } = await axios.request({
|
|
379
|
-
method: "get",
|
|
380
|
-
url: "https://graph.facebook.com/v15.0/me",
|
|
381
|
-
params: {
|
|
382
|
-
fields: fields.join(","),
|
|
383
|
-
access_token: accessToken
|
|
384
|
-
}
|
|
385
|
-
}).catch((err) => {
|
|
386
|
-
throw new EquippedError("Failed to sign in with facebook", { accessToken, fields }, err);
|
|
387
|
-
});
|
|
388
|
-
const isValidData = fields.every((key) => key in data);
|
|
389
|
-
if (!isValidData) throw new EquippedError("Incomplete scope for access token", { accessToken, fields, data });
|
|
390
|
-
data.email_verified = "true";
|
|
391
|
-
return data;
|
|
392
|
-
};
|
|
393
|
-
|
|
394
|
-
// src/utilities/configurable.ts
|
|
395
|
-
import { v as v2 } from "valleyed";
|
|
396
|
-
function configurable(pipeFn, base) {
|
|
397
|
-
const pipe = pipeFn();
|
|
398
|
-
v2.compile(pipe);
|
|
399
|
-
class Configurable extends base {
|
|
400
|
-
constructor(config, ...baseArgs) {
|
|
401
|
-
super(...baseArgs);
|
|
402
|
-
this.config = config;
|
|
403
|
-
}
|
|
404
|
-
static create(input, ...args) {
|
|
405
|
-
const r = v2.validate(pipe, input);
|
|
406
|
-
if (!r.valid) throw r.error;
|
|
407
|
-
return new this(r.value, ...args);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
return Configurable;
|
|
411
|
-
}
|
|
412
|
-
if (void 0) {
|
|
413
|
-
const { describe, test, expect, expectTypeOf } = void 0;
|
|
414
|
-
const { v: v8 } = await null;
|
|
415
|
-
const testPipe = () => v8.object({
|
|
416
|
-
host: v8.string(),
|
|
417
|
-
port: v8.number()
|
|
418
|
-
});
|
|
419
|
-
class TestBase {
|
|
420
|
-
baseValue;
|
|
421
|
-
constructor() {
|
|
422
|
-
this.baseValue = "base";
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
class TestBaseWithArgs {
|
|
426
|
-
label;
|
|
427
|
-
constructor(label) {
|
|
428
|
-
this.label = label;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
describe("configurable", () => {
|
|
432
|
-
test("validation runs in static create before constructor body executes", () => {
|
|
433
|
-
let constructorRan = false;
|
|
434
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
435
|
-
class MyClass extends Wrapped {
|
|
436
|
-
constructor(config) {
|
|
437
|
-
super(config);
|
|
438
|
-
constructorRan = true;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
expect(() => MyClass.create({ host: 123, port: "bad" })).toThrow();
|
|
442
|
-
expect(constructorRan).toBe(false);
|
|
443
|
-
MyClass.create({ host: "localhost", port: 3e3 });
|
|
444
|
-
expect(constructorRan).toBe(true);
|
|
445
|
-
});
|
|
446
|
-
test("constructor receives validated value", () => {
|
|
447
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
448
|
-
let receivedConfig;
|
|
449
|
-
class MyClass extends Wrapped {
|
|
450
|
-
constructor(config) {
|
|
451
|
-
super(config);
|
|
452
|
-
receivedConfig = this.config;
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
MyClass.create({ host: "localhost", port: 3e3 });
|
|
456
|
-
expect(receivedConfig).toEqual({ host: "localhost", port: 3e3 });
|
|
457
|
-
});
|
|
458
|
-
test("external new is a compile error", () => {
|
|
459
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
460
|
-
class MyClass extends Wrapped {
|
|
461
|
-
constructor(config) {
|
|
462
|
-
super(config);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
void (() => new MyClass({ host: "localhost", port: 3e3 }));
|
|
466
|
-
});
|
|
467
|
-
test("static Config resolves to PipeOutput<P> at the type level", () => {
|
|
468
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
469
|
-
class MyClass extends Wrapped {
|
|
470
|
-
constructor(config) {
|
|
471
|
-
super(config);
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
expectTypeOf().toEqualTypeOf();
|
|
475
|
-
expect(MyClass.create).toBeTypeOf("function");
|
|
476
|
-
});
|
|
477
|
-
test("ConstructorParameters<This>-based extras inference works for non-zero-arg leaf signatures", () => {
|
|
478
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
479
|
-
class MyClass extends Wrapped {
|
|
480
|
-
extra;
|
|
481
|
-
constructor(config, extra) {
|
|
482
|
-
super(config);
|
|
483
|
-
this.extra = extra;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
const instance = MyClass.create({ host: "localhost", port: 3e3 }, 42);
|
|
487
|
-
expect(instance.extra).toBe(42);
|
|
488
|
-
expectTypeOf(instance).toHaveProperty("extra");
|
|
489
|
-
expectTypeOf(instance.extra).toEqualTypeOf();
|
|
490
|
-
void (() => MyClass.create({ host: "localhost", port: 3e3 }, "not-a-number"));
|
|
491
|
-
});
|
|
492
|
-
test("base-args forwarding works for non-zero-arg bases", () => {
|
|
493
|
-
const Wrapped = configurable(testPipe, TestBaseWithArgs);
|
|
494
|
-
class MyClass extends Wrapped {
|
|
495
|
-
constructor(config, label) {
|
|
496
|
-
super(config, label);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
const instance = MyClass.create({ host: "localhost", port: 3e3 }, "test-label");
|
|
500
|
-
expect(instance.label).toBe("test-label");
|
|
501
|
-
});
|
|
502
|
-
test("config is accessible as protected readonly on instances", () => {
|
|
503
|
-
const Wrapped = configurable(testPipe, TestBase);
|
|
504
|
-
class MyClass extends Wrapped {
|
|
505
|
-
constructor(config) {
|
|
506
|
-
super(config);
|
|
507
|
-
}
|
|
508
|
-
getHost() {
|
|
509
|
-
return this.config.host;
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
const instance = MyClass.create({ host: "localhost", port: 3e3 });
|
|
513
|
-
expect(instance.getHost()).toBe("localhost");
|
|
514
|
-
});
|
|
515
|
-
test("accepts an abstract base class", () => {
|
|
516
|
-
class AbstractBase {
|
|
517
|
-
}
|
|
518
|
-
const Wrapped = configurable(testPipe, AbstractBase);
|
|
519
|
-
class Concrete extends Wrapped {
|
|
520
|
-
constructor(config) {
|
|
521
|
-
super(config);
|
|
522
|
-
}
|
|
523
|
-
greet() {
|
|
524
|
-
return `hello from ${this.config.host}`;
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
const instance = Concrete.create({ host: "localhost", port: 3e3 });
|
|
528
|
-
expect(instance.greet()).toBe("hello from localhost");
|
|
529
|
-
expectTypeOf(instance).toHaveProperty("config");
|
|
530
|
-
});
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
// src/utilities/hash.ts
|
|
535
|
-
var hash_exports = {};
|
|
536
|
-
__export(hash_exports, {
|
|
537
|
-
compare: () => compare2,
|
|
538
|
-
hash: () => hash2
|
|
539
|
-
});
|
|
540
|
-
import * as bcrypt from "bcryptjs";
|
|
541
|
-
var hash2 = async (password) => {
|
|
542
|
-
password = password.trim();
|
|
543
|
-
if (!password) return "";
|
|
544
|
-
return await bcrypt.hash(password, Instance.get().settings.utils.hashSaltRounds);
|
|
545
|
-
};
|
|
546
|
-
var compare2 = async (plainPassword, hashed) => {
|
|
547
|
-
plainPassword = plainPassword.trim();
|
|
548
|
-
if (!plainPassword && plainPassword === hashed) return true;
|
|
549
|
-
return await bcrypt.compare(plainPassword, hashed);
|
|
550
|
-
};
|
|
551
|
-
|
|
552
|
-
// src/utilities/json.ts
|
|
553
|
-
var parseJSONValue = (data) => {
|
|
554
|
-
try {
|
|
555
|
-
if (data?.constructor?.name !== "String") return data;
|
|
556
|
-
return JSON.parse(data);
|
|
557
|
-
} catch {
|
|
558
|
-
return data;
|
|
559
|
-
}
|
|
560
|
-
};
|
|
561
|
-
function parseJSONObject(data) {
|
|
562
|
-
return Object.fromEntries(Object.entries(data).map(([key, value]) => [key, parseJSONValue(value)]));
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
// src/utilities/media.ts
|
|
566
|
-
import { parseBuffer } from "music-metadata";
|
|
567
|
-
var getMediaDuration = async (buffer) => {
|
|
568
|
-
try {
|
|
569
|
-
const meta = await parseBuffer(buffer);
|
|
570
|
-
return meta.format.duration ?? 0;
|
|
571
|
-
} catch {
|
|
572
|
-
return 0;
|
|
573
|
-
}
|
|
574
|
-
};
|
|
575
|
-
|
|
576
|
-
// src/utilities/random.ts
|
|
577
|
-
var random_exports = {};
|
|
578
|
-
__export(random_exports, {
|
|
579
|
-
number: () => number,
|
|
580
|
-
string: () => string
|
|
581
|
-
});
|
|
582
|
-
import crypto from "crypto";
|
|
583
|
-
function string(length = 20) {
|
|
584
|
-
return crypto.randomBytes(length).toString("hex").slice(0, length);
|
|
585
|
-
}
|
|
586
|
-
function number(min = 0, max = 2 ** 48 - 1) {
|
|
587
|
-
return crypto.randomInt(min, max);
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
// src/utilities/retry.ts
|
|
591
|
-
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
592
|
-
var retry = async (cb, tries, waitTimeInMs) => {
|
|
593
|
-
if (tries <= 0) throw new EquippedError("out of tries", { tries, waitTimeInMs });
|
|
594
|
-
const result = await cb();
|
|
595
|
-
if (result.done === true) return result.value;
|
|
596
|
-
await sleep(waitTimeInMs);
|
|
597
|
-
return await retry(cb, tries - 1, waitTimeInMs);
|
|
598
|
-
};
|
|
599
|
-
|
|
600
340
|
// src/server/requests.ts
|
|
601
341
|
var Request = class {
|
|
602
342
|
ip;
|
|
@@ -625,8 +365,10 @@ var Request = class {
|
|
|
625
365
|
this.params = params;
|
|
626
366
|
this.cookies = cookies;
|
|
627
367
|
this.headers = headers;
|
|
628
|
-
|
|
629
|
-
|
|
368
|
+
const hasFiles = Object.keys(files).length > 0;
|
|
369
|
+
const bodyFields = body && typeof body === "object" && !Array.isArray(body) ? body : {};
|
|
370
|
+
this.query = query;
|
|
371
|
+
this.body = hasFiles ? Object.assign({}, bodyFields, files) : body;
|
|
630
372
|
}
|
|
631
373
|
pipe(stream, opts = {}) {
|
|
632
374
|
return new Response({ ...opts, piped: true, body: stream });
|
|
@@ -672,6 +414,83 @@ var Response = class {
|
|
|
672
414
|
});
|
|
673
415
|
}
|
|
674
416
|
};
|
|
417
|
+
if (void 0) {
|
|
418
|
+
const { describe, expect, test } = void 0;
|
|
419
|
+
describe("Request", () => {
|
|
420
|
+
test("preserves adapter-provided query and body values without JSON normalization", () => {
|
|
421
|
+
const query = {
|
|
422
|
+
count: "10",
|
|
423
|
+
active: "true",
|
|
424
|
+
filter: '{"name":"test"}',
|
|
425
|
+
quoted: '"value"'
|
|
426
|
+
};
|
|
427
|
+
const body = {
|
|
428
|
+
count: "10",
|
|
429
|
+
active: "false",
|
|
430
|
+
payload: '{"nested":true}',
|
|
431
|
+
quoted: '"value"'
|
|
432
|
+
};
|
|
433
|
+
const request = new Request({
|
|
434
|
+
ip: void 0,
|
|
435
|
+
body,
|
|
436
|
+
cookies: {},
|
|
437
|
+
params: {},
|
|
438
|
+
query,
|
|
439
|
+
method: "post",
|
|
440
|
+
path: "/items",
|
|
441
|
+
headers: {},
|
|
442
|
+
files: {}
|
|
443
|
+
});
|
|
444
|
+
expect(request.query).toEqual(query);
|
|
445
|
+
expect(request.body).toEqual(body);
|
|
446
|
+
});
|
|
447
|
+
test("continues merging uploaded files into body fields without parsing string fields", () => {
|
|
448
|
+
const file = {
|
|
449
|
+
name: "avatar.png",
|
|
450
|
+
type: "image/png",
|
|
451
|
+
size: 4,
|
|
452
|
+
isTruncated: false,
|
|
453
|
+
data: Buffer.from("file"),
|
|
454
|
+
duration: 0
|
|
455
|
+
};
|
|
456
|
+
const body = { metadata: '{"alt":"avatar"}' };
|
|
457
|
+
const request = new Request({
|
|
458
|
+
ip: void 0,
|
|
459
|
+
body,
|
|
460
|
+
cookies: {},
|
|
461
|
+
params: {},
|
|
462
|
+
query: {},
|
|
463
|
+
method: "post",
|
|
464
|
+
path: "/upload",
|
|
465
|
+
headers: {},
|
|
466
|
+
files: { avatar: [file] }
|
|
467
|
+
});
|
|
468
|
+
expect(request.body).toEqual({ metadata: '{"alt":"avatar"}', avatar: [file] });
|
|
469
|
+
});
|
|
470
|
+
test("does not spread non-object body values when uploaded files are present", () => {
|
|
471
|
+
const file = {
|
|
472
|
+
name: "avatar.png",
|
|
473
|
+
type: "image/png",
|
|
474
|
+
size: 4,
|
|
475
|
+
isTruncated: false,
|
|
476
|
+
data: Buffer.from("file"),
|
|
477
|
+
duration: 0
|
|
478
|
+
};
|
|
479
|
+
const request = new Request({
|
|
480
|
+
ip: void 0,
|
|
481
|
+
body: "raw text body",
|
|
482
|
+
cookies: {},
|
|
483
|
+
params: {},
|
|
484
|
+
query: {},
|
|
485
|
+
method: "post",
|
|
486
|
+
path: "/upload",
|
|
487
|
+
headers: {},
|
|
488
|
+
files: { avatar: [file] }
|
|
489
|
+
});
|
|
490
|
+
expect(request.body).toEqual({ avatar: [file] });
|
|
491
|
+
});
|
|
492
|
+
});
|
|
493
|
+
}
|
|
675
494
|
|
|
676
495
|
// src/server/requests-auth-methods/base.ts
|
|
677
496
|
import "http2";
|
|
@@ -709,7 +528,7 @@ var BaseApiKeyRequestAuthMethod = class extends BaseRequestAuthMethod {
|
|
|
709
528
|
|
|
710
529
|
// src/server/requests-auth-methods/jwt.ts
|
|
711
530
|
import cookie from "@fastify/cookie";
|
|
712
|
-
import
|
|
531
|
+
import jwt from "jsonwebtoken";
|
|
713
532
|
var BaseJwtRequestAuthMethod = class extends BaseRequestAuthMethod {
|
|
714
533
|
options;
|
|
715
534
|
constructor(options) {
|
|
@@ -720,14 +539,14 @@ var BaseJwtRequestAuthMethod = class extends BaseRequestAuthMethod {
|
|
|
720
539
|
return `${this.options.storagePrefix ?? ""}${userId}`;
|
|
721
540
|
}
|
|
722
541
|
async createToken(payload) {
|
|
723
|
-
const token =
|
|
542
|
+
const token = jwt.sign(payload, this.options.signingKey, { expiresIn: this.options.storageTTL });
|
|
724
543
|
await this.store(this.#getKey(payload.id), token, this.options.storageTTL);
|
|
725
544
|
return token;
|
|
726
545
|
}
|
|
727
546
|
async parse(headers) {
|
|
728
547
|
try {
|
|
729
548
|
const token = await this.parseHeader(headers);
|
|
730
|
-
const user =
|
|
549
|
+
const user = jwt.verify(token, this.options.signingKey);
|
|
731
550
|
if (!user) throw new NotAuthenticatedError();
|
|
732
551
|
if (this.options.enforceSingleSession) {
|
|
733
552
|
const cachedToken = await this.retrieve(this.#getKey(user.id));
|
|
@@ -736,7 +555,7 @@ var BaseJwtRequestAuthMethod = class extends BaseRequestAuthMethod {
|
|
|
736
555
|
return user;
|
|
737
556
|
} catch (err) {
|
|
738
557
|
if (err instanceof TokenExpired) throw err;
|
|
739
|
-
if (err instanceof
|
|
558
|
+
if (err instanceof jwt.TokenExpiredError) throw new TokenExpired(void 0, err);
|
|
740
559
|
else throw new NotAuthenticatedError(void 0, err);
|
|
741
560
|
}
|
|
742
561
|
}
|
|
@@ -891,50 +710,50 @@ var SocketEmitter = class {
|
|
|
891
710
|
};
|
|
892
711
|
|
|
893
712
|
// src/server/adapters/base.ts
|
|
894
|
-
var serverConfigPipe = () =>
|
|
895
|
-
port:
|
|
896
|
-
cors:
|
|
897
|
-
|
|
898
|
-
origin:
|
|
899
|
-
methods:
|
|
900
|
-
credentials:
|
|
713
|
+
var serverConfigPipe = () => v2.object({
|
|
714
|
+
port: v2.number(),
|
|
715
|
+
cors: v2.optional(
|
|
716
|
+
v2.object({
|
|
717
|
+
origin: v2.optional(v2.or([v2.array(v2.string()), v2.is(true)])),
|
|
718
|
+
methods: v2.optional(v2.array(v2.in(Object.values(Methods)))),
|
|
719
|
+
credentials: v2.optional(v2.boolean())
|
|
901
720
|
})
|
|
902
721
|
),
|
|
903
|
-
eventBus:
|
|
904
|
-
publicPath:
|
|
905
|
-
healthPath:
|
|
906
|
-
openapi:
|
|
907
|
-
|
|
908
|
-
docsVersion:
|
|
909
|
-
docsBaseUrl:
|
|
910
|
-
docsPath:
|
|
722
|
+
eventBus: v2.optional(v2.instanceOf(EventBus)),
|
|
723
|
+
publicPath: v2.optional(v2.string()),
|
|
724
|
+
healthPath: v2.optional(v2.string()),
|
|
725
|
+
openapi: v2.defaults(
|
|
726
|
+
v2.object({
|
|
727
|
+
docsVersion: v2.defaults(v2.string(), "1.0.0"),
|
|
728
|
+
docsBaseUrl: v2.defaults(v2.array(v2.string()), ["/"]),
|
|
729
|
+
docsPath: v2.defaults(v2.string(), "/__docs")
|
|
911
730
|
}),
|
|
912
731
|
{}
|
|
913
732
|
),
|
|
914
|
-
requests:
|
|
915
|
-
|
|
916
|
-
log:
|
|
917
|
-
rateLimit:
|
|
918
|
-
|
|
919
|
-
enabled:
|
|
920
|
-
periodInMs:
|
|
921
|
-
limit:
|
|
733
|
+
requests: v2.defaults(
|
|
734
|
+
v2.object({
|
|
735
|
+
log: v2.defaults(v2.boolean(), true),
|
|
736
|
+
rateLimit: v2.defaults(
|
|
737
|
+
v2.object({
|
|
738
|
+
enabled: v2.defaults(v2.boolean(), false),
|
|
739
|
+
periodInMs: v2.defaults(v2.number(), 60 * 60 * 1e3),
|
|
740
|
+
limit: v2.defaults(v2.number(), 5e3)
|
|
922
741
|
}),
|
|
923
742
|
{}
|
|
924
743
|
),
|
|
925
|
-
slowdown:
|
|
926
|
-
|
|
927
|
-
enabled:
|
|
928
|
-
periodInMs:
|
|
929
|
-
delayAfter:
|
|
930
|
-
delayInMs:
|
|
744
|
+
slowdown: v2.defaults(
|
|
745
|
+
v2.object({
|
|
746
|
+
enabled: v2.defaults(v2.boolean(), false),
|
|
747
|
+
periodInMs: v2.defaults(v2.number(), 10 * 60 * 1e3),
|
|
748
|
+
delayAfter: v2.defaults(v2.number(), 2e3),
|
|
749
|
+
delayInMs: v2.defaults(v2.number(), 500)
|
|
931
750
|
}),
|
|
932
751
|
{}
|
|
933
752
|
)
|
|
934
753
|
}),
|
|
935
754
|
{}
|
|
936
755
|
),
|
|
937
|
-
socketsAuthMethods:
|
|
756
|
+
socketsAuthMethods: v2.defaults(v2.array(v2.instanceOf(BaseRequestAuthMethod)), [])
|
|
938
757
|
});
|
|
939
758
|
var rawResponseHandledSymbol = /* @__PURE__ */ Symbol("rawResponseHandled");
|
|
940
759
|
var rawResponseHandled = Object.freeze({ [rawResponseHandledSymbol]: true });
|
|
@@ -955,7 +774,7 @@ function writeRawHandlerError(response, error) {
|
|
|
955
774
|
var errorsSchemas = Object.entries(StatusCodes).filter(([, value]) => value > 399).map(([key, value]) => ({
|
|
956
775
|
status: value,
|
|
957
776
|
contentType: "application/json",
|
|
958
|
-
pipe:
|
|
777
|
+
pipe: v2.meta(v2.array(v2.object({ message: v2.string(), field: v2.optional(v2.string()) })), {
|
|
959
778
|
$refId: `Errors.${key}Response`,
|
|
960
779
|
description: `${key} Response`
|
|
961
780
|
})
|
|
@@ -969,6 +788,7 @@ var Server = class {
|
|
|
969
788
|
#queue = [];
|
|
970
789
|
#routesByKey = /* @__PURE__ */ new Set();
|
|
971
790
|
#started = false;
|
|
791
|
+
#beforeListenHandlers = [];
|
|
972
792
|
#notFoundHandler = null;
|
|
973
793
|
setup(httpServer, config) {
|
|
974
794
|
this.#httpServer = httpServer;
|
|
@@ -1024,6 +844,11 @@ var Server = class {
|
|
|
1024
844
|
this.#notFoundHandler = handler;
|
|
1025
845
|
return this;
|
|
1026
846
|
}
|
|
847
|
+
onBeforeListen(handler) {
|
|
848
|
+
if (this.#started) throw new EquippedError("Cannot add before-listen handler after server has started", {});
|
|
849
|
+
this.#beforeListenHandlers.push(handler);
|
|
850
|
+
return this;
|
|
851
|
+
}
|
|
1027
852
|
test() {
|
|
1028
853
|
return supertest(this.#httpServer);
|
|
1029
854
|
}
|
|
@@ -1057,6 +882,7 @@ var Server = class {
|
|
|
1057
882
|
});
|
|
1058
883
|
return await this.handleResponse(res, response);
|
|
1059
884
|
});
|
|
885
|
+
for (const handler of this.#beforeListenHandlers) await handler({ httpServer: this.#httpServer, port: config.port });
|
|
1060
886
|
const started = await this.startServer(config.port);
|
|
1061
887
|
if (started) Instance.get().log.info(`${instance.id}(${app.name}) service listening on port ${config.port}`);
|
|
1062
888
|
return started;
|
|
@@ -1105,37 +931,37 @@ var Server = class {
|
|
|
1105
931
|
{ key: "responseCookies", type: "response" }
|
|
1106
932
|
];
|
|
1107
933
|
defs.forEach((def) => {
|
|
1108
|
-
const pipe = schema[def.key] ??
|
|
934
|
+
const pipe = schema[def.key] ?? v2.any();
|
|
1109
935
|
if (def.skip) return;
|
|
1110
936
|
if (def.type === "request") {
|
|
1111
937
|
requestPipeDefs[def.key] = pipe;
|
|
1112
|
-
jsonSchema.request[def.key] =
|
|
938
|
+
jsonSchema.request[def.key] = v2.schema(pipe);
|
|
1113
939
|
}
|
|
1114
940
|
if (def.type === "response") {
|
|
1115
941
|
const pipeRecords = errorsSchemas.concat({ status: defaultStatusCode, contentType, pipe });
|
|
1116
|
-
responsePipeDefs[def.key] =
|
|
942
|
+
responsePipeDefs[def.key] = v2.any().pipe((input) => {
|
|
1117
943
|
const p = pipeRecords.find((rec) => rec.status === status)?.pipe;
|
|
1118
944
|
if (!p) throw PipeError.root(`schema not defined for status code: ${status}`, input);
|
|
1119
|
-
const r =
|
|
945
|
+
const r = v2.validate(p, input);
|
|
1120
946
|
if (!r.valid) throw r.error;
|
|
1121
947
|
return r.value;
|
|
1122
948
|
});
|
|
1123
949
|
jsonSchema.response[def.key] = pipeRecords.map((record) => ({
|
|
1124
950
|
status: record.status,
|
|
1125
951
|
contentType: record.contentType,
|
|
1126
|
-
schema:
|
|
952
|
+
schema: v2.schema(record.pipe)
|
|
1127
953
|
}));
|
|
1128
954
|
}
|
|
1129
955
|
});
|
|
1130
|
-
const requestPipe =
|
|
1131
|
-
|
|
1132
|
-
const responsePipe =
|
|
1133
|
-
|
|
956
|
+
const requestPipe = v2.object(requestPipeDefs);
|
|
957
|
+
v2.compile(requestPipe, { allErrors: true });
|
|
958
|
+
const responsePipe = v2.object(responsePipeDefs);
|
|
959
|
+
v2.compile(responsePipe, { allErrors: true });
|
|
1134
960
|
const validateRequest = async (request) => {
|
|
1135
961
|
if (!Object.keys(requestPipeDefs)) return request;
|
|
1136
962
|
const validity = requestLocalStorage.run(
|
|
1137
963
|
request,
|
|
1138
|
-
() =>
|
|
964
|
+
() => v2.validate(requestPipe, {
|
|
1139
965
|
params: request.params,
|
|
1140
966
|
headers: request.headers,
|
|
1141
967
|
query: request.query,
|
|
@@ -1157,7 +983,7 @@ var Server = class {
|
|
|
1157
983
|
contentType = response.contentType;
|
|
1158
984
|
const validity = responseLocalStorage.run(
|
|
1159
985
|
response,
|
|
1160
|
-
() =>
|
|
986
|
+
() => v2.validate(responsePipe, {
|
|
1161
987
|
responseHeaders: response.headers,
|
|
1162
988
|
responseCookies: Object.fromEntries(Object.entries(response.cookies).map(([key, val]) => [key, val.value])),
|
|
1163
989
|
response: response.body
|
|
@@ -1208,6 +1034,7 @@ if (void 0) {
|
|
|
1208
1034
|
const testInstanceState = globalThis;
|
|
1209
1035
|
class TestServer extends Server {
|
|
1210
1036
|
handledResponse = null;
|
|
1037
|
+
startedPorts = [];
|
|
1211
1038
|
notFoundHandler = null;
|
|
1212
1039
|
constructor() {
|
|
1213
1040
|
super();
|
|
@@ -1252,7 +1079,8 @@ if (void 0) {
|
|
|
1252
1079
|
registerNotFoundHandler(cb) {
|
|
1253
1080
|
this.notFoundHandler = cb;
|
|
1254
1081
|
}
|
|
1255
|
-
async startServer() {
|
|
1082
|
+
async startServer(port) {
|
|
1083
|
+
this.startedPorts.push(port);
|
|
1256
1084
|
return true;
|
|
1257
1085
|
}
|
|
1258
1086
|
async dispatchNotFound(path) {
|
|
@@ -1263,6 +1091,43 @@ if (void 0) {
|
|
|
1263
1091
|
return { handledResponse: this.handledResponse, rawResponse };
|
|
1264
1092
|
}
|
|
1265
1093
|
}
|
|
1094
|
+
describe("Server before-listen handlers", () => {
|
|
1095
|
+
test("runs before-listen handlers before adapter listen in registration order", async () => {
|
|
1096
|
+
ensureTestInstance();
|
|
1097
|
+
const server = new TestServer();
|
|
1098
|
+
const calls = [];
|
|
1099
|
+
let receivedServer = null;
|
|
1100
|
+
server.onBeforeListen(({ httpServer, port }) => {
|
|
1101
|
+
calls.push(`first:${port}`);
|
|
1102
|
+
receivedServer = httpServer;
|
|
1103
|
+
expect(server.startedPorts).toEqual([]);
|
|
1104
|
+
}).onBeforeListen(({ httpServer, port }) => {
|
|
1105
|
+
calls.push(`second:${port}`);
|
|
1106
|
+
expect(httpServer).toBe(receivedServer);
|
|
1107
|
+
expect(server.startedPorts).toEqual([]);
|
|
1108
|
+
});
|
|
1109
|
+
await server.start();
|
|
1110
|
+
expect(calls).toEqual(["first:0", "second:0"]);
|
|
1111
|
+
expect(receivedServer).toBeInstanceOf(http.Server);
|
|
1112
|
+
expect(server.startedPorts).toEqual([0]);
|
|
1113
|
+
});
|
|
1114
|
+
test("rejects startup when a before-listen handler fails before adapter listen", async () => {
|
|
1115
|
+
ensureTestInstance();
|
|
1116
|
+
const server = new TestServer();
|
|
1117
|
+
server.onBeforeListen(async () => {
|
|
1118
|
+
throw new Error("before-listen failed");
|
|
1119
|
+
});
|
|
1120
|
+
await expect(server.start()).rejects.toThrow("before-listen failed");
|
|
1121
|
+
expect(server.startedPorts).toEqual([]);
|
|
1122
|
+
});
|
|
1123
|
+
test("rejects adding before-listen handlers after server startup", async () => {
|
|
1124
|
+
ensureTestInstance();
|
|
1125
|
+
const server = new TestServer();
|
|
1126
|
+
await server.start();
|
|
1127
|
+
expect(() => server.onBeforeListen(() => {
|
|
1128
|
+
})).toThrow("Cannot add before-listen handler after server has started");
|
|
1129
|
+
});
|
|
1130
|
+
});
|
|
1266
1131
|
describe("Server not-found handler", () => {
|
|
1267
1132
|
test("throws the default Equipped not-found error when no custom handler is set", async () => {
|
|
1268
1133
|
ensureTestInstance();
|
|
@@ -1812,22 +1677,22 @@ if (void 0) {
|
|
|
1812
1677
|
}
|
|
1813
1678
|
|
|
1814
1679
|
// src/instance/settings.ts
|
|
1815
|
-
import { v as
|
|
1816
|
-
var instanceSettingsPipe = () =>
|
|
1817
|
-
app:
|
|
1818
|
-
name:
|
|
1680
|
+
import { v as v3 } from "valleyed";
|
|
1681
|
+
var instanceSettingsPipe = () => v3.object({
|
|
1682
|
+
app: v3.object({
|
|
1683
|
+
name: v3.string()
|
|
1819
1684
|
}),
|
|
1820
|
-
log:
|
|
1821
|
-
|
|
1822
|
-
level:
|
|
1685
|
+
log: v3.defaults(
|
|
1686
|
+
v3.object({
|
|
1687
|
+
level: v3.defaults(v3.in(["fatal", "error", "warn", "info", "debug", "trace", "silent"]), "info")
|
|
1823
1688
|
}),
|
|
1824
1689
|
{}
|
|
1825
1690
|
),
|
|
1826
|
-
utils:
|
|
1827
|
-
|
|
1828
|
-
hashSaltRounds:
|
|
1829
|
-
paginationDefaultLimit:
|
|
1830
|
-
maxFileUploadSizeInMb:
|
|
1691
|
+
utils: v3.defaults(
|
|
1692
|
+
v3.object({
|
|
1693
|
+
hashSaltRounds: v3.defaults(v3.number(), 10),
|
|
1694
|
+
paginationDefaultLimit: v3.defaults(v3.number(), 100),
|
|
1695
|
+
maxFileUploadSizeInMb: v3.defaults(v3.number(), 500)
|
|
1831
1696
|
}),
|
|
1832
1697
|
{}
|
|
1833
1698
|
)
|
|
@@ -1877,7 +1742,7 @@ var Instance = class _Instance {
|
|
|
1877
1742
|
}
|
|
1878
1743
|
}
|
|
1879
1744
|
static envs(envsPipe) {
|
|
1880
|
-
const envValidity =
|
|
1745
|
+
const envValidity = v4.validate(envsPipe, process.env);
|
|
1881
1746
|
if (!envValidity.valid) {
|
|
1882
1747
|
_Instance.crash(
|
|
1883
1748
|
new EquippedError(`Environment variables are not valid
|
|
@@ -1890,7 +1755,7 @@ ${envValidity.error.toString()}`, {
|
|
|
1890
1755
|
}
|
|
1891
1756
|
static create(settings) {
|
|
1892
1757
|
if (_Instance.#instance) return _Instance.crash(new EquippedError("Instance has been initialized already", {}));
|
|
1893
|
-
const settingsValidity =
|
|
1758
|
+
const settingsValidity = v4.validate(instanceSettingsPipe(), settings);
|
|
1894
1759
|
if (!settingsValidity.valid) {
|
|
1895
1760
|
_Instance.crash(
|
|
1896
1761
|
new EquippedError(`Settings are not valid
|
|
@@ -1945,40 +1810,40 @@ ${settingsValidity.error.toString()}`, {
|
|
|
1945
1810
|
};
|
|
1946
1811
|
|
|
1947
1812
|
// src/validations/valleyed.ts
|
|
1948
|
-
var filePipe = (err) =>
|
|
1949
|
-
|
|
1813
|
+
var filePipe = (err) => v5.array(
|
|
1814
|
+
v5.file(err).pipe((input) => {
|
|
1950
1815
|
const err2 = `is larger than allowed limit of ${Instance.get().settings.utils.maxFileUploadSizeInMb}mb`;
|
|
1951
1816
|
const valid = input ? !input.isTruncated : true;
|
|
1952
1817
|
if (valid) return input;
|
|
1953
1818
|
throw PipeError2.root(err2, input);
|
|
1954
1819
|
})
|
|
1955
1820
|
);
|
|
1956
|
-
var incomingFile = (err) =>
|
|
1957
|
-
|
|
1958
|
-
filePipe(err).pipe(
|
|
1821
|
+
var incomingFile = (err) => v5.define(
|
|
1822
|
+
v5.compile(
|
|
1823
|
+
filePipe(err).pipe(v5.min(1, "no file provided")).pipe((files) => files[0])
|
|
1959
1824
|
),
|
|
1960
1825
|
{ schema: () => ({ type: "string", format: "binary" }) }
|
|
1961
1826
|
);
|
|
1962
|
-
var incomingFiles = (err) =>
|
|
1827
|
+
var incomingFiles = (err) => v5.define(v5.compile(filePipe(err)), {
|
|
1963
1828
|
schema: () => ({ type: "string", format: "binary" })
|
|
1964
1829
|
});
|
|
1965
1830
|
var requestLocalStorage = new AsyncLocalStorage();
|
|
1966
1831
|
var responseLocalStorage = new AsyncLocalStorage();
|
|
1967
|
-
var withRequest = (fn) =>
|
|
1832
|
+
var withRequest = (fn) => v5.define((input) => {
|
|
1968
1833
|
const req = requestLocalStorage.getStore();
|
|
1969
1834
|
if (!req) throw new Error("Request not found in context");
|
|
1970
|
-
const validated =
|
|
1835
|
+
const validated = v5.validate(fn(req), input);
|
|
1971
1836
|
return validated.valid ? validated.value : validated.error;
|
|
1972
1837
|
});
|
|
1973
|
-
var withResponse = (fn) =>
|
|
1838
|
+
var withResponse = (fn) => v5.define((input) => {
|
|
1974
1839
|
const res = responseLocalStorage.getStore();
|
|
1975
1840
|
if (!res) throw new Error("Response not found in context");
|
|
1976
|
-
const validated =
|
|
1841
|
+
const validated = v5.validate(fn(res), input);
|
|
1977
1842
|
return validated.valid ? validated.value : validated.error;
|
|
1978
1843
|
});
|
|
1979
1844
|
|
|
1980
1845
|
// src/validations/index.ts
|
|
1981
|
-
import { v as
|
|
1846
|
+
import { v as v6 } from "valleyed";
|
|
1982
1847
|
function pipeErrorToValidationError(error) {
|
|
1983
1848
|
const errorsObject = error.messages.reduce((acc, { path = "", message }) => {
|
|
1984
1849
|
if (acc[path]) acc[path].messages.push(message);
|
|
@@ -1988,7 +1853,7 @@ function pipeErrorToValidationError(error) {
|
|
|
1988
1853
|
return new ValidationError(Object.values(errorsObject));
|
|
1989
1854
|
}
|
|
1990
1855
|
function validate(pipe, value) {
|
|
1991
|
-
const validity =
|
|
1856
|
+
const validity = v6.validate(pipe, value);
|
|
1992
1857
|
if (validity.valid) return validity.value;
|
|
1993
1858
|
throw pipeErrorToValidationError(validity.error);
|
|
1994
1859
|
}
|
|
@@ -2005,15 +1870,6 @@ export {
|
|
|
2005
1870
|
makeResponseMiddleware,
|
|
2006
1871
|
makeErrorMiddleware,
|
|
2007
1872
|
Router,
|
|
2008
|
-
authProviders_exports,
|
|
2009
|
-
configurable,
|
|
2010
|
-
hash_exports,
|
|
2011
|
-
parseJSONValue,
|
|
2012
|
-
parseJSONObject,
|
|
2013
|
-
getMediaDuration,
|
|
2014
|
-
random_exports,
|
|
2015
|
-
sleep,
|
|
2016
|
-
retry,
|
|
2017
1873
|
Request,
|
|
2018
1874
|
Response,
|
|
2019
1875
|
BaseRequestAuthMethod,
|