wrangler 0.0.0-e151223 → 0.0.0-e29a241
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/miniflare-dist/index.mjs +79 -0
- package/miniflare-dist/index.mjs.map +7 -0
- package/package.json +29 -13
- package/pages/functions/filepath-routing.test.ts +212 -36
- package/pages/functions/filepath-routing.ts +69 -119
- package/pages/functions/routes.ts +8 -17
- package/pages/functions/template-worker.ts +3 -9
- package/src/__tests__/configuration.test.ts +2754 -0
- package/src/__tests__/dev.test.tsx +488 -63
- package/src/__tests__/dev2.test.tsx +154 -0
- package/src/__tests__/guess-worker-format.test.ts +58 -0
- package/src/__tests__/helpers/cmd-shim.d.ts +11 -0
- package/src/__tests__/helpers/faye-websocket.d.ts +6 -0
- package/src/__tests__/helpers/mock-account-id.ts +26 -8
- package/src/__tests__/helpers/mock-bin.ts +36 -0
- package/src/__tests__/helpers/mock-cfetch.ts +44 -10
- package/src/__tests__/helpers/mock-console.ts +21 -7
- package/src/__tests__/helpers/mock-kv.ts +9 -16
- package/src/__tests__/helpers/mock-stdin.ts +103 -0
- package/src/__tests__/helpers/mock-web-socket.ts +29 -0
- package/src/__tests__/helpers/run-in-tmp.ts +3 -0
- package/src/__tests__/helpers/run-wrangler.ts +5 -3
- package/src/__tests__/helpers/write-wrangler-toml.ts +17 -0
- package/src/__tests__/https-options.test.ts +127 -0
- package/src/__tests__/index.test.ts +617 -32
- package/src/__tests__/jest.setup.ts +41 -6
- package/src/__tests__/kv.test.ts +455 -222
- package/src/__tests__/logout.test.ts +15 -13
- package/src/__tests__/package-manager.test.ts +206 -0
- package/src/__tests__/pages.test.ts +44 -0
- package/src/__tests__/parse.test.ts +322 -0
- package/src/__tests__/publish.test.ts +1919 -437
- package/src/__tests__/r2.test.ts +198 -0
- package/src/__tests__/route.test.ts +45 -0
- package/src/__tests__/secret.test.ts +301 -86
- package/src/__tests__/sentry.test.ts +146 -0
- package/src/__tests__/tail.test.ts +564 -0
- package/src/__tests__/whoami.test.tsx +21 -7
- package/src/bundle.ts +142 -0
- package/src/cfetch/index.ts +9 -16
- package/src/cfetch/internal.ts +89 -22
- package/src/cli.ts +10 -0
- package/src/config/README.md +107 -0
- package/src/config/config.ts +274 -0
- package/src/config/diagnostics.ts +80 -0
- package/src/config/environment.ts +310 -0
- package/src/config/index.ts +56 -0
- package/src/config/validation-helpers.ts +486 -0
- package/src/config/validation.ts +1096 -0
- package/src/{api/preview.ts → create-worker-preview.ts} +59 -21
- package/src/create-worker-upload-form.ts +217 -0
- package/src/dev/dev.tsx +364 -0
- package/src/dev/local.tsx +226 -0
- package/src/dev/remote.tsx +203 -0
- package/src/dev/use-esbuild.ts +100 -0
- package/src/entry.ts +208 -0
- package/src/environment-variables.ts +33 -0
- package/src/https-options.ts +122 -0
- package/src/index.tsx +1079 -766
- package/src/inspect.ts +25 -4
- package/src/{kv.tsx → kv.ts} +104 -61
- package/src/miniflare-cli/README.md +30 -0
- package/src/miniflare-cli/enum-keys.ts +17 -0
- package/src/miniflare-cli/index.ts +37 -0
- package/src/module-collection.ts +226 -31
- package/src/open-in-browser.ts +25 -0
- package/src/package-manager.ts +126 -0
- package/src/pages.tsx +11 -11
- package/src/parse.ts +183 -0
- package/src/proxy.ts +115 -45
- package/src/publish.ts +265 -328
- package/src/r2.ts +50 -0
- package/src/reporting.ts +131 -0
- package/src/selfsigned.d.ts +29 -0
- package/src/sites.tsx +83 -43
- 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 +223 -124
- package/src/{api/worker.ts → worker.ts} +44 -36
- package/templates/new-worker.js +15 -0
- package/templates/new-worker.ts +15 -0
- package/{static-asset-facade.js → templates/static-asset-facade.js} +0 -0
- package/templates/tsconfig.json +105 -0
- package/wrangler-dist/cli.js +60837 -43876
- package/wrangler-dist/cli.js.map +3 -3
- package/src/__tests__/helpers/mock-user.ts +0 -27
- package/src/api/form_data.ts +0 -134
- package/src/config.ts +0 -641
- package/src/dev.tsx +0 -834
- package/src/npm-installer.ts +0 -20
- package/src/tail.tsx +0 -73
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { execa, execaCommandSync } from "execa";
|
|
4
|
+
|
|
5
|
+
export interface PackageManager {
|
|
6
|
+
cwd: string;
|
|
7
|
+
type: "npm" | "yarn";
|
|
8
|
+
addDevDeps(...packages: string[]): Promise<void>;
|
|
9
|
+
install(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function getPackageManager(cwd: string): Promise<PackageManager> {
|
|
13
|
+
const [hasYarn, hasNpm] = await Promise.all([supportsYarn(), supportsNpm()]);
|
|
14
|
+
const hasYarnLock = existsSync(join(cwd, "yarn.lock"));
|
|
15
|
+
const hasNpmLock = existsSync(join(cwd, "package-lock.json"));
|
|
16
|
+
|
|
17
|
+
if (hasNpmLock) {
|
|
18
|
+
if (hasNpm) {
|
|
19
|
+
console.log(
|
|
20
|
+
"Using npm as package manager, as there is already a package-lock.json file."
|
|
21
|
+
);
|
|
22
|
+
return { ...NpmPackageManager, cwd };
|
|
23
|
+
} else if (hasYarn) {
|
|
24
|
+
console.log("Using yarn as package manager.");
|
|
25
|
+
console.warn(
|
|
26
|
+
"There is already a package-lock.json file but could not find npm on the PATH."
|
|
27
|
+
);
|
|
28
|
+
return { ...YarnPackageManager, cwd };
|
|
29
|
+
}
|
|
30
|
+
} else if (hasYarnLock) {
|
|
31
|
+
if (hasYarn) {
|
|
32
|
+
console.log(
|
|
33
|
+
"Using yarn as package manager, as there is already a yarn.lock file."
|
|
34
|
+
);
|
|
35
|
+
return { ...YarnPackageManager, cwd };
|
|
36
|
+
} else if (hasNpm) {
|
|
37
|
+
console.log("Using npm as package manager.");
|
|
38
|
+
console.warn(
|
|
39
|
+
"There is already a yarn.lock file but could not find yarn on the PATH."
|
|
40
|
+
);
|
|
41
|
+
return { ...NpmPackageManager, cwd };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (hasNpm) {
|
|
46
|
+
console.log("Using npm as package manager.");
|
|
47
|
+
return { ...NpmPackageManager, cwd };
|
|
48
|
+
} else if (hasYarn) {
|
|
49
|
+
console.log("Using yarn as package manager.");
|
|
50
|
+
return { ...YarnPackageManager, cwd };
|
|
51
|
+
} else {
|
|
52
|
+
throw new Error(
|
|
53
|
+
"Unable to find a package manager. Supported managers are: npm and yarn."
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Get the name of the given `packageManager`.
|
|
60
|
+
*/
|
|
61
|
+
export function getPackageManagerName(packageManager: PackageManager): string {
|
|
62
|
+
return packageManager.type ?? "unknown";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Manage packages using npm
|
|
67
|
+
*/
|
|
68
|
+
const NpmPackageManager: PackageManager = {
|
|
69
|
+
cwd: process.cwd(),
|
|
70
|
+
type: "npm",
|
|
71
|
+
/** Add and install a new devDependency into the local package.json. */
|
|
72
|
+
async addDevDeps(...packages: string[]): Promise<void> {
|
|
73
|
+
await execa("npm", ["install", ...packages, "--save-dev"], {
|
|
74
|
+
stdio: "inherit",
|
|
75
|
+
cwd: this.cwd,
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
/** Install all the dependencies in the local package.json. */
|
|
80
|
+
async install(): Promise<void> {
|
|
81
|
+
await execa("npm", ["install"], {
|
|
82
|
+
stdio: "inherit",
|
|
83
|
+
cwd: this.cwd,
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Manage packages using yarn
|
|
90
|
+
*/
|
|
91
|
+
const YarnPackageManager: PackageManager = {
|
|
92
|
+
cwd: process.cwd(),
|
|
93
|
+
type: "yarn",
|
|
94
|
+
/** Add and install a new devDependency into the local package.json. */
|
|
95
|
+
async addDevDeps(...packages: string[]): Promise<void> {
|
|
96
|
+
await execa("yarn", ["add", ...packages, "--dev"], {
|
|
97
|
+
stdio: "inherit",
|
|
98
|
+
cwd: this.cwd,
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
/** Install all the dependencies in the local package.json. */
|
|
103
|
+
async install(): Promise<void> {
|
|
104
|
+
await execa("yarn", ["install"], {
|
|
105
|
+
stdio: "inherit",
|
|
106
|
+
cwd: this.cwd,
|
|
107
|
+
});
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
async function supports(name: string): Promise<boolean> {
|
|
112
|
+
try {
|
|
113
|
+
execaCommandSync(`${name} --version`, { stdio: "ignore" });
|
|
114
|
+
return true;
|
|
115
|
+
} catch {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function supportsYarn(): Promise<boolean> {
|
|
121
|
+
return supports("yarn");
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function supportsNpm(): Promise<boolean> {
|
|
125
|
+
return supports("npm");
|
|
126
|
+
}
|
package/src/pages.tsx
CHANGED
|
@@ -7,10 +7,10 @@ import { join } from "node:path";
|
|
|
7
7
|
import { URL } from "node:url";
|
|
8
8
|
import { watch } from "chokidar";
|
|
9
9
|
import { getType } from "mime";
|
|
10
|
-
import open from "open";
|
|
11
10
|
import { buildWorker } from "../pages/functions/buildWorker";
|
|
12
11
|
import { generateConfigFromFileTree } from "../pages/functions/filepath-routing";
|
|
13
12
|
import { writeRoutesModule } from "../pages/functions/routes";
|
|
13
|
+
import openInBrowser from "./open-in-browser";
|
|
14
14
|
import { toUrlPath } from "./paths";
|
|
15
15
|
import type { Config } from "../pages/functions/routes";
|
|
16
16
|
import type { Headers, Request, fetch } from "@miniflare/core";
|
|
@@ -771,7 +771,7 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
|
|
|
771
771
|
kv: kvs = [],
|
|
772
772
|
do: durableObjects = [],
|
|
773
773
|
"live-reload": liveReload,
|
|
774
|
-
|
|
774
|
+
_: [_pages, _dev, ...remaining],
|
|
775
775
|
}) => {
|
|
776
776
|
if (!local) {
|
|
777
777
|
console.error("Only local mode is supported at the moment.");
|
|
@@ -795,8 +795,8 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
|
|
|
795
795
|
|
|
796
796
|
let miniflareArgs: MiniflareOptions = {};
|
|
797
797
|
|
|
798
|
-
let scriptReadyResolve;
|
|
799
|
-
const scriptReadyPromise = new Promise(
|
|
798
|
+
let scriptReadyResolve: () => void;
|
|
799
|
+
const scriptReadyPromise = new Promise<void>(
|
|
800
800
|
(resolve) => (scriptReadyResolve = resolve)
|
|
801
801
|
);
|
|
802
802
|
|
|
@@ -830,6 +830,9 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
|
|
|
830
830
|
scriptPath,
|
|
831
831
|
};
|
|
832
832
|
} else {
|
|
833
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
834
|
+
scriptReadyResolve!();
|
|
835
|
+
|
|
833
836
|
const scriptPath =
|
|
834
837
|
directory !== undefined
|
|
835
838
|
? join(directory, singleWorkerScriptPath)
|
|
@@ -852,7 +855,6 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
|
|
|
852
855
|
}
|
|
853
856
|
}`,
|
|
854
857
|
};
|
|
855
|
-
scriptReadyResolve();
|
|
856
858
|
}
|
|
857
859
|
}
|
|
858
860
|
|
|
@@ -893,13 +895,13 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
|
|
|
893
895
|
// User bindings
|
|
894
896
|
bindings: {
|
|
895
897
|
...Object.fromEntries(
|
|
896
|
-
bindings.map((binding) => binding.toString().split("="))
|
|
898
|
+
bindings.map((binding) => binding.toString().split("=", 1))
|
|
897
899
|
),
|
|
898
900
|
},
|
|
899
901
|
|
|
900
902
|
// env.ASSETS.fetch
|
|
901
903
|
serviceBindings: {
|
|
902
|
-
async ASSETS(request) {
|
|
904
|
+
async ASSETS(request: Request) {
|
|
903
905
|
if (proxyPort) {
|
|
904
906
|
try {
|
|
905
907
|
const url = new URL(request.url);
|
|
@@ -944,9 +946,7 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
|
|
|
944
946
|
console.log(`Serving at http://localhost:${port}/`);
|
|
945
947
|
|
|
946
948
|
if (process.env.BROWSER !== "none") {
|
|
947
|
-
|
|
948
|
-
// fail silently if the open command doesn't work (e.g. in GitHub Codespaces)
|
|
949
|
-
childProcess.on("error", (_err) => {});
|
|
949
|
+
await openInBrowser(`http://localhost:${port}/`);
|
|
950
950
|
}
|
|
951
951
|
|
|
952
952
|
if (directory !== undefined && liveReload) {
|
|
@@ -963,7 +963,7 @@ export const pages: BuilderCallback<unknown, unknown> = (yargs) => {
|
|
|
963
963
|
miniflare.dispose().catch((err) => miniflare.log.error(err));
|
|
964
964
|
});
|
|
965
965
|
} catch (e) {
|
|
966
|
-
miniflare.log.error(e);
|
|
966
|
+
miniflare.log.error(e as Error);
|
|
967
967
|
EXIT("Could not start Miniflare.", 1);
|
|
968
968
|
}
|
|
969
969
|
}
|
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
|
+
}
|