@hot-updater/aws 1.0.0-rc.2 → 1.0.0-rc.21

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.mts CHANGED
@@ -1,17 +1,33 @@
1
1
  import { DynamoDBClientConfig } from "@aws-sdk/client-dynamodb";
2
- import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
3
- import { StoragePlugin, StoragePluginWith } from "@hot-updater/plugin-core";
4
- import "@hot-updater/plugin-core/internal";
2
+ import { DatabaseJsonObject, EngineDatabase, Platform, PluginTables, StorageAdapter, StorageAdapterWith } from "@hot-updater/plugin-core";
5
3
  import { S3ClientConfig } from "@aws-sdk/client-s3";
6
4
  //#region src/dynamoDB.d.ts
7
- declare const DYNAMODB_UPDATE_INDEX_NAME = "hot-updater-update-index";
8
5
  interface DynamoDBConfig extends DynamoDBClientConfig {
9
6
  readonly apiBasePath?: string;
10
7
  readonly cloudfrontDistributionId?: string;
11
8
  readonly shouldWaitForInvalidation?: boolean;
12
9
  readonly tableName: string;
10
+ /**
11
+ * DynamoDB bills each item a write touches, so Insights' aggregates are
12
+ * batched: through log rows a compaction merges (the default), or
13
+ * `{ mode: "memory" }` on a long-lived server. `false` commits them with
14
+ * each event.
15
+ */
16
+ readonly aggregateBatching?: EngineDatabase["aggregateBatching"] | false;
13
17
  }
14
- declare const dynamoDB: (config: DynamoDBConfig) => import("@hot-updater/plugin-core").DatabasePlugin;
18
+ /**
19
+ * Creates the table when it is missing and writes the schema settings of
20
+ * core and `plugins`, the plugins the server runs, which the database checks
21
+ * before its first read. `hot-updater init` runs it in AWS with the managed
22
+ * server's plugins.
23
+ */
24
+ declare const migrateDynamoDB: (config: DynamoDBConfig, plugins?: readonly PluginTables[]) => Promise<void>;
25
+ /**
26
+ * Hot Updater's database on one DynamoDB table, through the storage engine.
27
+ * With a distribution, it gives core the CloudFront invalidation core runs
28
+ * after a write that changes what the update-check routes answer.
29
+ */
30
+ declare const dynamoDB: (config: DynamoDBConfig) => EngineDatabase;
15
31
  //#endregion
16
32
  //#region src/cloudFrontDownloadUrl.d.ts
