repro-nest 0.0.217 → 0.0.219
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/index.d.ts +0 -3
- package/dist/index.js +22 -13
- package/dist/integrations/sendgrid.d.ts +0 -1
- package/dist/integrations/sendgrid.js +8 -5
- package/docs/tracing.md +0 -1
- package/package.json +1 -1
- package/src/index.ts +69 -68
- package/src/integrations/sendgrid.ts +8 -9
- package/tmp/dev-test.js +1 -1
- package/tmp/integration-unawaited.js +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -197,7 +197,6 @@ export type ReproMiddlewareConfig = {
|
|
|
197
197
|
appId: string;
|
|
198
198
|
tenantId: string;
|
|
199
199
|
appSecret: string;
|
|
200
|
-
apiBase: string;
|
|
201
200
|
/** Configure header capture/masking. Defaults to capturing with sensitive headers masked. */
|
|
202
201
|
captureHeaders?: boolean | HeaderCaptureOptions;
|
|
203
202
|
/** Optional masking rules for request/response payloads and function traces. */
|
|
@@ -208,13 +207,11 @@ export declare function reproMongoosePlugin(cfg: {
|
|
|
208
207
|
appId: string;
|
|
209
208
|
tenantId: string;
|
|
210
209
|
appSecret: string;
|
|
211
|
-
apiBase: string;
|
|
212
210
|
}): (schema: Schema) => void;
|
|
213
211
|
export type SendgridPatchConfig = {
|
|
214
212
|
appId: string;
|
|
215
213
|
tenantId: string;
|
|
216
214
|
appSecret: string;
|
|
217
|
-
apiBase: string;
|
|
218
215
|
resolveContext?: () => {
|
|
219
216
|
sid?: string;
|
|
220
217
|
aid?: string;
|
package/dist/index.js
CHANGED
|
@@ -818,15 +818,18 @@ function resolveCollectionOrWarn(source, type) {
|
|
|
818
818
|
}
|
|
819
819
|
return name;
|
|
820
820
|
}
|
|
821
|
-
async function post(
|
|
821
|
+
async function post(cfg, sessionId, body) {
|
|
822
822
|
try {
|
|
823
|
+
const envBase = typeof process !== 'undefined' ? process?.env?.REPRO_API_BASE : undefined;
|
|
824
|
+
const legacyBase = cfg?.apiBase;
|
|
825
|
+
const apiBase = String(envBase || legacyBase || 'https://oozy-loreta-gully.ngrok-free.dev').replace(/\/+$/, '');
|
|
823
826
|
await fetch(`${apiBase}/v1/sessions/${sessionId}/backend`, {
|
|
824
827
|
method: 'POST',
|
|
825
828
|
headers: {
|
|
826
829
|
'Content-Type': 'application/json',
|
|
827
|
-
'X-App-Id': appId,
|
|
828
|
-
'X-App-Secret': appSecret,
|
|
829
|
-
'X-Tenant-Id': tenantId,
|
|
830
|
+
'X-App-Id': cfg.appId,
|
|
831
|
+
'X-App-Secret': cfg.appSecret,
|
|
832
|
+
'X-Tenant-Id': cfg.tenantId,
|
|
830
833
|
},
|
|
831
834
|
body: JSON.stringify(body),
|
|
832
835
|
});
|
|
@@ -1541,7 +1544,7 @@ function reproMiddleware(cfg) {
|
|
|
1541
1544
|
let flushPayload = null;
|
|
1542
1545
|
const activeSpans = new Set();
|
|
1543
1546
|
let anonymousSpanDepth = 0;
|
|
1544
|
-
const ACTIVE_SPAN_FORCE_FLUSH_MS =
|
|
1547
|
+
const ACTIVE_SPAN_FORCE_FLUSH_MS = 60000; // hard cutoff after finish to avoid endlessly running replies
|
|
1545
1548
|
const clearTimers = () => {
|
|
1546
1549
|
if (idleTimer) {
|
|
1547
1550
|
try {
|
|
@@ -1597,7 +1600,13 @@ function reproMiddleware(cfg) {
|
|
|
1597
1600
|
if (quietMs < TRACE_LINGER_AFTER_FINISH_MS && waitedFinish < ACTIVE_SPAN_FORCE_FLUSH_MS) {
|
|
1598
1601
|
const remainingQuiet = TRACE_LINGER_AFTER_FINISH_MS - quietMs;
|
|
1599
1602
|
const remainingGuard = ACTIVE_SPAN_FORCE_FLUSH_MS - waitedFinish;
|
|
1600
|
-
|
|
1603
|
+
if (hardStopTimer) {
|
|
1604
|
+
try {
|
|
1605
|
+
clearTimeout(hardStopTimer);
|
|
1606
|
+
}
|
|
1607
|
+
catch { }
|
|
1608
|
+
}
|
|
1609
|
+
hardStopTimer = setTimeout(() => doFlush(true), Math.max(10, Math.min(remainingQuiet, remainingGuard)));
|
|
1601
1610
|
return;
|
|
1602
1611
|
}
|
|
1603
1612
|
}
|
|
@@ -1800,7 +1809,7 @@ function reproMiddleware(cfg) {
|
|
|
1800
1809
|
if (requestQuery !== undefined)
|
|
1801
1810
|
requestPayload.query = requestQuery;
|
|
1802
1811
|
requestPayload.entryPoint = chosenEndpoint;
|
|
1803
|
-
post(cfg
|
|
1812
|
+
post(cfg, sid, {
|
|
1804
1813
|
entries: [{
|
|
1805
1814
|
actionId: aid,
|
|
1806
1815
|
request: requestPayload,
|
|
@@ -1815,7 +1824,7 @@ function reproMiddleware(cfg) {
|
|
|
1815
1824
|
traceStr = JSON.stringify(batch);
|
|
1816
1825
|
}
|
|
1817
1826
|
catch { }
|
|
1818
|
-
post(cfg
|
|
1827
|
+
post(cfg, sid, {
|
|
1819
1828
|
entries: [{
|
|
1820
1829
|
actionId: aid,
|
|
1821
1830
|
trace: traceStr,
|
|
@@ -1910,7 +1919,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1910
1919
|
const query = meta.wasNew
|
|
1911
1920
|
? { op: 'insertOne', doc: after }
|
|
1912
1921
|
: { filter: { _id: this._id }, update: buildMinimalUpdate(before, after), options: { upsert: false } };
|
|
1913
|
-
post(cfg
|
|
1922
|
+
post(cfg, getCtx().sid, {
|
|
1914
1923
|
entries: [{
|
|
1915
1924
|
actionId: getCtx().aid,
|
|
1916
1925
|
db: [attachSpanContext({
|
|
@@ -1952,7 +1961,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1952
1961
|
if (!shouldCaptureDbSpan(spanContext))
|
|
1953
1962
|
return;
|
|
1954
1963
|
const pk = after?._id ?? before?._id;
|
|
1955
|
-
post(cfg
|
|
1964
|
+
post(cfg, getCtx().sid, {
|
|
1956
1965
|
entries: [{
|
|
1957
1966
|
actionId: getCtx().aid,
|
|
1958
1967
|
db: [attachSpanContext({
|
|
@@ -1993,7 +2002,7 @@ function reproMongoosePlugin(cfg) {
|
|
|
1993
2002
|
const spanContext = this.__repro_spanContext || captureSpanContextFromTracer(this);
|
|
1994
2003
|
if (!shouldCaptureDbSpan(spanContext))
|
|
1995
2004
|
return;
|
|
1996
|
-
post(cfg
|
|
2005
|
+
post(cfg, getCtx().sid, {
|
|
1997
2006
|
entries: [{
|
|
1998
2007
|
actionId: getCtx().aid,
|
|
1999
2008
|
db: [attachSpanContext({
|
|
@@ -2316,7 +2325,7 @@ function emitDbQuery(cfg, sid, aid, payload) {
|
|
|
2316
2325
|
pk: null, before: null, after: null,
|
|
2317
2326
|
error: payload.error ?? undefined,
|
|
2318
2327
|
}, spanContext);
|
|
2319
|
-
post(cfg
|
|
2328
|
+
post(cfg, sid, {
|
|
2320
2329
|
entries: [{
|
|
2321
2330
|
actionId: aid ?? null,
|
|
2322
2331
|
db: [dbEntry],
|
|
@@ -2413,7 +2422,7 @@ function patchSendgridMail(cfg) {
|
|
|
2413
2422
|
if (!sid)
|
|
2414
2423
|
return;
|
|
2415
2424
|
const norm = normalizeSendgridMessage(rawMsg);
|
|
2416
|
-
post(cfg
|
|
2425
|
+
post(cfg, sid, {
|
|
2417
2426
|
entries: [{
|
|
2418
2427
|
actionId: aid ?? null,
|
|
2419
2428
|
email: {
|
|
@@ -7,15 +7,18 @@ const als = new async_hooks_1.AsyncLocalStorage();
|
|
|
7
7
|
const getCtx = () => als.getStore() || {};
|
|
8
8
|
exports.getCtx = getCtx;
|
|
9
9
|
// If you already export als/getCtx from repro-node, reuse that instead of re-declaring.
|
|
10
|
-
async function post(
|
|
10
|
+
async function post(cfg, sessionId, body) {
|
|
11
11
|
try {
|
|
12
|
+
const envBase = typeof process !== 'undefined' ? process?.env?.REPRO_API_BASE : undefined;
|
|
13
|
+
const legacyBase = cfg?.apiBase;
|
|
14
|
+
const apiBase = String(envBase || legacyBase || 'https://oozy-loreta-gully.ngrok-free.dev').replace(/\/+$/, '');
|
|
12
15
|
await fetch(`${apiBase}/v1/sessions/${sessionId}/backend`, {
|
|
13
16
|
method: 'POST',
|
|
14
17
|
headers: {
|
|
15
18
|
'Content-Type': 'application/json',
|
|
16
|
-
'X-App-Id': appId,
|
|
17
|
-
'X-App-Secret': appSecret,
|
|
18
|
-
'X-Tenant-Id': tenantId,
|
|
19
|
+
'X-App-Id': cfg.appId,
|
|
20
|
+
'X-App-Secret': cfg.appSecret,
|
|
21
|
+
'X-Tenant-Id': cfg.tenantId,
|
|
19
22
|
},
|
|
20
23
|
body: JSON.stringify(body),
|
|
21
24
|
});
|
|
@@ -104,7 +107,7 @@ function patchSendgridMail(cfg) {
|
|
|
104
107
|
},
|
|
105
108
|
t: Date.now(),
|
|
106
109
|
};
|
|
107
|
-
post(cfg
|
|
110
|
+
post(cfg, sid, { entries: [entry] });
|
|
108
111
|
}
|
|
109
112
|
function normalizeAddress(a) {
|
|
110
113
|
if (!a)
|
package/docs/tracing.md
CHANGED
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1101,21 +1101,21 @@ function resolveCollectionOrWarn(source: any, type: 'doc' | 'query'): string {
|
|
|
1101
1101
|
}
|
|
1102
1102
|
|
|
1103
1103
|
async function post(
|
|
1104
|
-
|
|
1105
|
-
tenantId: string,
|
|
1106
|
-
appId: string,
|
|
1107
|
-
appSecret: string,
|
|
1104
|
+
cfg: { tenantId: string; appId: string; appSecret: string; apiBase?: string },
|
|
1108
1105
|
sessionId: string,
|
|
1109
1106
|
body: any,
|
|
1110
1107
|
) {
|
|
1111
1108
|
try {
|
|
1109
|
+
const envBase = typeof process !== 'undefined' ? (process as any)?.env?.REPRO_API_BASE : undefined;
|
|
1110
|
+
const legacyBase = (cfg as any)?.apiBase;
|
|
1111
|
+
const apiBase = String(envBase || legacyBase || 'https://oozy-loreta-gully.ngrok-free.dev').replace(/\/+$/, '');
|
|
1112
1112
|
await fetch(`${apiBase}/v1/sessions/${sessionId}/backend`, {
|
|
1113
1113
|
method: 'POST',
|
|
1114
1114
|
headers: {
|
|
1115
1115
|
'Content-Type': 'application/json',
|
|
1116
|
-
'X-App-Id': appId,
|
|
1117
|
-
'X-App-Secret': appSecret,
|
|
1118
|
-
'X-Tenant-Id': tenantId,
|
|
1116
|
+
'X-App-Id': cfg.appId,
|
|
1117
|
+
'X-App-Secret': cfg.appSecret,
|
|
1118
|
+
'X-Tenant-Id': cfg.tenantId,
|
|
1119
1119
|
},
|
|
1120
1120
|
body: JSON.stringify(body),
|
|
1121
1121
|
});
|
|
@@ -1764,7 +1764,6 @@ export type ReproMiddlewareConfig = {
|
|
|
1764
1764
|
appId: string;
|
|
1765
1765
|
tenantId: string;
|
|
1766
1766
|
appSecret: string;
|
|
1767
|
-
apiBase: string;
|
|
1768
1767
|
/** Configure header capture/masking. Defaults to capturing with sensitive headers masked. */
|
|
1769
1768
|
captureHeaders?: boolean | HeaderCaptureOptions;
|
|
1770
1769
|
/** Optional masking rules for request/response payloads and function traces. */
|
|
@@ -1820,7 +1819,7 @@ export function reproMiddleware(cfg: ReproMiddlewareConfig) {
|
|
|
1820
1819
|
return fn();
|
|
1821
1820
|
};
|
|
1822
1821
|
|
|
1823
|
-
|
|
1822
|
+
runInTrace(() => als.run({ sid, aid, clockSkewMs, excludedSpanIds: new Set<string>() }, () => {
|
|
1824
1823
|
const events: TraceEventRecord[] = [];
|
|
1825
1824
|
let endpointTrace: EndpointTraceInfo | null = null;
|
|
1826
1825
|
let preferredAppTrace: EndpointTraceInfo | null = null;
|
|
@@ -1831,12 +1830,12 @@ export function reproMiddleware(cfg: ReproMiddlewareConfig) {
|
|
|
1831
1830
|
let finishedAt: number | null = null;
|
|
1832
1831
|
let lastEventAt: number = Date.now();
|
|
1833
1832
|
let idleTimer: NodeJS.Timeout | null = null;
|
|
1834
|
-
|
|
1833
|
+
let hardStopTimer: NodeJS.Timeout | null = null;
|
|
1835
1834
|
let drainTimer: NodeJS.Timeout | null = null;
|
|
1836
1835
|
let flushPayload: null | (() => void) = null;
|
|
1837
1836
|
const activeSpans = new Set<string>();
|
|
1838
1837
|
let anonymousSpanDepth = 0;
|
|
1839
|
-
|
|
1838
|
+
const ACTIVE_SPAN_FORCE_FLUSH_MS = 60000; // hard cutoff after finish to avoid endlessly running replies
|
|
1840
1839
|
|
|
1841
1840
|
const clearTimers = () => {
|
|
1842
1841
|
if (idleTimer) {
|
|
@@ -1864,12 +1863,12 @@ export function reproMiddleware(cfg: ReproMiddlewareConfig) {
|
|
|
1864
1863
|
idleTimer = setTimeout(() => doFlush(false), delay);
|
|
1865
1864
|
};
|
|
1866
1865
|
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1866
|
+
const doFlush = (force: boolean = false) => {
|
|
1867
|
+
if (flushed) return;
|
|
1868
|
+
const now = Date.now();
|
|
1869
|
+
const stillActive = hasActiveWork();
|
|
1870
|
+
const quietMs = now - lastEventAt;
|
|
1871
|
+
const waitedFinish = finishedAt === null ? 0 : now - finishedAt;
|
|
1873
1872
|
|
|
1874
1873
|
// If work is still active and we haven't been quiet long enough, defer.
|
|
1875
1874
|
if (stillActive && !force) {
|
|
@@ -1877,17 +1876,20 @@ export function reproMiddleware(cfg: ReproMiddlewareConfig) {
|
|
|
1877
1876
|
scheduleIdleFlush(Math.max(remaining, 10));
|
|
1878
1877
|
return;
|
|
1879
1878
|
}
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1879
|
+
if (stillActive && force) {
|
|
1880
|
+
// Allow forced flush after either linger window of silence or max guard.
|
|
1881
|
+
if (quietMs < TRACE_LINGER_AFTER_FINISH_MS && waitedFinish < ACTIVE_SPAN_FORCE_FLUSH_MS) {
|
|
1882
|
+
const remainingQuiet = TRACE_LINGER_AFTER_FINISH_MS - quietMs;
|
|
1883
|
+
const remainingGuard = ACTIVE_SPAN_FORCE_FLUSH_MS - waitedFinish;
|
|
1884
|
+
if (hardStopTimer) {
|
|
1885
|
+
try { clearTimeout(hardStopTimer); } catch {}
|
|
1886
|
+
}
|
|
1887
|
+
hardStopTimer = setTimeout(() => doFlush(true), Math.max(10, Math.min(remainingQuiet, remainingGuard)));
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
flushed = true;
|
|
1892
|
+
clearTimers();
|
|
1891
1893
|
try { unsubscribe && unsubscribe(); } catch {}
|
|
1892
1894
|
try { flushPayload?.(); } catch {}
|
|
1893
1895
|
};
|
|
@@ -2128,13 +2130,13 @@ export function reproMiddleware(cfg: ReproMiddlewareConfig) {
|
|
|
2128
2130
|
if (requestQuery !== undefined) requestPayload.query = requestQuery;
|
|
2129
2131
|
requestPayload.entryPoint = chosenEndpoint;
|
|
2130
2132
|
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2133
|
+
post(cfg, sid, {
|
|
2134
|
+
entries: [{
|
|
2135
|
+
actionId: aid,
|
|
2136
|
+
request: requestPayload,
|
|
2137
|
+
t: alignedNow(),
|
|
2138
|
+
}]
|
|
2139
|
+
});
|
|
2138
2140
|
|
|
2139
2141
|
if (traceBatches.length) {
|
|
2140
2142
|
for (let i = 0; i < traceBatches.length; i++) {
|
|
@@ -2142,12 +2144,12 @@ export function reproMiddleware(cfg: ReproMiddlewareConfig) {
|
|
|
2142
2144
|
let traceStr = '[]';
|
|
2143
2145
|
try { traceStr = JSON.stringify(batch); } catch {}
|
|
2144
2146
|
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2147
|
+
post(cfg, sid, {
|
|
2148
|
+
entries: [{
|
|
2149
|
+
actionId: aid,
|
|
2150
|
+
trace: traceStr,
|
|
2151
|
+
traceBatch: {
|
|
2152
|
+
rid,
|
|
2151
2153
|
index: i,
|
|
2152
2154
|
total: traceBatches.length,
|
|
2153
2155
|
},
|
|
@@ -2200,7 +2202,7 @@ export function reproMiddleware(cfg: ReproMiddlewareConfig) {
|
|
|
2200
2202
|
// - ONLY schema middleware (pre/post) for specific ops
|
|
2201
2203
|
// - keeps your existing doc-diff hooks
|
|
2202
2204
|
// ===================================================================
|
|
2203
|
-
export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appSecret: string
|
|
2205
|
+
export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appSecret: string }) {
|
|
2204
2206
|
return function (schema: Schema) {
|
|
2205
2207
|
// -------- pre/post save (unchanged) --------
|
|
2206
2208
|
schema.pre('save', { document: true }, async function (next) {
|
|
@@ -2240,11 +2242,11 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
2240
2242
|
? { op: 'insertOne', doc: after }
|
|
2241
2243
|
: { filter: { _id: this._id }, update: buildMinimalUpdate(before, after), options: { upsert: false } };
|
|
2242
2244
|
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2245
|
+
post(cfg, (getCtx() as Ctx).sid!, {
|
|
2246
|
+
entries: [{
|
|
2247
|
+
actionId: (getCtx() as Ctx).aid!,
|
|
2248
|
+
db: [attachSpanContext({
|
|
2249
|
+
collection,
|
|
2248
2250
|
pk: { _id: (this as any)._id },
|
|
2249
2251
|
before,
|
|
2250
2252
|
after,
|
|
@@ -2282,11 +2284,11 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
2282
2284
|
if (!shouldCaptureDbSpan(spanContext)) return;
|
|
2283
2285
|
const pk = after?._id ?? before?._id;
|
|
2284
2286
|
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2287
|
+
post(cfg, (getCtx() as Ctx).sid!, {
|
|
2288
|
+
entries: [{
|
|
2289
|
+
actionId: (getCtx() as Ctx).aid!,
|
|
2290
|
+
db: [attachSpanContext({
|
|
2291
|
+
collection,
|
|
2290
2292
|
pk: { _id: pk },
|
|
2291
2293
|
before,
|
|
2292
2294
|
after,
|
|
@@ -2318,11 +2320,11 @@ export function reproMongoosePlugin(cfg: { appId: string; tenantId: string; appS
|
|
|
2318
2320
|
const filter = (this as any).__repro_filter ?? { _id: before._id };
|
|
2319
2321
|
const spanContext = (this as any).__repro_spanContext || captureSpanContextFromTracer(this);
|
|
2320
2322
|
if (!shouldCaptureDbSpan(spanContext)) return;
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2323
|
+
post(cfg, (getCtx() as Ctx).sid!, {
|
|
2324
|
+
entries: [{
|
|
2325
|
+
actionId: (getCtx() as Ctx).aid!,
|
|
2326
|
+
db: [attachSpanContext({
|
|
2327
|
+
collection,
|
|
2326
2328
|
pk: { _id: before._id },
|
|
2327
2329
|
before,
|
|
2328
2330
|
after: null,
|
|
@@ -2644,11 +2646,11 @@ function emitDbQuery(cfg: any, sid?: string, aid?: string, payload?: any) {
|
|
|
2644
2646
|
pk: null, before: null, after: null,
|
|
2645
2647
|
error: payload.error ?? undefined,
|
|
2646
2648
|
}, spanContext);
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2649
|
+
post(cfg, sid, {
|
|
2650
|
+
entries: [{
|
|
2651
|
+
actionId: aid ?? null,
|
|
2652
|
+
db: [dbEntry],
|
|
2653
|
+
t: payload.t,
|
|
2652
2654
|
}]
|
|
2653
2655
|
});
|
|
2654
2656
|
}
|
|
@@ -2697,7 +2699,6 @@ export type SendgridPatchConfig = {
|
|
|
2697
2699
|
appId: string;
|
|
2698
2700
|
tenantId: string;
|
|
2699
2701
|
appSecret: string;
|
|
2700
|
-
apiBase: string;
|
|
2701
2702
|
resolveContext?: () => { sid?: string; aid?: string } | undefined;
|
|
2702
2703
|
};
|
|
2703
2704
|
|
|
@@ -2752,11 +2753,11 @@ export function patchSendgridMail(cfg: SendgridPatchConfig) {
|
|
|
2752
2753
|
if (!sid) return;
|
|
2753
2754
|
|
|
2754
2755
|
const norm = normalizeSendgridMessage(rawMsg);
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2756
|
+
post(cfg, sid, {
|
|
2757
|
+
entries: [{
|
|
2758
|
+
actionId: aid ?? null,
|
|
2759
|
+
email: {
|
|
2760
|
+
provider: 'sendgrid',
|
|
2760
2761
|
kind,
|
|
2761
2762
|
to: norm.to, cc: norm.cc, bcc: norm.bcc, from: norm.from,
|
|
2762
2763
|
subject: norm.subject, text: norm.text, html: norm.html,
|
|
@@ -8,21 +8,21 @@ export const getCtx = () => als.getStore() || {};
|
|
|
8
8
|
// If you already export als/getCtx from repro-node, reuse that instead of re-declaring.
|
|
9
9
|
|
|
10
10
|
async function post(
|
|
11
|
-
|
|
12
|
-
tenantId: string,
|
|
13
|
-
appId: string,
|
|
14
|
-
appSecret: string,
|
|
11
|
+
cfg: { tenantId: string; appId: string; appSecret: string; apiBase?: string },
|
|
15
12
|
sessionId: string,
|
|
16
13
|
body: any,
|
|
17
14
|
) {
|
|
18
15
|
try {
|
|
16
|
+
const envBase = typeof process !== 'undefined' ? (process as any)?.env?.REPRO_API_BASE : undefined;
|
|
17
|
+
const legacyBase = (cfg as any)?.apiBase;
|
|
18
|
+
const apiBase = String(envBase || legacyBase || 'https://oozy-loreta-gully.ngrok-free.dev').replace(/\/+$/, '');
|
|
19
19
|
await fetch(`${apiBase}/v1/sessions/${sessionId}/backend`, {
|
|
20
20
|
method: 'POST',
|
|
21
21
|
headers: {
|
|
22
22
|
'Content-Type': 'application/json',
|
|
23
|
-
'X-App-Id': appId,
|
|
24
|
-
'X-App-Secret': appSecret,
|
|
25
|
-
'X-Tenant-Id': tenantId,
|
|
23
|
+
'X-App-Id': cfg.appId,
|
|
24
|
+
'X-App-Secret': cfg.appSecret,
|
|
25
|
+
'X-Tenant-Id': cfg.tenantId,
|
|
26
26
|
},
|
|
27
27
|
body: JSON.stringify(body),
|
|
28
28
|
});
|
|
@@ -33,7 +33,6 @@ export type SendgridPatchConfig = {
|
|
|
33
33
|
appId: string;
|
|
34
34
|
tenantId: string;
|
|
35
35
|
appSecret: string;
|
|
36
|
-
apiBase: string;
|
|
37
36
|
// Optional: provide a function to resolve sid/aid if AsyncLocalStorage is not set
|
|
38
37
|
resolveContext?: () => { sid?: string; aid?: string } | undefined;
|
|
39
38
|
};
|
|
@@ -120,7 +119,7 @@ export function patchSendgridMail(cfg: SendgridPatchConfig) {
|
|
|
120
119
|
t: Date.now(),
|
|
121
120
|
};
|
|
122
121
|
|
|
123
|
-
post(cfg
|
|
122
|
+
post(cfg, sid, { entries: [entry] });
|
|
124
123
|
}
|
|
125
124
|
|
|
126
125
|
function normalizeAddress(a: any): { email: string; name?: string } | null {
|
package/tmp/dev-test.js
CHANGED
|
@@ -10,7 +10,7 @@ global.fetch = async (url, opts = {}) => {
|
|
|
10
10
|
return { ok: true, json: async () => ({ ok: true }) };
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
const cfg = { appId: 'app', tenantId: 'tenant', appSecret: 'secret'
|
|
13
|
+
const cfg = { appId: 'app', tenantId: 'tenant', appSecret: 'secret' };
|
|
14
14
|
const middleware = reproMiddleware(cfg);
|
|
15
15
|
|
|
16
16
|
function makeReqRes(sessionId) {
|