wrangler 2.0.24 → 2.0.27
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 +142 -16
- package/package.json +3 -3
- package/src/__tests__/configuration.test.ts +7 -3
- package/src/__tests__/dev.test.tsx +26 -4
- package/src/__tests__/generate.test.ts +2 -4
- package/src/__tests__/helpers/mock-cfetch.ts +35 -2
- package/src/__tests__/init.test.ts +537 -359
- package/src/__tests__/jest.setup.ts +7 -0
- package/src/__tests__/metrics.test.ts +1 -1
- package/src/__tests__/pages.test.ts +14 -0
- package/src/__tests__/r2.test.ts +22 -3
- package/src/__tests__/tail.test.ts +112 -42
- package/src/__tests__/user.test.ts +11 -0
- package/src/api/dev.ts +7 -0
- package/src/bundle.ts +3 -2
- package/src/cfetch/internal.ts +56 -0
- package/src/config/config.ts +1 -1
- package/src/config/validation-helpers.ts +19 -6
- package/src/config/validation.ts +9 -3
- package/src/config-cache.ts +2 -1
- package/src/dev/dev.tsx +16 -2
- package/src/dev/local.tsx +69 -5
- package/src/dev/use-esbuild.ts +3 -0
- package/src/dev-registry.tsx +3 -0
- package/src/dev.tsx +28 -19
- package/src/generate.ts +1 -1
- package/src/index.tsx +51 -21
- package/src/init.ts +111 -38
- package/src/inspect.ts +1 -4
- package/src/{metrics/is-ci.ts → is-ci.ts} +0 -0
- package/src/metrics/metrics-config.ts +1 -1
- package/src/miniflare-cli/assets.ts +27 -16
- package/src/miniflare-cli/index.ts +124 -2
- package/src/pages/build.tsx +75 -41
- package/src/pages/constants.ts +4 -0
- package/src/pages/deployments.tsx +9 -9
- package/src/pages/dev.tsx +178 -64
- package/src/pages/errors.ts +22 -0
- package/src/pages/functions/buildPlugin.ts +4 -0
- package/src/pages/functions/buildWorker.ts +4 -0
- package/src/pages/functions/routes-consolidation.test.ts +250 -0
- package/src/pages/functions/routes-consolidation.ts +73 -0
- package/src/pages/functions/routes-transformation.test.ts +271 -0
- package/src/pages/functions/routes-transformation.ts +122 -0
- package/src/pages/functions.tsx +96 -0
- package/src/pages/index.tsx +65 -55
- package/src/pages/projects.tsx +9 -3
- package/src/pages/publish.tsx +75 -22
- package/src/pages/types.ts +9 -0
- package/src/pages/upload.tsx +6 -8
- package/src/proxy.ts +10 -0
- package/src/r2.ts +17 -4
- package/src/tail/filters.ts +3 -1
- package/src/tail/index.ts +15 -2
- package/src/tail/printing.ts +43 -3
- package/src/user/user.tsx +6 -4
- package/src/whoami.tsx +5 -5
- package/templates/pages-template-plugin.ts +16 -4
- package/templates/pages-template-worker.ts +16 -5
- package/templates/service-bindings-module-facade.js +10 -7
- package/templates/service-bindings-sw-facade.js +10 -7
- package/wrangler-dist/cli.d.ts +7 -0
- package/wrangler-dist/cli.js +1681 -1091
package/miniflare-dist/index.mjs
CHANGED
|
@@ -105,7 +105,18 @@ var require_mime = __commonJS({
|
|
|
105
105
|
});
|
|
106
106
|
|
|
107
107
|
// src/miniflare-cli/index.ts
|
|
108
|
-
import {
|
|
108
|
+
import { fetch } from "@miniflare/core";
|
|
109
|
+
import {
|
|
110
|
+
DurableObjectNamespace,
|
|
111
|
+
DurableObjectStub
|
|
112
|
+
} from "@miniflare/durable-objects";
|
|
113
|
+
import {
|
|
114
|
+
Log,
|
|
115
|
+
LogLevel,
|
|
116
|
+
Miniflare,
|
|
117
|
+
Response as MiniflareResponse,
|
|
118
|
+
Request as MiniflareRequest
|
|
119
|
+
} from "miniflare";
|
|
109
120
|
|
|
110
121
|
// ../../node_modules/yargs/lib/platform-shims/esm.mjs
|
|
111
122
|
import { notStrictEqual, strictEqual } from "assert";
|
|
@@ -4914,6 +4925,14 @@ function isYargsInstance(y) {
|
|
|
4914
4925
|
var Yargs = YargsFactory(esm_default);
|
|
4915
4926
|
var yargs_default = Yargs;
|
|
4916
4927
|
|
|
4928
|
+
// src/errors.ts
|
|
4929
|
+
var FatalError = class extends Error {
|
|
4930
|
+
constructor(message, code) {
|
|
4931
|
+
super(message);
|
|
4932
|
+
this.code = code;
|
|
4933
|
+
}
|
|
4934
|
+
};
|
|
4935
|
+
|
|
4917
4936
|
// src/miniflare-cli/assets.ts
|
|
4918
4937
|
var import_mime = __toESM(require_mime());
|
|
4919
4938
|
import { existsSync, lstatSync, readFileSync as readFileSync4 } from "node:fs";
|
|
@@ -5147,6 +5166,11 @@ async function generateAssetsFetch(directory, log) {
|
|
|
5147
5166
|
};
|
|
5148
5167
|
const generateResponse = (request) => {
|
|
5149
5168
|
const url = new URL(request.url);
|
|
5169
|
+
let assetName = url.pathname;
|
|
5170
|
+
try {
|
|
5171
|
+
assetName = decodeURIComponent(url.pathname);
|
|
5172
|
+
} catch {
|
|
5173
|
+
}
|
|
5150
5174
|
const deconstructedResponse = {
|
|
5151
5175
|
status: 200,
|
|
5152
5176
|
headers: new Headers(),
|
|
@@ -5176,7 +5200,7 @@ async function generateAssetsFetch(directory, log) {
|
|
|
5176
5200
|
return deconstructedResponse;
|
|
5177
5201
|
}
|
|
5178
5202
|
const notFound = () => {
|
|
5179
|
-
let cwd =
|
|
5203
|
+
let cwd = assetName;
|
|
5180
5204
|
while (cwd) {
|
|
5181
5205
|
cwd = cwd.slice(0, cwd.lastIndexOf("/"));
|
|
5182
5206
|
if (asset = getAsset(`${cwd}/404.html`)) {
|
|
@@ -5201,34 +5225,34 @@ async function generateAssetsFetch(directory, log) {
|
|
|
5201
5225
|
return deconstructedResponse;
|
|
5202
5226
|
};
|
|
5203
5227
|
let asset;
|
|
5204
|
-
if (
|
|
5205
|
-
if (asset = getAsset(`${
|
|
5228
|
+
if (assetName.endsWith("/")) {
|
|
5229
|
+
if (asset = getAsset(`${assetName}/index.html`)) {
|
|
5206
5230
|
deconstructedResponse.body = serveAsset(asset);
|
|
5207
5231
|
deconstructedResponse.headers.set(
|
|
5208
5232
|
"Content-Type",
|
|
5209
5233
|
(0, import_mime.getType)(asset) || "application/octet-stream"
|
|
5210
5234
|
);
|
|
5211
5235
|
return deconstructedResponse;
|
|
5212
|
-
} else if (asset = getAsset(`${
|
|
5236
|
+
} else if (asset = getAsset(`${assetName.replace(/\/$/, ".html")}`)) {
|
|
5213
5237
|
deconstructedResponse.status = 301;
|
|
5214
5238
|
deconstructedResponse.headers.set(
|
|
5215
5239
|
"Location",
|
|
5216
|
-
`${
|
|
5240
|
+
`${assetName.slice(0, -1)}${url.search}`
|
|
5217
5241
|
);
|
|
5218
5242
|
return deconstructedResponse;
|
|
5219
5243
|
}
|
|
5220
5244
|
}
|
|
5221
|
-
if (
|
|
5245
|
+
if (assetName.endsWith("/index")) {
|
|
5222
5246
|
deconstructedResponse.status = 301;
|
|
5223
5247
|
deconstructedResponse.headers.set(
|
|
5224
5248
|
"Location",
|
|
5225
|
-
`${
|
|
5249
|
+
`${assetName.slice(0, -"index".length)}${url.search}`
|
|
5226
5250
|
);
|
|
5227
5251
|
return deconstructedResponse;
|
|
5228
5252
|
}
|
|
5229
|
-
if (asset = getAsset(
|
|
5230
|
-
if (
|
|
5231
|
-
const extensionlessPath =
|
|
5253
|
+
if (asset = getAsset(assetName)) {
|
|
5254
|
+
if (assetName.endsWith(".html")) {
|
|
5255
|
+
const extensionlessPath = assetName.slice(0, -".html".length);
|
|
5232
5256
|
if (getAsset(extensionlessPath) || extensionlessPath === "/") {
|
|
5233
5257
|
deconstructedResponse.body = serveAsset(asset);
|
|
5234
5258
|
deconstructedResponse.headers.set(
|
|
@@ -5252,11 +5276,19 @@ async function generateAssetsFetch(directory, log) {
|
|
|
5252
5276
|
);
|
|
5253
5277
|
return deconstructedResponse;
|
|
5254
5278
|
}
|
|
5255
|
-
} else if (hasFileExtension(
|
|
5279
|
+
} else if (hasFileExtension(assetName)) {
|
|
5280
|
+
if (asset = getAsset(assetName + ".html")) {
|
|
5281
|
+
deconstructedResponse.body = serveAsset(asset);
|
|
5282
|
+
deconstructedResponse.headers.set(
|
|
5283
|
+
"Content-Type",
|
|
5284
|
+
(0, import_mime.getType)(asset) || "application/octet-stream"
|
|
5285
|
+
);
|
|
5286
|
+
return deconstructedResponse;
|
|
5287
|
+
}
|
|
5256
5288
|
notFound();
|
|
5257
5289
|
return deconstructedResponse;
|
|
5258
5290
|
}
|
|
5259
|
-
if (asset = getAsset(`${
|
|
5291
|
+
if (asset = getAsset(`${assetName}.html`)) {
|
|
5260
5292
|
deconstructedResponse.body = serveAsset(asset);
|
|
5261
5293
|
deconstructedResponse.headers.set(
|
|
5262
5294
|
"Content-Type",
|
|
@@ -5264,11 +5296,11 @@ async function generateAssetsFetch(directory, log) {
|
|
|
5264
5296
|
);
|
|
5265
5297
|
return deconstructedResponse;
|
|
5266
5298
|
}
|
|
5267
|
-
if (asset = getAsset(`${
|
|
5299
|
+
if (asset = getAsset(`${assetName}/index.html`)) {
|
|
5268
5300
|
deconstructedResponse.status = 301;
|
|
5269
5301
|
deconstructedResponse.headers.set(
|
|
5270
5302
|
"Location",
|
|
5271
|
-
`${
|
|
5303
|
+
`${assetName}/${url.search}`
|
|
5272
5304
|
);
|
|
5273
5305
|
return deconstructedResponse;
|
|
5274
5306
|
} else {
|
|
@@ -5369,7 +5401,44 @@ async function main() {
|
|
|
5369
5401
|
if (logLevel > LogLevel.INFO) {
|
|
5370
5402
|
console.log("OPTIONS:\n", JSON.stringify(config, null, 2));
|
|
5371
5403
|
}
|
|
5404
|
+
config.bindings = {
|
|
5405
|
+
...config.bindings,
|
|
5406
|
+
...Object.fromEntries(
|
|
5407
|
+
Object.entries(
|
|
5408
|
+
config.externalDurableObjects
|
|
5409
|
+
).map(([binding, { name, host, port }]) => {
|
|
5410
|
+
const factory = () => {
|
|
5411
|
+
throw new FatalError(
|
|
5412
|
+
"An external Durable Object instance's state has somehow been attempted to be accessed.",
|
|
5413
|
+
1
|
|
5414
|
+
);
|
|
5415
|
+
};
|
|
5416
|
+
const namespace = new DurableObjectNamespace(name, factory);
|
|
5417
|
+
namespace.get = (id) => {
|
|
5418
|
+
const stub = new DurableObjectStub(factory, id);
|
|
5419
|
+
stub.fetch = (...reqArgs) => {
|
|
5420
|
+
const requestFromArgs = new MiniflareRequest(...reqArgs);
|
|
5421
|
+
const url = new URL(requestFromArgs.url);
|
|
5422
|
+
url.host = host;
|
|
5423
|
+
if (port !== void 0)
|
|
5424
|
+
url.port = port.toString();
|
|
5425
|
+
const request = new MiniflareRequest(
|
|
5426
|
+
url.toString(),
|
|
5427
|
+
requestFromArgs
|
|
5428
|
+
);
|
|
5429
|
+
request.headers.set("x-miniflare-durable-object-name", name);
|
|
5430
|
+
request.headers.set("x-miniflare-durable-object-id", id.toString());
|
|
5431
|
+
return fetch(request);
|
|
5432
|
+
};
|
|
5433
|
+
return stub;
|
|
5434
|
+
};
|
|
5435
|
+
return [binding, namespace];
|
|
5436
|
+
})
|
|
5437
|
+
)
|
|
5438
|
+
};
|
|
5372
5439
|
let mf;
|
|
5440
|
+
let durableObjectsMf = void 0;
|
|
5441
|
+
let durableObjectsMfPort = void 0;
|
|
5373
5442
|
try {
|
|
5374
5443
|
if (args._[1]) {
|
|
5375
5444
|
const opts = JSON.parse(
|
|
@@ -5393,11 +5462,68 @@ async function main() {
|
|
|
5393
5462
|
mf = new Miniflare(config);
|
|
5394
5463
|
await mf.startServer();
|
|
5395
5464
|
await mf.startScheduler();
|
|
5396
|
-
|
|
5465
|
+
const internalDurableObjectClassNames = Object.values(
|
|
5466
|
+
config.durableObjects
|
|
5467
|
+
);
|
|
5468
|
+
if (internalDurableObjectClassNames.length > 0) {
|
|
5469
|
+
durableObjectsMf = new Miniflare({
|
|
5470
|
+
host: config.host,
|
|
5471
|
+
port: 0,
|
|
5472
|
+
script: `
|
|
5473
|
+
export default {
|
|
5474
|
+
fetch(request, env) {
|
|
5475
|
+
return env.DO.fetch(request)
|
|
5476
|
+
}
|
|
5477
|
+
}`,
|
|
5478
|
+
serviceBindings: {
|
|
5479
|
+
DO: async (request) => {
|
|
5480
|
+
request = new MiniflareRequest(request);
|
|
5481
|
+
const name = request.headers.get("x-miniflare-durable-object-name");
|
|
5482
|
+
const idString = request.headers.get(
|
|
5483
|
+
"x-miniflare-durable-object-id"
|
|
5484
|
+
);
|
|
5485
|
+
request.headers.delete("x-miniflare-durable-object-name");
|
|
5486
|
+
request.headers.delete("x-miniflare-durable-object-id");
|
|
5487
|
+
if (!name || !idString) {
|
|
5488
|
+
return new MiniflareResponse(
|
|
5489
|
+
"[durable-object-proxy-err] Missing `x-miniflare-durable-object-name` or `x-miniflare-durable-object-id` headers.",
|
|
5490
|
+
{ status: 400 }
|
|
5491
|
+
);
|
|
5492
|
+
}
|
|
5493
|
+
const namespace = await mf?.getDurableObjectNamespace(name);
|
|
5494
|
+
const id = namespace?.idFromString(idString);
|
|
5495
|
+
if (!id) {
|
|
5496
|
+
return new MiniflareResponse(
|
|
5497
|
+
"[durable-object-proxy-err] Could not generate an ID. Possibly due to a mismatched DO name and ID?",
|
|
5498
|
+
{ status: 500 }
|
|
5499
|
+
);
|
|
5500
|
+
}
|
|
5501
|
+
const stub = namespace?.get(id);
|
|
5502
|
+
if (!stub) {
|
|
5503
|
+
return new MiniflareResponse(
|
|
5504
|
+
"[durable-object-proxy-err] Could not generate a stub. Possibly due to a mismatched DO name and ID?",
|
|
5505
|
+
{ status: 500 }
|
|
5506
|
+
);
|
|
5507
|
+
}
|
|
5508
|
+
return stub.fetch(request);
|
|
5509
|
+
}
|
|
5510
|
+
},
|
|
5511
|
+
modules: true
|
|
5512
|
+
});
|
|
5513
|
+
const server = await durableObjectsMf.startServer();
|
|
5514
|
+
durableObjectsMfPort = server.address().port;
|
|
5515
|
+
}
|
|
5516
|
+
process.send && process.send(
|
|
5517
|
+
JSON.stringify({
|
|
5518
|
+
ready: true,
|
|
5519
|
+
durableObjectsPort: durableObjectsMfPort
|
|
5520
|
+
})
|
|
5521
|
+
);
|
|
5397
5522
|
} catch (e) {
|
|
5398
5523
|
mf?.log.error(e);
|
|
5399
5524
|
process.exitCode = 1;
|
|
5400
5525
|
await mf?.dispose();
|
|
5526
|
+
await durableObjectsMf?.dispose();
|
|
5401
5527
|
}
|
|
5402
5528
|
}
|
|
5403
5529
|
await main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wrangler",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.27",
|
|
4
4
|
"description": "Command-line interface for all things Cloudflare Workers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wrangler",
|
|
@@ -52,11 +52,11 @@
|
|
|
52
52
|
"build": "npm run clean && npm run bundle && npm run emit-types",
|
|
53
53
|
"bundle": "node -r esbuild-register scripts/bundle.ts",
|
|
54
54
|
"check:type": "tsc",
|
|
55
|
-
"clean": "
|
|
55
|
+
"clean": "rimraf wrangler-dist miniflare-dist emitted-types",
|
|
56
56
|
"dev": "npm run clean && concurrently -c black,blue --kill-others-on-fail false 'npm run bundle -- --watch' 'npm run check:type -- --watch --preserveWatchOutput'",
|
|
57
57
|
"emit-types": "tsc -p tsconfig.emit.json && node -r esbuild-register scripts/emit-types.ts",
|
|
58
58
|
"prepublishOnly": "SOURCEMAPS=false npm run build",
|
|
59
|
-
"start": "npm run bundle && NODE_OPTIONS=--enable-source-maps ./bin/wrangler.js",
|
|
59
|
+
"start": "npm run bundle && cross-env NODE_OPTIONS=--enable-source-maps ./bin/wrangler.js",
|
|
60
60
|
"test": "jest --silent=false --verbose=true",
|
|
61
61
|
"test-watch": "npm run test -- --runInBand --testTimeout=50000 --watch",
|
|
62
62
|
"test:ci": "npm run test -- --verbose=true --coverage"
|
|
@@ -26,7 +26,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
26
26
|
compatibility_flags: [],
|
|
27
27
|
configPath: undefined,
|
|
28
28
|
dev: {
|
|
29
|
-
ip: "
|
|
29
|
+
ip: "0.0.0.0",
|
|
30
30
|
local_protocol: "http",
|
|
31
31
|
port: undefined, // the default of 8787 is set at runtime
|
|
32
32
|
upstream_protocol: "https",
|
|
@@ -1635,6 +1635,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
1635
1635
|
id: "KV_ID_2",
|
|
1636
1636
|
preview_id: 2222,
|
|
1637
1637
|
},
|
|
1638
|
+
{ binding: "VALID", id: "" },
|
|
1638
1639
|
],
|
|
1639
1640
|
} as unknown as RawConfig,
|
|
1640
1641
|
undefined,
|
|
@@ -1654,7 +1655,8 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
1654
1655
|
- \\"kv_namespaces[1]\\" bindings should have a string \\"id\\" field but got {\\"binding\\":\\"VALID\\"}.
|
|
1655
1656
|
- \\"kv_namespaces[2]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":2000,\\"id\\":2111}.
|
|
1656
1657
|
- \\"kv_namespaces[2]\\" bindings should have a string \\"id\\" field but got {\\"binding\\":2000,\\"id\\":2111}.
|
|
1657
|
-
- \\"kv_namespaces[3]\\" bindings should, optionally, have a string \\"preview_id\\" field but got {\\"binding\\":\\"KV_BINDING_2\\",\\"id\\":\\"KV_ID_2\\",\\"preview_id\\":2222}.
|
|
1658
|
+
- \\"kv_namespaces[3]\\" bindings should, optionally, have a string \\"preview_id\\" field but got {\\"binding\\":\\"KV_BINDING_2\\",\\"id\\":\\"KV_ID_2\\",\\"preview_id\\":2222}.
|
|
1659
|
+
- \\"kv_namespaces[4]\\" bindings should have a string \\"id\\" field but got {\\"binding\\":\\"VALID\\",\\"id\\":\\"\\"}."
|
|
1658
1660
|
`);
|
|
1659
1661
|
});
|
|
1660
1662
|
});
|
|
@@ -1740,6 +1742,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
1740
1742
|
bucket_name: "R2_BUCKET_2",
|
|
1741
1743
|
preview_bucket_name: 2555,
|
|
1742
1744
|
},
|
|
1745
|
+
{ binding: "R2_BINDING_1", bucket_name: "" },
|
|
1743
1746
|
],
|
|
1744
1747
|
} as unknown as RawConfig,
|
|
1745
1748
|
undefined,
|
|
@@ -1759,7 +1762,8 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
1759
1762
|
- \\"r2_buckets[1]\\" bindings should have a string \\"bucket_name\\" field but got {\\"binding\\":\\"R2_BINDING_1\\"}.
|
|
1760
1763
|
- \\"r2_buckets[2]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":2333,\\"bucket_name\\":2444}.
|
|
1761
1764
|
- \\"r2_buckets[2]\\" bindings should have a string \\"bucket_name\\" field but got {\\"binding\\":2333,\\"bucket_name\\":2444}.
|
|
1762
|
-
- \\"r2_buckets[3]\\" bindings should, optionally, have a string \\"preview_bucket_name\\" field but got {\\"binding\\":\\"R2_BINDING_2\\",\\"bucket_name\\":\\"R2_BUCKET_2\\",\\"preview_bucket_name\\":2555}.
|
|
1765
|
+
- \\"r2_buckets[3]\\" bindings should, optionally, have a string \\"preview_bucket_name\\" field but got {\\"binding\\":\\"R2_BINDING_2\\",\\"bucket_name\\":\\"R2_BUCKET_2\\",\\"preview_bucket_name\\":2555}.
|
|
1766
|
+
- \\"r2_buckets[4]\\" bindings should have a string \\"bucket_name\\" field but got {\\"binding\\":\\"R2_BINDING_1\\",\\"bucket_name\\":\\"\\"}."
|
|
1763
1767
|
`);
|
|
1764
1768
|
});
|
|
1765
1769
|
});
|
|
@@ -68,6 +68,28 @@ describe("wrangler dev", () => {
|
|
|
68
68
|
});
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
+
describe("usage-model", () => {
|
|
72
|
+
it("should read wrangler.toml's usage_model", async () => {
|
|
73
|
+
writeWranglerToml({
|
|
74
|
+
main: "index.js",
|
|
75
|
+
usage_model: "unbound",
|
|
76
|
+
});
|
|
77
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
78
|
+
await runWrangler("dev");
|
|
79
|
+
expect((Dev as jest.Mock).mock.calls[0][0].usageModel).toEqual("unbound");
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("should read wrangler.toml's usage_model in local mode", async () => {
|
|
83
|
+
writeWranglerToml({
|
|
84
|
+
main: "index.js",
|
|
85
|
+
usage_model: "unbound",
|
|
86
|
+
});
|
|
87
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
88
|
+
await runWrangler("dev --local");
|
|
89
|
+
expect((Dev as jest.Mock).mock.calls[0][0].usageModel).toEqual("unbound");
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
71
93
|
describe("entry-points", () => {
|
|
72
94
|
it("should error if there is no entry-point specified", async () => {
|
|
73
95
|
writeWranglerToml();
|
|
@@ -630,13 +652,13 @@ describe("wrangler dev", () => {
|
|
|
630
652
|
});
|
|
631
653
|
|
|
632
654
|
describe("ip", () => {
|
|
633
|
-
it("should default ip to
|
|
655
|
+
it("should default ip to 0.0.0.0", async () => {
|
|
634
656
|
writeWranglerToml({
|
|
635
657
|
main: "index.js",
|
|
636
658
|
});
|
|
637
659
|
fs.writeFileSync("index.js", `export default {};`);
|
|
638
660
|
await runWrangler("dev");
|
|
639
|
-
expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("
|
|
661
|
+
expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("0.0.0.0");
|
|
640
662
|
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
641
663
|
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
642
664
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
@@ -849,7 +871,7 @@ describe("wrangler dev", () => {
|
|
|
849
871
|
});
|
|
850
872
|
fs.writeFileSync("index.js", `export default {};`);
|
|
851
873
|
await runWrangler("dev");
|
|
852
|
-
expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("
|
|
874
|
+
expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("0.0.0.0");
|
|
853
875
|
expect(std.out).toMatchInlineSnapshot(`
|
|
854
876
|
"Your worker has access to the following bindings:
|
|
855
877
|
- Durable Objects:
|
|
@@ -983,7 +1005,7 @@ describe("wrangler dev", () => {
|
|
|
983
1005
|
--compatibility-date Date to use for compatibility checks [string]
|
|
984
1006
|
--compatibility-flags, --compatibility-flag Flags to use for compatibility checks [array]
|
|
985
1007
|
--latest Use the latest version of the worker runtime [boolean] [default: true]
|
|
986
|
-
--ip IP address to listen on
|
|
1008
|
+
--ip IP address to listen on [string] [default: \\"0.0.0.0\\"]
|
|
987
1009
|
--port Port to listen on [number]
|
|
988
1010
|
--inspector-port Port for devtools to connect to [number]
|
|
989
1011
|
--routes, --route Routes to upload [array]
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import process from "node:process";
|
|
4
2
|
import { setup } from "create-cloudflare";
|
|
5
3
|
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
6
4
|
import { mockConfirm, clearConfirmMocks } from "./helpers/mock-dialogs";
|
|
@@ -73,7 +71,7 @@ describe("generate", () => {
|
|
|
73
71
|
).resolves.toBeUndefined();
|
|
74
72
|
|
|
75
73
|
expect(createCloudflareMock).lastCalledWith(
|
|
76
|
-
|
|
74
|
+
"my-worker-1",
|
|
77
75
|
"some-template",
|
|
78
76
|
{ debug: false, force: false, init: true }
|
|
79
77
|
);
|
|
@@ -85,7 +83,7 @@ describe("generate", () => {
|
|
|
85
83
|
).resolves.toBeUndefined();
|
|
86
84
|
|
|
87
85
|
expect(createCloudflareMock).lastCalledWith(
|
|
88
|
-
|
|
86
|
+
"my-worker-2",
|
|
89
87
|
"some-template",
|
|
90
88
|
{ debug: false, force: false, init: true }
|
|
91
89
|
);
|
|
@@ -183,6 +183,7 @@ export function unsetAllMocks() {
|
|
|
183
183
|
|
|
184
184
|
const kvGetMocks = new Map<string, string | Buffer>();
|
|
185
185
|
const r2GetMocks = new Map<string, string | undefined>();
|
|
186
|
+
const dashScriptMocks = new Map<string, string | undefined>();
|
|
186
187
|
|
|
187
188
|
/**
|
|
188
189
|
* @mocked typeof fetchKVGetValue
|
|
@@ -217,7 +218,7 @@ export async function mockFetchR2Objects(
|
|
|
217
218
|
bodyInit: {
|
|
218
219
|
body: BodyInit | Readable;
|
|
219
220
|
headers: HeadersInit | undefined;
|
|
220
|
-
method: "PUT" | "GET";
|
|
221
|
+
method: "PUT" | "GET" | "DELETE";
|
|
221
222
|
}
|
|
222
223
|
): Promise<Response> {
|
|
223
224
|
/**
|
|
@@ -234,7 +235,7 @@ export async function mockFetchR2Objects(
|
|
|
234
235
|
|
|
235
236
|
return new Response(value);
|
|
236
237
|
}
|
|
237
|
-
throw new Error(`no
|
|
238
|
+
throw new Error(`no mock found for \`r2 object\` - ${resource}`);
|
|
238
239
|
}
|
|
239
240
|
|
|
240
241
|
/**
|
|
@@ -260,4 +261,36 @@ export function setMockFetchR2Objects({
|
|
|
260
261
|
export function unsetSpecialMockFns() {
|
|
261
262
|
kvGetMocks.clear();
|
|
262
263
|
r2GetMocks.clear();
|
|
264
|
+
dashScriptMocks.clear();
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* @mocked typeof fetchDashScript
|
|
269
|
+
* multipart/form-data is the response for modules and raw text for the Script endpoint.
|
|
270
|
+
*/
|
|
271
|
+
export async function mockFetchDashScript(resource: string): Promise<string> {
|
|
272
|
+
if (dashScriptMocks.has(resource)) {
|
|
273
|
+
const value = dashScriptMocks.get(resource) ?? "";
|
|
274
|
+
|
|
275
|
+
return value;
|
|
276
|
+
}
|
|
277
|
+
throw new Error(`no mock found for \`init from-dash\` - ${resource}`);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Mock setter for usage within test blocks, companion helper to `mockFetchDashScript`
|
|
282
|
+
*/
|
|
283
|
+
export function setMockFetchDashScript({
|
|
284
|
+
accountId,
|
|
285
|
+
fromDashScriptName,
|
|
286
|
+
mockResponse,
|
|
287
|
+
}: {
|
|
288
|
+
accountId: string;
|
|
289
|
+
fromDashScriptName: string;
|
|
290
|
+
mockResponse?: string;
|
|
291
|
+
}) {
|
|
292
|
+
dashScriptMocks.set(
|
|
293
|
+
`/accounts/${accountId}/workers/scripts/${fromDashScriptName}`,
|
|
294
|
+
mockResponse
|
|
295
|
+
);
|
|
263
296
|
}
|