@hot-updater/plugin-core 1.0.0-rc.0 → 1.0.0-rc.14

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.
Files changed (142) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +1 -1
  2. package/dist/assetStorageLayout.cjs +4 -2
  3. package/dist/assetStorageLayout.d.cts +5 -24
  4. package/dist/assetStorageLayout.d.mts +5 -24
  5. package/dist/assetStorageLayout.mjs +4 -2
  6. package/dist/calculatePagination.d.cts +0 -1
  7. package/dist/calculatePagination.d.mts +0 -1
  8. package/dist/compressionFormat.cjs +12 -5
  9. package/dist/compressionFormat.d.cts +1 -1
  10. package/dist/compressionFormat.d.mts +1 -1
  11. package/dist/compressionFormat.mjs +11 -4
  12. package/dist/contentAddressedAssets.d.cts +1 -4
  13. package/dist/contentAddressedAssets.d.mts +1 -4
  14. package/dist/createDatabasePlugin.cjs +116 -42
  15. package/dist/createDatabasePlugin.d.cts +3 -1
  16. package/dist/createDatabasePlugin.d.mts +3 -1
  17. package/dist/createDatabasePlugin.mjs +116 -43
  18. package/dist/createStoragePlugin.d.cts +0 -1
  19. package/dist/createStoragePlugin.d.mts +0 -1
  20. package/dist/databaseClient.cjs +6 -1
  21. package/dist/databaseClient.d.cts +1 -2
  22. package/dist/databaseClient.d.mts +1 -2
  23. package/dist/databaseClient.mjs +6 -2
  24. package/dist/databaseClientReads.cjs +3 -1
  25. package/dist/databaseClientReads.mjs +3 -2
  26. package/dist/databaseClientUpdates.cjs +2 -1
  27. package/dist/databaseClientUpdates.d.cts +1 -1
  28. package/dist/databaseClientUpdates.d.mts +1 -1
  29. package/dist/databaseClientUpdates.mjs +2 -0
  30. package/dist/databaseJsonValue.cjs +4 -0
  31. package/dist/databaseJsonValue.d.cts +4 -2
  32. package/dist/databaseJsonValue.d.mts +4 -2
  33. package/dist/databaseJsonValue.mjs +2 -1
  34. package/dist/databaseMetadata.cjs +0 -1
  35. package/dist/databasePluginCrud.cjs +1 -0
  36. package/dist/databasePluginCrud.d.cts +4 -1
  37. package/dist/databasePluginCrud.d.mts +4 -1
  38. package/dist/databasePluginCrud.mjs +1 -1
  39. package/dist/databasePluginCrudValidation.d.cts +6 -1
  40. package/dist/databasePluginCrudValidation.d.mts +6 -1
  41. package/dist/databasePluginCrudValidationErrors.cjs +1 -0
  42. package/dist/databasePluginCrudValidationErrors.mjs +1 -0
  43. package/dist/databasePluginCrudValidationFields.cjs +21 -19
  44. package/dist/databasePluginCrudValidationFields.d.cts +1 -1
  45. package/dist/databasePluginCrudValidationFields.d.mts +1 -1
  46. package/dist/databasePluginCrudValidationFields.mjs +20 -20
  47. package/dist/databasePluginCrudValidationMutations.cjs +1 -1
  48. package/dist/databasePluginCrudValidationMutations.d.cts +1 -1
  49. package/dist/databasePluginCrudValidationMutations.d.mts +1 -1
  50. package/dist/databasePluginCrudValidationMutations.mjs +1 -1
  51. package/dist/databasePluginCrudValidationQueries.d.cts +2 -1
  52. package/dist/databasePluginCrudValidationQueries.d.mts +2 -1
  53. package/dist/databasePluginCrudValidationRows.cjs +2 -2
  54. package/dist/databasePluginCrudValidationRows.d.cts +1 -1
  55. package/dist/databasePluginCrudValidationRows.d.mts +1 -1
  56. package/dist/databasePluginCrudValidationRows.mjs +2 -2
  57. package/dist/databaseRows.cjs +0 -1
  58. package/dist/databaseRows.d.cts +2 -6
  59. package/dist/databaseRows.d.mts +2 -6
  60. package/dist/index.cjs +4 -1
  61. package/dist/index.d.cts +5 -4
  62. package/dist/index.d.mts +5 -4
  63. package/dist/index.mjs +3 -2
  64. package/dist/insightsContract.cjs +146 -0
  65. package/dist/insightsContract.d.cts +9 -0
  66. package/dist/insightsContract.d.mts +9 -0
  67. package/dist/insightsContract.mjs +143 -0
  68. package/dist/insightsLatestQueries.cjs +53 -0
  69. package/dist/insightsLatestQueries.d.cts +13 -0
  70. package/dist/insightsLatestQueries.d.mts +13 -0
  71. package/dist/insightsLatestQueries.mjs +52 -0
  72. package/dist/internal.cjs +3 -0
  73. package/dist/internal.d.cts +5 -3
  74. package/dist/internal.d.mts +5 -3
  75. package/dist/internal.mjs +2 -1
  76. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.cjs +136 -0
  77. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/comparison-DenM3wCn.mjs +116 -0
  78. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.cjs +167 -0
  79. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/range-DvX-Y6iv.mjs +165 -0
  80. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/set-CC5YeoYX.cjs +42 -0
  81. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/set-CC5YeoYX.mjs +39 -0
  82. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.cjs +39 -0
  83. package/dist/node_modules/.pnpm/verkit@0.4.0/node_modules/verkit/dist/version-CQ98ZBpL.mjs +37 -0
  84. package/dist/paginateBundles.d.cts +1 -8
  85. package/dist/paginateBundles.d.mts +1 -8
  86. package/dist/parseStorageUri.d.cts +1 -5
  87. package/dist/parseStorageUri.d.mts +1 -5
  88. package/dist/queryBundles.d.cts +0 -1
  89. package/dist/queryBundles.d.mts +0 -1
  90. package/dist/releaseCatalogCompiler.cjs +15 -12
  91. package/dist/releaseCatalogCompiler.d.cts +0 -1
  92. package/dist/releaseCatalogCompiler.d.mts +0 -1
  93. package/dist/releaseCatalogCompiler.mjs +11 -7
  94. package/dist/releaseCatalogMutation.cjs +1 -1
  95. package/dist/releaseCatalogMutation.d.cts +1 -1
  96. package/dist/releaseCatalogMutation.d.mts +1 -1
  97. package/dist/releaseCatalogMutation.mjs +1 -0
  98. package/dist/releaseManagement.cjs +3 -2
  99. package/dist/releaseManagement.d.cts +1 -1
  100. package/dist/releaseManagement.d.mts +1 -1
  101. package/dist/releaseManagement.mjs +3 -1
  102. package/dist/remoteBundleSigning.cjs +5 -7
  103. package/dist/remoteBundleSigning.d.cts +2 -15
  104. package/dist/remoteBundleSigning.d.mts +2 -15
  105. package/dist/remoteBundleSigning.mjs +5 -7
  106. package/dist/requestBundleCache.d.cts +1 -2
  107. package/dist/requestBundleCache.d.mts +1 -2
  108. package/dist/semverSatisfies.cjs +4 -3
  109. package/dist/semverSatisfies.mjs +2 -1
  110. package/dist/storageDownloadPath.cjs +2 -1
  111. package/dist/storageDownloadPath.d.cts +1 -3
  112. package/dist/storageDownloadPath.d.mts +1 -3
  113. package/dist/storageDownloadPath.mjs +2 -1
  114. package/dist/types/database.d.cts +4 -3
  115. package/dist/types/database.d.mts +4 -3
  116. package/dist/types/databaseFields.cjs +1 -5
  117. package/dist/types/databaseFields.d.cts +1 -1
  118. package/dist/types/databaseFields.d.mts +1 -1
  119. package/dist/types/databaseFields.mjs +1 -5
  120. package/dist/types/databaseOperations.d.cts +15 -12
  121. package/dist/types/databaseOperations.d.mts +15 -12
  122. package/dist/types/databasePlugin.d.cts +77 -13
  123. package/dist/types/databasePlugin.d.mts +77 -13
  124. package/dist/types/databaseQuery.d.cts +2 -3
  125. package/dist/types/databaseQuery.d.mts +2 -3
  126. package/dist/types/databaseRows.d.cts +16 -11
  127. package/dist/types/databaseRows.d.mts +16 -11
  128. package/dist/types/index.d.cts +15 -11
  129. package/dist/types/index.d.mts +15 -11
  130. package/dist/types/internal.d.cts +4 -3
  131. package/dist/types/internal.d.mts +4 -3
  132. package/dist/types/public.d.cts +4 -3
  133. package/dist/types/public.d.mts +4 -3
  134. package/dist/types/utils.d.cts +1 -1
  135. package/dist/types/utils.d.mts +1 -1
  136. package/dist/uuidv7.cjs +7 -2
  137. package/dist/uuidv7.d.cts +0 -1
  138. package/dist/uuidv7.d.mts +0 -1
  139. package/dist/uuidv7.mjs +1 -1
  140. package/package.json +4 -4
  141. package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.cjs +0 -345
  142. package/dist/node_modules/.pnpm/verkit@0.3.2/node_modules/verkit/dist/index.mjs +0 -341
