@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
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
45
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
46
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
47
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
48
|
+
function step(op) {
|
|
49
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
50
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
51
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
52
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
53
|
+
switch (op[0]) {
|
|
54
|
+
case 0: case 1: t = op; break;
|
|
55
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
56
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
57
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
58
|
+
default:
|
|
59
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
60
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
61
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
62
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
63
|
+
if (t[2]) _.ops.pop();
|
|
64
|
+
_.trys.pop(); continue;
|
|
65
|
+
}
|
|
66
|
+
op = body.call(thisArg, _);
|
|
67
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
68
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
72
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
73
|
+
};
|
|
74
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
75
|
+
var bun_test_1 = require("bun:test");
|
|
76
|
+
var node_stream_1 = require("node:stream");
|
|
77
|
+
var Sentry = __importStar(require("@sentry/bun"));
|
|
78
|
+
var express_1 = __importDefault(require("express"));
|
|
79
|
+
var supertest_1 = __importDefault(require("supertest"));
|
|
80
|
+
var winston_1 = __importDefault(require("winston"));
|
|
81
|
+
var logger_1 = require("./logger");
|
|
82
|
+
var requestContext_1 = require("./requestContext");
|
|
83
|
+
(0, bun_test_1.describe)("request context job propagation", function () {
|
|
84
|
+
(0, bun_test_1.beforeEach)(function () {
|
|
85
|
+
var scope = Sentry.getCurrentScope();
|
|
86
|
+
scope.setContext.mockClear();
|
|
87
|
+
scope.setTag.mockClear();
|
|
88
|
+
scope.setUser.mockClear();
|
|
89
|
+
});
|
|
90
|
+
(0, bun_test_1.afterEach)(function () {
|
|
91
|
+
(0, logger_1.setupLogging)({ disableFileLogging: true });
|
|
92
|
+
});
|
|
93
|
+
(0, bun_test_1.it)("serializes the current context for downstream jobs", function () {
|
|
94
|
+
(0, requestContext_1.runWithRequestContext)({
|
|
95
|
+
jobId: "job-1",
|
|
96
|
+
requestId: "request-1",
|
|
97
|
+
sessionId: "session-1",
|
|
98
|
+
spanId: "span-1",
|
|
99
|
+
traceId: "trace-1",
|
|
100
|
+
traceSampled: false,
|
|
101
|
+
userId: "user-1",
|
|
102
|
+
}, function () {
|
|
103
|
+
(0, bun_test_1.expect)((0, requestContext_1.getCurrentRequestContextAttributes)()).toEqual({
|
|
104
|
+
"x-job-id": "job-1",
|
|
105
|
+
"x-request-id": "request-1",
|
|
106
|
+
"x-session-id": "session-1",
|
|
107
|
+
"x-span-id": "span-1",
|
|
108
|
+
"x-trace-id": "trace-1",
|
|
109
|
+
"x-trace-sampled": "false",
|
|
110
|
+
"x-user-id": "user-1",
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
(0, bun_test_1.it)("allows downstream jobs to replace only the job id", function () {
|
|
115
|
+
(0, requestContext_1.runWithRequestContext)({ jobId: "job-parent", requestId: "request-1", sessionId: "session-1" }, function () {
|
|
116
|
+
(0, bun_test_1.expect)((0, requestContext_1.getCurrentRequestContextAttributes)({ jobId: "job-child" })).toEqual({
|
|
117
|
+
"x-job-id": "job-child",
|
|
118
|
+
"x-request-id": "request-1",
|
|
119
|
+
"x-session-id": "session-1",
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
(0, bun_test_1.it)("restores worker context from message attributes", function () {
|
|
124
|
+
var scope = Sentry.getCurrentScope();
|
|
125
|
+
var setContextMock = scope.setContext;
|
|
126
|
+
var setTagMock = scope.setTag;
|
|
127
|
+
var setUserMock = scope.setUser;
|
|
128
|
+
(0, requestContext_1.runWithRequestContextAttributes)({
|
|
129
|
+
traceparent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
|
|
130
|
+
"x-job-id": "job-worker-1",
|
|
131
|
+
"x-request-id": "request-1",
|
|
132
|
+
"x-session-id": "session-1",
|
|
133
|
+
"x-user-id": "user-1",
|
|
134
|
+
}, function () {
|
|
135
|
+
(0, bun_test_1.expect)((0, requestContext_1.getCurrentRequestContext)()).toEqual({
|
|
136
|
+
jobId: "job-worker-1",
|
|
137
|
+
requestId: "request-1",
|
|
138
|
+
sessionId: "session-1",
|
|
139
|
+
spanId: "00f067aa0ba902b7",
|
|
140
|
+
traceId: "4bf92f3577b34da6a3ce929d0e0e4736",
|
|
141
|
+
traceSampled: true,
|
|
142
|
+
userId: "user-1",
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
(0, bun_test_1.expect)(setTagMock).toHaveBeenCalledWith("request_id", "request-1");
|
|
146
|
+
(0, bun_test_1.expect)(setTagMock).toHaveBeenCalledWith("session_id", "session-1");
|
|
147
|
+
(0, bun_test_1.expect)(setTagMock).toHaveBeenCalledWith("job_id", "job-worker-1");
|
|
148
|
+
(0, bun_test_1.expect)(setTagMock).toHaveBeenCalledWith("user_id", "user-1");
|
|
149
|
+
(0, bun_test_1.expect)(setTagMock).toHaveBeenCalledWith("trace_id", "4bf92f3577b34da6a3ce929d0e0e4736");
|
|
150
|
+
(0, bun_test_1.expect)(setUserMock).toHaveBeenCalledWith({ id: "user-1" });
|
|
151
|
+
(0, bun_test_1.expect)(setContextMock).toHaveBeenCalledWith("request_context", {
|
|
152
|
+
jobId: "job-worker-1",
|
|
153
|
+
requestId: "request-1",
|
|
154
|
+
sessionId: "session-1",
|
|
155
|
+
spanId: "00f067aa0ba902b7",
|
|
156
|
+
traceId: "4bf92f3577b34da6a3ce929d0e0e4736",
|
|
157
|
+
traceSampled: true,
|
|
158
|
+
userId: "user-1",
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
(0, bun_test_1.it)("sends context updates to Sentry for auth session changes", function () {
|
|
162
|
+
var scope = Sentry.getCurrentScope();
|
|
163
|
+
var setTagMock = scope.setTag;
|
|
164
|
+
var setUserMock = scope.setUser;
|
|
165
|
+
(0, requestContext_1.runWithRequestContext)({ requestId: "request-auth-1" }, function () {
|
|
166
|
+
setTagMock.mockClear();
|
|
167
|
+
setUserMock.mockClear();
|
|
168
|
+
(0, requestContext_1.setRequestContext)({ sessionId: "session-auth-1", userId: "user-auth-1" });
|
|
169
|
+
});
|
|
170
|
+
(0, bun_test_1.expect)(setTagMock).toHaveBeenCalledWith("session_id", "session-auth-1");
|
|
171
|
+
(0, bun_test_1.expect)(setTagMock).toHaveBeenCalledWith("user_id", "user-auth-1");
|
|
172
|
+
(0, bun_test_1.expect)(setUserMock).toHaveBeenCalledWith({ id: "user-auth-1" });
|
|
173
|
+
});
|
|
174
|
+
(0, bun_test_1.it)("uses trace id as request id when attributes do not include request id", function () {
|
|
175
|
+
var context = (0, requestContext_1.getRequestContextFromAttributes)({
|
|
176
|
+
traceparent: "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00",
|
|
177
|
+
"x-job-id": "job-worker-1",
|
|
178
|
+
});
|
|
179
|
+
(0, bun_test_1.expect)(context).toEqual({
|
|
180
|
+
jobId: "job-worker-1",
|
|
181
|
+
requestId: "4bf92f3577b34da6a3ce929d0e0e4736",
|
|
182
|
+
sessionId: undefined,
|
|
183
|
+
spanId: "00f067aa0ba902b7",
|
|
184
|
+
traceId: "4bf92f3577b34da6a3ce929d0e0e4736",
|
|
185
|
+
traceSampled: false,
|
|
186
|
+
userId: undefined,
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
(0, bun_test_1.it)("accepts job id from HTTP headers", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
190
|
+
var app, res;
|
|
191
|
+
return __generator(this, function (_a) {
|
|
192
|
+
switch (_a.label) {
|
|
193
|
+
case 0:
|
|
194
|
+
app = (0, express_1.default)();
|
|
195
|
+
app.use(requestContext_1.requestContextMiddleware);
|
|
196
|
+
app.get("/job", function (req, res) {
|
|
197
|
+
res.json({ context: (0, requestContext_1.getCurrentLogContext)(), jobId: req.jobId });
|
|
198
|
+
});
|
|
199
|
+
return [4 /*yield*/, (0, supertest_1.default)(app)
|
|
200
|
+
.get("/job")
|
|
201
|
+
.set("X-Job-ID", "job-http-1")
|
|
202
|
+
.set("X-Request-ID", "request-http-1")
|
|
203
|
+
.expect(200)];
|
|
204
|
+
case 1:
|
|
205
|
+
res = _a.sent();
|
|
206
|
+
(0, bun_test_1.expect)(res.headers["x-job-id"]).toBe("job-http-1");
|
|
207
|
+
(0, bun_test_1.expect)(res.body).toEqual({
|
|
208
|
+
context: { jobId: "job-http-1", requestId: "request-http-1" },
|
|
209
|
+
jobId: "job-http-1",
|
|
210
|
+
});
|
|
211
|
+
return [2 /*return*/];
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}); });
|
|
215
|
+
(0, bun_test_1.it)("adds job id to logger context", function () {
|
|
216
|
+
var output = "";
|
|
217
|
+
var stream = new node_stream_1.Writable({
|
|
218
|
+
write: function (chunk, _encoding, callback) {
|
|
219
|
+
output += chunk.toString();
|
|
220
|
+
callback();
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
(0, logger_1.setupLogging)({
|
|
224
|
+
disableConsoleLogging: true,
|
|
225
|
+
disableFileLogging: true,
|
|
226
|
+
transports: [
|
|
227
|
+
new winston_1.default.transports.Stream({
|
|
228
|
+
format: winston_1.default.format.printf(function (info) {
|
|
229
|
+
return "".concat(info.level, ": ").concat(info.message, " requestId=").concat(info.requestId, " jobId=").concat(info.jobId);
|
|
230
|
+
}),
|
|
231
|
+
stream: stream,
|
|
232
|
+
}),
|
|
233
|
+
],
|
|
234
|
+
});
|
|
235
|
+
(0, requestContext_1.runWithRequestContext)({ jobId: "job-log-1", requestId: "request-log-1" }, function () {
|
|
236
|
+
logger_1.logger.info("worker handled job");
|
|
237
|
+
});
|
|
238
|
+
(0, bun_test_1.expect)(output).toContain("requestId=request-log-1");
|
|
239
|
+
(0, bun_test_1.expect)(output).toContain("jobId=job-log-1");
|
|
240
|
+
});
|
|
241
|
+
});
|
package/dist/terrenoApp.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { type ConfigurationAppOptions } from "./configurationApp";
|
|
|
6
6
|
import { type AuthOptions } from "./expressServer";
|
|
7
7
|
import { type GitHubAuthOptions } from "./githubAuth";
|
|
8
8
|
import { type LoggingOptions } from "./logger";
|
|
9
|
+
import type { RealtimeAppOptions } from "./realtime/types";
|
|
9
10
|
import type { TerrenoPlugin } from "./terrenoPlugin";
|
|
10
11
|
type CorsOrigin = string | boolean | RegExp | Array<boolean | string | RegExp> | ((requestOrigin: string | undefined, callback: (err: Error | null, origin?: boolean | string | RegExp | Array<boolean | string | RegExp>) => void) => void);
|
|
11
12
|
/**
|
|
@@ -30,6 +31,13 @@ export interface TerrenoAppOptions {
|
|
|
30
31
|
arrayLimit?: number;
|
|
31
32
|
/** Whether to log all incoming requests (default: true) */
|
|
32
33
|
logRequests?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Real-time sync configuration. When provided, Socket.io and MongoDB change streams
|
|
36
|
+
* are set up automatically — no need to register RealtimeApp as a separate plugin.
|
|
37
|
+
*
|
|
38
|
+
* Set to `true` for defaults, or pass a RealtimeAppOptions object for full control.
|
|
39
|
+
*/
|
|
40
|
+
realtime?: boolean | RealtimeAppOptions;
|
|
33
41
|
}
|
|
34
42
|
/**
|
|
35
43
|
* Fluent API for building Express applications with Terreno framework.
|
package/dist/terrenoApp.js
CHANGED
|
@@ -59,6 +59,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
59
59
|
};
|
|
60
60
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
61
61
|
exports.TerrenoApp = void 0;
|
|
62
|
+
var node_http_1 = require("node:http");
|
|
62
63
|
var Sentry = __importStar(require("@sentry/bun"));
|
|
63
64
|
var cors_1 = __importDefault(require("cors"));
|
|
64
65
|
var express_1 = __importDefault(require("express"));
|
|
@@ -71,6 +72,8 @@ var githubAuth_1 = require("./githubAuth");
|
|
|
71
72
|
var logger_1 = require("./logger");
|
|
72
73
|
var openApiCompat_1 = require("./openApiCompat");
|
|
73
74
|
var openApiEtag_1 = require("./openApiEtag");
|
|
75
|
+
var realtimeApp_1 = require("./realtime/realtimeApp");
|
|
76
|
+
var requestContext_1 = require("./requestContext");
|
|
74
77
|
var index_1 = __importDefault(require("./vendor/wesleytodd-openapi/index"));
|
|
75
78
|
/**
|
|
76
79
|
* Fluent API for building Express applications with Terreno framework.
|
|
@@ -211,7 +214,9 @@ var TerrenoApp = /** @class */ (function () {
|
|
|
211
214
|
* .start();
|
|
212
215
|
* ```
|
|
213
216
|
*/
|
|
214
|
-
TerrenoApp.prototype.configure = function (
|
|
217
|
+
TerrenoApp.prototype.configure = function (
|
|
218
|
+
// biome-ignore lint/suspicious/noExplicitAny: Model<any> required for invariance — consumers pass arbitrary configuration models
|
|
219
|
+
model, options) {
|
|
215
220
|
this.configurationApp = new configurationApp_1.ConfigurationApp(__assign({ model: model }, options));
|
|
216
221
|
return this;
|
|
217
222
|
};
|
|
@@ -247,6 +252,7 @@ var TerrenoApp = /** @class */ (function () {
|
|
|
247
252
|
// Record mount paths on layers for Express 5 → OpenAPI compat
|
|
248
253
|
(0, openApiCompat_1.patchAppUse)(app);
|
|
249
254
|
app.set("query parser", function (str) { var _a; return qs_1.default.parse(str, { arrayLimit: (_a = options.arrayLimit) !== null && _a !== void 0 ? _a : 200 }); });
|
|
255
|
+
app.use(requestContext_1.requestContextMiddleware);
|
|
250
256
|
app.use((0, cors_1.default)({ credentials: true, origin: (_c = options.corsOrigin) !== null && _c !== void 0 ? _c : "*" }));
|
|
251
257
|
try {
|
|
252
258
|
// Apply custom middleware before JSON parsing
|
|
@@ -273,6 +279,10 @@ var TerrenoApp = /** @class */ (function () {
|
|
|
273
279
|
// Auth routes (login/signup/refresh_token) before JWT middleware
|
|
274
280
|
(0, auth_1.addAuthRoutes)(app, options.userModel, options.authOptions);
|
|
275
281
|
(0, auth_1.setupAuth)(app, options.userModel);
|
|
282
|
+
app.use(function (req, res, next) {
|
|
283
|
+
(0, requestContext_1.updateRequestContextFromRequest)(req, res);
|
|
284
|
+
next();
|
|
285
|
+
});
|
|
276
286
|
if (options.logRequests !== false) {
|
|
277
287
|
app.use(expressServer_1.logRequests);
|
|
278
288
|
}
|
|
@@ -283,17 +293,21 @@ var TerrenoApp = /** @class */ (function () {
|
|
|
283
293
|
});
|
|
284
294
|
// Sentry scopes
|
|
285
295
|
app.use(function (req, _res, next) {
|
|
286
|
-
var _a;
|
|
296
|
+
var _a, _b;
|
|
297
|
+
var context = (0, requestContext_1.getCurrentRequestContext)();
|
|
287
298
|
var transactionId = req.header("X-Transaction-ID");
|
|
288
|
-
var sessionId = req.header("X-Session-ID");
|
|
299
|
+
var sessionId = (_a = context === null || context === void 0 ? void 0 : context.sessionId) !== null && _a !== void 0 ? _a : req.header("X-Session-ID");
|
|
300
|
+
if (context === null || context === void 0 ? void 0 : context.requestId) {
|
|
301
|
+
Sentry.getCurrentScope().setTag("request_id", context.requestId);
|
|
302
|
+
}
|
|
289
303
|
if (transactionId) {
|
|
290
304
|
Sentry.getCurrentScope().setTag("transaction_id", transactionId);
|
|
291
305
|
}
|
|
292
306
|
if (sessionId) {
|
|
293
307
|
Sentry.getCurrentScope().setTag("session_id", sessionId);
|
|
294
308
|
}
|
|
295
|
-
if ((
|
|
296
|
-
Sentry.getCurrentScope().setTag("user", req.user._id);
|
|
309
|
+
if ((_b = req.user) === null || _b === void 0 ? void 0 : _b._id) {
|
|
310
|
+
Sentry.getCurrentScope().setTag("user", String(req.user._id));
|
|
297
311
|
}
|
|
298
312
|
next();
|
|
299
313
|
});
|
|
@@ -348,12 +362,7 @@ var TerrenoApp = /** @class */ (function () {
|
|
|
348
362
|
// Error middleware
|
|
349
363
|
app.use(errors_1.apiUnauthorizedMiddleware);
|
|
350
364
|
app.use(errors_1.apiErrorMiddleware);
|
|
351
|
-
app.use(
|
|
352
|
-
logger_1.logger.error("Fallthrough error: ".concat(err).concat((err === null || err === void 0 ? void 0 : err.stack) ? "\n".concat(err.stack) : "", "}"));
|
|
353
|
-
Sentry.captureException(err);
|
|
354
|
-
res.statusCode = 500;
|
|
355
|
-
res.end("".concat(res.sentry, "\n"));
|
|
356
|
-
});
|
|
365
|
+
app.use(errors_1.apiFallthroughErrorMiddleware);
|
|
357
366
|
return app;
|
|
358
367
|
};
|
|
359
368
|
/**
|
|
@@ -377,16 +386,44 @@ var TerrenoApp = /** @class */ (function () {
|
|
|
377
386
|
* ```
|
|
378
387
|
*/
|
|
379
388
|
TerrenoApp.prototype.start = function () {
|
|
389
|
+
var e_3, _a;
|
|
390
|
+
var _this = this;
|
|
391
|
+
// If realtime option is set, auto-register the RealtimeApp plugin
|
|
392
|
+
if (this.options.realtime) {
|
|
393
|
+
var hasRealtimePlugin = this.registrations.some(function (r) { return !_this.isModelRouterRegistration(r) && r instanceof realtimeApp_1.RealtimeApp; });
|
|
394
|
+
if (!hasRealtimePlugin) {
|
|
395
|
+
var realtimeConfig = typeof this.options.realtime === "object" ? this.options.realtime : {};
|
|
396
|
+
this.register(new realtimeApp_1.RealtimeApp(realtimeConfig));
|
|
397
|
+
}
|
|
398
|
+
}
|
|
380
399
|
var app = this.build();
|
|
381
400
|
if (!this.options.skipListen) {
|
|
382
401
|
var port_1 = process.env.PORT || "9000";
|
|
383
402
|
try {
|
|
384
|
-
|
|
403
|
+
var server = (0, node_http_1.createServer)(app);
|
|
404
|
+
try {
|
|
405
|
+
// Notify plugins that need access to the HTTP server (e.g. WebSocket plugins)
|
|
406
|
+
for (var _b = __values(this.registrations), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
407
|
+
var reg = _c.value;
|
|
408
|
+
if (!this.isModelRouterRegistration(reg) && typeof reg.onServerCreated === "function") {
|
|
409
|
+
reg.onServerCreated(server);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
414
|
+
finally {
|
|
415
|
+
try {
|
|
416
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
417
|
+
}
|
|
418
|
+
finally { if (e_3) throw e_3.error; }
|
|
419
|
+
}
|
|
420
|
+
server.listen(port_1, function () {
|
|
385
421
|
logger_1.logger.info("Listening on port ".concat(port_1));
|
|
386
422
|
});
|
|
387
423
|
}
|
|
388
424
|
catch (error) {
|
|
389
|
-
|
|
425
|
+
var stack = error instanceof Error ? error.stack : String(error);
|
|
426
|
+
logger_1.logger.error("Error trying to start HTTP server: ".concat(error, "\n").concat(stack));
|
|
390
427
|
process.exit(1);
|
|
391
428
|
}
|
|
392
429
|
}
|