@terreno/api 0.13.0 → 0.13.1

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.
@@ -5,7 +5,7 @@
5
5
  * Provides admin CRUD for consent forms, read-only access to responses, and user-facing
6
6
  * endpoints for fetching pending consents and submitting responses.
7
7
  */
8
- import type express from "express";
8
+ import { type Application } from "express";
9
9
  import type { User } from "./auth";
10
10
  import type { TerrenoPlugin } from "./terrenoPlugin";
11
11
  import type { ConsentFormDocument } from "./types/consentForm";
@@ -29,5 +29,5 @@ export interface ConsentAppOptions {
29
29
  export declare class ConsentApp implements TerrenoPlugin {
30
30
  private options;
31
31
  constructor(options?: ConsentAppOptions);
32
- register(app: express.Application): void;
32
+ register(app: Application): void;
33
33
  }
@@ -55,6 +55,7 @@ var __values = (this && this.__values) || function(o) {
55
55
  };
56
56
  Object.defineProperty(exports, "__esModule", { value: true });
57
57
  exports.ConsentApp = void 0;
58
+ var express_1 = require("express");
58
59
  var luxon_1 = require("luxon");
59
60
  var api_1 = require("./api");
60
61
  var auth_1 = require("./auth");
@@ -203,7 +204,7 @@ var ConsentApp = /** @class */ (function () {
203
204
  ],
204
205
  }));
205
206
  // User-facing consent endpoints
206
- var router = require("express").Router();
207
+ var router = (0, express_1.Router)();
207
208
  // GET /consents/pending - fetch pending consent forms for the current user
208
209
  router.get("/pending", (0, auth_1.authenticateMiddleware)(), (0, api_1.asyncHandler)(function (req, res) { return __awaiter(_this, void 0, void 0, function () {
209
210
  var user, activeForms, resolvedForms, existingResponses, respondedFormVersions, existingResponses_1, existingResponses_1_1, response, formId, respondedFormIds, respondedForms, formVersionByFormId, respondedForms_1, respondedForms_1_1, form, pendingForms, filteredOutByResolverCount, filteredOutByResponsesCount;
@@ -77,10 +77,30 @@ var mongoose_1 = __importStar(require("mongoose"));
77
77
  var passport_1 = __importDefault(require("passport"));
78
78
  var passport_local_mongoose_1 = __importDefault(require("passport-local-mongoose"));
79
79
  var supertest_1 = __importDefault(require("supertest"));
80
+ var auth_1 = require("./auth");
80
81
  var expressServer_1 = require("./expressServer");
81
82
  var githubAuth_1 = require("./githubAuth");
82
83
  var logger_1 = require("./logger");
83
84
  var plugins_1 = require("./plugins");
85
+ var fakeGithubOutcome = { type: "redirect", url: "http://github.com/mock" };
86
+ var installFakeGithubStrategy = function () {
87
+ var strategy = {
88
+ authenticate: function () {
89
+ var _a, _b;
90
+ if (fakeGithubOutcome.type === "success") {
91
+ this.success(fakeGithubOutcome.user);
92
+ return;
93
+ }
94
+ if (fakeGithubOutcome.type === "fail") {
95
+ this.fail((_a = fakeGithubOutcome.challenge) !== null && _a !== void 0 ? _a : { message: "auth failed" });
96
+ return;
97
+ }
98
+ this.redirect((_b = fakeGithubOutcome.url) !== null && _b !== void 0 ? _b : "http://github.com/mock");
99
+ },
100
+ name: "github",
101
+ };
102
+ passport_1.default.use("github", strategy);
103
+ };
84
104
  // Create schema for GitHub-enabled user
85
105
  var testUserSchema = new mongoose_1.Schema({
86
106
  admin: { default: false, description: "Whether the user has admin privileges", type: Boolean },
@@ -729,3 +749,392 @@ var invokeGitHubVerify = function (req, accessToken, refreshToken, profile) {
729
749
  });
730
750
  }); });
731
751
  });
