@hot-updater/cloudflare 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
@@ -1,5 +1,6 @@
1
1
  import { DatabaseJsonObject, Platform, StorageAdapterWith, ToolingDatabase } from "@hot-updater/plugin-core";
2
2
  import { S3ClientConfig } from "@aws-sdk/client-s3";
3
+ import "@hot-updater/protocol";
3
4
  //#region src/d1Executor.d.ts
4
5
  declare class D1ExecutionError extends Error {
5
6
  readonly name = "D1ExecutionError";
@@ -51,9 +52,19 @@ type BundleEventFailure = DatabaseJsonObject & {
51
52
  readonly transport?: "timeout" | "dns" | "tls" | "connection" | "offline" | "cancelled" | "unknown";
52
53
  /** The storage origin's error code, such as `ExpiredToken`. */
53
54
  readonly origin_code?: string;
55
+ readonly error_message?: string;
56
+ readonly error_stack?: string;
54
57
  /** Android's `ApplicationExitInfo` reason for the process before this one. */
55
58
  readonly previous_process_exit?: string;
56
59
  };
60
+ type DatabaseHttpResponse = DatabaseJsonObject & {
61
+ readonly resource: "catalog" | "artifact";
62
+ readonly path: string;
63
+ readonly status: number;
64
+ readonly body: string | null;
65
+ readonly body_truncated: boolean;
66
+ readonly received_at_ms: number;
67
+ };
57
68
  /** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
58
69
  type DatabaseBundleEventMetadata = DatabaseJsonObject & {
59
70
  readonly cohort: string;
@@ -62,6 +73,7 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
62
73
  readonly sdk_version: string | null;
63
74
  /** `UPDATE_FAILED`: what failed. */
64
75
  readonly failure?: BundleEventFailure;
76
+ readonly http_response?: DatabaseHttpResponse;
65
77
  /** `UPDATE_DOWNLOADED`: how the bundle arrived. */
66
78
  readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
67
79
  /** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { DatabaseJsonObject, Platform, StorageAdapterWith, ToolingDatabase } from "@hot-updater/plugin-core";
2
2
  import { S3ClientConfig } from "@aws-sdk/client-s3";
3
+ import "@hot-updater/protocol";
3
4
  //#region src/d1Executor.d.ts
4
5
  declare class D1ExecutionError extends Error {
5
6
  readonly name = "D1ExecutionError";
@@ -51,9 +52,19 @@ type BundleEventFailure = DatabaseJsonObject & {
51
52
  readonly transport?: "timeout" | "dns" | "tls" | "connection" | "offline" | "cancelled" | "unknown";
52
53
  /** The storage origin's error code, such as `ExpiredToken`. */
53
54
  readonly origin_code?: string;
55
+ readonly error_message?: string;
56
+ readonly error_stack?: string;
54
57
  /** Android's `ApplicationExitInfo` reason for the process before this one. */
55
58
  readonly previous_process_exit?: string;
56
59
  };
60
+ type DatabaseHttpResponse = DatabaseJsonObject & {
61
+ readonly resource: "catalog" | "artifact";
62
+ readonly path: string;
63
+ readonly status: number;
64
+ readonly body: string | null;
65
+ readonly body_truncated: boolean;
66
+ readonly received_at_ms: number;
67
+ };
57
68
  /** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
58
69
  type DatabaseBundleEventMetadata = DatabaseJsonObject & {
59
70
  readonly cohort: string;
@@ -62,6 +73,7 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
62
73
  readonly sdk_version: string | null;
63
74
  /** `UPDATE_FAILED`: what failed. */
64
75
  readonly failure?: BundleEventFailure;
76
+ readonly http_response?: DatabaseHttpResponse;
65
77
  /** `UPDATE_DOWNLOADED`: how the bundle arrived. */
66
78
  readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
67
79
  /** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
@@ -1,4 +1,5 @@
1
1
  import { DatabaseJsonObject, EngineDatabase, Platform, StorageAdapterWith } from "@hot-updater/plugin-core";
2
+ import "@hot-updater/protocol";
2
3
  //#region src/d1Executor.d.ts
3
4
  /** A D1 result, from the binding or the REST API. */
