@hot-updater/cloudflare 0.32.0 → 0.33.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/index.cjs +9 -12
- package/dist/index.mjs +9 -12
- package/dist/worker/index.cjs +9 -12
- package/dist/worker/index.mjs +9 -12
- package/package.json +7 -7
- package/src/cloudflareWorkerDatabase.spec.ts +260 -0
- package/src/cloudflareWorkerDatabase.ts +23 -19
- package/src/d1Database.spec.ts +16 -2
- package/src/d1Database.ts +23 -19
- package/worker/dist/README.md +1 -1
- package/worker/dist/index.js +165 -35
- package/worker/dist/index.js.map +4 -4
- package/worker/src/getUpdateInfo.ts +0 -194
package/src/d1Database.ts
CHANGED
|
@@ -34,6 +34,19 @@ interface BuildQueryResult {
|
|
|
34
34
|
params: any[];
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
const buildJsonEachInClause = (
|
|
38
|
+
columnName: string,
|
|
39
|
+
values: string[],
|
|
40
|
+
params: any[],
|
|
41
|
+
) => {
|
|
42
|
+
if (values.length === 0) {
|
|
43
|
+
return "1 = 0";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
params.push(JSON.stringify(values));
|
|
47
|
+
return `${columnName} IN (SELECT value FROM json_each(?))`;
|
|
48
|
+
};
|
|
49
|
+
|
|
37
50
|
interface D1BundleRow {
|
|
38
51
|
id: string;
|
|
39
52
|
channel: string;
|
|
@@ -94,12 +107,7 @@ function buildWhereClause(conditions: QueryConditions): BuildQueryResult {
|
|
|
94
107
|
}
|
|
95
108
|
|
|
96
109
|
if (conditions.id?.in) {
|
|
97
|
-
|
|
98
|
-
clauses.push("1 = 0");
|
|
99
|
-
} else {
|
|
100
|
-
clauses.push(`id IN (${conditions.id.in.map(() => "?").join(", ")})`);
|
|
101
|
-
params.push(...conditions.id.in);
|
|
102
|
-
}
|
|
110
|
+
clauses.push(buildJsonEachInClause("id", conditions.id.in, params));
|
|
103
111
|
}
|
|
104
112
|
|
|
105
113
|
if (conditions.id?.eq) {
|
|
@@ -141,16 +149,13 @@ function buildWhereClause(conditions: QueryConditions): BuildQueryResult {
|
|
|
141
149
|
}
|
|
142
150
|
|
|
143
151
|
if (conditions.targetAppVersionIn) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
);
|
|
152
|
-
params.push(...conditions.targetAppVersionIn);
|
|
153
|
-
}
|
|
152
|
+
clauses.push(
|
|
153
|
+
buildJsonEachInClause(
|
|
154
|
+
"target_app_version",
|
|
155
|
+
conditions.targetAppVersionIn,
|
|
156
|
+
params,
|
|
157
|
+
),
|
|
158
|
+
);
|
|
154
159
|
}
|
|
155
160
|
|
|
156
161
|
if (conditions.fingerprintHash !== undefined) {
|
|
@@ -275,18 +280,17 @@ export const d1Database = createDatabasePlugin<D1DatabaseConfig>({
|
|
|
275
280
|
return patchMap;
|
|
276
281
|
}
|
|
277
282
|
|
|
278
|
-
const placeholders = bundleIds.map(() => "?").join(", ");
|
|
279
283
|
const sql = minify(`
|
|
280
284
|
SELECT *
|
|
281
285
|
FROM bundle_patches
|
|
282
|
-
WHERE bundle_id IN (
|
|
286
|
+
WHERE bundle_id IN (SELECT value FROM json_each(?))
|
|
283
287
|
ORDER BY order_index ASC, base_bundle_id ASC
|
|
284
288
|
`);
|
|
285
289
|
|
|
286
290
|
const result = await cf.d1.database.query(config.databaseId, {
|
|
287
291
|
account_id: config.accountId,
|
|
288
292
|
sql,
|
|
289
|
-
params: bundleIds,
|
|
293
|
+
params: [JSON.stringify(bundleIds)],
|
|
290
294
|
});
|
|
291
295
|
const rows = await resolvePage<D1BundlePatchRow>(result);
|
|
292
296
|
|
package/worker/dist/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
This folder contains the built output assets for the worker "hot-updater" generated at 2026-
|
|
1
|
+
This folder contains the built output assets for the worker "hot-updater" generated at 2026-06-11T16:55:59.241Z.
|
package/worker/dist/index.js
CHANGED
|
@@ -5594,7 +5594,28 @@ var filterCompatibleAppVersions = /* @__PURE__ */ __name((targetAppVersionList,
|
|
|
5594
5594
|
return targetAppVersionList.filter((version2) => semverSatisfies(version2, currentVersion)).sort((a, b) => b.localeCompare(a));
|
|
5595
5595
|
}, "filterCompatibleAppVersions");
|
|
5596
5596
|
|
|
5597
|
-
// ../
|
|
5597
|
+
// ../plugin-core/dist/requestUpdateBundleState.mjs
|
|
5598
|
+
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
|
|
5599
|
+
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
|
|
5600
|
+
init_performance2();
|
|
5601
|
+
var requestUpdateBundleSeeds = /* @__PURE__ */ new WeakMap();
|
|
5602
|
+
var isWeakMapKey = /* @__PURE__ */ __name((value) => typeof value === "object" && value !== null || typeof value === "function", "isWeakMapKey");
|
|
5603
|
+
var toBundleSeeds = /* @__PURE__ */ __name((seeds) => seeds.filter((seed) => !!seed), "toBundleSeeds");
|
|
5604
|
+
var seedRequestUpdateBundles = /* @__PURE__ */ __name((context2, seeds) => {
|
|
5605
|
+
if (!isWeakMapKey(context2)) return;
|
|
5606
|
+
const nextSeeds = toBundleSeeds(seeds);
|
|
5607
|
+
if (nextSeeds.length === 0) return;
|
|
5608
|
+
const bundlesById = /* @__PURE__ */ new Map();
|
|
5609
|
+
for (const seed of requestUpdateBundleSeeds.get(context2) ?? []) bundlesById.set(seed.id, seed);
|
|
5610
|
+
for (const seed of nextSeeds) bundlesById.set(seed.id, seed);
|
|
5611
|
+
requestUpdateBundleSeeds.set(context2, [...bundlesById.values()]);
|
|
5612
|
+
}, "seedRequestUpdateBundles");
|
|
5613
|
+
var getRequestUpdateBundleSeeds = /* @__PURE__ */ __name((context2) => {
|
|
5614
|
+
if (!isWeakMapKey(context2)) return [];
|
|
5615
|
+
return requestUpdateBundleSeeds.get(context2) ?? [];
|
|
5616
|
+
}, "getRequestUpdateBundleSeeds");
|
|
5617
|
+
|
|
5618
|
+
// ../plugin-core/dist/resolveUpdateInfoFromBundles.mjs
|
|
5598
5619
|
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
|
|
5599
5620
|
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
|
|
5600
5621
|
init_performance2();
|
|
@@ -5747,6 +5768,9 @@ __name(isCohortEligibleForUpdate, "isCohortEligibleForUpdate");
|
|
|
5747
5768
|
var NIL_UUID = "00000000-0000-0000-0000-000000000000";
|
|
5748
5769
|
|
|
5749
5770
|
// ../js/dist/index.mjs
|
|
5771
|
+
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
|
|
5772
|
+
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
|
|
5773
|
+
init_performance2();
|
|
5750
5774
|
var __create2 = Object.create;
|
|
5751
5775
|
var __defProp2 = Object.defineProperty;
|
|
5752
5776
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
@@ -8279,6 +8303,15 @@ var signToken = /* @__PURE__ */ __name(async (key, jwtSecret) => {
|
|
|
8279
8303
|
return await new SignJWT({ key }).setProtectedHeader({ alg: "HS256" }).setExpirationTime("60s").sign(secretKey);
|
|
8280
8304
|
}, "signToken");
|
|
8281
8305
|
|
|
8306
|
+
// ../plugin-core/dist/resolveUpdateInfoFromBundles.mjs
|
|
8307
|
+
var findSeedBundle = /* @__PURE__ */ __name((bundles, bundleId) => bundles.find((bundle) => bundle.id === bundleId), "findSeedBundle");
|
|
8308
|
+
var resolveUpdateInfoFromBundles = /* @__PURE__ */ __name(async ({ args, bundles, context: context2 }) => {
|
|
8309
|
+
const info3 = await getUpdateInfo(bundles, args);
|
|
8310
|
+
if (!info3) return null;
|
|
8311
|
+
seedRequestUpdateBundles(context2, [findSeedBundle(bundles, info3.id), args.bundleId === NIL_UUID ? null : findSeedBundle(bundles, args.bundleId)]);
|
|
8312
|
+
return info3;
|
|
8313
|
+
}, "resolveUpdateInfoFromBundles");
|
|
8314
|
+
|
|
8282
8315
|
// ../plugin-core/dist/createDatabasePluginGetUpdateInfo.mjs
|
|
8283
8316
|
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
|
|
8284
8317
|
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
|
|
@@ -8298,10 +8331,18 @@ var createDatabasePluginGetUpdateInfo = /* @__PURE__ */ __name(({ getBundlesByFi
|
|
|
8298
8331
|
if (args._updateStrategy === "appVersion") {
|
|
8299
8332
|
const normalizedArgs2 = normalizeAppVersionArgs(args);
|
|
8300
8333
|
const compatibleAppVersions = filterCompatibleAppVersions(await listTargetAppVersions(normalizedArgs2, context2), normalizedArgs2.appVersion);
|
|
8301
|
-
return
|
|
8334
|
+
return resolveUpdateInfoFromBundles({
|
|
8335
|
+
args: normalizedArgs2,
|
|
8336
|
+
bundles: compatibleAppVersions.length > 0 ? await getBundlesByTargetAppVersions(normalizedArgs2, compatibleAppVersions, context2) : [],
|
|
8337
|
+
context: context2
|
|
8338
|
+
});
|
|
8302
8339
|
}
|
|
8303
8340
|
const normalizedArgs = normalizeFingerprintArgs(args);
|
|
8304
|
-
return
|
|
8341
|
+
return resolveUpdateInfoFromBundles({
|
|
8342
|
+
args: normalizedArgs,
|
|
8343
|
+
bundles: await getBundlesByFingerprint(normalizedArgs, context2),
|
|
8344
|
+
context: context2
|
|
8345
|
+
});
|
|
8305
8346
|
};
|
|
8306
8347
|
}, "createDatabasePluginGetUpdateInfo");
|
|
8307
8348
|
|
|
@@ -8414,6 +8455,51 @@ init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
|
|
|
8414
8455
|
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
|
|
8415
8456
|
init_performance2();
|
|
8416
8457
|
|
|
8458
|
+
// ../../packages/server/src/db/requestBundleIdentityMap.ts
|
|
8459
|
+
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
|
|
8460
|
+
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
|
|
8461
|
+
init_performance2();
|
|
8462
|
+
var createRequestBundleIdentityMap = /* @__PURE__ */ __name(({
|
|
8463
|
+
context: context2,
|
|
8464
|
+
loadBundleById,
|
|
8465
|
+
seeds
|
|
8466
|
+
}) => {
|
|
8467
|
+
const bundles = /* @__PURE__ */ new Map();
|
|
8468
|
+
const pendingBundles = /* @__PURE__ */ new Map();
|
|
8469
|
+
for (const seed of seeds) {
|
|
8470
|
+
if (seed) {
|
|
8471
|
+
bundles.set(seed.id, seed);
|
|
8472
|
+
}
|
|
8473
|
+
}
|
|
8474
|
+
const get = /* @__PURE__ */ __name(async (bundleId) => {
|
|
8475
|
+
const cachedBundle = bundles.get(bundleId);
|
|
8476
|
+
if (cachedBundle) {
|
|
8477
|
+
return cachedBundle;
|
|
8478
|
+
}
|
|
8479
|
+
const pendingBundle = pendingBundles.get(bundleId);
|
|
8480
|
+
if (pendingBundle) {
|
|
8481
|
+
return pendingBundle;
|
|
8482
|
+
}
|
|
8483
|
+
const lookup = loadBundleById(bundleId, context2).then(
|
|
8484
|
+
(bundle) => {
|
|
8485
|
+
pendingBundles.delete(bundleId);
|
|
8486
|
+
if (bundle) {
|
|
8487
|
+
bundles.set(bundle.id, bundle);
|
|
8488
|
+
}
|
|
8489
|
+
return bundle;
|
|
8490
|
+
},
|
|
8491
|
+
(error3) => {
|
|
8492
|
+
pendingBundles.delete(bundleId);
|
|
8493
|
+
throw error3;
|
|
8494
|
+
}
|
|
8495
|
+
);
|
|
8496
|
+
pendingBundles.set(bundleId, lookup);
|
|
8497
|
+
return lookup;
|
|
8498
|
+
}, "get");
|
|
8499
|
+
const peek = /* @__PURE__ */ __name((bundleId) => bundles.get(bundleId) ?? null, "peek");
|
|
8500
|
+
return { get, peek };
|
|
8501
|
+
}, "createRequestBundleIdentityMap");
|
|
8502
|
+
|
|
8417
8503
|
// ../../packages/server/src/db/schemaEnhancements.ts
|
|
8418
8504
|
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
|
|
8419
8505
|
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
|
|
@@ -8872,10 +8958,26 @@ function createPluginDatabaseCore(getPlugin, resolveFileUrl, options) {
|
|
|
8872
8958
|
const baseResponse2 = { ...rest, fileUrl: fileUrl2 };
|
|
8873
8959
|
return baseResponse2;
|
|
8874
8960
|
}
|
|
8961
|
+
const requestBundleSeeds = getRequestUpdateBundleSeeds(context2);
|
|
8962
|
+
const requestBundles = createRequestBundleIdentityMap({
|
|
8963
|
+
context: context2,
|
|
8964
|
+
loadBundleById: /* @__PURE__ */ __name((bundleId, requestContext) => getPlugin().getBundleById(bundleId, requestContext), "loadBundleById"),
|
|
8965
|
+
seeds: requestBundleSeeds
|
|
8966
|
+
});
|
|
8967
|
+
const getCurrentBundle = /* @__PURE__ */ __name(() => {
|
|
8968
|
+
if (args.bundleId === NIL_UUID) {
|
|
8969
|
+
return null;
|
|
8970
|
+
}
|
|
8971
|
+
const seededCurrentBundle = requestBundles.peek(args.bundleId);
|
|
8972
|
+
if (seededCurrentBundle || requestBundleSeeds.length > 0) {
|
|
8973
|
+
return seededCurrentBundle;
|
|
8974
|
+
}
|
|
8975
|
+
return requestBundles.get(args.bundleId);
|
|
8976
|
+
}, "getCurrentBundle");
|
|
8875
8977
|
const [fileUrl, targetBundle, currentBundle] = await Promise.all([
|
|
8876
8978
|
resolveFileUrl(storageUri ?? null, context2),
|
|
8877
|
-
|
|
8878
|
-
|
|
8979
|
+
requestBundles.get(info3.id),
|
|
8980
|
+
getCurrentBundle()
|
|
8879
8981
|
]);
|
|
8880
8982
|
const baseResponse = { ...rest, fileUrl };
|
|
8881
8983
|
const manifestArtifacts = await resolveManifestArtifacts({
|
|
@@ -8928,6 +9030,36 @@ function createPluginDatabaseCore(getPlugin, resolveFileUrl, options) {
|
|
|
8928
9030
|
});
|
|
8929
9031
|
}
|
|
8930
9032
|
};
|
|
9033
|
+
Object.defineProperty(api, "diagnostics", {
|
|
9034
|
+
configurable: true,
|
|
9035
|
+
enumerable: true,
|
|
9036
|
+
get() {
|
|
9037
|
+
const diagnostics = getPlugin().diagnostics;
|
|
9038
|
+
if (!diagnostics) {
|
|
9039
|
+
Object.defineProperty(this, "diagnostics", {
|
|
9040
|
+
configurable: true,
|
|
9041
|
+
enumerable: true,
|
|
9042
|
+
value: void 0
|
|
9043
|
+
});
|
|
9044
|
+
return void 0;
|
|
9045
|
+
}
|
|
9046
|
+
const wrappedDiagnostics = {};
|
|
9047
|
+
if (diagnostics.bundleIndex) {
|
|
9048
|
+
wrappedDiagnostics.bundleIndex = {
|
|
9049
|
+
check: /* @__PURE__ */ __name((context2) => getPlugin().diagnostics.bundleIndex.check(context2), "check"),
|
|
9050
|
+
...diagnostics.bundleIndex.repair ? {
|
|
9051
|
+
repair: /* @__PURE__ */ __name((context2) => getPlugin().diagnostics.bundleIndex.repair(context2), "repair")
|
|
9052
|
+
} : {}
|
|
9053
|
+
};
|
|
9054
|
+
}
|
|
9055
|
+
Object.defineProperty(this, "diagnostics", {
|
|
9056
|
+
configurable: true,
|
|
9057
|
+
enumerable: true,
|
|
9058
|
+
value: wrappedDiagnostics
|
|
9059
|
+
});
|
|
9060
|
+
return wrappedDiagnostics;
|
|
9061
|
+
}
|
|
9062
|
+
});
|
|
8931
9063
|
return {
|
|
8932
9064
|
api,
|
|
8933
9065
|
adapterName: getPlugin().name,
|
|
@@ -9064,7 +9196,7 @@ init_performance2();
|
|
|
9064
9196
|
// ../../packages/server/package.json
|
|
9065
9197
|
var package_default = {
|
|
9066
9198
|
name: "@hot-updater/server",
|
|
9067
|
-
version: "0.
|
|
9199
|
+
version: "0.33.0",
|
|
9068
9200
|
type: "module",
|
|
9069
9201
|
description: "React Native OTA solution for self-hosted",
|
|
9070
9202
|
sideEffects: false,
|
|
@@ -9656,25 +9788,23 @@ function createHotUpdater(options) {
|
|
|
9656
9788
|
readStorageText
|
|
9657
9789
|
} : { readStorageText }
|
|
9658
9790
|
);
|
|
9659
|
-
const
|
|
9660
|
-
|
|
9661
|
-
|
|
9662
|
-
|
|
9663
|
-
routes: options.routes
|
|
9664
|
-
}),
|
|
9665
|
-
adapterName: core.adapterName
|
|
9666
|
-
};
|
|
9791
|
+
const internalHandler = createHandler(core.api, {
|
|
9792
|
+
basePath,
|
|
9793
|
+
routes: options.routes
|
|
9794
|
+
});
|
|
9667
9795
|
const handler = /* @__PURE__ */ __name((request, context2, ...extraArgs) => {
|
|
9668
9796
|
if (extraArgs.length > 0) {
|
|
9669
|
-
return
|
|
9797
|
+
return internalHandler(request);
|
|
9670
9798
|
}
|
|
9671
|
-
return
|
|
9799
|
+
return internalHandler(request, context2);
|
|
9672
9800
|
}, "handler");
|
|
9673
|
-
|
|
9674
|
-
...api,
|
|
9801
|
+
const api = {
|
|
9675
9802
|
basePath,
|
|
9803
|
+
adapterName: core.adapterName,
|
|
9676
9804
|
handler
|
|
9677
9805
|
};
|
|
9806
|
+
Object.defineProperties(api, Object.getOwnPropertyDescriptors(core.api));
|
|
9807
|
+
return api;
|
|
9678
9808
|
}
|
|
9679
9809
|
__name(createHotUpdater, "createHotUpdater");
|
|
9680
9810
|
|
|
@@ -11878,6 +12008,13 @@ init_performance2();
|
|
|
11878
12008
|
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
|
|
11879
12009
|
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
|
|
11880
12010
|
init_performance2();
|
|
12011
|
+
var buildJsonEachInClause = /* @__PURE__ */ __name((columnName, values, params) => {
|
|
12012
|
+
if (values.length === 0) {
|
|
12013
|
+
return "1 = 0";
|
|
12014
|
+
}
|
|
12015
|
+
params.push(JSON.stringify(values));
|
|
12016
|
+
return `${columnName} IN (SELECT value FROM json_each(?))`;
|
|
12017
|
+
}, "buildJsonEachInClause");
|
|
11881
12018
|
function buildWhereClause(conditions) {
|
|
11882
12019
|
if (!conditions) {
|
|
11883
12020
|
return { sql: "", params: [] };
|
|
@@ -11897,12 +12034,7 @@ function buildWhereClause(conditions) {
|
|
|
11897
12034
|
params.push(conditions.enabled ? 1 : 0);
|
|
11898
12035
|
}
|
|
11899
12036
|
if (conditions.id?.in) {
|
|
11900
|
-
|
|
11901
|
-
clauses.push("1 = 0");
|
|
11902
|
-
} else {
|
|
11903
|
-
clauses.push(`id IN (${conditions.id.in.map(() => "?").join(", ")})`);
|
|
11904
|
-
params.push(...conditions.id.in);
|
|
11905
|
-
}
|
|
12037
|
+
clauses.push(buildJsonEachInClause("id", conditions.id.in, params));
|
|
11906
12038
|
}
|
|
11907
12039
|
if (conditions.id?.eq) {
|
|
11908
12040
|
clauses.push("id = ?");
|
|
@@ -11936,14 +12068,13 @@ function buildWhereClause(conditions) {
|
|
|
11936
12068
|
}
|
|
11937
12069
|
}
|
|
11938
12070
|
if (conditions.targetAppVersionIn) {
|
|
11939
|
-
|
|
11940
|
-
|
|
11941
|
-
|
|
11942
|
-
|
|
11943
|
-
|
|
11944
|
-
)
|
|
11945
|
-
|
|
11946
|
-
}
|
|
12071
|
+
clauses.push(
|
|
12072
|
+
buildJsonEachInClause(
|
|
12073
|
+
"target_app_version",
|
|
12074
|
+
conditions.targetAppVersionIn,
|
|
12075
|
+
params
|
|
12076
|
+
)
|
|
12077
|
+
);
|
|
11947
12078
|
}
|
|
11948
12079
|
if (conditions.fingerprintHash !== void 0) {
|
|
11949
12080
|
if (conditions.fingerprintHash === null) {
|
|
@@ -12060,15 +12191,14 @@ var d1WorkerDatabase = /* @__PURE__ */ __name(() => createDatabasePlugin({
|
|
|
12060
12191
|
if (bundleIds.length === 0) {
|
|
12061
12192
|
return patchMap;
|
|
12062
12193
|
}
|
|
12063
|
-
const placeholders = bundleIds.map(() => "?").join(", ");
|
|
12064
12194
|
const rows = await queryAll(
|
|
12065
12195
|
`
|
|
12066
12196
|
SELECT *
|
|
12067
12197
|
FROM bundle_patches
|
|
12068
|
-
WHERE bundle_id IN (
|
|
12198
|
+
WHERE bundle_id IN (SELECT value FROM json_each(?))
|
|
12069
12199
|
ORDER BY order_index ASC, base_bundle_id ASC
|
|
12070
12200
|
`,
|
|
12071
|
-
bundleIds,
|
|
12201
|
+
[JSON.stringify(bundleIds)],
|
|
12072
12202
|
context2
|
|
12073
12203
|
);
|
|
12074
12204
|
for (const row of rows) {
|