752
+ (0, bun_test_1.describe)("GitHub callback handler (fake strategy)", function () {
753
+ var app;
754
+ var agent;
755
+ (0, bun_test_1.beforeEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
756
+ function addRoutes(router) {
757
+ router.get("/test", function (_req, res) { return res.json({ ok: true }); });
758
+ }
759
+ return __generator(this, function (_a) {
760
+ switch (_a.label) {
761
+ case 0:
762
+ (0, bun_test_1.setSystemTime)();
763
+ return [4 /*yield*/, connectDb()];
764
+ case 1:
765
+ _a.sent();
766
+ return [4 /*yield*/, GitHubTestUserModel.deleteMany({})];
767
+ case 2:
768
+ _a.sent();
769
+ app = (0, expressServer_1.setupServer)({
770
+ addMiddleware: function (a) {
771
+ // The handler reads (req as unknown as {session?: {returnTo?: string}}).session?.returnTo.
772
+ // setupServer does not install express-session, so prime a fake session from a request
773
+ // header for tests.
774
+ a.use(function (req, _res, next) {
775
+ var headerReturnTo = req.headers["x-mock-return-to"];
776
+ if (typeof headerReturnTo === "string") {
777
+ req.session = { returnTo: headerReturnTo };
778
+ }
779
+ next();
780
+ });
781
+ },
782
+ addRoutes: addRoutes,
783
+ githubAuth: {
784
+ allowAccountLinking: true,
785
+ callbackURL: "http://localhost:9000/auth/github/callback",
786
+ clientId: "test-client-id",
787
+ clientSecret: "test-client-secret",
788
+ },
789
+ skipListen: true,
790
+ userModel: GitHubTestUserModel,
791
+ });
792
+ // Swap the github strategy with our fake after setupServer registered it.
793
+ installFakeGithubStrategy();
794
+ agent = supertest_1.default.agent(app);
795
+ return [2 /*return*/];
796
+ }
797
+ });
798
+ }); });
799
+ (0, bun_test_1.afterEach)(function () {
800
+ (0, bun_test_1.setSystemTime)();
801
+ fakeGithubOutcome = { type: "redirect", url: "http://github.com/mock" };
802
+ });
803
+ (0, bun_test_1.it)("GET /auth/github/callback returns JSON tokens on success", function () { return __awaiter(void 0, void 0, void 0, function () {
804
+ var user, res;
805
+ return __generator(this, function (_a) {
806
+ switch (_a.label) {
807
+ case 0: return [4 /*yield*/, GitHubTestUserModel.create({
808
+ email: "cb@example.com",
809
+ githubId: "cb-gh-1",
810
+ name: "CB User",
811
+ })];
812
+ case 1:
813
+ user = _a.sent();
814
+ fakeGithubOutcome = { type: "success", user: user };
815
+ return [4 /*yield*/, agent.get("/auth/github/callback").expect(200)];
816
+ case 2:
817
+ res = _a.sent();
818
+ (0, bun_test_1.expect)(res.body.data.token).toBeDefined();
819
+ (0, bun_test_1.expect)(res.body.data.refreshToken).toBeDefined();
820
+ (0, bun_test_1.expect)(res.body.data.userId).toBeDefined();
821
+ return [2 /*return*/];
822
+ }
823
+ });
824
+ }); });
825
+ (0, bun_test_1.it)("GET /auth/github/callback redirects to returnTo with tokens when session.returnTo is set", function () { return __awaiter(void 0, void 0, void 0, function () {
826
+ var user, res;
827
+ return __generator(this, function (_a) {
828
+ switch (_a.label) {
829
+ case 0: return [4 /*yield*/, GitHubTestUserModel.create({
830
+ email: "cb2@example.com",
831
+ githubId: "cb-gh-2",
832
+ name: "CB User 2",
833
+ })];
834
+ case 1:
835
+ user = _a.sent();
836
+ fakeGithubOutcome = { type: "success", user: user };
837
+ return [4 /*yield*/, agent
838
+ .get("/auth/github/callback")
839
+ .set("x-mock-return-to", "https://example.com/cb")
840
+ .expect(302)];
841
+ case 2:
842
+ res = _a.sent();
843
+ (0, bun_test_1.expect)(res.headers.location).toContain("https://example.com/cb");
844
+ (0, bun_test_1.expect)(res.headers.location).toContain("token=");
845
+ (0, bun_test_1.expect)(res.headers.location).toContain("refreshToken=");
846
+ (0, bun_test_1.expect)(res.headers.location).toContain("userId=");
847
+ return [2 /*return*/];
848
+ }
849
+ });
850
+ }); });
851
+ (0, bun_test_1.it)("GET /auth/github/callback redirects on failure", function () { return __awaiter(void 0, void 0, void 0, function () {
852
+ var res;
853
+ return __generator(this, function (_a) {
854
+ switch (_a.label) {
855
+ case 0:
856
+ fakeGithubOutcome = { challenge: { message: "denied" }, type: "fail" };
857
+ return [4 /*yield*/, agent.get("/auth/github/callback").expect(302)];
858
+ case 1:
859
+ res = _a.sent();
860
+ (0, bun_test_1.expect)(res.headers.location).toContain("/auth/github/failure");
861
+ return [2 /*return*/];
862
+ }
863
+ });
864
+ }); });
865
+ (0, bun_test_1.it)("GET /auth/github/callback returns 500 when token generation fails", function () { return __awaiter(void 0, void 0, void 0, function () {
866
+ var user, savedSecret, res;
867
+ return __generator(this, function (_a) {
868
+ switch (_a.label) {
869
+ case 0: return [4 /*yield*/, GitHubTestUserModel.create({
870
+ email: "cb3@example.com",
871
+ githubId: "cb-gh-3",
872
+ name: "CB User 3",
873
+ })];
874
+ case 1:
875
+ user = _a.sent();
876
+ fakeGithubOutcome = { type: "success", user: user };
877
+ savedSecret = process.env.TOKEN_SECRET;
878
+ process.env.TOKEN_SECRET = "";
879
+ _a.label = 2;
880
+ case 2:
881
+ _a.trys.push([2, , 4, 5]);
882
+ return [4 /*yield*/, agent.get("/auth/github/callback").expect(500)];
883
+ case 3:
884
+ res = _a.sent();
885
+ (0, bun_test_1.expect)(res.body.message).toBe("Authentication failed");
886
+ return [3 /*break*/, 5];
887
+ case 4:
888
+ process.env.TOKEN_SECRET = savedSecret;
889
+ return [7 /*endfinally*/];
890
+ case 5: return [2 /*return*/];
891
+ }
892
+ });
893
+ }); });
894
+ });
895
+ (0, bun_test_1.describe)("GET /auth/github/link with JWT (fake strategy)", function () {
896
+ var app;
897
+ var agent;
898
+ (0, bun_test_1.beforeEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
899
+ function addRoutes(router) {
900
+ router.get("/test", function (_req, res) { return res.json({ ok: true }); });
901
+ }
902
+ return __generator(this, function (_a) {
903
+ switch (_a.label) {
904
+ case 0:
905
+ (0, bun_test_1.setSystemTime)();
906
+ return [4 /*yield*/, connectDb()];
907
+ case 1:
908
+ _a.sent();
909
+ return [4 /*yield*/, GitHubTestUserModel.deleteMany({})];
910
+ case 2:
911
+ _a.sent();
912
+ app = (0, expressServer_1.setupServer)({
913
+ addRoutes: addRoutes,
914
+ githubAuth: {
915
+ allowAccountLinking: true,
916
+ callbackURL: "http://localhost:9000/auth/github/callback",
917
+ clientId: "test-client-id",
918
+ clientSecret: "test-client-secret",
919
+ },
920
+ skipListen: true,
921
+ userModel: GitHubTestUserModel,
922
+ });
923
+ installFakeGithubStrategy();
924
+ agent = supertest_1.default.agent(app);
925
+ return [2 /*return*/];
926
+ }
927
+ });
928
+ }); });
929
+ (0, bun_test_1.afterEach)(function () {
930
+ (0, bun_test_1.setSystemTime)();
931
+ fakeGithubOutcome = { type: "redirect", url: "http://github.com/mock" };
932
+ });
933
+ (0, bun_test_1.it)("GET /auth/github/link forwards to GitHub auth when JWT is valid", function () { return __awaiter(void 0, void 0, void 0, function () {
934
+ var user, loginRes, res;
935
+ return __generator(this, function (_a) {
936
+ switch (_a.label) {
937
+ case 0: return [4 /*yield*/, GitHubTestUserModel.create({
938
+ email: "linkjwt@example.com",
939
+ name: "Link JWT User",
940
+ })];
941
+ case 1:
942
+ user = _a.sent();
943
+ return [4 /*yield*/, user.setPassword("password123")];
944
+ case 2:
945
+ _a.sent();
946
+ return [4 /*yield*/, user.save()];
947
+ case 3:
948
+ _a.sent();
949
+ return [4 /*yield*/, agent
950
+ .post("/auth/login")
951
+ .send({ email: "linkjwt@example.com", password: "password123" })
952
+ .expect(200)];
953
+ case 4:
954
+ loginRes = _a.sent();
955
+ fakeGithubOutcome = { type: "redirect", url: "http://github.com/auth" };
956
+ return [4 /*yield*/, agent
957
+ .get("/auth/github/link")
958
+ .set("authorization", "Bearer ".concat(loginRes.body.data.token))
959
+ .expect(302)];
960
+ case 5:
961
+ res = _a.sent();
962
+ (0, bun_test_1.expect)(res.headers.location).toBe("http://github.com/auth");
963
+ return [2 /*return*/];
964
+ }
965
+ });
966
+ }); });
967
+ });
968
+ (0, bun_test_1.describe)("DELETE /auth/github/unlink edge cases", function () {
969
+ var app;
970
+ var agent;
971
+ (0, bun_test_1.beforeEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
972
+ function addRoutes(router) {
973
+ router.get("/test", function (_req, res) { return res.json({ ok: true }); });
974
+ }
975
+ return __generator(this, function (_a) {
976
+ switch (_a.label) {
977
+ case 0:
978
+ (0, bun_test_1.setSystemTime)();
979
+ return [4 /*yield*/, connectDb()];
980
+ case 1:
981
+ _a.sent();
982
+ return [4 /*yield*/, GitHubTestUserModel.deleteMany({})];
983
+ case 2:
984
+ _a.sent();
985
+ app = (0, expressServer_1.setupServer)({
986
+ addRoutes: addRoutes,
987
+ githubAuth: {
988
+ allowAccountLinking: true,
989
+ callbackURL: "http://localhost:9000/auth/github/callback",
990
+ clientId: "test-client-id",
991
+ clientSecret: "test-client-secret",
992
+ },
993
+ skipListen: true,
994
+ userModel: GitHubTestUserModel,
995
+ });
996
+ installFakeGithubStrategy();
997
+ agent = supertest_1.default.agent(app);
998
+ return [2 /*return*/];
999
+ }
1000
+ });
1001
+ }); });
1002
+ (0, bun_test_1.afterEach)(function () {
1003
+ (0, bun_test_1.setSystemTime)();
1004
+ });
1005
+ (0, bun_test_1.it)("returns 400 when user has no password (no other auth method)", function () { return __awaiter(void 0, void 0, void 0, function () {
1006
+ var user, token, res;
1007
+ return __generator(this, function (_a) {
1008
+ switch (_a.label) {
1009
+ case 0: return [4 /*yield*/, GitHubTestUserModel.create({
1010
+ email: "ghonly@example.com",
1011
+ githubId: "ghonly-1",
1012
+ githubUsername: "ghonly",
1013
+ })];
1014
+ case 1:
1015
+ user = _a.sent();
1016
+ return [4 /*yield*/, (0, auth_1.generateTokens)({ _id: user._id })];
1017
+ case 2:
1018
+ token = (_a.sent()).token;
1019
+ return [4 /*yield*/, agent
1020
+ .delete("/auth/github/unlink")
1021
+ .set("authorization", "Bearer ".concat(token))
1022
+ .expect(400)];
1023
+ case 3:
1024
+ res = _a.sent();
1025
+ (0, bun_test_1.expect)(res.body.message).toContain("Cannot unlink GitHub account");
1026
+ return [2 /*return*/];
1027
+ }
1028
+ });
1029
+ }); });
1030
+ (0, bun_test_1.it)("returns 500 when save throws during unlink", function () { return __awaiter(void 0, void 0, void 0, function () {
1031
+ var user, loginRes, mockableModel, originalFindById, res;
1032
+ return __generator(this, function (_a) {
1033
+ switch (_a.label) {
1034
+ case 0: return [4 /*yield*/, GitHubTestUserModel.create({
1035
+ email: "savefail@example.com",
1036
+ githubId: "savefail-1",
1037
+ })];
1038
+ case 1:
1039
+ user = _a.sent();
1040
+ return [4 /*yield*/, user.setPassword("password123")];
1041
+ case 2:
1042
+ _a.sent();
1043
+ return [4 /*yield*/, user.save()];
1044
+ case 3:
1045
+ _a.sent();
1046
+ return [4 /*yield*/, agent
1047
+ .post("/auth/login")
1048
+ .send({ email: "savefail@example.com", password: "password123" })
1049
+ .expect(200)];
1050
+ case 4:
1051
+ loginRes = _a.sent();
1052
+ mockableModel = GitHubTestUserModel;
1053
+ originalFindById = mockableModel.findById;
1054
+ mockableModel.findById = function () { return ({
1055
+ select: function () { return __awaiter(void 0, void 0, void 0, function () {
1056
+ return __generator(this, function (_a) {
1057
+ return [2 /*return*/, ({
1058
+ hash: "x",
1059
+ salt: "y",
1060
+ save: function () { return __awaiter(void 0, void 0, void 0, function () {
1061
+ return __generator(this, function (_a) {
1062
+ throw new Error("boom");
1063
+ });
1064
+ }); },
1065
+ setPassword: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
1066
+ return [2 /*return*/, undefined];
1067
+ }); }); },
1068
+ })];
1069
+ });
1070
+ }); },
1071
+ }); };
1072
+ _a.label = 5;
1073
+ case 5:
1074
+ _a.trys.push([5, , 7, 8]);
1075
+ return [4 /*yield*/, agent
1076
+ .delete("/auth/github/unlink")
1077
+ .set("authorization", "Bearer ".concat(loginRes.body.data.token))
1078
+ .expect(500)];
1079
+ case 6:
1080
+ res = _a.sent();
1081
+ (0, bun_test_1.expect)(res.body.message).toBe("Failed to unlink GitHub account");
1082
+ return [3 /*break*/, 8];
1083
+ case 7:
1084
+ mockableModel.findById = originalFindById;
1085
+ return [7 /*endfinally*/];
1086
+ case 8: return [2 /*return*/];
1087
+ }
1088
+ });
1089
+ }); });
1090
+ });
1091
+ (0, bun_test_1.describe)("GitHub strategy verify callback edge cases", function () {
1092
+ var testApp = { get: function () { }, use: function () { } };
1093
+ (0, bun_test_1.beforeEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
1094
+ return __generator(this, function (_a) {
1095
+ switch (_a.label) {
1096
+ case 0: return [4 /*yield*/, connectDb()];
1097
+ case 1:
1098
+ _a.sent();
1099
+ return [4 /*yield*/, GitHubTestUserModel.deleteMany({})];
1100
+ case 2:
1101
+ _a.sent();
1102
+ return [2 /*return*/];
1103
+ }
1104
+ });
1105
+ }); });
1106
+ (0, bun_test_1.it)("returns 404 when linking a user whose record disappears", function () { return __awaiter(void 0, void 0, void 0, function () {
1107
+ var existingUser, req, result;
1108
+ var _a;
1109
+ return __generator(this, function (_b) {
1110
+ switch (_b.label) {
1111
+ case 0: return [4 /*yield*/, GitHubTestUserModel.create({
1112
+ email: "gone@example.com",
1113
+ })];
1114
+ case 1:
1115
+ existingUser = _b.sent();
1116
+ (0, githubAuth_1.setupGitHubAuth)(testApp, GitHubTestUserModel, {
1117
+ allowAccountLinking: true,
1118
+ callbackURL: "http://localhost:9000/auth/github/callback",
1119
+ clientId: "id",
1120
+ clientSecret: "secret",
1121
+ });
1122
+ // Delete user before verify runs to hit the 404 path.
1123
+ return [4 /*yield*/, GitHubTestUserModel.deleteOne({ _id: existingUser._id })];
1124
+ case 2:
1125
+ // Delete user before verify runs to hit the 404 path.
1126
+ _b.sent();
1127
+ req = { user: existingUser };
1128
+ return [4 /*yield*/, invokeGitHubVerify(req, "access", "refresh", {
1129
+ id: "gh-missing-1",
1130
+ username: "missing",
1131
+ })];
1132
+ case 3:
1133
+ result = _b.sent();
1134
+ (0, bun_test_1.expect)(result.err).toBeDefined();
1135
+ (0, bun_test_1.expect)((_a = result.err) === null || _a === void 0 ? void 0 : _a.status).toBe(404);
1136
+ return [2 /*return*/];
1137
+ }
1138
+ });
1139
+ }); });
1140
+ });
@@ -6,15 +6,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ConsentForm = void 0;
7
7
  var mongoose_1 = __importDefault(require("mongoose"));
