wrangler 0.0.0-e2a26a0 → 0.0.0-e3cab74
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/package.json +16 -7
- package/pages/functions/filepath-routing.test.ts +112 -36
- package/pages/functions/filepath-routing.ts +66 -119
- package/pages/functions/routes.ts +8 -17
- package/pages/functions/template-worker.ts +3 -9
- package/src/__tests__/configuration.test.ts +2185 -0
- package/src/__tests__/dev.test.tsx +48 -6
- package/src/__tests__/guess-worker-format.test.ts +66 -0
- package/src/__tests__/helpers/faye-websocket.d.ts +6 -0
- package/src/__tests__/helpers/mock-account-id.ts +6 -6
- package/src/__tests__/helpers/mock-bin.ts +4 -1
- package/src/__tests__/helpers/mock-cfetch.ts +2 -2
- package/src/__tests__/helpers/mock-console.ts +11 -5
- package/src/__tests__/helpers/mock-web-socket.ts +29 -0
- package/src/__tests__/helpers/run-wrangler.ts +5 -3
- package/src/__tests__/helpers/write-wrangler-toml.ts +17 -0
- package/src/__tests__/index.test.ts +343 -20
- package/src/__tests__/jest.setup.ts +21 -1
- package/src/__tests__/kv.test.ts +82 -80
- package/src/__tests__/package-manager.test.ts +2 -2
- package/src/__tests__/parse.test.ts +322 -0
- package/src/__tests__/publish.test.ts +1428 -244
- package/src/__tests__/r2.test.ts +198 -0
- package/src/__tests__/secret.test.ts +176 -60
- package/src/__tests__/sentry.test.ts +146 -0
- package/src/__tests__/tail.test.ts +564 -0
- package/src/api/form_data.ts +106 -23
- package/src/api/preview.ts +32 -13
- package/src/api/worker.ts +49 -18
- package/src/bundle.ts +133 -0
- package/src/cfetch/index.ts +8 -6
- package/src/cfetch/internal.ts +49 -17
- package/src/cli.ts +10 -0
- package/src/config/README.md +107 -0
- package/src/config/config.ts +265 -0
- package/src/config/diagnostics.ts +80 -0
- package/src/config/environment.ts +305 -0
- package/src/config/index.ts +52 -0
- package/src/config/validation-helpers.ts +370 -0
- package/src/config/validation.ts +1017 -0
- package/src/dev.tsx +338 -211
- package/src/entry.ts +57 -0
- package/src/environment-variables.ts +33 -0
- package/src/guess-worker-format.ts +68 -0
- package/src/index.tsx +860 -634
- package/src/inspect.ts +16 -3
- package/src/kv.tsx +20 -29
- package/src/module-collection.ts +141 -34
- package/src/open-in-browser.ts +13 -0
- package/src/package-manager.ts +21 -15
- package/src/pages.tsx +9 -10
- package/src/parse.ts +183 -0
- package/src/proxy.ts +11 -5
- package/src/publish.ts +272 -314
- package/src/r2.ts +50 -0
- package/src/reporting.ts +115 -0
- package/src/sites.tsx +16 -15
- package/src/tail/filters.ts +279 -0
- package/src/tail/index.ts +299 -0
- package/src/tail/printing.ts +62 -0
- package/src/user.tsx +74 -44
- package/templates/new-worker.js +1 -1
- package/templates/new-worker.ts +1 -1
- package/templates/tsconfig.json +105 -0
- package/wrangler-dist/cli.js +51308 -36440
- package/wrangler-dist/cli.js.map +3 -3
- package/src/config.ts +0 -641
- package/src/tail.tsx +0 -73
package/src/parse.ts
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import TOML from "@iarna/toml";
|
|
4
|
+
import { formatMessagesSync } from "esbuild";
|
|
5
|
+
|
|
6
|
+
export type Message = {
|
|
7
|
+
text: string;
|
|
8
|
+
location?: Location;
|
|
9
|
+
notes?: Message[];
|
|
10
|
+
kind?: "warning" | "error";
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type Location = File & {
|
|
14
|
+
line: number;
|
|
15
|
+
column: number;
|
|
16
|
+
length?: number;
|
|
17
|
+
lineText?: string;
|
|
18
|
+
suggestion?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type File = {
|
|
22
|
+
file?: string;
|
|
23
|
+
fileText?: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Formats a `Message` using esbuild's pretty-printing algorithm.
|
|
28
|
+
*/
|
|
29
|
+
export function formatMessage(
|
|
30
|
+
{ text, notes, location, kind = "error" }: Message,
|
|
31
|
+
color = true
|
|
32
|
+
): string {
|
|
33
|
+
const input = { text, notes, location };
|
|
34
|
+
delete input.location?.fileText;
|
|
35
|
+
for (const note of notes ?? []) {
|
|
36
|
+
delete note.location?.fileText;
|
|
37
|
+
}
|
|
38
|
+
const lines = formatMessagesSync([input], {
|
|
39
|
+
color,
|
|
40
|
+
kind: kind,
|
|
41
|
+
terminalWidth: process.stderr.columns,
|
|
42
|
+
});
|
|
43
|
+
return lines.join("\n");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* An error that's thrown when something fails to parse.
|
|
48
|
+
*/
|
|
49
|
+
export class ParseError extends Error implements Message {
|
|
50
|
+
readonly text: string;
|
|
51
|
+
readonly notes: Message[];
|
|
52
|
+
readonly location?: Location;
|
|
53
|
+
readonly kind: "warning" | "error";
|
|
54
|
+
|
|
55
|
+
constructor({ text, notes, location, kind }: Message) {
|
|
56
|
+
super(text);
|
|
57
|
+
this.name = this.constructor.name;
|
|
58
|
+
this.text = text;
|
|
59
|
+
this.notes = notes ?? [];
|
|
60
|
+
this.location = location;
|
|
61
|
+
this.kind = kind ?? "error";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
66
|
+
|
|
67
|
+
const TOML_ERROR_NAME = "TomlError";
|
|
68
|
+
const TOML_ERROR_SUFFIX = " at row ";
|
|
69
|
+
|
|
70
|
+
type TomlError = Error & {
|
|
71
|
+
line: number;
|
|
72
|
+
col: number;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* A wrapper around `TOML.parse` that throws a `ParseError`.
|
|
77
|
+
*/
|
|
78
|
+
export function parseTOML(input: string, file?: string): object {
|
|
79
|
+
try {
|
|
80
|
+
return TOML.parse(input);
|
|
81
|
+
} catch (err) {
|
|
82
|
+
const { name, message, line, col } = err as TomlError;
|
|
83
|
+
if (name !== TOML_ERROR_NAME) {
|
|
84
|
+
throw err;
|
|
85
|
+
}
|
|
86
|
+
const text = message.substring(0, message.lastIndexOf(TOML_ERROR_SUFFIX));
|
|
87
|
+
const lineText = input.split("\n")[line];
|
|
88
|
+
const location = {
|
|
89
|
+
lineText,
|
|
90
|
+
line: line + 1,
|
|
91
|
+
column: col - 1,
|
|
92
|
+
file,
|
|
93
|
+
fileText: input,
|
|
94
|
+
};
|
|
95
|
+
throw new ParseError({ text, location });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const JSON_ERROR_SUFFIX = " in JSON at position ";
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* A wrapper around `JSON.parse` that throws a `ParseError`.
|
|
103
|
+
*/
|
|
104
|
+
export function parseJSON(input: string, file?: string): any {
|
|
105
|
+
try {
|
|
106
|
+
return JSON.parse(input);
|
|
107
|
+
} catch (err) {
|
|
108
|
+
const { message } = err as Error;
|
|
109
|
+
const index = message.lastIndexOf(JSON_ERROR_SUFFIX);
|
|
110
|
+
if (index < 0) {
|
|
111
|
+
throw err;
|
|
112
|
+
}
|
|
113
|
+
const text = message.substring(0, index);
|
|
114
|
+
const position = parseInt(
|
|
115
|
+
message.substring(index + JSON_ERROR_SUFFIX.length)
|
|
116
|
+
);
|
|
117
|
+
const location = indexLocation({ file, fileText: input }, position);
|
|
118
|
+
throw new ParseError({ text, location });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Reads a file and parses it based on its type.
|
|
124
|
+
*/
|
|
125
|
+
export function readFileSync(file: string): string {
|
|
126
|
+
try {
|
|
127
|
+
return fs.readFileSync(file, { encoding: "utf-8" });
|
|
128
|
+
} catch (err) {
|
|
129
|
+
const { message } = err as Error;
|
|
130
|
+
throw new ParseError({
|
|
131
|
+
text: `Could not read file: ${file}`,
|
|
132
|
+
notes: [
|
|
133
|
+
{
|
|
134
|
+
text: message.replace(file, resolve(file)),
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Calculates the line and column location from an index.
|
|
143
|
+
*/
|
|
144
|
+
export function indexLocation(file: File, index: number): Location {
|
|
145
|
+
let lineText,
|
|
146
|
+
line = 0,
|
|
147
|
+
column = 0,
|
|
148
|
+
cursor = 0;
|
|
149
|
+
const { fileText = "" } = file;
|
|
150
|
+
for (const row of fileText.split("\n")) {
|
|
151
|
+
line++;
|
|
152
|
+
cursor += row.length + 1;
|
|
153
|
+
if (cursor >= index) {
|
|
154
|
+
lineText = row;
|
|
155
|
+
column = row.length - (cursor - index);
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return { lineText, line, column, ...file };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Guesses the line and column location of a search query.
|
|
164
|
+
*/
|
|
165
|
+
export function searchLocation(file: File, query: unknown): Location {
|
|
166
|
+
let lineText,
|
|
167
|
+
length,
|
|
168
|
+
line = 0,
|
|
169
|
+
column = 0;
|
|
170
|
+
const queryText = String(query);
|
|
171
|
+
const { fileText = "" } = file;
|
|
172
|
+
for (const content of fileText.split("\n")) {
|
|
173
|
+
line++;
|
|
174
|
+
const index = content.indexOf(queryText);
|
|
175
|
+
if (index >= 0) {
|
|
176
|
+
lineText = content;
|
|
177
|
+
column = index;
|
|
178
|
+
length = queryText.length;
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return { lineText, line, column, length, ...file };
|
|
183
|
+
}
|
package/src/proxy.ts
CHANGED
|
@@ -12,6 +12,12 @@ import type {
|
|
|
12
12
|
Server,
|
|
13
13
|
} from "node:http";
|
|
14
14
|
import type { ClientHttp2Session, ServerHttp2Stream } from "node:http2";
|
|
15
|
+
import type ws from "ws";
|
|
16
|
+
|
|
17
|
+
interface IWebsocket extends ws {
|
|
18
|
+
// Pipe implements .on("message", ...)
|
|
19
|
+
pipe<T>(fn: T): IWebsocket;
|
|
20
|
+
}
|
|
15
21
|
|
|
16
22
|
/**
|
|
17
23
|
* `usePreviewServer` is a React hook that creates a local development
|
|
@@ -81,7 +87,7 @@ export function usePreviewServer({
|
|
|
81
87
|
>([]);
|
|
82
88
|
|
|
83
89
|
/**
|
|
84
|
-
* The session doesn't last forever, and will
|
|
90
|
+
* The session doesn't last forever, and will eventually drop
|
|
85
91
|
* (usually within 5-15 minutes). When that happens, we simply
|
|
86
92
|
* restart the effect, effectively restarting the server. We use
|
|
87
93
|
* a state sigil as an effect dependency to do so.
|
|
@@ -207,18 +213,18 @@ export function usePreviewServer({
|
|
|
207
213
|
const { headers, url } = message;
|
|
208
214
|
addCfPreviewTokenHeader(headers, previewToken.value);
|
|
209
215
|
headers["host"] = previewToken.host;
|
|
210
|
-
const localWebsocket = new WebSocket(message, socket, body);
|
|
216
|
+
const localWebsocket = new WebSocket(message, socket, body) as IWebsocket;
|
|
211
217
|
// TODO(soon): Custom WebSocket protocol is not working?
|
|
212
218
|
const remoteWebsocketClient = new WebSocket.Client(
|
|
213
219
|
`wss://${previewToken.host}${url}`,
|
|
214
220
|
[],
|
|
215
221
|
{ headers }
|
|
216
|
-
);
|
|
222
|
+
) as IWebsocket;
|
|
217
223
|
localWebsocket.pipe(remoteWebsocketClient).pipe(localWebsocket);
|
|
218
224
|
// We close down websockets whenever we refresh the token.
|
|
219
225
|
cleanupListeners.push(() => {
|
|
220
|
-
localWebsocket.
|
|
221
|
-
remoteWebsocketClient.
|
|
226
|
+
localWebsocket.close();
|
|
227
|
+
remoteWebsocketClient.close();
|
|
222
228
|
});
|
|
223
229
|
};
|
|
224
230
|
proxy.on("upgrade", handleUpgrade);
|