@hot-updater/cloudflare 0.30.11 → 0.31.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/iac/index.cjs +0 -1
- package/dist/iac/index.mjs +0 -1
- package/dist/index.cjs +164 -57
- package/dist/index.d.cts +1 -21
- package/dist/index.d.mts +1 -21
- package/dist/index.mjs +174 -67
- package/dist/worker/index.cjs +109 -25
- package/dist/worker/index.d.cts +6 -1
- package/dist/worker/index.d.mts +6 -1
- package/dist/worker/index.mjs +111 -27
- package/package.json +7 -7
- package/sql/bundles.sql +23 -3
- package/src/cloudflareWorkerDatabase.ts +198 -15
- package/src/d1Database.spec.ts +85 -3
- package/src/d1Database.ts +206 -19
- package/src/r2Storage.spec.ts +85 -0
- package/src/r2Storage.ts +33 -37
- package/src/r2WorkerStorage.spec.ts +50 -0
- package/src/r2WorkerStorage.ts +52 -20
- package/worker/dist/README.md +1 -1
- package/worker/dist/index.js +3038 -247
- package/worker/dist/index.js.map +4 -4
- package/worker/migrations/0005_hot-updater_0.31.0.sql +24 -0
- package/worker/src/index.integration.spec.ts +209 -18
package/dist/index.mjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import { DEFAULT_ROLLOUT_COHORT_COUNT } from "@hot-updater/core";
|
|
3
|
-
import { calculatePagination, createDatabasePlugin, createDatabasePluginGetUpdateInfo,
|
|
2
|
+
import { DEFAULT_ROLLOUT_COHORT_COUNT, getAssetBaseStorageUri, getBundlePatches, getManifestFileHash, getManifestStorageUri, stripBundleArtifactMetadata } from "@hot-updater/core";
|
|
3
|
+
import { calculatePagination, createDatabasePlugin, createDatabasePluginGetUpdateInfo, createNodeStoragePlugin, createStorageKeyBuilder, getContentType, parseStorageUri } from "@hot-updater/plugin-core";
|
|
4
4
|
import Cloudflare from "cloudflare";
|
|
5
|
-
import
|
|
5
|
+
import fs from "node:fs/promises";
|
|
6
|
+
import path from "node:path";
|
|
6
7
|
import { fileURLToPath } from "node:url";
|
|
7
8
|
import { ChildProcess, execFile, spawn, spawnSync } from "node:child_process";
|
|
8
9
|
import { StringDecoder } from "node:string_decoder";
|
|
9
10
|
import { aborted, callbackify, debuglog, inspect, promisify, stripVTControlCharacters } from "node:util";
|
|
10
11
|
import process$1, { execArgv, execPath, hrtime, platform } from "node:process";
|
|
11
12
|
import tty from "node:tty";
|
|
12
|
-
import path$1 from "node:path";
|
|
13
13
|
import { scheduler, setImmediate, setTimeout } from "node:timers/promises";
|
|
14
14
|
import { constants } from "node:os";
|
|
15
15
|
import { EventEmitter, addAbortListener, on, once, setMaxListeners } from "node:events";
|
|
@@ -353,7 +353,34 @@ function parseTargetCohorts(value) {
|
|
|
353
353
|
}
|
|
354
354
|
return null;
|
|
355
355
|
}
|
|
356
|
-
|
|
356
|
+
const parseMetadata = (value) => {
|
|
357
|
+
if (!value) return void 0;
|
|
358
|
+
if (typeof value === "string") try {
|
|
359
|
+
return parseMetadata(JSON.parse(value));
|
|
360
|
+
} catch {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
return typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
364
|
+
};
|
|
365
|
+
const buildBundlePatchId = (bundleId, baseBundleId) => `${bundleId}:${baseBundleId}`;
|
|
366
|
+
const bundleToPatchRows = (bundle) => getBundlePatches(bundle).map((patch, index) => ({
|
|
367
|
+
id: buildBundlePatchId(bundle.id, patch.baseBundleId),
|
|
368
|
+
bundle_id: bundle.id,
|
|
369
|
+
base_bundle_id: patch.baseBundleId,
|
|
370
|
+
base_file_hash: patch.baseFileHash,
|
|
371
|
+
patch_file_hash: patch.patchFileHash,
|
|
372
|
+
patch_storage_uri: patch.patchStorageUri,
|
|
373
|
+
order_index: index
|
|
374
|
+
}));
|
|
375
|
+
function transformRowToBundle(row, patchRows = []) {
|
|
376
|
+
const rawMetadata = parseMetadata(row.metadata);
|
|
377
|
+
const patches = patchRows.slice().sort((left, right) => (left.order_index ?? 0) - (right.order_index ?? 0) || left.base_bundle_id.localeCompare(right.base_bundle_id)).map((patch) => ({
|
|
378
|
+
baseBundleId: patch.base_bundle_id,
|
|
379
|
+
baseFileHash: patch.base_file_hash,
|
|
380
|
+
patchFileHash: patch.patch_file_hash,
|
|
381
|
+
patchStorageUri: patch.patch_storage_uri
|
|
382
|
+
}));
|
|
383
|
+
const primaryPatch = patches[0] ?? null;
|
|
357
384
|
return {
|
|
358
385
|
id: row.id,
|
|
359
386
|
channel: row.channel,
|
|
@@ -366,7 +393,15 @@ function transformRowToBundle(row) {
|
|
|
366
393
|
targetAppVersion: row.target_app_version,
|
|
367
394
|
storageUri: row.storage_uri,
|
|
368
395
|
fingerprintHash: row.fingerprint_hash,
|
|
369
|
-
metadata:
|
|
396
|
+
metadata: stripBundleArtifactMetadata(rawMetadata),
|
|
397
|
+
manifestStorageUri: row.manifest_storage_uri ?? null,
|
|
398
|
+
manifestFileHash: row.manifest_file_hash ?? null,
|
|
399
|
+
assetBaseStorageUri: row.asset_base_storage_uri ?? null,
|
|
400
|
+
patches,
|
|
401
|
+
patchBaseBundleId: primaryPatch?.baseBundleId ?? null,
|
|
402
|
+
patchBaseFileHash: primaryPatch?.baseFileHash ?? null,
|
|
403
|
+
patchFileHash: primaryPatch?.patchFileHash ?? null,
|
|
404
|
+
patchStorageUri: primaryPatch?.patchStorageUri ?? null,
|
|
370
405
|
rolloutCohortCount: row.rollout_cohort_count ?? DEFAULT_ROLLOUT_COHORT_COUNT,
|
|
371
406
|
targetCohorts: parseTargetCohorts(row.target_cohorts)
|
|
372
407
|
};
|
|
@@ -375,6 +410,27 @@ const d1Database = createDatabasePlugin({
|
|
|
375
410
|
name: "d1Database",
|
|
376
411
|
factory: (config) => {
|
|
377
412
|
const cf = new Cloudflare({ apiToken: config.cloudflareApiToken });
|
|
413
|
+
const getPatchMap = async (bundleIds) => {
|
|
414
|
+
const patchMap = /* @__PURE__ */ new Map();
|
|
415
|
+
if (bundleIds.length === 0) return patchMap;
|
|
416
|
+
const sql = (0, import_lib.default)(`
|
|
417
|
+
SELECT *
|
|
418
|
+
FROM bundle_patches
|
|
419
|
+
WHERE bundle_id IN (${bundleIds.map(() => "?").join(", ")})
|
|
420
|
+
ORDER BY order_index ASC, base_bundle_id ASC
|
|
421
|
+
`);
|
|
422
|
+
const rows = await resolvePage(await cf.d1.database.query(config.databaseId, {
|
|
423
|
+
account_id: config.accountId,
|
|
424
|
+
sql,
|
|
425
|
+
params: bundleIds
|
|
426
|
+
}));
|
|
427
|
+
for (const row of rows) {
|
|
428
|
+
const current = patchMap.get(row.bundle_id) ?? [];
|
|
429
|
+
current.push(row);
|
|
430
|
+
patchMap.set(row.bundle_id, current);
|
|
431
|
+
}
|
|
432
|
+
return patchMap;
|
|
433
|
+
};
|
|
378
434
|
async function getTotalCount(conditions) {
|
|
379
435
|
const { sql: whereClause, params } = buildWhereClause(conditions);
|
|
380
436
|
const countSql = (0, import_lib.default)(`SELECT COUNT(*) as total FROM bundles${whereClause}`);
|
|
@@ -394,11 +450,13 @@ const d1Database = createDatabasePlugin({
|
|
|
394
450
|
OFFSET ?
|
|
395
451
|
`);
|
|
396
452
|
params.push(limit, offset);
|
|
397
|
-
|
|
453
|
+
const rows = await resolvePage(await cf.d1.database.query(config.databaseId, {
|
|
398
454
|
account_id: config.accountId,
|
|
399
455
|
sql,
|
|
400
456
|
params
|
|
401
|
-
}))
|
|
457
|
+
}));
|
|
458
|
+
const patchMap = await getPatchMap(rows.map((row) => row.id));
|
|
459
|
+
return rows.map((row) => transformRowToBundle(row, patchMap.get(row.id)));
|
|
402
460
|
}
|
|
403
461
|
async function queryBundlesForUpdateInfo(conditions) {
|
|
404
462
|
const { sql: whereClause, params } = buildWhereClause(conditions);
|
|
@@ -406,11 +464,13 @@ const d1Database = createDatabasePlugin({
|
|
|
406
464
|
SELECT * FROM bundles
|
|
407
465
|
${whereClause}
|
|
408
466
|
`);
|
|
409
|
-
|
|
467
|
+
const rows = await resolvePage(await cf.d1.database.query(config.databaseId, {
|
|
410
468
|
account_id: config.accountId,
|
|
411
469
|
sql,
|
|
412
470
|
params
|
|
413
|
-
}))
|
|
471
|
+
}));
|
|
472
|
+
const patchMap = await getPatchMap(rows.map((row) => row.id));
|
|
473
|
+
return rows.map((row) => transformRowToBundle(row, patchMap.get(row.id)));
|
|
414
474
|
}
|
|
415
475
|
async function getTargetAppVersionsForUpdateInfo({ platform, channel, minBundleId }) {
|
|
416
476
|
const sql = (0, import_lib.default)(`
|
|
@@ -458,13 +518,14 @@ const d1Database = createDatabasePlugin({
|
|
|
458
518
|
async getBundleById(bundleId) {
|
|
459
519
|
const sql = (0, import_lib.default)(`
|
|
460
520
|
SELECT * FROM bundles WHERE id = ? LIMIT 1`);
|
|
461
|
-
const
|
|
521
|
+
const [singlePage, patchMap] = await Promise.all([cf.d1.database.query(config.databaseId, {
|
|
462
522
|
account_id: config.accountId,
|
|
463
523
|
sql,
|
|
464
524
|
params: [bundleId]
|
|
465
|
-
}));
|
|
525
|
+
}), getPatchMap([bundleId])]);
|
|
526
|
+
const rows = await resolvePage(singlePage);
|
|
466
527
|
if (rows.length === 0) return null;
|
|
467
|
-
return transformRowToBundle(rows[0]);
|
|
528
|
+
return transformRowToBundle(rows[0], patchMap.get(bundleId));
|
|
468
529
|
},
|
|
469
530
|
async getBundles(options) {
|
|
470
531
|
const { where = {}, limit, orderBy } = options;
|
|
@@ -494,6 +555,22 @@ const d1Database = createDatabasePlugin({
|
|
|
494
555
|
const deleteSql = (0, import_lib.default)(`
|
|
495
556
|
DELETE FROM bundles WHERE id = ?
|
|
496
557
|
`);
|
|
558
|
+
const deletePatchSql = (0, import_lib.default)(`
|
|
559
|
+
DELETE FROM bundle_patches WHERE bundle_id = ?
|
|
560
|
+
`);
|
|
561
|
+
await cf.d1.database.query(config.databaseId, {
|
|
562
|
+
account_id: config.accountId,
|
|
563
|
+
sql: deletePatchSql,
|
|
564
|
+
params: [op.data.id]
|
|
565
|
+
});
|
|
566
|
+
const deleteBasePatchSql = (0, import_lib.default)(`
|
|
567
|
+
DELETE FROM bundle_patches WHERE base_bundle_id = ?
|
|
568
|
+
`);
|
|
569
|
+
await cf.d1.database.query(config.databaseId, {
|
|
570
|
+
account_id: config.accountId,
|
|
571
|
+
sql: deleteBasePatchSql,
|
|
572
|
+
params: [op.data.id]
|
|
573
|
+
});
|
|
497
574
|
await cf.d1.database.query(config.databaseId, {
|
|
498
575
|
account_id: config.accountId,
|
|
499
576
|
sql: deleteSql,
|
|
@@ -515,10 +592,13 @@ const d1Database = createDatabasePlugin({
|
|
|
515
592
|
storage_uri,
|
|
516
593
|
fingerprint_hash,
|
|
517
594
|
metadata,
|
|
595
|
+
manifest_storage_uri,
|
|
596
|
+
manifest_file_hash,
|
|
597
|
+
asset_base_storage_uri,
|
|
518
598
|
rollout_cohort_count,
|
|
519
599
|
target_cohorts
|
|
520
600
|
)
|
|
521
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
601
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
522
602
|
`);
|
|
523
603
|
const params = [
|
|
524
604
|
bundle.id,
|
|
@@ -532,7 +612,10 @@ const d1Database = createDatabasePlugin({
|
|
|
532
612
|
bundle.targetAppVersion,
|
|
533
613
|
bundle.storageUri,
|
|
534
614
|
bundle.fingerprintHash,
|
|
535
|
-
|
|
615
|
+
JSON.stringify(stripBundleArtifactMetadata(bundle.metadata) ?? {}),
|
|
616
|
+
getManifestStorageUri(bundle),
|
|
617
|
+
getManifestFileHash(bundle),
|
|
618
|
+
getAssetBaseStorageUri(bundle),
|
|
536
619
|
bundle.rolloutCohortCount ?? DEFAULT_ROLLOUT_COHORT_COUNT,
|
|
537
620
|
bundle.targetCohorts ? JSON.stringify(bundle.targetCohorts) : null
|
|
538
621
|
];
|
|
@@ -541,6 +624,41 @@ const d1Database = createDatabasePlugin({
|
|
|
541
624
|
sql: upsertSql,
|
|
542
625
|
params
|
|
543
626
|
});
|
|
627
|
+
await cf.d1.database.query(config.databaseId, {
|
|
628
|
+
account_id: config.accountId,
|
|
629
|
+
sql: (0, import_lib.default)(`
|
|
630
|
+
DELETE FROM bundle_patches WHERE bundle_id = ?
|
|
631
|
+
`),
|
|
632
|
+
params: [bundle.id]
|
|
633
|
+
});
|
|
634
|
+
const patchRows = bundleToPatchRows(bundle);
|
|
635
|
+
if (patchRows.length > 0) {
|
|
636
|
+
const patchInsertSql = (0, import_lib.default)(`
|
|
637
|
+
INSERT OR REPLACE INTO bundle_patches (
|
|
638
|
+
id,
|
|
639
|
+
bundle_id,
|
|
640
|
+
base_bundle_id,
|
|
641
|
+
base_file_hash,
|
|
642
|
+
patch_file_hash,
|
|
643
|
+
patch_storage_uri,
|
|
644
|
+
order_index
|
|
645
|
+
)
|
|
646
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
647
|
+
`);
|
|
648
|
+
for (const patchRow of patchRows) await cf.d1.database.query(config.databaseId, {
|
|
649
|
+
account_id: config.accountId,
|
|
650
|
+
sql: patchInsertSql,
|
|
651
|
+
params: [
|
|
652
|
+
patchRow.id,
|
|
653
|
+
patchRow.bundle_id,
|
|
654
|
+
patchRow.base_bundle_id,
|
|
655
|
+
patchRow.base_file_hash,
|
|
656
|
+
patchRow.patch_file_hash,
|
|
657
|
+
patchRow.patch_storage_uri,
|
|
658
|
+
String(patchRow.order_index ?? 0)
|
|
659
|
+
]
|
|
660
|
+
});
|
|
661
|
+
}
|
|
544
662
|
}
|
|
545
663
|
}
|
|
546
664
|
};
|
|
@@ -1316,7 +1434,7 @@ const handleCommand = (filePath, rawArguments, rawOptions) => {
|
|
|
1316
1434
|
var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1317
1435
|
module.exports = isexe;
|
|
1318
1436
|
isexe.sync = sync;
|
|
1319
|
-
var fs$
|
|
1437
|
+
var fs$3 = __require("fs");
|
|
1320
1438
|
function checkPathExt(path, options) {
|
|
1321
1439
|
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
1322
1440
|
if (!pathext) return true;
|
|
@@ -1333,12 +1451,12 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1333
1451
|
return checkPathExt(path, options);
|
|
1334
1452
|
}
|
|
1335
1453
|
function isexe(path, options, cb) {
|
|
1336
|
-
fs$
|
|
1454
|
+
fs$3.stat(path, function(er, stat) {
|
|
1337
1455
|
cb(er, er ? false : checkStat(stat, path, options));
|
|
1338
1456
|
});
|
|
1339
1457
|
}
|
|
1340
1458
|
function sync(path, options) {
|
|
1341
|
-
return checkStat(fs$
|
|
1459
|
+
return checkStat(fs$3.statSync(path), path, options);
|
|
1342
1460
|
}
|
|
1343
1461
|
}));
|
|
1344
1462
|
//#endregion
|
|
@@ -1346,14 +1464,14 @@ var require_windows = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1346
1464
|
var require_mode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1347
1465
|
module.exports = isexe;
|
|
1348
1466
|
isexe.sync = sync;
|
|
1349
|
-
var fs$
|
|
1467
|
+
var fs$2 = __require("fs");
|
|
1350
1468
|
function isexe(path, options, cb) {
|
|
1351
|
-
fs$
|
|
1469
|
+
fs$2.stat(path, function(er, stat) {
|
|
1352
1470
|
cb(er, er ? false : checkStat(stat, options));
|
|
1353
1471
|
});
|
|
1354
1472
|
}
|
|
1355
1473
|
function sync(path, options) {
|
|
1356
|
-
return checkStat(fs$
|
|
1474
|
+
return checkStat(fs$2.statSync(path), options);
|
|
1357
1475
|
}
|
|
1358
1476
|
function checkStat(stat, options) {
|
|
1359
1477
|
return stat.isFile() && checkMode(stat, options);
|
|
@@ -1417,7 +1535,7 @@ var require_isexe = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1417
1535
|
//#region ../../node_modules/.pnpm/which@2.0.2/node_modules/which/which.js
|
|
1418
1536
|
var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1419
1537
|
const isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
1420
|
-
const path$
|
|
1538
|
+
const path$3 = __require("path");
|
|
1421
1539
|
const COLON = isWindows ? ";" : ":";
|
|
1422
1540
|
const isexe = require_isexe();
|
|
1423
1541
|
const getNotFoundError = (cmd) => Object.assign(/* @__PURE__ */ new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
@@ -1447,7 +1565,7 @@ var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1447
1565
|
if (i === pathEnv.length) return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
|
|
1448
1566
|
const ppRaw = pathEnv[i];
|
|
1449
1567
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
1450
|
-
const pCmd = path$
|
|
1568
|
+
const pCmd = path$3.join(pathPart, cmd);
|
|
1451
1569
|
resolve(subStep(!pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd, i, 0));
|
|
1452
1570
|
});
|
|
1453
1571
|
const subStep = (p, i, ii) => new Promise((resolve, reject) => {
|
|
@@ -1468,7 +1586,7 @@ var require_which = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1468
1586
|
for (let i = 0; i < pathEnv.length; i++) {
|
|
1469
1587
|
const ppRaw = pathEnv[i];
|
|
1470
1588
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
1471
|
-
const pCmd = path$
|
|
1589
|
+
const pCmd = path$3.join(pathPart, cmd);
|
|
1472
1590
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
1473
1591
|
for (let j = 0; j < pathExt.length; j++) {
|
|
1474
1592
|
const cur = p + pathExt[j];
|
|
@@ -1499,7 +1617,7 @@ var require_path_key = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1499
1617
|
//#endregion
|
|
1500
1618
|
//#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js
|
|
1501
1619
|
var require_resolveCommand = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1502
|
-
const path$
|
|
1620
|
+
const path$2 = __require("path");
|
|
1503
1621
|
const which = require_which();
|
|
1504
1622
|
const getPathKey = require_path_key();
|
|
1505
1623
|
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
@@ -1514,12 +1632,12 @@ var require_resolveCommand = /* @__PURE__ */ __commonJSMin(((exports, module) =>
|
|
|
1514
1632
|
try {
|
|
1515
1633
|
resolved = which.sync(parsed.command, {
|
|
1516
1634
|
path: env[getPathKey({ env })],
|
|
1517
|
-
pathExt: withoutPathExt ? path$
|
|
1635
|
+
pathExt: withoutPathExt ? path$2.delimiter : void 0
|
|
1518
1636
|
});
|
|
1519
1637
|
} catch (e) {} finally {
|
|
1520
1638
|
if (shouldSwitchCwd) process.chdir(cwd);
|
|
1521
1639
|
}
|
|
1522
|
-
if (resolved) resolved = path$
|
|
1640
|
+
if (resolved) resolved = path$2.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
1523
1641
|
return resolved;
|
|
1524
1642
|
}
|
|
1525
1643
|
function resolveCommand(parsed) {
|
|
@@ -1568,16 +1686,16 @@ var require_shebang_command = /* @__PURE__ */ __commonJSMin(((exports, module) =
|
|
|
1568
1686
|
//#endregion
|
|
1569
1687
|
//#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js
|
|
1570
1688
|
var require_readShebang = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1571
|
-
const fs = __require("fs");
|
|
1689
|
+
const fs$1 = __require("fs");
|
|
1572
1690
|
const shebangCommand = require_shebang_command();
|
|
1573
1691
|
function readShebang(command) {
|
|
1574
1692
|
const size = 150;
|
|
1575
1693
|
const buffer = Buffer.alloc(size);
|
|
1576
1694
|
let fd;
|
|
1577
1695
|
try {
|
|
1578
|
-
fd = fs.openSync(command, "r");
|
|
1579
|
-
fs.readSync(fd, buffer, 0, size, 0);
|
|
1580
|
-
fs.closeSync(fd);
|
|
1696
|
+
fd = fs$1.openSync(command, "r");
|
|
1697
|
+
fs$1.readSync(fd, buffer, 0, size, 0);
|
|
1698
|
+
fs$1.closeSync(fd);
|
|
1581
1699
|
} catch (e) {}
|
|
1582
1700
|
return shebangCommand(buffer.toString());
|
|
1583
1701
|
}
|
|
@@ -1586,7 +1704,7 @@ var require_readShebang = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1586
1704
|
//#endregion
|
|
1587
1705
|
//#region ../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js
|
|
1588
1706
|
var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1589
|
-
const path$
|
|
1707
|
+
const path$1 = __require("path");
|
|
1590
1708
|
const resolveCommand = require_resolveCommand();
|
|
1591
1709
|
const escape = require_escape();
|
|
1592
1710
|
const readShebang = require_readShebang();
|
|
@@ -1609,7 +1727,7 @@ var require_parse = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
1609
1727
|
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
1610
1728
|
if (parsed.options.forceShell || needsShell) {
|
|
1611
1729
|
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
1612
|
-
parsed.command = path$
|
|
1730
|
+
parsed.command = path$1.normalize(parsed.command);
|
|
1613
1731
|
parsed.command = escape.command(parsed.command);
|
|
1614
1732
|
parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
|
|
1615
1733
|
parsed.args = [
|
|
@@ -1718,33 +1836,33 @@ function toPath(urlOrPath) {
|
|
|
1718
1836
|
}
|
|
1719
1837
|
function traversePathUp(startPath) {
|
|
1720
1838
|
return { *[Symbol.iterator]() {
|
|
1721
|
-
let currentPath = path
|
|
1839
|
+
let currentPath = path.resolve(toPath(startPath));
|
|
1722
1840
|
let previousPath;
|
|
1723
1841
|
while (previousPath !== currentPath) {
|
|
1724
1842
|
yield currentPath;
|
|
1725
1843
|
previousPath = currentPath;
|
|
1726
|
-
currentPath = path
|
|
1844
|
+
currentPath = path.resolve(currentPath, "..");
|
|
1727
1845
|
}
|
|
1728
1846
|
} };
|
|
1729
1847
|
}
|
|
1730
1848
|
//#endregion
|
|
1731
1849
|
//#region ../../node_modules/.pnpm/npm-run-path@6.0.0/node_modules/npm-run-path/index.js
|
|
1732
1850
|
const npmRunPath = ({ cwd = process$1.cwd(), path: pathOption = process$1.env[pathKey()], preferLocal = true, execPath = process$1.execPath, addExecPath = true } = {}) => {
|
|
1733
|
-
const cwdPath = path
|
|
1851
|
+
const cwdPath = path.resolve(toPath(cwd));
|
|
1734
1852
|
const result = [];
|
|
1735
|
-
const pathParts = pathOption.split(path
|
|
1853
|
+
const pathParts = pathOption.split(path.delimiter);
|
|
1736
1854
|
if (preferLocal) applyPreferLocal(result, pathParts, cwdPath);
|
|
1737
1855
|
if (addExecPath) applyExecPath(result, pathParts, execPath, cwdPath);
|
|
1738
|
-
return pathOption === "" || pathOption === path
|
|
1856
|
+
return pathOption === "" || pathOption === path.delimiter ? `${result.join(path.delimiter)}${pathOption}` : [...result, pathOption].join(path.delimiter);
|
|
1739
1857
|
};
|
|
1740
1858
|
const applyPreferLocal = (result, pathParts, cwdPath) => {
|
|
1741
1859
|
for (const directory of traversePathUp(cwdPath)) {
|
|
1742
|
-
const pathPart = path
|
|
1860
|
+
const pathPart = path.join(directory, "node_modules/.bin");
|
|
1743
1861
|
if (!pathParts.includes(pathPart)) result.push(pathPart);
|
|
1744
1862
|
}
|
|
1745
1863
|
};
|
|
1746
1864
|
const applyExecPath = (result, pathParts, execPath, cwdPath) => {
|
|
1747
|
-
const pathPart = path
|
|
1865
|
+
const pathPart = path.resolve(cwdPath, toPath(execPath), "..");
|
|
1748
1866
|
if (!pathParts.includes(pathPart)) result.push(pathPart);
|
|
1749
1867
|
};
|
|
1750
1868
|
const npmRunPathEnv = ({ env = process$1.env, ...options } = {}) => {
|
|
@@ -2754,7 +2872,7 @@ const mapNode = ({ options }) => {
|
|
|
2754
2872
|
const handleNodeOption = (file, commandArguments, { node: shouldHandleNode = false, nodePath = execPath, nodeOptions = execArgv.filter((nodeOption) => !nodeOption.startsWith("--inspect")), cwd, execPath: formerNodePath, ...options }) => {
|
|
2755
2873
|
if (formerNodePath !== void 0) throw new TypeError("The \"execPath\" option has been removed. Please use the \"nodePath\" option instead.");
|
|
2756
2874
|
const normalizedNodePath = safeNormalizeFileUrl(nodePath, "The \"nodePath\" option");
|
|
2757
|
-
const resolvedNodePath = path
|
|
2875
|
+
const resolvedNodePath = path.resolve(cwd, normalizedNodePath);
|
|
2758
2876
|
const newOptions = {
|
|
2759
2877
|
...options,
|
|
2760
2878
|
nodePath: resolvedNodePath,
|
|
@@ -2766,7 +2884,7 @@ const handleNodeOption = (file, commandArguments, { node: shouldHandleNode = fal
|
|
|
2766
2884
|
commandArguments,
|
|
2767
2885
|
newOptions
|
|
2768
2886
|
];
|
|
2769
|
-
if (path
|
|
2887
|
+
if (path.basename(file, ".exe") === "node") throw new TypeError("When the \"node\" option is true, the first argument does not need to be \"node\".");
|
|
2770
2888
|
return [
|
|
2771
2889
|
resolvedNodePath,
|
|
2772
2890
|
[
|
|
@@ -2850,7 +2968,7 @@ const serializeEncoding = (encoding) => typeof encoding === "string" ? `"${encod
|
|
|
2850
2968
|
//#region ../../node_modules/.pnpm/execa@9.5.2/node_modules/execa/lib/arguments/cwd.js
|
|
2851
2969
|
const normalizeCwd = (cwd = getDefaultCwd()) => {
|
|
2852
2970
|
const cwdString = safeNormalizeFileUrl(cwd, "The \"cwd\" option");
|
|
2853
|
-
return path
|
|
2971
|
+
return path.resolve(cwdString);
|
|
2854
2972
|
};
|
|
2855
2973
|
const getDefaultCwd = () => {
|
|
2856
2974
|
try {
|
|
@@ -2888,7 +3006,7 @@ const normalizeOptions = (filePath, rawArguments, rawOptions) => {
|
|
|
2888
3006
|
options.killSignal = normalizeKillSignal(options.killSignal);
|
|
2889
3007
|
options.forceKillAfterDelay = normalizeForceKillAfterDelay(options.forceKillAfterDelay);
|
|
2890
3008
|
options.lines = options.lines.map((lines, fdNumber) => lines && !BINARY_ENCODINGS.has(options.encoding) && options.buffer[fdNumber]);
|
|
2891
|
-
if (process$1.platform === "win32" && path
|
|
3009
|
+
if (process$1.platform === "win32" && path.basename(file, ".exe") === "cmd") commandArguments.unshift("/q");
|
|
2892
3010
|
return {
|
|
2893
3011
|
file,
|
|
2894
3012
|
commandArguments,
|
|
@@ -6723,28 +6841,8 @@ const createWrangler = ({ stdio, accountId, cloudflareApiToken, cwd }) => {
|
|
|
6723
6841
|
//#region src/r2Storage.ts
|
|
6724
6842
|
/**
|
|
6725
6843
|
* Cloudflare R2 storage plugin for Hot Updater.
|
|
6726
|
-
*
|
|
6727
|
-
* Note: This plugin does not support `getDownloadUrl()`.
|
|
6728
|
-
* If you need download URL generation, use `s3Storage` from `@hot-updater/aws` instead,
|
|
6729
|
-
* which is fully compatible with Cloudflare R2.
|
|
6730
|
-
*
|
|
6731
|
-
* @example
|
|
6732
|
-
* ```typescript
|
|
6733
|
-
* // Using s3Storage with Cloudflare R2 for download URL support
|
|
6734
|
-
* import { s3Storage } from "@hot-updater/aws";
|
|
6735
|
-
*
|
|
6736
|
-
* s3Storage({
|
|
6737
|
-
* region: "auto",
|
|
6738
|
-
* endpoint: "https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com",
|
|
6739
|
-
* credentials: {
|
|
6740
|
-
* accessKeyId: "YOUR_ACCESS_KEY_ID",
|
|
6741
|
-
* secretAccessKey: "YOUR_SECRET_ACCESS_KEY",
|
|
6742
|
-
* },
|
|
6743
|
-
* bucketName: "YOUR_BUCKET_NAME",
|
|
6744
|
-
* })
|
|
6745
|
-
* ```
|
|
6746
6844
|
*/
|
|
6747
|
-
const r2Storage =
|
|
6845
|
+
const r2Storage = createNodeStoragePlugin({
|
|
6748
6846
|
name: "r2Storage",
|
|
6749
6847
|
supportedProtocol: "r2",
|
|
6750
6848
|
factory: (config) => {
|
|
@@ -6777,8 +6875,17 @@ const r2Storage = createStoragePlugin({
|
|
|
6777
6875
|
}
|
|
6778
6876
|
return { storageUri: `r2://${bucketName}/${Key}` };
|
|
6779
6877
|
},
|
|
6780
|
-
async
|
|
6781
|
-
|
|
6878
|
+
async downloadFile(storageUri, filePath) {
|
|
6879
|
+
const { bucket, key } = parseStorageUri(storageUri, "r2");
|
|
6880
|
+
if (bucket !== bucketName) throw new Error(`Bucket name mismatch: expected "${bucketName}", but found "${bucket}".`);
|
|
6881
|
+
try {
|
|
6882
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
6883
|
+
const { stderr, exitCode } = await wrangler("r2", "object", "get", [bucketName, key].join("/"), "--file", filePath, "--remote");
|
|
6884
|
+
if (exitCode !== 0 && stderr) throw new Error(stderr);
|
|
6885
|
+
} catch (error) {
|
|
6886
|
+
if (error instanceof ExecaError) throw new Error(error.stderr || error.stdout);
|
|
6887
|
+
throw error;
|
|
6888
|
+
}
|
|
6782
6889
|
}
|
|
6783
6890
|
};
|
|
6784
6891
|
}
|