@hot-updater/aws 1.0.0-rc.27 → 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/index.d.cts CHANGED
@@ -84,9 +84,19 @@ type BundleEventFailure = DatabaseJsonObject & {
84
84
  readonly transport?: "timeout" | "dns" | "tls" | "connection" | "offline" | "cancelled" | "unknown";
85
85
  /** The storage origin's error code, such as `ExpiredToken`. */
86
86
  readonly origin_code?: string;
87
+ readonly error_message?: string;
88
+ readonly error_stack?: string;
87
89
  /** Android's `ApplicationExitInfo` reason for the process before this one. */
88
90
  readonly previous_process_exit?: string;
89
91
  };
92
+ type DatabaseHttpResponse = DatabaseJsonObject & {
93
+ readonly resource: "catalog" | "artifact";
94
+ readonly path: string;
95
+ readonly status: number;
96
+ readonly body: string | null;
97
+ readonly body_truncated: boolean;
98
+ readonly received_at_ms: number;
99
+ };
90
100
  /** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
91
101
  type DatabaseBundleEventMetadata = DatabaseJsonObject & {
92
102
  readonly cohort: string;
@@ -95,6 +105,7 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
95
105
  readonly sdk_version: string | null;
96
106
  /** `UPDATE_FAILED`: what failed. */
97
107
  readonly failure?: BundleEventFailure;
108
+ readonly http_response?: DatabaseHttpResponse;
98
109
  /** `UPDATE_DOWNLOADED`: how the bundle arrived. */
99
110
  readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
100
111
  /** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
package/dist/index.d.mts CHANGED
@@ -84,9 +84,19 @@ type BundleEventFailure = DatabaseJsonObject & {
84
84
  readonly transport?: "timeout" | "dns" | "tls" | "connection" | "offline" | "cancelled" | "unknown";
85
85
  /** The storage origin's error code, such as `ExpiredToken`. */
86
86
  readonly origin_code?: string;
87
+ readonly error_message?: string;
88
+ readonly error_stack?: string;
87
89
  /** Android's `ApplicationExitInfo` reason for the process before this one. */
88
90
  readonly previous_process_exit?: string;
89
91
  };
92
+ type DatabaseHttpResponse = DatabaseJsonObject & {
93
+ readonly resource: "catalog" | "artifact";
94
+ readonly path: string;
95
+ readonly status: number;
96
+ readonly body: string | null;
97
+ readonly body_truncated: boolean;
98
+ readonly received_at_ms: number;
99
+ };
90
100
  /** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
91
101
  type DatabaseBundleEventMetadata = DatabaseJsonObject & {
92
102
  readonly cohort: string;
@@ -95,6 +105,7 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
95
105
  readonly sdk_version: string | null;
96
106
  /** `UPDATE_FAILED`: what failed. */
97
107
  readonly failure?: BundleEventFailure;
108
+ readonly http_response?: DatabaseHttpResponse;
98
109
  /** `UPDATE_DOWNLOADED`: how the bundle arrived. */
99
110
  readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
100
111
  /** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
@@ -4570,7 +4570,7 @@ const createKvAdapter = ({ store, tablePrefix = "" }) => {
4570
4570
  };
4571
4571
  //#endregion
4572
4572
  //#region ../../packages/server/dist/version.mjs
4573
- const HOT_UPDATER_SERVER_VERSION = "1.0.0-rc.27";
4573
+ const HOT_UPDATER_SERVER_VERSION = "1.0.0-rc.29";
4574
4574
  //#endregion
4575
4575
  //#region ../../packages/server/dist/handlerVersionRoutes.mjs
4576
4576
  /**
@@ -9790,9 +9790,10 @@ const apiKeys = (options = {}) => {
9790
9790
  //#region ../insights/dist/server/eventRow.mjs
9791
9791
  const isOptional = (value, key, valid) => !Object.hasOwn(value, key) || valid(value[key]);
9792
9792
  const isString = (value) => typeof value === "string";
9793
+ 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);
9793
9794
  /** An `UPDATE_FAILED` report's stored failure: a stage and a reason, and what else the client knew. */
9794
- 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, "previous_process_exit", isString);
9795
- 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);
9795
+ 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);
9796
+ 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);
9796
9797
  const isRecord$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
9797
9798
  const isIdentity$1 = (value) => typeof value === "string" && value.length > 0 && value.length <= 255;
9798
9799
  const isTextOrNull = (value) => value === null || typeof value === "string";