8
8
  var plugins_1 = require("../plugins");
9
- var consentFormTypeMap = {
10
- agreement: "agreement",
11
- custom: "custom",
12
- hipaa: "hipaa",
13
- privacy: "privacy",
14
- research: "research",
15
- terms: "terms",
16
- };
17
- var consentFormTypeValues = Object.values(consentFormTypeMap);
9
+ var consentFormTypeValues = [
10
+ "agreement",
11
+ "privacy",
12
+ "hipaa",
13
+ "research",
14
+ "terms",
15
+ "custom",
16
+ ];
18
17
  var consentFormSchema = new mongoose_1.default.Schema({
19
18
  active: {
20
19
  default: false,
@@ -1,6 +1,6 @@
1
- export declare function sendToSlack(text: string, { slackChannel, shouldThrow, env, url, }?: {
1
+ export declare const sendToSlack: (text: string, { slackChannel, shouldThrow, env, url, }?: {
2
2
  slackChannel?: string;
3
3
  shouldThrow?: boolean;
4
4
  env?: string;
5
5
  url?: string;
6
- }): Promise<void>;
6
+ }) => Promise<void>;
@@ -68,11 +68,36 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
68
68
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
69
69
  }
70
70
  };
71
+ var __read = (this && this.__read) || function (o, n) {
72
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
73
+ if (!m) return o;
74
+ var i = m.call(o), r, ar = [], e;
75
+ try {
76
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
77
+ }
78
+ catch (error) { e = { error: error }; }
79
+ finally {
80
+ try {
81
+ if (r && !r.done && (m = i["return"])) m.call(i);
82
+ }
83
+ finally { if (e) throw e.error; }
84
+ }
85
+ return ar;
86
+ };
87
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
88
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
89
+ if (ar || !(i in from)) {
90
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
91
+ ar[i] = from[i];
92
+ }
93
+ }
94
+ return to.concat(ar || Array.prototype.slice.call(from));
95
+ };
71
96
  var __importDefault = (this && this.__importDefault) || function (mod) {
72
97
  return (mod && mod.__esModule) ? mod : { "default": mod };
73
98
  };