@@ -1,7 +1,6 @@
1
1
  import { ApiKeyRow, BundleRow, DatabaseModel, DatabaseRow, ReleaseCatalogRow, ReleaseRow } from "./databaseRows.mjs";
2
- import { ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, DatabaseCommit, DatabaseCommitResult } from "./databasePlugin.mjs";
2
+ import { ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, DatabaseCommit, DatabaseCommitResult, InsightsModel, InsightsRecordEventInput } from "./databasePlugin.mjs";
3
3
  import { DatabaseDistinctFields, DatabaseDistinctOn, DatabaseOrderBy, DatabaseSelect, DatabaseWhere, SelectedDatabaseRow } from "./databaseQuery.mjs";
4
-
5
4
  //#region src/types/databaseOperations.d.ts
6
5
  type DatabaseCapability = "create" | "update" | "delete" | "count" | "findOne" | "findMany";
7
6
  type DatabaseModelCapabilities = {
@@ -49,7 +48,7 @@ type DatabaseModelCapabilities = {
49
48
  readonly create: true;
50
49
  readonly update: false;
51
50
  readonly delete: false;
52
- readonly count: false;
51
+ readonly count: true;
53
52
  readonly findOne: false;
54
53
  readonly findMany: true;
55
54
  };
@@ -62,7 +61,7 @@ type DatabaseModelCapabilities = {
62
61
  readonly findMany: true;
63
62
  };
64
63
  };
65
- type DatabaseModelsWithCapability<TCapability extends DatabaseCapability> = { readonly [TModel in DatabaseModel]: DatabaseModelCapabilities[TModel][TCapability] extends true ? TModel : never }[DatabaseModel];
64
+ type DatabaseModelsWithCapability<TCapability extends DatabaseCapability> = { readonly [TModel in DatabaseModel]: DatabaseModelCapabilities[TModel][TCapability] extends true ? TModel : never; }[DatabaseModel];
66
65
  type CreateDatabaseModel = DatabaseModelsWithCapability<"create">;
67
66
  type UpdateDatabaseModel = DatabaseModelsWithCapability<"update">;
68
67
  type DeleteDatabaseModel = DatabaseModelsWithCapability<"delete">;
@@ -135,19 +134,19 @@ interface DatabasePluginCrud {
135
134
  findOne<TInput extends FindOneDatabaseImplementationInput>(input: TInput): Promise<SelectedDatabaseInputRow<TInput> | null>;
136
135
  findMany<TInput extends FindManyDatabasePluginInput>(input: TInput): Promise<SelectedDatabaseInputRow<TInput>[]>;
137
136
  }
138
- type DatabaseImplementationResult = { readonly [TModel in DatabaseModel]: Partial<DatabaseRow<TModel>> }[DatabaseModel];
139
- type CreateDatabaseImplementationInput = { readonly [TModel in CreateDatabaseModel]: CreateDatabaseInput<TModel, DatabaseSelect<TModel> | undefined> }[CreateDatabaseModel];
140
- type UpdateDatabaseImplementationInput = { readonly [TModel in UpdateDatabaseModel]: UpdateDatabaseInput<TModel, DatabaseSelect<TModel> | undefined> }[UpdateDatabaseModel];
141
- type DeleteDatabaseImplementationInput = { readonly [TModel in DeleteDatabaseModel]: DeleteDatabaseInput<TModel> }[DeleteDatabaseModel];
142
- type CountDatabaseImplementationInput = { readonly [TModel in CountDatabaseModel]: CountDatabaseInput<TModel> }[CountDatabaseModel];
137
+ type DatabaseImplementationResult = { readonly [TModel in DatabaseModel]: Partial<DatabaseRow<TModel>>; }[DatabaseModel];
138
+ type CreateDatabaseImplementationInput = { readonly [TModel in CreateDatabaseModel]: CreateDatabaseInput<TModel, DatabaseSelect<TModel> | undefined>; }[CreateDatabaseModel];
139
+ type UpdateDatabaseImplementationInput = { readonly [TModel in UpdateDatabaseModel]: UpdateDatabaseInput<TModel, DatabaseSelect<TModel> | undefined>; }[UpdateDatabaseModel];
140
+ type DeleteDatabaseImplementationInput = { readonly [TModel in DeleteDatabaseModel]: DeleteDatabaseInput<TModel>; }[DeleteDatabaseModel];
141
+ type CountDatabaseImplementationInput = { readonly [TModel in CountDatabaseModel]: CountDatabaseInput<TModel>; }[CountDatabaseModel];
143
142
  type UpdateBundleDatabaseImplementationInput = UpdateDatabaseInput<"bundles", DatabaseSelect<"bundles"> | undefined>;
144
143
  type CountBundlesDatabaseImplementationInput = CountDatabaseInput<"bundles">;
