wrangler 0.0.7 → 0.0.12
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 +11 -6
- package/pages/functions/buildWorker.ts +5 -0
- package/pages/functions/filepath-routing.test.ts +8 -1
- package/pages/functions/filepath-routing.ts +25 -20
- package/pages/functions/identifiers.ts +1 -1
- package/pages/functions/routes.ts +11 -9
- package/pages/functions/template-worker.ts +24 -21
- package/src/__tests__/dev.test.tsx +67 -0
- package/src/__tests__/index.test.ts +2 -0
- package/src/__tests__/jest.setup.ts +5 -1
- package/src/__tests__/kv.test.ts +922 -45
- package/src/__tests__/mock-cfetch.ts +140 -30
- package/src/__tests__/publish.test.ts +672 -0
- package/src/__tests__/whoami.test.tsx +130 -0
- package/src/api/form_data.ts +1 -1
- package/src/api/preview.ts +4 -4
- package/src/api/worker.ts +6 -6
- package/src/cfetch/index.ts +110 -0
- package/src/cfetch/internal.ts +71 -0
- package/src/config.ts +633 -118
- package/src/dev.tsx +126 -226
- package/src/index.tsx +318 -245
- package/src/inspect.ts +543 -0
- package/src/kv.tsx +49 -30
- package/src/pages.tsx +323 -204
- package/src/proxy.ts +275 -76
- package/src/publish.ts +92 -60
- package/src/sites.tsx +169 -41
- package/src/tail.tsx +5 -3
- package/src/user.tsx +56 -59
- package/src/whoami.tsx +69 -0
- package/wrangler-dist/cli.js +30481 -29677
- package/wrangler-dist/cli.js.map +3 -3
- package/src/api/inspect.ts +0 -430
- package/src/cfetch.ts +0 -72
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wrangler",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"author": "wrangler@cloudflare.com",
|
|
5
5
|
"description": "Command-line interface for all things Cloudflare Workers",
|
|
6
6
|
"bin": {
|
|
@@ -37,9 +37,10 @@
|
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"esbuild": "0.14.1",
|
|
40
|
-
"miniflare": "2.
|
|
40
|
+
"miniflare": "2.2.0",
|
|
41
41
|
"path-to-regexp": "^6.2.0",
|
|
42
|
-
"semiver": "^1.1.0"
|
|
42
|
+
"semiver": "^1.1.0",
|
|
43
|
+
"xxhash-addon": "^1.4.0"
|
|
43
44
|
},
|
|
44
45
|
"optionalDependencies": {
|
|
45
46
|
"fsevents": "~2.3.2"
|
|
@@ -47,8 +48,8 @@
|
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@babel/types": "^7.16.0",
|
|
49
50
|
"@iarna/toml": "^2.2.5",
|
|
50
|
-
"@types/mime": "^2.0.3",
|
|
51
51
|
"@types/estree": "^0.0.50",
|
|
52
|
+
"@types/mime": "^2.0.3",
|
|
52
53
|
"@types/react": "^17.0.37",
|
|
53
54
|
"@types/serve-static": "^1.13.10",
|
|
54
55
|
"@types/signal-exit": "^3.0.1",
|
|
@@ -59,17 +60,20 @@
|
|
|
59
60
|
"chokidar": "^3.5.2",
|
|
60
61
|
"clipboardy": "^3.0.0",
|
|
61
62
|
"command-exists": "^1.2.9",
|
|
63
|
+
"devtools-protocol": "^0.0.955664",
|
|
62
64
|
"execa": "^6.0.0",
|
|
63
65
|
"faye-websocket": "^0.11.4",
|
|
64
66
|
"finalhandler": "^1.1.2",
|
|
65
67
|
"find-up": "^6.2.0",
|
|
66
68
|
"formdata-node": "^4.3.1",
|
|
69
|
+
"ignore": "^5.2.0",
|
|
67
70
|
"ink": "^3.2.0",
|
|
68
71
|
"ink-select-input": "^4.2.1",
|
|
69
72
|
"ink-table": "^3.0.0",
|
|
73
|
+
"ink-testing-library": "^2.1.0",
|
|
70
74
|
"ink-text-input": "^4.0.2",
|
|
71
75
|
"mime": "^3.0.0",
|
|
72
|
-
"node-fetch": "
|
|
76
|
+
"node-fetch": "3.1.1",
|
|
73
77
|
"open": "^8.4.0",
|
|
74
78
|
"react": "^17.0.2",
|
|
75
79
|
"react-error-boundary": "^3.1.4",
|
|
@@ -95,7 +99,8 @@
|
|
|
95
99
|
"bundle": "node -r esbuild-register scripts/bundle.ts",
|
|
96
100
|
"build": "npm run clean && npm run bundle",
|
|
97
101
|
"start": "npm run bundle && NODE_OPTIONS=--enable-source-maps ./bin/wrangler.js",
|
|
98
|
-
"test": "CF_API_TOKEN=some-api-token CF_ACCOUNT_ID=some-account-id jest --silent=false --verbose=true"
|
|
102
|
+
"test": "CF_API_TOKEN=some-api-token CF_ACCOUNT_ID=some-account-id jest --silent=false --verbose=true",
|
|
103
|
+
"test-watch": "npm run test -- --runInBand --testTimeout=50000 --watch"
|
|
99
104
|
},
|
|
100
105
|
"engines": {
|
|
101
106
|
"node": ">=16.7.0"
|
|
@@ -6,6 +6,7 @@ type Options = {
|
|
|
6
6
|
outfile: string;
|
|
7
7
|
minify?: boolean;
|
|
8
8
|
sourcemap?: boolean;
|
|
9
|
+
fallbackService?: string;
|
|
9
10
|
watch?: boolean;
|
|
10
11
|
onEnd?: () => void;
|
|
11
12
|
};
|
|
@@ -15,6 +16,7 @@ export function buildWorker({
|
|
|
15
16
|
outfile = "bundle.js",
|
|
16
17
|
minify = false,
|
|
17
18
|
sourcemap = false,
|
|
19
|
+
fallbackService = "ASSETS",
|
|
18
20
|
watch = false,
|
|
19
21
|
onEnd = () => {},
|
|
20
22
|
}: Options) {
|
|
@@ -31,6 +33,9 @@ export function buildWorker({
|
|
|
31
33
|
sourcemap,
|
|
32
34
|
watch,
|
|
33
35
|
allowOverwrite: true,
|
|
36
|
+
define: {
|
|
37
|
+
__FALLBACK_SERVICE__: JSON.stringify(fallbackService),
|
|
38
|
+
},
|
|
34
39
|
plugins: [
|
|
35
40
|
{
|
|
36
41
|
name: "wrangler notifier and monitor",
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { compareRoutes } from "./filepath-routing";
|
|
2
2
|
|
|
3
3
|
describe("compareRoutes()", () => {
|
|
4
|
+
test("routes / last", () => {
|
|
5
|
+
expect(compareRoutes("/", "/foo")).toBeGreaterThanOrEqual(1);
|
|
6
|
+
expect(compareRoutes("/", "/:foo")).toBeGreaterThanOrEqual(1);
|
|
7
|
+
expect(compareRoutes("/", "/:foo*")).toBeGreaterThanOrEqual(1);
|
|
8
|
+
});
|
|
9
|
+
|
|
4
10
|
test("routes with fewer segments come after those with more segments", () => {
|
|
5
|
-
expect(compareRoutes("/foo", "/foo/bar")).
|
|
11
|
+
expect(compareRoutes("/foo", "/foo/bar")).toBeGreaterThanOrEqual(1);
|
|
12
|
+
expect(compareRoutes("/foo", "/foo/bar/cat")).toBeGreaterThanOrEqual(1);
|
|
6
13
|
});
|
|
7
14
|
|
|
8
15
|
test("routes with wildcard segments come after those without", () => {
|
|
@@ -3,9 +3,8 @@ import fs from "fs/promises";
|
|
|
3
3
|
import { transform } from "esbuild";
|
|
4
4
|
import * as acorn from "acorn";
|
|
5
5
|
import * as acornWalk from "acorn-walk";
|
|
6
|
-
import type { Config } from "./routes";
|
|
7
|
-
import type { Identifier } from "estree";
|
|
8
|
-
import type { ExportNamedDeclaration } from "@babel/types";
|
|
6
|
+
import type { Config, RouteConfig } from "./routes";
|
|
7
|
+
import type { ExportNamedDeclaration, Identifier } from "estree";
|
|
9
8
|
|
|
10
9
|
type Arguments = {
|
|
11
10
|
baseDir: string;
|
|
@@ -16,10 +15,7 @@ export async function generateConfigFromFileTree({
|
|
|
16
15
|
baseDir,
|
|
17
16
|
baseURL,
|
|
18
17
|
}: Arguments) {
|
|
19
|
-
let routeEntries: [
|
|
20
|
-
string,
|
|
21
|
-
{ [key in "module" | "middleware"]?: string[] }
|
|
22
|
-
][] = [] as any;
|
|
18
|
+
let routeEntries: [string, RouteConfig][] = [];
|
|
23
19
|
|
|
24
20
|
if (!baseURL.startsWith("/")) {
|
|
25
21
|
baseURL = `/${baseURL}`;
|
|
@@ -31,7 +27,7 @@ export async function generateConfigFromFileTree({
|
|
|
31
27
|
|
|
32
28
|
await forEachFile(baseDir, async (filepath) => {
|
|
33
29
|
const ext = path.extname(filepath);
|
|
34
|
-
if (
|
|
30
|
+
if (/^\.(mjs|js|ts|tsx|jsx)$/.test(ext)) {
|
|
35
31
|
// transform the code to ensure we're working with vanilla JS + ESM
|
|
36
32
|
const { code } = await transform(await fs.readFile(filepath, "utf-8"), {
|
|
37
33
|
loader: ext === ".ts" ? "ts" : "js",
|
|
@@ -43,8 +39,10 @@ export async function generateConfigFromFileTree({
|
|
|
43
39
|
sourceType: "module",
|
|
44
40
|
});
|
|
45
41
|
acornWalk.simple(ast, {
|
|
46
|
-
ExportNamedDeclaration(_node) {
|
|
47
|
-
|
|
42
|
+
ExportNamedDeclaration(_node: unknown) {
|
|
43
|
+
// This dynamic cast assumes that the AST generated by acornWalk will generate nodes that
|
|
44
|
+
// are compatible with the eslint AST nodes.
|
|
45
|
+
const node = _node as ExportNamedDeclaration;
|
|
48
46
|
|
|
49
47
|
// this is an array because multiple things can be exported from a single statement
|
|
50
48
|
// i.e. `export {foo, bar}` or `export const foo = "f", bar = "b"`
|
|
@@ -54,7 +52,7 @@ export async function generateConfigFromFileTree({
|
|
|
54
52
|
const declaration = node.declaration;
|
|
55
53
|
|
|
56
54
|
// `export async function onRequest() {...}`
|
|
57
|
-
if (declaration.type === "FunctionDeclaration") {
|
|
55
|
+
if (declaration.type === "FunctionDeclaration" && declaration.id) {
|
|
58
56
|
exportNames.push(declaration.id.name);
|
|
59
57
|
}
|
|
60
58
|
|
|
@@ -157,14 +155,14 @@ export async function generateConfigFromFileTree({
|
|
|
157
155
|
// more specific routes aren't occluded from matching due to
|
|
158
156
|
// less specific routes appearing first in the route list.
|
|
159
157
|
export function compareRoutes(a: string, b: string) {
|
|
160
|
-
function parseRoutePath(routePath: string) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const segments = segmentedPath.slice(1).split("/");
|
|
158
|
+
function parseRoutePath(routePath: string): [string | null, string[]] {
|
|
159
|
+
const parts = routePath.split(" ", 2);
|
|
160
|
+
// split() will guarantee at least one element.
|
|
161
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
162
|
+
const segmentedPath = parts.pop()!;
|
|
163
|
+
const method = parts.pop() ?? null;
|
|
164
|
+
|
|
165
|
+
const segments = segmentedPath.slice(1).split("/").filter(Boolean);
|
|
168
166
|
return [method, segments];
|
|
169
167
|
}
|
|
170
168
|
|
|
@@ -206,7 +204,7 @@ async function forEachFile<T>(
|
|
|
206
204
|
const searchPaths = [baseDir];
|
|
207
205
|
const returnValues: T[] = [];
|
|
208
206
|
|
|
209
|
-
while (searchPaths
|
|
207
|
+
while (isNotEmpty(searchPaths)) {
|
|
210
208
|
const cwd = searchPaths.shift();
|
|
211
209
|
const dir = await fs.readdir(cwd, { withFileTypes: true });
|
|
212
210
|
for (const entry of dir) {
|
|
@@ -221,3 +219,10 @@ async function forEachFile<T>(
|
|
|
221
219
|
|
|
222
220
|
return returnValues;
|
|
223
221
|
}
|
|
222
|
+
|
|
223
|
+
interface NonEmptyArray<T> extends Array<T> {
|
|
224
|
+
shift(): T;
|
|
225
|
+
}
|
|
226
|
+
function isNotEmpty<T>(array: T[]): array is NonEmptyArray<T> {
|
|
227
|
+
return array.length > 0;
|
|
228
|
+
}
|
|
@@ -68,7 +68,7 @@ export const validIdentifierRegex = new RegExp(
|
|
|
68
68
|
"u"
|
|
69
69
|
);
|
|
70
70
|
|
|
71
|
-
export const
|
|
71
|
+
export const isValidIdentifier = (identifier: string) =>
|
|
72
72
|
validIdentifierRegex.test(identifier);
|
|
73
73
|
|
|
74
74
|
export const normalizeIdentifier = (identifier: string) =>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import fs from "fs/promises";
|
|
3
|
-
import {
|
|
3
|
+
import { isValidIdentifier, normalizeIdentifier } from "./identifiers";
|
|
4
4
|
|
|
5
5
|
export const HTTP_METHODS = [
|
|
6
6
|
"HEAD",
|
|
@@ -15,7 +15,7 @@ export type HTTPMethod = typeof HTTP_METHODS[number];
|
|
|
15
15
|
export function isHTTPMethod(
|
|
16
16
|
maybeHTTPMethod: string
|
|
17
17
|
): maybeHTTPMethod is HTTPMethod {
|
|
18
|
-
return HTTP_METHODS.includes(maybeHTTPMethod
|
|
18
|
+
return (HTTP_METHODS as readonly string[]).includes(maybeHTTPMethod);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export type RoutesCollection = Array<{
|
|
@@ -27,14 +27,16 @@ export type RoutesCollection = Array<{
|
|
|
27
27
|
|
|
28
28
|
export type Config = {
|
|
29
29
|
routes?: RoutesConfig;
|
|
30
|
-
schedules?:
|
|
30
|
+
schedules?: unknown;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
export type RoutesConfig = {
|
|
34
|
-
[route: string]:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
[route: string]: RouteConfig;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type RouteConfig = {
|
|
38
|
+
middleware?: string | string[];
|
|
39
|
+
module?: string | string[];
|
|
38
40
|
};
|
|
39
41
|
|
|
40
42
|
type ImportMap = Map<
|
|
@@ -91,7 +93,7 @@ export function parseConfig(config: Config, baseDir: string) {
|
|
|
91
93
|
}
|
|
92
94
|
|
|
93
95
|
// ensure the module name (if provided) is a valid identifier to guard against injection attacks
|
|
94
|
-
if (name !== "default" && !
|
|
96
|
+
if (name !== "default" && !isValidIdentifier(name)) {
|
|
95
97
|
throw new Error(`Invalid module identifier "${name}"`);
|
|
96
98
|
}
|
|
97
99
|
|
|
@@ -112,7 +114,7 @@ export function parseConfig(config: Config, baseDir: string) {
|
|
|
112
114
|
});
|
|
113
115
|
}
|
|
114
116
|
|
|
115
|
-
for (const [route, props] of Object.entries(config.routes)) {
|
|
117
|
+
for (const [route, props] of Object.entries(config.routes ?? {})) {
|
|
116
118
|
let [_methods, routePath] = route.split(" ");
|
|
117
119
|
if (!routePath) {
|
|
118
120
|
routePath = _methods;
|
|
@@ -2,11 +2,11 @@ import { match } from "path-to-regexp";
|
|
|
2
2
|
import type { HTTPMethod } from "./routes";
|
|
3
3
|
|
|
4
4
|
/* TODO: Grab these from @cloudflare/workers-types instead */
|
|
5
|
-
type Params<P extends string =
|
|
5
|
+
type Params<P extends string = string> = Record<P, string | string[]>;
|
|
6
6
|
|
|
7
7
|
type EventContext<Env, P extends string, Data> = {
|
|
8
8
|
request: Request;
|
|
9
|
-
waitUntil: (promise: Promise<
|
|
9
|
+
waitUntil: (promise: Promise<unknown>) => void;
|
|
10
10
|
next: (input?: Request | string, init?: RequestInit) => Promise<Response>;
|
|
11
11
|
env: Env & { ASSETS: { fetch: typeof fetch } };
|
|
12
12
|
params: Params<P>;
|
|
@@ -15,7 +15,7 @@ type EventContext<Env, P extends string, Data> = {
|
|
|
15
15
|
|
|
16
16
|
declare type PagesFunction<
|
|
17
17
|
Env = unknown,
|
|
18
|
-
P extends string =
|
|
18
|
+
P extends string = string,
|
|
19
19
|
Data extends Record<string, unknown> = Record<string, unknown>
|
|
20
20
|
> = (context: EventContext<Env, P, Data>) => Response | Promise<Response>;
|
|
21
21
|
/* end @cloudflare/workers-types */
|
|
@@ -29,22 +29,24 @@ type RouteHandler = {
|
|
|
29
29
|
|
|
30
30
|
// inject `routes` via ESBuild
|
|
31
31
|
declare const routes: RouteHandler[];
|
|
32
|
+
// define `__FALLBACK_SERVICE__` via ESBuild
|
|
33
|
+
declare const __FALLBACK_SERVICE__: string;
|
|
32
34
|
|
|
33
35
|
// expect an ASSETS fetcher binding pointing to the asset-server stage
|
|
34
|
-
type
|
|
35
|
-
[name: string]:
|
|
36
|
-
ASSETS: { fetch
|
|
36
|
+
type FetchEnv = {
|
|
37
|
+
[name: string]: { fetch: typeof fetch };
|
|
38
|
+
ASSETS: { fetch: typeof fetch };
|
|
37
39
|
};
|
|
38
40
|
|
|
39
41
|
type WorkerContext = {
|
|
40
|
-
waitUntil: (promise: Promise<
|
|
42
|
+
waitUntil: (promise: Promise<unknown>) => void;
|
|
41
43
|
};
|
|
42
44
|
|
|
43
|
-
function* executeRequest(request: Request,
|
|
45
|
+
function* executeRequest(request: Request, _env: FetchEnv) {
|
|
44
46
|
const requestPath = new URL(request.url).pathname;
|
|
45
47
|
|
|
46
|
-
// First, iterate through the routes and execute "middlewares" on partial route matches
|
|
47
|
-
for (const route of routes) {
|
|
48
|
+
// First, iterate through the routes (backwards) and execute "middlewares" on partial route matches
|
|
49
|
+
for (const route of [...routes].reverse()) {
|
|
48
50
|
if (
|
|
49
51
|
route.methods.length &&
|
|
50
52
|
!route.methods.includes(request.method as HTTPMethod)
|
|
@@ -85,16 +87,10 @@ function* executeRequest(request: Request, env: Env) {
|
|
|
85
87
|
break;
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
|
-
|
|
89
|
-
// Finally, yield to the asset-server
|
|
90
|
-
return {
|
|
91
|
-
handler: () => env.ASSETS.fetch(request.url, request),
|
|
92
|
-
params: {} as Params,
|
|
93
|
-
};
|
|
94
90
|
}
|
|
95
91
|
|
|
96
92
|
export default {
|
|
97
|
-
async fetch(request: Request, env:
|
|
93
|
+
async fetch(request: Request, env: FetchEnv, workerContext: WorkerContext) {
|
|
98
94
|
const handlerIterator = executeRequest(request, env);
|
|
99
95
|
const data = {}; // arbitrary data the user can set between functions
|
|
100
96
|
const next = async (input?: RequestInfo, init?: RequestInit) => {
|
|
@@ -102,10 +98,11 @@ export default {
|
|
|
102
98
|
request = new Request(input, init);
|
|
103
99
|
}
|
|
104
100
|
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const
|
|
101
|
+
const result = handlerIterator.next();
|
|
102
|
+
// Note we can't use `!result.done` because this doesn't narrow to the correct type
|
|
103
|
+
if (result.done == false) {
|
|
104
|
+
const { handler, params } = result.value;
|
|
105
|
+
const context = {
|
|
109
106
|
request: new Request(request.clone()),
|
|
110
107
|
next,
|
|
111
108
|
params,
|
|
@@ -121,6 +118,12 @@ export default {
|
|
|
121
118
|
[101, 204, 205, 304].includes(response.status) ? null : response.body,
|
|
122
119
|
response
|
|
123
120
|
);
|
|
121
|
+
} else if (__FALLBACK_SERVICE__) {
|
|
122
|
+
// There are no more handlers so finish with the fallback service (`env.ASSETS.fetch` in Pages' case)
|
|
123
|
+
return env[__FALLBACK_SERVICE__].fetch(request);
|
|
124
|
+
} else {
|
|
125
|
+
// There was not fallback service so actually make the request to the origin.
|
|
126
|
+
return fetch(request);
|
|
124
127
|
}
|
|
125
128
|
};
|
|
126
129
|
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { render } from "ink-testing-library";
|
|
2
|
+
import patchConsole from "patch-console";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import Dev from "../dev";
|
|
5
|
+
import type { DevProps } from "../dev";
|
|
6
|
+
|
|
7
|
+
describe("Dev component", () => {
|
|
8
|
+
let restoreConsole;
|
|
9
|
+
beforeEach(() => (restoreConsole = patchConsole(() => {})));
|
|
10
|
+
afterEach(() => restoreConsole());
|
|
11
|
+
|
|
12
|
+
it("should throw if format is service-worker and there is a public directory", () => {
|
|
13
|
+
const { lastFrame } = renderDev({
|
|
14
|
+
format: "service-worker",
|
|
15
|
+
accountId: "some-account-id",
|
|
16
|
+
public: "some/public/path",
|
|
17
|
+
});
|
|
18
|
+
expect(lastFrame()?.split("\n").slice(0, 2).join("\n"))
|
|
19
|
+
.toMatchInlineSnapshot(`
|
|
20
|
+
"Something went wrong:
|
|
21
|
+
Error: You cannot use the service worker format with a \`public\` directory."
|
|
22
|
+
`);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Helper function to make it easier to setup and render the `Dev` component.
|
|
28
|
+
*
|
|
29
|
+
* All the `Dev` props are optional here, with sensible defaults for testing.
|
|
30
|
+
*/
|
|
31
|
+
function renderDev({
|
|
32
|
+
name,
|
|
33
|
+
entry = "some/entry.ts",
|
|
34
|
+
port,
|
|
35
|
+
format,
|
|
36
|
+
accountId,
|
|
37
|
+
initialMode = "remote",
|
|
38
|
+
jsxFactory,
|
|
39
|
+
jsxFragment,
|
|
40
|
+
bindings = {},
|
|
41
|
+
public: publicDir,
|
|
42
|
+
assetPaths,
|
|
43
|
+
compatibilityDate,
|
|
44
|
+
compatibilityFlags,
|
|
45
|
+
usageModel,
|
|
46
|
+
buildCommand = {},
|
|
47
|
+
}: Partial<DevProps>) {
|
|
48
|
+
return render(
|
|
49
|
+
<Dev
|
|
50
|
+
name={name}
|
|
51
|
+
entry={entry}
|
|
52
|
+
port={port}
|
|
53
|
+
buildCommand={buildCommand}
|
|
54
|
+
format={format}
|
|
55
|
+
initialMode={initialMode}
|
|
56
|
+
jsxFactory={jsxFactory}
|
|
57
|
+
jsxFragment={jsxFragment}
|
|
58
|
+
accountId={accountId}
|
|
59
|
+
assetPaths={assetPaths}
|
|
60
|
+
public={publicDir}
|
|
61
|
+
compatibilityDate={compatibilityDate}
|
|
62
|
+
compatibilityFlags={compatibilityFlags}
|
|
63
|
+
usageModel={usageModel}
|
|
64
|
+
bindings={bindings}
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
@@ -17,6 +17,7 @@ describe("wrangler", () => {
|
|
|
17
17
|
|
|
18
18
|
Commands:
|
|
19
19
|
wrangler init [name] 📥 Create a wrangler.toml configuration file
|
|
20
|
+
wrangler whoami 🕵️ Retrieve your user info and test your auth config
|
|
20
21
|
wrangler dev <filename> 👂 Start a local server for developing your worker
|
|
21
22
|
wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
|
|
22
23
|
wrangler tail [name] 🦚 Starts a log tailing session for a deployed Worker.
|
|
@@ -49,6 +50,7 @@ describe("wrangler", () => {
|
|
|
49
50
|
|
|
50
51
|
Commands:
|
|
51
52
|
wrangler init [name] 📥 Create a wrangler.toml configuration file
|
|
53
|
+
wrangler whoami 🕵️ Retrieve your user info and test your auth config
|
|
52
54
|
wrangler dev <filename> 👂 Start a local server for developing your worker
|
|
53
55
|
wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
|
|
54
56
|
wrangler tail [name] 🦚 Starts a log tailing session for a deployed Worker.
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { mockFetchInternal } from "./mock-cfetch";
|
|
1
2
|
import { confirm, prompt } from "../dialogs";
|
|
3
|
+
import { fetchInternal } from "../cfetch/internal";
|
|
4
|
+
|
|
5
|
+
jest.mock("../cfetch/internal");
|
|
6
|
+
(fetchInternal as jest.Mock).mockImplementation(mockFetchInternal);
|
|
2
7
|
|
|
3
|
-
jest.mock("../cfetch", () => jest.requireActual("./mock-cfetch"));
|
|
4
8
|
jest.mock("../dialogs");
|
|
5
9
|
|
|
6
10
|
// By default (if not configured by mockConfirm()) calls to `confirm()` should throw.
|