@@ -10143,6 +10144,8 @@ function readFailure(value) {
10143
10144
  const failure = isRecord$1(value) ? value : {};
10144
10145
  const httpStatus = failure.httpStatus;
10145
10146
  const originCode = readCode(failure.originCode);
10147
+ const errorMessage = typeof failure.errorMessage === "string" && failure.errorMessage.length <= 2048 ? failure.errorMessage : void 0;
10148
+ const errorStack = typeof failure.errorStack === "string" && failure.errorStack.length <= 4096 ? failure.errorStack : void 0;
10146
10149
  const previousProcessExit = readCode(failure.previousProcessExit);
10147
10150
  return {
10148
10151
  stage: oneOf(STAGES, failure.stage),
@@ -10151,9 +10154,22 @@ function readFailure(value) {
10151
10154
  ...Number.isSafeInteger(httpStatus) && httpStatus >= 100 && httpStatus <= 599 ? { httpStatus } : {},
10152
10155
  ...failure.transport == null ? {} : { transport: oneOf(TRANSPORTS, failure.transport) },
10153
10156
  ...originCode === void 0 ? {} : { originCode },
10157
+ ...errorMessage === void 0 ? {} : { errorMessage },
10158
+ ...errorStack === void 0 ? {} : { errorStack },
10154
10159
  ...previousProcessExit === void 0 ? {} : { previousProcessExit }
10155
10160
  };
10156
10161
  }
10162
+ function readHttpResponse(value) {
10163
+ if (!isRecord$1(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");
10164
+ return {
10165
+ resource: value.resource,
10166
+ path: value.path,
10167
+ status: value.status,
10168
+ body: value.body,
10169
+ bodyTruncated: value.bodyTruncated,
10170
+ receivedAtMs: value.receivedAtMs
10171
+ };
10172
+ }
10157
10173
  async function readBoundedText(request) {
10158
10174
  const contentLength = request.headers.get("content-length");
10159
10175
  const declaredByteLength = Number(contentLength);
@@ -10189,7 +10205,10 @@ function requireEvent(payload) {
10189
10205
  const platform = requireStringField(payload, "platform");
10190
10206
  if (platform !== "ios" && platform !== "android") throw new InsightsBadRequestError("Invalid event field: platform");
10191
10207
  const eventId = readEventId(payload);
10208
+ const metadata = readMetadata(payload);
10209
+ const httpMetadata = metadata.httpResponse === void 0 ? {} : { httpResponse: readHttpResponse(metadata.httpResponse) };
10192
10210
  const base = {
10211
+ ...metadata.httpResponse === void 0 ? {} : { metadata: httpMetadata },
10193
10212
  ...eventId === void 0 ? {} : { eventId },
10194
10213
  installId: requireIdentityField(payload, "installId"),
10195
10214
  toBundleId: requireStringField(payload, "toBundleId"),
@@ -10213,11 +10232,11 @@ function requireEvent(payload) {
10213
10232
  updateStrategy
10214
10233
  };
10215
10234
  };
10216
- const metadata = readMetadata(payload);
10217
10235
  switch (type) {
10218
10236
  case "UPDATE_DOWNLOADED": {
10219
10237
  const delivery = metadata.delivery;
10220
10238
  const read = {
10239
+ ...httpMetadata,
10221
10240
  ...delivery == null ? {} : { delivery: oneOf(DELIVERIES, delivery) },
10222
10241
  ...metadata.patchFallback === true ? { patchFallback: true } : {}
10223
10242
  };
@@ -10236,13 +10255,19 @@ function requireEvent(payload) {
10236
10255
  return {
10237
10256
  ...movement(),
10238
10257
  type,
10239
- ...previousProcessExit === void 0 ? {} : { metadata: { previousProcessExit } }
10258
+ ...previousProcessExit === void 0 ? {} : { metadata: {
10259
+ ...httpMetadata,
10260
+ previousProcessExit
10261
+ } }
10240
10262
  };
10241
10263
  }
10242
10264
  case "UPDATE_FAILED": return {
10243
10265
  ...movement(),
10244
10266
  type,
10245
- metadata: { failure: readFailure(metadata.failure) }
10267
+ metadata: {
10268
+ ...httpMetadata,
10269
+ failure: readFailure(metadata.failure)
10270
+ }
10246
10271
  };
10247
10272
  case "UNCHANGED":
10248
10273
  if (payload.fromBundleId !== null || payload.updateStrategy !== null) throw new InsightsBadRequestError("Invalid unchanged event shape");
@@ -10272,7 +10297,16 @@ function createBundleEventRow(input) {
10272
10297
  to_release_id: input.toReleaseId,
10273
10298
  user_id: input.userId ?? null
10274
10299
  };
10300
+ const response = input.metadata?.httpResponse;
10275
10301
  const metadata = {
10302
+ ...response ? { http_response: {
10303
+ resource: response.resource,
10304
+ path: response.path,
10305
+ status: response.status,
10306
+ body: response.body,
10307
+ body_truncated: response.bodyTruncated,
10308
+ received_at_ms: response.receivedAtMs
10309
+ } } : {},
10276
10310
  cohort: input.cohort,
10277
10311
  fingerprint_hash: input.fingerprintHash,
10278
10312
  sdk_version: input.sdkVersion ?? null,
@@ -10321,6 +10355,8 @@ function createBundleEventRow(input) {
10321
10355
  failure: {
10322
10356
  stage: failure.stage,
10323
10357
  reason: failure.reason,
10358
+ ...failure.errorMessage === void 0 ? {} : { error_message: failure.errorMessage },
10359
+ ...failure.errorStack === void 0 ? {} : { error_stack: failure.errorStack },
10324
10360
  ...failure.resource === void 0 ? {} : { resource: failure.resource },
10325
10361
  ...failure.httpStatus === void 0 ? {} : { http_status: failure.httpStatus },
10326
10362
  ...failure.transport === void 0 ? {} : { transport: failure.transport },
@@ -10484,6 +10520,8 @@ const assertEventRows = (rows, input) => {
10484
10520
  const toFailure = (failure) => ({
10485
10521
  stage: failure.stage,
10486
10522
  reason: failure.reason,
10523
+ ...failure.error_message === void 0 ? {} : { errorMessage: failure.error_message },
10524
+ ...failure.error_stack === void 0 ? {} : { errorStack: failure.error_stack },
10487
10525
  ...failure.resource === void 0 ? {} : { resource: failure.resource },
10488
10526
  ...failure.http_status === void 0 ? {} : { httpStatus: failure.http_status },
10489
10527
  ...failure.transport === void 0 ? {} : { transport: failure.transport },
@@ -10492,12 +10530,22 @@ const toFailure = (failure) => ({
10492
10530
  });
10493
10531
  /** What a row's metadata adds for its type: a failure, a delivery, an exit reason. */
10494
10532
  const eventDetails = ({ type, metadata }) => ({
10533
+ ...metadata.http_response !== void 0 ? { httpResponse: {
10534
+ resource: metadata.http_response.resource,
10535
+ path: metadata.http_response.path,
10536
+ status: metadata.http_response.status,
10537
+ body: metadata.http_response.body,
10538
+ bodyTruncated: metadata.http_response.body_truncated,
10539
+ receivedAtMs: metadata.http_response.received_at_ms
10540
+ } } : {},
10495
10541
  ...type === "UPDATE_FAILED" && metadata.failure !== void 0 ? { failure: toFailure(metadata.failure) } : {},
10496
10542
  ...type === "UPDATE_DOWNLOADED" && metadata.delivery !== void 0 ? { delivery: metadata.delivery } : {},
10497
10543
  ...type === "UPDATE_DOWNLOADED" && metadata.patch_fallback === true ? { patchFallback: true } : {},
10498
10544
  ...type === "RECOVERED" && metadata.previous_process_exit !== void 0 ? { previousProcessExit: metadata.previous_process_exit } : {}
10499
10545
  });
10500
10546
  const toEventHistoryRow = (row) => ({
10547
+ ...row.to_release_id == null ? {} : { toReleaseId: row.to_release_id },
10548
+ ...row.metadata.sdk_version == null ? {} : { sdkVersion: row.metadata.sdk_version },
10501
10549
  appVersion: row.app_version,
10502
10550
  channel: row.channel,
10503
10551
  cohort: row.metadata.cohort,
@@ -10512,6 +10560,7 @@ const toEventHistoryRow = (row) => ({
10512
10560
  ...eventDetails(row)
10513
10561
  });
10514
10562
  const toInstallationRow = (row) => ({
10563
+ ...eventDetails(row).httpResponse ? { httpResponse: eventDetails(row).httpResponse } : {},
10515
10564
  appVersion: row.app_version,
10516
10565
  channel: row.channel,
10517
10566
  cohort: row.metadata.cohort,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hot-updater/aws",
3
3
  "type": "module",
4
- "version": "1.0.0-rc.27",
4
+ "version": "1.0.0-rc.29",
5
5
  "description": "React Native OTA solution for self-hosted",
6
6
  "main": "dist/index.cjs",
7
7
  "module": "dist/index.mjs",
@@ -45,9 +45,9 @@
45
45
  "es-toolkit": "^1.32.0",
46
46
  "execa": "9.5.2",
47
47
  "mime": "^4.0.4",
48
- "@hot-updater/mock": "1.0.0-rc.27",
49
- "@hot-updater/protocol": "1.0.0-rc.27",
50
- "@hot-updater/test-utils": "1.0.0-rc.27"
48
+ "@hot-updater/protocol": "1.0.0-rc.28",
49
+ "@hot-updater/mock": "1.0.0-rc.28",
50
+ "@hot-updater/test-utils": "1.0.0-rc.28"
51
51
  },
52
52
  "dependencies": {
53
53
  "@aws-sdk/client-cloudfront": "3.1066.0",
@@ -62,9 +62,9 @@
62
62
  "@aws-sdk/lib-storage": "3.1066.0",
63
63
  "@aws-sdk/lib-dynamodb": "3.1066.0",
64
64
  "hono": "4.12.34",
65
- "@hot-updater/cli-tools": "1.0.0-rc.27",
66
- "@hot-updater/server": "1.0.0-rc.27",
67
- "@hot-updater/plugin-core": "1.0.0-rc.27"
65
+ "@hot-updater/cli-tools": "1.0.0-rc.29",
66
+ "@hot-updater/plugin-core": "1.0.0-rc.28",
67
+ "@hot-updater/server": "1.0.0-rc.29"
68
68
  },
69
69
  "scripts": {
70
70
  "build": "tsdown",