@vercel/queue 0.0.0-alpha.2 → 0.0.0-alpha.20

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.
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Standalone CLI script to discover queue handlers in development mode
5
+ * This script is self-contained and doesn't import from the main package
6
+ */
7
+
8
+ const fs = require("fs");
9
+ const path = require("path");
10
+
11
+ function showHelp() {
12
+ console.log(`
13
+ @vercel/queue local-init - Initialize queue handlers in local development
14
+
15
+ USAGE:
16
+ npx vercel-queue-local-init [options]
17
+
18
+ OPTIONS:
19
+ --port <number> Port number for Next.js dev server (default: 3000)
20
+ --config <path> Path to vercel.json file (default: ./vercel.json)
21
+ --help, -h Show this help message
22
+
23
+ EXAMPLES:
24
+ npx vercel-queue-local-init
25
+ npx vercel-queue-local-init --port 3001
26
+ npx vercel-queue-local-init --config ./my-vercel.json
27
+ `);
28
+ }
29
+
30
+ /**
31
+ * Read vercel.json and extract function endpoints with queue triggers
32
+ */
33
+ function readVercelConfig(configPath = "./vercel.json") {
34
+ try {
35
+ const fullPath = path.resolve(configPath);
36
+ const configContent = fs.readFileSync(fullPath, "utf-8");
37
+ const config = JSON.parse(configContent);
38
+
39
+ const routes = [];
40
+
41
+ // Extract routes from functions with queue triggers
42
+ if (config.functions) {
43
+ for (const [functionPath, functionConfig] of Object.entries(
44
+ config.functions,
45
+ )) {
46
+ if (
47
+ functionConfig &&
48
+ typeof functionConfig === "object" &&
49
+ "experimentalTriggers" in functionConfig
50
+ ) {
51
+ const triggers = functionConfig.experimentalTriggers;
52
+ if (Array.isArray(triggers)) {
53
+ // Check if any trigger is a queue trigger
54
+ const hasQueueTrigger = triggers.some(
55
+ (trigger) =>
56
+ trigger &&
57
+ typeof trigger === "object" &&
58
+ trigger.type === "queue/v1beta",
59
+ );
60
+
61
+ if (hasQueueTrigger) {
62
+ // Convert file path to API route
63
+ // app/api/vm/queue/route.ts -> /api/vm/queue
64
+ // pages/api/queue.ts -> /api/queue
65
+ let apiPath = functionPath;
66
+
67
+ if (apiPath.startsWith("app/api/")) {
68
+ apiPath = apiPath.replace("app/api/", "/api/");
69
+ } else if (apiPath.startsWith("pages/api/")) {
70
+ apiPath = apiPath.replace("pages/api/", "/api/");
71
+ }
72
+
73
+ // Remove file extensions and /route suffix
74
+ apiPath = apiPath.replace(
75
+ /\/(route|index)\.(ts|js|tsx|jsx)$/,
76
+ "",
77
+ );
78
+ apiPath = apiPath.replace(/\.(ts|js|tsx|jsx)$/, "");
79
+
80
+ routes.push(apiPath);
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
86
+
87
+ return routes;
88
+ } catch (error) {
89
+ // vercel.json might not exist or be malformed
90
+ return [];
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Make OPTIONS requests to trigger Next.js lazy loading
96
+ */
97
+ async function discoverQueueHandlers(options = {}) {
98
+ const baseUrl = options.baseUrl || "http://localhost:3000";
99
+ const configPath = options.configPath || "./vercel.json";
100
+
101
+ let routes = options.routes || [];
102
+
103
+ // Auto-discover from vercel.json
104
+ if (routes.length === 0) {
105
+ const configRoutes = readVercelConfig(configPath);
106
+ if (configRoutes.length > 0) {
107
+ routes = configRoutes;
108
+ console.log(
109
+ `[Dev Mode] Found ${configRoutes.length} queue endpoints in vercel.json`,
110
+ );
111
+ } else {
112
+ console.error("[Dev Mode] No queue endpoints found in vercel.json");
113
+ process.exit(1);
114
+ }
115
+ }
116
+
117
+ console.log(
118
+ "[Dev Mode] Making OPTIONS requests to trigger module loading...",
119
+ );
120
+
121
+ for (const route of routes) {
122
+ try {
123
+ // Make an OPTIONS request to trigger module loading without processing
124
+ const response = await fetch(`${baseUrl}${route}`, {
125
+ method: "OPTIONS",
126
+ // Add a header to identify this as a discovery request
127
+ headers: { "x-queue-discovery": "true" },
128
+ });
129
+
130
+ // Any response means the route exists and module was loaded
131
+ console.log(`[Dev Mode] ✓ ${route} (${response.status})`);
132
+ } catch (error) {
133
+ // Ignore errors - route might not exist or server not running
134
+ console.log(`[Dev Mode] ✗ ${route} (server may not be running)`);
135
+ }
136
+ }
137
+
138
+ console.log("[Dev Mode] Module loading complete.");
139
+ }
140
+
141
+ async function main() {
142
+ const args = process.argv.slice(2);
143
+ const options = {};
144
+
145
+ // Parse simple command line arguments
146
+ for (let i = 0; i < args.length; i++) {
147
+ const arg = args[i];
148
+ if (arg === "--help" || arg === "-h") {
149
+ showHelp();
150
+ return;
151
+ } else if (arg === "--port" && args[i + 1]) {
152
+ options.baseUrl = `http://localhost:${args[i + 1]}`;
153
+ i++;
154
+ } else if (arg === "--config" && args[i + 1]) {
155
+ options.configPath = args[i + 1];
156
+ i++;
157
+ }
158
+ }
159
+
160
+ try {
161
+ await discoverQueueHandlers(options);
162
+ } catch (error) {
163
+ console.error("Failed to discover queue handlers:", error.message);
164
+ process.exit(1);
165
+ }
166
+ }
167
+
168
+ main();