@hot-updater/plugin-insights 1.0.0-rc.28 → 1.0.0-rc.29
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/client/errorDetails.cjs +1 -0
- package/dist/client/errorDetails.mjs +1 -1
- package/dist/client/index.cjs +18 -1
- package/dist/client/index.mjs +19 -2
- package/dist/client/state.cjs +18 -0
- package/dist/client/state.mjs +18 -0
- package/dist/server/domain.d.cts +10 -1
- package/dist/server/domain.d.mts +10 -1
- package/dist/server/eventInput.cjs +32 -3
- package/dist/server/eventInput.mjs +32 -3
- package/dist/server/eventRow.cjs +2 -1
- package/dist/server/eventRow.d.cts +10 -1
- package/dist/server/eventRow.d.mts +10 -1
- package/dist/server/eventRow.mjs +2 -1
- package/dist/server/index.d.cts +2 -2
- package/dist/server/index.d.mts +2 -2
- package/dist/server/provider.cjs +9 -0
- package/dist/server/provider.mjs +9 -0
- package/package.json +5 -5
package/dist/client/index.cjs
CHANGED
|
@@ -46,8 +46,13 @@ const insights = (options = {}) => {
|
|
|
46
46
|
const now = context.now();
|
|
47
47
|
const installId = context.installId;
|
|
48
48
|
const userId = state.readUserId();
|
|
49
|
+
const response = state.readHttpResponse(movement.channel, appVersion);
|
|
49
50
|
const body = {
|
|
50
51
|
...movement,
|
|
52
|
+
...response ? { metadata: {
|
|
53
|
+
...movement.metadata,
|
|
54
|
+
httpResponse: response
|
|
55
|
+
} } : {},
|
|
51
56
|
eventId: eventId?.(now, installId) ?? require_eventId.createUUIDv7(),
|
|
52
57
|
installId,
|
|
53
58
|
...userId === null ? {} : { userId },
|
|
@@ -176,6 +181,17 @@ const insights = (options = {}) => {
|
|
|
176
181
|
failureKey
|
|
177
182
|
});
|
|
178
183
|
};
|
|
184
|
+
const onHttpResponse = (response) => {
|
|
185
|
+
if (context === null || state === null || context.appVersion === null) return;
|
|
186
|
+
const body = response.body === null ? null : require_errorDetails.boundedText(response.body, 4096);
|
|
187
|
+
state.recordHttpResponse(context.getChannel(), context.appVersion, {
|
|
188
|
+
...response,
|
|
189
|
+
path: require_errorDetails.boundedText(response.path, 1024),
|
|
190
|
+
body,
|
|
191
|
+
bodyTruncated: response.bodyTruncated || body !== response.body,
|
|
192
|
+
receivedAtMs: context.now()
|
|
193
|
+
});
|
|
194
|
+
};
|
|
179
195
|
const admit = (body) => {
|
|
180
196
|
const event = pending.get(body);
|
|
181
197
|
if (event === void 0 || state === null || context === null) return false;
|
|
@@ -220,7 +236,8 @@ const insights = (options = {}) => {
|
|
|
220
236
|
onAppReady,
|
|
221
237
|
onUpdateCheck,
|
|
222
238
|
onBundleDownloaded,
|
|
223
|
-
onUpdateError
|
|
239
|
+
onUpdateError,
|
|
240
|
+
onHttpResponse
|
|
224
241
|
};
|
|
225
242
|
},
|
|
226
243
|
setUser(user) {
|
package/dist/client/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readErrorDetails } from "./errorDetails.mjs";
|
|
1
|
+
import { boundedText, readErrorDetails } from "./errorDetails.mjs";
|
|
2
2
|
import { createKeyedUUIDv7, createUUIDv7 } from "./eventId.mjs";
|
|
3
3
|
import { createInsightsEventSender } from "./sender.mjs";
|
|
4
4
|
import { createInsightsState, utcDay, utcDayStart } from "./state.mjs";
|
|
@@ -45,8 +45,13 @@ const insights = (options = {}) => {
|
|
|
45
45
|
const now = context.now();
|
|
46
46
|
const installId = context.installId;
|
|
47
47
|
const userId = state.readUserId();
|
|
48
|
+
const response = state.readHttpResponse(movement.channel, appVersion);
|
|
48
49
|
const body = {
|
|
49
50
|
...movement,
|
|
51
|
+
...response ? { metadata: {
|
|
52
|
+
...movement.metadata,
|
|
53
|
+
httpResponse: response
|
|
54
|
+
} } : {},
|
|
50
55
|
eventId: eventId?.(now, installId) ?? createUUIDv7(),
|
|
51
56
|
installId,
|
|
52
57
|
...userId === null ? {} : { userId },
|
|
@@ -175,6 +180,17 @@ const insights = (options = {}) => {
|
|
|
175
180
|
failureKey
|
|
176
181
|
});
|
|
177
182
|
};
|
|
183
|
+
const onHttpResponse = (response) => {
|
|
184
|
+
if (context === null || state === null || context.appVersion === null) return;
|
|
185
|
+
const body = response.body === null ? null : boundedText(response.body, 4096);
|
|
186
|
+
state.recordHttpResponse(context.getChannel(), context.appVersion, {
|
|
187
|
+
...response,
|
|
188
|
+
path: boundedText(response.path, 1024),
|
|
189
|
+
body,
|
|
190
|
+
bodyTruncated: response.bodyTruncated || body !== response.body,
|
|
191
|
+
receivedAtMs: context.now()
|
|
192
|
+
});
|
|
193
|
+
};
|
|
178
194
|
const admit = (body) => {
|
|
179
195
|
const event = pending.get(body);
|
|
180
196
|
if (event === void 0 || state === null || context === null) return false;
|
|
@@ -219,7 +235,8 @@ const insights = (options = {}) => {
|
|
|
219
235
|
onAppReady,
|
|
220
236
|
onUpdateCheck,
|
|
221
237
|
onBundleDownloaded,
|
|
222
|
-
onUpdateError
|
|
238
|
+
onUpdateError,
|
|
239
|
+
onHttpResponse
|
|
223
240
|
};
|
|
224
241
|
},
|
|
225
242
|
setUser(user) {
|
package/dist/client/state.cjs
CHANGED
|
@@ -102,6 +102,24 @@ const createInsightsState = (storage) => {
|
|
|
102
102
|
keys: [...keys, key].slice(-32)
|
|
103
103
|
}));
|
|
104
104
|
},
|
|
105
|
+
readHttpResponse(channel, appVersion) {
|
|
106
|
+
try {
|
|
107
|
+
const saved = JSON.parse(read("httpResponse") ?? "null");
|
|
108
|
+
if (!isRecord(saved) || saved.channel !== channel || saved.appVersion !== appVersion || !isRecord(saved.response)) return void 0;
|
|
109
|
+
const response = saved.response;
|
|
110
|
+
if (response.resource !== "catalog" && response.resource !== "artifact" || typeof response.path !== "string" || response.path.length > 1024 || typeof response.status !== "number" || !Number.isInteger(response.status) || response.status < 100 || response.status > 599 || !isNullableString(response.body) || JSON.stringify(response.body).length > 4096 || typeof response.bodyTruncated !== "boolean" || typeof response.receivedAtMs !== "number" || !Number.isSafeInteger(response.receivedAtMs) || response.receivedAtMs < 0) return void 0;
|
|
111
|
+
return response;
|
|
112
|
+
} catch {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
recordHttpResponse(channel, appVersion, response) {
|
|
117
|
+
write("httpResponse", JSON.stringify({
|
|
118
|
+
channel,
|
|
119
|
+
appVersion,
|
|
120
|
+
response
|
|
121
|
+
}));
|
|
122
|
+
},
|
|
105
123
|
readUserId() {
|
|
106
124
|
try {
|
|
107
125
|
const user = JSON.parse(read("user") ?? "null");
|
package/dist/client/state.mjs
CHANGED
|
@@ -102,6 +102,24 @@ const createInsightsState = (storage) => {
|
|
|
102
102
|
keys: [...keys, key].slice(-32)
|
|
103
103
|
}));
|
|
104
104
|
},
|
|
105
|
+
readHttpResponse(channel, appVersion) {
|
|
106
|
+
try {
|
|
107
|
+
const saved = JSON.parse(read("httpResponse") ?? "null");
|
|
108
|
+
if (!isRecord(saved) || saved.channel !== channel || saved.appVersion !== appVersion || !isRecord(saved.response)) return void 0;
|
|
109
|
+
const response = saved.response;
|
|
110
|
+
if (response.resource !== "catalog" && response.resource !== "artifact" || typeof response.path !== "string" || response.path.length > 1024 || typeof response.status !== "number" || !Number.isInteger(response.status) || response.status < 100 || response.status > 599 || !isNullableString(response.body) || JSON.stringify(response.body).length > 4096 || typeof response.bodyTruncated !== "boolean" || typeof response.receivedAtMs !== "number" || !Number.isSafeInteger(response.receivedAtMs) || response.receivedAtMs < 0) return void 0;
|
|
111
|
+
return response;
|
|
112
|
+
} catch {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
recordHttpResponse(channel, appVersion, response) {
|
|
117
|
+
write("httpResponse", JSON.stringify({
|
|
118
|
+
channel,
|
|
119
|
+
appVersion,
|
|
120
|
+
response
|
|
121
|
+
}));
|
|
122
|
+
},
|
|
105
123
|
readUserId() {
|
|
106
124
|
try {
|
|
107
125
|
const user = JSON.parse(read("user") ?? "null");
|
package/dist/server/domain.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, DatabaseBundleEventMetadata } from "./eventRow.cjs";
|
|
2
2
|
import { InsightsScope } from "./modelTypes.cjs";
|
|
3
|
+
import { UpdateHttpResponse } from "@hot-updater/protocol";
|
|
3
4
|
//#region src/server/domain.d.ts
|
|
4
5
|
/**
|
|
5
6
|
* Where an update failed and why, as a report carries it. Unknown values of
|
|
@@ -33,6 +34,9 @@ type CreateBundleEventRequestBase = {
|
|
|
33
34
|
* server creates the ID, and a retry counts as another report.
|
|
34
35
|
*/
|
|
35
36
|
readonly eventId?: string;
|
|
37
|
+
readonly metadata?: {
|
|
38
|
+
readonly httpResponse?: InsightsHttpResponse;
|
|
39
|
+
};
|
|
36
40
|
readonly installId: string;
|
|
37
41
|
readonly toBundleId: string;
|
|
38
42
|
readonly userId?: string;
|
|
@@ -94,6 +98,7 @@ type EventHistoryRow = {
|
|
|
94
98
|
readonly channel: string;
|
|
95
99
|
readonly cohort: string;
|
|
96
100
|
readonly receivedAtMs: number;
|
|
101
|
+
readonly httpResponse?: InsightsHttpResponse;
|
|
97
102
|
/** `UPDATE_FAILED`: where the update failed and why. */
|
|
98
103
|
readonly failure?: BundleEventFailureInput;
|
|
99
104
|
/** `UPDATE_DOWNLOADED`: how the bundle arrived, when the client said. */
|
|
@@ -107,7 +112,11 @@ type InstallationHistoryRow = EventHistoryRow & {
|
|
|
107
112
|
readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "RECOVERED" | "UPDATE_FAILED";
|
|
108
113
|
readonly fromBundleId: string;
|
|
109
114
|
};
|
|
115
|
+
type InsightsHttpResponse = UpdateHttpResponse & {
|
|
116
|
+
readonly receivedAtMs: number;
|
|
117
|
+
};
|
|
110
118
|
type InstallationRow = {
|
|
119
|
+
readonly httpResponse?: InsightsHttpResponse;
|
|
111
120
|
readonly installId: string;
|
|
112
121
|
readonly userId: string | null;
|
|
113
122
|
readonly lastKnownBundleId: string;
|
|
@@ -151,4 +160,4 @@ type ReportingOverview = InsightsScope & {
|
|
|
151
160
|
};
|
|
152
161
|
};
|
|
153
162
|
//#endregion
|
|
154
|
-
export { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InstallationHistoryRow, InstallationRow, ReportingOverview };
|
|
163
|
+
export { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsHttpResponse, InstallationHistoryRow, InstallationRow, ReportingOverview };
|
package/dist/server/domain.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, DatabaseBundleEventMetadata } from "./eventRow.mjs";
|
|
2
2
|
import { InsightsScope } from "./modelTypes.mjs";
|
|
3
|
+
import { UpdateHttpResponse } from "@hot-updater/protocol";
|
|
3
4
|
//#region src/server/domain.d.ts
|
|
4
5
|
/**
|
|
5
6
|
* Where an update failed and why, as a report carries it. Unknown values of
|
|
@@ -33,6 +34,9 @@ type CreateBundleEventRequestBase = {
|
|
|
33
34
|
* server creates the ID, and a retry counts as another report.
|
|
34
35
|
*/
|
|
35
36
|
readonly eventId?: string;
|
|
37
|
+
readonly metadata?: {
|
|
38
|
+
readonly httpResponse?: InsightsHttpResponse;
|
|
39
|
+
};
|
|
36
40
|
readonly installId: string;
|
|
37
41
|
readonly toBundleId: string;
|
|
38
42
|
readonly userId?: string;
|
|
@@ -94,6 +98,7 @@ type EventHistoryRow = {
|
|
|
94
98
|
readonly channel: string;
|
|
95
99
|
readonly cohort: string;
|
|
96
100
|
readonly receivedAtMs: number;
|
|
101
|
+
readonly httpResponse?: InsightsHttpResponse;
|
|
97
102
|
/** `UPDATE_FAILED`: where the update failed and why. */
|
|
98
103
|
readonly failure?: BundleEventFailureInput;
|
|
99
104
|
/** `UPDATE_DOWNLOADED`: how the bundle arrived, when the client said. */
|
|
@@ -107,7 +112,11 @@ type InstallationHistoryRow = EventHistoryRow & {
|
|
|
107
112
|
readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "RECOVERED" | "UPDATE_FAILED";
|
|
108
113
|
readonly fromBundleId: string;
|
|
109
114
|
};
|
|
115
|
+
type InsightsHttpResponse = UpdateHttpResponse & {
|
|
116
|
+
readonly receivedAtMs: number;
|
|
117
|
+
};
|
|
110
118
|
type InstallationRow = {
|
|
119
|
+
readonly httpResponse?: InsightsHttpResponse;
|
|
111
120
|
readonly installId: string;
|
|
112
121
|
readonly userId: string | null;
|
|
113
122
|
readonly lastKnownBundleId: string;
|
|
@@ -151,4 +160,4 @@ type ReportingOverview = InsightsScope & {
|
|
|
151
160
|
};
|
|
152
161
|
};
|
|
153
162
|
//#endregion
|
|
154
|
-
export { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InstallationHistoryRow, InstallationRow, ReportingOverview };
|
|
163
|
+
export { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsHttpResponse, InstallationHistoryRow, InstallationRow, ReportingOverview };
|
|
@@ -98,6 +98,17 @@ function readFailure(value) {
|
|
|
98
98
|
...previousProcessExit === void 0 ? {} : { previousProcessExit }
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
|
+
function readHttpResponse(value) {
|
|
102
|
+
if (!isRecord(value) || value.resource !== "catalog" && value.resource !== "artifact" || typeof value.path !== "string" || value.path.length > 1024 || !Number.isSafeInteger(value.status) || value.status < 100 || value.status > 599 || value.body !== null && (typeof value.body !== "string" || new TextEncoder().encode(JSON.stringify(value.body)).byteLength > 4096) || typeof value.bodyTruncated !== "boolean" || !Number.isSafeInteger(value.receivedAtMs) || value.receivedAtMs < 0) throw new require_errors.InsightsBadRequestError("Invalid HTTP response details");
|
|
103
|
+
return {
|
|
104
|
+
resource: value.resource,
|
|
105
|
+
path: value.path,
|
|
106
|
+
status: value.status,
|
|
107
|
+
body: value.body,
|
|
108
|
+
bodyTruncated: value.bodyTruncated,
|
|
109
|
+
receivedAtMs: value.receivedAtMs
|
|
110
|
+
};
|
|
111
|
+
}
|
|
101
112
|
async function readBoundedText(request) {
|
|
102
113
|
const contentLength = request.headers.get("content-length");
|
|
103
114
|
const declaredByteLength = Number(contentLength);
|
|
@@ -133,7 +144,10 @@ function requireEvent(payload) {
|
|
|
133
144
|
const platform = requireStringField(payload, "platform");
|
|
134
145
|
if (platform !== "ios" && platform !== "android") throw new require_errors.InsightsBadRequestError("Invalid event field: platform");
|
|
135
146
|
const eventId = readEventId(payload);
|
|
147
|
+
const metadata = readMetadata(payload);
|
|
148
|
+
const httpMetadata = metadata.httpResponse === void 0 ? {} : { httpResponse: readHttpResponse(metadata.httpResponse) };
|
|
136
149
|
const base = {
|
|
150
|
+
...metadata.httpResponse === void 0 ? {} : { metadata: httpMetadata },
|
|
137
151
|
...eventId === void 0 ? {} : { eventId },
|
|
138
152
|
installId: requireIdentityField(payload, "installId"),
|
|
139
153
|
toBundleId: requireStringField(payload, "toBundleId"),
|
|
@@ -157,11 +171,11 @@ function requireEvent(payload) {
|
|
|
157
171
|
updateStrategy
|
|
158
172
|
};
|
|
159
173
|
};
|
|
160
|
-
const metadata = readMetadata(payload);
|
|
161
174
|
switch (type) {
|
|
162
175
|
case "UPDATE_DOWNLOADED": {
|
|
163
176
|
const delivery = metadata.delivery;
|
|
164
177
|
const read = {
|
|
178
|
+
...httpMetadata,
|
|
165
179
|
...delivery == null ? {} : { delivery: oneOf(DELIVERIES, delivery) },
|
|
166
180
|
...metadata.patchFallback === true ? { patchFallback: true } : {}
|
|
167
181
|
};
|
|
@@ -180,13 +194,19 @@ function requireEvent(payload) {
|
|
|
180
194
|
return {
|
|
181
195
|
...movement(),
|
|
182
196
|
type,
|
|
183
|
-
...previousProcessExit === void 0 ? {} : { metadata: {
|
|
197
|
+
...previousProcessExit === void 0 ? {} : { metadata: {
|
|
198
|
+
...httpMetadata,
|
|
199
|
+
previousProcessExit
|
|
200
|
+
} }
|
|
184
201
|
};
|
|
185
202
|
}
|
|
186
203
|
case "UPDATE_FAILED": return {
|
|
187
204
|
...movement(),
|
|
188
205
|
type,
|
|
189
|
-
metadata: {
|
|
206
|
+
metadata: {
|
|
207
|
+
...httpMetadata,
|
|
208
|
+
failure: readFailure(metadata.failure)
|
|
209
|
+
}
|
|
190
210
|
};
|
|
191
211
|
case "UNCHANGED":
|
|
192
212
|
if (payload.fromBundleId !== null || payload.updateStrategy !== null) throw new require_errors.InsightsBadRequestError("Invalid unchanged event shape");
|
|
@@ -216,7 +236,16 @@ function createBundleEventRow(input) {
|
|
|
216
236
|
to_release_id: input.toReleaseId,
|
|
217
237
|
user_id: input.userId ?? null
|
|
218
238
|
};
|
|
239
|
+
const response = input.metadata?.httpResponse;
|
|
219
240
|
const metadata = {
|
|
241
|
+
...response ? { http_response: {
|
|
242
|
+
resource: response.resource,
|
|
243
|
+
path: response.path,
|
|
244
|
+
status: response.status,
|
|
245
|
+
body: response.body,
|
|
246
|
+
body_truncated: response.bodyTruncated,
|
|
247
|
+
received_at_ms: response.receivedAtMs
|
|
248
|
+
} } : {},
|
|
220
249
|
cohort: input.cohort,
|
|
221
250
|
fingerprint_hash: input.fingerprintHash,
|
|
222
251
|
sdk_version: input.sdkVersion ?? null,
|
|
@@ -98,6 +98,17 @@ function readFailure(value) {
|
|
|
98
98
|
...previousProcessExit === void 0 ? {} : { previousProcessExit }
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
|
+
function readHttpResponse(value) {
|
|
102
|
+
if (!isRecord(value) || value.resource !== "catalog" && value.resource !== "artifact" || typeof value.path !== "string" || value.path.length > 1024 || !Number.isSafeInteger(value.status) || value.status < 100 || value.status > 599 || value.body !== null && (typeof value.body !== "string" || new TextEncoder().encode(JSON.stringify(value.body)).byteLength > 4096) || typeof value.bodyTruncated !== "boolean" || !Number.isSafeInteger(value.receivedAtMs) || value.receivedAtMs < 0) throw new InsightsBadRequestError("Invalid HTTP response details");
|
|
103
|
+
return {
|
|
104
|
+
resource: value.resource,
|
|
105
|
+
path: value.path,
|
|
106
|
+
status: value.status,
|
|
107
|
+
body: value.body,
|
|
108
|
+
bodyTruncated: value.bodyTruncated,
|
|
109
|
+
receivedAtMs: value.receivedAtMs
|
|
110
|
+
};
|
|
111
|
+
}
|
|
101
112
|
async function readBoundedText(request) {
|
|
102
113
|
const contentLength = request.headers.get("content-length");
|
|
103
114
|
const declaredByteLength = Number(contentLength);
|
|
@@ -133,7 +144,10 @@ function requireEvent(payload) {
|
|
|
133
144
|
const platform = requireStringField(payload, "platform");
|
|
134
145
|
if (platform !== "ios" && platform !== "android") throw new InsightsBadRequestError("Invalid event field: platform");
|
|
135
146
|
const eventId = readEventId(payload);
|
|
147
|
+
const metadata = readMetadata(payload);
|
|
148
|
+
const httpMetadata = metadata.httpResponse === void 0 ? {} : { httpResponse: readHttpResponse(metadata.httpResponse) };
|
|
136
149
|
const base = {
|
|
150
|
+
...metadata.httpResponse === void 0 ? {} : { metadata: httpMetadata },
|
|
137
151
|
...eventId === void 0 ? {} : { eventId },
|
|
138
152
|
installId: requireIdentityField(payload, "installId"),
|
|
139
153
|
toBundleId: requireStringField(payload, "toBundleId"),
|
|
@@ -157,11 +171,11 @@ function requireEvent(payload) {
|
|
|
157
171
|
updateStrategy
|
|
158
172
|
};
|
|
159
173
|
};
|
|
160
|
-
const metadata = readMetadata(payload);
|
|
161
174
|
switch (type) {
|
|
162
175
|
case "UPDATE_DOWNLOADED": {
|
|
163
176
|
const delivery = metadata.delivery;
|
|
164
177
|
const read = {
|
|
178
|
+
...httpMetadata,
|
|
165
179
|
...delivery == null ? {} : { delivery: oneOf(DELIVERIES, delivery) },
|
|
166
180
|
...metadata.patchFallback === true ? { patchFallback: true } : {}
|
|
167
181
|
};
|
|
@@ -180,13 +194,19 @@ function requireEvent(payload) {
|
|
|
180
194
|
return {
|
|
181
195
|
...movement(),
|
|
182
196
|
type,
|
|
183
|
-
...previousProcessExit === void 0 ? {} : { metadata: {
|
|
197
|
+
...previousProcessExit === void 0 ? {} : { metadata: {
|
|
198
|
+
...httpMetadata,
|
|
199
|
+
previousProcessExit
|
|
200
|
+
} }
|
|
184
201
|
};
|
|
185
202
|
}
|
|
186
203
|
case "UPDATE_FAILED": return {
|
|
187
204
|
...movement(),
|
|
188
205
|
type,
|
|
189
|
-
metadata: {
|
|
206
|
+
metadata: {
|
|
207
|
+
...httpMetadata,
|
|
208
|
+
failure: readFailure(metadata.failure)
|
|
209
|
+
}
|
|
190
210
|
};
|
|
191
211
|
case "UNCHANGED":
|
|
192
212
|
if (payload.fromBundleId !== null || payload.updateStrategy !== null) throw new InsightsBadRequestError("Invalid unchanged event shape");
|
|
@@ -216,7 +236,16 @@ function createBundleEventRow(input) {
|
|
|
216
236
|
to_release_id: input.toReleaseId,
|
|
217
237
|
user_id: input.userId ?? null
|
|
218
238
|
};
|
|
239
|
+
const response = input.metadata?.httpResponse;
|
|
219
240
|
const metadata = {
|
|
241
|
+
...response ? { http_response: {
|
|
242
|
+
resource: response.resource,
|
|
243
|
+
path: response.path,
|
|
244
|
+
status: response.status,
|
|
245
|
+
body: response.body,
|
|
246
|
+
body_truncated: response.bodyTruncated,
|
|
247
|
+
received_at_ms: response.receivedAtMs
|
|
248
|
+
} } : {},
|
|
220
249
|
cohort: input.cohort,
|
|
221
250
|
fingerprint_hash: input.fingerprintHash,
|
|
222
251
|
sdk_version: input.sdkVersion ?? null,
|
package/dist/server/eventRow.cjs
CHANGED
|
@@ -2,9 +2,10 @@ let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
|
2
2
|
//#region src/server/eventRow.ts
|
|
3
3
|
const isOptional = (value, key, valid) => !Object.hasOwn(value, key) || valid(value[key]);
|
|
4
4
|
const isString = (value) => typeof value === "string";
|
|
5
|
+
const isDatabaseHttpResponse = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && (value.resource === "catalog" || value.resource === "artifact") && isString(value.path) && Number.isSafeInteger(value.status) && (value.body === null || isString(value.body)) && typeof value.body_truncated === "boolean" && Number.isSafeInteger(value.received_at_ms);
|
|
5
6
|
/** An `UPDATE_FAILED` report's stored failure: a stage and a reason, and what else the client knew. */
|
|
6
7
|
const isDatabaseBundleEventFailure = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && isString(value.stage) && isString(value.reason) && isOptional(value, "resource", isString) && isOptional(value, "http_status", (status) => Number.isSafeInteger(status)) && isOptional(value, "transport", isString) && isOptional(value, "origin_code", isString) && isOptional(value, "error_message", isString) && isOptional(value, "error_stack", isString) && isOptional(value, "previous_process_exit", isString);
|
|
7
|
-
const isDatabaseBundleEventMetadata = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && typeof value.cohort === "string" && (value.update_strategy === null || value.update_strategy === "fingerprint" || value.update_strategy === "appVersion") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === "string") && (value.sdk_version === null || typeof value.sdk_version === "string") && isOptional(value, "failure", isDatabaseBundleEventFailure) && isOptional(value, "delivery", isString) && isOptional(value, "patch_fallback", (flag) => typeof flag === "boolean") && isOptional(value, "previous_process_exit", isString);
|
|
8
|
+
const isDatabaseBundleEventMetadata = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && typeof value.cohort === "string" && (value.update_strategy === null || value.update_strategy === "fingerprint" || value.update_strategy === "appVersion") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === "string") && (value.sdk_version === null || typeof value.sdk_version === "string") && isOptional(value, "failure", isDatabaseBundleEventFailure) && isOptional(value, "http_response", isDatabaseHttpResponse) && isOptional(value, "delivery", isString) && isOptional(value, "patch_fallback", (flag) => typeof flag === "boolean") && isOptional(value, "previous_process_exit", isString);
|
|
8
9
|
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9
10
|
const isIdentity = (value) => typeof value === "string" && value.length > 0 && value.length <= 255;
|
|
10
11
|
const isTextOrNull = (value) => value === null || typeof value === "string";
|
|
@@ -19,6 +19,14 @@ type BundleEventFailure = DatabaseJsonObject & {
|
|
|
19
19
|
/** Android's `ApplicationExitInfo` reason for the process before this one. */
|
|
20
20
|
readonly previous_process_exit?: string;
|
|
21
21
|
};
|
|
22
|
+
type DatabaseHttpResponse = DatabaseJsonObject & {
|
|
23
|
+
readonly resource: "catalog" | "artifact";
|
|
24
|
+
readonly path: string;
|
|
25
|
+
readonly status: number;
|
|
26
|
+
readonly body: string | null;
|
|
27
|
+
readonly body_truncated: boolean;
|
|
28
|
+
readonly received_at_ms: number;
|
|
29
|
+
};
|
|
22
30
|
/** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
|
|
23
31
|
type DatabaseBundleEventMetadata = DatabaseJsonObject & {
|
|
24
32
|
readonly cohort: string;
|
|
@@ -27,6 +35,7 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
|
|
|
27
35
|
readonly sdk_version: string | null;
|
|
28
36
|
/** `UPDATE_FAILED`: what failed. */
|
|
29
37
|
readonly failure?: BundleEventFailure;
|
|
38
|
+
readonly http_response?: DatabaseHttpResponse;
|
|
30
39
|
/** `UPDATE_DOWNLOADED`: how the bundle arrived. */
|
|
31
40
|
readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
|
|
32
41
|
/** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
|
|
@@ -63,4 +72,4 @@ type BundleEventRow = BundleEventRowBase & ({
|
|
|
63
72
|
readonly from_bundle_id: null;
|
|
64
73
|
});
|
|
65
74
|
//#endregion
|
|
66
|
-
export { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, BundleEventRow, BundleEventRowBase, DatabaseBundleEventMetadata };
|
|
75
|
+
export { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, BundleEventRow, BundleEventRowBase, DatabaseBundleEventMetadata, DatabaseHttpResponse };
|
|
@@ -19,6 +19,14 @@ type BundleEventFailure = DatabaseJsonObject & {
|
|
|
19
19
|
/** Android's `ApplicationExitInfo` reason for the process before this one. */
|
|
20
20
|
readonly previous_process_exit?: string;
|
|
21
21
|
};
|
|
22
|
+
type DatabaseHttpResponse = DatabaseJsonObject & {
|
|
23
|
+
readonly resource: "catalog" | "artifact";
|
|
24
|
+
readonly path: string;
|
|
25
|
+
readonly status: number;
|
|
26
|
+
readonly body: string | null;
|
|
27
|
+
readonly body_truncated: boolean;
|
|
28
|
+
readonly received_at_ms: number;
|
|
29
|
+
};
|
|
22
30
|
/** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
|
|
23
31
|
type DatabaseBundleEventMetadata = DatabaseJsonObject & {
|
|
24
32
|
readonly cohort: string;
|
|
@@ -27,6 +35,7 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
|
|
|
27
35
|
readonly sdk_version: string | null;
|
|
28
36
|
/** `UPDATE_FAILED`: what failed. */
|
|
29
37
|
readonly failure?: BundleEventFailure;
|
|
38
|
+
readonly http_response?: DatabaseHttpResponse;
|
|
30
39
|
/** `UPDATE_DOWNLOADED`: how the bundle arrived. */
|
|
31
40
|
readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
|
|
32
41
|
/** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
|
|
@@ -63,4 +72,4 @@ type BundleEventRow = BundleEventRowBase & ({
|
|
|
63
72
|
readonly from_bundle_id: null;
|
|
64
73
|
});
|
|
65
74
|
//#endregion
|
|
66
|
-
export { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, BundleEventRow, BundleEventRowBase, DatabaseBundleEventMetadata };
|
|
75
|
+
export { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, BundleEventRow, BundleEventRowBase, DatabaseBundleEventMetadata, DatabaseHttpResponse };
|
package/dist/server/eventRow.mjs
CHANGED
|
@@ -2,9 +2,10 @@ import { DatabaseAdapterInputError, isDatabaseJsonObject } from "@hot-updater/pl
|
|
|
2
2
|
//#region src/server/eventRow.ts
|
|
3
3
|
const isOptional = (value, key, valid) => !Object.hasOwn(value, key) || valid(value[key]);
|
|
4
4
|
const isString = (value) => typeof value === "string";
|
|
5
|
+
const isDatabaseHttpResponse = (value) => isDatabaseJsonObject(value) && (value.resource === "catalog" || value.resource === "artifact") && isString(value.path) && Number.isSafeInteger(value.status) && (value.body === null || isString(value.body)) && typeof value.body_truncated === "boolean" && Number.isSafeInteger(value.received_at_ms);
|
|
5
6
|
/** An `UPDATE_FAILED` report's stored failure: a stage and a reason, and what else the client knew. */
|
|
6
7
|
const isDatabaseBundleEventFailure = (value) => isDatabaseJsonObject(value) && isString(value.stage) && isString(value.reason) && isOptional(value, "resource", isString) && isOptional(value, "http_status", (status) => Number.isSafeInteger(status)) && isOptional(value, "transport", isString) && isOptional(value, "origin_code", isString) && isOptional(value, "error_message", isString) && isOptional(value, "error_stack", isString) && isOptional(value, "previous_process_exit", isString);
|
|
7
|
-
const isDatabaseBundleEventMetadata = (value) => isDatabaseJsonObject(value) && typeof value.cohort === "string" && (value.update_strategy === null || value.update_strategy === "fingerprint" || value.update_strategy === "appVersion") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === "string") && (value.sdk_version === null || typeof value.sdk_version === "string") && isOptional(value, "failure", isDatabaseBundleEventFailure) && isOptional(value, "delivery", isString) && isOptional(value, "patch_fallback", (flag) => typeof flag === "boolean") && isOptional(value, "previous_process_exit", isString);
|
|
8
|
+
const isDatabaseBundleEventMetadata = (value) => isDatabaseJsonObject(value) && typeof value.cohort === "string" && (value.update_strategy === null || value.update_strategy === "fingerprint" || value.update_strategy === "appVersion") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === "string") && (value.sdk_version === null || typeof value.sdk_version === "string") && isOptional(value, "failure", isDatabaseBundleEventFailure) && isOptional(value, "http_response", isDatabaseHttpResponse) && isOptional(value, "delivery", isString) && isOptional(value, "patch_fallback", (flag) => typeof flag === "boolean") && isOptional(value, "previous_process_exit", isString);
|
|
8
9
|
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9
10
|
const isIdentity = (value) => typeof value === "string" && value.length > 0 && value.length <= 255;
|
|
10
11
|
const isTextOrNull = (value) => value === null || typeof value === "string";
|
package/dist/server/index.d.cts
CHANGED
|
@@ -2,7 +2,7 @@ import { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage,
|
|
|
2
2
|
import { InsightsBundleEventFilter, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsCoverage, InsightsEventCursor, InsightsEventFilter, InsightsFindLatestEventsInput, InsightsGetAppUsageInput, InsightsGetAppUsageResult, InsightsGetReleaseActivityInput, InsightsGetReleaseActivityResult, InsightsListEventsInput, InsightsModel, InsightsRecordEventInput, InsightsScope, InsightsTimeRange, ReleaseActivityMetrics, ReleaseReference } from "./modelTypes.cjs";
|
|
3
3
|
import { DEFAULT_INSIGHTS_RETENTION, InsightsRetention, InsightsSchema, createInsightsSchema, insightsSchema } from "./schema.cjs";
|
|
4
4
|
import { InsightsFailureBreakdown, InsightsUpdateFailures, InsightsUpdateFailuresInput } from "./reads.cjs";
|
|
5
|
-
import { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InstallationHistoryRow, InstallationRow, ReportingOverview } from "./domain.cjs";
|
|
5
|
+
import { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsHttpResponse, InstallationHistoryRow, InstallationRow, ReportingOverview } from "./domain.cjs";
|
|
6
6
|
import { InsightsBadRequestError } from "./errors.cjs";
|
|
7
7
|
import { createInsightsModel } from "./model.cjs";
|
|
8
8
|
import { InsightsEventPageInput, InsightsInstallationEventPageInput, InsightsProvider, InsightsUserInstallationPageInput } from "./types.cjs";
|
|
@@ -392,4 +392,4 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
392
392
|
endpoints: PluginEndpoint[];
|
|
393
393
|
}, {}>;
|
|
394
394
|
//#endregion
|
|
395
|
-
export { type ActiveInstallationWindow, type BundleEventFailure, type BundleEventFailureInput, type BundleEventFailureReason, type BundleEventFailureStage, type BundleEventRow, type BundleEventRowBase, type CreateBundleEventRequest, type CreateBundleEventRequestBase, type CursorPage, DEFAULT_INSIGHTS_RETENTION, type DatabaseBundleEventMetadata, type EventCursorPage, type EventHistoryRow, InsightsApi, InsightsBadRequestError, type InsightsBundleEventFilter, type InsightsBundleSelection, type InsightsCountEventsInput, type InsightsCountLatestEventsInput, type InsightsCountMeasurement, type InsightsCoverage, type InsightsEventCursor, type InsightsEventFilter, type InsightsEventPageInput, type InsightsFailureBreakdown, type InsightsFindLatestEventsInput, type InsightsGetAppUsageInput, type InsightsGetAppUsageResult, type InsightsGetReleaseActivityInput, type InsightsGetReleaseActivityResult, type InsightsIdentityParts, type InsightsInstallationEventPageInput, type InsightsListEventsInput, type InsightsModel, InsightsOptions, type InsightsProvider, type InsightsRecordEventInput, type InsightsRetention, type InsightsSchema, type InsightsScope, type InsightsTimeRange, type InsightsUpdateFailures, type InsightsUpdateFailuresInput, type InsightsUserInstallationPageInput, type InstallationHistoryRow, type InstallationRow, type ReleaseActivityMetrics, type ReleaseReference, type ReportingOverview, createInsightsModel, createInsightsProvider, createInsightsSchema, insights, insightsIdentity, insightsSchema };
|
|
395
|
+
export { type ActiveInstallationWindow, type BundleEventFailure, type BundleEventFailureInput, type BundleEventFailureReason, type BundleEventFailureStage, type BundleEventRow, type BundleEventRowBase, type CreateBundleEventRequest, type CreateBundleEventRequestBase, type CursorPage, DEFAULT_INSIGHTS_RETENTION, type DatabaseBundleEventMetadata, type EventCursorPage, type EventHistoryRow, InsightsApi, InsightsBadRequestError, type InsightsBundleEventFilter, type InsightsBundleSelection, type InsightsCountEventsInput, type InsightsCountLatestEventsInput, type InsightsCountMeasurement, type InsightsCoverage, type InsightsEventCursor, type InsightsEventFilter, type InsightsEventPageInput, type InsightsFailureBreakdown, type InsightsFindLatestEventsInput, type InsightsGetAppUsageInput, type InsightsGetAppUsageResult, type InsightsGetReleaseActivityInput, type InsightsGetReleaseActivityResult, type InsightsHttpResponse, type InsightsIdentityParts, type InsightsInstallationEventPageInput, type InsightsListEventsInput, type InsightsModel, InsightsOptions, type InsightsProvider, type InsightsRecordEventInput, type InsightsRetention, type InsightsSchema, type InsightsScope, type InsightsTimeRange, type InsightsUpdateFailures, type InsightsUpdateFailuresInput, type InsightsUserInstallationPageInput, type InstallationHistoryRow, type InstallationRow, type ReleaseActivityMetrics, type ReleaseReference, type ReportingOverview, createInsightsModel, createInsightsProvider, createInsightsSchema, insights, insightsIdentity, insightsSchema };
|
package/dist/server/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage,
|
|
|
2
2
|
import { InsightsBundleEventFilter, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsCoverage, InsightsEventCursor, InsightsEventFilter, InsightsFindLatestEventsInput, InsightsGetAppUsageInput, InsightsGetAppUsageResult, InsightsGetReleaseActivityInput, InsightsGetReleaseActivityResult, InsightsListEventsInput, InsightsModel, InsightsRecordEventInput, InsightsScope, InsightsTimeRange, ReleaseActivityMetrics, ReleaseReference } from "./modelTypes.mjs";
|
|
3
3
|
import { DEFAULT_INSIGHTS_RETENTION, InsightsRetention, InsightsSchema, createInsightsSchema, insightsSchema } from "./schema.mjs";
|
|
4
4
|
import { InsightsFailureBreakdown, InsightsUpdateFailures, InsightsUpdateFailuresInput } from "./reads.mjs";
|
|
5
|
-
import { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InstallationHistoryRow, InstallationRow, ReportingOverview } from "./domain.mjs";
|
|
5
|
+
import { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsHttpResponse, InstallationHistoryRow, InstallationRow, ReportingOverview } from "./domain.mjs";
|
|
6
6
|
import { InsightsBadRequestError } from "./errors.mjs";
|
|
7
7
|
import { createInsightsModel } from "./model.mjs";
|
|
8
8
|
import { InsightsEventPageInput, InsightsInstallationEventPageInput, InsightsProvider, InsightsUserInstallationPageInput } from "./types.mjs";
|
|
@@ -392,4 +392,4 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
392
392
|
endpoints: PluginEndpoint[];
|
|
393
393
|
}, {}>;
|
|
394
394
|
//#endregion
|
|
395
|
-
export { type ActiveInstallationWindow, type BundleEventFailure, type BundleEventFailureInput, type BundleEventFailureReason, type BundleEventFailureStage, type BundleEventRow, type BundleEventRowBase, type CreateBundleEventRequest, type CreateBundleEventRequestBase, type CursorPage, DEFAULT_INSIGHTS_RETENTION, type DatabaseBundleEventMetadata, type EventCursorPage, type EventHistoryRow, InsightsApi, InsightsBadRequestError, type InsightsBundleEventFilter, type InsightsBundleSelection, type InsightsCountEventsInput, type InsightsCountLatestEventsInput, type InsightsCountMeasurement, type InsightsCoverage, type InsightsEventCursor, type InsightsEventFilter, type InsightsEventPageInput, type InsightsFailureBreakdown, type InsightsFindLatestEventsInput, type InsightsGetAppUsageInput, type InsightsGetAppUsageResult, type InsightsGetReleaseActivityInput, type InsightsGetReleaseActivityResult, type InsightsIdentityParts, type InsightsInstallationEventPageInput, type InsightsListEventsInput, type InsightsModel, InsightsOptions, type InsightsProvider, type InsightsRecordEventInput, type InsightsRetention, type InsightsSchema, type InsightsScope, type InsightsTimeRange, type InsightsUpdateFailures, type InsightsUpdateFailuresInput, type InsightsUserInstallationPageInput, type InstallationHistoryRow, type InstallationRow, type ReleaseActivityMetrics, type ReleaseReference, type ReportingOverview, createInsightsModel, createInsightsProvider, createInsightsSchema, insights, insightsIdentity, insightsSchema };
|
|
395
|
+
export { type ActiveInstallationWindow, type BundleEventFailure, type BundleEventFailureInput, type BundleEventFailureReason, type BundleEventFailureStage, type BundleEventRow, type BundleEventRowBase, type CreateBundleEventRequest, type CreateBundleEventRequestBase, type CursorPage, DEFAULT_INSIGHTS_RETENTION, type DatabaseBundleEventMetadata, type EventCursorPage, type EventHistoryRow, InsightsApi, InsightsBadRequestError, type InsightsBundleEventFilter, type InsightsBundleSelection, type InsightsCountEventsInput, type InsightsCountLatestEventsInput, type InsightsCountMeasurement, type InsightsCoverage, type InsightsEventCursor, type InsightsEventFilter, type InsightsEventPageInput, type InsightsFailureBreakdown, type InsightsFindLatestEventsInput, type InsightsGetAppUsageInput, type InsightsGetAppUsageResult, type InsightsGetReleaseActivityInput, type InsightsGetReleaseActivityResult, type InsightsHttpResponse, type InsightsIdentityParts, type InsightsInstallationEventPageInput, type InsightsListEventsInput, type InsightsModel, InsightsOptions, type InsightsProvider, type InsightsRecordEventInput, type InsightsRetention, type InsightsSchema, type InsightsScope, type InsightsTimeRange, type InsightsUpdateFailures, type InsightsUpdateFailuresInput, type InsightsUserInstallationPageInput, type InstallationHistoryRow, type InstallationRow, type ReleaseActivityMetrics, type ReleaseReference, type ReportingOverview, createInsightsModel, createInsightsProvider, createInsightsSchema, insights, insightsIdentity, insightsSchema };
|
package/dist/server/provider.cjs
CHANGED
|
@@ -157,6 +157,14 @@ const toFailure = (failure) => ({
|
|
|
157
157
|
});
|
|
158
158
|
/** What a row's metadata adds for its type: a failure, a delivery, an exit reason. */
|
|
159
159
|
const eventDetails = ({ type, metadata }) => ({
|
|
160
|
+
...metadata.http_response !== void 0 ? { httpResponse: {
|
|
161
|
+
resource: metadata.http_response.resource,
|
|
162
|
+
path: metadata.http_response.path,
|
|
163
|
+
status: metadata.http_response.status,
|
|
164
|
+
body: metadata.http_response.body,
|
|
165
|
+
bodyTruncated: metadata.http_response.body_truncated,
|
|
166
|
+
receivedAtMs: metadata.http_response.received_at_ms
|
|
167
|
+
} } : {},
|
|
160
168
|
...type === "UPDATE_FAILED" && metadata.failure !== void 0 ? { failure: toFailure(metadata.failure) } : {},
|
|
161
169
|
...type === "UPDATE_DOWNLOADED" && metadata.delivery !== void 0 ? { delivery: metadata.delivery } : {},
|
|
162
170
|
...type === "UPDATE_DOWNLOADED" && metadata.patch_fallback === true ? { patchFallback: true } : {},
|
|
@@ -179,6 +187,7 @@ const toEventHistoryRow = (row) => ({
|
|
|
179
187
|
...eventDetails(row)
|
|
180
188
|
});
|
|
181
189
|
const toInstallationRow = (row) => ({
|
|
190
|
+
...eventDetails(row).httpResponse ? { httpResponse: eventDetails(row).httpResponse } : {},
|
|
182
191
|
appVersion: row.app_version,
|
|
183
192
|
channel: row.channel,
|
|
184
193
|
cohort: row.metadata.cohort,
|
package/dist/server/provider.mjs
CHANGED
|
@@ -157,6 +157,14 @@ const toFailure = (failure) => ({
|
|
|
157
157
|
});
|
|
158
158
|
/** What a row's metadata adds for its type: a failure, a delivery, an exit reason. */
|
|
159
159
|
const eventDetails = ({ type, metadata }) => ({
|
|
160
|
+
...metadata.http_response !== void 0 ? { httpResponse: {
|
|
161
|
+
resource: metadata.http_response.resource,
|
|
162
|
+
path: metadata.http_response.path,
|
|
163
|
+
status: metadata.http_response.status,
|
|
164
|
+
body: metadata.http_response.body,
|
|
165
|
+
bodyTruncated: metadata.http_response.body_truncated,
|
|
166
|
+
receivedAtMs: metadata.http_response.received_at_ms
|
|
167
|
+
} } : {},
|
|
160
168
|
...type === "UPDATE_FAILED" && metadata.failure !== void 0 ? { failure: toFailure(metadata.failure) } : {},
|
|
161
169
|
...type === "UPDATE_DOWNLOADED" && metadata.delivery !== void 0 ? { delivery: metadata.delivery } : {},
|
|
162
170
|
...type === "UPDATE_DOWNLOADED" && metadata.patch_fallback === true ? { patchFallback: true } : {},
|
|
@@ -179,6 +187,7 @@ const toEventHistoryRow = (row) => ({
|
|
|
179
187
|
...eventDetails(row)
|
|
180
188
|
});
|
|
181
189
|
const toInstallationRow = (row) => ({
|
|
190
|
+
...eventDetails(row).httpResponse ? { httpResponse: eventDetails(row).httpResponse } : {},
|
|
182
191
|
appVersion: row.app_version,
|
|
183
192
|
channel: row.channel,
|
|
184
193
|
cohort: row.metadata.cohort,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/plugin-insights",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-rc.
|
|
4
|
+
"version": "1.0.0-rc.29",
|
|
5
5
|
"description": "Hot Updater's Insights plugin: launch, download, and update failure events, for the server and the React Native app",
|
|
6
6
|
"exports": {
|
|
7
7
|
"./client": {
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"package.json"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@hot-updater/protocol": "1.0.0-rc.
|
|
36
|
+
"@hot-updater/protocol": "1.0.0-rc.28"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@hot-updater/plugin-core": "^1.0.0-rc.
|
|
39
|
+
"@hot-updater/plugin-core": "^1.0.0-rc.28"
|
|
40
40
|
},
|
|
41
41
|
"peerDependenciesMeta": {
|
|
42
42
|
"@hot-updater/plugin-core": {
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/node": "^20",
|
|
48
48
|
"vitest": "4.1.4",
|
|
49
|
-
"@hot-updater/plugin-core": "1.0.0-rc.
|
|
50
|
-
"@hot-updater/test-utils": "1.0.0-rc.
|
|
49
|
+
"@hot-updater/plugin-core": "1.0.0-rc.28",
|
|
50
|
+
"@hot-updater/test-utils": "1.0.0-rc.28"
|
|
51
51
|
},
|
|
52
52
|
"nx": {
|
|
53
53
|
"implicitDependencies": [
|