@hot-updater/server 0.28.0 → 0.29.0
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/adapters/drizzle.cjs +7 -7
- package/dist/adapters/drizzle.mjs +2 -0
- package/dist/adapters/kysely.cjs +7 -7
- package/dist/adapters/kysely.mjs +2 -0
- package/dist/adapters/mongodb.cjs +7 -7
- package/dist/adapters/mongodb.mjs +2 -0
- package/dist/adapters/prisma.cjs +7 -7
- package/dist/adapters/prisma.mjs +2 -0
- package/dist/calculatePagination.cjs +1 -3
- package/dist/{calculatePagination.js → calculatePagination.mjs} +1 -2
- package/dist/db/index.cjs +24 -15
- package/dist/db/index.d.cts +12 -9
- package/dist/db/index.d.mts +30 -0
- package/dist/db/index.mjs +45 -0
- package/dist/db/ormCore.cjs +247 -138
- package/dist/db/ormCore.d.cts +35 -17
- package/dist/db/ormCore.d.mts +44 -0
- package/dist/db/ormCore.mjs +386 -0
- package/dist/db/pluginCore.cjs +145 -40
- package/dist/db/pluginCore.mjs +176 -0
- package/dist/db/types.cjs +1 -3
- package/dist/db/types.d.cts +14 -21
- package/dist/db/types.d.mts +24 -0
- package/dist/db/{types.js → types.mjs} +1 -2
- package/dist/handler.cjs +117 -48
- package/dist/handler.d.cts +28 -18
- package/dist/handler.d.mts +47 -0
- package/dist/handler.mjs +217 -0
- package/dist/index.cjs +5 -5
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +5 -0
- package/dist/index.mjs +4 -0
- package/dist/internalRouter.cjs +54 -0
- package/dist/internalRouter.mjs +52 -0
- package/dist/node.cjs +2 -3
- package/dist/node.d.cts +0 -1
- package/dist/{node.d.ts → node.d.mts} +1 -2
- package/dist/{node.js → node.mjs} +1 -2
- package/dist/route.cjs +7 -0
- package/dist/route.mjs +7 -0
- package/dist/runtime.cjs +42 -0
- package/dist/runtime.d.cts +21 -0
- package/dist/runtime.d.mts +21 -0
- package/dist/runtime.mjs +40 -0
- package/dist/schema/v0_21_0.cjs +1 -5
- package/dist/schema/{v0_21_0.js → v0_21_0.mjs} +1 -3
- package/dist/schema/v0_29_0.cjs +24 -0
- package/dist/schema/v0_29_0.mjs +24 -0
- package/dist/types/{index.d.ts → index.d.mts} +1 -1
- package/package.json +18 -18
- package/src/db/index.spec.ts +64 -29
- package/src/db/index.ts +55 -35
- package/src/db/ormCore.ts +438 -210
- package/src/db/ormUpdateCheck.bench.ts +261 -0
- package/src/db/pluginCore.ts +298 -49
- package/src/db/pluginUpdateCheck.bench.ts +250 -0
- package/src/db/types.ts +52 -27
- package/src/{handler-standalone-integration.spec.ts → handler-standalone.integration.spec.ts} +106 -0
- package/src/handler.spec.ts +156 -0
- package/src/handler.ts +296 -77
- package/src/internalRouter.ts +104 -0
- package/src/route.ts +7 -0
- package/src/runtime.spec.ts +277 -0
- package/src/runtime.ts +121 -0
- package/src/schema/v0_29_0.ts +26 -0
- package/dist/_virtual/rolldown_runtime.cjs +0 -25
- package/dist/adapters/drizzle.js +0 -3
- package/dist/adapters/kysely.js +0 -3
- package/dist/adapters/mongodb.js +0 -3
- package/dist/adapters/prisma.js +0 -3
- package/dist/db/index.d.ts +0 -27
- package/dist/db/index.js +0 -36
- package/dist/db/ormCore.d.ts +0 -26
- package/dist/db/ormCore.js +0 -273
- package/dist/db/pluginCore.js +0 -69
- package/dist/db/types.d.ts +0 -31
- package/dist/handler.d.ts +0 -37
- package/dist/handler.js +0 -146
- package/dist/index.d.ts +0 -5
- package/dist/index.js +0 -5
- /package/dist/adapters/{drizzle.d.ts → drizzle.d.mts} +0 -0
- /package/dist/adapters/{kysely.d.ts → kysely.d.mts} +0 -0
- /package/dist/adapters/{mongodb.d.ts → mongodb.d.mts} +0 -0
- /package/dist/adapters/{prisma.d.ts → prisma.d.mts} +0 -0
package/dist/db/ormCore.cjs
CHANGED
|
@@ -1,25 +1,66 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
let
|
|
5
|
-
|
|
6
|
-
let __hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
7
|
-
__hot_updater_plugin_core = require_rolldown_runtime.__toESM(__hot_updater_plugin_core);
|
|
1
|
+
const require_calculatePagination = require("../calculatePagination.cjs");
|
|
2
|
+
const require_v0_21_0 = require("../schema/v0_21_0.cjs");
|
|
3
|
+
const require_v0_29_0 = require("../schema/v0_29_0.cjs");
|
|
4
|
+
let _hot_updater_core = require("@hot-updater/core");
|
|
5
|
+
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
8
6
|
let fumadb = require("fumadb");
|
|
9
|
-
fumadb = require_rolldown_runtime.__toESM(fumadb);
|
|
10
|
-
|
|
11
7
|
//#region src/db/ormCore.ts
|
|
8
|
+
const parseTargetCohorts = (value) => {
|
|
9
|
+
if (!value) return null;
|
|
10
|
+
if (Array.isArray(value)) return value.filter((v) => typeof v === "string");
|
|
11
|
+
if (typeof value === "string") try {
|
|
12
|
+
const parsed = JSON.parse(value);
|
|
13
|
+
if (Array.isArray(parsed)) return parsed.filter((v) => typeof v === "string");
|
|
14
|
+
} catch {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
};
|
|
19
|
+
const schemas = [require_v0_21_0.v0_21_0, require_v0_29_0.v0_29_0];
|
|
20
|
+
const getLastItem = (items) => items.at(-1);
|
|
12
21
|
const HotUpdaterDB = (0, fumadb.fumadb)({
|
|
13
22
|
namespace: "hot_updater",
|
|
14
|
-
schemas
|
|
23
|
+
schemas
|
|
15
24
|
});
|
|
16
25
|
function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
17
26
|
const client = HotUpdaterDB.client(database);
|
|
27
|
+
const UPDATE_CHECK_PAGE_SIZE = 100;
|
|
28
|
+
const isMongoAdapter = client.adapter.name.toLowerCase().includes("mongodb");
|
|
29
|
+
const ensureORM = async () => {
|
|
30
|
+
const lastSchemaVersion = getLastItem(schemas).version;
|
|
31
|
+
try {
|
|
32
|
+
const currentVersion = await client.createMigrator().getVersion();
|
|
33
|
+
if (currentVersion === void 0) throw new Error("Database is not initialized. Please run 'npx hot-updater migrate' to set up the database schema.");
|
|
34
|
+
if (currentVersion !== lastSchemaVersion) throw new Error(`Database schema version mismatch. Expected version ${lastSchemaVersion}, but database is on version ${currentVersion}. Please run 'npx hot-updater migrate' to update your database schema.`);
|
|
35
|
+
return client.orm(lastSchemaVersion);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
if (error instanceof Error && error.message.includes("doesn't support migration")) return client.orm(lastSchemaVersion);
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const buildBundleWhere = (where) => (b) => {
|
|
42
|
+
if (where?.id?.in && where.id.in.length === 0) return false;
|
|
43
|
+
if (where?.targetAppVersionIn && where.targetAppVersionIn.length === 0) return false;
|
|
44
|
+
const conditions = [];
|
|
45
|
+
if (where?.channel !== void 0) conditions.push(b("channel", "=", where.channel));
|
|
46
|
+
if (where?.platform !== void 0) conditions.push(b("platform", "=", where.platform));
|
|
47
|
+
if (where?.enabled !== void 0) conditions.push(b("enabled", "=", where.enabled));
|
|
48
|
+
if (where?.id?.eq !== void 0) conditions.push(b("id", "=", where.id.eq));
|
|
49
|
+
if (where?.id?.gt !== void 0) conditions.push(b("id", ">", where.id.gt));
|
|
50
|
+
if (where?.id?.gte !== void 0) conditions.push(b("id", ">=", where.id.gte));
|
|
51
|
+
if (where?.id?.lt !== void 0) conditions.push(b("id", "<", where.id.lt));
|
|
52
|
+
if (where?.id?.lte !== void 0) conditions.push(b("id", "<=", where.id.lte));
|
|
53
|
+
if (where?.id?.in) conditions.push(b("id", "in", where.id.in));
|
|
54
|
+
if (where?.targetAppVersionNotNull) conditions.push(b.isNotNull("target_app_version"));
|
|
55
|
+
if (where?.targetAppVersion !== void 0) conditions.push(where.targetAppVersion === null ? b.isNull("target_app_version") : b("target_app_version", "=", where.targetAppVersion));
|
|
56
|
+
if (where?.targetAppVersionIn) conditions.push(b("target_app_version", "in", where.targetAppVersionIn));
|
|
57
|
+
if (where?.fingerprintHash !== void 0) conditions.push(where.fingerprintHash === null ? b.isNull("fingerprint_hash") : b("fingerprint_hash", "=", where.fingerprintHash));
|
|
58
|
+
return conditions.length > 0 ? b.and(...conditions) : true;
|
|
59
|
+
};
|
|
18
60
|
return {
|
|
19
61
|
api: {
|
|
20
62
|
async getBundleById(id) {
|
|
21
|
-
const
|
|
22
|
-
const result = await client.orm(version).findFirst("bundles", {
|
|
63
|
+
const result = await (await ensureORM()).findFirst("bundles", {
|
|
23
64
|
select: [
|
|
24
65
|
"id",
|
|
25
66
|
"platform",
|
|
@@ -32,7 +73,9 @@ function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
|
32
73
|
"storage_uri",
|
|
33
74
|
"target_app_version",
|
|
34
75
|
"fingerprint_hash",
|
|
35
|
-
"metadata"
|
|
76
|
+
"metadata",
|
|
77
|
+
"rollout_cohort_count",
|
|
78
|
+
"target_cohorts"
|
|
36
79
|
],
|
|
37
80
|
where: (b) => b("id", "=", id)
|
|
38
81
|
});
|
|
@@ -48,12 +91,13 @@ function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
|
48
91
|
channel: result.channel,
|
|
49
92
|
storageUri: result.storage_uri,
|
|
50
93
|
targetAppVersion: result.target_app_version ?? null,
|
|
51
|
-
fingerprintHash: result.fingerprint_hash ?? null
|
|
94
|
+
fingerprintHash: result.fingerprint_hash ?? null,
|
|
95
|
+
rolloutCohortCount: result.rollout_cohort_count ?? _hot_updater_core.DEFAULT_ROLLOUT_COHORT_COUNT,
|
|
96
|
+
targetCohorts: parseTargetCohorts(result.target_cohorts)
|
|
52
97
|
};
|
|
53
98
|
},
|
|
54
99
|
async getUpdateInfo(args) {
|
|
55
|
-
const
|
|
56
|
-
const orm = client.orm(version);
|
|
100
|
+
const orm = await ensureORM();
|
|
57
101
|
const toUpdateInfo = (row, status) => ({
|
|
58
102
|
id: row.id,
|
|
59
103
|
shouldForceUpdate: status === "ROLLBACK" ? true : Boolean(row.should_force_update),
|
|
@@ -63,145 +107,210 @@ function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
|
63
107
|
fileHash: row.file_hash ?? null
|
|
64
108
|
});
|
|
65
109
|
const INIT_BUNDLE_ROLLBACK_UPDATE_INFO = {
|
|
66
|
-
id:
|
|
110
|
+
id: _hot_updater_core.NIL_UUID,
|
|
67
111
|
message: null,
|
|
68
112
|
shouldForceUpdate: true,
|
|
69
113
|
status: "ROLLBACK",
|
|
70
114
|
storageUri: null,
|
|
71
115
|
fileHash: null
|
|
72
116
|
};
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
const isEligibleForUpdate = (row, cohort) => {
|
|
118
|
+
return (0, _hot_updater_core.isCohortEligibleForUpdate)(row.id, cohort, row.rollout_cohort_count ?? null, parseTargetCohorts(row.target_cohorts));
|
|
119
|
+
};
|
|
120
|
+
const findUpdateInfoByScanning = async ({ args, where, isCandidate }) => {
|
|
121
|
+
if (isMongoAdapter) {
|
|
122
|
+
const rows = await orm.findMany("bundles", {
|
|
123
|
+
select: [
|
|
124
|
+
"id",
|
|
125
|
+
"should_force_update",
|
|
126
|
+
"message",
|
|
127
|
+
"storage_uri",
|
|
128
|
+
"file_hash",
|
|
129
|
+
"rollout_cohort_count",
|
|
130
|
+
"target_cohorts",
|
|
131
|
+
"target_app_version",
|
|
132
|
+
"fingerprint_hash"
|
|
133
|
+
],
|
|
134
|
+
where: buildBundleWhere(where)
|
|
135
|
+
});
|
|
136
|
+
rows.sort((a, b) => b.id.localeCompare(a.id));
|
|
137
|
+
for (const row of rows) {
|
|
138
|
+
if (!isCandidate(row)) continue;
|
|
139
|
+
if (args.bundleId === _hot_updater_core.NIL_UUID) {
|
|
140
|
+
if (isEligibleForUpdate(row, args.cohort)) return toUpdateInfo(row, "UPDATE");
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const compareResult = row.id.localeCompare(args.bundleId);
|
|
144
|
+
if (compareResult > 0) {
|
|
145
|
+
if (isEligibleForUpdate(row, args.cohort)) return toUpdateInfo(row, "UPDATE");
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (compareResult === 0) {
|
|
149
|
+
if (isEligibleForUpdate(row, args.cohort)) return null;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
return toUpdateInfo(row, "ROLLBACK");
|
|
153
|
+
}
|
|
154
|
+
if (args.bundleId === _hot_updater_core.NIL_UUID) return null;
|
|
155
|
+
if (args.minBundleId && args.bundleId.localeCompare(args.minBundleId) <= 0) return null;
|
|
156
|
+
return INIT_BUNDLE_ROLLBACK_UPDATE_INFO;
|
|
101
157
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
158
|
+
let offset = 0;
|
|
159
|
+
while (true) {
|
|
160
|
+
const rows = await orm.findMany("bundles", {
|
|
161
|
+
select: [
|
|
162
|
+
"id",
|
|
163
|
+
"should_force_update",
|
|
164
|
+
"message",
|
|
165
|
+
"storage_uri",
|
|
166
|
+
"file_hash",
|
|
167
|
+
"rollout_cohort_count",
|
|
168
|
+
"target_cohorts",
|
|
169
|
+
"target_app_version",
|
|
170
|
+
"fingerprint_hash"
|
|
171
|
+
],
|
|
172
|
+
where: buildBundleWhere(where),
|
|
173
|
+
orderBy: [["id", "desc"]],
|
|
174
|
+
limit: UPDATE_CHECK_PAGE_SIZE,
|
|
175
|
+
offset
|
|
176
|
+
});
|
|
177
|
+
for (const row of rows) {
|
|
178
|
+
if (!isCandidate(row)) continue;
|
|
179
|
+
if (args.bundleId === _hot_updater_core.NIL_UUID) {
|
|
180
|
+
if (isEligibleForUpdate(row, args.cohort)) return toUpdateInfo(row, "UPDATE");
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const compareResult = row.id.localeCompare(args.bundleId);
|
|
184
|
+
if (compareResult > 0) {
|
|
185
|
+
if (isEligibleForUpdate(row, args.cohort)) return toUpdateInfo(row, "UPDATE");
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (compareResult === 0) {
|
|
189
|
+
if (isEligibleForUpdate(row, args.cohort)) return null;
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
return toUpdateInfo(row, "ROLLBACK");
|
|
193
|
+
}
|
|
194
|
+
if (rows.length < UPDATE_CHECK_PAGE_SIZE) break;
|
|
195
|
+
offset += UPDATE_CHECK_PAGE_SIZE;
|
|
105
196
|
}
|
|
106
|
-
if (
|
|
107
|
-
if (
|
|
108
|
-
if (minBundleId && bundleId.localeCompare(minBundleId) <= 0) return null;
|
|
197
|
+
if (args.bundleId === _hot_updater_core.NIL_UUID) return null;
|
|
198
|
+
if (args.minBundleId && args.bundleId.localeCompare(args.minBundleId) <= 0) return null;
|
|
109
199
|
return INIT_BUNDLE_ROLLBACK_UPDATE_INFO;
|
|
110
200
|
};
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
"
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
201
|
+
const appVersionStrategy = async ({ platform, appVersion, bundleId, minBundleId = _hot_updater_core.NIL_UUID, channel = "production", cohort }) => {
|
|
202
|
+
return findUpdateInfoByScanning({
|
|
203
|
+
args: {
|
|
204
|
+
_updateStrategy: "appVersion",
|
|
205
|
+
platform,
|
|
206
|
+
appVersion,
|
|
207
|
+
bundleId,
|
|
208
|
+
minBundleId,
|
|
209
|
+
channel,
|
|
210
|
+
cohort
|
|
211
|
+
},
|
|
212
|
+
where: {
|
|
213
|
+
enabled: true,
|
|
214
|
+
platform,
|
|
215
|
+
channel,
|
|
216
|
+
id: { gte: minBundleId },
|
|
217
|
+
targetAppVersionNotNull: true
|
|
218
|
+
},
|
|
219
|
+
isCandidate: (row) => !!row.target_app_version && (0, _hot_updater_plugin_core.semverSatisfies)(row.target_app_version, appVersion)
|
|
220
|
+
});
|
|
221
|
+
};
|
|
222
|
+
const fingerprintStrategy = async ({ platform, fingerprintHash, bundleId, minBundleId = _hot_updater_core.NIL_UUID, channel = "production", cohort }) => {
|
|
223
|
+
return findUpdateInfoByScanning({
|
|
224
|
+
args: {
|
|
225
|
+
_updateStrategy: "fingerprint",
|
|
226
|
+
platform,
|
|
227
|
+
fingerprintHash,
|
|
228
|
+
bundleId,
|
|
229
|
+
minBundleId,
|
|
230
|
+
channel,
|
|
231
|
+
cohort
|
|
232
|
+
},
|
|
233
|
+
where: {
|
|
234
|
+
enabled: true,
|
|
235
|
+
platform,
|
|
236
|
+
channel,
|
|
237
|
+
id: { gte: minBundleId },
|
|
238
|
+
fingerprintHash
|
|
239
|
+
},
|
|
240
|
+
isCandidate: (row) => row.fingerprint_hash === fingerprintHash
|
|
124
241
|
});
|
|
125
|
-
const byIdDesc = (a, b) => b.id.localeCompare(a.id);
|
|
126
|
-
const sorted = (candidates ?? []).slice().sort(byIdDesc);
|
|
127
|
-
const latestCandidate = sorted[0] ?? null;
|
|
128
|
-
const currentBundle = sorted.find((b) => b.id === bundleId);
|
|
129
|
-
const updateCandidate = sorted.find((b) => b.id.localeCompare(bundleId) > 0) ?? null;
|
|
130
|
-
const rollbackCandidate = sorted.find((b) => b.id.localeCompare(bundleId) < 0) ?? null;
|
|
131
|
-
if (bundleId === __hot_updater_core.NIL_UUID) {
|
|
132
|
-
if (latestCandidate && latestCandidate.id !== bundleId) return toUpdateInfo(latestCandidate, "UPDATE");
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
if (currentBundle) {
|
|
136
|
-
if (latestCandidate && latestCandidate.id.localeCompare(currentBundle.id) > 0) return toUpdateInfo(latestCandidate, "UPDATE");
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
139
|
-
if (updateCandidate) return toUpdateInfo(updateCandidate, "UPDATE");
|
|
140
|
-
if (rollbackCandidate) return toUpdateInfo(rollbackCandidate, "ROLLBACK");
|
|
141
|
-
if (minBundleId && bundleId.localeCompare(minBundleId) <= 0) return null;
|
|
142
|
-
return INIT_BUNDLE_ROLLBACK_UPDATE_INFO;
|
|
143
242
|
};
|
|
144
243
|
if (args._updateStrategy === "appVersion") return appVersionStrategy(args);
|
|
145
244
|
if (args._updateStrategy === "fingerprint") return fingerprintStrategy(args);
|
|
146
245
|
return null;
|
|
147
246
|
},
|
|
148
|
-
async getAppUpdateInfo(args) {
|
|
247
|
+
async getAppUpdateInfo(args, context) {
|
|
149
248
|
const info = await this.getUpdateInfo(args);
|
|
150
249
|
if (!info) return null;
|
|
151
|
-
const { storageUri
|
|
152
|
-
const fileUrl = await resolveFileUrl(storageUri ?? null);
|
|
250
|
+
const { storageUri, ...rest } = info;
|
|
251
|
+
const fileUrl = await resolveFileUrl(storageUri ?? null, context);
|
|
153
252
|
return {
|
|
154
253
|
...rest,
|
|
155
254
|
fileUrl
|
|
156
255
|
};
|
|
157
256
|
},
|
|
158
257
|
async getChannels() {
|
|
159
|
-
const
|
|
160
|
-
|
|
258
|
+
const rows = await (await ensureORM()).findMany("bundles", {
|
|
259
|
+
select: ["channel"],
|
|
260
|
+
orderBy: [["channel", "asc"]]
|
|
261
|
+
});
|
|
161
262
|
const set = new Set(rows?.map((r) => r.channel) ?? []);
|
|
162
263
|
return Array.from(set);
|
|
163
264
|
},
|
|
164
265
|
async getBundles(options) {
|
|
165
|
-
const
|
|
166
|
-
const
|
|
167
|
-
const
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const conditions = [];
|
|
185
|
-
if (where?.channel) conditions.push(b("channel", "=", where.channel));
|
|
186
|
-
if (where?.platform) conditions.push(b("platform", "=", where.platform));
|
|
187
|
-
return conditions.length > 0 ? b.and(...conditions) : true;
|
|
188
|
-
}
|
|
189
|
-
})).map((r) => ({
|
|
190
|
-
id: r.id,
|
|
191
|
-
platform: r.platform,
|
|
192
|
-
shouldForceUpdate: Boolean(r.should_force_update),
|
|
193
|
-
enabled: Boolean(r.enabled),
|
|
194
|
-
fileHash: r.file_hash,
|
|
195
|
-
gitCommitHash: r.git_commit_hash ?? null,
|
|
196
|
-
message: r.message ?? null,
|
|
197
|
-
channel: r.channel,
|
|
198
|
-
storageUri: r.storage_uri,
|
|
199
|
-
targetAppVersion: r.target_app_version ?? null,
|
|
200
|
-
fingerprintHash: r.fingerprint_hash ?? null
|
|
201
|
-
})).sort((a, b) => b.id.localeCompare(a.id));
|
|
202
|
-
const total = all.length;
|
|
266
|
+
const orm = await ensureORM();
|
|
267
|
+
const { where, limit, offset, orderBy } = options;
|
|
268
|
+
const total = await orm.count("bundles", { where: buildBundleWhere(where) });
|
|
269
|
+
const selectedColumns = [
|
|
270
|
+
"id",
|
|
271
|
+
"platform",
|
|
272
|
+
"should_force_update",
|
|
273
|
+
"enabled",
|
|
274
|
+
"file_hash",
|
|
275
|
+
"git_commit_hash",
|
|
276
|
+
"message",
|
|
277
|
+
"channel",
|
|
278
|
+
"storage_uri",
|
|
279
|
+
"target_app_version",
|
|
280
|
+
"fingerprint_hash",
|
|
281
|
+
"metadata",
|
|
282
|
+
"rollout_cohort_count",
|
|
283
|
+
"target_cohorts"
|
|
284
|
+
];
|
|
203
285
|
return {
|
|
204
|
-
data:
|
|
286
|
+
data: (isMongoAdapter ? (await orm.findMany("bundles", {
|
|
287
|
+
select: selectedColumns,
|
|
288
|
+
where: buildBundleWhere(where)
|
|
289
|
+
})).sort((a, b) => {
|
|
290
|
+
const direction = orderBy?.direction ?? "desc";
|
|
291
|
+
const result = a.id.localeCompare(b.id);
|
|
292
|
+
return direction === "asc" ? result : -result;
|
|
293
|
+
}).slice(offset, offset + limit) : await orm.findMany("bundles", {
|
|
294
|
+
select: selectedColumns,
|
|
295
|
+
where: buildBundleWhere(where),
|
|
296
|
+
orderBy: [[orderBy?.field ?? "id", orderBy?.direction ?? "desc"]],
|
|
297
|
+
limit,
|
|
298
|
+
offset
|
|
299
|
+
})).map((r) => ({
|
|
300
|
+
id: r.id,
|
|
301
|
+
platform: r.platform,
|
|
302
|
+
shouldForceUpdate: Boolean(r.should_force_update),
|
|
303
|
+
enabled: Boolean(r.enabled),
|
|
304
|
+
fileHash: r.file_hash,
|
|
305
|
+
gitCommitHash: r.git_commit_hash ?? null,
|
|
306
|
+
message: r.message ?? null,
|
|
307
|
+
channel: r.channel,
|
|
308
|
+
storageUri: r.storage_uri,
|
|
309
|
+
targetAppVersion: r.target_app_version ?? null,
|
|
310
|
+
fingerprintHash: r.fingerprint_hash ?? null,
|
|
311
|
+
rolloutCohortCount: r.rollout_cohort_count ?? _hot_updater_core.DEFAULT_ROLLOUT_COHORT_COUNT,
|
|
312
|
+
targetCohorts: parseTargetCohorts(r.target_cohorts)
|
|
313
|
+
})),
|
|
205
314
|
pagination: require_calculatePagination.calculatePagination(total, {
|
|
206
315
|
limit,
|
|
207
316
|
offset
|
|
@@ -209,8 +318,7 @@ function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
|
209
318
|
};
|
|
210
319
|
},
|
|
211
320
|
async insertBundle(bundle) {
|
|
212
|
-
const
|
|
213
|
-
const orm = client.orm(version);
|
|
321
|
+
const orm = await ensureORM();
|
|
214
322
|
const values = {
|
|
215
323
|
id: bundle.id,
|
|
216
324
|
platform: bundle.platform,
|
|
@@ -223,9 +331,11 @@ function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
|
223
331
|
storage_uri: bundle.storageUri,
|
|
224
332
|
target_app_version: bundle.targetAppVersion,
|
|
225
333
|
fingerprint_hash: bundle.fingerprintHash,
|
|
226
|
-
metadata: bundle.metadata ?? {}
|
|
334
|
+
metadata: bundle.metadata ?? {},
|
|
335
|
+
rollout_cohort_count: bundle.rolloutCohortCount ?? _hot_updater_core.DEFAULT_ROLLOUT_COHORT_COUNT,
|
|
336
|
+
target_cohorts: bundle.targetCohorts ?? null
|
|
227
337
|
};
|
|
228
|
-
const { id
|
|
338
|
+
const { id, ...updateValues } = values;
|
|
229
339
|
await orm.upsert("bundles", {
|
|
230
340
|
where: (b) => b("id", "=", id),
|
|
231
341
|
create: values,
|
|
@@ -233,8 +343,7 @@ function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
|
233
343
|
});
|
|
234
344
|
},
|
|
235
345
|
async updateBundleById(bundleId, newBundle) {
|
|
236
|
-
const
|
|
237
|
-
const orm = client.orm(version);
|
|
346
|
+
const orm = await ensureORM();
|
|
238
347
|
const current = await this.getBundleById(bundleId);
|
|
239
348
|
if (!current) throw new Error("targetBundleId not found");
|
|
240
349
|
const merged = {
|
|
@@ -253,9 +362,11 @@ function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
|
253
362
|
storage_uri: merged.storageUri,
|
|
254
363
|
target_app_version: merged.targetAppVersion,
|
|
255
364
|
fingerprint_hash: merged.fingerprintHash,
|
|
256
|
-
metadata: merged.metadata ?? {}
|
|
365
|
+
metadata: merged.metadata ?? {},
|
|
366
|
+
rollout_cohort_count: merged.rolloutCohortCount ?? _hot_updater_core.DEFAULT_ROLLOUT_COHORT_COUNT,
|
|
367
|
+
target_cohorts: merged.targetCohorts ?? null
|
|
257
368
|
};
|
|
258
|
-
const { id: id2
|
|
369
|
+
const { id: id2, ...updateValues2 } = values;
|
|
259
370
|
await orm.upsert("bundles", {
|
|
260
371
|
where: (b) => b("id", "=", id2),
|
|
261
372
|
create: values,
|
|
@@ -263,8 +374,7 @@ function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
|
263
374
|
});
|
|
264
375
|
},
|
|
265
376
|
async deleteBundleById(bundleId) {
|
|
266
|
-
|
|
267
|
-
await client.orm(version).deleteMany("bundles", { where: (b) => b("id", "=", bundleId) });
|
|
377
|
+
await (await ensureORM()).deleteMany("bundles", { where: (b) => b("id", "=", bundleId) });
|
|
268
378
|
}
|
|
269
379
|
},
|
|
270
380
|
adapterName: client.adapter.name,
|
|
@@ -272,7 +382,6 @@ function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
|
272
382
|
generateSchema: client.generateSchema
|
|
273
383
|
};
|
|
274
384
|
}
|
|
275
|
-
|
|
276
385
|
//#endregion
|
|
277
386
|
exports.HotUpdaterDB = HotUpdaterDB;
|
|
278
|
-
exports.createOrmDatabaseCore = createOrmDatabaseCore;
|
|
387
|
+
exports.createOrmDatabaseCore = createOrmDatabaseCore;
|
package/dist/db/ormCore.d.cts
CHANGED
|
@@ -1,25 +1,43 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as
|
|
1
|
+
import { HotUpdaterContext } from "@hot-updater/plugin-core";
|
|
2
|
+
import * as _$fumadb_schema0 from "fumadb/schema";
|
|
3
|
+
import * as _$fumadb from "fumadb";
|
|
3
4
|
import { InferFumaDB } from "fumadb";
|
|
4
5
|
import { FumaDBAdapter } from "fumadb/adapters";
|
|
5
6
|
|
|
6
7
|
//#region src/db/ormCore.d.ts
|
|
7
|
-
declare const HotUpdaterDB:
|
|
8
|
-
bundles: fumadb_schema0.Table<{
|
|
9
|
-
id: fumadb_schema0.IdColumn<"uuid", string, string>;
|
|
10
|
-
platform: fumadb_schema0.Column<"string", string, string>;
|
|
11
|
-
should_force_update: fumadb_schema0.Column<"bool", boolean, boolean>;
|
|
12
|
-
enabled: fumadb_schema0.Column<"bool", boolean, boolean>;
|
|
13
|
-
file_hash: fumadb_schema0.Column<"string", string, string>;
|
|
14
|
-
git_commit_hash: fumadb_schema0.Column<"string", string | null, string | null>;
|
|
15
|
-
message: fumadb_schema0.Column<"string", string | null, string | null>;
|
|
16
|
-
channel: fumadb_schema0.Column<"string", string, string>;
|
|
17
|
-
storage_uri: fumadb_schema0.Column<"string", string, string>;
|
|
18
|
-
target_app_version: fumadb_schema0.Column<"string", string | null, string | null>;
|
|
19
|
-
fingerprint_hash: fumadb_schema0.Column<"string", string | null, string | null>;
|
|
20
|
-
metadata: fumadb_schema0.Column<"json", unknown, unknown>;
|
|
8
|
+
declare const HotUpdaterDB: _$fumadb.FumaDBFactory<[_$fumadb_schema0.Schema<"0.21.0", {
|
|
9
|
+
bundles: _$fumadb_schema0.Table<{
|
|
10
|
+
id: _$fumadb_schema0.IdColumn<"uuid", string, string>;
|
|
11
|
+
platform: _$fumadb_schema0.Column<"string", string, string>;
|
|
12
|
+
should_force_update: _$fumadb_schema0.Column<"bool", boolean, boolean>;
|
|
13
|
+
enabled: _$fumadb_schema0.Column<"bool", boolean, boolean>;
|
|
14
|
+
file_hash: _$fumadb_schema0.Column<"string", string, string>;
|
|
15
|
+
git_commit_hash: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
16
|
+
message: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
17
|
+
channel: _$fumadb_schema0.Column<"string", string, string>;
|
|
18
|
+
storage_uri: _$fumadb_schema0.Column<"string", string, string>;
|
|
19
|
+
target_app_version: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
20
|
+
fingerprint_hash: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
21
|
+
metadata: _$fumadb_schema0.Column<"json", unknown, unknown>;
|
|
21
22
|
}, {}>;
|
|
22
|
-
}
|
|
23
|
+
}>, _$fumadb_schema0.Schema<"0.29.0", {
|
|
24
|
+
bundles: _$fumadb_schema0.Table<{
|
|
25
|
+
id: _$fumadb_schema0.IdColumn<"uuid", string, string>;
|
|
26
|
+
platform: _$fumadb_schema0.Column<"string", string, string>;
|
|
27
|
+
should_force_update: _$fumadb_schema0.Column<"bool", boolean, boolean>;
|
|
28
|
+
enabled: _$fumadb_schema0.Column<"bool", boolean, boolean>;
|
|
29
|
+
file_hash: _$fumadb_schema0.Column<"string", string, string>;
|
|
30
|
+
git_commit_hash: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
31
|
+
message: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
32
|
+
channel: _$fumadb_schema0.Column<"string", string, string>;
|
|
33
|
+
storage_uri: _$fumadb_schema0.Column<"string", string, string>;
|
|
34
|
+
target_app_version: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
35
|
+
fingerprint_hash: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
36
|
+
metadata: _$fumadb_schema0.Column<"json", unknown, unknown>;
|
|
37
|
+
rollout_cohort_count: _$fumadb_schema0.Column<"integer", number | null, number>;
|
|
38
|
+
target_cohorts: _$fumadb_schema0.Column<"json", unknown, unknown>;
|
|
39
|
+
}, {}>;
|
|
40
|
+
}>]>;
|
|
23
41
|
type HotUpdaterClient = InferFumaDB<typeof HotUpdaterDB>;
|
|
24
42
|
type Migrator = ReturnType<HotUpdaterClient["createMigrator"]>;
|
|
25
43
|
//#endregion
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { HotUpdaterContext } from "@hot-updater/plugin-core";
|
|
2
|
+
import * as _$fumadb from "fumadb";
|
|
3
|
+
import { InferFumaDB } from "fumadb";
|
|
4
|
+
import * as _$fumadb_schema0 from "fumadb/schema";
|
|
5
|
+
import { FumaDBAdapter } from "fumadb/adapters";
|
|
6
|
+
|
|
7
|
+
//#region src/db/ormCore.d.ts
|
|
8
|
+
declare const HotUpdaterDB: _$fumadb.FumaDBFactory<[_$fumadb_schema0.Schema<"0.21.0", {
|
|
9
|
+
bundles: _$fumadb_schema0.Table<{
|
|
10
|
+
id: _$fumadb_schema0.IdColumn<"uuid", string, string>;
|
|
11
|
+
platform: _$fumadb_schema0.Column<"string", string, string>;
|
|
12
|
+
should_force_update: _$fumadb_schema0.Column<"bool", boolean, boolean>;
|
|
13
|
+
enabled: _$fumadb_schema0.Column<"bool", boolean, boolean>;
|
|
14
|
+
file_hash: _$fumadb_schema0.Column<"string", string, string>;
|
|
15
|
+
git_commit_hash: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
16
|
+
message: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
17
|
+
channel: _$fumadb_schema0.Column<"string", string, string>;
|
|
18
|
+
storage_uri: _$fumadb_schema0.Column<"string", string, string>;
|
|
19
|
+
target_app_version: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
20
|
+
fingerprint_hash: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
21
|
+
metadata: _$fumadb_schema0.Column<"json", unknown, unknown>;
|
|
22
|
+
}, {}>;
|
|
23
|
+
}>, _$fumadb_schema0.Schema<"0.29.0", {
|
|
24
|
+
bundles: _$fumadb_schema0.Table<{
|
|
25
|
+
id: _$fumadb_schema0.IdColumn<"uuid", string, string>;
|
|
26
|
+
platform: _$fumadb_schema0.Column<"string", string, string>;
|
|
27
|
+
should_force_update: _$fumadb_schema0.Column<"bool", boolean, boolean>;
|
|
28
|
+
enabled: _$fumadb_schema0.Column<"bool", boolean, boolean>;
|
|
29
|
+
file_hash: _$fumadb_schema0.Column<"string", string, string>;
|
|
30
|
+
git_commit_hash: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
31
|
+
message: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
32
|
+
channel: _$fumadb_schema0.Column<"string", string, string>;
|
|
33
|
+
storage_uri: _$fumadb_schema0.Column<"string", string, string>;
|
|
34
|
+
target_app_version: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
35
|
+
fingerprint_hash: _$fumadb_schema0.Column<"string", string | null, string | null>;
|
|
36
|
+
metadata: _$fumadb_schema0.Column<"json", unknown, unknown>;
|
|
37
|
+
rollout_cohort_count: _$fumadb_schema0.Column<"integer", number | null, number>;
|
|
38
|
+
target_cohorts: _$fumadb_schema0.Column<"json", unknown, unknown>;
|
|
39
|
+
}, {}>;
|
|
40
|
+
}>]>;
|
|
41
|
+
type HotUpdaterClient = InferFumaDB<typeof HotUpdaterDB>;
|
|
42
|
+
type Migrator = ReturnType<HotUpdaterClient["createMigrator"]>;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { HotUpdaterClient, HotUpdaterDB, Migrator };
|