@hot-updater/server 0.29.4 → 0.29.6
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/db/ormCore.cjs +105 -23
- package/dist/db/ormCore.mjs +105 -23
- package/dist/db/pluginCore.cjs +7 -4
- package/dist/db/pluginCore.mjs +7 -4
- package/dist/handler.cjs +13 -3
- package/dist/handler.mjs +13 -3
- package/dist/types/index.d.cts +2 -0
- package/dist/types/index.d.mts +2 -0
- package/package.json +6 -6
- package/src/db/ormCore.ts +194 -38
- package/src/db/pluginCore.spec.ts +172 -0
- package/src/db/pluginCore.ts +20 -3
- package/src/db/pluginUpdateCheck.bench.ts +10 -10
- package/src/handler-standalone.integration.spec.ts +1 -2
- package/src/handler.spec.ts +152 -2
- package/src/handler.ts +30 -2
- package/src/runtime.spec.ts +105 -0
- package/src/types/index.ts +2 -0
package/dist/db/ormCore.cjs
CHANGED
|
@@ -18,6 +18,40 @@ const parseTargetCohorts = (value) => {
|
|
|
18
18
|
};
|
|
19
19
|
const schemas = [require_v0_21_0.v0_21_0, require_v0_29_0.v0_29_0];
|
|
20
20
|
const getLastItem = (items) => items.at(-1);
|
|
21
|
+
const DEFAULT_BUNDLE_ORDER = {
|
|
22
|
+
field: "id",
|
|
23
|
+
direction: "desc"
|
|
24
|
+
};
|
|
25
|
+
const mergeIdFilter = (base, patch) => ({
|
|
26
|
+
...base,
|
|
27
|
+
...patch
|
|
28
|
+
});
|
|
29
|
+
const mergeWhereWithIdFilter = (where, idFilter) => ({
|
|
30
|
+
...where,
|
|
31
|
+
id: mergeIdFilter(where?.id, idFilter)
|
|
32
|
+
});
|
|
33
|
+
const buildCursorPageWhere = (where, cursor, orderBy) => {
|
|
34
|
+
const direction = orderBy.direction;
|
|
35
|
+
if (cursor.after) return {
|
|
36
|
+
reverseData: false,
|
|
37
|
+
where: mergeWhereWithIdFilter(where, { [direction === "desc" ? "lt" : "gt"]: cursor.after }),
|
|
38
|
+
orderBy
|
|
39
|
+
};
|
|
40
|
+
if (cursor.before) return {
|
|
41
|
+
reverseData: true,
|
|
42
|
+
where: mergeWhereWithIdFilter(where, { [direction === "desc" ? "gt" : "lt"]: cursor.before }),
|
|
43
|
+
orderBy: {
|
|
44
|
+
field: orderBy.field,
|
|
45
|
+
direction: direction === "desc" ? "asc" : "desc"
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
reverseData: false,
|
|
50
|
+
where: where ?? {},
|
|
51
|
+
orderBy
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
const buildCountBeforeWhere = (where, firstBundleId, orderBy) => mergeWhereWithIdFilter(where, { [orderBy.direction === "desc" ? "gt" : "lt"]: firstBundleId });
|
|
21
55
|
const HotUpdaterDB = (0, fumadb.fumadb)({
|
|
22
56
|
namespace: "hot_updater",
|
|
23
57
|
schemas
|
|
@@ -264,7 +298,9 @@ function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
|
264
298
|
},
|
|
265
299
|
async getBundles(options) {
|
|
266
300
|
const orm = await ensureORM();
|
|
267
|
-
const { where, limit
|
|
301
|
+
const { where, limit } = options;
|
|
302
|
+
const orderBy = options.orderBy ?? DEFAULT_BUNDLE_ORDER;
|
|
303
|
+
const offset = ("offset" in options ? options.offset : void 0) ?? 0;
|
|
268
304
|
const total = await orm.count("bundles", { where: buildBundleWhere(where) });
|
|
269
305
|
const selectedColumns = [
|
|
270
306
|
"id",
|
|
@@ -282,39 +318,85 @@ function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
|
282
318
|
"rollout_cohort_count",
|
|
283
319
|
"target_cohorts"
|
|
284
320
|
];
|
|
285
|
-
|
|
286
|
-
|
|
321
|
+
const mapRowsToBundles = (rows) => rows.map((r) => ({
|
|
322
|
+
id: r.id,
|
|
323
|
+
platform: r.platform,
|
|
324
|
+
shouldForceUpdate: Boolean(r.should_force_update),
|
|
325
|
+
enabled: Boolean(r.enabled),
|
|
326
|
+
fileHash: r.file_hash,
|
|
327
|
+
gitCommitHash: r.git_commit_hash ?? null,
|
|
328
|
+
message: r.message ?? null,
|
|
329
|
+
channel: r.channel,
|
|
330
|
+
storageUri: r.storage_uri,
|
|
331
|
+
targetAppVersion: r.target_app_version ?? null,
|
|
332
|
+
fingerprintHash: r.fingerprint_hash ?? null,
|
|
333
|
+
rolloutCohortCount: r.rollout_cohort_count ?? _hot_updater_core.DEFAULT_ROLLOUT_COHORT_COUNT,
|
|
334
|
+
targetCohorts: parseTargetCohorts(r.target_cohorts)
|
|
335
|
+
}));
|
|
336
|
+
const findBundles = async ({ where, orderBy, limit, offset }) => {
|
|
337
|
+
return mapRowsToBundles(isMongoAdapter ? (await orm.findMany("bundles", {
|
|
287
338
|
select: selectedColumns,
|
|
288
339
|
where: buildBundleWhere(where)
|
|
289
340
|
})).sort((a, b) => {
|
|
290
|
-
const direction = orderBy?.direction ?? "desc";
|
|
291
341
|
const result = a.id.localeCompare(b.id);
|
|
292
|
-
return direction === "asc" ? result : -result;
|
|
342
|
+
return orderBy.direction === "asc" ? result : -result;
|
|
293
343
|
}).slice(offset, offset + limit) : await orm.findMany("bundles", {
|
|
294
344
|
select: selectedColumns,
|
|
295
345
|
where: buildBundleWhere(where),
|
|
296
|
-
orderBy: [[orderBy
|
|
346
|
+
orderBy: [[orderBy.field, orderBy.direction]],
|
|
297
347
|
limit,
|
|
298
348
|
offset
|
|
299
|
-
}))
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
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
|
-
})),
|
|
314
|
-
pagination: require_calculatePagination.calculatePagination(total, {
|
|
349
|
+
}));
|
|
350
|
+
};
|
|
351
|
+
if (!options.cursor?.after && !options.cursor?.before) {
|
|
352
|
+
const data = await findBundles({
|
|
353
|
+
where,
|
|
354
|
+
orderBy,
|
|
315
355
|
limit,
|
|
316
356
|
offset
|
|
317
|
-
})
|
|
357
|
+
});
|
|
358
|
+
return {
|
|
359
|
+
data,
|
|
360
|
+
pagination: {
|
|
361
|
+
...require_calculatePagination.calculatePagination(total, {
|
|
362
|
+
limit,
|
|
363
|
+
offset
|
|
364
|
+
}),
|
|
365
|
+
...data.length > 0 && offset + data.length < total ? { nextCursor: data.at(-1)?.id } : {},
|
|
366
|
+
...data.length > 0 && offset > 0 ? { previousCursor: data[0]?.id } : {}
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
const { where: cursorWhere, orderBy: cursorOrderBy, reverseData } = buildCursorPageWhere(where, options.cursor, orderBy);
|
|
371
|
+
const cursorPage = await findBundles({
|
|
372
|
+
where: cursorWhere,
|
|
373
|
+
orderBy: cursorOrderBy,
|
|
374
|
+
limit,
|
|
375
|
+
offset: 0
|
|
376
|
+
});
|
|
377
|
+
const data = reverseData ? cursorPage.slice().reverse() : cursorPage;
|
|
378
|
+
if (data.length === 0) return {
|
|
379
|
+
data,
|
|
380
|
+
pagination: {
|
|
381
|
+
...require_calculatePagination.calculatePagination(total, {
|
|
382
|
+
limit,
|
|
383
|
+
offset: options.cursor.after ? total : 0
|
|
384
|
+
}),
|
|
385
|
+
...options.cursor.after ? { previousCursor: options.cursor.after } : {},
|
|
386
|
+
...options.cursor.before ? { nextCursor: options.cursor.before } : {}
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
const startIndex = await orm.count("bundles", { where: buildBundleWhere(buildCountBeforeWhere(where, data[0].id, orderBy)) });
|
|
390
|
+
return {
|
|
391
|
+
data,
|
|
392
|
+
pagination: {
|
|
393
|
+
...require_calculatePagination.calculatePagination(total, {
|
|
394
|
+
limit,
|
|
395
|
+
offset: startIndex
|
|
396
|
+
}),
|
|
397
|
+
...startIndex + data.length < total ? { nextCursor: data.at(-1)?.id } : {},
|
|
398
|
+
...startIndex > 0 ? { previousCursor: data[0]?.id } : {}
|
|
399
|
+
}
|
|
318
400
|
};
|
|
319
401
|
},
|
|
320
402
|
async insertBundle(bundle) {
|
package/dist/db/ormCore.mjs
CHANGED
|
@@ -18,6 +18,40 @@ const parseTargetCohorts = (value) => {
|
|
|
18
18
|
};
|
|
19
19
|
const schemas = [v0_21_0, v0_29_0];
|
|
20
20
|
const getLastItem = (items) => items.at(-1);
|
|
21
|
+
const DEFAULT_BUNDLE_ORDER = {
|
|
22
|
+
field: "id",
|
|
23
|
+
direction: "desc"
|
|
24
|
+
};
|
|
25
|
+
const mergeIdFilter = (base, patch) => ({
|
|
26
|
+
...base,
|
|
27
|
+
...patch
|
|
28
|
+
});
|
|
29
|
+
const mergeWhereWithIdFilter = (where, idFilter) => ({
|
|
30
|
+
...where,
|
|
31
|
+
id: mergeIdFilter(where?.id, idFilter)
|
|
32
|
+
});
|
|
33
|
+
const buildCursorPageWhere = (where, cursor, orderBy) => {
|
|
34
|
+
const direction = orderBy.direction;
|
|
35
|
+
if (cursor.after) return {
|
|
36
|
+
reverseData: false,
|
|
37
|
+
where: mergeWhereWithIdFilter(where, { [direction === "desc" ? "lt" : "gt"]: cursor.after }),
|
|
38
|
+
orderBy
|
|
39
|
+
};
|
|
40
|
+
if (cursor.before) return {
|
|
41
|
+
reverseData: true,
|
|
42
|
+
where: mergeWhereWithIdFilter(where, { [direction === "desc" ? "gt" : "lt"]: cursor.before }),
|
|
43
|
+
orderBy: {
|
|
44
|
+
field: orderBy.field,
|
|
45
|
+
direction: direction === "desc" ? "asc" : "desc"
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
return {
|
|
49
|
+
reverseData: false,
|
|
50
|
+
where: where ?? {},
|
|
51
|
+
orderBy
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
const buildCountBeforeWhere = (where, firstBundleId, orderBy) => mergeWhereWithIdFilter(where, { [orderBy.direction === "desc" ? "gt" : "lt"]: firstBundleId });
|
|
21
55
|
const HotUpdaterDB = fumadb({
|
|
22
56
|
namespace: "hot_updater",
|
|
23
57
|
schemas
|
|
@@ -264,7 +298,9 @@ function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
|
264
298
|
},
|
|
265
299
|
async getBundles(options) {
|
|
266
300
|
const orm = await ensureORM();
|
|
267
|
-
const { where, limit
|
|
301
|
+
const { where, limit } = options;
|
|
302
|
+
const orderBy = options.orderBy ?? DEFAULT_BUNDLE_ORDER;
|
|
303
|
+
const offset = ("offset" in options ? options.offset : void 0) ?? 0;
|
|
268
304
|
const total = await orm.count("bundles", { where: buildBundleWhere(where) });
|
|
269
305
|
const selectedColumns = [
|
|
270
306
|
"id",
|
|
@@ -282,39 +318,85 @@ function createOrmDatabaseCore({ database, resolveFileUrl }) {
|
|
|
282
318
|
"rollout_cohort_count",
|
|
283
319
|
"target_cohorts"
|
|
284
320
|
];
|
|
285
|
-
|
|
286
|
-
|
|
321
|
+
const mapRowsToBundles = (rows) => rows.map((r) => ({
|
|
322
|
+
id: r.id,
|
|
323
|
+
platform: r.platform,
|
|
324
|
+
shouldForceUpdate: Boolean(r.should_force_update),
|
|
325
|
+
enabled: Boolean(r.enabled),
|
|
326
|
+
fileHash: r.file_hash,
|
|
327
|
+
gitCommitHash: r.git_commit_hash ?? null,
|
|
328
|
+
message: r.message ?? null,
|
|
329
|
+
channel: r.channel,
|
|
330
|
+
storageUri: r.storage_uri,
|
|
331
|
+
targetAppVersion: r.target_app_version ?? null,
|
|
332
|
+
fingerprintHash: r.fingerprint_hash ?? null,
|
|
333
|
+
rolloutCohortCount: r.rollout_cohort_count ?? DEFAULT_ROLLOUT_COHORT_COUNT,
|
|
334
|
+
targetCohorts: parseTargetCohorts(r.target_cohorts)
|
|
335
|
+
}));
|
|
336
|
+
const findBundles = async ({ where, orderBy, limit, offset }) => {
|
|
337
|
+
return mapRowsToBundles(isMongoAdapter ? (await orm.findMany("bundles", {
|
|
287
338
|
select: selectedColumns,
|
|
288
339
|
where: buildBundleWhere(where)
|
|
289
340
|
})).sort((a, b) => {
|
|
290
|
-
const direction = orderBy?.direction ?? "desc";
|
|
291
341
|
const result = a.id.localeCompare(b.id);
|
|
292
|
-
return direction === "asc" ? result : -result;
|
|
342
|
+
return orderBy.direction === "asc" ? result : -result;
|
|
293
343
|
}).slice(offset, offset + limit) : await orm.findMany("bundles", {
|
|
294
344
|
select: selectedColumns,
|
|
295
345
|
where: buildBundleWhere(where),
|
|
296
|
-
orderBy: [[orderBy
|
|
346
|
+
orderBy: [[orderBy.field, orderBy.direction]],
|
|
297
347
|
limit,
|
|
298
348
|
offset
|
|
299
|
-
}))
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
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 ?? DEFAULT_ROLLOUT_COHORT_COUNT,
|
|
312
|
-
targetCohorts: parseTargetCohorts(r.target_cohorts)
|
|
313
|
-
})),
|
|
314
|
-
pagination: calculatePagination(total, {
|
|
349
|
+
}));
|
|
350
|
+
};
|
|
351
|
+
if (!options.cursor?.after && !options.cursor?.before) {
|
|
352
|
+
const data = await findBundles({
|
|
353
|
+
where,
|
|
354
|
+
orderBy,
|
|
315
355
|
limit,
|
|
316
356
|
offset
|
|
317
|
-
})
|
|
357
|
+
});
|
|
358
|
+
return {
|
|
359
|
+
data,
|
|
360
|
+
pagination: {
|
|
361
|
+
...calculatePagination(total, {
|
|
362
|
+
limit,
|
|
363
|
+
offset
|
|
364
|
+
}),
|
|
365
|
+
...data.length > 0 && offset + data.length < total ? { nextCursor: data.at(-1)?.id } : {},
|
|
366
|
+
...data.length > 0 && offset > 0 ? { previousCursor: data[0]?.id } : {}
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
const { where: cursorWhere, orderBy: cursorOrderBy, reverseData } = buildCursorPageWhere(where, options.cursor, orderBy);
|
|
371
|
+
const cursorPage = await findBundles({
|
|
372
|
+
where: cursorWhere,
|
|
373
|
+
orderBy: cursorOrderBy,
|
|
374
|
+
limit,
|
|
375
|
+
offset: 0
|
|
376
|
+
});
|
|
377
|
+
const data = reverseData ? cursorPage.slice().reverse() : cursorPage;
|
|
378
|
+
if (data.length === 0) return {
|
|
379
|
+
data,
|
|
380
|
+
pagination: {
|
|
381
|
+
...calculatePagination(total, {
|
|
382
|
+
limit,
|
|
383
|
+
offset: options.cursor.after ? total : 0
|
|
384
|
+
}),
|
|
385
|
+
...options.cursor.after ? { previousCursor: options.cursor.after } : {},
|
|
386
|
+
...options.cursor.before ? { nextCursor: options.cursor.before } : {}
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
const startIndex = await orm.count("bundles", { where: buildBundleWhere(buildCountBeforeWhere(where, data[0].id, orderBy)) });
|
|
390
|
+
return {
|
|
391
|
+
data,
|
|
392
|
+
pagination: {
|
|
393
|
+
...calculatePagination(total, {
|
|
394
|
+
limit,
|
|
395
|
+
offset: startIndex
|
|
396
|
+
}),
|
|
397
|
+
...startIndex + data.length < total ? { nextCursor: data.at(-1)?.id } : {},
|
|
398
|
+
...startIndex > 0 ? { previousCursor: data[0]?.id } : {}
|
|
399
|
+
}
|
|
318
400
|
};
|
|
319
401
|
},
|
|
320
402
|
async insertBundle(bundle) {
|
package/dist/db/pluginCore.cjs
CHANGED
|
@@ -69,13 +69,13 @@ function createPluginDatabaseCore(getPlugin, resolveFileUrl, options) {
|
|
|
69
69
|
return (0, _hot_updater_core.isCohortEligibleForUpdate)(bundle.id, cohort, bundle.rolloutCohortCount, bundle.targetCohorts);
|
|
70
70
|
};
|
|
71
71
|
const findUpdateInfoByScanning = async ({ args, queryWhere, isCandidate, context }) => {
|
|
72
|
-
let
|
|
72
|
+
let after;
|
|
73
73
|
while (true) {
|
|
74
74
|
const { data, pagination } = await getSortedBundlePage({
|
|
75
75
|
where: queryWhere,
|
|
76
76
|
limit: PAGE_SIZE,
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
orderBy: DESC_ORDER,
|
|
78
|
+
...after ? { cursor: { after } } : {}
|
|
79
79
|
}, context);
|
|
80
80
|
for (const bundle of data) {
|
|
81
81
|
if (!bundleMatchesQueryWhere(bundle, queryWhere) || !isCandidate(bundle)) continue;
|
|
@@ -95,7 +95,8 @@ function createPluginDatabaseCore(getPlugin, resolveFileUrl, options) {
|
|
|
95
95
|
return makeResponse(bundle, "ROLLBACK");
|
|
96
96
|
}
|
|
97
97
|
if (!pagination.hasNextPage) break;
|
|
98
|
-
|
|
98
|
+
after = data.at(-1)?.id;
|
|
99
|
+
if (!after) break;
|
|
99
100
|
}
|
|
100
101
|
if (args.bundleId === _hot_updater_core.NIL_UUID) return null;
|
|
101
102
|
if (args.minBundleId && args.bundleId.localeCompare(args.minBundleId) <= 0) return null;
|
|
@@ -113,6 +114,8 @@ function createPluginDatabaseCore(getPlugin, resolveFileUrl, options) {
|
|
|
113
114
|
return getPlugin().getBundleById(id, context);
|
|
114
115
|
},
|
|
115
116
|
async getUpdateInfo(args, context) {
|
|
117
|
+
const directGetUpdateInfo = getPlugin().getUpdateInfo;
|
|
118
|
+
if (directGetUpdateInfo) return context === void 0 ? await directGetUpdateInfo(args) : await directGetUpdateInfo(args, context);
|
|
116
119
|
const channel = args.channel ?? "production";
|
|
117
120
|
const minBundleId = args.minBundleId ?? _hot_updater_core.NIL_UUID;
|
|
118
121
|
const baseWhere = getBaseWhere({
|
package/dist/db/pluginCore.mjs
CHANGED
|
@@ -69,13 +69,13 @@ function createPluginDatabaseCore(getPlugin, resolveFileUrl, options) {
|
|
|
69
69
|
return isCohortEligibleForUpdate(bundle.id, cohort, bundle.rolloutCohortCount, bundle.targetCohorts);
|
|
70
70
|
};
|
|
71
71
|
const findUpdateInfoByScanning = async ({ args, queryWhere, isCandidate, context }) => {
|
|
72
|
-
let
|
|
72
|
+
let after;
|
|
73
73
|
while (true) {
|
|
74
74
|
const { data, pagination } = await getSortedBundlePage({
|
|
75
75
|
where: queryWhere,
|
|
76
76
|
limit: PAGE_SIZE,
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
orderBy: DESC_ORDER,
|
|
78
|
+
...after ? { cursor: { after } } : {}
|
|
79
79
|
}, context);
|
|
80
80
|
for (const bundle of data) {
|
|
81
81
|
if (!bundleMatchesQueryWhere(bundle, queryWhere) || !isCandidate(bundle)) continue;
|
|
@@ -95,7 +95,8 @@ function createPluginDatabaseCore(getPlugin, resolveFileUrl, options) {
|
|
|
95
95
|
return makeResponse(bundle, "ROLLBACK");
|
|
96
96
|
}
|
|
97
97
|
if (!pagination.hasNextPage) break;
|
|
98
|
-
|
|
98
|
+
after = data.at(-1)?.id;
|
|
99
|
+
if (!after) break;
|
|
99
100
|
}
|
|
100
101
|
if (args.bundleId === NIL_UUID) return null;
|
|
101
102
|
if (args.minBundleId && args.bundleId.localeCompare(args.minBundleId) <= 0) return null;
|
|
@@ -113,6 +114,8 @@ function createPluginDatabaseCore(getPlugin, resolveFileUrl, options) {
|
|
|
113
114
|
return getPlugin().getBundleById(id, context);
|
|
114
115
|
},
|
|
115
116
|
async getUpdateInfo(args, context) {
|
|
117
|
+
const directGetUpdateInfo = getPlugin().getUpdateInfo;
|
|
118
|
+
if (directGetUpdateInfo) return context === void 0 ? await directGetUpdateInfo(args) : await directGetUpdateInfo(args, context);
|
|
116
119
|
const channel = args.channel ?? "production";
|
|
117
120
|
const minBundleId = args.minBundleId ?? NIL_UUID;
|
|
118
121
|
const baseWhere = getBaseWhere({
|
package/dist/handler.cjs
CHANGED
|
@@ -7,7 +7,7 @@ var HandlerBadRequestError = class extends Error {
|
|
|
7
7
|
}
|
|
8
8
|
};
|
|
9
9
|
const handleVersion = async () => {
|
|
10
|
-
return new Response(JSON.stringify({ version: "0.29.
|
|
10
|
+
return new Response(JSON.stringify({ version: "0.29.6" }), {
|
|
11
11
|
status: 200,
|
|
12
12
|
headers: { "Content-Type": "application/json" }
|
|
13
13
|
});
|
|
@@ -97,7 +97,13 @@ const handleGetBundles = async (_params, request, api, context) => {
|
|
|
97
97
|
const channel = url.searchParams.get("channel") ?? void 0;
|
|
98
98
|
const platform = url.searchParams.get("platform");
|
|
99
99
|
const limit = Number(url.searchParams.get("limit")) || 50;
|
|
100
|
-
const
|
|
100
|
+
const pageParam = url.searchParams.get("page");
|
|
101
|
+
const offset = url.searchParams.get("offset");
|
|
102
|
+
const after = url.searchParams.get("after") ?? void 0;
|
|
103
|
+
const before = url.searchParams.get("before") ?? void 0;
|
|
104
|
+
const page = pageParam === null ? void 0 : Number.isInteger(Number(pageParam)) && Number(pageParam) > 0 ? Number(pageParam) : null;
|
|
105
|
+
if (offset !== null) throw new HandlerBadRequestError("The 'offset' query parameter has been removed. Use 'after' or 'before' cursor pagination instead.");
|
|
106
|
+
if (page === null) throw new HandlerBadRequestError("The 'page' query parameter must be a positive integer.");
|
|
101
107
|
if (platform !== null && !isPlatform(platform)) throw new HandlerBadRequestError(`Invalid platform: ${platform}. Expected 'ios' or 'android'.`);
|
|
102
108
|
const result = await api.getBundles({
|
|
103
109
|
where: {
|
|
@@ -105,7 +111,11 @@ const handleGetBundles = async (_params, request, api, context) => {
|
|
|
105
111
|
...platform && { platform }
|
|
106
112
|
},
|
|
107
113
|
limit,
|
|
108
|
-
|
|
114
|
+
page,
|
|
115
|
+
cursor: after || before ? {
|
|
116
|
+
after,
|
|
117
|
+
before
|
|
118
|
+
} : void 0
|
|
109
119
|
}, context);
|
|
110
120
|
return new Response(JSON.stringify(result), {
|
|
111
121
|
status: 200,
|
package/dist/handler.mjs
CHANGED
|
@@ -7,7 +7,7 @@ var HandlerBadRequestError = class extends Error {
|
|
|
7
7
|
}
|
|
8
8
|
};
|
|
9
9
|
const handleVersion = async () => {
|
|
10
|
-
return new Response(JSON.stringify({ version: "0.29.
|
|
10
|
+
return new Response(JSON.stringify({ version: "0.29.6" }), {
|
|
11
11
|
status: 200,
|
|
12
12
|
headers: { "Content-Type": "application/json" }
|
|
13
13
|
});
|
|
@@ -97,7 +97,13 @@ const handleGetBundles = async (_params, request, api, context) => {
|
|
|
97
97
|
const channel = url.searchParams.get("channel") ?? void 0;
|
|
98
98
|
const platform = url.searchParams.get("platform");
|
|
99
99
|
const limit = Number(url.searchParams.get("limit")) || 50;
|
|
100
|
-
const
|
|
100
|
+
const pageParam = url.searchParams.get("page");
|
|
101
|
+
const offset = url.searchParams.get("offset");
|
|
102
|
+
const after = url.searchParams.get("after") ?? void 0;
|
|
103
|
+
const before = url.searchParams.get("before") ?? void 0;
|
|
104
|
+
const page = pageParam === null ? void 0 : Number.isInteger(Number(pageParam)) && Number(pageParam) > 0 ? Number(pageParam) : null;
|
|
105
|
+
if (offset !== null) throw new HandlerBadRequestError("The 'offset' query parameter has been removed. Use 'after' or 'before' cursor pagination instead.");
|
|
106
|
+
if (page === null) throw new HandlerBadRequestError("The 'page' query parameter must be a positive integer.");
|
|
101
107
|
if (platform !== null && !isPlatform(platform)) throw new HandlerBadRequestError(`Invalid platform: ${platform}. Expected 'ios' or 'android'.`);
|
|
102
108
|
const result = await api.getBundles({
|
|
103
109
|
where: {
|
|
@@ -105,7 +111,11 @@ const handleGetBundles = async (_params, request, api, context) => {
|
|
|
105
111
|
...platform && { platform }
|
|
106
112
|
},
|
|
107
113
|
limit,
|
|
108
|
-
|
|
114
|
+
page,
|
|
115
|
+
cursor: after || before ? {
|
|
116
|
+
after,
|
|
117
|
+
before
|
|
118
|
+
} : void 0
|
|
109
119
|
}, context);
|
|
110
120
|
return new Response(JSON.stringify(result), {
|
|
111
121
|
status: 200,
|
package/dist/types/index.d.cts
CHANGED
package/dist/types/index.d.mts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/server",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "React Native OTA solution for self-hosted",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"fumadb": "0.2.2",
|
|
54
54
|
"rou3": "0.7.9",
|
|
55
55
|
"semver": "^7.7.2",
|
|
56
|
-
"@hot-updater/plugin-core": "0.29.
|
|
57
|
-
"@hot-updater/
|
|
58
|
-
"@hot-updater/
|
|
56
|
+
"@hot-updater/plugin-core": "0.29.6",
|
|
57
|
+
"@hot-updater/js": "0.29.6",
|
|
58
|
+
"@hot-updater/core": "0.29.6"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@electric-sql/pglite": "^0.2.17",
|
|
@@ -66,8 +66,8 @@
|
|
|
66
66
|
"kysely-pglite-dialect": "^1.2.0",
|
|
67
67
|
"msw": "^2.7.0",
|
|
68
68
|
"uuidv7": "^1.0.2",
|
|
69
|
-
"@hot-updater/
|
|
70
|
-
"@hot-updater/
|
|
69
|
+
"@hot-updater/test-utils": "0.29.6",
|
|
70
|
+
"@hot-updater/standalone": "0.29.6"
|
|
71
71
|
},
|
|
72
72
|
"scripts": {
|
|
73
73
|
"build": "tsdown",
|