@terreno/api 0.13.2 → 0.14.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/__tests__/versionCheckPlugin.test.js +53 -3
- package/dist/api.arrayOperations.test.js +1 -0
- package/dist/api.asyncHandler.test.d.ts +1 -0
- package/dist/api.asyncHandler.test.js +236 -0
- package/dist/api.d.ts +15 -4
- package/dist/api.errors.test.js +1 -0
- package/dist/api.hooks.test.js +1 -0
- package/dist/api.js +153 -104
- package/dist/api.query.test.js +1 -0
- package/dist/api.test.js +174 -0
- package/dist/auth.d.ts +10 -5
- package/dist/auth.js +163 -90
- package/dist/auth.test.js +159 -0
- package/dist/betterAuthApp.test.js +1 -0
- package/dist/betterAuthSetup.d.ts +5 -6
- package/dist/betterAuthSetup.js +17 -14
- package/dist/betterAuthSetup.test.js +1 -0
- package/dist/config.d.ts +48 -0
- package/dist/config.js +248 -0
- package/dist/config.test.d.ts +1 -0
- package/dist/config.test.js +328 -0
- package/dist/configuration.test.js +1 -0
- package/dist/configurationApp.d.ts +1 -1
- package/dist/configurationApp.js +17 -13
- package/dist/configurationPlugin.test.js +1 -0
- package/dist/consentApp.test.js +1 -0
- package/dist/envConfigurationPlugin.d.ts +2 -0
- package/dist/envConfigurationPlugin.js +173 -0
- package/dist/envConfigurationPlugin.test.d.ts +1 -0
- package/dist/envConfigurationPlugin.test.js +322 -0
- package/dist/errors.d.ts +18 -7
- package/dist/errors.js +106 -10
- package/dist/errors.test.js +16 -1
- package/dist/example.js +16 -7
- package/dist/expressServer.d.ts +10 -9
- package/dist/expressServer.js +62 -53
- package/dist/expressServer.test.js +53 -2
- package/dist/githubAuth.d.ts +2 -1
- package/dist/githubAuth.js +41 -26
- package/dist/githubAuth.test.js +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/logger.d.ts +1 -1
- package/dist/logger.js +42 -20
- package/dist/models/versionConfig.d.ts +2 -0
- package/dist/models/versionConfig.js +8 -0
- package/dist/notifiers/googleChatNotifier.js +14 -16
- package/dist/notifiers/googleChatNotifier.test.js +1 -0
- package/dist/notifiers/slackNotifier.js +16 -14
- package/dist/notifiers/slackNotifier.test.js +41 -3
- package/dist/notifiers/zoomNotifier.js +7 -10
- package/dist/notifiers/zoomNotifier.test.js +1 -0
- package/dist/openApi.d.ts +1 -1
- package/dist/openApi.test.js +1 -0
- package/dist/openApiBuilder.d.ts +39 -6
- package/dist/openApiBuilder.js +1 -31
- package/dist/openApiBuilder.test.js +1 -0
- package/dist/openApiValidator.js +1 -0
- package/dist/openApiValidator.test.js +65 -0
- package/dist/permissions.d.ts +4 -4
- package/dist/permissions.js +67 -65
- package/dist/permissions.middleware.test.js +1 -0
- package/dist/permissions.test.js +1 -0
- package/dist/plugins.d.ts +5 -5
- package/dist/plugins.js +18 -9
- package/dist/plugins.test.js +1 -1
- package/dist/populate.d.ts +15 -8
- package/dist/populate.js +23 -24
- package/dist/populate.test.js +1 -0
- package/dist/realtime/changeStreamWatcher.d.ts +73 -0
- package/dist/realtime/changeStreamWatcher.js +720 -0
- package/dist/realtime/index.d.ts +6 -0
- package/dist/realtime/index.js +27 -0
- package/dist/realtime/queryMatcher.d.ts +14 -0
- package/dist/realtime/queryMatcher.js +250 -0
- package/dist/realtime/queryStore.d.ts +37 -0
- package/dist/realtime/queryStore.js +195 -0
- package/dist/realtime/realtime.test.d.ts +10 -0
- package/dist/realtime/realtime.test.js +2158 -0
- package/dist/realtime/realtimeApp.d.ts +93 -0
- package/dist/realtime/realtimeApp.js +560 -0
- package/dist/realtime/registry.d.ts +40 -0
- package/dist/realtime/registry.js +38 -0
- package/dist/realtime/socketUser.d.ts +10 -0
- package/dist/realtime/socketUser.js +17 -0
- package/dist/realtime/types.d.ts +100 -0
- package/dist/realtime/types.js +2 -0
- package/dist/requestContext.d.ts +37 -0
- package/dist/requestContext.js +344 -0
- package/dist/requestContext.test.d.ts +1 -0
- package/dist/requestContext.test.js +241 -0
- package/dist/terrenoApp.d.ts +8 -0
- package/dist/terrenoApp.js +50 -13
- package/dist/terrenoApp.test.js +194 -21
- package/dist/terrenoPlugin.d.ts +11 -0
- package/dist/tests/bunSetup.js +1 -0
- package/dist/tests.js +1 -1
- package/dist/transformers.d.ts +2 -2
- package/dist/transformers.js +5 -3
- package/dist/transformers.test.js +90 -0
- package/dist/types/consentResponse.d.ts +6 -3
- package/dist/versionCheckPlugin.d.ts +2 -0
- package/dist/versionCheckPlugin.js +18 -12
- package/package.json +4 -2
- package/src/__tests__/versionCheckPlugin.test.ts +37 -3
- package/src/api.arrayOperations.test.ts +1 -0
- package/src/api.asyncHandler.test.ts +177 -0
- package/src/api.errors.test.ts +1 -0
- package/src/api.hooks.test.ts +1 -0
- package/src/api.query.test.ts +1 -0
- package/src/api.test.ts +132 -0
- package/src/api.ts +199 -84
- package/src/auth.test.ts +160 -0
- package/src/auth.ts +120 -50
- package/src/betterAuthApp.test.ts +1 -0
- package/src/betterAuthSetup.test.ts +1 -0
- package/src/betterAuthSetup.ts +46 -19
- package/src/config.test.ts +255 -0
- package/src/config.ts +206 -0
- package/src/configuration.test.ts +1 -0
- package/src/configurationApp.ts +59 -24
- package/src/configurationPlugin.test.ts +1 -0
- package/src/consentApp.test.ts +1 -0
- package/src/envConfigurationPlugin.test.ts +143 -0
- package/src/envConfigurationPlugin.ts +100 -0
- package/src/errors.test.ts +19 -1
- package/src/errors.ts +94 -20
- package/src/example.ts +46 -21
- package/src/express.d.ts +18 -1
- package/src/expressServer.test.ts +50 -2
- package/src/expressServer.ts +80 -50
- package/src/githubAuth.test.ts +1 -0
- package/src/githubAuth.ts +59 -38
- package/src/index.ts +4 -0
- package/src/logger.ts +47 -17
- package/src/models/versionConfig.ts +13 -2
- package/src/notifiers/googleChatNotifier.test.ts +1 -0
- package/src/notifiers/googleChatNotifier.ts +7 -9
- package/src/notifiers/slackNotifier.test.ts +29 -3
- package/src/notifiers/slackNotifier.ts +9 -7
- package/src/notifiers/zoomNotifier.test.ts +1 -0
- package/src/notifiers/zoomNotifier.ts +8 -11
- package/src/openApi.test.ts +1 -0
- package/src/openApi.ts +4 -4
- package/src/openApiBuilder.test.ts +1 -0
- package/src/openApiBuilder.ts +14 -11
- package/src/openApiValidator.test.ts +59 -0
- package/src/openApiValidator.ts +3 -2
- package/src/permissions.middleware.test.ts +1 -0
- package/src/permissions.test.ts +1 -0
- package/src/permissions.ts +30 -25
- package/src/plugins.test.ts +1 -1
- package/src/plugins.ts +21 -14
- package/src/populate.test.ts +1 -0
- package/src/populate.ts +44 -36
- package/src/realtime/changeStreamWatcher.ts +568 -0
- package/src/realtime/index.ts +34 -0
- package/src/realtime/queryMatcher.ts +179 -0
- package/src/realtime/queryStore.ts +132 -0
- package/src/realtime/realtime.test.ts +1755 -0
- package/src/realtime/realtimeApp.ts +478 -0
- package/src/realtime/registry.ts +64 -0
- package/src/realtime/socketUser.ts +25 -0
- package/src/realtime/types.ts +112 -0
- package/src/requestContext.test.ts +196 -0
- package/src/requestContext.ts +368 -0
- package/src/terrenoApp.test.ts +137 -11
- package/src/terrenoApp.ts +64 -17
- package/src/terrenoPlugin.ts +12 -0
- package/src/tests/bunSetup.ts +1 -0
- package/src/tests.ts +7 -2
- package/src/transformers.test.ts +70 -2
- package/src/transformers.ts +15 -7
- package/src/types/consentResponse.ts +8 -10
- package/src/versionCheckPlugin.ts +15 -7
package/dist/terrenoApp.test.js
CHANGED
|
@@ -10,6 +10,39 @@ var __assign = (this && this.__assign) || function () {
|
|
|
10
10
|
};
|
|
11
11
|
return __assign.apply(this, arguments);
|
|
12
12
|
};
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
13
46
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
47
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
48
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -67,11 +100,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
67
100
|
};
|
|
68
101
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
69
102
|
var bun_test_1 = require("bun:test");
|
|
103
|
+
var mongoose_1 = __importStar(require("mongoose"));
|
|
70
104
|
var supertest_1 = __importDefault(require("supertest"));
|
|
71
105
|
var api_1 = require("./api");
|
|
106
|
+
var configurationPlugin_1 = require("./configurationPlugin");
|
|
72
107
|
var permissions_1 = require("./permissions");
|
|
108
|
+
var plugins_1 = require("./plugins");
|
|
73
109
|
var terrenoApp_1 = require("./terrenoApp");
|
|
74
110
|
var tests_1 = require("./tests");
|
|
111
|
+
var typedUserModel = tests_1.UserModel;
|
|
75
112
|
(0, bun_test_1.describe)("TerrenoApp", function () {
|
|
76
113
|
var originalEnv = process.env;
|
|
77
114
|
(0, bun_test_1.beforeEach)(function () {
|
|
@@ -84,7 +121,7 @@ var tests_1 = require("./tests");
|
|
|
84
121
|
(0, bun_test_1.it)("returns an express application without listening", function () {
|
|
85
122
|
var app = new terrenoApp_1.TerrenoApp({
|
|
86
123
|
skipListen: true,
|
|
87
|
-
userModel:
|
|
124
|
+
userModel: typedUserModel,
|
|
88
125
|
}).build();
|
|
89
126
|
(0, bun_test_1.expect)(app).toBeDefined();
|
|
90
127
|
});
|
|
@@ -92,7 +129,7 @@ var tests_1 = require("./tests");
|
|
|
92
129
|
var app = new terrenoApp_1.TerrenoApp({
|
|
93
130
|
corsOrigin: "https://example.com",
|
|
94
131
|
skipListen: true,
|
|
95
|
-
userModel:
|
|
132
|
+
userModel: typedUserModel,
|
|
96
133
|
}).build();
|
|
97
134
|
(0, bun_test_1.expect)(app).toBeDefined();
|
|
98
135
|
});
|
|
@@ -101,7 +138,7 @@ var tests_1 = require("./tests");
|
|
|
101
138
|
(0, bun_test_1.it)("returns an express application with skipListen", function () {
|
|
102
139
|
var app = new terrenoApp_1.TerrenoApp({
|
|
103
140
|
skipListen: true,
|
|
104
|
-
userModel:
|
|
141
|
+
userModel: typedUserModel,
|
|
105
142
|
}).start();
|
|
106
143
|
(0, bun_test_1.expect)(app).toBeDefined();
|
|
107
144
|
});
|
|
@@ -109,20 +146,20 @@ var tests_1 = require("./tests");
|
|
|
109
146
|
(0, bun_test_1.describe)("register with modelRouter", function () {
|
|
110
147
|
var admin;
|
|
111
148
|
(0, bun_test_1.beforeEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
112
|
-
var
|
|
113
|
-
return __generator(this, function (
|
|
114
|
-
switch (
|
|
149
|
+
var _d;
|
|
150
|
+
return __generator(this, function (_e) {
|
|
151
|
+
switch (_e.label) {
|
|
115
152
|
case 0: return [4 /*yield*/, (0, tests_1.setupDb)()];
|
|
116
153
|
case 1:
|
|
117
|
-
|
|
154
|
+
_d = __read.apply(void 0, [_e.sent(), 1]), admin = _d[0];
|
|
118
155
|
return [2 /*return*/];
|
|
119
156
|
}
|
|
120
157
|
});
|
|
121
158
|
}); });
|
|
122
159
|
(0, bun_test_1.it)("mounts model router at the specified path", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
123
160
|
var foodRegistration, app, agent, res;
|
|
124
|
-
return __generator(this, function (
|
|
125
|
-
switch (
|
|
161
|
+
return __generator(this, function (_d) {
|
|
162
|
+
switch (_d.label) {
|
|
126
163
|
case 0:
|
|
127
164
|
foodRegistration = (0, api_1.modelRouter)("/food", tests_1.FoodModel, {
|
|
128
165
|
allowAnonymous: true,
|
|
@@ -139,7 +176,7 @@ var tests_1 = require("./tests");
|
|
|
139
176
|
(0, bun_test_1.expect)(foodRegistration.path).toBe("/food");
|
|
140
177
|
app = new terrenoApp_1.TerrenoApp({
|
|
141
178
|
skipListen: true,
|
|
142
|
-
userModel:
|
|
179
|
+
userModel: typedUserModel,
|
|
143
180
|
})
|
|
144
181
|
.register(foodRegistration)
|
|
145
182
|
.build();
|
|
@@ -150,13 +187,13 @@ var tests_1 = require("./tests");
|
|
|
150
187
|
source: { name: "Nature" },
|
|
151
188
|
})];
|
|
152
189
|
case 1:
|
|
153
|
-
|
|
190
|
+
_d.sent();
|
|
154
191
|
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
155
192
|
case 2:
|
|
156
|
-
agent =
|
|
193
|
+
agent = _d.sent();
|
|
157
194
|
return [4 /*yield*/, agent.get("/food").expect(200)];
|
|
158
195
|
case 3:
|
|
159
|
-
res =
|
|
196
|
+
res = _d.sent();
|
|
160
197
|
(0, bun_test_1.expect)(res.body.data).toHaveLength(1);
|
|
161
198
|
(0, bun_test_1.expect)(res.body.data[0].name).toBe("Apple");
|
|
162
199
|
return [2 /*return*/];
|
|
@@ -165,7 +202,7 @@ var tests_1 = require("./tests");
|
|
|
165
202
|
}); });
|
|
166
203
|
(0, bun_test_1.it)("supports chaining multiple registrations", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
167
204
|
var foodRegistration, app;
|
|
168
|
-
return __generator(this, function (
|
|
205
|
+
return __generator(this, function (_d) {
|
|
169
206
|
foodRegistration = (0, api_1.modelRouter)("/food", tests_1.FoodModel, {
|
|
170
207
|
allowAnonymous: true,
|
|
171
208
|
permissions: {
|
|
@@ -178,7 +215,7 @@ var tests_1 = require("./tests");
|
|
|
178
215
|
});
|
|
179
216
|
app = new terrenoApp_1.TerrenoApp({
|
|
180
217
|
skipListen: true,
|
|
181
|
-
userModel:
|
|
218
|
+
userModel: typedUserModel,
|
|
182
219
|
})
|
|
183
220
|
.register(foodRegistration)
|
|
184
221
|
.build();
|
|
@@ -195,12 +232,11 @@ var tests_1 = require("./tests");
|
|
|
195
232
|
};
|
|
196
233
|
var app = new terrenoApp_1.TerrenoApp({
|
|
197
234
|
skipListen: true,
|
|
198
|
-
userModel:
|
|
235
|
+
userModel: typedUserModel,
|
|
199
236
|
})
|
|
200
237
|
.register(plugin)
|
|
201
238
|
.build();
|
|
202
239
|
(0, bun_test_1.expect)(registerFn).toHaveBeenCalledTimes(1);
|
|
203
|
-
// Verify the plugin received the express app
|
|
204
240
|
var calledWith = registerFn.mock.calls[0][0];
|
|
205
241
|
(0, bun_test_1.expect)(calledWith).toBe(app);
|
|
206
242
|
});
|
|
@@ -208,8 +244,8 @@ var tests_1 = require("./tests");
|
|
|
208
244
|
(0, bun_test_1.describe)("addMiddleware", function () {
|
|
209
245
|
(0, bun_test_1.it)("runs request handler middleware", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
210
246
|
var middlewareCalled, middleware, app;
|
|
211
|
-
return __generator(this, function (
|
|
212
|
-
switch (
|
|
247
|
+
return __generator(this, function (_d) {
|
|
248
|
+
switch (_d.label) {
|
|
213
249
|
case 0:
|
|
214
250
|
middlewareCalled = false;
|
|
215
251
|
middleware = function (_req, _res, next) {
|
|
@@ -218,19 +254,156 @@ var tests_1 = require("./tests");
|
|
|
218
254
|
};
|
|
219
255
|
app = new terrenoApp_1.TerrenoApp({
|
|
220
256
|
skipListen: true,
|
|
221
|
-
userModel:
|
|
257
|
+
userModel: typedUserModel,
|
|
222
258
|
})
|
|
223
259
|
.addMiddleware(middleware)
|
|
224
260
|
.build();
|
|
225
261
|
return [4 /*yield*/, (0, supertest_1.default)(app).get("/nonexistent").expect(404)];
|
|
226
262
|
case 1:
|
|
227
|
-
|
|
263
|
+
_d.sent();
|
|
228
264
|
(0, bun_test_1.expect)(middlewareCalled).toBe(true);
|
|
229
265
|
return [2 /*return*/];
|
|
230
266
|
}
|
|
231
267
|
});
|
|
232
268
|
}); });
|
|
233
269
|
});
|
|
270
|
+
(0, bun_test_1.describe)("configure", function () {
|
|
271
|
+
(0, bun_test_1.beforeEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
272
|
+
return __generator(this, function (_d) {
|
|
273
|
+
switch (_d.label) {
|
|
274
|
+
case 0: return [4 /*yield*/, (0, tests_1.setupDb)()];
|
|
275
|
+
case 1:
|
|
276
|
+
_d.sent();
|
|
277
|
+
return [2 /*return*/];
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
}); });
|
|
281
|
+
(0, bun_test_1.it)("mounts configuration routes when configure() is called", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
282
|
+
var cfgSchema, modelName, CfgModel, app, agent, res;
|
|
283
|
+
return __generator(this, function (_d) {
|
|
284
|
+
switch (_d.label) {
|
|
285
|
+
case 0:
|
|
286
|
+
cfgSchema = new mongoose_1.Schema({ siteName: { default: "My Site", description: "Site name", type: String } }, { strict: "throw", toJSON: { virtuals: true }, toObject: { virtuals: true } });
|
|
287
|
+
cfgSchema.plugin(configurationPlugin_1.configurationPlugin);
|
|
288
|
+
cfgSchema.plugin(plugins_1.createdUpdatedPlugin);
|
|
289
|
+
modelName = "CfgModel_".concat(Date.now());
|
|
290
|
+
CfgModel = mongoose_1.default.model(modelName, cfgSchema);
|
|
291
|
+
app = new terrenoApp_1.TerrenoApp({
|
|
292
|
+
skipListen: true,
|
|
293
|
+
userModel: typedUserModel,
|
|
294
|
+
})
|
|
295
|
+
.configure(CfgModel)
|
|
296
|
+
.build();
|
|
297
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
298
|
+
case 1:
|
|
299
|
+
agent = _d.sent();
|
|
300
|
+
return [4 /*yield*/, agent.get("/configuration/meta")];
|
|
301
|
+
case 2:
|
|
302
|
+
res = _d.sent();
|
|
303
|
+
(0, bun_test_1.expect)(res.status).toBe(200);
|
|
304
|
+
return [2 /*return*/];
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}); });
|
|
308
|
+
(0, bun_test_1.it)("supports custom basePath via configure options", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
309
|
+
var cfgSchema2, modelName, CfgModel2, app, agent, res;
|
|
310
|
+
return __generator(this, function (_d) {
|
|
311
|
+
switch (_d.label) {
|
|
312
|
+
case 0:
|
|
313
|
+
cfgSchema2 = new mongoose_1.Schema({ siteName: { default: "Test", description: "Site name", type: String } }, { strict: "throw", toJSON: { virtuals: true }, toObject: { virtuals: true } });
|
|
314
|
+
cfgSchema2.plugin(configurationPlugin_1.configurationPlugin);
|
|
315
|
+
cfgSchema2.plugin(plugins_1.createdUpdatedPlugin);
|
|
316
|
+
modelName = "CfgModel2_".concat(Date.now());
|
|
317
|
+
CfgModel2 = mongoose_1.default.model(modelName, cfgSchema2);
|
|
318
|
+
app = new terrenoApp_1.TerrenoApp({
|
|
319
|
+
skipListen: true,
|
|
320
|
+
userModel: typedUserModel,
|
|
321
|
+
})
|
|
322
|
+
.configure(CfgModel2, { basePath: "/settings" })
|
|
323
|
+
.build();
|
|
324
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(app, "admin")];
|
|
325
|
+
case 1:
|
|
326
|
+
agent = _d.sent();
|
|
327
|
+
return [4 /*yield*/, agent.get("/settings/meta")];
|
|
328
|
+
case 2:
|
|
329
|
+
res = _d.sent();
|
|
330
|
+
(0, bun_test_1.expect)(res.status).toBe(200);
|
|
331
|
+
return [2 /*return*/];
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
}); });
|
|
335
|
+
});
|
|
336
|
+
(0, bun_test_1.describe)("fallthrough error handler", function () {
|
|
337
|
+
(0, bun_test_1.it)("returns 500 for non-API errors", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
338
|
+
var plugin, app, res;
|
|
339
|
+
return __generator(this, function (_d) {
|
|
340
|
+
switch (_d.label) {
|
|
341
|
+
case 0:
|
|
342
|
+
plugin = {
|
|
343
|
+
register: function (pluginApp) {
|
|
344
|
+
pluginApp.get("/trigger-fallthrough", function (_req, _res) {
|
|
345
|
+
throw new Error("unexpected failure");
|
|
346
|
+
});
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
app = new terrenoApp_1.TerrenoApp({
|
|
350
|
+
skipListen: true,
|
|
351
|
+
userModel: typedUserModel,
|
|
352
|
+
})
|
|
353
|
+
.register(plugin)
|
|
354
|
+
.build();
|
|
355
|
+
return [4 /*yield*/, (0, supertest_1.default)(app).get("/trigger-fallthrough")];
|
|
356
|
+
case 1:
|
|
357
|
+
res = _d.sent();
|
|
358
|
+
(0, bun_test_1.expect)(res.status).toBe(500);
|
|
359
|
+
return [2 /*return*/];
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
}); });
|
|
363
|
+
});
|
|
364
|
+
(0, bun_test_1.describe)("start with listen", function () {
|
|
365
|
+
(0, bun_test_1.it)("starts and listens on the configured port", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
366
|
+
var port, app;
|
|
367
|
+
return __generator(this, function (_d) {
|
|
368
|
+
port = "19876";
|
|
369
|
+
process.env.PORT = port;
|
|
370
|
+
app = new terrenoApp_1.TerrenoApp({
|
|
371
|
+
userModel: typedUserModel,
|
|
372
|
+
}).start();
|
|
373
|
+
(0, bun_test_1.expect)(app).toBeDefined();
|
|
374
|
+
return [2 /*return*/];
|
|
375
|
+
});
|
|
376
|
+
}); });
|
|
377
|
+
});
|
|
378
|
+
(0, bun_test_1.describe)("addMiddleware with app-configuring function", function () {
|
|
379
|
+
(0, bun_test_1.it)("invokes a function that receives the express app (fn.length > 3)", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
380
|
+
var receivedApp, configFn, app;
|
|
381
|
+
return __generator(this, function (_d) {
|
|
382
|
+
configFn = function (_appInstance, _a, _b, _c) {
|
|
383
|
+
receivedApp = _appInstance;
|
|
384
|
+
};
|
|
385
|
+
app = new terrenoApp_1.TerrenoApp({
|
|
386
|
+
skipListen: true,
|
|
387
|
+
userModel: typedUserModel,
|
|
388
|
+
})
|
|
389
|
+
.addMiddleware(configFn)
|
|
390
|
+
.build();
|
|
391
|
+
(0, bun_test_1.expect)(app).toBeDefined();
|
|
392
|
+
(0, bun_test_1.expect)(receivedApp).toBe(app);
|
|
393
|
+
return [2 /*return*/];
|
|
394
|
+
});
|
|
395
|
+
}); });
|
|
396
|
+
});
|
|
397
|
+
(0, bun_test_1.describe)("logRequests option", function () {
|
|
398
|
+
(0, bun_test_1.it)("disables request logging when logRequests is false", function () {
|
|
399
|
+
var app = new terrenoApp_1.TerrenoApp({
|
|
400
|
+
logRequests: false,
|
|
401
|
+
skipListen: true,
|
|
402
|
+
userModel: typedUserModel,
|
|
403
|
+
}).build();
|
|
404
|
+
(0, bun_test_1.expect)(app).toBeDefined();
|
|
405
|
+
});
|
|
406
|
+
});
|
|
234
407
|
(0, bun_test_1.describe)("modelRouter overload", function () {
|
|
235
408
|
(0, bun_test_1.it)("returns ModelRouterRegistration when path is provided", function () {
|
|
236
409
|
var result = (0, api_1.modelRouter)("/food", tests_1.FoodModel, {
|
package/dist/terrenoPlugin.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type http from "node:http";
|
|
1
2
|
import type express from "express";
|
|
2
3
|
/**
|
|
3
4
|
* Interface for plugins that can be registered with TerrenoApp.
|
|
@@ -35,4 +36,14 @@ export interface TerrenoPlugin {
|
|
|
35
36
|
* @param app - The Express application instance to register with
|
|
36
37
|
*/
|
|
37
38
|
register(app: express.Application, openApi?: unknown): void;
|
|
39
|
+
/**
|
|
40
|
+
* Called after the HTTP server is created but before it starts listening.
|
|
41
|
+
* Use this to attach services that need the raw HTTP server, such as
|
|
42
|
+
* Socket.io or other WebSocket libraries.
|
|
43
|
+
*
|
|
44
|
+
* Only called when using `TerrenoApp.start()` (not `build()`).
|
|
45
|
+
*
|
|
46
|
+
* @param server - The Node.js HTTP server instance
|
|
47
|
+
*/
|
|
48
|
+
onServerCreated?(server: http.Server): void;
|
|
38
49
|
}
|
package/dist/tests/bunSetup.js
CHANGED
|
@@ -64,6 +64,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
64
64
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
65
65
|
};
|
|
66
66
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
67
|
+
// biome-ignore-all lint/suspicious/noExplicitAny: test mock typing
|
|
67
68
|
var bun_test_1 = require("bun:test");
|
|
68
69
|
var node_stream_1 = require("node:stream");
|
|
69
70
|
var mongoose_1 = __importDefault(require("mongoose"));
|
package/dist/tests.js
CHANGED
|
@@ -156,7 +156,7 @@ var foodSchema = new mongoose_1.Schema({
|
|
|
156
156
|
type: mongoose_1.Schema.Types.ObjectId,
|
|
157
157
|
},
|
|
158
158
|
],
|
|
159
|
-
// noExplicitAny: DateOnly is a custom SchemaType not recognized by Mongoose's built-in type definitions
|
|
159
|
+
// biome-ignore lint/suspicious/noExplicitAny: DateOnly is a custom SchemaType not recognized by Mongoose's built-in type definitions
|
|
160
160
|
expiration: { description: "Expiration date of the food", type: plugins_1.DateOnly },
|
|
161
161
|
hidden: {
|
|
162
162
|
default: false,
|
package/dist/transformers.d.ts
CHANGED
|
@@ -17,9 +17,9 @@ export declare const AdminOwnerTransformer: <T>(options: {
|
|
|
17
17
|
adminWriteFields?: string[];
|
|
18
18
|
}) => TerrenoTransformer<T>;
|
|
19
19
|
export declare const transform: <T>(options: ModelRouterOptions<T>, data: Partial<T> | Partial<T>[], method: "create" | "update", user?: User) => Partial<T> | (Partial<T> | undefined)[] | undefined;
|
|
20
|
-
export declare const serialize: <T>(req: express.Request, options: ModelRouterOptions<T>, data: (Document & T) | (Document & T)[]) => Partial<T> | (Partial<T> | undefined)[] | undefined;
|
|
20
|
+
export declare const serialize: <T>(req: express.Request, options: ModelRouterOptions<T>, data: (Document<unknown, unknown, unknown> & T) | (Document<unknown, unknown, unknown> & T)[]) => Partial<T> | (Partial<T> | undefined)[] | undefined;
|
|
21
21
|
/**
|
|
22
22
|
* Default response handler for modelRouter. Calls toObject on each doc and returns the result,
|
|
23
23
|
* using transformers.serializer if provided.
|
|
24
24
|
*/
|
|
25
|
-
export declare const defaultResponseHandler: <T>(doc: (Document & T) | (Document & T)[] | null, method: "list" | "create" | "read" | "update", request: express.Request, options: ModelRouterOptions<T>) => Promise<Partial<T> | (Partial<T> | undefined)[] | null | undefined>;
|
|
25
|
+
export declare const defaultResponseHandler: <T>(doc: (Document<unknown, unknown, unknown> & T) | (Document<unknown, unknown, unknown> & T)[] | null, method: "list" | "create" | "read" | "update", request: express.Request, options: ModelRouterOptions<T>) => Promise<Partial<T> | (Partial<T> | undefined)[] | null | undefined>;
|
package/dist/transformers.js
CHANGED
|
@@ -79,7 +79,8 @@ var getUserType = function (user, obj) {
|
|
|
79
79
|
if (user === null || user === void 0 ? void 0 : user.admin) {
|
|
80
80
|
return "admin";
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
var withOwner = obj;
|
|
83
|
+
if (withOwner && user && String(withOwner === null || withOwner === void 0 ? void 0 : withOwner.ownerId) === String(user === null || user === void 0 ? void 0 : user.id)) {
|
|
83
84
|
return "owner";
|
|
84
85
|
}
|
|
85
86
|
if (user === null || user === void 0 ? void 0 : user.id) {
|
|
@@ -94,8 +95,9 @@ var AdminOwnerTransformer = function (options) {
|
|
|
94
95
|
try {
|
|
95
96
|
for (var fields_1 = __values(fields), fields_1_1 = fields_1.next(); !fields_1_1.done; fields_1_1 = fields_1.next()) {
|
|
96
97
|
var field = fields_1_1.value;
|
|
97
|
-
|
|
98
|
-
|
|
98
|
+
var key = field;
|
|
99
|
+
if (obj[key] !== undefined) {
|
|
100
|
+
newData[key] = obj[key];
|
|
99
101
|
}
|
|
100
102
|
}
|
|
101
103
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
2
13
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
14
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
15
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -55,10 +66,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
55
66
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
56
67
|
};
|
|
57
68
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
69
|
+
// biome-ignore-all lint/suspicious/noExplicitAny: test mock typing
|
|
58
70
|
var bun_test_1 = require("bun:test");
|
|
59
71
|
var supertest_1 = __importDefault(require("supertest"));
|
|
60
72
|
var api_1 = require("./api");
|
|
61
73
|
var auth_1 = require("./auth");
|
|
74
|
+
var errors_1 = require("./errors");
|
|
62
75
|
var permissions_1 = require("./permissions");
|
|
63
76
|
var tests_1 = require("./tests");
|
|
64
77
|
var transformers_1 = require("./transformers");
|
|
@@ -368,3 +381,80 @@ var transformers_1 = require("./transformers");
|
|
|
368
381
|
});
|
|
369
382
|
}); });
|
|
370
383
|
});
|
|
384
|
+
(0, bun_test_1.describe)("transform (deprecated helper)", function () {
|
|
385
|
+
var mockTransformFn = function (obj, _method) { return (__assign(__assign({}, obj), { name: "".concat(obj.name, "_transformed") })); };
|
|
386
|
+
(0, bun_test_1.it)("returns data unchanged when no transformer is configured", function () {
|
|
387
|
+
var options = { permissions: {} };
|
|
388
|
+
var data = { name: "Apple" };
|
|
389
|
+
(0, bun_test_1.expect)((0, transformers_1.transform)(options, data, "create")).toEqual(data);
|
|
390
|
+
});
|
|
391
|
+
(0, bun_test_1.it)("transforms a single object", function () {
|
|
392
|
+
var options = {
|
|
393
|
+
transformer: { transform: mockTransformFn },
|
|
394
|
+
};
|
|
395
|
+
var result = (0, transformers_1.transform)(options, { name: "Apple" }, "create");
|
|
396
|
+
(0, bun_test_1.expect)(result.name).toBe("Apple_transformed");
|
|
397
|
+
});
|
|
398
|
+
(0, bun_test_1.it)("transforms an array of objects", function () {
|
|
399
|
+
var options = {
|
|
400
|
+
transformer: { transform: mockTransformFn },
|
|
401
|
+
};
|
|
402
|
+
var data = [{ name: "Apple" }, { name: "Banana" }];
|
|
403
|
+
var result = (0, transformers_1.transform)(options, data, "update");
|
|
404
|
+
(0, bun_test_1.expect)(result).toHaveLength(2);
|
|
405
|
+
(0, bun_test_1.expect)(result[0].name).toBe("Apple_transformed");
|
|
406
|
+
(0, bun_test_1.expect)(result[1].name).toBe("Banana_transformed");
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
(0, bun_test_1.describe)("defaultResponseHandler", function () {
|
|
410
|
+
(0, bun_test_1.it)("returns null when doc is null", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
411
|
+
var options, req, result;
|
|
412
|
+
return __generator(this, function (_a) {
|
|
413
|
+
switch (_a.label) {
|
|
414
|
+
case 0:
|
|
415
|
+
options = { permissions: {} };
|
|
416
|
+
req = {};
|
|
417
|
+
return [4 /*yield*/, (0, transformers_1.defaultResponseHandler)(null, "read", req, options)];
|
|
418
|
+
case 1:
|
|
419
|
+
result = _a.sent();
|
|
420
|
+
(0, bun_test_1.expect)(result).toBeNull();
|
|
421
|
+
return [2 /*return*/];
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
}); });
|
|
425
|
+
(0, bun_test_1.it)("throws APIError when serialize throws", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
426
|
+
var options, fakeDoc, req, err_1;
|
|
427
|
+
return __generator(this, function (_a) {
|
|
428
|
+
switch (_a.label) {
|
|
429
|
+
case 0:
|
|
430
|
+
options = {
|
|
431
|
+
transformer: {
|
|
432
|
+
serialize: function () {
|
|
433
|
+
throw new Error("serialize boom");
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
};
|
|
437
|
+
fakeDoc = {
|
|
438
|
+
_id: "abc",
|
|
439
|
+
toObject: function () { return ({ name: "Apple" }); },
|
|
440
|
+
};
|
|
441
|
+
req = {};
|
|
442
|
+
_a.label = 1;
|
|
443
|
+
case 1:
|
|
444
|
+
_a.trys.push([1, 3, , 4]);
|
|
445
|
+
return [4 /*yield*/, (0, transformers_1.defaultResponseHandler)(fakeDoc, "read", req, options)];
|
|
446
|
+
case 2:
|
|
447
|
+
_a.sent();
|
|
448
|
+
(0, bun_test_1.expect)(true).toBe(false);
|
|
449
|
+
return [3 /*break*/, 4];
|
|
450
|
+
case 3:
|
|
451
|
+
err_1 = _a.sent();
|
|
452
|
+
(0, bun_test_1.expect)(err_1).toBeInstanceOf(errors_1.APIError);
|
|
453
|
+
(0, bun_test_1.expect)(err_1.status).toBe(400);
|
|
454
|
+
(0, bun_test_1.expect)(err_1.title).toContain("Error serializing read response");
|
|
455
|
+
return [3 /*break*/, 4];
|
|
456
|
+
case 4: return [2 /*return*/];
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
}); });
|
|
460
|
+
});
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type mongoose from "mongoose";
|
|
2
2
|
import type { FindExactlyOnePlugin, FindOneOrNonePlugin } from "../plugins";
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
export
|
|
3
|
+
export interface ConsentResponseMethods {
|
|
4
|
+
}
|
|
5
|
+
export interface ConsentResponseStatics extends FindExactlyOnePlugin<ConsentResponseDocument>, FindOneOrNonePlugin<ConsentResponseDocument> {
|
|
6
|
+
}
|
|
7
|
+
export interface ConsentResponseModel extends mongoose.Model<ConsentResponseDocument, object, ConsentResponseMethods>, ConsentResponseStatics {
|
|
8
|
+
}
|
|
6
9
|
export interface ConsentResponseDocument extends mongoose.Document {
|
|
7
10
|
_id: mongoose.Types.ObjectId;
|
|
8
11
|
userId: mongoose.Types.ObjectId;
|
|
@@ -3,6 +3,8 @@ import type { TerrenoPlugin } from "./terrenoPlugin";
|
|
|
3
3
|
export type VersionCheckStatus = "ok" | "warning" | "required";
|
|
4
4
|
export interface VersionCheckResponse {
|
|
5
5
|
message?: string;
|
|
6
|
+
/** How often the client should poll for updates, in milliseconds. */
|
|
7
|
+
pollingIntervalMs?: number;
|
|
6
8
|
requiredVersion?: number;
|
|
7
9
|
status: VersionCheckStatus;
|
|
8
10
|
updateUrl?: string;
|
|
@@ -41,6 +41,7 @@ var api_1 = require("./api");
|
|
|
41
41
|
var versionConfig_1 = require("./models/versionConfig");
|
|
42
42
|
var DEFAULT_WARNING_MESSAGE = "A new version is available. Please update for the best experience.";
|
|
43
43
|
var DEFAULT_REQUIRED_MESSAGE = "This version is no longer supported. Please update to continue.";
|
|
44
|
+
var DEFAULT_POLLING_INTERVAL_MINUTES = 1440;
|
|
44
45
|
/**
|
|
45
46
|
* TerrenoPlugin that adds a public GET /version-check endpoint for upgrade enforcement.
|
|
46
47
|
* Compares client build number against admin-configured thresholds per platform.
|
|
@@ -52,26 +53,30 @@ var VersionCheckPlugin = /** @class */ (function () {
|
|
|
52
53
|
var _this = this;
|
|
53
54
|
app.get("/version-check", (0, api_1.asyncHandler)(function (req, res) { return __awaiter(_this, void 0, void 0, function () {
|
|
54
55
|
var versionParam, platform, version, platformNormalized, config, requiredVersion, warningVersion, response;
|
|
55
|
-
var _a, _b, _c, _d, _e, _f;
|
|
56
|
-
return __generator(this, function (
|
|
57
|
-
switch (
|
|
56
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
57
|
+
return __generator(this, function (_h) {
|
|
58
|
+
switch (_h.label) {
|
|
58
59
|
case 0:
|
|
59
60
|
versionParam = req.query.version;
|
|
60
61
|
platform = req.query.platform;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
if (typeof versionParam === "string") {
|
|
63
|
+
version = parseInt(versionParam, 10);
|
|
64
|
+
}
|
|
65
|
+
else if (typeof versionParam === "number") {
|
|
66
|
+
version = versionParam;
|
|
67
|
+
}
|
|
66
68
|
if (version === undefined || Number.isNaN(version)) {
|
|
67
69
|
return [2 /*return*/, res.json({ status: "ok" })];
|
|
68
70
|
}
|
|
69
71
|
platformNormalized = platform === "web" || platform === "mobile" ? platform : "web";
|
|
70
72
|
return [4 /*yield*/, versionConfig_1.VersionConfig.findOneOrNone({ _singleton: "config" })];
|
|
71
73
|
case 1:
|
|
72
|
-
config =
|
|
74
|
+
config = _h.sent();
|
|
73
75
|
if (!config) {
|
|
74
|
-
return [2 /*return*/, res.json({
|
|
76
|
+
return [2 /*return*/, res.json({
|
|
77
|
+
pollingIntervalMs: DEFAULT_POLLING_INTERVAL_MINUTES * 60 * 1000,
|
|
78
|
+
status: "ok",
|
|
79
|
+
})];
|
|
75
80
|
}
|
|
76
81
|
requiredVersion = platformNormalized === "web"
|
|
77
82
|
? ((_a = config.webRequiredVersion) !== null && _a !== void 0 ? _a : 0)
|
|
@@ -80,6 +85,7 @@ var VersionCheckPlugin = /** @class */ (function () {
|
|
|
80
85
|
? ((_c = config.webWarningVersion) !== null && _c !== void 0 ? _c : 0)
|
|
81
86
|
: ((_d = config.mobileWarningVersion) !== null && _d !== void 0 ? _d : 0);
|
|
82
87
|
response = {
|
|
88
|
+
pollingIntervalMs: ((_e = config.pollingIntervalMinutes) !== null && _e !== void 0 ? _e : DEFAULT_POLLING_INTERVAL_MINUTES) * 60 * 1000,
|
|
83
89
|
requiredVersion: requiredVersion > 0 ? requiredVersion : undefined,
|
|
84
90
|
status: "ok",
|
|
85
91
|
updateUrl: config.updateUrl || undefined,
|
|
@@ -87,11 +93,11 @@ var VersionCheckPlugin = /** @class */ (function () {
|
|
|
87
93
|
};
|
|
88
94
|
if (requiredVersion > 0 && version < requiredVersion) {
|
|
89
95
|
response.status = "required";
|
|
90
|
-
response.message = (
|
|
96
|
+
response.message = (_f = config.requiredMessage) !== null && _f !== void 0 ? _f : DEFAULT_REQUIRED_MESSAGE;
|
|
91
97
|
}
|
|
92
98
|
else if (warningVersion > 0 && version < warningVersion) {
|
|
93
99
|
response.status = "warning";
|
|
94
|
-
response.message = (
|
|
100
|
+
response.message = (_g = config.warningMessage) !== null && _g !== void 0 ? _g : DEFAULT_WARNING_MESSAGE;
|
|
95
101
|
}
|
|
96
102
|
return [2 /*return*/, res.json(response)];
|
|
97
103
|
}
|
package/package.json
CHANGED
|
@@ -37,7 +37,9 @@
|
|
|
37
37
|
"passport-local": "^1.0.0",
|
|
38
38
|
"passport-local-mongoose": "^9.0.1",
|
|
39
39
|
"qs": "^6.14.1",
|
|
40
|
+
"@thream/socketio-jwt": "^3.1.4",
|
|
40
41
|
"scmp": "^2.1.0",
|
|
42
|
+
"socket.io": "^4.8.1",
|
|
41
43
|
"winston": "^3.18.3"
|
|
42
44
|
},
|
|
43
45
|
"description": "Styled after the Django & Django REST Framework, a batteries-include framework for building REST APIs with Node/Express/Mongoose.",
|
|
@@ -81,7 +83,7 @@
|
|
|
81
83
|
"access": "public"
|
|
82
84
|
},
|
|
83
85
|
"peerDependencies": {
|
|
84
|
-
"mongoose": "^8.0.0"
|
|
86
|
+
"mongoose": "^8.0.0 || ^9.0.0"
|
|
85
87
|
},
|
|
86
88
|
"repository": {
|
|
87
89
|
"type": "git",
|
|
@@ -104,5 +106,5 @@
|
|
|
104
106
|
"updateSnapshot": "bun test --update-snapshots"
|
|
105
107
|
},
|
|
106
108
|
"types": "dist/index.d.ts",
|
|
107
|
-
"version": "0.
|
|
109
|
+
"version": "0.14.0"
|
|
108
110
|
}
|