4
5
  interface D1ResultLike {
@@ -39,9 +40,19 @@ type BundleEventFailure = DatabaseJsonObject & {
39
40
  readonly transport?: "timeout" | "dns" | "tls" | "connection" | "offline" | "cancelled" | "unknown";
40
41
  /** The storage origin's error code, such as `ExpiredToken`. */
41
42
  readonly origin_code?: string;
43
+ readonly error_message?: string;
44
+ readonly error_stack?: string;
42
45
  /** Android's `ApplicationExitInfo` reason for the process before this one. */
43
46
  readonly previous_process_exit?: string;
44
47
  };
48
+ type DatabaseHttpResponse = DatabaseJsonObject & {
49
+ readonly resource: "catalog" | "artifact";
50
+ readonly path: string;
51
+ readonly status: number;
52
+ readonly body: string | null;
53
+ readonly body_truncated: boolean;
54
+ readonly received_at_ms: number;
55
+ };
45
56
  /** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
46
57
  type DatabaseBundleEventMetadata = DatabaseJsonObject & {
47
58
  readonly cohort: string;
@@ -50,6 +61,7 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
50
61
  readonly sdk_version: string | null;
51
62
  /** `UPDATE_FAILED`: what failed. */
52
63
  readonly failure?: BundleEventFailure;
64
+ readonly http_response?: DatabaseHttpResponse;
53
65
  /** `UPDATE_DOWNLOADED`: how the bundle arrived. */
54
66
  readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
55
67
  /** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
@@ -1,4 +1,5 @@
1
1
  import { DatabaseJsonObject, EngineDatabase, Platform, StorageAdapterWith } from "@hot-updater/plugin-core";
2
+ import "@hot-updater/protocol";
2
3
  //#region src/d1Executor.d.ts
3
4
  /** A D1 result, from the binding or the REST API. */
4
5
  interface D1ResultLike {
@@ -39,9 +40,19 @@ type BundleEventFailure = DatabaseJsonObject & {
39
40
  readonly transport?: "timeout" | "dns" | "tls" | "connection" | "offline" | "cancelled" | "unknown";
40
41
  /** The storage origin's error code, such as `ExpiredToken`. */
41
42
  readonly origin_code?: string;
43
+ readonly error_message?: string;
44
+ readonly error_stack?: string;
42
45
  /** Android's `ApplicationExitInfo` reason for the process before this one. */
43
46
  readonly previous_process_exit?: string;
44
47
  };
48
+ type DatabaseHttpResponse = DatabaseJsonObject & {
49
+ readonly resource: "catalog" | "artifact";
50
+ readonly path: string;
51
+ readonly status: number;
52
+ readonly body: string | null;
53
+ readonly body_truncated: boolean;
54
+ readonly received_at_ms: number;
55
+ };
45
56
  /** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
46
57
  type DatabaseBundleEventMetadata = DatabaseJsonObject & {
47
58
  readonly cohort: string;
@@ -50,6 +61,7 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
50
61
  readonly sdk_version: string | null;
51
62
  /** `UPDATE_FAILED`: what failed. */
52
63
  readonly failure?: BundleEventFailure;
64
+ readonly http_response?: DatabaseHttpResponse;
53
65
  /** `UPDATE_DOWNLOADED`: how the bundle arrived. */
54
66
  readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
55
67
  /** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hot-updater/cloudflare",
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",
@@ -56,10 +56,10 @@
56
56
  "cloudflare": "4.2.0",
57
57
  "hono": "4.12.34",
58
58
  "uuidv7": "^1.0.2",
59
- "@hot-updater/cli-tools": "1.0.0-rc.27",
60
- "@hot-updater/protocol": "1.0.0-rc.27",
61
- "@hot-updater/server": "1.0.0-rc.27",
62
- "@hot-updater/plugin-core": "1.0.0-rc.27"
59
+ "@hot-updater/cli-tools": "1.0.0-rc.29",
60
+ "@hot-updater/protocol": "1.0.0-rc.28",
61
+ "@hot-updater/server": "1.0.0-rc.29",
62
+ "@hot-updater/plugin-core": "1.0.0-rc.28"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@cloudflare/vitest-pool-workers": "0.13.0",
@@ -75,7 +75,7 @@
75
75
  "vitest": "4.1.4",
76
76
  "wrangler": "^4.69.0",
77
77
  "xdg-app-paths": "^8.3.0",
78
- "@hot-updater/test-utils": "1.0.0-rc.27"
78
+ "@hot-updater/test-utils": "1.0.0-rc.28"
79
79
  },
80
80
  "scripts": {
81
81
  "build": "tsdown && pnpm build:worker",
@@ -1 +1 @@
1
- This folder contains the built output assets for the worker "hot-updater" generated at 2026-10-03T03:46:48.935Z.
1
+ This folder contains the built output assets for the worker "hot-updater" generated at 2026-10-03T08:14:41.223Z.
@@ -4511,7 +4511,7 @@ var createSqlAdapter = /* @__PURE__ */ __name(({ executor, tablePrefix = "", max
4511
4511
  }, "createSqlAdapter");
4512
4512
 
4513
4513
  // ../../packages/server/dist/package.mjs
4514
- var version = "1.0.0-rc.27";
4514
+ var version = "1.0.0-rc.29";
4515
4515
 
4516
4516
  // ../../packages/server/dist/version.mjs
4517
4517
  var HOT_UPDATER_SERVER_VERSION = version;
@@ -9555,8 +9555,9 @@ var apiKeys = /* @__PURE__ */ __name((options = {}) => {
9555
9555
  // ../insights/dist/server/eventRow.mjs
9556
9556
  var isOptional = /* @__PURE__ */ __name((value, key, valid) => !Object.hasOwn(value, key) || valid(value[key]), "isOptional");
9557
9557
  var isString = /* @__PURE__ */ __name((value) => typeof value === "string", "isString");
9558
- var isDatabaseBundleEventFailure = /* @__PURE__ */ __name((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), "isDatabaseBundleEventFailure");
9559
- var isDatabaseBundleEventMetadata = /* @__PURE__ */ __name((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), "isDatabaseBundleEventMetadata");
9558
+ var isDatabaseHttpResponse = /* @__PURE__ */ __name((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), "isDatabaseHttpResponse");
9559
+ var isDatabaseBundleEventFailure = /* @__PURE__ */ __name((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), "isDatabaseBundleEventFailure");
9560
+ var isDatabaseBundleEventMetadata = /* @__PURE__ */ __name((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), "isDatabaseBundleEventMetadata");
9560
9561
  var isRecord5 = /* @__PURE__ */ __name((value) => typeof value === "object" && value !== null && !Array.isArray(value), "isRecord");
9561
9562
  var isIdentity = /* @__PURE__ */ __name((value) => typeof value === "string" && value.length > 0 && value.length <= 255, "isIdentity");
9562
9563
  var isTextOrNull2 = /* @__PURE__ */ __name((value) => value === null || typeof value === "string", "isTextOrNull");
@@ -9876,6 +9877,8 @@ function readFailure(value) {
9876
9877
  const failure = isRecord6(value) ? value : {};
9877
9878
  const httpStatus = failure.httpStatus;
9878
9879
  const originCode = readCode(failure.originCode);
9880
+ const errorMessage = typeof failure.errorMessage === "string" && failure.errorMessage.length <= 2048 ? failure.errorMessage : void 0;
9881
+ const errorStack = typeof failure.errorStack === "string" && failure.errorStack.length <= 4096 ? failure.errorStack : void 0;
9879
9882
  const previousProcessExit = readCode(failure.previousProcessExit);
9880
9883
  return {
9881
9884
  stage: oneOf(STAGES, failure.stage),
@@ -9884,10 +9887,24 @@ function readFailure(value) {
9884
9887
  ...Number.isSafeInteger(httpStatus) && httpStatus >= 100 && httpStatus <= 599 ? { httpStatus } : {},
9885
9888
  ...failure.transport == null ? {} : { transport: oneOf(TRANSPORTS, failure.transport) },
9886
9889
  ...originCode === void 0 ? {} : { originCode },
9890
+ ...errorMessage === void 0 ? {} : { errorMessage },
9891
+ ...errorStack === void 0 ? {} : { errorStack },
9887
9892
  ...previousProcessExit === void 0 ? {} : { previousProcessExit }
9888
9893
  };
9889
9894
  }
9890
9895
  __name(readFailure, "readFailure");
9896
+ function readHttpResponse(value) {
9897
+ if (!isRecord6(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");
9898
+ return {
9899
+ resource: value.resource,
9900
+ path: value.path,
9901
+ status: value.status,
9902
+ body: value.body,
9903
+ bodyTruncated: value.bodyTruncated,
9904
+ receivedAtMs: value.receivedAtMs
9905
+ };
9906
+ }
9907
+ __name(readHttpResponse, "readHttpResponse");
9891
9908
  async function readBoundedText(request) {
9892
9909
  const contentLength = request.headers.get("content-length");
9893
9910
  const declaredByteLength = Number(contentLength);
@@ -9925,7 +9942,10 @@ function requireEvent(payload) {
9925
9942
  const platform = requireStringField(payload, "platform");
9926
9943
  if (platform !== "ios" && platform !== "android") throw new InsightsBadRequestError("Invalid event field: platform");
9927
9944
  const eventId = readEventId(payload);
9945
+ const metadata = readMetadata(payload);
9946
+ const httpMetadata = metadata.httpResponse === void 0 ? {} : { httpResponse: readHttpResponse(metadata.httpResponse) };
9928
9947
  const base = {
9948
+ ...metadata.httpResponse === void 0 ? {} : { metadata: httpMetadata },
9929
9949
  ...eventId === void 0 ? {} : { eventId },
9930
9950
  installId: requireIdentityField(payload, "installId"),
9931
9951
  toBundleId: requireStringField(payload, "toBundleId"),
@@ -9949,11 +9969,11 @@ function requireEvent(payload) {
9949
9969
  updateStrategy
9950
9970
  };
9951
9971
  }, "movement");
9952
- const metadata = readMetadata(payload);
9953
9972
  switch (type) {
9954
9973
  case "UPDATE_DOWNLOADED": {
9955
9974
  const delivery = metadata.delivery;
9956
9975
  const read = {
9976
+ ...httpMetadata,
9957
9977
  ...delivery == null ? {} : { delivery: oneOf(DELIVERIES, delivery) },
9958
9978
  ...metadata.patchFallback === true ? { patchFallback: true } : {}
9959
9979
  };
@@ -9973,14 +9993,20 @@ function requireEvent(payload) {
9973
9993
  return {
9974
9994
  ...movement(),
9975
9995
  type,
9976
- ...previousProcessExit === void 0 ? {} : { metadata: { previousProcessExit } }
9996
+ ...previousProcessExit === void 0 ? {} : { metadata: {
9997
+ ...httpMetadata,
9998
+ previousProcessExit
9999
+ } }
9977
10000
  };
9978
10001
  }
9979
10002
  case "UPDATE_FAILED":
9980
10003
  return {
9981
10004
  ...movement(),
9982
10005
  type,
9983
- metadata: { failure: readFailure(metadata.failure) }
10006
+ metadata: {
10007
+ ...httpMetadata,
10008
+ failure: readFailure(metadata.failure)
10009
+ }
9984
10010
  };
9985
10011
  case "UNCHANGED":
9986
10012
  if (payload.fromBundleId !== null || payload.updateStrategy !== null) throw new InsightsBadRequestError("Invalid unchanged event shape");
@@ -10013,7 +10039,16 @@ function createBundleEventRow(input) {
10013
10039
  to_release_id: input.toReleaseId,
10014
10040
  user_id: input.userId ?? null
10015
10041
  };
10042
+ const response = input.metadata?.httpResponse;
10016
10043
  const metadata = {
10044
+ ...response ? { http_response: {
10045
+ resource: response.resource,
10046
+ path: response.path,
10047
+ status: response.status,
10048
+ body: response.body,
10049
+ body_truncated: response.bodyTruncated,
10050
+ received_at_ms: response.receivedAtMs
10051
+ } } : {},
10017
10052
  cohort: input.cohort,
10018
10053
  fingerprint_hash: input.fingerprintHash,
10019
10054
  sdk_version: input.sdkVersion ?? null,
@@ -10063,6 +10098,8 @@ function createBundleEventRow(input) {
10063
10098
  failure: {
10064
10099
  stage: failure.stage,
10065
10100
  reason: failure.reason,
10101
+ ...failure.errorMessage === void 0 ? {} : { error_message: failure.errorMessage },
10102
+ ...failure.errorStack === void 0 ? {} : { error_stack: failure.errorStack },
10066
10103
  ...failure.resource === void 0 ? {} : { resource: failure.resource },
10067
10104
  ...failure.httpStatus === void 0 ? {} : { http_status: failure.httpStatus },
10068
10105
  ...failure.transport === void 0 ? {} : { transport: failure.transport },
@@ -10228,6 +10265,8 @@ var assertEventRows = /* @__PURE__ */ __name((rows, input) => {
10228
10265
  var toFailure = /* @__PURE__ */ __name((failure) => ({
10229
10266
  stage: failure.stage,
10230
10267
  reason: failure.reason,
10268
+ ...failure.error_message === void 0 ? {} : { errorMessage: failure.error_message },
10269
+ ...failure.error_stack === void 0 ? {} : { errorStack: failure.error_stack },
10231
10270
  ...failure.resource === void 0 ? {} : { resource: failure.resource },
10232
10271
  ...failure.http_status === void 0 ? {} : { httpStatus: failure.http_status },
10233
10272
  ...failure.transport === void 0 ? {} : { transport: failure.transport },
@@ -10235,12 +10274,22 @@ var toFailure = /* @__PURE__ */ __name((failure) => ({
10235
10274
  ...failure.previous_process_exit === void 0 ? {} : { previousProcessExit: failure.previous_process_exit }
10236
10275
  }), "toFailure");
10237
10276
  var eventDetails = /* @__PURE__ */ __name(({ type, metadata }) => ({
10277
+ ...metadata.http_response !== void 0 ? { httpResponse: {
10278
+ resource: metadata.http_response.resource,
10279
+ path: metadata.http_response.path,
10280
+ status: metadata.http_response.status,
10281
+ body: metadata.http_response.body,
10282
+ bodyTruncated: metadata.http_response.body_truncated,
10283
+ receivedAtMs: metadata.http_response.received_at_ms
10284
+ } } : {},
10238
10285
  ...type === "UPDATE_FAILED" && metadata.failure !== void 0 ? { failure: toFailure(metadata.failure) } : {},
10239
10286
  ...type === "UPDATE_DOWNLOADED" && metadata.delivery !== void 0 ? { delivery: metadata.delivery } : {},
10240
10287
  ...type === "UPDATE_DOWNLOADED" && metadata.patch_fallback === true ? { patchFallback: true } : {},
10241
10288
  ...type === "RECOVERED" && metadata.previous_process_exit !== void 0 ? { previousProcessExit: metadata.previous_process_exit } : {}
10242
10289
  }), "eventDetails");
10243
10290
  var toEventHistoryRow = /* @__PURE__ */ __name((row) => ({
10291
+ ...row.to_release_id == null ? {} : { toReleaseId: row.to_release_id },
10292
+ ...row.metadata.sdk_version == null ? {} : { sdkVersion: row.metadata.sdk_version },
10244
10293
  appVersion: row.app_version,
10245
10294
  channel: row.channel,
10246
10295
  cohort: row.metadata.cohort,
@@ -10255,6 +10304,7 @@ var toEventHistoryRow = /* @__PURE__ */ __name((row) => ({
10255
10304
  ...eventDetails(row)
10256
10305
  }), "toEventHistoryRow");
10257
10306
  var toInstallationRow = /* @__PURE__ */ __name((row) => ({
10307
+ ...eventDetails(row).httpResponse ? { httpResponse: eventDetails(row).httpResponse } : {},
10258
10308
  appVersion: row.app_version,
10259
10309
  channel: row.channel,
10260
10310
  cohort: row.metadata.cohort,