74
99
  Object.defineProperty(exports, "__esModule", { value: true });
75
- exports.sendToSlack = sendToSlack;
100
+ exports.sendToSlack = void 0;
76
101
  var Sentry = __importStar(require("@sentry/bun"));
77
102
  var axios_1 = __importDefault(require("axios"));
78
103
  var errors_1 = require("../errors");
@@ -81,9 +106,13 @@ var logger_1 = require("../logger");
81
106
  // If `url` is provided, it will be used directly instead of looking up from environment.
82
107
  // DEPRECATED: Looking up webhook URLs from the SLACK_WEBHOOKS environment variable by channel name
83
108
  // is deprecated and will be removed in a future version. Please pass the `url` parameter directly.
84
- function sendToSlack(text_1) {
85
- return __awaiter(this, arguments, void 0, function (text, _a) {
86
- var slackWebhookUrl, slackWebhooksString, slackWebhooks, channel, formattedText, error_1;
109
+ var sendToSlack = function (text_1) {
110
+ var args_1 = [];
111
+ for (var _i = 1; _i < arguments.length; _i++) {
112
+ args_1[_i - 1] = arguments[_i];
113
+ }
114
+ return __awaiter(void 0, __spreadArray([text_1], __read(args_1), false), void 0, function (text, _a) {
115
+ var slackWebhookUrl, slackWebhooksString, slackWebhooks, channel, formattedText, error_1, errorObj;
87
116
  var _b, _c, _d;
88
117
  var _e = _a === void 0 ? {} : _a, slackChannel = _e.slackChannel, _f = _e.shouldThrow, shouldThrow = _f === void 0 ? false : _f, env = _e.env, url = _e.url;
89
118
  return __generator(this, function (_g) {
@@ -121,12 +150,13 @@ function sendToSlack(text_1) {
121
150
  return [3 /*break*/, 4];
122
151
  case 3:
123
152
  error_1 = _g.sent();
124
- logger_1.logger.error("Error posting to slack: ".concat((_c = error_1.text) !== null && _c !== void 0 ? _c : error_1.message));
153
+ errorObj = error_1;
154
+ logger_1.logger.error("Error posting to slack: ".concat((_c = errorObj.text) !== null && _c !== void 0 ? _c : errorObj.message));
125
155
  Sentry.captureException(error_1);
126
156
  if (shouldThrow) {
127
157
  throw new errors_1.APIError({
128
158
  status: 500,
129
- title: "Error posting to slack: ".concat((_d = error_1.text) !== null && _d !== void 0 ? _d : error_1.message),
159
+ title: "Error posting to slack: ".concat((_d = errorObj.text) !== null && _d !== void 0 ? _d : errorObj.message),
130
160
  });
131
161
  }
132
162
  return [3 /*break*/, 4];
@@ -134,4 +164,5 @@ function sendToSlack(text_1) {
134
164
  }
135
165
  });
136
166
  });
137
- }
167
+ };
168
+ exports.sendToSlack = sendToSlack;
package/dist/plugins.d.ts CHANGED
@@ -69,10 +69,10 @@ export interface FindExactlyOnePlugin<T> {
69
69
  findExactlyOne(query: Record<string, any>, errorArgs?: Partial<APIErrorConstructor>): Promise<Document & T>;
70
70
  }
71
71
  export declare class DateOnly extends SchemaType {
72
- constructor(key: string, options: SchemaTypeOptions<any>);
72
+ constructor(key: string, options: SchemaTypeOptions<Date>);
73
73
  handleSingle(val: any): Date | undefined;
74
74
  $conditionalHandlers: any;
75
75
  castForQuery($conditional: any, val: any, context: any): Date | undefined;
76
- cast(val: any): Date | undefined;
77
- get(val: any): this;
76
+ cast(val: unknown): Date | undefined;
77
+ get(val: unknown): this;
78
78
  }
package/dist/plugins.js CHANGED
@@ -154,13 +154,13 @@ var createdUpdatedPlugin = function (schema) {
154
154
  }
155
155
  // If we aren't specifying created, use now.
156
156
  if (!this.created) {
157
- this.created = new Date();
157
+ this.created = luxon_1.DateTime.now().toJSDate();
158
158
  }
159
159
  // All writes change the updated time.
160
- this.updated = new Date();
160
+ this.updated = luxon_1.DateTime.now().toJSDate();
161
161
  });
162
162
  schema.pre(/save|updateOne|insertMany/, function () {
163
- void this.updateOne({}, { $set: { updated: new Date() } });
163
+ void this.updateOne({}, { $set: { updated: luxon_1.DateTime.now().toJSDate() } });
164
164
  });
165
165
  };