17
33
  interface CloudFrontPrivateKeyFromGetter {
@@ -41,15 +57,723 @@ interface S3StorageConfig extends S3ClientConfig {
41
57
  /** Base path where bundles will be stored in the bucket. */
42
58
  basePath?: string;
43
59
  downloadUrlSigningKey?: string;
44
- getDownloadUrl?: StoragePlugin["getDownloadUrl"];
60
+ getDownloadUrl?: StorageAdapter["getDownloadUrl"];
45
61
  }
46
62
  type S3StorageConfigWithDownloadUrl = S3StorageConfig & ({
47
63
  downloadUrlSigningKey: string;
48
64
  } | {
49
- getDownloadUrl: NonNullable<StoragePlugin["getDownloadUrl"]>;
65
+ getDownloadUrl: NonNullable<StorageAdapter["getDownloadUrl"]>;
50
66
  });
51
67
  type S3StorageOperations = "put" | "get" | "exists" | "delete" | "listObjects" | "deleteObjects";
52
- declare function s3Storage(config: S3StorageConfigWithDownloadUrl): StoragePluginWith<S3StorageOperations | "getDownloadUrl">;
53
- declare function s3Storage(config: S3StorageConfig): StoragePluginWith<S3StorageOperations>;
68
+ declare function s3Storage(config: S3StorageConfigWithDownloadUrl): StorageAdapterWith<S3StorageOperations | "getDownloadUrl">;
69
+ declare function s3Storage(config: S3StorageConfig): StorageAdapterWith<S3StorageOperations>;
54
70
  //#endregion
55
- export { CloudFrontDownloadUrlOptions, DYNAMODB_UPDATE_INDEX_NAME, type DynamoDBConfig, S3StorageConfig, S3StorageConfigWithDownloadUrl, cloudFrontDownloadUrl, dynamoDB, s3Storage };
71
+ //#region ../insights/dist/server/eventRow.d.mts
72
+ //#region src/server/eventRow.d.ts
73
+ /** Where an update failed, and what failed; open sets, `unknown` for any other value. */
74
+ type BundleEventFailureStage = "check" | "download" | "install" | "unknown";
75
+ type BundleEventFailureReason = "network" | "http" | "invalid_response" | "hash_mismatch" | "signature" | "patch" | "extract" | "storage" | "unknown";
76
+ /** An `UPDATE_FAILED` report's failure, as stored. */
77
+ type BundleEventFailure = DatabaseJsonObject & {
78
+ readonly stage: BundleEventFailureStage;
79
+ readonly reason: BundleEventFailureReason;
80
+ /** What the client was fetching or writing. */
81
+ readonly resource?: "catalog" | "artifact" | "manifest" | "file" | "patch" | "archive" | "unknown";
82
+ readonly http_status?: number;
83
+ /** How the connection failed, when it did. */
84
+ readonly transport?: "timeout" | "dns" | "tls" | "connection" | "offline" | "cancelled" | "unknown";
85
+ /** The storage origin's error code, such as `ExpiredToken`. */
86
+ readonly origin_code?: string;
87
+ /** Android's `ApplicationExitInfo` reason for the process before this one. */
88
+ readonly previous_process_exit?: string;
89
+ };
90
+ /** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
91
+ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
92
+ readonly cohort: string;
93
+ readonly update_strategy: "fingerprint" | "appVersion" | null;
94
+ readonly fingerprint_hash: string | null;
95
+ readonly sdk_version: string | null;
96
+ /** `UPDATE_FAILED`: what failed. */
97
+ readonly failure?: BundleEventFailure;
98
+ /** `UPDATE_DOWNLOADED`: how the bundle arrived. */
99
+ readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
100
+ /** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
101
+ readonly patch_fallback?: boolean;
102
+ /** `RECOVERED`: Android's `ApplicationExitInfo` reason for the crashed process. */
103
+ readonly previous_process_exit?: string;
104
+ };
105
+ type BundleEventRowBase = {
106
+ readonly id: string;
107
+ readonly install_id: string;
108
+ readonly user_id: string | null;
109
+ readonly from_release_id: string | null;
110
+ readonly to_release_id: string | null;
111
+ readonly to_bundle_id: string;
112
+ readonly platform: Platform;
113
+ readonly app_version: string;
114
+ readonly channel: string;
115
+ readonly metadata: DatabaseBundleEventMetadata;
116
+ readonly received_at_ms: number;
117
+ };
118
+ type BundleEventRow = BundleEventRowBase & ({
119
+ readonly type: "UPDATE_DOWNLOADED";
120
+ readonly from_bundle_id: string;
121
+ } | {
122
+ readonly type: "UPDATE_APPLIED" | "RECOVERED";
123
+ readonly from_bundle_id: string;
124
+ } |
125
+ /** An update that failed: `from` is the running bundle, `to` the target (for a check, the running bundle). */
126
+ {
127
+ readonly type: "UPDATE_FAILED";
128
+ readonly from_bundle_id: string;
129
+ } | {
130
+ readonly type: "UNCHANGED";
131
+ readonly from_bundle_id: null;
132
+ });
133
+ //#endregion
134
+ //#region ../insights/dist/server/modelTypes.d.mts
135
+ //#region src/server/modelTypes.d.ts
136
+ interface InsightsEventCursor {
137
+ readonly receivedAtMs: number;
138
+ readonly id: string;
139
+ }
140
+ interface InsightsScope {
141
+ readonly platform: "ios" | "android";
142
+ readonly channel: string;
143
+ }
144
+ /**
145
+ * Raw event predicates; recovery is attributed to the source bundle. An
146
+ * UNCHANGED report is kept as no event, so no filter names it.
147
+ */
148
+ type InsightsBundleEventFilter = InsightsScope & ({
149
+ readonly type: "RECOVERED";
150
+ readonly fromBundleId: string;
151
+ } | {
152
+ readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "UPDATE_FAILED";
153
+ readonly toBundleId: string;
154
+ });
155
+ type InsightsEventFilter = {
156
+ readonly kind: "all";
157
+ } | {
158
+ readonly kind: "installationMovement";
159
+ readonly installId: string;
160
+ } | ({
161
+ readonly kind: "bundle";
162
+ } & InsightsBundleEventFilter);
163
+ interface InsightsListEventsInput {
164
+ readonly filter: InsightsEventFilter;
165
+ readonly sinceMs?: number;
166
+ readonly beforeReceivedAtMs: number;
167
+ readonly after?: InsightsEventCursor;
168
+ readonly limit: number;
169
+ }
170
+ type InsightsFindLatestEventsInput = {
171
+ readonly installId: string;
172
+ } | {
173
+ readonly userId: string;
174
+ readonly afterInstallId?: string;
175
+ readonly limit: number;
176
+ };
177
+ interface InsightsCountLatestEventsInput extends InsightsScope {
178
+ /** A UTC day's start: latest events are counted by the day they fall in. */
179
+ readonly sinceMs: number;
180
+ /** Optional OR of one or two fixed predicates; count a matching event once. */
181
+ readonly bundle?: readonly {
182
+ readonly field: "from_bundle_id" | "to_bundle_id";
183
+ readonly value: string;
184
+ readonly types: readonly BundleEventRow["type"][];
185
+ }[];
186
+ }
187
+ interface InsightsCountEventsInput {
188
+ readonly filter: InsightsBundleEventFilter;
189
+ readonly sinceMs: number;
190
+ readonly beforeReceivedAtMs: number;
191
+ }
192
+ interface ReleaseReference {
193
+ readonly releaseId: string;
194
+ readonly platform: "ios" | "android";
195
+ readonly channel: string;
196
+ }
197
+ interface InsightsTimeRange {
198
+ /** Inclusive UTC Unix timestamp in milliseconds. */
199
+ readonly start: number;
200
+ /** Exclusive UTC Unix timestamp in milliseconds. */
201
+ readonly end: number;
202
+ }
203
+ type InsightsCoverage = {
204
+ readonly kind: "complete";
205
+ readonly sinceMs: number;
206
+ } | {
207
+ readonly kind: "partial";
208
+ readonly sinceMs: number | null;
209
+ };
210
+ interface ReleaseActivityMetrics {
211
+ readonly downloads: number;
212
+ readonly launches: number;
213
+ readonly failedLaunches: number;
214
+ /** Omitted for lifetime-only bundle-row reads. */
215
+ readonly uniqueUsers?: number;
216
+ /** Daily points, present only for period reads. */
217
+ readonly series?: readonly {
218
+ readonly startMs: number;
219
+ readonly launches: number;
220
+ readonly failedLaunches: number;
221
+ }[];
222
+ }
223
+ type InsightsGetReleaseActivityInput = {
224
+ readonly releases: readonly ReleaseReference[];
225
+ readonly timeRange?: InsightsTimeRange;
226
+ readonly scope?: never;
227
+ } | {
228
+ readonly scope: InsightsScope;
229
+ readonly timeRange: InsightsTimeRange;
230
+ readonly releases?: never;
231
+ };
232
+ interface InsightsGetReleaseActivityResult {
233
+ readonly coverage: InsightsCoverage;
234
+ readonly data: readonly {
235
+ readonly release?: ReleaseReference;
236
+ readonly scope?: InsightsScope;
237
+ readonly metrics: ReleaseActivityMetrics;
238
+ }[];
239
+ readonly measuredAtMs: number;
240
+ }
241
+ interface InsightsGetAppUsageInput {
242
+ readonly channel: string;
243
+ readonly platform: "all" | "ios" | "android";
244
+ readonly appVersion?: string;
245
+ readonly timeRange: InsightsTimeRange;
246
+ readonly intervalMs: number;
247
+ }
248
+ interface InsightsGetAppUsageResult {
249
+ readonly coverage: InsightsCoverage;
250
+ readonly activeInstallations: number;
251
+ readonly points: readonly {
252
+ readonly startMs: number;
253
+ readonly installations: number;
254
+ }[];
255
+ readonly appVersions: readonly string[];
256
+ readonly versions: readonly {
257
+ readonly name: string;
258
+ readonly installations: number;
259
+ }[];
260
+ readonly platforms: readonly {
261
+ readonly name: string;
262
+ readonly installations: number;
263
+ }[];
264
+ readonly bundleDistribution: readonly {
265
+ readonly appVersion: string;
266
+ readonly platform: "ios" | "android";
267
+ readonly releaseId: string | null;
268
+ readonly installations: number;
269
+ }[];
270
+ readonly measuredAtMs: number;
271
+ }
272
+ //#endregion
273
+ //#region ../insights/dist/server/schema.d.mts
274
+ //#region src/server/schema.d.ts
275
+ /** How long Insights keeps its rows, in whole days. Lifetime counters are kept. */
276
+ interface InsightsRetention {
277
+ /** Raw events and hourly rollups. */
278
+ readonly rawDays: number;
279
+ /** Daily rollups, and each installation's latest event and the gauges that count it. */
280
+ readonly dailyDays: number;
281
+ }
282
+ //#endregion
283
+ //#region ../insights/dist/server/reads.d.mts
284
+ //#region src/server/reads.d.ts
285
+ interface InsightsUpdateFailuresInput {
286
+ readonly platform: "ios" | "android";
287
+ readonly channel: string;
288
+ /** A release's failures; without it, the channel's, which need a time range. */
289
+ readonly releaseId?: string;
290
+ /** Without it, a release's failures since its first report. */
291
+ readonly timeRange?: InsightsTimeRange;
292
+ }
293
+ /** Update failures of one stage and reason, and what else their clients knew. */
294
+ interface InsightsFailureBreakdown {
295
+ readonly stage: string;
296
+ readonly reason: string;
297
+ readonly events: number;
298
+ /** By resource, HTTP status, origin code, and transport, most first. */
299
+ readonly details: readonly {
300
+ readonly resource: string | null;
301
+ readonly httpStatus: number | null;
302
+ readonly originCode: string | null;
303
+ readonly transport: string | null;
304
+ readonly events: number;
305
+ }[];
306
+ }
307
+ interface InsightsUpdateFailures {
308
+ readonly coverage: InsightsCoverage;
309
+ readonly measuredAtMs: number;
310
+ /** Update failures other than failed checks: each client reports one at most once a UTC day. */
311
+ readonly failedUpdates: number;
312
+ /** Installations with such a failure, estimated. */
313
+ readonly failedInstallations: number;
314
+ /** Download reports: each installation reports a bundle's download once. */
315
+ readonly downloads: number;
316
+ /** Downloads a patch delivered, and those that fell back from a patch to files or the archive. */
317
+ readonly patchDownloads: number;
318
+ readonly patchFallbacks: number;
319
+ /** A channel's failed update checks, installations with one, and its active installations, estimated. */
320
+ readonly checks?: {
321
+ readonly failures: number;
322
+ readonly failedInstallations: number;
323
+ readonly activeInstallations: number;
324
+ };
325
+ /** Over a time range: failures by stage and reason, most first. */
326
+ readonly breakdown?: readonly InsightsFailureBreakdown[];
327
+ /**
328
+ * Over a time range: failed launches, and the recoveries whose crashed
329
+ * process exited for a reason Android 11+ reported, by reason, most first.
330
+ */
331
+ readonly recoveries?: {
332
+ readonly failedLaunches: number;
333
+ readonly byExitReason: readonly {
334
+ readonly exitReason: string;
335
+ readonly events: number;
336
+ }[];
337
+ };
338
+ }
339
+ //#endregion
340
+ //#region ../api-keys/dist/server/model.d.mts
341
+ //#region src/server/model.d.ts
342
+ interface ApiKeyRow {
343
+ readonly id: string;
344
+ readonly hash: string;
345
+ readonly name: string;
346
+ readonly prefix: string;
347
+ readonly role: "client";
348
+ readonly created_at_ms: number;
349
+ readonly revoked_at_ms: number | null;
350
+ }
351
+ //#endregion
352
+ //#region ../api-keys/dist/server/apiKeys.d.mts
353
+ type ApiKeyMetadata = Omit<ApiKeyRow, "hash">;
354
+ interface CreatedApiKey {
355
+ /** Plaintext credential. It cannot be recovered after this call returns. */
356
+ readonly apiKey: string;
357
+ /** Non-secret metadata. The persisted SHA-256 hash is never exposed. */
358
+ readonly record: ApiKeyMetadata;
359
+ }
360
+ //#endregion
361
+ //#region src/plugins.d.ts
362
+ /**
363
+ * The plugins the managed AWS server runs: Insights, and API keys on every
364
+ * client route. Its Lambda@Edge function imports this list.
365
+ */
366
+ declare const plugins: readonly [import("@hot-updater/plugin-core").HotUpdaterPlugin<"insights", {
367
+ readonly bundle_events: import("@hot-updater/plugin-core").TableDefinition<{
368
+ readonly id: {
369
+ readonly type: "string";
370
+ readonly maxLength: 36;
371
+ };
372
+ readonly type: {
373
+ readonly type: "string";
374
+ readonly maxLength: 32;
375
+ };
376
+ readonly install_id: {
377
+ readonly type: "string";
378
+ readonly maxLength: 255;
379
+ };
380
+ readonly user_id: {
381
+ readonly type: "string";
382
+ readonly maxLength: 255;
383
+ readonly required: false;
384
+ };
385
+ readonly from_release_id: {
386
+ readonly type: "string";
387
+ readonly maxLength: 36;
388
+ readonly required: false;
389
+ };
390
+ readonly from_bundle_id: {
391
+ readonly type: "string";
392
+ readonly maxLength: 36;
393
+ readonly required: false;
394
+ };
395
+ readonly to_release_id: {
396
+ readonly type: "string";
397
+ readonly maxLength: 36;
398
+ readonly required: false;
399
+ };
400
+ readonly to_bundle_id: {
401
+ readonly type: "string";
402
+ readonly maxLength: 36;
403
+ };
404
+ readonly platform: {
405
+ readonly type: "string";
406
+ readonly maxLength: 16;
407
+ };
408
+ readonly app_version: {
409
+ readonly type: "string";
410
+ };
411
+ readonly channel: {
412
+ readonly type: "string";
413
+ };
414
+ readonly metadata: {
415
+ readonly type: "json";
416
+ };
417
+ readonly received_at_ms: {
418
+ readonly type: "integer";
419
+ };
420
+ }, {
421
+ day: "integer";
422
+ movement_install_id: "string";
423
+ bundle_ref: "string";
424
+ }, {
425
+ readonly recent: {
426
+ readonly eq: readonly ["channel", "platform", "day"];
427
+ readonly sort: readonly ["received_at_ms"];
428
+ };
429
+ readonly movementsByInstall: {
430
+ readonly eq: readonly ["movement_install_id"];
431
+ readonly sort: readonly ["received_at_ms"];
432
+ };
433
+ readonly byBundle: {
434
+ readonly eq: readonly ["platform", "channel", "type", "bundle_ref", "day"];
435
+ readonly sort: readonly ["received_at_ms"];
436
+ };
437
+ readonly byDay: {
438
+ readonly eq: readonly ["day"];
439
+ readonly sort: readonly ["received_at_ms"];
440
+ };
441
+ }, readonly ["id"]>;
442
+ readonly bundle_event_heads: import("@hot-updater/plugin-core").TableDefinition<{
443
+ readonly install_id: {
444
+ readonly type: "string";
445
+ readonly maxLength: 255;
446
+ };
447
+ readonly id: {
448
+ readonly type: "string";
449
+ readonly maxLength: 36;
450
+ };
451
+ readonly type: {
452
+ readonly type: "string";
453
+ readonly maxLength: 32;
454
+ };
455
+ readonly user_id: {
456
+ readonly type: "string";
457
+ readonly maxLength: 255;
458
+ readonly required: false;
459
+ };
460
+ readonly from_release_id: {
461
+ readonly type: "string";
462
+ readonly maxLength: 36;
463
+ readonly required: false;
464
+ };
465
+ readonly from_bundle_id: {
466
+ readonly type: "string";
467
+ readonly maxLength: 36;
468
+ readonly required: false;
469
+ };
470
+ readonly to_release_id: {
471
+ readonly type: "string";
472
+ readonly maxLength: 36;
473
+ readonly required: false;
474
+ };
475
+ readonly to_bundle_id: {
476
+ readonly type: "string";
477
+ readonly maxLength: 36;
478
+ };
479
+ readonly platform: {
480
+ readonly type: "string";
481
+ readonly maxLength: 16;
482
+ };
483
+ readonly app_version: {
484
+ readonly type: "string";
485
+ };
486
+ readonly channel: {
487
+ readonly type: "string";
488
+ };
489
+ readonly metadata: {
490
+ readonly type: "json";
491
+ };
492
+ readonly received_at_ms: {
493
+ readonly type: "integer";
494
+ };
495
+ }, Readonly<Record<string, import("@hot-updater/plugin-core").FieldType>>, {
496
+ readonly byUser: {
497
+ readonly eq: readonly ["user_id"];
498
+ readonly sort: readonly ["install_id"];
499
+ };
500
+ }, readonly ["install_id"]>;
501
+ readonly insights_overview: import("@hot-updater/plugin-core").AggregateDefinition<{
502
+ readonly identity: {
503
+ readonly type: "string";
504
+ readonly maxLength: 32;
505
+ };
506
+ readonly bucket_start_ms: {
507
+ readonly type: "integer";
508
+ };
509
+ }, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
510
+ readonly window: {
511
+ readonly eq: readonly ["identity"];
512
+ readonly sort: readonly ["bucket_start_ms"];
513
+ };
514
+ }, never, readonly ["identity", "bucket_start_ms"]>;
515
+ readonly insights_sketches: import("@hot-updater/plugin-core").AggregateDefinition<{
516
+ readonly identity: {
517
+ readonly type: "string";
518
+ readonly maxLength: 32;
519
+ };
520
+ readonly bucket_start_ms: {
521
+ readonly type: "integer";
522
+ };
523
+ }, never, {
524
+ readonly window: {
525
+ readonly eq: readonly ["identity"];
526
+ readonly sort: readonly ["bucket_start_ms"];
527
+ };
528
+ }, "launch_users" | "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
529
+ readonly insights_overview_daily: import("@hot-updater/plugin-core").AggregateDefinition<{
530
+ readonly identity: {
531
+ readonly type: "string";
532
+ readonly maxLength: 32;
533
+ };
534
+ readonly bucket_start_ms: {
535
+ readonly type: "integer";
536
+ };
537
+ }, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
538
+ readonly window: {
539
+ readonly eq: readonly ["identity"];
540
+ readonly sort: readonly ["bucket_start_ms"];
541
+ };
542
+ }, never, readonly ["identity", "bucket_start_ms"]>;
543
+ readonly insights_sketches_daily: import("@hot-updater/plugin-core").AggregateDefinition<{
544
+ readonly identity: {
545
+ readonly type: "string";
546
+ readonly maxLength: 32;
547
+ };
548
+ readonly bucket_start_ms: {
549
+ readonly type: "integer";
550
+ };
551
+ }, never, {
552
+ readonly window: {
553
+ readonly eq: readonly ["identity"];
554
+ readonly sort: readonly ["bucket_start_ms"];
555
+ };
556
+ }, "launch_users" | "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
557
+ readonly insights_overview_lifetime: import("@hot-updater/plugin-core").AggregateDefinition<{
558
+ readonly identity: {
559
+ readonly type: "string";
560
+ readonly maxLength: 32;
561
+ };
562
+ readonly bucket_start_ms: {
563
+ readonly type: "integer";
564
+ };
565
+ }, "downloads" | "launches" | "failed_launches" | "failed_updates" | "patch_downloads" | "patch_fallbacks", {
566
+ readonly window: {
567
+ readonly eq: readonly ["identity"];
568
+ readonly sort: readonly ["bucket_start_ms"];
569
+ };
570
+ }, never, readonly ["identity", "bucket_start_ms"]>;
571
+ readonly insights_sketches_lifetime: import("@hot-updater/plugin-core").AggregateDefinition<{
572
+ readonly identity: {
573
+ readonly type: "string";
574
+ readonly maxLength: 32;
575
+ };
576
+ readonly bucket_start_ms: {
577
+ readonly type: "integer";
578
+ };
579
+ }, never, {
580
+ readonly window: {
581
+ readonly eq: readonly ["identity"];
582
+ readonly sort: readonly ["bucket_start_ms"];
583
+ };
584
+ }, "failed_users", readonly ["identity", "bucket_start_ms"]>;
585
+ readonly insights_distribution: import("@hot-updater/plugin-core").AggregateDefinition<{
586
+ readonly channel: {
587
+ readonly type: "string";
588
+ };
589
+ readonly platform: {
590
+ readonly type: "string";
591
+ readonly maxLength: 16;
592
+ };
593
+ readonly app_version: {
594
+ readonly type: "string";
595
+ };
596
+ readonly release_id: {
597
+ readonly type: "string";
598
+ readonly maxLength: 36;
599
+ };
600
+ readonly bucket_start_ms: {
601
+ readonly type: "integer";
602
+ };
603
+ }, "latest_installations", {
604
+ readonly byScope: {
605
+ readonly eq: readonly ["channel", "platform"];
606
+ readonly sort: readonly ["bucket_start_ms"];
607
+ };
608
+ readonly byVersion: {
609
+ readonly eq: readonly ["channel", "platform", "app_version"];
610
+ readonly sort: readonly ["bucket_start_ms"];
611
+ };
612
+ }, never, readonly ["channel", "platform", "app_version", "release_id", "bucket_start_ms"]>;
613
+ readonly insights_latest_by_bundle: import("@hot-updater/plugin-core").AggregateDefinition<{
614
+ readonly platform: {
615
+ readonly type: "string";
616
+ readonly maxLength: 16;
617
+ };
618
+ readonly channel: {
619
+ readonly type: "string";
620
+ };
621
+ readonly bundle_field: {
622
+ readonly type: "string";
623
+ readonly maxLength: 16;
624
+ };
625
+ readonly bundle_id: {
626
+ readonly type: "string";
627
+ readonly maxLength: 36;
628
+ };
629
+ readonly type: {
630
+ readonly type: "string";
631
+ readonly maxLength: 32;
632
+ };
633
+ readonly bucket_start_ms: {
634
+ readonly type: "integer";
635
+ };
636
+ }, "installations", {
637
+ readonly byBundle: {
638
+ readonly eq: readonly ["platform", "channel", "bundle_field", "bundle_id", "type"];
639
+ readonly sort: readonly ["bucket_start_ms"];
640
+ };
641
+ }, never, readonly ["platform", "channel", "bundle_field", "bundle_id", "type", "bucket_start_ms"]>;
642
+ readonly insights_outcomes: import("@hot-updater/plugin-core").AggregateDefinition<{
643
+ readonly platform: {
644
+ readonly type: "string";
645
+ readonly maxLength: 16;
646
+ };
647
+ readonly channel: {
648
+ readonly type: "string";
649
+ };
650
+ readonly type: {
651
+ readonly type: "string";
652
+ readonly maxLength: 32;
653
+ };
654
+ readonly bundle_ref: {
655
+ readonly type: "string";
656
+ readonly maxLength: 41;
657
+ };
658
+ readonly bucket_start_ms: {
659
+ readonly type: "integer";
660
+ };
661
+ }, "events", {
662
+ readonly byRef: {
663
+ readonly eq: readonly ["platform", "channel", "type", "bundle_ref"];
664
+ readonly sort: readonly ["bucket_start_ms"];
665
+ };
666
+ }, never, readonly ["platform", "channel", "type", "bundle_ref", "bucket_start_ms"]>;
667
+ readonly insights_failures: import("@hot-updater/plugin-core").AggregateDefinition<{
668
+ readonly platform: {
669
+ readonly type: "string";
670
+ readonly maxLength: 16;
671
+ };
672
+ readonly channel: {
673
+ readonly type: "string";
674
+ };
675
+ readonly bucket_start_ms: {
676
+ readonly type: "integer";
677
+ };
678
+ readonly release_id: {
679
+ readonly type: "string";
680
+ readonly maxLength: 36;
681
+ };
682
+ readonly stage: {
683
+ readonly type: "string";
684
+ readonly maxLength: 16;
685
+ };
686
+ readonly reason: {
687
+ readonly type: "string";
688
+ readonly maxLength: 64;
689
+ };
690
+ readonly detail: {
691
+ readonly type: "string";
692
+ readonly maxLength: 160;
693
+ };
694
+ }, "events", {
695
+ readonly byScope: {
696
+ readonly eq: readonly ["platform", "channel"];
697
+ readonly sort: readonly ["bucket_start_ms"];
698
+ };
699
+ }, never, readonly ["platform", "channel", "bucket_start_ms", "release_id", "stage", "reason", "detail"]>;
700
+ }, {
701
+ api: {
702
+ retention: InsightsRetention;
703
+ recordEvent: (event: BundleEventRow) => Promise<void>;
704
+ listEvents: (input: InsightsListEventsInput) => Promise<readonly BundleEventRow[]>;
705
+ findLatestEvents: (input: InsightsFindLatestEventsInput) => Promise<readonly BundleEventRow[]>;
706
+ countLatestEvents: (input: InsightsCountLatestEventsInput) => Promise<number>;
707
+ countEvents: (input: InsightsCountEventsInput) => Promise<number>;
708
+ getReleaseActivity: (input: InsightsGetReleaseActivityInput) => Promise<InsightsGetReleaseActivityResult>;
709
+ getAppUsage: (input: InsightsGetAppUsageInput) => Promise<InsightsGetAppUsageResult>;
710
+ getUpdateFailures: (input: InsightsUpdateFailuresInput) => Promise<InsightsUpdateFailures>;
711
+ };
712
+ endpoints: import("@hot-updater/plugin-core").PluginEndpoint[];
713
+ }, {}>, import("@hot-updater/plugin-core").HotUpdaterPlugin<"apiKeys", {
714
+ readonly api_keys: import("@hot-updater/plugin-core").TableDefinition<{
715
+ readonly id: {
716
+ readonly type: "string";
717
+ readonly maxLength: 255;
718
+ };
719
+ readonly hash: {
720
+ readonly type: "string";
721
+ readonly maxLength: 64;
722
+ readonly unique: true;
723
+ };
724
+ readonly name: {
725
+ readonly type: "string";
726
+ readonly maxLength: 64;
727
+ };
728
+ readonly prefix: {
729
+ readonly type: "string";
730
+ readonly maxLength: 16;
731
+ };
732
+ readonly role: {
733
+ readonly type: "string";
734
+ readonly maxLength: 16;
735
+ };
736
+ readonly created_at_ms: {
737
+ readonly type: "integer";
738
+ };
739
+ readonly revoked_at_ms: {
740
+ readonly type: "integer";
741
+ readonly required: false;
742
+ };
743
+ }, {}, {
744
+ readonly byCreated: {
745
+ readonly eq: readonly [];
746
+ readonly sort: readonly ["created_at_ms"];
747
+ };
748
+ }, readonly ["id"]>;
749
+ }, {
750
+ api: {
751
+ register: (input: {
752
+ readonly apiKey: string;
753
+ readonly name: string;
754
+ readonly createdAtMs?: number;
755
+ }) => Promise<CreatedApiKey>;
756
+ provision: (input: {
757
+ readonly existingApiKey?: string;
758
+ readonly name: string;
759
+ }) => Promise<CreatedApiKey>;
760
+ create(input: {
761
+ readonly name: string;
762
+ }): Promise<{
763
+ readonly apiKey: string;
764
+ readonly record: ApiKeyMetadata;
765
+ }>;
766
+ list(): Promise<readonly ApiKeyMetadata[]>;
767
+ revoke(input: {
768
+ readonly id: string;
769
+ }): Promise<ApiKeyMetadata | null>;
770
+ };
771
+ clientAuth: {
772
+ varyHeaders: string[];
773
+ authenticate: (headers: Headers) => Promise<boolean>;
774
+ };
775
+ }, {
776
+ readonly clientAuth: true;
777
+ }>];
778
+ //#endregion
779
+ export { CloudFrontDownloadUrlOptions, type DynamoDBConfig, S3StorageConfig, S3StorageConfigWithDownloadUrl, cloudFrontDownloadUrl, dynamoDB, migrateDynamoDB, plugins, s3Storage };