145
- type FindOneDatabaseImplementationInput = { readonly [TModel in FindOneDatabaseModel]: FindOneDatabaseInput<TModel, DatabaseSelect<TModel> | undefined> }[FindOneDatabaseModel];
144
+ type FindOneDatabaseImplementationInput = { readonly [TModel in FindOneDatabaseModel]: FindOneDatabaseInput<TModel, DatabaseSelect<TModel> | undefined>; }[FindOneDatabaseModel];
146
145
  type FindManyDatabaseImplementationInput = { readonly [TModel in FindManyDatabaseModel]: Omit<FindManyDatabaseInput<TModel, DatabaseSelect<TModel> | undefined>, "limit" | "offset"> & {
147
146
  readonly limit: number;
148
147
  readonly offset: number;
149
- } }[FindManyDatabaseModel];
150
- type FindManyDatabasePluginInput = { readonly [TModel in FindManyDatabaseModel]: FindManyDatabaseInput<TModel, DatabaseSelect<TModel> | undefined> }[FindManyDatabaseModel];
148
+ }; }[FindManyDatabaseModel];
149
+ type FindManyDatabasePluginInput = { readonly [TModel in FindManyDatabaseModel]: FindManyDatabaseInput<TModel, DatabaseSelect<TModel> | undefined>; }[FindManyDatabaseModel];
151
150
  interface TransactionDatabasePluginImplementation {
152
151
  create(input: CreateDatabaseImplementationInput): Promise<DatabaseImplementationResult>;
153
152
  update(input: UpdateDatabaseImplementationInput): Promise<DatabaseImplementationResult | null>;
@@ -157,6 +156,10 @@ interface TransactionDatabasePluginImplementation {
157
156
  findMany(input: FindManyDatabaseImplementationInput): Promise<readonly DatabaseImplementationResult[]>;
158
157
  }
159
158
  interface DatabasePluginImplementation {
159
+ findLatestInsightsEvents: InsightsModel["findLatestEvents"];
160
+ countLatestInsightsEvents: InsightsModel["countLatestEvents"];
161
+ /** Native immutable event insert; any private index is advanced atomically. */
162
+ recordInsights(input: InsightsRecordEventInput): Promise<void>;
160
163
  create(input: CreateDatabaseImplementationInput): Promise<DatabaseImplementationResult>;
161
164
  update(input: UpdateDatabaseImplementationInput): Promise<DatabaseImplementationResult | null>;
162
165
  delete(input: DeleteDatabaseImplementationInput): Promise<void>;
@@ -1,7 +1,6 @@
1
1
  import { ApiKeyRow, BundleEventRow, BundlePatchRow, BundleRow, ChannelRow, ReleaseCatalogRow, ReleaseRow } from "./databaseRows.cjs";
2
2
  import { BundleRowUpdate, ReleaseRowUpdate } from "./databaseOperations.cjs";
3
3
  import { DatabaseBundleQueryOrder, DatabaseBundleQueryWhere } from "./index.cjs";
4
-
5
4
  //#region src/types/databasePlugin.d.ts
6
5
  interface BundleModelQuery {
7
6
  readonly where?: DatabaseBundleQueryWhere;
@@ -43,18 +42,87 @@ interface ReleaseCatalogModel {
43
42
  readonly limit: number;
44
43
  }): Promise<readonly ReleaseCatalogRow[]>;
45
44
  }
46
- interface AnalyticsScanCursor {
45
+ interface InsightsEventCursor {
47
46
  readonly receivedAtMs: number;
48
47
  readonly id: string;
49
48
  }
50
- interface AnalyticsScanInput {
49
+ interface InsightsScope {
50
+ readonly platform: "ios" | "android";
51
+ readonly channel: string;
52
+ }
53
+ /** Raw event predicates; recovery is attributed to the source bundle. */
54
+ type InsightsBundleEventFilter = InsightsScope & ({
55
+ readonly type: "RECOVERED";
56
+ readonly fromBundleId: string;
57
+ } | {
58
+ readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "UNCHANGED";
59
+ readonly toBundleId: string;
60
+ });
61
+ type InsightsEventFilter = {
62
+ readonly kind: "all";
63
+ } | {
64
+ readonly kind: "installationMovement";
65
+ readonly installId: string;
66
+ } | ({
67
+ readonly kind: "bundle";
68
+ } & InsightsBundleEventFilter);
69
+ interface InsightsRecordEventInput {
70
+ readonly event: BundleEventRow;
71
+ }
72
+ interface InsightsListEventsInput {
73
+ readonly filter: InsightsEventFilter;
74
+ readonly sinceMs?: number;
51
75
  readonly beforeReceivedAtMs: number;
52
- readonly after?: AnalyticsScanCursor;
76
+ readonly after?: InsightsEventCursor;
77
+ readonly limit: number;
78
+ }
79
+ type InsightsFindLatestEventsInput = {
80
+ readonly installId: string;
81
+ } | {
82
+ readonly userId: string;
83
+ readonly afterInstallId?: string;
53
84
  readonly limit: number;
85
+ };
86
+ interface InsightsCountLatestEventsInput extends InsightsScope {
87
+ readonly sinceMs: number;
88
+ /** Optional OR of one or two fixed predicates; count a matching event once. */
89
+ readonly bundle?: readonly {
90
+ readonly field: "from_bundle_id" | "to_bundle_id";
91
+ readonly value: string;
92
+ readonly types: readonly BundleEventRow["type"][];
93
+ }[];
94
+ }
95
+ interface InsightsCountEventsInput {
96
+ readonly filter: InsightsBundleEventFilter;
97
+ readonly sinceMs: number;
98
+ readonly beforeReceivedAtMs: number;
54
99
  }
55
- interface AnalyticsModel {
56
- append(row: BundleEventRow): Promise<void>;
57
- scan(input: AnalyticsScanInput): Promise<readonly BundleEventRow[]>;
100
+ interface InsightsModel {
101
+ /**
102
+ * Persist the immutable event once. A private latest-event index, if used,
103
+ * advances atomically for a greater (received_at_ms, id). Duplicate event
104
+ * IDs are complete no-ops.
105
+ * Retry the identical prepared input after an ambiguous commit outcome.
106
+ */
107
+ recordEvent(input: InsightsRecordEventInput): Promise<void>;
108
+ /**
109
+ * Descending (received_at_ms, id), in [sinceMs ?? 0, beforeReceivedAtMs).
110
+ * Apply filters and the exclusive cursor before limit (1..101). Return the
111
+ * complete matching prefix; native continuation pages must not truncate it.
112
+ */
113
+ listEvents(input: InsightsListEventsInput): Promise<readonly BundleEventRow[]>;
114
+ /**
115
+ * Choose each installation's greatest (received_at_ms, id) before filtering.
116
+ * Exact installation lookup returns zero or one canonical event. User lookup
117
+ * returns current membership ordered by UTF-8 installation ID, exclusive
118
+ * afterInstallId and limit 1..101. Check lagging index candidates against
119
+ * canonical state; newly indexed associations may temporarily be absent.
120
+ */
121
+ findLatestEvents(input: InsightsFindLatestEventsInput): Promise<readonly BundleEventRow[]>;
122
+ /** Count latest events once per installation, then apply the supplied predicates. */
123
+ countLatestEvents(input: InsightsCountLatestEventsInput): Promise<number>;
124
+ /** Count accepted reports in [sinceMs, beforeReceivedAtMs), across all pages. */
125
+ countEvents(input: InsightsCountEventsInput): Promise<number>;
58
126
  }
59
127
  interface ApiKeyModel {
60
128
  create(row: ApiKeyRow): Promise<"created" | "existing">;
@@ -148,10 +216,6 @@ type DatabaseChange = {
148
216
  readonly where: {
149
217
  readonly id: string;
150
218
  };
151
- } | {
152
- readonly model: "analytics";
153
- readonly operation: "insert";
154
- readonly row: BundleEventRow;
155
219
  } | {
156
220
  readonly model: "apiKeys";
157
221
  readonly operation: "insert";
@@ -221,7 +285,7 @@ interface DatabaseModels {
221
285
  readonly releases: ReleaseModel;
222
286
  readonly releaseCatalogs: ReleaseCatalogModel;
223
287
  readonly channels: ChannelModel;
224
- readonly analytics: AnalyticsModel;
288
+ readonly insights: InsightsModel;
225
289
  readonly apiKeys: ApiKeyModel;
226
290
  }
227
291
  interface BundleRepository {
@@ -237,4 +301,4 @@ interface DatabasePlugin {
237
301
  dispose?: () => Promise<void>;
238
302
  }
239
303
  //#endregion
240
- export { AnalyticsModel, AnalyticsScanCursor, AnalyticsScanInput, ApiKeyModel, BundleModel, BundleModelQuery, BundlePatchModel, BundleRepository, BundleRepositoryChange, BundleRepositoryCommit, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelModel, DatabaseChange, DatabaseCommit, DatabaseCommitExpectation, DatabaseCommitResult, DatabaseModels, DatabasePlugin, ReleaseCatalogModel, ReleaseModel };
304
+ export { ApiKeyModel, BundleModel, BundleModelQuery, BundlePatchModel, BundleRepository, BundleRepositoryChange, BundleRepositoryCommit, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelModel, DatabaseChange, DatabaseCommit, DatabaseCommitExpectation, DatabaseCommitResult, DatabaseModels, DatabasePlugin, InsightsBundleEventFilter, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsEventCursor, InsightsEventFilter, InsightsFindLatestEventsInput, InsightsListEventsInput, InsightsModel, InsightsRecordEventInput, InsightsScope, ReleaseCatalogModel, ReleaseModel };
@@ -1,7 +1,6 @@
1
1
  import { ApiKeyRow, BundleEventRow, BundlePatchRow, BundleRow, ChannelRow, ReleaseCatalogRow, ReleaseRow } from "./databaseRows.mjs";
2
2
  import { BundleRowUpdate, ReleaseRowUpdate } from "./databaseOperations.mjs";
3
3
  import { DatabaseBundleQueryOrder, DatabaseBundleQueryWhere } from "./index.mjs";
4
-
5
4
  //#region src/types/databasePlugin.d.ts
6
5
  interface BundleModelQuery {
7
6
  readonly where?: DatabaseBundleQueryWhere;
@@ -43,18 +42,87 @@ interface ReleaseCatalogModel {
43
42
  readonly limit: number;
44
43
  }): Promise<readonly ReleaseCatalogRow[]>;
45
44
  }
46
- interface AnalyticsScanCursor {
45
+ interface InsightsEventCursor {
47
46
  readonly receivedAtMs: number;
48
47
  readonly id: string;
49
48
  }
50
- interface AnalyticsScanInput {
49
+ interface InsightsScope {
50
+ readonly platform: "ios" | "android";
51
+ readonly channel: string;
52
+ }
53
+ /** Raw event predicates; recovery is attributed to the source bundle. */
54
+ type InsightsBundleEventFilter = InsightsScope & ({
55
+ readonly type: "RECOVERED";
56
+ readonly fromBundleId: string;
57
+ } | {
58
+ readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "UNCHANGED";
59
+ readonly toBundleId: string;
60
+ });
61
+ type InsightsEventFilter = {
62
+ readonly kind: "all";
63
+ } | {
64
+ readonly kind: "installationMovement";
65
+ readonly installId: string;
66
+ } | ({
67
+ readonly kind: "bundle";
68
+ } & InsightsBundleEventFilter);
69
+ interface InsightsRecordEventInput {
70
+ readonly event: BundleEventRow;
71
+ }
72
+ interface InsightsListEventsInput {
73
+ readonly filter: InsightsEventFilter;
74
+ readonly sinceMs?: number;
51
75
  readonly beforeReceivedAtMs: number;
52
- readonly after?: AnalyticsScanCursor;
76
+ readonly after?: InsightsEventCursor;
77
+ readonly limit: number;
78
+ }
79
+ type InsightsFindLatestEventsInput = {
80
+ readonly installId: string;
81
+ } | {
82
+ readonly userId: string;
83
+ readonly afterInstallId?: string;
53
84
  readonly limit: number;
85
+ };
86
+ interface InsightsCountLatestEventsInput extends InsightsScope {
87
+ readonly sinceMs: number;
88
+ /** Optional OR of one or two fixed predicates; count a matching event once. */
89
+ readonly bundle?: readonly {
90
+ readonly field: "from_bundle_id" | "to_bundle_id";
91
+ readonly value: string;
92
+ readonly types: readonly BundleEventRow["type"][];
93
+ }[];
94
+ }
95
+ interface InsightsCountEventsInput {
96
+ readonly filter: InsightsBundleEventFilter;
97
+ readonly sinceMs: number;
98
+ readonly beforeReceivedAtMs: number;
54
99
  }
55
- interface AnalyticsModel {
56
- append(row: BundleEventRow): Promise<void>;
57
- scan(input: AnalyticsScanInput): Promise<readonly BundleEventRow[]>;
100
+ interface InsightsModel {
101
+ /**
102
+ * Persist the immutable event once. A private latest-event index, if used,
103
+ * advances atomically for a greater (received_at_ms, id). Duplicate event
104
+ * IDs are complete no-ops.
105
+ * Retry the identical prepared input after an ambiguous commit outcome.
106
+ */
107
+ recordEvent(input: InsightsRecordEventInput): Promise<void>;
108
+ /**
109
+ * Descending (received_at_ms, id), in [sinceMs ?? 0, beforeReceivedAtMs).
110
+ * Apply filters and the exclusive cursor before limit (1..101). Return the
111
+ * complete matching prefix; native continuation pages must not truncate it.
112
+ */
113
+ listEvents(input: InsightsListEventsInput): Promise<readonly BundleEventRow[]>;
114
+ /**
115
+ * Choose each installation's greatest (received_at_ms, id) before filtering.
116
+ * Exact installation lookup returns zero or one canonical event. User lookup
117
+ * returns current membership ordered by UTF-8 installation ID, exclusive
118
+ * afterInstallId and limit 1..101. Check lagging index candidates against
119
+ * canonical state; newly indexed associations may temporarily be absent.
120
+ */
121
+ findLatestEvents(input: InsightsFindLatestEventsInput): Promise<readonly BundleEventRow[]>;
122
+ /** Count latest events once per installation, then apply the supplied predicates. */
123
+ countLatestEvents(input: InsightsCountLatestEventsInput): Promise<number>;
124
+ /** Count accepted reports in [sinceMs, beforeReceivedAtMs), across all pages. */
125
+ countEvents(input: InsightsCountEventsInput): Promise<number>;
58
126
  }
59
127
  interface ApiKeyModel {
60
128
  create(row: ApiKeyRow): Promise<"created" | "existing">;
@@ -148,10 +216,6 @@ type DatabaseChange = {
148
216
  readonly where: {
149
217
  readonly id: string;
150
218
  };
151
- } | {
152
- readonly model: "analytics";
153
- readonly operation: "insert";
154
- readonly row: BundleEventRow;
155
219
  } | {
156
220
  readonly model: "apiKeys";
157
221
  readonly operation: "insert";
@@ -221,7 +285,7 @@ interface DatabaseModels {
221
285
  readonly releases: ReleaseModel;
222
286
  readonly releaseCatalogs: ReleaseCatalogModel;
223
287
  readonly channels: ChannelModel;
224
- readonly analytics: AnalyticsModel;
288
+ readonly insights: InsightsModel;
225
289
  readonly apiKeys: ApiKeyModel;
226
290
  }
227
291
  interface BundleRepository {
@@ -237,4 +301,4 @@ interface DatabasePlugin {
237
301
  dispose?: () => Promise<void>;
238
302
  }
239
303
  //#endregion
240
- export { AnalyticsModel, AnalyticsScanCursor, AnalyticsScanInput, ApiKeyModel, BundleModel, BundleModelQuery, BundlePatchModel, BundleRepository, BundleRepositoryChange, BundleRepositoryCommit, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelModel, DatabaseChange, DatabaseCommit, DatabaseCommitExpectation, DatabaseCommitResult, DatabaseModels, DatabasePlugin, ReleaseCatalogModel, ReleaseModel };
304
+ export { ApiKeyModel, BundleModel, BundleModelQuery, BundlePatchModel, BundleRepository, BundleRepositoryChange, BundleRepositoryCommit, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelModel, DatabaseChange, DatabaseCommit, DatabaseCommitExpectation, DatabaseCommitResult, DatabaseModels, DatabasePlugin, InsightsBundleEventFilter, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsEventCursor, InsightsEventFilter, InsightsFindLatestEventsInput, InsightsListEventsInput, InsightsModel, InsightsRecordEventInput, InsightsScope, ReleaseCatalogModel, ReleaseModel };
@@ -1,5 +1,4 @@
1
1
  import { DatabaseField, DatabaseModel, DatabaseRow } from "./databaseRows.cjs";
2
-
3
2
  //#region src/types/databaseQuery.d.ts
4
3
  type DatabaseWhereOperator = "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with";
5
4
  type DatabaseWhereConnector = "AND" | "OR";
@@ -28,10 +27,10 @@ type SetWhere<TField extends string, TValue extends boolean | number | string> =
28
27
  };
29
28
  type ScalarWhereValue<TValue> = unknown extends TValue ? never : Extract<TValue, readonly unknown[] | object> extends never ? Extract<TValue, boolean | number | string | null> : never;
30
29
  type FieldWhere<TField extends string, TValue> = ([ScalarWhereValue<TValue>] extends [never] ? never : EqualityWhere<TField, ScalarWhereValue<TValue>>) | (Extract<TValue, string> extends never ? never : StringWhere<TField>) | (Extract<TValue, number | string> extends never ? never : OrderedWhere<TField, Extract<TValue, number | string>>) | (Extract<TValue, boolean | number | string> extends never ? never : SetWhere<TField, Extract<TValue, boolean | number | string>>);
31
- type DatabaseWhere<TModel extends DatabaseModel> = { readonly [TField in DatabaseField<TModel>]: FieldWhere<TField, DatabaseRow<TModel>[TField]> }[DatabaseField<TModel>];
30
+ type DatabaseWhere<TModel extends DatabaseModel> = { readonly [TField in DatabaseField<TModel>]: FieldWhere<TField, DatabaseRow<TModel>[TField]>; }[DatabaseField<TModel>];
32
31
  type DatabaseSelect<TModel extends DatabaseModel> = readonly DatabaseField<TModel>[];
33
32
  type SelectedDatabaseRow<TModel extends DatabaseModel, TSelect extends DatabaseSelect<TModel> | undefined> = TSelect extends DatabaseSelect<TModel> ? Pick<DatabaseRow<TModel>, TSelect[number]> : DatabaseRow<TModel>;
34
- type DatabaseSortableField<TModel extends DatabaseModel> = { readonly [TField in DatabaseField<TModel>]: Exclude<DatabaseRow<TModel>[TField], null> extends number | string ? TField : never }[DatabaseField<TModel>];
33
+ type DatabaseSortableField<TModel extends DatabaseModel> = { readonly [TField in DatabaseField<TModel>]: Exclude<DatabaseRow<TModel>[TField], null> extends number | string ? TField : never; }[DatabaseField<TModel>];
35
34
  interface DatabaseSortClause<TModel extends DatabaseModel> {
36
35
  readonly field: DatabaseSortableField<TModel>;
37
36
  readonly direction: "asc" | "desc";
@@ -1,5 +1,4 @@
1
1
  import { DatabaseField, DatabaseModel, DatabaseRow } from "./databaseRows.mjs";
2
-
3
2
  //#region src/types/databaseQuery.d.ts
4
3
  type DatabaseWhereOperator = "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with";
5
4
  type DatabaseWhereConnector = "AND" | "OR";
@@ -28,10 +27,10 @@ type SetWhere<TField extends string, TValue extends boolean | number | string> =
28
27
  };
29
28
  type ScalarWhereValue<TValue> = unknown extends TValue ? never : Extract<TValue, readonly unknown[] | object> extends never ? Extract<TValue, boolean | number | string | null> : never;
30
29
  type FieldWhere<TField extends string, TValue> = ([ScalarWhereValue<TValue>] extends [never] ? never : EqualityWhere<TField, ScalarWhereValue<TValue>>) | (Extract<TValue, string> extends never ? never : StringWhere<TField>) | (Extract<TValue, number | string> extends never ? never : OrderedWhere<TField, Extract<TValue, number | string>>) | (Extract<TValue, boolean | number | string> extends never ? never : SetWhere<TField, Extract<TValue, boolean | number | string>>);
31
- type DatabaseWhere<TModel extends DatabaseModel> = { readonly [TField in DatabaseField<TModel>]: FieldWhere<TField, DatabaseRow<TModel>[TField]> }[DatabaseField<TModel>];
30
+ type DatabaseWhere<TModel extends DatabaseModel> = { readonly [TField in DatabaseField<TModel>]: FieldWhere<TField, DatabaseRow<TModel>[TField]>; }[DatabaseField<TModel>];
32
31
  type DatabaseSelect<TModel extends DatabaseModel> = readonly DatabaseField<TModel>[];
33
32
  type SelectedDatabaseRow<TModel extends DatabaseModel, TSelect extends DatabaseSelect<TModel> | undefined> = TSelect extends DatabaseSelect<TModel> ? Pick<DatabaseRow<TModel>, TSelect[number]> : DatabaseRow<TModel>;
34
- type DatabaseSortableField<TModel extends DatabaseModel> = { readonly [TField in DatabaseField<TModel>]: Exclude<DatabaseRow<TModel>[TField], null> extends number | string ? TField : never }[DatabaseField<TModel>];
33
+ type DatabaseSortableField<TModel extends DatabaseModel> = { readonly [TField in DatabaseField<TModel>]: Exclude<DatabaseRow<TModel>[TField], null> extends number | string ? TField : never; }[DatabaseField<TModel>];
35
34
  interface DatabaseSortClause<TModel extends DatabaseModel> {
36
35
  readonly field: DatabaseSortableField<TModel>;
37
36
  readonly direction: "asc" | "desc";
@@ -1,5 +1,4 @@
1
1
  import { Platform } from "@hot-updater/core";
2
-
3
2
  //#region src/types/databaseRows.d.ts
4
3
  type DatabaseJsonValue = boolean | number | string | null | readonly DatabaseJsonValue[] | DatabaseJsonObject;
5
4
  type DatabaseJsonObject = {
@@ -70,30 +69,36 @@ interface ChannelRow {
70
69
  readonly id: string;
71
70
  readonly name: string;
72
71
  }
72
+ /** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
73
+ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
74
+ readonly username: string | null;
75
+ readonly cohort: string;
76
+ readonly update_strategy: "fingerprint" | "appVersion" | null;
77
+ readonly fingerprint_hash: string | null;
78
+ readonly sdk_version: string | null;
79
+ };
73
80
  type BundleEventRowBase = {
74
81
  readonly id: string;
75
82
  readonly install_id: string;
76
83
  readonly user_id: string | null;
77
- readonly username: string | null;
78
84
  readonly from_release_id: string | null;
79
85
  readonly to_release_id: string | null;
80
86
  readonly to_bundle_id: string;
81
87
  readonly platform: Platform;
82
88
  readonly app_version: string;
83
89
  readonly channel: string;
84
- readonly cohort: string;
85
- readonly fingerprint_hash: string | null;
86
- readonly sdk_version: string | null;
90
+ readonly metadata: DatabaseBundleEventMetadata;
87
91
  readonly received_at_ms: number;
88
92
  };
89
- type BundleEventRow = (BundleEventRowBase & {
90
- readonly type: "UPDATE_APPLIED" | "RECOVERED" | "RELEASE_ADOPTED";
93
+ type BundleEventRow = BundleEventRowBase & ({
94
+ readonly type: "UPDATE_DOWNLOADED";
95
+ readonly from_bundle_id: string;
96
+ } | {
97
+ readonly type: "UPDATE_APPLIED" | "RECOVERED";
91
98
  readonly from_bundle_id: string;
92
- readonly update_strategy: "fingerprint" | "appVersion";
93
- }) | (BundleEventRowBase & {
99
+ } | {
94
100
  readonly type: "UNCHANGED";
95
101
  readonly from_bundle_id: null;
96
- readonly update_strategy: null;
97
102
  });
98
103
  interface ApiKeyRow {
99
104
  readonly id: string;
@@ -117,4 +122,4 @@ type DatabaseModel = keyof DatabaseModelMap;
117
122
  type DatabaseRow<TModel extends DatabaseModel> = DatabaseModelMap[TModel];
118
123
  type DatabaseField<TModel extends DatabaseModel> = Extract<keyof DatabaseRow<TModel>, string>;
119
124
  //#endregion
120
- export { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleMetadata, DatabaseField, DatabaseJsonObject, DatabaseJsonValue, DatabaseModel, DatabaseModelMap, DatabaseRow, ReleaseCatalogRow, ReleaseRow };
125
+ export { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleEventMetadata, DatabaseBundleMetadata, DatabaseField, DatabaseJsonObject, DatabaseJsonValue, DatabaseModel, DatabaseModelMap, DatabaseRow, ReleaseCatalogRow, ReleaseRow };
@@ -1,5 +1,4 @@
1
1
  import { Platform } from "@hot-updater/core";
2
-
3
2
  //#region src/types/databaseRows.d.ts
4
3
  type DatabaseJsonValue = boolean | number | string | null | readonly DatabaseJsonValue[] | DatabaseJsonObject;
5
4
  type DatabaseJsonObject = {
@@ -70,30 +69,36 @@ interface ChannelRow {
70
69
  readonly id: string;
71
70
  readonly name: string;
72
71
  }
72
+ /** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
73
+ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
74
+ readonly username: string | null;
75
+ readonly cohort: string;
76
+ readonly update_strategy: "fingerprint" | "appVersion" | null;
77
+ readonly fingerprint_hash: string | null;
78
+ readonly sdk_version: string | null;
79
+ };
73
80
  type BundleEventRowBase = {
74
81
  readonly id: string;
75
82
  readonly install_id: string;
76
83
  readonly user_id: string | null;
77
- readonly username: string | null;
78
84
  readonly from_release_id: string | null;
79
85
  readonly to_release_id: string | null;
80
86
  readonly to_bundle_id: string;
81
87
  readonly platform: Platform;
82
88
  readonly app_version: string;
83
89
  readonly channel: string;
84
- readonly cohort: string;
85
- readonly fingerprint_hash: string | null;
86
- readonly sdk_version: string | null;
90
+ readonly metadata: DatabaseBundleEventMetadata;
87
91
  readonly received_at_ms: number;
88
92
  };
89
- type BundleEventRow = (BundleEventRowBase & {
90
- readonly type: "UPDATE_APPLIED" | "RECOVERED" | "RELEASE_ADOPTED";
93
+ type BundleEventRow = BundleEventRowBase & ({
94
+ readonly type: "UPDATE_DOWNLOADED";
95
+ readonly from_bundle_id: string;
96
+ } | {
97
+ readonly type: "UPDATE_APPLIED" | "RECOVERED";
91
98
  readonly from_bundle_id: string;
92
- readonly update_strategy: "fingerprint" | "appVersion";
93
- }) | (BundleEventRowBase & {
99
+ } | {
94
100
  readonly type: "UNCHANGED";
95
101
  readonly from_bundle_id: null;
96
- readonly update_strategy: null;
97
102
  });
98
103
  interface ApiKeyRow {
99
104
  readonly id: string;
@@ -117,4 +122,4 @@ type DatabaseModel = keyof DatabaseModelMap;
117
122
  type DatabaseRow<TModel extends DatabaseModel> = DatabaseModelMap[TModel];
118
123
  type DatabaseField<TModel extends DatabaseModel> = Extract<keyof DatabaseRow<TModel>, string>;
119
124
  //#endregion
120
- export { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleMetadata, DatabaseField, DatabaseJsonObject, DatabaseJsonValue, DatabaseModel, DatabaseModelMap, DatabaseRow, ReleaseCatalogRow, ReleaseRow };
125
+ export { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleEventMetadata, DatabaseBundleMetadata, DatabaseField, DatabaseJsonObject, DatabaseJsonValue, DatabaseModel, DatabaseModelMap, DatabaseRow, ReleaseCatalogRow, ReleaseRow };
@@ -1,9 +1,10 @@
1
- import { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleMetadata, DatabaseJsonObject, DatabaseJsonValue, ReleaseCatalogRow, ReleaseRow } from "./databaseRows.cjs";
2
- import { AnalyticsModel, AnalyticsScanCursor, AnalyticsScanInput, ApiKeyModel, BundleModel, BundleModelQuery, BundlePatchModel, BundleRepository, BundleRepositoryChange, BundleRepositoryCommit, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelModel, DatabaseChange, DatabaseCommit, DatabaseCommitExpectation, DatabaseCommitResult, DatabaseModels, DatabasePlugin, ReleaseCatalogModel, ReleaseModel } from "./databasePlugin.cjs";
1
+ import { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleEventMetadata, DatabaseBundleMetadata, DatabaseJsonObject, DatabaseJsonValue, ReleaseCatalogRow, ReleaseRow } from "./databaseRows.cjs";
2
+ import { ApiKeyModel, BundleModel, BundleModelQuery, BundlePatchModel, BundleRepository, BundleRepositoryChange, BundleRepositoryCommit, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelModel, DatabaseChange, DatabaseCommit, DatabaseCommitExpectation, DatabaseCommitResult, DatabaseModels, DatabasePlugin, InsightsBundleEventFilter, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsEventCursor, InsightsEventFilter, InsightsFindLatestEventsInput, InsightsListEventsInput, InsightsModel, InsightsRecordEventInput, InsightsScope, ReleaseCatalogModel, ReleaseModel } from "./databasePlugin.cjs";
3
3
  import { BundleRowUpdate, ReleaseCatalogRowUpdate, ReleaseRowUpdate } from "./databaseOperations.cjs";
4
+ import "./database.cjs";
4
5
  import { BuiltIns, HasMultipleCallSignatures, Primitive, RequiredDeep } from "./utils.cjs";
6
+ import "./public.cjs";
5
7
  import { Bundle, Bundle as Bundle$1, Platform, Platform as Platform$1 } from "@hot-updater/core";
6
-
7
8
  //#region src/types/index.d.ts
8
9
  interface BasePluginArgs {
9
10
  cwd: string;
@@ -80,6 +81,12 @@ interface BuildPluginConfig {
80
81
  }
81
82
  interface BuildPlugin {
82
83
  nativeBuild?: {
84
+ /** Resolves the public key embedded by the native build configuration. */
85
+ getBundleSigningPublicKey?: () => Promise<{
86
+ readonly publicKey: string;
87
+ } | null>;
88
+ /** Resolves native configuration files that must affect the fingerprint. */
89
+ getFingerprintExtraSources?: () => Promise<readonly string[]>;
83
90
  prebuild?: (args: {
84
91
  platform: Platform;
85
92
  }) => Promise<void>;
@@ -329,8 +336,6 @@ interface StoragePlugin {
329
336
  }
330
337
  interface BundleSigningPlugin {
331
338
  readonly name: string;
332
- /** Path to the pinned RSA public key embedded in native builds. */
333
- readonly publicKeyPath: string;
334
339
  /** Returns the RSA public key used by this provider in SPKI PEM format. */
335
340
  readonly getPublicKey: (input?: {
336
341
  readonly cwd?: string;
@@ -351,16 +356,15 @@ interface BundleSigningPlugin {
351
356
  readonly signature: Uint8Array;
352
357
  }>;
353
358
  }
354
- /** Built-in local PEM signing, compatible with the v0 configuration. */
359
+ /** Built-in local PEM signing. */
355
360
  type LocalSigningConfig = {
356
- /** Optional pinned RSA SPKI public key. Also enables public-key-only builds. */readonly publicKeyPath?: string;
357
- } & ({
358
- readonly enabled: true; /** Path to an RSA private key in PEM format. */
361
+ readonly enabled: true;
362
+ /** Path to an RSA private key in PEM format. */
359
363
  readonly privateKeyPath: string;
360
364
  } | {
361
365
  readonly enabled: false;
362
366
  readonly privateKeyPath?: string;
363
- });
367
+ };
364
368
  /** Local config or signing plugin. Signing is disabled when omitted. */
365
369
  type SigningConfig = BundleSigningPlugin | LocalSigningConfig;
366
370
  /**
@@ -493,4 +497,4 @@ interface NativeBuildOptions {
493
497
  scheme?: string;
494
498
  }
495
499
  //#endregion
496
- export { ApplePlatform, BasePluginArgs, BuildPlugin, BuildPluginConfig, type Bundle$1 as Bundle, BundleSigningPlugin, ConfigInput, DatabaseBundleCursor, DatabaseBundleIdFilter, DatabaseBundleQueryOptions, DatabaseBundleQueryOrder, DatabaseBundleQueryWhere, FingerprintExtraSources, IosBuildDestination, LocalSigningConfig, NativeBuildAndroidScheme, NativeBuildArgs, NativeBuildIosScheme, NativeBuildOptions, Paginated, PaginatedResult, PaginationInfo, type Platform$1 as Platform, PlatformConfig, SigningConfig, StorageDeleteInput, StorageDeleteResult, StorageExistsInput, StorageExistsResult, StorageGetDownloadUrlInput, StorageGetDownloadUrlResult, StorageGetInput, StorageGetResult, StorageObject, StoragePlugin, StoragePutInput, StoragePutResult, supportedIosPlatforms };
500
+ export { type ApiKeyModel, type ApiKeyRow, ApplePlatform, BasePluginArgs, BuildPlugin, BuildPluginConfig, BuiltIns, type Bundle$1 as Bundle, type BundleEventRow, type BundleEventRowBase, type BundleModel, type BundleModelQuery, type BundlePatchModel, type BundlePatchRow, type BundleRepository, type BundleRepositoryChange, type BundleRepositoryCommit, type BundleRow, type BundleRowUpdate, BundleSigningPlugin, type ChannelDeleteInput, type ChannelDeleteResult, type ChannelInsertInput, type ChannelInsertResult, type ChannelModel, type ChannelRow, ConfigInput, DatabaseBundleCursor, type DatabaseBundleEventMetadata, DatabaseBundleIdFilter, type DatabaseBundleMetadata, DatabaseBundleQueryOptions, DatabaseBundleQueryOrder, DatabaseBundleQueryWhere, type DatabaseChange, type DatabaseCommit, type DatabaseCommitExpectation, type DatabaseCommitResult, type DatabaseJsonObject, type DatabaseJsonValue, type DatabaseModels, type DatabasePlugin, FingerprintExtraSources, HasMultipleCallSignatures, type InsightsBundleEventFilter, type InsightsCountEventsInput, type InsightsCountLatestEventsInput, type InsightsEventCursor, type InsightsEventFilter, type InsightsFindLatestEventsInput, type InsightsListEventsInput, type InsightsModel, type InsightsRecordEventInput, type InsightsScope, IosBuildDestination, LocalSigningConfig, NativeBuildAndroidScheme, NativeBuildArgs, NativeBuildIosScheme, NativeBuildOptions, Paginated, PaginatedResult, PaginationInfo, type Platform$1 as Platform, PlatformConfig, Primitive, type ReleaseCatalogModel, type ReleaseCatalogRow, type ReleaseCatalogRowUpdate, type ReleaseModel, type ReleaseRow, type ReleaseRowUpdate, RequiredDeep, SigningConfig, StorageDeleteInput, StorageDeleteResult, StorageExistsInput, StorageExistsResult, StorageGetDownloadUrlInput, StorageGetDownloadUrlResult, StorageGetInput, StorageGetResult, StorageObject, StoragePlugin, StoragePutInput, StoragePutResult, supportedIosPlatforms };
@@ -1,9 +1,10 @@
1
- import { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleMetadata, DatabaseJsonObject, DatabaseJsonValue, ReleaseCatalogRow, ReleaseRow } from "./databaseRows.mjs";
2
- import { AnalyticsModel, AnalyticsScanCursor, AnalyticsScanInput, ApiKeyModel, BundleModel, BundleModelQuery, BundlePatchModel, BundleRepository, BundleRepositoryChange, BundleRepositoryCommit, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelModel, DatabaseChange, DatabaseCommit, DatabaseCommitExpectation, DatabaseCommitResult, DatabaseModels, DatabasePlugin, ReleaseCatalogModel, ReleaseModel } from "./databasePlugin.mjs";
1
+ import { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleEventMetadata, DatabaseBundleMetadata, DatabaseJsonObject, DatabaseJsonValue, ReleaseCatalogRow, ReleaseRow } from "./databaseRows.mjs";
2
+ import { ApiKeyModel, BundleModel, BundleModelQuery, BundlePatchModel, BundleRepository, BundleRepositoryChange, BundleRepositoryCommit, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelModel, DatabaseChange, DatabaseCommit, DatabaseCommitExpectation, DatabaseCommitResult, DatabaseModels, DatabasePlugin, InsightsBundleEventFilter, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsEventCursor, InsightsEventFilter, InsightsFindLatestEventsInput, InsightsListEventsInput, InsightsModel, InsightsRecordEventInput, InsightsScope, ReleaseCatalogModel, ReleaseModel } from "./databasePlugin.mjs";
3
3
  import { BundleRowUpdate, ReleaseCatalogRowUpdate, ReleaseRowUpdate } from "./databaseOperations.mjs";
4
+ import "./database.mjs";
4
5
  import { BuiltIns, HasMultipleCallSignatures, Primitive, RequiredDeep } from "./utils.mjs";
6
+ import "./public.mjs";
5
7
  import { Bundle, Bundle as Bundle$1, Platform, Platform as Platform$1 } from "@hot-updater/core";
6
-
7
8
  //#region src/types/index.d.ts
8
9
  interface BasePluginArgs {
9
10
  cwd: string;
@@ -80,6 +81,12 @@ interface BuildPluginConfig {
80
81
  }
81
82
  interface BuildPlugin {
82
83
  nativeBuild?: {
84
+ /** Resolves the public key embedded by the native build configuration. */
85
+ getBundleSigningPublicKey?: () => Promise<{
86
+ readonly publicKey: string;
87
+ } | null>;
88
+ /** Resolves native configuration files that must affect the fingerprint. */
89
+ getFingerprintExtraSources?: () => Promise<readonly string[]>;
83
90
  prebuild?: (args: {
84
91
  platform: Platform;
85
92
  }) => Promise<void>;
@@ -329,8 +336,6 @@ interface StoragePlugin {
329
336
  }
330
337
  interface BundleSigningPlugin {
331
338
  readonly name: string;
332
- /** Path to the pinned RSA public key embedded in native builds. */
333
- readonly publicKeyPath: string;
334
339
  /** Returns the RSA public key used by this provider in SPKI PEM format. */
335
340
  readonly getPublicKey: (input?: {
336
341
  readonly cwd?: string;
@@ -351,16 +356,15 @@ interface BundleSigningPlugin {
351
356
  readonly signature: Uint8Array;
352
357
  }>;
353
358
  }
354
- /** Built-in local PEM signing, compatible with the v0 configuration. */
359
+ /** Built-in local PEM signing. */
355
360
  type LocalSigningConfig = {
356
- /** Optional pinned RSA SPKI public key. Also enables public-key-only builds. */readonly publicKeyPath?: string;
357
- } & ({
358
- readonly enabled: true; /** Path to an RSA private key in PEM format. */
361
+ readonly enabled: true;
362
+ /** Path to an RSA private key in PEM format. */
359
363
  readonly privateKeyPath: string;
360
364
  } | {
361
365
  readonly enabled: false;
362
366
  readonly privateKeyPath?: string;
363
- });
367
+ };
364
368
  /** Local config or signing plugin. Signing is disabled when omitted. */
365
369
  type SigningConfig = BundleSigningPlugin | LocalSigningConfig;
366
370
  /**
@@ -493,4 +497,4 @@ interface NativeBuildOptions {
493
497
  scheme?: string;
494
498
  }
495
499
  //#endregion
496
- export { ApplePlatform, BasePluginArgs, BuildPlugin, BuildPluginConfig, type Bundle$1 as Bundle, BundleSigningPlugin, ConfigInput, DatabaseBundleCursor, DatabaseBundleIdFilter, DatabaseBundleQueryOptions, DatabaseBundleQueryOrder, DatabaseBundleQueryWhere, FingerprintExtraSources, IosBuildDestination, LocalSigningConfig, NativeBuildAndroidScheme, NativeBuildArgs, NativeBuildIosScheme, NativeBuildOptions, Paginated, PaginatedResult, PaginationInfo, type Platform$1 as Platform, PlatformConfig, SigningConfig, StorageDeleteInput, StorageDeleteResult, StorageExistsInput, StorageExistsResult, StorageGetDownloadUrlInput, StorageGetDownloadUrlResult, StorageGetInput, StorageGetResult, StorageObject, StoragePlugin, StoragePutInput, StoragePutResult, supportedIosPlatforms };
500
+ export { type ApiKeyModel, type ApiKeyRow, ApplePlatform, BasePluginArgs, BuildPlugin, BuildPluginConfig, BuiltIns, type Bundle$1 as Bundle, type BundleEventRow, type BundleEventRowBase, type BundleModel, type BundleModelQuery, type BundlePatchModel, type BundlePatchRow, type BundleRepository, type BundleRepositoryChange, type BundleRepositoryCommit, type BundleRow, type BundleRowUpdate, BundleSigningPlugin, type ChannelDeleteInput, type ChannelDeleteResult, type ChannelInsertInput, type ChannelInsertResult, type ChannelModel, type ChannelRow, ConfigInput, DatabaseBundleCursor, type DatabaseBundleEventMetadata, DatabaseBundleIdFilter, type DatabaseBundleMetadata, DatabaseBundleQueryOptions, DatabaseBundleQueryOrder, DatabaseBundleQueryWhere, type DatabaseChange, type DatabaseCommit, type DatabaseCommitExpectation, type DatabaseCommitResult, type DatabaseJsonObject, type DatabaseJsonValue, type DatabaseModels, type DatabasePlugin, FingerprintExtraSources, HasMultipleCallSignatures, type InsightsBundleEventFilter, type InsightsCountEventsInput, type InsightsCountLatestEventsInput, type InsightsEventCursor, type InsightsEventFilter, type InsightsFindLatestEventsInput, type InsightsListEventsInput, type InsightsModel, type InsightsRecordEventInput, type InsightsScope, IosBuildDestination, LocalSigningConfig, NativeBuildAndroidScheme, NativeBuildArgs, NativeBuildIosScheme, NativeBuildOptions, Paginated, PaginatedResult, PaginationInfo, type Platform$1 as Platform, PlatformConfig, Primitive, type ReleaseCatalogModel, type ReleaseCatalogRow, type ReleaseCatalogRowUpdate, type ReleaseModel, type ReleaseRow, type ReleaseRowUpdate, RequiredDeep, SigningConfig, StorageDeleteInput, StorageDeleteResult, StorageExistsInput, StorageExistsResult, StorageGetDownloadUrlInput, StorageGetDownloadUrlResult, StorageGetInput, StorageGetResult, StorageObject, StoragePlugin, StoragePutInput, StoragePutResult, supportedIosPlatforms };
@@ -1,7 +1,8 @@
1
- import { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleMetadata, DatabaseField, DatabaseJsonObject, DatabaseJsonValue, DatabaseModel, DatabaseModelMap, DatabaseRow, ReleaseCatalogRow, ReleaseRow } from "./databaseRows.cjs";
2
- import { AnalyticsModel, AnalyticsScanCursor, AnalyticsScanInput, ApiKeyModel, BundleModel, BundleModelQuery, BundlePatchModel, BundleRepository, BundleRepositoryChange, BundleRepositoryCommit, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelModel, DatabaseChange, DatabaseCommit, DatabaseCommitExpectation, DatabaseCommitResult, DatabaseModels, DatabasePlugin, ReleaseCatalogModel, ReleaseModel } from "./databasePlugin.cjs";
1
+ import { ApiKeyRow, BundleEventRow, BundleEventRowBase, BundlePatchRow, BundleRow, ChannelRow, DatabaseBundleEventMetadata, DatabaseBundleMetadata, DatabaseField, DatabaseJsonObject, DatabaseJsonValue, DatabaseModel, DatabaseModelMap, DatabaseRow, ReleaseCatalogRow, ReleaseRow } from "./databaseRows.cjs";
2
+ import { ApiKeyModel, BundleModel, BundleModelQuery, BundlePatchModel, BundleRepository, BundleRepositoryChange, BundleRepositoryCommit, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelModel, DatabaseChange, DatabaseCommit, DatabaseCommitExpectation, DatabaseCommitResult, DatabaseModels, DatabasePlugin, InsightsBundleEventFilter, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsEventCursor, InsightsEventFilter, InsightsFindLatestEventsInput, InsightsListEventsInput, InsightsModel, InsightsRecordEventInput, InsightsScope, ReleaseCatalogModel, ReleaseModel } from "./databasePlugin.cjs";
3
3
  import { DatabaseDistinctFields, DatabaseDistinctOn, DatabaseOrderBy, DatabaseSelect, DatabaseSortBy, DatabaseSortClause, DatabaseSortNulls, DatabaseStringComparisonMode, DatabaseWhere, DatabaseWhereConnector, DatabaseWhereOperator, SelectedDatabaseRow } from "./databaseQuery.cjs";
4
4
  import { ApiKeyRowUpdate, BundleRowUpdate, CountBundlesDatabaseImplementationInput, CountBundlesDatabaseInput, CountDatabaseImplementationInput, CountDatabaseInput, CountDatabaseModel, CreateDatabaseImplementationInput, CreateDatabaseInput, CreateDatabaseModel, DatabaseCapability, DatabaseDeleteModel, DatabaseFindOneModel, DatabaseImplementationResult, DatabaseModelCapabilities, DatabaseModelsWithCapability, DatabasePluginCrud, DatabasePluginImplementation, DatabaseRowUpdate, DeleteDatabaseImplementationInput, DeleteDatabaseInput, DeleteDatabaseModel, FindManyDatabaseImplementationInput, FindManyDatabaseInput, FindManyDatabaseModel, FindManyDatabasePluginInput, FindOneDatabaseImplementationInput, FindOneDatabaseInput, FindOneDatabaseModel, ReleaseCatalogRowUpdate, ReleaseRowUpdate, SelectedDatabaseInputRow, TransactionDatabasePluginImplementation, UpdateBundleDatabaseImplementationInput, UpdateBundleDatabaseInput, UpdateDatabaseImplementationInput, UpdateDatabaseInput, UpdateDatabaseModel } from "./databaseOperations.cjs";
5
5
  import { BuiltIns, HasMultipleCallSignatures, Primitive, RequiredDeep } from "./utils.cjs";
6
6
  import { ApplePlatform, BasePluginArgs, BuildPlugin, BuildPluginConfig, Bundle, BundleSigningPlugin, ConfigInput, DatabaseBundleCursor, DatabaseBundleIdFilter, DatabaseBundleQueryOptions, DatabaseBundleQueryOrder, DatabaseBundleQueryWhere, FingerprintExtraSources, IosBuildDestination, LocalSigningConfig, NativeBuildAndroidScheme, NativeBuildArgs, NativeBuildIosScheme, NativeBuildOptions, Paginated, PaginatedResult, PaginationInfo, Platform, PlatformConfig, SigningConfig, StorageDeleteInput, StorageDeleteResult, StorageExistsInput, StorageExistsResult, StorageGetDownloadUrlInput, StorageGetDownloadUrlResult, StorageGetInput, StorageGetResult, StorageObject, StoragePlugin, StoragePutInput, StoragePutResult, supportedIosPlatforms } from "./index.cjs";
7
- import { databaseFields } from "./databaseFields.cjs";
7
+ import { databaseFields } from "./databaseFields.cjs";
8
+ export { ApiKeyModel, ApiKeyRow, ApiKeyRowUpdate, ApplePlatform, BasePluginArgs, BuildPlugin, BuildPluginConfig, BuiltIns, type Bundle, BundleEventRow, BundleEventRowBase, BundleModel, BundleModelQuery, BundlePatchModel, BundlePatchRow, BundleRepository, BundleRepositoryChange, BundleRepositoryCommit, BundleRow, BundleRowUpdate, BundleSigningPlugin, ChannelDeleteInput, ChannelDeleteResult, ChannelInsertInput, ChannelInsertResult, ChannelModel, ChannelRow, ConfigInput, CountBundlesDatabaseImplementationInput, CountBundlesDatabaseInput, CountDatabaseImplementationInput, CountDatabaseInput, CountDatabaseModel, CreateDatabaseImplementationInput, CreateDatabaseInput, CreateDatabaseModel, DatabaseBundleCursor, DatabaseBundleEventMetadata, DatabaseBundleIdFilter, DatabaseBundleMetadata, DatabaseBundleQueryOptions, DatabaseBundleQueryOrder, DatabaseBundleQueryWhere, DatabaseCapability, DatabaseChange, DatabaseCommit, DatabaseCommitExpectation, DatabaseCommitResult, DatabaseDeleteModel, DatabaseDistinctFields, DatabaseDistinctOn, DatabaseField, DatabaseFindOneModel, DatabaseImplementationResult, DatabaseJsonObject, DatabaseJsonValue, DatabaseModel, DatabaseModelCapabilities, DatabaseModelMap, DatabaseModels, DatabaseModelsWithCapability, DatabaseOrderBy, DatabasePlugin, DatabasePluginCrud, DatabasePluginImplementation, DatabaseRow, DatabaseRowUpdate, DatabaseSelect, DatabaseSortBy, DatabaseSortClause, DatabaseSortNulls, DatabaseStringComparisonMode, DatabaseWhere, DatabaseWhereConnector, DatabaseWhereOperator, DeleteDatabaseImplementationInput, DeleteDatabaseInput, DeleteDatabaseModel, FindManyDatabaseImplementationInput, FindManyDatabaseInput, FindManyDatabaseModel, FindManyDatabasePluginInput, FindOneDatabaseImplementationInput, FindOneDatabaseInput, FindOneDatabaseModel, FingerprintExtraSources, HasMultipleCallSignatures, InsightsBundleEventFilter, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsEventCursor, InsightsEventFilter, InsightsFindLatestEventsInput, InsightsListEventsInput, InsightsModel, InsightsRecordEventInput, InsightsScope, IosBuildDestination, LocalSigningConfig, NativeBuildAndroidScheme, NativeBuildArgs, NativeBuildIosScheme, NativeBuildOptions, Paginated, PaginatedResult, PaginationInfo, type Platform, PlatformConfig, Primitive, ReleaseCatalogModel, ReleaseCatalogRow, ReleaseCatalogRowUpdate, ReleaseModel, ReleaseRow, ReleaseRowUpdate, RequiredDeep, SelectedDatabaseInputRow, SelectedDatabaseRow, SigningConfig, StorageDeleteInput, StorageDeleteResult, StorageExistsInput, StorageExistsResult, StorageGetDownloadUrlInput, StorageGetDownloadUrlResult, StorageGetInput, StorageGetResult, StorageObject, StoragePlugin, StoragePutInput, StoragePutResult, TransactionDatabasePluginImplementation, UpdateBundleDatabaseImplementationInput, UpdateBundleDatabaseInput, UpdateDatabaseImplementationInput, UpdateDatabaseInput, UpdateDatabaseModel, databaseFields, supportedIosPlatforms };