166
166
  exports.createdUpdatedPlugin = createdUpdatedPlugin;
@@ -313,6 +313,7 @@ var DateOnly = /** @class */ (function (_super) {
313
313
  // When using $gt, $gte, $lt, $lte, etc, we need to cast the value to a Date
314
314
  DateOnly.prototype.castForQuery = function ($conditional, val, context) {
315
315
  if ($conditional == null) {
316
+ // noExplicitAny: applySetters is an internal Mongoose SchemaType method not in public type definitions
316
317
  return this.applySetters(val, context);
317
318
  }
318
319
  var handler = this.$conditionalHandlers[$conditional];
@@ -345,10 +346,13 @@ var DateOnly = /** @class */ (function (_super) {
345
346
  throw new mongoose_1.Error.CastError("DateOnly", val, this.path, new Error("Value is not a valid date"));
346
347
  };
347
348
  DateOnly.prototype.get = function (val) {
348
- return (val instanceof Date ? luxon_1.DateTime.fromJSDate(val).startOf("day").toJSDate() : val);
349
+ return (val instanceof Date
350
+ ? luxon_1.DateTime.fromJSDate(val).startOf("day").toJSDate()
351
+ : val);
349
352
  };
350
353
  return DateOnly;
351
354
  }(mongoose_1.SchemaType));
352
355
  exports.DateOnly = DateOnly;
353
356
  // Register DateOnly with Mongoose's Schema.Types
357
+ // noExplicitAny: DateOnly is a custom SchemaType not declared in Mongoose's Schema.Types interface
354
358
  mongoose_1.default.Schema.Types.DateOnly = DateOnly;
@@ -92,6 +92,7 @@ var tests_1 = require("./tests");
92
92
  (0, bun_test_1.describe)("populate functions", function () {
93
93
  var admin;
94
94
  var notAdmin;
95
+ // noExplicitAny: typing as HydratedDocument<Food> causes cascading errors on populated field access patterns (e.g. populated.ownerId.name)
95
96
  var spinach;
96
97
  (0, bun_test_1.beforeEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
97
98
  var _a, _b;
@@ -228,7 +229,9 @@ var tests_1 = require("./tests");
228
229
  });
229
230
  (0, bun_test_1.it)("replaces Mixed fields with only description", function () {
230
231
  var schema = new mongoose_1.Schema({ data: { description: "any data", type: mongoose_1.Schema.Types.Mixed } });
231
- var properties = { data: { description: "any data", type: "object" } };
232
+ var properties = {
233
+ data: { description: "any data", type: "object" },
234
+ };
232
235
  (0, populate_1.fixMixedFields)(schema, properties);
233
236
  (0, bun_test_1.expect)(properties.data).toEqual({ description: "any data" });
234
237
  });
@@ -338,6 +341,7 @@ var tests_1 = require("./tests");
338
341
  populatePaths: [{ fields: ["__proto__.polluted"], path: "ownerId" }],
339
342
  });
340
343
  (0, bun_test_1.expect)(result.properties).toBeDefined();
344
+ // noExplicitAny: testing that prototype pollution did not add a 'polluted' property to Object.prototype
341
345
  (0, bun_test_1.expect)(Object.prototype.polluted).toBeUndefined();
342
346
  var ownerProps = result.properties.ownerId.properties;
343
347
  (0, bun_test_1.expect)(ownerProps).toBeDefined();
@@ -168,7 +168,10 @@ var GcpSecretProvider = /** @class */ (function () {
168
168
  case 4:
169
169
  SecretManagerServiceClient = (_b = mod.SecretManagerServiceClient) !== null && _b !== void 0 ? _b : (_c = mod.default) === null || _c === void 0 ? void 0 : _c.SecretManagerServiceClient;
170
170
  if (!SecretManagerServiceClient) {
171
- throw new Error("SecretManagerServiceClient not found in @google-cloud/secret-manager module");
171
+ throw new errors_1.APIError({
172
+ status: 500,
173
+ title: "SecretManagerServiceClient not found in @google-cloud/secret-manager module",
174
+ });
172
175
  }
173
176
  this.client = new SecretManagerServiceClient();
174
177
  _d.label = 5;