@upstash/qstash 2.10.1 → 2.11.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/{chunk-Z37KJCW7.mjs → chunk-7DSF3QVE.mjs} +1 -1
- package/{chunk-PIBVA43B.mjs → chunk-JQP6NQUW.mjs} +1 -1
- package/{chunk-35B33QW3.mjs → chunk-LB3C5PJP.mjs} +486 -11
- package/{client-CsM1dTnz.d.ts → client-CUioGZfg.d.mts} +19 -0
- package/{client-CsM1dTnz.d.mts → client-CUioGZfg.d.ts} +19 -0
- package/cloudflare.d.mts +1 -1
- package/cloudflare.d.ts +1 -1
- package/cloudflare.js +484 -11
- package/cloudflare.mjs +1 -1
- package/h3.d.mts +1 -1
- package/h3.d.ts +1 -1
- package/h3.js +484 -11
- package/h3.mjs +3 -3
- package/hono.d.mts +1 -1
- package/hono.d.ts +1 -1
- package/hono.js +484 -11
- package/hono.mjs +1 -1
- package/index.d.mts +2 -2
- package/index.d.ts +2 -2
- package/index.js +484 -11
- package/index.mjs +2 -2
- package/nextjs.d.mts +33 -2
- package/nextjs.d.ts +33 -2
- package/nextjs.js +505 -17
- package/nextjs.mjs +24 -8
- package/nuxt.js +70 -3
- package/nuxt.mjs +3 -3
- package/package.json +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +484 -11
- package/solidjs.mjs +2 -2
- package/svelte.d.mts +1 -1
- package/svelte.d.ts +1 -1
- package/svelte.js +484 -11
- package/svelte.mjs +2 -2
- package/workflow.d.mts +1 -1
- package/workflow.d.ts +1 -1
- package/workflow.js +484 -11
- package/workflow.mjs +1 -1
|
@@ -437,17 +437,23 @@ function normalizeCursor(response) {
|
|
|
437
437
|
const cursor = response.cursor;
|
|
438
438
|
return { ...response, cursor: cursor || void 0 };
|
|
439
439
|
}
|
|
440
|
+
function _processGlobal() {
|
|
441
|
+
const proc = globalThis["process"];
|
|
442
|
+
return proc;
|
|
443
|
+
}
|
|
440
444
|
function getRuntime() {
|
|
441
|
-
|
|
442
|
-
|
|
445
|
+
const proc = _processGlobal();
|
|
446
|
+
if (proc?.versions?.bun)
|
|
447
|
+
return `bun@${proc.versions.bun}`;
|
|
443
448
|
if (typeof EdgeRuntime === "string")
|
|
444
449
|
return "edge-light";
|
|
445
|
-
|
|
446
|
-
return `node@${
|
|
450
|
+
if (typeof proc?.version === "string")
|
|
451
|
+
return `node@${proc.version}`;
|
|
447
452
|
return "";
|
|
448
453
|
}
|
|
449
454
|
function getSafeEnvironment() {
|
|
450
|
-
|
|
455
|
+
const proc = _processGlobal();
|
|
456
|
+
return proc?.env ?? {};
|
|
451
457
|
}
|
|
452
458
|
|
|
453
459
|
// src/client/multi-region/utils.ts
|
|
@@ -491,12 +497,451 @@ function normalizeRegionHeader(region) {
|
|
|
491
497
|
return void 0;
|
|
492
498
|
}
|
|
493
499
|
|
|
500
|
+
// src/dev-server/constants.ts
|
|
501
|
+
var DEFAULT_DEV_PORT = 8080;
|
|
502
|
+
var DEV_CREDENTIALS = {
|
|
503
|
+
token: "eyJVc2VySUQiOiJkZWZhdWx0VXNlciIsIlBhc3N3b3JkIjoiZGVmYXVsdFBhc3N3b3JkIn0=",
|
|
504
|
+
currentSigningKey: "sig_7kYjw48mhY7kAjqNGcy6cr29RJ6r",
|
|
505
|
+
nextSigningKey: "sig_5ZB6DVzB1wjE8S6rZ7eenA8Pdnhs"
|
|
506
|
+
};
|
|
507
|
+
var GITHUB_RELEASES_URL = "https://api.github.com/repos/upstash/qstash-cli/releases/latest";
|
|
508
|
+
var BINARY_URL_BASE = "https://artifacts.upstash.com/qstash/versions";
|
|
509
|
+
var CONSOLE_URL = "https://console.upstash.com/qstash/local-mode-user";
|
|
510
|
+
var DEV_PREFIX = "\x1B[2m[QStash Dev]\x1B[0m";
|
|
511
|
+
var CLI_PREFIX = "\x1B[2m[QStash CLI]\x1B[0m";
|
|
512
|
+
var _n = (m) => `node:${m}`;
|
|
513
|
+
var importHttp = () => import(
|
|
514
|
+
/* webpackIgnore: true */
|
|
515
|
+
_n("http")
|
|
516
|
+
);
|
|
517
|
+
var importHttps = () => import(
|
|
518
|
+
/* webpackIgnore: true */
|
|
519
|
+
_n("https")
|
|
520
|
+
);
|
|
521
|
+
var importFs = () => import(
|
|
522
|
+
/* webpackIgnore: true */
|
|
523
|
+
_n("fs")
|
|
524
|
+
);
|
|
525
|
+
var importChildProcess = () => import(
|
|
526
|
+
/* webpackIgnore: true */
|
|
527
|
+
_n("child_process")
|
|
528
|
+
);
|
|
529
|
+
var importOs = () => import(
|
|
530
|
+
/* webpackIgnore: true */
|
|
531
|
+
_n("os")
|
|
532
|
+
);
|
|
533
|
+
|
|
534
|
+
// src/dev-server/http.ts
|
|
535
|
+
var HTTP_OK = 200;
|
|
536
|
+
var HTTP_MULTI_CHOICE = 300;
|
|
537
|
+
var nativeGet = async (url, headers, timeoutMs) => {
|
|
538
|
+
const parsedUrl = new URL(url);
|
|
539
|
+
const httpModule = parsedUrl.protocol === "https:" ? await importHttps() : await importHttp();
|
|
540
|
+
return new Promise((resolve, reject) => {
|
|
541
|
+
const request = httpModule.get(url, { headers }, (response) => {
|
|
542
|
+
const chunks = [];
|
|
543
|
+
response.on("data", (chunk) => chunks.push(chunk));
|
|
544
|
+
response.on("end", () => {
|
|
545
|
+
const statusCode = response.statusCode ?? 0;
|
|
546
|
+
resolve({
|
|
547
|
+
ok: statusCode >= HTTP_OK && statusCode < HTTP_MULTI_CHOICE,
|
|
548
|
+
statusCode,
|
|
549
|
+
body: Buffer.concat(chunks)
|
|
550
|
+
});
|
|
551
|
+
});
|
|
552
|
+
response.on("error", reject);
|
|
553
|
+
});
|
|
554
|
+
if (timeoutMs) {
|
|
555
|
+
request.setTimeout(timeoutMs, () => {
|
|
556
|
+
request.destroy(new Error("Request timed out"));
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
request.on("error", reject);
|
|
560
|
+
});
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
// src/dev-server/health.ts
|
|
564
|
+
var HEALTH_CHECK_TIMEOUT_MS = 2e3;
|
|
565
|
+
var isDevServerRunning = async (baseUrl) => {
|
|
566
|
+
try {
|
|
567
|
+
const { ok: ok4, body } = await nativeGet(
|
|
568
|
+
`${baseUrl}/v2/keys`,
|
|
569
|
+
{ Authorization: `Bearer ${DEV_CREDENTIALS.token}` },
|
|
570
|
+
HEALTH_CHECK_TIMEOUT_MS
|
|
571
|
+
);
|
|
572
|
+
if (!ok4)
|
|
573
|
+
return false;
|
|
574
|
+
const data = JSON.parse(body.toString());
|
|
575
|
+
return data.current === DEV_CREDENTIALS.currentSigningKey && data.next === DEV_CREDENTIALS.nextSigningKey;
|
|
576
|
+
} catch {
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
var _didLogUnreachable = false;
|
|
581
|
+
var checkDevServerReachable = async (baseUrl, runtime) => {
|
|
582
|
+
if (await pingEdge(baseUrl))
|
|
583
|
+
return;
|
|
584
|
+
if (!_didLogUnreachable) {
|
|
585
|
+
console.error(unreachableMessage(baseUrl, runtime));
|
|
586
|
+
_didLogUnreachable = true;
|
|
587
|
+
}
|
|
588
|
+
throw new Error(`${DEV_PREFIX} dev server unreachable at ${baseUrl}`);
|
|
589
|
+
};
|
|
590
|
+
var pingEdge = async (baseUrl) => {
|
|
591
|
+
try {
|
|
592
|
+
const controller = new AbortController();
|
|
593
|
+
const timeout = setTimeout(() => controller.abort(), HEALTH_CHECK_TIMEOUT_MS);
|
|
594
|
+
const response = await fetch(`${baseUrl}/v2/keys`, {
|
|
595
|
+
headers: { Authorization: `Bearer ${DEV_CREDENTIALS.token}` },
|
|
596
|
+
signal: controller.signal
|
|
597
|
+
});
|
|
598
|
+
clearTimeout(timeout);
|
|
599
|
+
return response.ok;
|
|
600
|
+
} catch {
|
|
601
|
+
return false;
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
var unreachableMessage = (baseUrl, runtime) => {
|
|
605
|
+
const port = new URL(baseUrl).port;
|
|
606
|
+
const manualStartCmd = `npx @upstash/qstash-cli dev --port ${port}`;
|
|
607
|
+
const header = `
|
|
608
|
+
${DEV_PREFIX} The dev server is not running at ${baseUrl}.
|
|
609
|
+
|
|
610
|
+
`;
|
|
611
|
+
if (runtime === "cloudflare-workers") {
|
|
612
|
+
return header + `Cloudflare Workers cannot start the dev server automatically.
|
|
613
|
+
Start it manually before running wrangler dev:
|
|
614
|
+
|
|
615
|
+
${manualStartCmd}
|
|
616
|
+
`;
|
|
617
|
+
}
|
|
618
|
+
return header + `Edge runtimes cannot start the dev server automatically.
|
|
619
|
+
Either:
|
|
620
|
+
1. Add the instrumentation hook to start it with your app:
|
|
621
|
+
|
|
622
|
+
// instrumentation.ts
|
|
623
|
+
import { registerQStashDev } from "@upstash/qstash/nextjs";
|
|
624
|
+
export async function register() { await registerQStashDev(); }
|
|
625
|
+
|
|
626
|
+
2. Or start it manually:
|
|
627
|
+
|
|
628
|
+
${manualStartCmd}
|
|
629
|
+
`;
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
// src/dev-server/binary.ts
|
|
633
|
+
var ensureBinary = async () => {
|
|
634
|
+
const fs = await importFs();
|
|
635
|
+
const os = await importOs();
|
|
636
|
+
const cacheDirectory = await findCacheDirectory();
|
|
637
|
+
const isWindows = os.platform() === "win32";
|
|
638
|
+
const binaryName = isWindows ? "qstash.exe" : "qstash";
|
|
639
|
+
const binaryPath = `${cacheDirectory}/${binaryName}`;
|
|
640
|
+
const versionFile = `${cacheDirectory}/.version`;
|
|
641
|
+
let version;
|
|
642
|
+
try {
|
|
643
|
+
version = await fetchLatestVersion();
|
|
644
|
+
} catch (error) {
|
|
645
|
+
if (fs.existsSync(binaryPath)) {
|
|
646
|
+
const cachedVersion = fs.existsSync(versionFile) ? fs.readFileSync(versionFile, "utf8").trim() : "unknown";
|
|
647
|
+
console.log(`${DEV_PREFIX} Offline, using local v${cachedVersion}`);
|
|
648
|
+
return binaryPath;
|
|
649
|
+
}
|
|
650
|
+
throw error;
|
|
651
|
+
}
|
|
652
|
+
return downloadBinary(version, cacheDirectory);
|
|
653
|
+
};
|
|
654
|
+
var fetchLatestVersion = async () => {
|
|
655
|
+
const { ok: ok4, statusCode, body } = await nativeGet(GITHUB_RELEASES_URL, {
|
|
656
|
+
Accept: "application/vnd.github.v3+json",
|
|
657
|
+
"User-Agent": "upstash-qstash-js"
|
|
658
|
+
});
|
|
659
|
+
if (!ok4) {
|
|
660
|
+
throw new Error(`[QStash Dev] Failed to fetch latest version: HTTP ${statusCode}`);
|
|
661
|
+
}
|
|
662
|
+
const data = JSON.parse(body.toString());
|
|
663
|
+
return data.tag_name.replace(/^v/, "");
|
|
664
|
+
};
|
|
665
|
+
var findCacheDirectory = async () => {
|
|
666
|
+
const fs = await importFs();
|
|
667
|
+
const os = await importOs();
|
|
668
|
+
const home = os.homedir();
|
|
669
|
+
const platform = os.platform();
|
|
670
|
+
let base;
|
|
671
|
+
if (platform === "darwin") {
|
|
672
|
+
base = `${home}/Library/Caches/upstash`;
|
|
673
|
+
} else if (platform === "win32") {
|
|
674
|
+
base = `${process.env.LOCALAPPDATA ?? `${home}/AppData/Local`}/upstash`;
|
|
675
|
+
} else {
|
|
676
|
+
base = `${home}/.cache/upstash`;
|
|
677
|
+
}
|
|
678
|
+
const cacheDirectory = `${base}/qstash-dev`;
|
|
679
|
+
await fs.promises.mkdir(cacheDirectory, { recursive: true });
|
|
680
|
+
return cacheDirectory;
|
|
681
|
+
};
|
|
682
|
+
var downloadBinary = async (version, cacheDirectory) => {
|
|
683
|
+
const fs = await importFs();
|
|
684
|
+
const childProcess = await importChildProcess();
|
|
685
|
+
const os = await importOs();
|
|
686
|
+
const osPlatform = os.platform();
|
|
687
|
+
const isWindows = osPlatform === "win32";
|
|
688
|
+
const platform = isWindows ? "windows" : osPlatform === "darwin" ? "darwin" : "linux";
|
|
689
|
+
const arch = os.arch() === "arm64" ? "arm64" : "amd64";
|
|
690
|
+
const archiveName = `qstash-server_${version}_${platform}_${arch}`;
|
|
691
|
+
const binaryName = isWindows ? "qstash.exe" : "qstash";
|
|
692
|
+
const binaryPath = `${cacheDirectory}/${binaryName}`;
|
|
693
|
+
const versionFile = `${cacheDirectory}/.version`;
|
|
694
|
+
if (fs.existsSync(binaryPath) && fs.existsSync(versionFile)) {
|
|
695
|
+
const cachedVersion = fs.readFileSync(versionFile, "utf8").trim();
|
|
696
|
+
if (cachedVersion === version) {
|
|
697
|
+
return binaryPath;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
await fs.promises.rm(cacheDirectory, { recursive: true, force: true });
|
|
701
|
+
await fs.promises.mkdir(cacheDirectory, { recursive: true });
|
|
702
|
+
const extension = isWindows ? "zip" : "tar.gz";
|
|
703
|
+
const archiveUrl = `${BINARY_URL_BASE}/${version}/${archiveName}.${extension}`;
|
|
704
|
+
console.log(`${DEV_PREFIX} Downloading dev server v${version}...`);
|
|
705
|
+
const { ok: ok4, statusCode, body } = await nativeGet(archiveUrl);
|
|
706
|
+
if (!ok4) {
|
|
707
|
+
throw new Error(`[QStash Dev] Failed to download binary: HTTP ${statusCode}`);
|
|
708
|
+
}
|
|
709
|
+
const archivePath = `${cacheDirectory}/${archiveName}.${extension}`;
|
|
710
|
+
await fs.promises.writeFile(archivePath, new Uint8Array(body));
|
|
711
|
+
childProcess.execFileSync("tar", ["-xf", archivePath, "-C", cacheDirectory], {
|
|
712
|
+
stdio: "pipe"
|
|
713
|
+
});
|
|
714
|
+
if (!isWindows) {
|
|
715
|
+
const EXECUTABLE_PERMISSION = 493;
|
|
716
|
+
await fs.promises.chmod(binaryPath, EXECUTABLE_PERMISSION);
|
|
717
|
+
}
|
|
718
|
+
await fs.promises.writeFile(versionFile, version);
|
|
719
|
+
await fs.promises.unlink(archivePath).catch(() => {
|
|
720
|
+
});
|
|
721
|
+
return binaryPath;
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
// src/dev-server/process.ts
|
|
725
|
+
var STARTUP_TIMEOUT_MS = 3e4;
|
|
726
|
+
var _proc = () => {
|
|
727
|
+
return globalThis["process"] ?? {};
|
|
728
|
+
};
|
|
729
|
+
var spawnServer = async (binaryPath, port, onUnexpectedExit) => {
|
|
730
|
+
const childProcess = await importChildProcess();
|
|
731
|
+
const child = await new Promise((resolve, reject) => {
|
|
732
|
+
const child2 = childProcess.spawn(binaryPath, ["dev", "--port", String(port)], {
|
|
733
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
734
|
+
});
|
|
735
|
+
const timeout = setTimeout(() => {
|
|
736
|
+
child2.kill();
|
|
737
|
+
reject(new Error("[QStash Dev] Server failed to start within 30 seconds"));
|
|
738
|
+
}, STARTUP_TIMEOUT_MS);
|
|
739
|
+
let startupOutput = "";
|
|
740
|
+
let started = false;
|
|
741
|
+
const bufferLine = (line) => {
|
|
742
|
+
if (!started)
|
|
743
|
+
startupOutput += `${line}
|
|
744
|
+
`;
|
|
745
|
+
};
|
|
746
|
+
forwardWithPrefix(child2.stdout, _proc().stdout, (line) => {
|
|
747
|
+
bufferLine(line);
|
|
748
|
+
if (!started && /runn+ing( at|\.)/i.test(line)) {
|
|
749
|
+
clearTimeout(timeout);
|
|
750
|
+
started = true;
|
|
751
|
+
resolve(child2);
|
|
752
|
+
}
|
|
753
|
+
});
|
|
754
|
+
forwardWithPrefix(child2.stderr, _proc().stderr, bufferLine);
|
|
755
|
+
child2.on("error", (error) => {
|
|
756
|
+
clearTimeout(timeout);
|
|
757
|
+
reject(new Error(`[QStash Dev] Failed to start server: ${error.message}`));
|
|
758
|
+
});
|
|
759
|
+
child2.on("close", (code, _signal) => {
|
|
760
|
+
if (started) {
|
|
761
|
+
onUnexpectedExit?.();
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
clearTimeout(timeout);
|
|
765
|
+
reject(new Error(formatStartupError(code, startupOutput)));
|
|
766
|
+
});
|
|
767
|
+
});
|
|
768
|
+
registerCleanup(child);
|
|
769
|
+
child.unref?.();
|
|
770
|
+
child.stdout?.unref?.();
|
|
771
|
+
child.stderr?.unref?.();
|
|
772
|
+
};
|
|
773
|
+
var formatStartupError = (code, startupOutput) => {
|
|
774
|
+
const cleaned = startupOutput.replaceAll(/\u001B\[[\d;]*m/g, "").replaceAll(/^\d{1,2}:\d{2}(AM|PM)\s+\w{3}\s+/gm, "").trim();
|
|
775
|
+
if (/address already in use/i.test(cleaned)) {
|
|
776
|
+
const match = /:(\d+)\s*$/.exec(cleaned);
|
|
777
|
+
const portHint = match ? ` on port ${match[1]}` : "";
|
|
778
|
+
return `[QStash Dev] Port already in use${portHint}. Set QSTASH_DEV_PORT to use a different port, or stop the process holding it.`;
|
|
779
|
+
}
|
|
780
|
+
const codeSuffix = code ? ` with code ${code}` : "";
|
|
781
|
+
const detail = cleaned ? `: ${cleaned}` : "";
|
|
782
|
+
return `[QStash Dev] Server exited unexpectedly${codeSuffix}${detail}`;
|
|
783
|
+
};
|
|
784
|
+
var forwardWithPrefix = (source, destination, onLine) => {
|
|
785
|
+
if (!source)
|
|
786
|
+
return;
|
|
787
|
+
let buffer = "";
|
|
788
|
+
const flushLine = (line) => {
|
|
789
|
+
destination?.write(`${CLI_PREFIX} ${line}
|
|
790
|
+
`);
|
|
791
|
+
onLine(line);
|
|
792
|
+
};
|
|
793
|
+
source.on("data", (data) => {
|
|
794
|
+
buffer += data.toString();
|
|
795
|
+
let newlineIndex = buffer.indexOf("\n");
|
|
796
|
+
while (newlineIndex !== -1) {
|
|
797
|
+
flushLine(buffer.slice(0, newlineIndex));
|
|
798
|
+
buffer = buffer.slice(newlineIndex + 1);
|
|
799
|
+
newlineIndex = buffer.indexOf("\n");
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
source.on("end", () => {
|
|
803
|
+
if (buffer.length > 0) {
|
|
804
|
+
flushLine(buffer);
|
|
805
|
+
buffer = "";
|
|
806
|
+
}
|
|
807
|
+
});
|
|
808
|
+
source.on("error", () => {
|
|
809
|
+
});
|
|
810
|
+
};
|
|
811
|
+
var currentChild;
|
|
812
|
+
var processHandlersRegistered = false;
|
|
813
|
+
var killCurrentChild = () => {
|
|
814
|
+
if (!currentChild)
|
|
815
|
+
return;
|
|
816
|
+
try {
|
|
817
|
+
currentChild.kill("SIGTERM");
|
|
818
|
+
} catch {
|
|
819
|
+
}
|
|
820
|
+
currentChild = void 0;
|
|
821
|
+
};
|
|
822
|
+
var registerCleanup = (child) => {
|
|
823
|
+
currentChild = child;
|
|
824
|
+
if (!processHandlersRegistered) {
|
|
825
|
+
processHandlersRegistered = true;
|
|
826
|
+
const proc = _proc();
|
|
827
|
+
proc.on?.("exit", killCurrentChild);
|
|
828
|
+
proc.on?.("SIGINT", () => {
|
|
829
|
+
killCurrentChild();
|
|
830
|
+
proc.exit?.(0);
|
|
831
|
+
});
|
|
832
|
+
proc.on?.("SIGTERM", () => {
|
|
833
|
+
killCurrentChild();
|
|
834
|
+
proc.exit?.(0);
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
};
|
|
838
|
+
|
|
839
|
+
// src/dev-server/index.ts
|
|
840
|
+
var _processGlobal2 = () => {
|
|
841
|
+
const proc = globalThis["process"];
|
|
842
|
+
return proc;
|
|
843
|
+
};
|
|
844
|
+
var devServerPromise;
|
|
845
|
+
var ensureDevelopmentServer = (env, devMode) => {
|
|
846
|
+
if (!shouldUseDevelopmentMode(devMode, env))
|
|
847
|
+
return Promise.resolve();
|
|
848
|
+
const procEnv = _processGlobal2()?.env;
|
|
849
|
+
if (procEnv?.NEXT_PHASE === "phase-production-build")
|
|
850
|
+
return Promise.resolve();
|
|
851
|
+
if (procEnv?.NODE_ENV === "production")
|
|
852
|
+
return Promise.resolve();
|
|
853
|
+
const runtime = getRuntime2();
|
|
854
|
+
if (runtime !== "nodejs") {
|
|
855
|
+
return checkDevServerReachable(getDevUrl(env), runtime);
|
|
856
|
+
}
|
|
857
|
+
if (!devServerPromise) {
|
|
858
|
+
devServerPromise = startPipeline(env).catch((error) => {
|
|
859
|
+
devServerPromise = void 0;
|
|
860
|
+
throw error;
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
return devServerPromise;
|
|
864
|
+
};
|
|
865
|
+
var startPipeline = async (env) => {
|
|
866
|
+
const baseUrl = getDevUrl(env);
|
|
867
|
+
const port = new URL(baseUrl).port;
|
|
868
|
+
const consoleLink = `\x1B[36m${CONSOLE_URL}?port=${port}\x1B[0m`;
|
|
869
|
+
if (await isDevServerRunning(baseUrl)) {
|
|
870
|
+
console.log(
|
|
871
|
+
`${DEV_PREFIX} Server already running at ${baseUrl}
|
|
872
|
+
${DEV_PREFIX} Console: ${consoleLink}`
|
|
873
|
+
);
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
const binaryPath = await ensureBinary();
|
|
877
|
+
await spawnServer(binaryPath, port, () => {
|
|
878
|
+
devServerPromise = void 0;
|
|
879
|
+
});
|
|
880
|
+
};
|
|
881
|
+
var shouldUseDevelopmentMode = (devMode, env) => {
|
|
882
|
+
if (devMode !== void 0)
|
|
883
|
+
return devMode;
|
|
884
|
+
const value = env?.QSTASH_DEV ?? getProcessEnvironment("QSTASH_DEV");
|
|
885
|
+
if (value === void 0 || value === "" || value === "false" || value === "0")
|
|
886
|
+
return false;
|
|
887
|
+
if (value === "true" || value === "1")
|
|
888
|
+
return true;
|
|
889
|
+
throw new Error(`[QStash Dev] Invalid value for QSTASH_DEV in environment: ${value}`);
|
|
890
|
+
};
|
|
891
|
+
var getDevelopmentCredentials = (env) => {
|
|
892
|
+
return {
|
|
893
|
+
...DEV_CREDENTIALS,
|
|
894
|
+
baseUrl: getDevUrl(env)
|
|
895
|
+
};
|
|
896
|
+
};
|
|
897
|
+
var getDevUrl = (env) => {
|
|
898
|
+
const portString = env?.QSTASH_DEV_PORT ?? getProcessEnvironment("QSTASH_DEV_PORT");
|
|
899
|
+
let port = DEFAULT_DEV_PORT;
|
|
900
|
+
if (portString) {
|
|
901
|
+
const parsed = Number.parseInt(portString, 10);
|
|
902
|
+
if (!Number.isNaN(parsed) && parsed > 0) {
|
|
903
|
+
port = parsed;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
return `http://127.0.0.1:${port}`;
|
|
907
|
+
};
|
|
908
|
+
var getRuntime2 = () => {
|
|
909
|
+
if (typeof navigator !== "undefined" && navigator.userAgent === "Cloudflare-Workers") {
|
|
910
|
+
return "cloudflare-workers";
|
|
911
|
+
}
|
|
912
|
+
const proc = _processGlobal2();
|
|
913
|
+
if (!proc) {
|
|
914
|
+
return "browser";
|
|
915
|
+
}
|
|
916
|
+
if (!proc.release?.name) {
|
|
917
|
+
return "edge";
|
|
918
|
+
}
|
|
919
|
+
return "nodejs";
|
|
920
|
+
};
|
|
921
|
+
var getProcessEnvironment = (key) => {
|
|
922
|
+
const proc = _processGlobal2();
|
|
923
|
+
return proc?.env ? proc.env[key] : void 0;
|
|
924
|
+
};
|
|
925
|
+
|
|
494
926
|
// src/client/multi-region/incoming.ts
|
|
495
927
|
var getReceiverSigningKeys = ({
|
|
496
928
|
environment,
|
|
497
929
|
regionFromHeader,
|
|
498
|
-
config
|
|
930
|
+
config,
|
|
931
|
+
devMode
|
|
499
932
|
}) => {
|
|
933
|
+
if (shouldUseDevelopmentMode(devMode, environment)) {
|
|
934
|
+
if (config?.currentSigningKey || config?.nextSigningKey) {
|
|
935
|
+
console.warn(
|
|
936
|
+
`${DEV_PREFIX} Dev mode is active. Ignoring signing keys from config. Set devMode: false to use your own keys.`
|
|
937
|
+
);
|
|
938
|
+
}
|
|
939
|
+
const developmentCreds = getDevelopmentCredentials(environment);
|
|
940
|
+
return {
|
|
941
|
+
currentSigningKey: developmentCreds.currentSigningKey,
|
|
942
|
+
nextSigningKey: developmentCreds.nextSigningKey
|
|
943
|
+
};
|
|
944
|
+
}
|
|
500
945
|
if (config?.currentSigningKey && config.nextSigningKey) {
|
|
501
946
|
return {
|
|
502
947
|
currentSigningKey: config.currentSigningKey,
|
|
@@ -541,8 +986,21 @@ var getClientCredentials = (clientCredentialConfig) => {
|
|
|
541
986
|
};
|
|
542
987
|
var resolveCredentials = ({
|
|
543
988
|
environment,
|
|
544
|
-
config
|
|
989
|
+
config,
|
|
990
|
+
devMode
|
|
545
991
|
}) => {
|
|
992
|
+
if (shouldUseDevelopmentMode(devMode, environment)) {
|
|
993
|
+
if (config?.baseUrl || config?.token) {
|
|
994
|
+
console.warn(
|
|
995
|
+
`${DEV_PREFIX} Dev mode is active. Ignoring baseUrl/token from config. Set devMode: false to use your own credentials.`
|
|
996
|
+
);
|
|
997
|
+
}
|
|
998
|
+
const developmentCreds = getDevelopmentCredentials(environment);
|
|
999
|
+
return {
|
|
1000
|
+
baseUrl: developmentCreds.baseUrl,
|
|
1001
|
+
token: developmentCreds.token
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
546
1004
|
if (config?.baseUrl && config.token) {
|
|
547
1005
|
return {
|
|
548
1006
|
baseUrl: config.baseUrl,
|
|
@@ -595,9 +1053,11 @@ var SignatureError = class extends Error {
|
|
|
595
1053
|
var Receiver = class {
|
|
596
1054
|
currentSigningKey;
|
|
597
1055
|
nextSigningKey;
|
|
1056
|
+
devMode;
|
|
598
1057
|
constructor(config) {
|
|
599
1058
|
this.currentSigningKey = config?.currentSigningKey;
|
|
600
1059
|
this.nextSigningKey = config?.nextSigningKey;
|
|
1060
|
+
this.devMode = config?.devMode;
|
|
601
1061
|
}
|
|
602
1062
|
/**
|
|
603
1063
|
* Verify the signature of a request.
|
|
@@ -616,7 +1076,8 @@ var Receiver = class {
|
|
|
616
1076
|
config: {
|
|
617
1077
|
currentSigningKey: this.currentSigningKey,
|
|
618
1078
|
nextSigningKey: this.nextSigningKey
|
|
619
|
-
}
|
|
1079
|
+
},
|
|
1080
|
+
devMode: this.devMode
|
|
620
1081
|
});
|
|
621
1082
|
if (!signingKeys) {
|
|
622
1083
|
throw new Error(
|
|
@@ -882,12 +1343,14 @@ var HttpClient = class {
|
|
|
882
1343
|
baseUrl;
|
|
883
1344
|
authorization;
|
|
884
1345
|
options;
|
|
1346
|
+
devMode;
|
|
885
1347
|
retry;
|
|
886
1348
|
headers;
|
|
887
1349
|
telemetryHeaders;
|
|
888
1350
|
constructor(config) {
|
|
889
1351
|
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
890
1352
|
this.authorization = config.authorization;
|
|
1353
|
+
this.devMode = config.devMode;
|
|
891
1354
|
this.retry = // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
892
1355
|
typeof config.retry === "boolean" && !config.retry ? {
|
|
893
1356
|
attempts: 1,
|
|
@@ -900,6 +1363,7 @@ var HttpClient = class {
|
|
|
900
1363
|
this.telemetryHeaders = config.telemetryHeaders;
|
|
901
1364
|
}
|
|
902
1365
|
async request(request) {
|
|
1366
|
+
await ensureDevelopmentServer(void 0, this.devMode);
|
|
903
1367
|
const { response } = await this.requestWithBackoff(request);
|
|
904
1368
|
if (request.parseResponseAsJson === false) {
|
|
905
1369
|
return void 0;
|
|
@@ -907,6 +1371,7 @@ var HttpClient = class {
|
|
|
907
1371
|
return await response.json();
|
|
908
1372
|
}
|
|
909
1373
|
async *requestStream(request) {
|
|
1374
|
+
await ensureDevelopmentServer(void 0, this.devMode);
|
|
910
1375
|
const { response } = await this.requestWithBackoff(request);
|
|
911
1376
|
if (!response.body) {
|
|
912
1377
|
throw new Error("No response body");
|
|
@@ -1629,7 +2094,7 @@ var UrlGroups = class {
|
|
|
1629
2094
|
};
|
|
1630
2095
|
|
|
1631
2096
|
// version.ts
|
|
1632
|
-
var VERSION = "2.
|
|
2097
|
+
var VERSION = "2.11.0";
|
|
1633
2098
|
|
|
1634
2099
|
// src/client/client.ts
|
|
1635
2100
|
var Client = class {
|
|
@@ -1637,7 +2102,14 @@ var Client = class {
|
|
|
1637
2102
|
token;
|
|
1638
2103
|
constructor(config) {
|
|
1639
2104
|
const environment = getSafeEnvironment();
|
|
1640
|
-
const { baseUrl, token } = getClientCredentials({
|
|
2105
|
+
const { baseUrl, token } = getClientCredentials({
|
|
2106
|
+
environment,
|
|
2107
|
+
config,
|
|
2108
|
+
devMode: config?.devMode
|
|
2109
|
+
});
|
|
2110
|
+
if (shouldUseDevelopmentMode(config?.devMode, environment)) {
|
|
2111
|
+
void ensureDevelopmentServer(environment, config?.devMode);
|
|
2112
|
+
}
|
|
1641
2113
|
const enableTelemetry = environment.UPSTASH_DISABLE_TELEMETRY ? false : config?.enableTelemetry ?? true;
|
|
1642
2114
|
const isCloudflare = typeof caches !== "undefined" && "default" in caches;
|
|
1643
2115
|
const telemetryHeaders = new Headers(
|
|
@@ -1654,7 +2126,8 @@ var Client = class {
|
|
|
1654
2126
|
//@ts-expect-error caused by undici and bunjs type overlap
|
|
1655
2127
|
headers: prefixHeaders(new Headers(config?.headers ?? {})),
|
|
1656
2128
|
//@ts-expect-error caused by undici and bunjs type overlap
|
|
1657
|
-
telemetryHeaders
|
|
2129
|
+
telemetryHeaders,
|
|
2130
|
+
devMode: config?.devMode
|
|
1658
2131
|
});
|
|
1659
2132
|
this.token = token;
|
|
1660
2133
|
}
|
|
@@ -3272,6 +3745,8 @@ export {
|
|
|
3272
3745
|
QStashWorkflowAbort,
|
|
3273
3746
|
formatWorkflowError,
|
|
3274
3747
|
decodeBase64,
|
|
3748
|
+
ensureDevelopmentServer,
|
|
3749
|
+
shouldUseDevelopmentMode,
|
|
3275
3750
|
SignatureError,
|
|
3276
3751
|
Receiver,
|
|
3277
3752
|
FlowControlApi,
|
|
@@ -18,6 +18,15 @@ type ReceiverConfig = {
|
|
|
18
18
|
* and UPSTASH_REGION header.
|
|
19
19
|
*/
|
|
20
20
|
nextSigningKey?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Controls the local dev server signing keys.
|
|
23
|
+
* - `true`: use dev server signing keys
|
|
24
|
+
* - `false`: never use dev server signing keys (ignores QSTASH_DEV env var)
|
|
25
|
+
* - `undefined`: check QSTASH_DEV env var
|
|
26
|
+
*
|
|
27
|
+
* @default undefined
|
|
28
|
+
*/
|
|
29
|
+
devMode?: boolean;
|
|
21
30
|
};
|
|
22
31
|
type VerifyRequest = {
|
|
23
32
|
/**
|
|
@@ -56,6 +65,7 @@ declare class SignatureError extends Error {
|
|
|
56
65
|
declare class Receiver {
|
|
57
66
|
private readonly currentSigningKey?;
|
|
58
67
|
private readonly nextSigningKey?;
|
|
68
|
+
private readonly devMode?;
|
|
59
69
|
constructor(config?: ReceiverConfig);
|
|
60
70
|
/**
|
|
61
71
|
* Verify the signature of a request.
|
|
@@ -2125,6 +2135,15 @@ type ClientConfig = {
|
|
|
2125
2135
|
* @default true
|
|
2126
2136
|
*/
|
|
2127
2137
|
enableTelemetry?: boolean;
|
|
2138
|
+
/**
|
|
2139
|
+
* Controls the local dev server.
|
|
2140
|
+
* - `true`: force dev mode on (downloads, starts, and manages the dev server automatically)
|
|
2141
|
+
* - `false`: force dev mode off (ignores QSTASH_DEV env var)
|
|
2142
|
+
* - `undefined`: check QSTASH_DEV env var
|
|
2143
|
+
*
|
|
2144
|
+
* @default undefined
|
|
2145
|
+
*/
|
|
2146
|
+
devMode?: boolean;
|
|
2128
2147
|
};
|
|
2129
2148
|
type PublishBatchRequest<TBody = BodyInit> = PublishRequest<TBody> & {
|
|
2130
2149
|
queueName?: string;
|
|
@@ -18,6 +18,15 @@ type ReceiverConfig = {
|
|
|
18
18
|
* and UPSTASH_REGION header.
|
|
19
19
|
*/
|
|
20
20
|
nextSigningKey?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Controls the local dev server signing keys.
|
|
23
|
+
* - `true`: use dev server signing keys
|
|
24
|
+
* - `false`: never use dev server signing keys (ignores QSTASH_DEV env var)
|
|
25
|
+
* - `undefined`: check QSTASH_DEV env var
|
|
26
|
+
*
|
|
27
|
+
* @default undefined
|
|
28
|
+
*/
|
|
29
|
+
devMode?: boolean;
|
|
21
30
|
};
|
|
22
31
|
type VerifyRequest = {
|
|
23
32
|
/**
|
|
@@ -56,6 +65,7 @@ declare class SignatureError extends Error {
|
|
|
56
65
|
declare class Receiver {
|
|
57
66
|
private readonly currentSigningKey?;
|
|
58
67
|
private readonly nextSigningKey?;
|
|
68
|
+
private readonly devMode?;
|
|
59
69
|
constructor(config?: ReceiverConfig);
|
|
60
70
|
/**
|
|
61
71
|
* Verify the signature of a request.
|
|
@@ -2125,6 +2135,15 @@ type ClientConfig = {
|
|
|
2125
2135
|
* @default true
|
|
2126
2136
|
*/
|
|
2127
2137
|
enableTelemetry?: boolean;
|
|
2138
|
+
/**
|
|
2139
|
+
* Controls the local dev server.
|
|
2140
|
+
* - `true`: force dev mode on (downloads, starts, and manages the dev server automatically)
|
|
2141
|
+
* - `false`: force dev mode off (ignores QSTASH_DEV env var)
|
|
2142
|
+
* - `undefined`: check QSTASH_DEV env var
|
|
2143
|
+
*
|
|
2144
|
+
* @default undefined
|
|
2145
|
+
*/
|
|
2146
|
+
devMode?: boolean;
|
|
2128
2147
|
};
|
|
2129
2148
|
type PublishBatchRequest<TBody = BodyInit> = PublishRequest<TBody> & {
|
|
2130
2149
|
queueName?: string;
|
package/cloudflare.d.mts
CHANGED