@terreno/api 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.test.js +18 -8
- package/dist/auth.d.ts +5 -5
- package/dist/auth.js +123 -131
- package/dist/envConfigurationPlugin.test.js +49 -0
- package/dist/expressServer.test.js +0 -1
- package/dist/openApi.d.ts +6 -6
- package/dist/openApi.js +21 -21
- package/dist/populate.test.js +23 -0
- package/dist/realtime/queryMatcher.js +0 -6
- package/dist/realtime/queryStore.js +3 -11
- package/dist/realtime/realtime.test.js +41 -34
- package/package.json +1 -1
- package/src/actions.openApi.test.ts +1 -1
- package/src/actions.ts +0 -1
- package/src/api.test.ts +10 -2
- package/src/auth.ts +19 -19
- package/src/envConfigurationPlugin.test.ts +37 -0
- package/src/expressServer.test.ts +0 -1
- package/src/openApi.ts +21 -21
- package/src/populate.test.ts +25 -0
- package/src/realtime/queryMatcher.ts +0 -6
- package/src/realtime/queryStore.ts +1 -10
- package/src/realtime/realtime.test.ts +24 -24
- package/src/realtime/realtimeApp.ts +0 -1
- package/src/realtime/registry.ts +0 -1
- package/src/realtime/types.ts +0 -4
package/dist/api.test.js
CHANGED
|
@@ -2545,14 +2545,20 @@ var transformers_1 = require("./transformers");
|
|
|
2545
2545
|
});
|
|
2546
2546
|
}); });
|
|
2547
2547
|
(0, bun_test_1.it)("returns 409 when precise conflict timestamp is older than doc.updated", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
2548
|
+
var ifUnmodifiedSince;
|
|
2548
2549
|
return __generator(this, function (_a) {
|
|
2549
2550
|
switch (_a.label) {
|
|
2550
|
-
case 0:
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2551
|
+
case 0:
|
|
2552
|
+
ifUnmodifiedSince = luxon_1.DateTime.fromISO("2025-06-15T12:00:01.000Z").toHTTP();
|
|
2553
|
+
if (ifUnmodifiedSince === null) {
|
|
2554
|
+
throw new Error("expected HTTP If-Unmodified-Since value");
|
|
2555
|
+
}
|
|
2556
|
+
return [4 /*yield*/, agent
|
|
2557
|
+
.patch("/food/".concat(spinach._id))
|
|
2558
|
+
.set("If-Unmodified-Since", ifUnmodifiedSince)
|
|
2559
|
+
.set("X-Unmodified-Since-ISO", "2025-06-15T11:59:59.500Z")
|
|
2560
|
+
.send({ name: "Precise Stale" })
|
|
2561
|
+
.expect(409)];
|
|
2556
2562
|
case 1:
|
|
2557
2563
|
_a.sent();
|
|
2558
2564
|
return [2 /*return*/];
|
|
@@ -2560,15 +2566,19 @@ var transformers_1 = require("./transformers");
|
|
|
2560
2566
|
});
|
|
2561
2567
|
}); });
|
|
2562
2568
|
(0, bun_test_1.it)("falls back to doc.created when doc.updated is unavailable", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
2563
|
-
var res;
|
|
2569
|
+
var ifUnmodifiedSince, res;
|
|
2564
2570
|
return __generator(this, function (_a) {
|
|
2565
2571
|
switch (_a.label) {
|
|
2566
2572
|
case 0: return [4 /*yield*/, tests_1.FoodModel.collection.updateOne({ _id: spinach._id }, { $unset: { updated: "" } })];
|
|
2567
2573
|
case 1:
|
|
2568
2574
|
_a.sent();
|
|
2575
|
+
ifUnmodifiedSince = luxon_1.DateTime.fromISO("2025-06-15T11:59:59.999Z").toHTTP();
|
|
2576
|
+
if (ifUnmodifiedSince === null) {
|
|
2577
|
+
throw new Error("expected HTTP If-Unmodified-Since value");
|
|
2578
|
+
}
|
|
2569
2579
|
return [4 /*yield*/, agent
|
|
2570
2580
|
.patch("/food/".concat(spinach._id))
|
|
2571
|
-
.set("If-Unmodified-Since",
|
|
2581
|
+
.set("If-Unmodified-Since", ifUnmodifiedSince)
|
|
2572
2582
|
.send({ name: "Created Fallback" })
|
|
2573
2583
|
.expect(409)];
|
|
2574
2584
|
case 2:
|
package/dist/auth.d.ts
CHANGED
|
@@ -22,8 +22,8 @@ export interface UserModel extends Model<User> {
|
|
|
22
22
|
export interface GenerateTokensOptions {
|
|
23
23
|
sessionId?: string;
|
|
24
24
|
}
|
|
25
|
-
export declare
|
|
26
|
-
export declare
|
|
25
|
+
export declare const authenticateMiddleware: (anonymous?: boolean) => (req: express.Request, res: express.Response, next: express.NextFunction) => any;
|
|
26
|
+
export declare const signupUser: (userModel: UserModel, email: string, password: string, body?: Record<string, unknown>) => Promise<any>;
|
|
27
27
|
/**
|
|
28
28
|
* Generates both an access token (JWT) and a refresh token for a given user.
|
|
29
29
|
*
|
|
@@ -50,6 +50,6 @@ export declare const generateTokens: (user: unknown, authOptions?: AuthOptions,
|
|
|
50
50
|
sessionId: string;
|
|
51
51
|
token: string;
|
|
52
52
|
}>;
|
|
53
|
-
export declare
|
|
54
|
-
export declare
|
|
55
|
-
export declare
|
|
53
|
+
export declare const setupAuth: (app: express.Application, userModel: UserModel) => void;
|
|
54
|
+
export declare const addAuthRoutes: (app: express.Application, userModel: UserModel, authOptions?: AuthOptions) => void;
|
|
55
|
+
export declare const addMeRoutes: (app: express.Application, userModel: UserModel, _authOptions?: AuthOptions) => void;
|
package/dist/auth.js
CHANGED
|
@@ -86,12 +86,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
86
86
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
87
87
|
};
|
|
88
88
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
89
|
-
exports.generateTokens = void 0;
|
|
90
|
-
exports.authenticateMiddleware = authenticateMiddleware;
|
|
91
|
-
exports.signupUser = signupUser;
|
|
92
|
-
exports.setupAuth = setupAuth;
|
|
93
|
-
exports.addAuthRoutes = addAuthRoutes;
|
|
94
|
-
exports.addMeRoutes = addMeRoutes;
|
|
89
|
+
exports.addMeRoutes = exports.addAuthRoutes = exports.setupAuth = exports.generateTokens = exports.signupUser = exports.authenticateMiddleware = void 0;
|
|
95
90
|
var node_crypto_1 = require("node:crypto");
|
|
96
91
|
var express_1 = __importDefault(require("express"));
|
|
97
92
|
var jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
@@ -103,7 +98,7 @@ var passport_local_1 = require("passport-local");
|
|
|
103
98
|
var errors_1 = require("./errors");
|
|
104
99
|
var logger_1 = require("./logger");
|
|
105
100
|
var requestContext_1 = require("./requestContext");
|
|
106
|
-
function
|
|
101
|
+
var authenticateMiddleware = function (anonymous) {
|
|
107
102
|
if (anonymous === void 0) { anonymous = false; }
|
|
108
103
|
var strategies = ["jwt"];
|
|
109
104
|
if (anonymous) {
|
|
@@ -120,45 +115,45 @@ function authenticateMiddleware(anonymous) {
|
|
|
120
115
|
}
|
|
121
116
|
return passportAuth(req, res, next);
|
|
122
117
|
};
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
});
|
|
118
|
+
};
|
|
119
|
+
exports.authenticateMiddleware = authenticateMiddleware;
|
|
120
|
+
var signupUser = function (userModel, email, password, body) { return __awaiter(void 0, void 0, void 0, function () {
|
|
121
|
+
var _a, _email, _password, bodyRest, user, error_1, error_2, message;
|
|
122
|
+
return __generator(this, function (_b) {
|
|
123
|
+
switch (_b.label) {
|
|
124
|
+
case 0:
|
|
125
|
+
_a = body !== null && body !== void 0 ? body : {}, _email = _a.email, _password = _a.password, bodyRest = __rest(_a, ["email", "password"]);
|
|
126
|
+
_b.label = 1;
|
|
127
|
+
case 1:
|
|
128
|
+
_b.trys.push([1, 8, , 9]);
|
|
129
|
+
return [4 /*yield*/, userModel.register(__assign({ email: email }, bodyRest), password)];
|
|
130
|
+
case 2:
|
|
131
|
+
user = _b.sent();
|
|
132
|
+
if (!user.postCreate) return [3 /*break*/, 6];
|
|
133
|
+
_b.label = 3;
|
|
134
|
+
case 3:
|
|
135
|
+
_b.trys.push([3, 5, , 6]);
|
|
136
|
+
return [4 /*yield*/, user.postCreate(bodyRest)];
|
|
137
|
+
case 4:
|
|
138
|
+
_b.sent();
|
|
139
|
+
return [3 /*break*/, 6];
|
|
140
|
+
case 5:
|
|
141
|
+
error_1 = _b.sent();
|
|
142
|
+
logger_1.logger.error("Error in user.postCreate: ".concat(error_1));
|
|
143
|
+
throw error_1;
|
|
144
|
+
case 6: return [4 /*yield*/, user.save()];
|
|
145
|
+
case 7:
|
|
146
|
+
_b.sent();
|
|
147
|
+
return [2 /*return*/, user];
|
|
148
|
+
case 8:
|
|
149
|
+
error_2 = _b.sent();
|
|
150
|
+
message = (0, errors_1.errorMessage)(error_2);
|
|
151
|
+
throw new errors_1.APIError({ title: message });
|
|
152
|
+
case 9: return [2 /*return*/];
|
|
153
|
+
}
|
|
160
154
|
});
|
|
161
|
-
}
|
|
155
|
+
}); };
|
|
156
|
+
exports.signupUser = signupUser;
|
|
162
157
|
/**
|
|
163
158
|
* Generates both an access token (JWT) and a refresh token for a given user.
|
|
164
159
|
*
|
|
@@ -188,7 +183,7 @@ var generateTokens = function (user_1, authOptions_1) {
|
|
|
188
183
|
return __generator(this, function (_b) {
|
|
189
184
|
tokenSecretOrKey = process.env.TOKEN_SECRET;
|
|
190
185
|
if (!tokenSecretOrKey) {
|
|
191
|
-
throw new
|
|
186
|
+
throw new errors_1.APIError({ status: 500, title: "TOKEN_SECRET must be set in env." });
|
|
192
187
|
}
|
|
193
188
|
tokenUser = user;
|
|
194
189
|
if (!(tokenUser === null || tokenUser === void 0 ? void 0 : tokenUser._id)) {
|
|
@@ -253,15 +248,14 @@ var generateTokens = function (user_1, authOptions_1) {
|
|
|
253
248
|
};
|
|
254
249
|
exports.generateTokens = generateTokens;
|
|
255
250
|
// TODO allow customization
|
|
256
|
-
function
|
|
257
|
-
var _this = this;
|
|
251
|
+
var setupAuth = function (app, userModel) {
|
|
258
252
|
passport_1.default.use(new passport_anonymous_1.Strategy());
|
|
259
253
|
passport_1.default.use(userModel.createStrategy());
|
|
260
254
|
passport_1.default.use("signup", new passport_local_1.Strategy({
|
|
261
255
|
passReqToCallback: true,
|
|
262
256
|
passwordField: "password",
|
|
263
257
|
usernameField: "email",
|
|
264
|
-
}, function (req, email, password, done) { return __awaiter(
|
|
258
|
+
}, function (req, email, password, done) { return __awaiter(void 0, void 0, void 0, function () {
|
|
265
259
|
var _a, _b, error_3;
|
|
266
260
|
return __generator(this, function (_c) {
|
|
267
261
|
switch (_c.label) {
|
|
@@ -269,7 +263,7 @@ function setupAuth(app, userModel) {
|
|
|
269
263
|
_c.trys.push([0, 2, , 3]);
|
|
270
264
|
_a = done;
|
|
271
265
|
_b = [undefined];
|
|
272
|
-
return [4 /*yield*/, signupUser(userModel, email, password, req.body)];
|
|
266
|
+
return [4 /*yield*/, (0, exports.signupUser)(userModel, email, password, req.body)];
|
|
273
267
|
case 1:
|
|
274
268
|
_a.apply(void 0, _b.concat([_c.sent()]));
|
|
275
269
|
return [3 /*break*/, 3];
|
|
@@ -281,7 +275,7 @@ function setupAuth(app, userModel) {
|
|
|
281
275
|
});
|
|
282
276
|
}); }));
|
|
283
277
|
if (!userModel.createStrategy) {
|
|
284
|
-
throw new
|
|
278
|
+
throw new errors_1.APIError({ status: 500, title: "setupAuth userModel must have .createStrategy()" });
|
|
285
279
|
}
|
|
286
280
|
var customTokenExtractor = function (req) {
|
|
287
281
|
var _a, _b, _c;
|
|
@@ -300,14 +294,14 @@ function setupAuth(app, userModel) {
|
|
|
300
294
|
}
|
|
301
295
|
var secretOrKey = process.env.TOKEN_SECRET;
|
|
302
296
|
if (!secretOrKey) {
|
|
303
|
-
throw new
|
|
297
|
+
throw new errors_1.APIError({ status: 500, title: "TOKEN_SECRET must be set in env." });
|
|
304
298
|
}
|
|
305
299
|
var jwtOpts = {
|
|
306
300
|
issuer: process.env.TOKEN_ISSUER,
|
|
307
301
|
jwtFromRequest: customTokenExtractor,
|
|
308
302
|
secretOrKey: secretOrKey,
|
|
309
303
|
};
|
|
310
|
-
passport_1.default.use("jwt", new passport_jwt_1.Strategy(jwtOpts, function (jwtPayload, done) { return __awaiter(
|
|
304
|
+
passport_1.default.use("jwt", new passport_jwt_1.Strategy(jwtOpts, function (jwtPayload, done) { return __awaiter(void 0, void 0, void 0, function () {
|
|
311
305
|
var user, error_4;
|
|
312
306
|
return __generator(this, function (_a) {
|
|
313
307
|
switch (_a.label) {
|
|
@@ -346,82 +340,79 @@ function setupAuth(app, userModel) {
|
|
|
346
340
|
}
|
|
347
341
|
// Adds req.user to the request. This may wind up duplicating requests with passport,
|
|
348
342
|
// but passport doesn't give us req.user early enough.
|
|
349
|
-
function
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
}
|
|
411
|
-
});
|
|
343
|
+
var decodeJWTMiddleware = function (req, res, next) { return __awaiter(void 0, void 0, void 0, function () {
|
|
344
|
+
var token, decoded, userText, expiredAt, message, details, sessionId, user, error_5;
|
|
345
|
+
var _a, _b, _c, _d;
|
|
346
|
+
return __generator(this, function (_e) {
|
|
347
|
+
switch (_e.label) {
|
|
348
|
+
case 0:
|
|
349
|
+
if (!process.env.TOKEN_SECRET) {
|
|
350
|
+
return [2 /*return*/, next()];
|
|
351
|
+
}
|
|
352
|
+
// Allow requests with a "Secret" prefix to pass through since this is a string value,
|
|
353
|
+
// not a jwt that needs to be decoded
|
|
354
|
+
if (((_b = (_a = req === null || req === void 0 ? void 0 : req.headers) === null || _a === void 0 ? void 0 : _a.authorization) === null || _b === void 0 ? void 0 : _b.split(" ")[0]) === "Secret") {
|
|
355
|
+
return [2 /*return*/, next()];
|
|
356
|
+
}
|
|
357
|
+
token = customTokenExtractor(req);
|
|
358
|
+
// For some reason, our app will happily put null into the authorization header when logging
|
|
359
|
+
// out then back in.
|
|
360
|
+
if (!token || token === "null" || token === "undefined") {
|
|
361
|
+
return [2 /*return*/, next()];
|
|
362
|
+
}
|
|
363
|
+
try {
|
|
364
|
+
decoded = jsonwebtoken_1.default.verify(token, process.env.TOKEN_SECRET, {
|
|
365
|
+
issuer: process.env.TOKEN_ISSUER,
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
userText = ((_c = req.user) === null || _c === void 0 ? void 0 : _c._id) ? " for user ".concat(req.user._id, " ") : "";
|
|
370
|
+
expiredAt = error && typeof error === "object" && "expiredAt" in error
|
|
371
|
+
? error.expiredAt
|
|
372
|
+
: undefined;
|
|
373
|
+
message = (0, errors_1.errorMessage)(error);
|
|
374
|
+
details = "[jwt] Error decoding token".concat(userText, ": ").concat(error, ", expired at ").concat(expiredAt, ", current time: ").concat(Date.now());
|
|
375
|
+
logger_1.logger.debug(details);
|
|
376
|
+
return [2 /*return*/, res.status(401).json({ details: details, message: message })];
|
|
377
|
+
}
|
|
378
|
+
if (!(decoded === null || decoded === void 0 ? void 0 : decoded.id)) return [3 /*break*/, 4];
|
|
379
|
+
sessionId = (0, requestContext_1.getSessionIdFromJwtPayload)(decoded);
|
|
380
|
+
req.authTokenPayload = decoded;
|
|
381
|
+
if (sessionId) {
|
|
382
|
+
req.sessionId = sessionId;
|
|
383
|
+
(0, requestContext_1.setRequestContext)({ sessionId: sessionId });
|
|
384
|
+
}
|
|
385
|
+
_e.label = 1;
|
|
386
|
+
case 1:
|
|
387
|
+
_e.trys.push([1, 3, , 4]);
|
|
388
|
+
return [4 /*yield*/, userModel.findById(decoded.id)];
|
|
389
|
+
case 2:
|
|
390
|
+
user = _e.sent();
|
|
391
|
+
req.user = user;
|
|
392
|
+
(0, requestContext_1.updateRequestContextFromRequest)(req, res);
|
|
393
|
+
if ((_d = req.user) === null || _d === void 0 ? void 0 : _d.disabled) {
|
|
394
|
+
logger_1.logger.warn("[jwt] User ".concat(req.user.id, " is disabled"));
|
|
395
|
+
return [2 /*return*/, res.status(401).json({ status: 401, title: "User is disabled" })];
|
|
396
|
+
}
|
|
397
|
+
return [3 /*break*/, 4];
|
|
398
|
+
case 3:
|
|
399
|
+
error_5 = _e.sent();
|
|
400
|
+
logger_1.logger.warn("[jwt] Error finding user from id: ".concat(error_5));
|
|
401
|
+
return [3 /*break*/, 4];
|
|
402
|
+
case 4: return [2 /*return*/, next()];
|
|
403
|
+
}
|
|
412
404
|
});
|
|
413
|
-
}
|
|
405
|
+
}); };
|
|
414
406
|
app.use(decodeJWTMiddleware);
|
|
415
407
|
// biome-ignore lint/suspicious/noExplicitAny: express 5 type for urlencoded doesn't match RequestHandler
|
|
416
408
|
app.use(express_1.default.urlencoded({ extended: false }));
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
|
|
409
|
+
};
|
|
410
|
+
exports.setupAuth = setupAuth;
|
|
411
|
+
var addAuthRoutes = function (app, userModel, authOptions) {
|
|
420
412
|
var router = express_1.default.Router();
|
|
421
|
-
router.post("/login", function (req, res, next) { return __awaiter(
|
|
422
|
-
var _this = this;
|
|
413
|
+
router.post("/login", function (req, res, next) { return __awaiter(void 0, void 0, void 0, function () {
|
|
423
414
|
return __generator(this, function (_a) {
|
|
424
|
-
passport_1.default.authenticate("local", { session: false }, function (err, user, info) { return __awaiter(
|
|
415
|
+
passport_1.default.authenticate("local", { session: false }, function (err, user, info) { return __awaiter(void 0, void 0, void 0, function () {
|
|
425
416
|
var tokens;
|
|
426
417
|
return __generator(this, function (_a) {
|
|
427
418
|
switch (_a.label) {
|
|
@@ -453,7 +444,7 @@ function addAuthRoutes(app, userModel, authOptions) {
|
|
|
453
444
|
return [2 /*return*/];
|
|
454
445
|
});
|
|
455
446
|
}); });
|
|
456
|
-
router.post("/refresh_token", function (req, res) { return __awaiter(
|
|
447
|
+
router.post("/refresh_token", function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
|
|
457
448
|
var refreshTokenSecretOrKey, decoded, message, user, sessionId, tokens;
|
|
458
449
|
var _a, _b, _c, _d;
|
|
459
450
|
return __generator(this, function (_e) {
|
|
@@ -503,7 +494,7 @@ function addAuthRoutes(app, userModel, authOptions) {
|
|
|
503
494
|
}); });
|
|
504
495
|
var signupDisabled = process.env.SIGNUP_DISABLED === "true";
|
|
505
496
|
if (!signupDisabled) {
|
|
506
|
-
router.post("/signup", passport_1.default.authenticate("signup", { failWithError: true, session: false }), function (req, res) { return __awaiter(
|
|
497
|
+
router.post("/signup", passport_1.default.authenticate("signup", { failWithError: true, session: false }), function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
|
|
507
498
|
var tokens;
|
|
508
499
|
var _a, _b;
|
|
509
500
|
return __generator(this, function (_c) {
|
|
@@ -527,11 +518,11 @@ function addAuthRoutes(app, userModel, authOptions) {
|
|
|
527
518
|
}
|
|
528
519
|
app.set("etag", false);
|
|
529
520
|
app.use("/auth", router);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
|
|
521
|
+
};
|
|
522
|
+
exports.addAuthRoutes = addAuthRoutes;
|
|
523
|
+
var addMeRoutes = function (app, userModel, _authOptions) {
|
|
533
524
|
var router = express_1.default.Router();
|
|
534
|
-
router.get("/me", authenticateMiddleware(), function (req, res) { return __awaiter(
|
|
525
|
+
router.get("/me", (0, exports.authenticateMiddleware)(), function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
|
|
535
526
|
var data, dataObject;
|
|
536
527
|
var _a;
|
|
537
528
|
return __generator(this, function (_b) {
|
|
@@ -554,7 +545,7 @@ function addMeRoutes(app, userModel, _authOptions) {
|
|
|
554
545
|
}
|
|
555
546
|
});
|
|
556
547
|
}); });
|
|
557
|
-
router.patch("/me", authenticateMiddleware(), function (req, res) { return __awaiter(
|
|
548
|
+
router.patch("/me", (0, exports.authenticateMiddleware)(), function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
|
|
558
549
|
var doc, dataObject, error_6, message;
|
|
559
550
|
var _a;
|
|
560
551
|
return __generator(this, function (_b) {
|
|
@@ -590,4 +581,5 @@ function addMeRoutes(app, userModel, _authOptions) {
|
|
|
590
581
|
app.set("etag", false);
|
|
591
582
|
app.use("/auth", router);
|
|
592
583
|
app.use(errors_1.apiErrorMiddleware);
|
|
593
|
-
}
|
|
584
|
+
};
|
|
585
|
+
exports.addMeRoutes = addMeRoutes;
|
|
@@ -319,4 +319,53 @@ var setupLoader = function () {
|
|
|
319
319
|
}
|
|
320
320
|
});
|
|
321
321
|
}); });
|
|
322
|
+
(0, bun_test_1.it)("mapToObject handles a plain Record (non-Map) env field", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
323
|
+
var col;
|
|
324
|
+
var _a;
|
|
325
|
+
return __generator(this, function (_b) {
|
|
326
|
+
switch (_b.label) {
|
|
327
|
+
case 0:
|
|
328
|
+
col = (_a = mongoose_1.default.connection.db) === null || _a === void 0 ? void 0 : _a.collection("testenvconfigs");
|
|
329
|
+
return [4 /*yield*/, (col === null || col === void 0 ? void 0 : col.insertOne({ env: { TERRENO_PLUGIN_KEY: "plainObj" } }))];
|
|
330
|
+
case 1:
|
|
331
|
+
_b.sent();
|
|
332
|
+
// Trigger refresh via findOneAndUpdate hook
|
|
333
|
+
return [4 /*yield*/, TestEnvConfig.findOneAndUpdate({}, { $set: { __v: 1 } })];
|
|
334
|
+
case 2:
|
|
335
|
+
// Trigger refresh via findOneAndUpdate hook
|
|
336
|
+
_b.sent();
|
|
337
|
+
(0, bun_test_1.expect)(config_1.Config.get("TERRENO_PLUGIN_KEY")).toBe("plainObj");
|
|
338
|
+
return [2 /*return*/];
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
}); });
|
|
342
|
+
(0, bun_test_1.it)("refreshFromDoc logs a warning and does not throw when the model query fails", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
343
|
+
var doc, originalFind;
|
|
344
|
+
return __generator(this, function (_a) {
|
|
345
|
+
switch (_a.label) {
|
|
346
|
+
case 0:
|
|
347
|
+
doc = new TestEnvConfig();
|
|
348
|
+
doc.env.set("TERRENO_PLUGIN_KEY", "initial");
|
|
349
|
+
return [4 /*yield*/, doc.save()];
|
|
350
|
+
case 1:
|
|
351
|
+
_a.sent();
|
|
352
|
+
// Pre-set cache to verify it is NOT overwritten when the hook errors
|
|
353
|
+
config_1.Config.setCachedEnv({ TERRENO_PLUGIN_KEY: "cached" });
|
|
354
|
+
originalFind = TestEnvConfig.find;
|
|
355
|
+
TestEnvConfig.find = function () {
|
|
356
|
+
throw new Error("Simulated DB error");
|
|
357
|
+
};
|
|
358
|
+
// Trigger the post-findOneAndUpdate hook → refreshFromDoc → findOneOrNoneFor → throws
|
|
359
|
+
return [4 /*yield*/, TestEnvConfig.findOneAndUpdate({ _id: doc._id }, { $set: { __v: 2 } })];
|
|
360
|
+
case 2:
|
|
361
|
+
// Trigger the post-findOneAndUpdate hook → refreshFromDoc → findOneOrNoneFor → throws
|
|
362
|
+
_a.sent();
|
|
363
|
+
// Restore immediately
|
|
364
|
+
TestEnvConfig.find = originalFind;
|
|
365
|
+
// The catch block should have swallowed the error; cache keeps old value
|
|
366
|
+
(0, bun_test_1.expect)(config_1.Config.get("TERRENO_PLUGIN_KEY")).toBe("cached");
|
|
367
|
+
return [2 /*return*/];
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
}); });
|
|
322
371
|
});
|
|
@@ -1039,7 +1039,6 @@ var tests_1 = require("./tests");
|
|
|
1039
1039
|
case 1:
|
|
1040
1040
|
express = _a.sent();
|
|
1041
1041
|
originalListen = express.default.application.listen;
|
|
1042
|
-
// biome-ignore lint/suspicious/noExplicitAny: mocking Express internals requires type escape
|
|
1043
1042
|
express.default.application.listen = (0, bun_test_1.mock)(function () {
|
|
1044
1043
|
var args = [];
|
|
1045
1044
|
for (var _i = 0; _i < arguments.length; _i++) {
|
package/dist/openApi.d.ts
CHANGED
|
@@ -53,9 +53,9 @@ export declare const defaultOpenApiErrorResponses: {
|
|
|
53
53
|
description: string;
|
|
54
54
|
};
|
|
55
55
|
};
|
|
56
|
-
export declare
|
|
57
|
-
export declare
|
|
58
|
-
export declare
|
|
59
|
-
export declare
|
|
60
|
-
export declare
|
|
61
|
-
export declare
|
|
56
|
+
export declare const getOpenApiMiddleware: <T>(model: Model<T>, options: Partial<ModelRouterOptions<T>>) => express.RequestHandler;
|
|
57
|
+
export declare const listOpenApiMiddleware: <T>(model: Model<T>, options: Partial<ModelRouterOptions<T>>) => express.RequestHandler;
|
|
58
|
+
export declare const createOpenApiMiddleware: <T>(model: Model<T>, options: Partial<ModelRouterOptions<T>>) => express.RequestHandler;
|
|
59
|
+
export declare const patchOpenApiMiddleware: <T>(model: Model<T>, options: Partial<ModelRouterOptions<T>>) => express.RequestHandler;
|
|
60
|
+
export declare const deleteOpenApiMiddleware: <T>(model: Model<T>, options: Partial<ModelRouterOptions<T>>) => express.RequestHandler;
|
|
61
|
+
export declare const readOpenApiMiddleware: <T>(options: Partial<ModelRouterOptions<T>>, properties: Record<string, unknown>, required: string[], queryParameters: Array<Record<string, unknown>>) => express.RequestHandler;
|
package/dist/openApi.js
CHANGED
|
@@ -39,13 +39,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
39
39
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
40
|
};
|
|
41
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
exports.defaultOpenApiErrorResponses = exports.apiErrorContent = void 0;
|
|
43
|
-
exports.getOpenApiMiddleware = getOpenApiMiddleware;
|
|
44
|
-
exports.listOpenApiMiddleware = listOpenApiMiddleware;
|
|
45
|
-
exports.createOpenApiMiddleware = createOpenApiMiddleware;
|
|
46
|
-
exports.patchOpenApiMiddleware = patchOpenApiMiddleware;
|
|
47
|
-
exports.deleteOpenApiMiddleware = deleteOpenApiMiddleware;
|
|
48
|
-
exports.readOpenApiMiddleware = readOpenApiMiddleware;
|
|
42
|
+
exports.readOpenApiMiddleware = exports.deleteOpenApiMiddleware = exports.patchOpenApiMiddleware = exports.createOpenApiMiddleware = exports.listOpenApiMiddleware = exports.getOpenApiMiddleware = exports.defaultOpenApiErrorResponses = exports.apiErrorContent = void 0;
|
|
49
43
|
var flatten_1 = __importDefault(require("lodash/flatten"));
|
|
50
44
|
var merge_1 = __importDefault(require("lodash/merge"));
|
|
51
45
|
var mongoose_to_swagger_1 = __importDefault(require("mongoose-to-swagger"));
|
|
@@ -83,7 +77,7 @@ exports.defaultOpenApiErrorResponses = {
|
|
|
83
77
|
},
|
|
84
78
|
};
|
|
85
79
|
// We repeat this constantly, so we make it a component so we only have to define it once.
|
|
86
|
-
function
|
|
80
|
+
var createAPIErrorComponent = function (openApi) {
|
|
87
81
|
// Create a schema component called APIError
|
|
88
82
|
openApi === null || openApi === void 0 ? void 0 : openApi.component("schemas", "APIError", {
|
|
89
83
|
properties: {
|
|
@@ -144,8 +138,8 @@ function createAPIErrorComponent(openApi) {
|
|
|
144
138
|
},
|
|
145
139
|
type: "object",
|
|
146
140
|
});
|
|
147
|
-
}
|
|
148
|
-
function
|
|
141
|
+
};
|
|
142
|
+
var getOpenApiMiddleware = function (model, options) {
|
|
149
143
|
var _c, _d, _e, _f, _g;
|
|
150
144
|
createAPIErrorComponent(options.openApi);
|
|
151
145
|
if (!((_c = options.openApi) === null || _c === void 0 ? void 0 : _c.path)) {
|
|
@@ -175,8 +169,9 @@ function getOpenApiMiddleware(model, options) {
|
|
|
175
169
|
} }, exports.defaultOpenApiErrorResponses),
|
|
176
170
|
tags: [model.collection.collectionName],
|
|
177
171
|
}, (_g = (_f = options.openApiOverwrite) === null || _f === void 0 ? void 0 : _f.get) !== null && _g !== void 0 ? _g : {}));
|
|
178
|
-
}
|
|
179
|
-
|
|
172
|
+
};
|
|
173
|
+
exports.getOpenApiMiddleware = getOpenApiMiddleware;
|
|
174
|
+
var listOpenApiMiddleware = function (model, options) {
|
|
180
175
|
var _c, _d, _e, _f, _g, _h;
|
|
181
176
|
if (!((_c = options.openApi) === null || _c === void 0 ? void 0 : _c.path)) {
|
|
182
177
|
return noop;
|
|
@@ -316,8 +311,9 @@ function listOpenApiMiddleware(model, options) {
|
|
|
316
311
|
} }, exports.defaultOpenApiErrorResponses),
|
|
317
312
|
tags: [model.collection.collectionName],
|
|
318
313
|
}, (_h = (_g = options.openApiOverwrite) === null || _g === void 0 ? void 0 : _g.list) !== null && _h !== void 0 ? _h : {}));
|
|
319
|
-
}
|
|
320
|
-
|
|
314
|
+
};
|
|
315
|
+
exports.listOpenApiMiddleware = listOpenApiMiddleware;
|
|
316
|
+
var createOpenApiMiddleware = function (model, options) {
|
|
321
317
|
var _c, _d, _e, _f, _g;
|
|
322
318
|
if (!((_c = options.openApi) === null || _c === void 0 ? void 0 : _c.path)) {
|
|
323
319
|
return noop;
|
|
@@ -355,8 +351,9 @@ function createOpenApiMiddleware(model, options) {
|
|
|
355
351
|
} }, exports.defaultOpenApiErrorResponses),
|
|
356
352
|
tags: [model.collection.collectionName],
|
|
357
353
|
}, (_g = (_f = options.openApiOverwrite) === null || _f === void 0 ? void 0 : _f.create) !== null && _g !== void 0 ? _g : {}));
|
|
358
|
-
}
|
|
359
|
-
|
|
354
|
+
};
|
|
355
|
+
exports.createOpenApiMiddleware = createOpenApiMiddleware;
|
|
356
|
+
var patchOpenApiMiddleware = function (model, options) {
|
|
360
357
|
var _c, _d, _e, _f, _g;
|
|
361
358
|
if (!((_c = options.openApi) === null || _c === void 0 ? void 0 : _c.path)) {
|
|
362
359
|
return noop;
|
|
@@ -394,8 +391,9 @@ function patchOpenApiMiddleware(model, options) {
|
|
|
394
391
|
} }, exports.defaultOpenApiErrorResponses),
|
|
395
392
|
tags: [model.collection.collectionName],
|
|
396
393
|
}, (_g = (_f = options.openApiOverwrite) === null || _f === void 0 ? void 0 : _f.update) !== null && _g !== void 0 ? _g : {}));
|
|
397
|
-
}
|
|
398
|
-
|
|
394
|
+
};
|
|
395
|
+
exports.patchOpenApiMiddleware = patchOpenApiMiddleware;
|
|
396
|
+
var deleteOpenApiMiddleware = function (model, options) {
|
|
399
397
|
var _c, _d, _e, _f, _g;
|
|
400
398
|
if (!((_c = options.openApi) === null || _c === void 0 ? void 0 : _c.path)) {
|
|
401
399
|
return noop;
|
|
@@ -409,10 +407,11 @@ function deleteOpenApiMiddleware(model, options) {
|
|
|
409
407
|
} }, exports.defaultOpenApiErrorResponses),
|
|
410
408
|
tags: [model.collection.collectionName],
|
|
411
409
|
}, (_g = (_f = options.openApiOverwrite) === null || _f === void 0 ? void 0 : _f.delete) !== null && _g !== void 0 ? _g : {}));
|
|
412
|
-
}
|
|
410
|
+
};
|
|
411
|
+
exports.deleteOpenApiMiddleware = deleteOpenApiMiddleware;
|
|
413
412
|
// This is a generic OpenAPI wrapper for a read that returns any object described by `properties`.
|
|
414
413
|
// Useful for endpoints that don't directly map to a model.
|
|
415
|
-
function
|
|
414
|
+
var readOpenApiMiddleware = function (options, properties, required, queryParameters) {
|
|
416
415
|
var _c, _d, _e, _f, _g;
|
|
417
416
|
if (!((_c = options.openApi) === null || _c === void 0 ? void 0 : _c.path)) {
|
|
418
417
|
// Just log this once rather than for each middleware.
|
|
@@ -438,4 +437,5 @@ function readOpenApiMiddleware(options, properties, required, queryParameters) {
|
|
|
438
437
|
} }, exports.defaultOpenApiErrorResponses),
|
|
439
438
|
tags: [],
|
|
440
439
|
}, (_g = (_f = options.openApiOverwrite) === null || _f === void 0 ? void 0 : _f.get) !== null && _g !== void 0 ? _g : {}));
|
|
441
|
-
}
|
|
440
|
+
};
|
|
441
|
+
exports.readOpenApiMiddleware = readOpenApiMiddleware;
|