@hot-updater/server 1.0.0-rc.1 → 1.0.0-rc.2
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/_virtual/_rolldown/runtime.cjs +1 -1
- package/dist/adapters/databaseConstraintErrors.cjs +0 -1
- package/dist/adapters/databasePluginUtils.cjs +0 -1
- package/dist/adapters/drizzle.cjs +10 -3
- package/dist/adapters/drizzle.d.cts +0 -1
- package/dist/adapters/drizzle.d.mts +0 -1
- package/dist/adapters/drizzle.mjs +11 -3
- package/dist/adapters/drizzleCrud.cjs +62 -1
- package/dist/adapters/drizzleCrud.mjs +61 -2
- package/dist/adapters/drizzleLazyDB.cjs +6 -1
- package/dist/adapters/drizzleLazyDB.mjs +6 -1
- package/dist/adapters/drizzleQuery.cjs +3 -2
- package/dist/adapters/drizzleQuery.mjs +3 -1
- package/dist/adapters/insightsTransaction.cjs +22 -0
- package/dist/adapters/insightsTransaction.mjs +22 -0
- package/dist/adapters/kysely.cjs +2 -1
- package/dist/adapters/kysely.d.cts +0 -1
- package/dist/adapters/kysely.d.mts +0 -1
- package/dist/adapters/kysely.mjs +3 -1
- package/dist/adapters/kyselyCrud.cjs +54 -3
- package/dist/adapters/kyselyCrud.mjs +54 -3
- package/dist/adapters/kyselyQuery.cjs +2 -2
- package/dist/adapters/kyselyQuery.mjs +2 -1
- package/dist/adapters/mongodb.cjs +27 -1
- package/dist/adapters/mongodb.d.cts +1 -1
- package/dist/adapters/mongodb.d.mts +1 -1
- package/dist/adapters/mongodb.mjs +28 -1
- package/dist/adapters/mongodbCollections.cjs +2 -0
- package/dist/adapters/mongodbCollections.mjs +2 -0
- package/dist/adapters/mongodbQuery.cjs +21 -4
- package/dist/adapters/mongodbQuery.mjs +21 -5
- package/dist/adapters/mongodbReads.cjs +91 -29
- package/dist/adapters/mongodbReads.mjs +92 -29
- package/dist/adapters/mongodbWrites.cjs +16 -2
- package/dist/adapters/mongodbWrites.mjs +18 -3
- package/dist/adapters/prisma.cjs +55 -7
- package/dist/adapters/prisma.d.cts +0 -1
- package/dist/adapters/prisma.d.mts +0 -1
- package/dist/adapters/prisma.mjs +56 -7
- package/dist/adapters/prismaQuery.cjs +0 -1
- package/dist/adapters/prismaRows.cjs +22 -1
- package/dist/adapters/prismaRows.mjs +22 -1
- package/dist/apiKeys.cjs +6 -2
- package/dist/apiKeys.d.cts +0 -1
- package/dist/apiKeys.d.mts +0 -1
- package/dist/apiKeys.mjs +3 -3
- package/dist/createHotUpdaterCore.cjs +24 -9
- package/dist/createHotUpdaterCore.d.cts +1 -1
- package/dist/createHotUpdaterCore.d.mts +1 -1
- package/dist/createHotUpdaterCore.mjs +23 -9
- package/dist/db/createBundleDiff.cjs +2 -2
- package/dist/db/createBundleDiff.d.cts +1 -5
- package/dist/db/createBundleDiff.d.mts +1 -5
- package/dist/db/databasePluginCore.cjs +0 -1
- package/dist/db/fixedMigrator.cjs +2 -2
- package/dist/db/fixedMigrator.mjs +2 -2
- package/dist/db/fixedMigratorMongo.cjs +6 -4
- package/dist/db/fixedMigratorMongo.mjs +6 -4
- package/dist/db/index.d.cts +0 -1
- package/dist/db/index.d.mts +0 -1
- package/dist/db/releaseCatalog.cjs +0 -1
- package/dist/db/releaseCatalog.d.cts +0 -1
- package/dist/db/releaseCatalog.d.mts +0 -1
- package/dist/db/schema/insightsCollation.cjs +14 -0
- package/dist/db/schema/insightsCollation.mjs +14 -0
- package/dist/db/schema/sql.cjs +11 -7
- package/dist/db/schema/sql.mjs +8 -8
- package/dist/db/schemaGenerators.cjs +28 -9
- package/dist/db/schemaGenerators.mjs +28 -9
- package/dist/db/schemaReadiness.cjs +2 -0
- package/dist/db/schemaReadiness.d.cts +1 -0
- package/dist/db/schemaReadiness.d.mts +1 -0
- package/dist/db/schemaReadiness.mjs +2 -0
- package/dist/db/sqlMigrationExecution.cjs +1 -1
- package/dist/db/sqlMigrationExecution.mjs +1 -0
- package/dist/db/types.cjs +3 -1
- package/dist/db/types.d.cts +3 -6
- package/dist/db/types.d.mts +3 -6
- package/dist/db/types.mjs +2 -2
- package/dist/db/updateArtifacts.cjs +0 -1
- package/dist/handler.d.cts +1 -2
- package/dist/handler.d.mts +1 -2
- package/dist/handlerReleaseCatalogRoutes.cjs +0 -1
- package/dist/handlerReleaseManagementRoutes.cjs +0 -1
- package/dist/handlerTypes.d.cts +0 -1
- package/dist/handlerTypes.d.mts +0 -1
- package/dist/handlerVersionRoutes.d.cts +1 -0
- package/dist/handlerVersionRoutes.d.mts +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +1 -1
- package/dist/insights/domain.d.cts +37 -69
- package/dist/insights/domain.d.mts +37 -69
- package/dist/insights/errors.cjs +1 -8
- package/dist/insights/errors.mjs +2 -8
- package/dist/insights/eventInput.cjs +49 -5
- package/dist/insights/eventInput.mjs +48 -6
- package/dist/insights/provider.cjs +314 -0
- package/dist/insights/provider.d.cts +6 -0
- package/dist/insights/provider.d.mts +6 -0
- package/dist/insights/provider.mjs +314 -0
- package/dist/insights/queryInput.cjs +78 -43
- package/dist/insights/queryInput.mjs +76 -40
- package/dist/insights/routes.cjs +20 -25
- package/dist/insights/routes.mjs +22 -27
- package/dist/insights/types.d.cts +27 -12
- package/dist/insights/types.d.mts +27 -12
- package/dist/node.d.cts +0 -1
- package/dist/node.d.mts +0 -1
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/schema/index.cjs +17 -3
- package/dist/schema/index.mjs +4 -4
- package/dist/schema/v1_0_0.cjs +72 -30
- package/dist/schema/v1_0_0.mjs +72 -31
- package/dist/storageAccess.cjs +0 -1
- package/dist/types/index.d.cts +0 -1
- package/dist/types/index.d.mts +0 -1
- package/package.json +7 -7
- package/src/adapters/databasePluginTestDatabase.ts +14 -0
- package/src/adapters/drizzle.spec.ts +99 -0
- package/src/adapters/drizzle.ts +21 -3
- package/src/adapters/drizzleCrud.ts +154 -2
- package/src/adapters/drizzleLazyDB.ts +17 -3
- package/src/adapters/insightsTransaction.ts +32 -0
- package/src/adapters/kysely.spec.ts +29 -0
- package/src/adapters/kysely.ts +10 -1
- package/src/adapters/kyselyCrud.ts +121 -0
- package/src/adapters/mongodb.integration.spec.ts +210 -0
- package/src/adapters/mongodb.spec.ts +69 -1
- package/src/adapters/mongodb.ts +66 -2
- package/src/adapters/mongodbCollections.ts +5 -0
- package/src/adapters/mongodbQuery.ts +32 -3
- package/src/adapters/mongodbReads.ts +69 -0
- package/src/adapters/mongodbTestClient.ts +41 -6
- package/src/adapters/mongodbTestFilter.ts +4 -1
- package/src/adapters/mongodbWrites.ts +27 -0
- package/src/adapters/prisma.spec.ts +97 -0
- package/src/adapters/prisma.ts +103 -3
- package/src/adapters/prismaRows.ts +37 -1
- package/src/adapters/prismaTestClient.ts +22 -5
- package/src/apiKeys.integration.spec.ts +1 -1
- package/src/createHotUpdaterCore.ts +21 -7
- package/src/db/databasePluginUpdateCheck.bench.ts +3 -0
- package/src/db/fixedMigrator.spec.ts +65 -0
- package/src/db/fixedMigratorMongo.spec.ts +56 -9
- package/src/db/fixedMigratorMongo.ts +10 -10
- package/src/db/index.spec.ts +8 -1
- package/src/db/schema/insightsCollation.ts +21 -0
- package/src/db/schema/sql.ts +8 -5
- package/src/db/schemaGenerators.ts +41 -13
- package/src/db/types.spec.ts +8 -0
- package/src/db/types.ts +10 -4
- package/src/handler-standalone.integration.spec.ts +5 -7
- package/src/index.ts +2 -2
- package/src/insights/domain.ts +39 -75
- package/src/insights/errors.ts +0 -7
- package/src/insights/eventInput.ts +60 -3
- package/src/insights/insights.integration.spec.ts +254 -17
- package/src/insights/provider.spec.ts +385 -0
- package/src/insights/provider.ts +591 -0
- package/src/insights/queryInput.ts +112 -73
- package/src/insights/routes.ts +37 -56
- package/src/insights/types.ts +47 -36
- package/src/schema/dsl-all-versions.spec.ts +3 -1
- package/src/schema/v1_0_0.spec.ts +77 -3
- package/src/schema/v1_0_0.ts +94 -30
- package/dist/insights/bounded/activeOverview.cjs +0 -87
- package/dist/insights/bounded/activeOverview.mjs +0 -85
- package/dist/insights/bounded/installationSearch.cjs +0 -42
- package/dist/insights/bounded/installationSearch.mjs +0 -42
- package/dist/insights/bounded/persistence.cjs +0 -39
- package/dist/insights/bounded/persistence.mjs +0 -38
- package/dist/insights/bounded/provider.cjs +0 -170
- package/dist/insights/bounded/provider.d.cts +0 -7
- package/dist/insights/bounded/provider.d.mts +0 -7
- package/dist/insights/bounded/provider.mjs +0 -170
- package/dist/insights/bounded/scan.cjs +0 -144
- package/dist/insights/bounded/scan.mjs +0 -138
- package/dist/insights/persistence.d.cts +0 -6
- package/dist/insights/persistence.d.mts +0 -6
- package/src/insights/bounded/activeOverview.spec.ts +0 -189
- package/src/insights/bounded/activeOverview.ts +0 -148
- package/src/insights/bounded/installationSearch.spec.ts +0 -130
- package/src/insights/bounded/installationSearch.ts +0 -69
- package/src/insights/bounded/persistence.ts +0 -43
- package/src/insights/bounded/provider.spec.ts +0 -219
- package/src/insights/bounded/provider.ts +0 -229
- package/src/insights/bounded/scan.ts +0 -235
- package/src/insights/persistence.ts +0 -10
|
@@ -14,15 +14,7 @@ type CreateBundleEventRequestBase = {
|
|
|
14
14
|
readonly toReleaseId: string | null;
|
|
15
15
|
};
|
|
16
16
|
type CreateBundleEventRequest = (CreateBundleEventRequestBase & {
|
|
17
|
-
readonly type: "UPDATE_APPLIED";
|
|
18
|
-
readonly fromBundleId: string;
|
|
19
|
-
readonly updateStrategy: "fingerprint" | "appVersion";
|
|
20
|
-
}) | (CreateBundleEventRequestBase & {
|
|
21
|
-
readonly type: "RECOVERED";
|
|
22
|
-
readonly fromBundleId: string;
|
|
23
|
-
readonly updateStrategy: "fingerprint" | "appVersion";
|
|
24
|
-
}) | (CreateBundleEventRequestBase & {
|
|
25
|
-
readonly type: "RELEASE_ADOPTED";
|
|
17
|
+
readonly type: "UPDATE_APPLIED" | "RECOVERED" | "RELEASE_ADOPTED";
|
|
26
18
|
readonly fromBundleId: string;
|
|
27
19
|
readonly updateStrategy: "fingerprint" | "appVersion";
|
|
28
20
|
}) | (CreateBundleEventRequestBase & {
|
|
@@ -30,92 +22,68 @@ type CreateBundleEventRequest = (CreateBundleEventRequestBase & {
|
|
|
30
22
|
readonly fromBundleId: null;
|
|
31
23
|
readonly updateStrategy: null;
|
|
32
24
|
});
|
|
33
|
-
type BundleEventSummary = {
|
|
34
|
-
readonly installed: number;
|
|
35
|
-
readonly recovered: number;
|
|
36
|
-
};
|
|
37
|
-
type BundleEventSummaryByBundle = BundleEventSummary & {
|
|
38
|
-
readonly bundleId: string;
|
|
39
|
-
};
|
|
40
|
-
type BundleEventInsightsWindow = "24h" | "7d" | "30d" | "all";
|
|
41
25
|
type ActiveInstallationWindow = "24h" | "7d" | "30d";
|
|
42
|
-
type
|
|
26
|
+
type EventHistoryRow = {
|
|
27
|
+
readonly id: string;
|
|
43
28
|
readonly installId: string;
|
|
29
|
+
readonly type: "UPDATE_APPLIED" | "RECOVERED" | "RELEASE_ADOPTED" | "UNCHANGED";
|
|
30
|
+
readonly fromBundleId: string | null;
|
|
31
|
+
readonly toBundleId: string;
|
|
44
32
|
readonly username: string | null;
|
|
45
33
|
readonly userId: string | null;
|
|
46
|
-
readonly lastKnownBundleId: string;
|
|
47
|
-
readonly latestStatus: "UPDATE_APPLIED" | "RECOVERED" | "RELEASE_ADOPTED" | "UNCHANGED";
|
|
48
34
|
readonly platform: "ios" | "android";
|
|
49
35
|
readonly appVersion: string;
|
|
50
36
|
readonly channel: string;
|
|
51
37
|
readonly cohort: string;
|
|
52
38
|
readonly receivedAtMs: number;
|
|
53
39
|
};
|
|
54
|
-
type InstallationHistoryRow = {
|
|
55
|
-
readonly id: string;
|
|
40
|
+
type InstallationHistoryRow = EventHistoryRow & {
|
|
56
41
|
readonly type: "UPDATE_APPLIED" | "RECOVERED";
|
|
57
42
|
readonly fromBundleId: string;
|
|
58
|
-
|
|
43
|
+
};
|
|
44
|
+
type InstallationRow = {
|
|
45
|
+
readonly installId: string;
|
|
59
46
|
readonly username: string | null;
|
|
60
47
|
readonly userId: string | null;
|
|
48
|
+
readonly lastKnownBundleId: string;
|
|
49
|
+
readonly latestStatus: EventHistoryRow["type"];
|
|
61
50
|
readonly platform: "ios" | "android";
|
|
62
51
|
readonly appVersion: string;
|
|
63
52
|
readonly channel: string;
|
|
64
53
|
readonly cohort: string;
|
|
65
54
|
readonly receivedAtMs: number;
|
|
66
55
|
};
|
|
67
|
-
type
|
|
68
|
-
readonly data: readonly
|
|
69
|
-
readonly
|
|
70
|
-
readonly total: number;
|
|
71
|
-
readonly limit: number;
|
|
72
|
-
readonly offset: number;
|
|
73
|
-
};
|
|
56
|
+
type CursorPage<T> = {
|
|
57
|
+
readonly data: readonly T[];
|
|
58
|
+
readonly nextCursor: string | null;
|
|
74
59
|
};
|
|
75
|
-
type
|
|
76
|
-
readonly
|
|
77
|
-
readonly value: number;
|
|
60
|
+
type EventCursorPage<T extends EventHistoryRow> = CursorPage<T> & {
|
|
61
|
+
readonly beforeReceivedAtMs: number;
|
|
78
62
|
};
|
|
79
|
-
type
|
|
80
|
-
readonly
|
|
81
|
-
readonly
|
|
63
|
+
type InsightsScope = {
|
|
64
|
+
readonly platform: "ios" | "android";
|
|
65
|
+
readonly channel: string;
|
|
82
66
|
};
|
|
83
|
-
type
|
|
84
|
-
readonly
|
|
85
|
-
readonly
|
|
86
|
-
readonly installed: readonly InsightsSeriesPoint[];
|
|
87
|
-
readonly recovered: readonly InsightsSeriesPoint[];
|
|
88
|
-
};
|
|
89
|
-
readonly cohorts: {
|
|
90
|
-
readonly installed: readonly InsightsCohortPoint[];
|
|
91
|
-
readonly recovered: readonly InsightsCohortPoint[];
|
|
92
|
-
};
|
|
93
|
-
readonly recentEvents: OffsetPaginationResult<InstallationHistoryRow>;
|
|
67
|
+
type InsightsBundleSelection = InsightsScope & {
|
|
68
|
+
readonly bundleId: string;
|
|
69
|
+
readonly outcome: "applied" | "recovered" | "adopted";
|
|
94
70
|
};
|
|
95
|
-
type
|
|
96
|
-
readonly
|
|
97
|
-
readonly
|
|
98
|
-
readonly bundleId: string;
|
|
99
|
-
readonly installations: number;
|
|
100
|
-
}[];
|
|
71
|
+
type InsightsCountMeasurement = {
|
|
72
|
+
readonly count: number;
|
|
73
|
+
readonly measuredAtMs: number;
|
|
101
74
|
};
|
|
102
|
-
type
|
|
103
|
-
readonly asOfMs: number;
|
|
75
|
+
type ReportingOverview = InsightsScope & {
|
|
104
76
|
readonly window: ActiveInstallationWindow;
|
|
105
|
-
readonly
|
|
106
|
-
readonly
|
|
107
|
-
readonly
|
|
77
|
+
readonly sinceMs: number;
|
|
78
|
+
readonly beforeReceivedAtMs: number;
|
|
79
|
+
readonly reportingInstallations: InsightsCountMeasurement;
|
|
80
|
+
readonly bundle?: {
|
|
108
81
|
readonly bundleId: string;
|
|
109
|
-
readonly
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
readonly
|
|
113
|
-
|
|
114
|
-
}[];
|
|
115
|
-
};
|
|
116
|
-
type ActiveInstallationInput = {
|
|
117
|
-
readonly window: ActiveInstallationWindow;
|
|
118
|
-
readonly userId?: string;
|
|
82
|
+
readonly reportingInstallations: InsightsCountMeasurement;
|
|
83
|
+
readonly appliedReports: InsightsCountMeasurement;
|
|
84
|
+
readonly recoveredReports: InsightsCountMeasurement;
|
|
85
|
+
readonly adoptedReports: InsightsCountMeasurement;
|
|
86
|
+
};
|
|
119
87
|
};
|
|
120
88
|
//#endregion
|
|
121
|
-
export {
|
|
89
|
+
export { ActiveInstallationWindow, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsScope, InstallationHistoryRow, InstallationRow, ReportingOverview };
|
|
@@ -14,15 +14,7 @@ type CreateBundleEventRequestBase = {
|
|
|
14
14
|
readonly toReleaseId: string | null;
|
|
15
15
|
};
|
|
16
16
|
type CreateBundleEventRequest = (CreateBundleEventRequestBase & {
|
|
17
|
-
readonly type: "UPDATE_APPLIED";
|
|
18
|
-
readonly fromBundleId: string;
|
|
19
|
-
readonly updateStrategy: "fingerprint" | "appVersion";
|
|
20
|
-
}) | (CreateBundleEventRequestBase & {
|
|
21
|
-
readonly type: "RECOVERED";
|
|
22
|
-
readonly fromBundleId: string;
|
|
23
|
-
readonly updateStrategy: "fingerprint" | "appVersion";
|
|
24
|
-
}) | (CreateBundleEventRequestBase & {
|
|
25
|
-
readonly type: "RELEASE_ADOPTED";
|
|
17
|
+
readonly type: "UPDATE_APPLIED" | "RECOVERED" | "RELEASE_ADOPTED";
|
|
26
18
|
readonly fromBundleId: string;
|
|
27
19
|
readonly updateStrategy: "fingerprint" | "appVersion";
|
|
28
20
|
}) | (CreateBundleEventRequestBase & {
|
|
@@ -30,92 +22,68 @@ type CreateBundleEventRequest = (CreateBundleEventRequestBase & {
|
|
|
30
22
|
readonly fromBundleId: null;
|
|
31
23
|
readonly updateStrategy: null;
|
|
32
24
|
});
|
|
33
|
-
type BundleEventSummary = {
|
|
34
|
-
readonly installed: number;
|
|
35
|
-
readonly recovered: number;
|
|
36
|
-
};
|
|
37
|
-
type BundleEventSummaryByBundle = BundleEventSummary & {
|
|
38
|
-
readonly bundleId: string;
|
|
39
|
-
};
|
|
40
|
-
type BundleEventInsightsWindow = "24h" | "7d" | "30d" | "all";
|
|
41
25
|
type ActiveInstallationWindow = "24h" | "7d" | "30d";
|
|
42
|
-
type
|
|
26
|
+
type EventHistoryRow = {
|
|
27
|
+
readonly id: string;
|
|
43
28
|
readonly installId: string;
|
|
29
|
+
readonly type: "UPDATE_APPLIED" | "RECOVERED" | "RELEASE_ADOPTED" | "UNCHANGED";
|
|
30
|
+
readonly fromBundleId: string | null;
|
|
31
|
+
readonly toBundleId: string;
|
|
44
32
|
readonly username: string | null;
|
|
45
33
|
readonly userId: string | null;
|
|
46
|
-
readonly lastKnownBundleId: string;
|
|
47
|
-
readonly latestStatus: "UPDATE_APPLIED" | "RECOVERED" | "RELEASE_ADOPTED" | "UNCHANGED";
|
|
48
34
|
readonly platform: "ios" | "android";
|
|
49
35
|
readonly appVersion: string;
|
|
50
36
|
readonly channel: string;
|
|
51
37
|
readonly cohort: string;
|
|
52
38
|
readonly receivedAtMs: number;
|
|
53
39
|
};
|
|
54
|
-
type InstallationHistoryRow = {
|
|
55
|
-
readonly id: string;
|
|
40
|
+
type InstallationHistoryRow = EventHistoryRow & {
|
|
56
41
|
readonly type: "UPDATE_APPLIED" | "RECOVERED";
|
|
57
42
|
readonly fromBundleId: string;
|
|
58
|
-
|
|
43
|
+
};
|
|
44
|
+
type InstallationRow = {
|
|
45
|
+
readonly installId: string;
|
|
59
46
|
readonly username: string | null;
|
|
60
47
|
readonly userId: string | null;
|
|
48
|
+
readonly lastKnownBundleId: string;
|
|
49
|
+
readonly latestStatus: EventHistoryRow["type"];
|
|
61
50
|
readonly platform: "ios" | "android";
|
|
62
51
|
readonly appVersion: string;
|
|
63
52
|
readonly channel: string;
|
|
64
53
|
readonly cohort: string;
|
|
65
54
|
readonly receivedAtMs: number;
|
|
66
55
|
};
|
|
67
|
-
type
|
|
68
|
-
readonly data: readonly
|
|
69
|
-
readonly
|
|
70
|
-
readonly total: number;
|
|
71
|
-
readonly limit: number;
|
|
72
|
-
readonly offset: number;
|
|
73
|
-
};
|
|
56
|
+
type CursorPage<T> = {
|
|
57
|
+
readonly data: readonly T[];
|
|
58
|
+
readonly nextCursor: string | null;
|
|
74
59
|
};
|
|
75
|
-
type
|
|
76
|
-
readonly
|
|
77
|
-
readonly value: number;
|
|
60
|
+
type EventCursorPage<T extends EventHistoryRow> = CursorPage<T> & {
|
|
61
|
+
readonly beforeReceivedAtMs: number;
|
|
78
62
|
};
|
|
79
|
-
type
|
|
80
|
-
readonly
|
|
81
|
-
readonly
|
|
63
|
+
type InsightsScope = {
|
|
64
|
+
readonly platform: "ios" | "android";
|
|
65
|
+
readonly channel: string;
|
|
82
66
|
};
|
|
83
|
-
type
|
|
84
|
-
readonly
|
|
85
|
-
readonly
|
|
86
|
-
readonly installed: readonly InsightsSeriesPoint[];
|
|
87
|
-
readonly recovered: readonly InsightsSeriesPoint[];
|
|
88
|
-
};
|
|
89
|
-
readonly cohorts: {
|
|
90
|
-
readonly installed: readonly InsightsCohortPoint[];
|
|
91
|
-
readonly recovered: readonly InsightsCohortPoint[];
|
|
92
|
-
};
|
|
93
|
-
readonly recentEvents: OffsetPaginationResult<InstallationHistoryRow>;
|
|
67
|
+
type InsightsBundleSelection = InsightsScope & {
|
|
68
|
+
readonly bundleId: string;
|
|
69
|
+
readonly outcome: "applied" | "recovered" | "adopted";
|
|
94
70
|
};
|
|
95
|
-
type
|
|
96
|
-
readonly
|
|
97
|
-
readonly
|
|
98
|
-
readonly bundleId: string;
|
|
99
|
-
readonly installations: number;
|
|
100
|
-
}[];
|
|
71
|
+
type InsightsCountMeasurement = {
|
|
72
|
+
readonly count: number;
|
|
73
|
+
readonly measuredAtMs: number;
|
|
101
74
|
};
|
|
102
|
-
type
|
|
103
|
-
readonly asOfMs: number;
|
|
75
|
+
type ReportingOverview = InsightsScope & {
|
|
104
76
|
readonly window: ActiveInstallationWindow;
|
|
105
|
-
readonly
|
|
106
|
-
readonly
|
|
107
|
-
readonly
|
|
77
|
+
readonly sinceMs: number;
|
|
78
|
+
readonly beforeReceivedAtMs: number;
|
|
79
|
+
readonly reportingInstallations: InsightsCountMeasurement;
|
|
80
|
+
readonly bundle?: {
|
|
108
81
|
readonly bundleId: string;
|
|
109
|
-
readonly
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
readonly
|
|
113
|
-
|
|
114
|
-
}[];
|
|
115
|
-
};
|
|
116
|
-
type ActiveInstallationInput = {
|
|
117
|
-
readonly window: ActiveInstallationWindow;
|
|
118
|
-
readonly userId?: string;
|
|
82
|
+
readonly reportingInstallations: InsightsCountMeasurement;
|
|
83
|
+
readonly appliedReports: InsightsCountMeasurement;
|
|
84
|
+
readonly recoveredReports: InsightsCountMeasurement;
|
|
85
|
+
readonly adoptedReports: InsightsCountMeasurement;
|
|
86
|
+
};
|
|
119
87
|
};
|
|
120
88
|
//#endregion
|
|
121
|
-
export {
|
|
89
|
+
export { ActiveInstallationWindow, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsScope, InstallationHistoryRow, InstallationRow, ReportingOverview };
|
package/dist/insights/errors.cjs
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
//#region src/insights/errors.ts
|
|
2
|
-
var InsightsScanLimitExceededError = class extends Error {
|
|
3
|
-
constructor(limit) {
|
|
4
|
-
super(`Insights event scan exceeded ${limit} rows.`);
|
|
5
|
-
this.limit = limit;
|
|
6
|
-
this.name = "InsightsScanLimitExceededError";
|
|
7
|
-
}
|
|
8
|
-
};
|
|
9
2
|
var InsightsBadRequestError = class extends Error {
|
|
10
3
|
name = "InsightsBadRequestError";
|
|
11
4
|
};
|
|
12
5
|
var InsightsPayloadTooLargeError = class extends Error {
|
|
6
|
+
maximumBytes;
|
|
13
7
|
name = "InsightsPayloadTooLargeError";
|
|
14
8
|
constructor(maximumBytes) {
|
|
15
9
|
super(`Event payload exceeds ${maximumBytes} bytes`);
|
|
@@ -19,4 +13,3 @@ var InsightsPayloadTooLargeError = class extends Error {
|
|
|
19
13
|
//#endregion
|
|
20
14
|
exports.InsightsBadRequestError = InsightsBadRequestError;
|
|
21
15
|
exports.InsightsPayloadTooLargeError = InsightsPayloadTooLargeError;
|
|
22
|
-
exports.InsightsScanLimitExceededError = InsightsScanLimitExceededError;
|
package/dist/insights/errors.mjs
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
//#region src/insights/errors.ts
|
|
2
|
-
var InsightsScanLimitExceededError = class extends Error {
|
|
3
|
-
constructor(limit) {
|
|
4
|
-
super(`Insights event scan exceeded ${limit} rows.`);
|
|
5
|
-
this.limit = limit;
|
|
6
|
-
this.name = "InsightsScanLimitExceededError";
|
|
7
|
-
}
|
|
8
|
-
};
|
|
9
2
|
var InsightsBadRequestError = class extends Error {
|
|
10
3
|
name = "InsightsBadRequestError";
|
|
11
4
|
};
|
|
12
5
|
var InsightsPayloadTooLargeError = class extends Error {
|
|
6
|
+
maximumBytes;
|
|
13
7
|
name = "InsightsPayloadTooLargeError";
|
|
14
8
|
constructor(maximumBytes) {
|
|
15
9
|
super(`Event payload exceeds ${maximumBytes} bytes`);
|
|
@@ -17,4 +11,4 @@ var InsightsPayloadTooLargeError = class extends Error {
|
|
|
17
11
|
}
|
|
18
12
|
};
|
|
19
13
|
//#endregion
|
|
20
|
-
export { InsightsBadRequestError, InsightsPayloadTooLargeError
|
|
14
|
+
export { InsightsBadRequestError, InsightsPayloadTooLargeError };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
const require_errors = require("./errors.cjs");
|
|
2
|
+
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
2
3
|
//#region src/insights/eventInput.ts
|
|
3
4
|
const MAX_EVENT_STRING_LENGTH = 1024;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
5
|
+
const MAX_IDENTITY_LENGTH = 255;
|
|
6
|
+
const EVENT_BODY_MAX_BYTES = 16384;
|
|
7
|
+
const eventKeys = /* @__PURE__ */ new Set([
|
|
6
8
|
"type",
|
|
7
9
|
"installId",
|
|
8
10
|
"toBundleId",
|
|
@@ -24,13 +26,18 @@ function isRecord(value) {
|
|
|
24
26
|
}
|
|
25
27
|
function requireStringField(payload, key) {
|
|
26
28
|
const value = payload[key];
|
|
27
|
-
if (typeof value !== "string" || value.length === 0 || value.length > MAX_EVENT_STRING_LENGTH) throw new require_errors.InsightsBadRequestError(`Invalid event field: ${key}`);
|
|
29
|
+
if (typeof value !== "string" || value.length === 0 || value.length > MAX_EVENT_STRING_LENGTH || new TextDecoder("utf-8", { ignoreBOM: true }).decode(new TextEncoder().encode(value)) !== value) throw new require_errors.InsightsBadRequestError(`Invalid event field: ${key}`);
|
|
28
30
|
return value;
|
|
29
31
|
}
|
|
30
32
|
function requireNullableStringField(payload, key) {
|
|
31
33
|
if (payload[key] === null) return null;
|
|
32
34
|
return requireStringField(payload, key);
|
|
33
35
|
}
|
|
36
|
+
function requireIdentityField(payload, key) {
|
|
37
|
+
const value = requireStringField(payload, key);
|
|
38
|
+
if (value.length > MAX_IDENTITY_LENGTH) throw new require_errors.InsightsBadRequestError(`Invalid event field: ${key}`);
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
34
41
|
async function readBoundedText(request) {
|
|
35
42
|
const contentLength = request.headers.get("content-length");
|
|
36
43
|
const declaredByteLength = Number(contentLength);
|
|
@@ -66,9 +73,9 @@ function requireEvent(payload) {
|
|
|
66
73
|
const platform = requireStringField(payload, "platform");
|
|
67
74
|
if (platform !== "ios" && platform !== "android") throw new require_errors.InsightsBadRequestError("Invalid event field: platform");
|
|
68
75
|
const base = {
|
|
69
|
-
installId:
|
|
76
|
+
installId: requireIdentityField(payload, "installId"),
|
|
70
77
|
toBundleId: requireStringField(payload, "toBundleId"),
|
|
71
|
-
...payload.userId === void 0 ? {} : { userId:
|
|
78
|
+
...payload.userId === void 0 ? {} : { userId: requireIdentityField(payload, "userId") },
|
|
72
79
|
...payload.username === void 0 ? {} : { username: requireStringField(payload, "username") },
|
|
73
80
|
platform,
|
|
74
81
|
appVersion: requireStringField(payload, "appVersion"),
|
|
@@ -107,5 +114,42 @@ function requireEvent(payload) {
|
|
|
107
114
|
async function parseBundleEventRequest(request) {
|
|
108
115
|
return requireEvent(await parseJson(request));
|
|
109
116
|
}
|
|
117
|
+
function createBundleEventRow(input) {
|
|
118
|
+
input = requireEvent(input);
|
|
119
|
+
const base = {
|
|
120
|
+
app_version: input.appVersion,
|
|
121
|
+
channel: input.channel,
|
|
122
|
+
cohort: input.cohort,
|
|
123
|
+
fingerprint_hash: input.fingerprintHash,
|
|
124
|
+
from_release_id: input.fromReleaseId,
|
|
125
|
+
id: (0, _hot_updater_plugin_core.createUUIDv7)(),
|
|
126
|
+
install_id: input.installId,
|
|
127
|
+
platform: input.platform,
|
|
128
|
+
received_at_ms: Date.now(),
|
|
129
|
+
sdk_version: input.sdkVersion ?? null,
|
|
130
|
+
to_bundle_id: input.toBundleId,
|
|
131
|
+
to_release_id: input.toReleaseId,
|
|
132
|
+
user_id: input.userId ?? null,
|
|
133
|
+
username: input.username ?? null
|
|
134
|
+
};
|
|
135
|
+
switch (input.type) {
|
|
136
|
+
case "UPDATE_APPLIED":
|
|
137
|
+
case "RECOVERED":
|
|
138
|
+
case "RELEASE_ADOPTED": return {
|
|
139
|
+
...base,
|
|
140
|
+
from_bundle_id: input.fromBundleId,
|
|
141
|
+
type: input.type,
|
|
142
|
+
update_strategy: input.updateStrategy
|
|
143
|
+
};
|
|
144
|
+
case "UNCHANGED": return {
|
|
145
|
+
...base,
|
|
146
|
+
from_bundle_id: null,
|
|
147
|
+
type: input.type,
|
|
148
|
+
update_strategy: null
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
110
152
|
//#endregion
|
|
153
|
+
exports.EVENT_BODY_MAX_BYTES = EVENT_BODY_MAX_BYTES;
|
|
154
|
+
exports.createBundleEventRow = createBundleEventRow;
|
|
111
155
|
exports.parseBundleEventRequest = parseBundleEventRequest;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { InsightsBadRequestError, InsightsPayloadTooLargeError } from "./errors.mjs";
|
|
2
|
+
import { createUUIDv7 } from "@hot-updater/plugin-core";
|
|
2
3
|
//#region src/insights/eventInput.ts
|
|
3
4
|
const MAX_EVENT_STRING_LENGTH = 1024;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
5
|
+
const MAX_IDENTITY_LENGTH = 255;
|
|
6
|
+
const EVENT_BODY_MAX_BYTES = 16384;
|
|
7
|
+
const eventKeys = /* @__PURE__ */ new Set([
|
|
6
8
|
"type",
|
|
7
9
|
"installId",
|
|
8
10
|
"toBundleId",
|
|
@@ -24,13 +26,18 @@ function isRecord(value) {
|
|
|
24
26
|
}
|
|
25
27
|
function requireStringField(payload, key) {
|
|
26
28
|
const value = payload[key];
|
|
27
|
-
if (typeof value !== "string" || value.length === 0 || value.length > MAX_EVENT_STRING_LENGTH) throw new InsightsBadRequestError(`Invalid event field: ${key}`);
|
|
29
|
+
if (typeof value !== "string" || value.length === 0 || value.length > MAX_EVENT_STRING_LENGTH || new TextDecoder("utf-8", { ignoreBOM: true }).decode(new TextEncoder().encode(value)) !== value) throw new InsightsBadRequestError(`Invalid event field: ${key}`);
|
|
28
30
|
return value;
|
|
29
31
|
}
|
|
30
32
|
function requireNullableStringField(payload, key) {
|
|
31
33
|
if (payload[key] === null) return null;
|
|
32
34
|
return requireStringField(payload, key);
|
|
33
35
|
}
|
|
36
|
+
function requireIdentityField(payload, key) {
|
|
37
|
+
const value = requireStringField(payload, key);
|
|
38
|
+
if (value.length > MAX_IDENTITY_LENGTH) throw new InsightsBadRequestError(`Invalid event field: ${key}`);
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
34
41
|
async function readBoundedText(request) {
|
|
35
42
|
const contentLength = request.headers.get("content-length");
|
|
36
43
|
const declaredByteLength = Number(contentLength);
|
|
@@ -66,9 +73,9 @@ function requireEvent(payload) {
|
|
|
66
73
|
const platform = requireStringField(payload, "platform");
|
|
67
74
|
if (platform !== "ios" && platform !== "android") throw new InsightsBadRequestError("Invalid event field: platform");
|
|
68
75
|
const base = {
|
|
69
|
-
installId:
|
|
76
|
+
installId: requireIdentityField(payload, "installId"),
|
|
70
77
|
toBundleId: requireStringField(payload, "toBundleId"),
|
|
71
|
-
...payload.userId === void 0 ? {} : { userId:
|
|
78
|
+
...payload.userId === void 0 ? {} : { userId: requireIdentityField(payload, "userId") },
|
|
72
79
|
...payload.username === void 0 ? {} : { username: requireStringField(payload, "username") },
|
|
73
80
|
platform,
|
|
74
81
|
appVersion: requireStringField(payload, "appVersion"),
|
|
@@ -107,5 +114,40 @@ function requireEvent(payload) {
|
|
|
107
114
|
async function parseBundleEventRequest(request) {
|
|
108
115
|
return requireEvent(await parseJson(request));
|
|
109
116
|
}
|
|
117
|
+
function createBundleEventRow(input) {
|
|
118
|
+
input = requireEvent(input);
|
|
119
|
+
const base = {
|
|
120
|
+
app_version: input.appVersion,
|
|
121
|
+
channel: input.channel,
|
|
122
|
+
cohort: input.cohort,
|
|
123
|
+
fingerprint_hash: input.fingerprintHash,
|
|
124
|
+
from_release_id: input.fromReleaseId,
|
|
125
|
+
id: createUUIDv7(),
|
|
126
|
+
install_id: input.installId,
|
|
127
|
+
platform: input.platform,
|
|
128
|
+
received_at_ms: Date.now(),
|
|
129
|
+
sdk_version: input.sdkVersion ?? null,
|
|
130
|
+
to_bundle_id: input.toBundleId,
|
|
131
|
+
to_release_id: input.toReleaseId,
|
|
132
|
+
user_id: input.userId ?? null,
|
|
133
|
+
username: input.username ?? null
|
|
134
|
+
};
|
|
135
|
+
switch (input.type) {
|
|
136
|
+
case "UPDATE_APPLIED":
|
|
137
|
+
case "RECOVERED":
|
|
138
|
+
case "RELEASE_ADOPTED": return {
|
|
139
|
+
...base,
|
|
140
|
+
from_bundle_id: input.fromBundleId,
|
|
141
|
+
type: input.type,
|
|
142
|
+
update_strategy: input.updateStrategy
|
|
143
|
+
};
|
|
144
|
+
case "UNCHANGED": return {
|
|
145
|
+
...base,
|
|
146
|
+
from_bundle_id: null,
|
|
147
|
+
type: input.type,
|
|
148
|
+
update_strategy: null
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
110
152
|
//#endregion
|
|
111
|
-
export { parseBundleEventRequest };
|
|
153
|
+
export { EVENT_BODY_MAX_BYTES, createBundleEventRow, parseBundleEventRequest };
|