wrangler 2.0.23 → 2.0.26
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/README.md +20 -2
- package/bin/wrangler.js +1 -1
- package/miniflare-dist/index.mjs +235 -47
- package/package.json +11 -6
- package/src/__tests__/configuration.test.ts +89 -17
- package/src/__tests__/dev.test.tsx +29 -4
- package/src/__tests__/generate.test.ts +93 -0
- package/src/__tests__/helpers/mock-cfetch.ts +87 -2
- package/src/__tests__/index.test.ts +10 -27
- package/src/__tests__/init.test.ts +537 -359
- package/src/__tests__/jest.setup.ts +34 -1
- package/src/__tests__/kv.test.ts +2 -2
- package/src/__tests__/metrics.test.ts +5 -0
- package/src/__tests__/pages.test.ts +14 -0
- package/src/__tests__/publish.test.ts +497 -254
- package/src/__tests__/r2.test.ts +173 -71
- package/src/__tests__/tail.test.ts +112 -42
- package/src/__tests__/user.test.ts +1 -0
- package/src/__tests__/validate-dev-props.test.ts +56 -0
- package/src/__tests__/whoami.test.tsx +60 -1
- package/src/api/dev.ts +7 -0
- package/src/bundle.ts +279 -44
- package/src/cfetch/internal.ts +73 -2
- package/src/config/config.ts +8 -3
- package/src/config/environment.ts +40 -8
- package/src/config/index.ts +13 -0
- package/src/config/validation.ts +102 -8
- package/src/create-worker-upload-form.ts +25 -0
- package/src/dev/dev.tsx +121 -28
- package/src/dev/local.tsx +88 -14
- package/src/dev/remote.tsx +39 -8
- package/src/dev/use-esbuild.ts +28 -0
- package/src/dev/validate-dev-props.ts +31 -0
- package/src/dev-registry.tsx +160 -0
- package/src/dev.tsx +107 -80
- package/src/generate.ts +112 -14
- package/src/index.tsx +212 -4
- package/src/init.ts +111 -38
- package/src/inspect.ts +90 -5
- package/src/metrics/index.ts +1 -0
- package/src/metrics/metrics-dispatcher.ts +1 -0
- package/src/metrics/metrics-usage-headers.ts +24 -0
- package/src/metrics/send-event.ts +2 -2
- package/src/miniflare-cli/assets.ts +27 -16
- package/src/miniflare-cli/index.ts +124 -2
- package/src/module-collection.ts +3 -3
- package/src/pages/build.tsx +75 -41
- package/src/pages/constants.ts +5 -0
- package/src/pages/deployments.tsx +10 -10
- package/src/pages/dev.tsx +177 -52
- 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 +76 -23
- package/src/pages/types.ts +9 -0
- package/src/pages/upload.tsx +38 -21
- package/src/publish.ts +126 -112
- package/src/r2.ts +81 -0
- 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 +20 -2
- package/src/whoami.tsx +79 -1
- package/src/worker.ts +12 -0
- package/templates/first-party-worker-module-facade.ts +18 -0
- package/templates/format-dev-errors.ts +32 -0
- package/templates/pages-template-plugin.ts +16 -4
- package/templates/pages-template-worker.ts +16 -5
- package/templates/{static-asset-facade.js → serve-static-assets.ts} +21 -7
- package/templates/service-bindings-module-facade.js +54 -0
- package/templates/service-bindings-sw-facade.js +42 -0
- package/wrangler-dist/cli.d.ts +7 -0
- package/wrangler-dist/cli.js +40851 -15332
package/README.md
CHANGED
|
@@ -39,11 +39,25 @@ npm run deploy
|
|
|
39
39
|
$ npm install wrangler --save-dev
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
## Configuration:
|
|
43
|
+
|
|
44
|
+
Wrangler is configured via a `wrangler.toml` file in the project root. When utilizing the `wrangler init` command, a `wrangler.toml` file will be created for you.
|
|
45
|
+
|
|
46
|
+
example:
|
|
47
|
+
|
|
48
|
+
```toml
|
|
49
|
+
main = "./src/index.ts" # init w/ TypeScript
|
|
50
|
+
name = "my-worker"
|
|
51
|
+
compatibility_date = "YYY-MM-DD"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
for more detailed information about configuration, see the [documentation](https://developers.cloudflare.com/workers/cli-wrangler/configuration)
|
|
55
|
+
|
|
42
56
|
## Commands
|
|
43
57
|
|
|
44
58
|
### `wrangler init [name]`
|
|
45
59
|
|
|
46
|
-
Creates a Worker project. For details on configuration keys and values, refer to the [documentation](https://developers.cloudflare.com/workers/
|
|
60
|
+
Creates a Worker project. For details on configuration keys and values, refer to the [documentation](https://developers.cloudflare.com/workers/wrangler/commands/#init).
|
|
47
61
|
|
|
48
62
|
### `wrangler dev`
|
|
49
63
|
|
|
@@ -67,4 +81,8 @@ For more commands and options, refer to the [documentation](https://developers.c
|
|
|
67
81
|
|
|
68
82
|
## Documentation
|
|
69
83
|
|
|
70
|
-
For the latest Wrangler documentation, [click here](https://
|
|
84
|
+
For the latest Wrangler documentation, [click here](https://developers.cloudflare.com/workers/wrangler/).
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
```
|
package/bin/wrangler.js
CHANGED
|
@@ -35,7 +35,7 @@ Consider using a Node.js version manager such as https://volta.sh/ or https://gi
|
|
|
35
35
|
// - maybe we can generate a certificate that concatenates with ours?
|
|
36
36
|
//
|
|
37
37
|
// I do think it'll be rare that someone wants to add a cert AND
|
|
38
|
-
// use
|
|
38
|
+
// use Cloudflare WARP, but let's wait till the situation actually
|
|
39
39
|
// arises before we do anything about it
|
|
40
40
|
} else {
|
|
41
41
|
const osTempDir = os.tmpdir();
|
package/miniflare-dist/index.mjs
CHANGED
|
@@ -22,7 +22,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
22
22
|
}
|
|
23
23
|
return to;
|
|
24
24
|
};
|
|
25
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
26
29
|
|
|
27
30
|
// ../../node_modules/mime/Mime.js
|
|
28
31
|
var require_Mime = __commonJS({
|
|
@@ -50,7 +53,9 @@ var require_Mime = __commonJS({
|
|
|
50
53
|
continue;
|
|
51
54
|
}
|
|
52
55
|
if (!force && ext in this._types) {
|
|
53
|
-
throw new Error(
|
|
56
|
+
throw new Error(
|
|
57
|
+
'Attempt to change mapping for "' + ext + '" extension from "' + this._types[ext] + '" to "' + type + '". Pass `force=true` to allow this, otherwise remove "' + ext + '" from the list of extensions for "' + type + '".'
|
|
58
|
+
);
|
|
54
59
|
}
|
|
55
60
|
this._types[ext] = type;
|
|
56
61
|
}
|
|
@@ -100,7 +105,18 @@ var require_mime = __commonJS({
|
|
|
100
105
|
});
|
|
101
106
|
|
|
102
107
|
// src/miniflare-cli/index.ts
|
|
103
|
-
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";
|
|
104
120
|
|
|
105
121
|
// ../../node_modules/yargs/lib/platform-shims/esm.mjs
|
|
106
122
|
import { notStrictEqual, strictEqual } from "assert";
|
|
@@ -4909,6 +4925,14 @@ function isYargsInstance(y) {
|
|
|
4909
4925
|
var Yargs = YargsFactory(esm_default);
|
|
4910
4926
|
var yargs_default = Yargs;
|
|
4911
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
|
+
|
|
4912
4936
|
// src/miniflare-cli/assets.ts
|
|
4913
4937
|
var import_mime = __toESM(require_mime());
|
|
4914
4938
|
import { existsSync, lstatSync, readFileSync as readFileSync4 } from "node:fs";
|
|
@@ -4935,7 +4959,10 @@ async function generateASSETSBinding(options) {
|
|
|
4935
4959
|
return await assetsFetch(request);
|
|
4936
4960
|
} catch (thrown) {
|
|
4937
4961
|
options.log.error(new Error(`Could not serve static asset: ${thrown}`));
|
|
4938
|
-
return new Response(
|
|
4962
|
+
return new Response(
|
|
4963
|
+
`[wrangler] Could not serve static asset: ${thrown}`,
|
|
4964
|
+
{ status: 502 }
|
|
4965
|
+
);
|
|
4939
4966
|
}
|
|
4940
4967
|
}
|
|
4941
4968
|
};
|
|
@@ -4955,7 +4982,9 @@ function generateRulesMatcher(rules, replacerFn = (match) => match) {
|
|
|
4955
4982
|
const compiledRules = Object.entries(rules).map(([rule, match]) => {
|
|
4956
4983
|
const crossHost = rule.startsWith("https://");
|
|
4957
4984
|
rule = rule.split("*").map(escapeRegex).join("(?<splat>.*)");
|
|
4958
|
-
const host_matches = rule.matchAll(
|
|
4985
|
+
const host_matches = rule.matchAll(
|
|
4986
|
+
/(?<=^https:\\\/\\\/[^/]*?):([^\\]+)(?=\\)/g
|
|
4987
|
+
);
|
|
4959
4988
|
for (const hostMatch of host_matches) {
|
|
4960
4989
|
rule = rule.split(hostMatch[0]).join(`(?<${hostMatch[1]}>[^/.]+)`);
|
|
4961
4990
|
}
|
|
@@ -5016,10 +5045,15 @@ function generateHeadersMatcher(headersFile) {
|
|
|
5016
5045
|
if (rule && Object.keys(rule.headers).length > 0) {
|
|
5017
5046
|
rules[rule.path] = rule.headers;
|
|
5018
5047
|
}
|
|
5019
|
-
const rulesMatcher = generateRulesMatcher(
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5048
|
+
const rulesMatcher = generateRulesMatcher(
|
|
5049
|
+
rules,
|
|
5050
|
+
(match, replacements) => Object.fromEntries(
|
|
5051
|
+
Object.entries(match).map(([name, value]) => [
|
|
5052
|
+
name,
|
|
5053
|
+
replacer(value, replacements)
|
|
5054
|
+
])
|
|
5055
|
+
)
|
|
5056
|
+
);
|
|
5023
5057
|
return (request) => {
|
|
5024
5058
|
const matches = rulesMatcher({
|
|
5025
5059
|
request
|
|
@@ -5035,17 +5069,22 @@ function generateRedirectsMatcher(redirectsFile) {
|
|
|
5035
5069
|
if (existsSync(redirectsFile)) {
|
|
5036
5070
|
const contents = readFileSync4(redirectsFile).toString();
|
|
5037
5071
|
const lines = contents.split("\n").map((line) => line.trim()).filter((line) => !line.startsWith("#") && line !== "");
|
|
5038
|
-
const rules = Object.fromEntries(
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5072
|
+
const rules = Object.fromEntries(
|
|
5073
|
+
lines.map((line) => line.split(" ")).filter((tokens) => tokens.length === 2 || tokens.length === 3).map((tokens) => {
|
|
5074
|
+
const from = validateURL(tokens[0], true, false, false);
|
|
5075
|
+
const to = validateURL(tokens[1], false, true, true);
|
|
5076
|
+
let status = parseInt(tokens[2]) || 302;
|
|
5077
|
+
status = [301, 302, 303, 307, 308].includes(status) ? status : void 0;
|
|
5078
|
+
return from && to && status ? [from, { to, status }] : void 0;
|
|
5079
|
+
}).filter((rule) => rule !== void 0)
|
|
5080
|
+
);
|
|
5081
|
+
const rulesMatcher = generateRulesMatcher(
|
|
5082
|
+
rules,
|
|
5083
|
+
({ status, to }, replacements) => ({
|
|
5084
|
+
status,
|
|
5085
|
+
to: replacer(to, replacements)
|
|
5086
|
+
})
|
|
5087
|
+
);
|
|
5049
5088
|
return (request) => {
|
|
5050
5089
|
const match = rulesMatcher({
|
|
5051
5090
|
request
|
|
@@ -5068,7 +5107,11 @@ function validateURL(token, onlyRelative = false, includeSearch = false, include
|
|
|
5068
5107
|
if (host && host.groups && host.groups.host) {
|
|
5069
5108
|
if (onlyRelative)
|
|
5070
5109
|
return;
|
|
5071
|
-
return `https://${host.groups.host}${extractPathname(
|
|
5110
|
+
return `https://${host.groups.host}${extractPathname(
|
|
5111
|
+
host.groups.path,
|
|
5112
|
+
includeSearch,
|
|
5113
|
+
includeHash
|
|
5114
|
+
)}`;
|
|
5072
5115
|
} else {
|
|
5073
5116
|
if (!token.startsWith("/") && onlyRelative)
|
|
5074
5117
|
token = `/${token}`;
|
|
@@ -5123,6 +5166,11 @@ async function generateAssetsFetch(directory, log) {
|
|
|
5123
5166
|
};
|
|
5124
5167
|
const generateResponse = (request) => {
|
|
5125
5168
|
const url = new URL(request.url);
|
|
5169
|
+
let assetName = url.pathname;
|
|
5170
|
+
try {
|
|
5171
|
+
assetName = decodeURIComponent(url.pathname);
|
|
5172
|
+
} catch {
|
|
5173
|
+
}
|
|
5126
5174
|
const deconstructedResponse = {
|
|
5127
5175
|
status: 200,
|
|
5128
5176
|
headers: new Headers(),
|
|
@@ -5152,70 +5200,108 @@ async function generateAssetsFetch(directory, log) {
|
|
|
5152
5200
|
return deconstructedResponse;
|
|
5153
5201
|
}
|
|
5154
5202
|
const notFound = () => {
|
|
5155
|
-
let cwd =
|
|
5203
|
+
let cwd = assetName;
|
|
5156
5204
|
while (cwd) {
|
|
5157
5205
|
cwd = cwd.slice(0, cwd.lastIndexOf("/"));
|
|
5158
5206
|
if (asset = getAsset(`${cwd}/404.html`)) {
|
|
5159
5207
|
deconstructedResponse.status = 404;
|
|
5160
5208
|
deconstructedResponse.body = serveAsset(asset);
|
|
5161
|
-
deconstructedResponse.headers.set(
|
|
5209
|
+
deconstructedResponse.headers.set(
|
|
5210
|
+
"Content-Type",
|
|
5211
|
+
(0, import_mime.getType)(asset) || "application/octet-stream"
|
|
5212
|
+
);
|
|
5162
5213
|
return deconstructedResponse;
|
|
5163
5214
|
}
|
|
5164
5215
|
}
|
|
5165
5216
|
if (asset = getAsset(`/index.html`)) {
|
|
5166
5217
|
deconstructedResponse.body = serveAsset(asset);
|
|
5167
|
-
deconstructedResponse.headers.set(
|
|
5218
|
+
deconstructedResponse.headers.set(
|
|
5219
|
+
"Content-Type",
|
|
5220
|
+
(0, import_mime.getType)(asset) || "application/octet-stream"
|
|
5221
|
+
);
|
|
5168
5222
|
return deconstructedResponse;
|
|
5169
5223
|
}
|
|
5170
5224
|
deconstructedResponse.status = 404;
|
|
5171
5225
|
return deconstructedResponse;
|
|
5172
5226
|
};
|
|
5173
5227
|
let asset;
|
|
5174
|
-
if (
|
|
5175
|
-
if (asset = getAsset(`${
|
|
5228
|
+
if (assetName.endsWith("/")) {
|
|
5229
|
+
if (asset = getAsset(`${assetName}/index.html`)) {
|
|
5176
5230
|
deconstructedResponse.body = serveAsset(asset);
|
|
5177
|
-
deconstructedResponse.headers.set(
|
|
5231
|
+
deconstructedResponse.headers.set(
|
|
5232
|
+
"Content-Type",
|
|
5233
|
+
(0, import_mime.getType)(asset) || "application/octet-stream"
|
|
5234
|
+
);
|
|
5178
5235
|
return deconstructedResponse;
|
|
5179
|
-
} else if (asset = getAsset(`${
|
|
5236
|
+
} else if (asset = getAsset(`${assetName.replace(/\/$/, ".html")}`)) {
|
|
5180
5237
|
deconstructedResponse.status = 301;
|
|
5181
|
-
deconstructedResponse.headers.set(
|
|
5238
|
+
deconstructedResponse.headers.set(
|
|
5239
|
+
"Location",
|
|
5240
|
+
`${assetName.slice(0, -1)}${url.search}`
|
|
5241
|
+
);
|
|
5182
5242
|
return deconstructedResponse;
|
|
5183
5243
|
}
|
|
5184
5244
|
}
|
|
5185
|
-
if (
|
|
5245
|
+
if (assetName.endsWith("/index")) {
|
|
5186
5246
|
deconstructedResponse.status = 301;
|
|
5187
|
-
deconstructedResponse.headers.set(
|
|
5247
|
+
deconstructedResponse.headers.set(
|
|
5248
|
+
"Location",
|
|
5249
|
+
`${assetName.slice(0, -"index".length)}${url.search}`
|
|
5250
|
+
);
|
|
5188
5251
|
return deconstructedResponse;
|
|
5189
5252
|
}
|
|
5190
|
-
if (asset = getAsset(
|
|
5191
|
-
if (
|
|
5192
|
-
const extensionlessPath =
|
|
5253
|
+
if (asset = getAsset(assetName)) {
|
|
5254
|
+
if (assetName.endsWith(".html")) {
|
|
5255
|
+
const extensionlessPath = assetName.slice(0, -".html".length);
|
|
5193
5256
|
if (getAsset(extensionlessPath) || extensionlessPath === "/") {
|
|
5194
5257
|
deconstructedResponse.body = serveAsset(asset);
|
|
5195
|
-
deconstructedResponse.headers.set(
|
|
5258
|
+
deconstructedResponse.headers.set(
|
|
5259
|
+
"Content-Type",
|
|
5260
|
+
(0, import_mime.getType)(asset) || "application/octet-stream"
|
|
5261
|
+
);
|
|
5196
5262
|
return deconstructedResponse;
|
|
5197
5263
|
} else {
|
|
5198
5264
|
deconstructedResponse.status = 301;
|
|
5199
|
-
deconstructedResponse.headers.set(
|
|
5265
|
+
deconstructedResponse.headers.set(
|
|
5266
|
+
"Location",
|
|
5267
|
+
`${extensionlessPath}${url.search}`
|
|
5268
|
+
);
|
|
5200
5269
|
return deconstructedResponse;
|
|
5201
5270
|
}
|
|
5202
5271
|
} else {
|
|
5203
5272
|
deconstructedResponse.body = serveAsset(asset);
|
|
5204
|
-
deconstructedResponse.headers.set(
|
|
5273
|
+
deconstructedResponse.headers.set(
|
|
5274
|
+
"Content-Type",
|
|
5275
|
+
(0, import_mime.getType)(asset) || "application/octet-stream"
|
|
5276
|
+
);
|
|
5277
|
+
return deconstructedResponse;
|
|
5278
|
+
}
|
|
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
|
+
);
|
|
5205
5286
|
return deconstructedResponse;
|
|
5206
5287
|
}
|
|
5207
|
-
} else if (hasFileExtension(url.pathname)) {
|
|
5208
5288
|
notFound();
|
|
5209
5289
|
return deconstructedResponse;
|
|
5210
5290
|
}
|
|
5211
|
-
if (asset = getAsset(`${
|
|
5291
|
+
if (asset = getAsset(`${assetName}.html`)) {
|
|
5212
5292
|
deconstructedResponse.body = serveAsset(asset);
|
|
5213
|
-
deconstructedResponse.headers.set(
|
|
5293
|
+
deconstructedResponse.headers.set(
|
|
5294
|
+
"Content-Type",
|
|
5295
|
+
(0, import_mime.getType)(asset) || "application/octet-stream"
|
|
5296
|
+
);
|
|
5214
5297
|
return deconstructedResponse;
|
|
5215
5298
|
}
|
|
5216
|
-
if (asset = getAsset(`${
|
|
5299
|
+
if (asset = getAsset(`${assetName}/index.html`)) {
|
|
5217
5300
|
deconstructedResponse.status = 301;
|
|
5218
|
-
deconstructedResponse.headers.set(
|
|
5301
|
+
deconstructedResponse.headers.set(
|
|
5302
|
+
"Location",
|
|
5303
|
+
`${assetName}/${url.search}`
|
|
5304
|
+
);
|
|
5219
5305
|
return deconstructedResponse;
|
|
5220
5306
|
} else {
|
|
5221
5307
|
notFound();
|
|
@@ -5257,13 +5343,17 @@ async function generateAssetsFetch(directory, log) {
|
|
|
5257
5343
|
};
|
|
5258
5344
|
}
|
|
5259
5345
|
var invalidAssetsFetch = () => {
|
|
5260
|
-
throw new Error(
|
|
5346
|
+
throw new Error(
|
|
5347
|
+
"Trying to fetch assets directly when there is no `directory` option specified."
|
|
5348
|
+
);
|
|
5261
5349
|
};
|
|
5262
5350
|
|
|
5263
5351
|
// src/miniflare-cli/enum-keys.ts
|
|
5264
5352
|
var enumObject = (e) => {
|
|
5265
5353
|
const copy = { ...e };
|
|
5266
|
-
Object.values(e).forEach(
|
|
5354
|
+
Object.values(e).forEach(
|
|
5355
|
+
(value) => typeof value === "number" && delete copy[value]
|
|
5356
|
+
);
|
|
5267
5357
|
return copy;
|
|
5268
5358
|
};
|
|
5269
5359
|
var enumKeys = (e) => {
|
|
@@ -5311,12 +5401,53 @@ async function main() {
|
|
|
5311
5401
|
if (logLevel > LogLevel.INFO) {
|
|
5312
5402
|
console.log("OPTIONS:\n", JSON.stringify(config, null, 2));
|
|
5313
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
|
+
};
|
|
5314
5439
|
let mf;
|
|
5440
|
+
let durableObjectsMf = void 0;
|
|
5441
|
+
let durableObjectsMfPort = void 0;
|
|
5315
5442
|
try {
|
|
5316
5443
|
if (args._[1]) {
|
|
5317
|
-
const opts = JSON.parse(
|
|
5444
|
+
const opts = JSON.parse(
|
|
5445
|
+
args._[1]
|
|
5446
|
+
);
|
|
5318
5447
|
if (isNaN(opts.proxyPort || NaN) && !opts.directory) {
|
|
5319
|
-
throw new Error(
|
|
5448
|
+
throw new Error(
|
|
5449
|
+
"MiniflareCLIOptions: built in service bindings set to true, but no port or directory provided"
|
|
5450
|
+
);
|
|
5320
5451
|
}
|
|
5321
5452
|
const options = {
|
|
5322
5453
|
log: config.log,
|
|
@@ -5331,11 +5462,68 @@ async function main() {
|
|
|
5331
5462
|
mf = new Miniflare(config);
|
|
5332
5463
|
await mf.startServer();
|
|
5333
5464
|
await mf.startScheduler();
|
|
5334
|
-
|
|
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
|
+
);
|
|
5335
5522
|
} catch (e) {
|
|
5336
5523
|
mf?.log.error(e);
|
|
5337
5524
|
process.exitCode = 1;
|
|
5338
5525
|
await mf?.dispose();
|
|
5526
|
+
await durableObjectsMf?.dispose();
|
|
5339
5527
|
}
|
|
5340
5528
|
}
|
|
5341
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.26",
|
|
4
4
|
"description": "Command-line interface for all things Cloudflare Workers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wrangler",
|
|
@@ -52,16 +52,16 @@
|
|
|
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
|
-
"test-watch": "npm run test -- --runInBand --testTimeout=50000 --watch"
|
|
61
|
+
"test-watch": "npm run test -- --runInBand --testTimeout=50000 --watch",
|
|
62
|
+
"test:ci": "npm run test -- --verbose=true --coverage"
|
|
62
63
|
},
|
|
63
64
|
"jest": {
|
|
64
|
-
"collectCoverage": true,
|
|
65
65
|
"coverageReporters": [
|
|
66
66
|
"json",
|
|
67
67
|
"html",
|
|
@@ -96,17 +96,19 @@
|
|
|
96
96
|
"@esbuild-plugins/node-modules-polyfill": "^0.1.4",
|
|
97
97
|
"blake3-wasm": "^2.1.5",
|
|
98
98
|
"chokidar": "^3.5.3",
|
|
99
|
-
"esbuild": "0.14.
|
|
99
|
+
"esbuild": "0.14.51",
|
|
100
100
|
"miniflare": "^2.6.0",
|
|
101
101
|
"nanoid": "^3.3.3",
|
|
102
102
|
"path-to-regexp": "^6.2.0",
|
|
103
103
|
"selfsigned": "^2.0.1",
|
|
104
|
+
"source-map": "^0.7.4",
|
|
104
105
|
"xxhash-wasm": "^1.0.1"
|
|
105
106
|
},
|
|
106
107
|
"devDependencies": {
|
|
107
108
|
"@iarna/toml": "^3.0.0",
|
|
108
109
|
"@microsoft/api-extractor": "^7.28.3",
|
|
109
110
|
"@types/command-exists": "^1.2.0",
|
|
111
|
+
"@types/express": "^4.17.13",
|
|
110
112
|
"@types/glob-to-regexp": "0.4.1",
|
|
111
113
|
"@types/mime": "^2.0.3",
|
|
112
114
|
"@types/prompts": "^2.0.14",
|
|
@@ -117,13 +119,16 @@
|
|
|
117
119
|
"@types/ws": "^8.5.3",
|
|
118
120
|
"@types/yargs": "^17.0.10",
|
|
119
121
|
"@webcontainer/env": "^1.0.1",
|
|
122
|
+
"body-parser": "^1.20.0",
|
|
120
123
|
"clipboardy": "^3.0.0",
|
|
121
124
|
"cmd-shim": "^4.1.0",
|
|
122
125
|
"command-exists": "^1.2.9",
|
|
123
126
|
"concurrently": "^7.2.2",
|
|
127
|
+
"create-cloudflare": "^1.0.0",
|
|
124
128
|
"devtools-protocol": "^0.0.955664",
|
|
125
129
|
"dotenv": "^16.0.0",
|
|
126
130
|
"execa": "^6.1.0",
|
|
131
|
+
"express": "^4.18.1",
|
|
127
132
|
"faye-websocket": "^0.11.4",
|
|
128
133
|
"finalhandler": "^1.2.0",
|
|
129
134
|
"find-up": "^6.3.0",
|