wrangler 0.0.0-e7cf0caa → 0.0.0-e87ad068
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 +167 -93
- package/package.json +6 -6
- package/src/__tests__/configuration.test.ts +218 -0
- package/src/__tests__/constellation.test.ts +371 -0
- package/src/__tests__/d1/migrate.test.ts +100 -0
- package/src/__tests__/index.test.ts +4 -2
- package/src/__tests__/init.test.ts +109 -3
- package/src/__tests__/mtls-certificates.test.ts +2 -1
- package/src/__tests__/pages/functions-build.test.ts +77 -0
- package/src/__tests__/pages-deployment-tail.test.ts +2 -0
- package/src/__tests__/publish.test.ts +646 -187
- package/src/__tests__/tail.test.ts +49 -7
- package/src/__tests__/tsconfig.tsbuildinfo +1 -1
- package/src/__tests__/unstableDev.test.ts +61 -0
- package/src/__tests__/user.test.ts +1 -1
- package/src/api/dev.ts +12 -0
- package/src/api/pages/create-worker-bundle-contents.ts +4 -0
- package/src/api/pages/publish.tsx +28 -12
- package/src/bundle.ts +58 -14
- package/src/cfetch/internal.ts +19 -14
- package/src/config/environment.ts +41 -0
- package/src/config/index.ts +21 -0
- package/src/config/validation.ts +182 -0
- package/src/constellation/createProject.tsx +51 -0
- package/src/constellation/deleteProject.ts +51 -0
- package/src/constellation/deleteProjectModel.ts +76 -0
- package/src/constellation/index.ts +75 -0
- package/src/constellation/listCatalog.tsx +35 -0
- package/src/constellation/listModel.tsx +49 -0
- package/src/constellation/listProject.tsx +28 -0
- package/src/constellation/listRuntime.tsx +28 -0
- package/src/constellation/options.ts +17 -0
- package/src/constellation/types.ts +17 -0
- package/src/constellation/uploadModel.tsx +84 -0
- package/src/constellation/utils.ts +90 -0
- package/src/create-worker-upload-form.ts +25 -0
- package/src/d1/backups.tsx +4 -4
- package/src/d1/constants.ts +3 -0
- package/src/d1/create.tsx +77 -43
- package/src/d1/delete.ts +1 -1
- package/src/d1/execute.tsx +27 -13
- package/src/d1/list.tsx +13 -11
- package/src/d1/migrations/apply.tsx +29 -6
- package/src/d1/migrations/helpers.ts +8 -9
- package/src/d1/types.ts +7 -0
- package/src/dev/dev.tsx +9 -2
- package/src/dev/local.tsx +52 -20
- package/src/dev/remote.tsx +4 -0
- package/src/dev/start-server.ts +64 -40
- package/src/dev/use-esbuild.ts +70 -43
- package/src/dev-registry.ts +11 -0
- package/src/dev.tsx +23 -6
- package/src/docs/helpers.ts +50 -0
- package/src/docs/index.ts +25 -68
- package/src/entry.ts +8 -1
- package/src/environment-variables/factory.ts +2 -1
- package/src/generate/index.ts +5 -0
- package/src/index.ts +12 -1
- package/src/init.ts +52 -10
- package/src/inspect.ts +107 -6
- package/src/kv/helpers.ts +7 -4
- package/src/logger.ts +5 -1
- package/src/miniflare-cli/index.ts +2 -2
- package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -1
- package/src/module-collection.ts +1 -1
- package/src/pages/build.ts +30 -17
- package/src/pages/dev.ts +51 -8
- package/src/pages/functions/buildPlugin.ts +1 -0
- package/src/pages/functions/buildWorker.ts +92 -2
- package/src/pages/functions/tsconfig.tsbuildinfo +1 -1
- package/src/publish/publish.ts +9 -1
- package/src/secret/index.ts +4 -0
- package/src/sites.ts +164 -52
- package/src/tail/createTail.ts +9 -0
- package/src/tail/printing.ts +12 -0
- package/src/traverse-module-graph.ts +2 -1
- package/src/type-generation.ts +6 -0
- package/src/user/user.ts +1 -0
- package/src/utils/render.ts +1 -1
- package/src/worker.ts +26 -0
- package/templates/__tests__/tsconfig.tsbuildinfo +1 -1
- package/templates/pages-dev-util.ts +4 -1
- package/templates/tsconfig.tsbuildinfo +1 -1
- package/wrangler-dist/cli.d.ts +78 -2
- package/wrangler-dist/cli.js +65057 -63883
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { fetch } from "undici";
|
|
2
|
+
import {
|
|
3
|
+
stopWorkerRegistry,
|
|
4
|
+
registerWorker,
|
|
5
|
+
startWorkerRegistry,
|
|
6
|
+
} from "../dev-registry";
|
|
7
|
+
|
|
8
|
+
jest.unmock("undici");
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Sometimes the devRegistry killed by some reason, the register worker will to restart it.
|
|
12
|
+
*/
|
|
13
|
+
describe("unstable devRegistry testing", () => {
|
|
14
|
+
afterAll(async () => {
|
|
15
|
+
await stopWorkerRegistry();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should start the devRegistry if the devRegistry not start", async () => {
|
|
19
|
+
await registerWorker("test", {
|
|
20
|
+
port: 6789,
|
|
21
|
+
protocol: "http",
|
|
22
|
+
host: "localhost",
|
|
23
|
+
mode: "local",
|
|
24
|
+
durableObjects: [{ name: "testing", className: "testing" }],
|
|
25
|
+
});
|
|
26
|
+
const resp = await fetch("http://localhost:6284/workers");
|
|
27
|
+
if (resp) {
|
|
28
|
+
const parsedResp = (await resp.json()) as {
|
|
29
|
+
test: unknown;
|
|
30
|
+
};
|
|
31
|
+
expect(parsedResp.test).toBeTruthy();
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should not restart the devRegistry if the devRegistry already start", async () => {
|
|
36
|
+
await startWorkerRegistry();
|
|
37
|
+
|
|
38
|
+
await fetch("http://localhost:6284/workers/init", {
|
|
39
|
+
method: "POST",
|
|
40
|
+
body: JSON.stringify({}),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
await registerWorker("test", {
|
|
44
|
+
port: 6789,
|
|
45
|
+
protocol: "http",
|
|
46
|
+
host: "localhost",
|
|
47
|
+
mode: "local",
|
|
48
|
+
durableObjects: [{ name: "testing", className: "testing" }],
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const resp = await fetch("http://localhost:6284/workers");
|
|
52
|
+
if (resp) {
|
|
53
|
+
const parsedResp = (await resp.json()) as {
|
|
54
|
+
test: unknown;
|
|
55
|
+
init: unknown;
|
|
56
|
+
};
|
|
57
|
+
expect(parsedResp.init).toBeTruthy();
|
|
58
|
+
expect(parsedResp.test).toBeTruthy();
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -60,7 +60,7 @@ describe("User", () => {
|
|
|
60
60
|
expect(counter).toBe(1);
|
|
61
61
|
expect(std.out).toMatchInlineSnapshot(`
|
|
62
62
|
"Attempting to login via OAuth...
|
|
63
|
-
Opening a link in your default browser: https://dash.cloudflare.com/oauth2/auth?response_type=code&client_id=54d11594-84e4-41aa-b438-e81b8fa78ee7&redirect_uri=http%3A%2F%2Flocalhost%3A8976%2Foauth%2Fcallback&scope=account%3Aread%20user%3Aread%20workers%3Awrite%20workers_kv%3Awrite%20workers_routes%3Awrite%20workers_scripts%3Awrite%20workers_tail%3Aread%20d1%3Awrite%20pages%3Awrite%20zone%3Aread%20ssl_certs%3Awrite%20offline_access&state=MOCK_STATE_PARAM&code_challenge=MOCK_CODE_CHALLENGE&code_challenge_method=S256
|
|
63
|
+
Opening a link in your default browser: https://dash.cloudflare.com/oauth2/auth?response_type=code&client_id=54d11594-84e4-41aa-b438-e81b8fa78ee7&redirect_uri=http%3A%2F%2Flocalhost%3A8976%2Foauth%2Fcallback&scope=account%3Aread%20user%3Aread%20workers%3Awrite%20workers_kv%3Awrite%20workers_routes%3Awrite%20workers_scripts%3Awrite%20workers_tail%3Aread%20d1%3Awrite%20pages%3Awrite%20zone%3Aread%20ssl_certs%3Awrite%20constellation%3Awrite%20offline_access&state=MOCK_STATE_PARAM&code_challenge=MOCK_CODE_CHALLENGE&code_challenge_method=S256
|
|
64
64
|
Successfully logged in."
|
|
65
65
|
`);
|
|
66
66
|
expect(readAuthConfigFile()).toEqual<UserAuthConfig>({
|
package/src/api/dev.ts
CHANGED
|
@@ -3,7 +3,9 @@ import { startApiDev, startDev } from "../dev";
|
|
|
3
3
|
import { logger } from "../logger";
|
|
4
4
|
|
|
5
5
|
import type { Environment } from "../config";
|
|
6
|
+
import type { Rule } from "../config/environment";
|
|
6
7
|
import type { EnablePagesAssetsServiceBindingOptions } from "../miniflare-cli/types";
|
|
8
|
+
import type { CfModule } from "../worker";
|
|
7
9
|
import type { RequestInit, Response, RequestInfo } from "undici";
|
|
8
10
|
|
|
9
11
|
export interface UnstableDevOptions {
|
|
@@ -42,11 +44,15 @@ export interface UnstableDevOptions {
|
|
|
42
44
|
bucket_name: string;
|
|
43
45
|
preview_bucket_name?: string;
|
|
44
46
|
}[];
|
|
47
|
+
moduleRoot?: string;
|
|
48
|
+
rules?: Rule[];
|
|
45
49
|
logLevel?: "none" | "info" | "error" | "log" | "warn" | "debug"; // Specify logging level [choices: "debug", "info", "log", "warn", "error", "none"] [default: "log"]
|
|
46
50
|
inspect?: boolean;
|
|
47
51
|
local?: boolean;
|
|
48
52
|
accountId?: string;
|
|
49
53
|
experimental?: {
|
|
54
|
+
processEntrypoint?: boolean;
|
|
55
|
+
additionalModules?: CfModule[];
|
|
50
56
|
d1Databases?: Environment["d1_databases"];
|
|
51
57
|
disableExperimentalWarning?: boolean; // Disables wrangler's warning when unstable APIs are used.
|
|
52
58
|
disableDevRegistry?: boolean; // Disables wrangler's support multi-worker setups. May reduce flakiness when used in tests in CI.
|
|
@@ -92,6 +98,8 @@ export async function unstable_dev(
|
|
|
92
98
|
const {
|
|
93
99
|
// there are two types of "experimental" options:
|
|
94
100
|
// 1. options to unstable_dev that we're still testing or are unsure of
|
|
101
|
+
processEntrypoint = false,
|
|
102
|
+
additionalModules,
|
|
95
103
|
disableDevRegistry,
|
|
96
104
|
disableExperimentalWarning,
|
|
97
105
|
forceLocal,
|
|
@@ -150,6 +158,8 @@ export async function unstable_dev(
|
|
|
150
158
|
},
|
|
151
159
|
config: options?.config,
|
|
152
160
|
env: options?.env,
|
|
161
|
+
processEntrypoint,
|
|
162
|
+
additionalModules,
|
|
153
163
|
bundle: options?.bundle,
|
|
154
164
|
compatibilityDate: options?.compatibilityDate,
|
|
155
165
|
compatibilityFlags: options?.compatibilityFlags,
|
|
@@ -240,6 +250,8 @@ export async function unstable_dev(
|
|
|
240
250
|
},
|
|
241
251
|
config: options?.config,
|
|
242
252
|
env: options?.env,
|
|
253
|
+
processEntrypoint,
|
|
254
|
+
additionalModules,
|
|
243
255
|
bundle: options?.bundle,
|
|
244
256
|
compatibilityDate: options?.compatibilityDate,
|
|
245
257
|
compatibilityFlags: options?.compatibilityFlags,
|
|
@@ -52,11 +52,13 @@ function createWorkerBundleFormData(workerBundle: BundleResult): FormData {
|
|
|
52
52
|
send_email: undefined,
|
|
53
53
|
wasm_modules: undefined,
|
|
54
54
|
text_blobs: undefined,
|
|
55
|
+
browser: undefined,
|
|
55
56
|
data_blobs: undefined,
|
|
56
57
|
durable_objects: undefined,
|
|
57
58
|
queues: undefined,
|
|
58
59
|
r2_buckets: undefined,
|
|
59
60
|
d1_databases: undefined,
|
|
61
|
+
constellation: undefined,
|
|
60
62
|
services: undefined,
|
|
61
63
|
analytics_engine_datasets: undefined,
|
|
62
64
|
dispatch_namespaces: undefined,
|
|
@@ -70,6 +72,8 @@ function createWorkerBundleFormData(workerBundle: BundleResult): FormData {
|
|
|
70
72
|
usage_model: undefined,
|
|
71
73
|
keepVars: undefined,
|
|
72
74
|
logpush: undefined,
|
|
75
|
+
placement: undefined,
|
|
76
|
+
tail_consumers: undefined,
|
|
73
77
|
};
|
|
74
78
|
|
|
75
79
|
return createWorkerUploadForm(worker);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, lstatSync, readFileSync } from "node:fs";
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join, resolve as resolvePath } from "node:path";
|
|
4
4
|
import { cwd } from "node:process";
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
import {
|
|
15
15
|
buildRawWorker,
|
|
16
16
|
checkRawWorker,
|
|
17
|
+
traverseAndBuildWorkerJSDirectory,
|
|
17
18
|
} from "../../pages/functions/buildWorker";
|
|
18
19
|
import { validateRoutes } from "../../pages/functions/routes-validation";
|
|
19
20
|
import { upload } from "../../pages/upload";
|
|
@@ -65,7 +66,7 @@ interface PagesPublishOptions {
|
|
|
65
66
|
|
|
66
67
|
/**
|
|
67
68
|
* Whether to run bundling on `_worker.js` before deploying.
|
|
68
|
-
* Default:
|
|
69
|
+
* Default: true
|
|
69
70
|
*/
|
|
70
71
|
bundle?: boolean;
|
|
71
72
|
|
|
@@ -95,9 +96,12 @@ export async function publish({
|
|
|
95
96
|
_redirects: string | undefined,
|
|
96
97
|
_routesGenerated: string | undefined,
|
|
97
98
|
_routesCustom: string | undefined,
|
|
99
|
+
_workerJSIsDirectory = false,
|
|
98
100
|
_workerJS: string | undefined;
|
|
99
101
|
|
|
100
|
-
|
|
102
|
+
bundle = bundle ?? true;
|
|
103
|
+
|
|
104
|
+
const _workerPath = resolvePath(directory, "_worker.js");
|
|
101
105
|
|
|
102
106
|
try {
|
|
103
107
|
_headers = readFileSync(join(directory, "_headers"), "utf-8");
|
|
@@ -116,7 +120,10 @@ export async function publish({
|
|
|
116
120
|
} catch {}
|
|
117
121
|
|
|
118
122
|
try {
|
|
119
|
-
|
|
123
|
+
_workerJSIsDirectory = lstatSync(_workerPath).isDirectory();
|
|
124
|
+
if (!_workerJSIsDirectory) {
|
|
125
|
+
_workerJS = readFileSync(_workerPath, "utf-8");
|
|
126
|
+
}
|
|
120
127
|
} catch {}
|
|
121
128
|
|
|
122
129
|
// Grab the bindings from the API, we need these for shims and other such hacky inserts
|
|
@@ -240,16 +247,23 @@ export async function publish({
|
|
|
240
247
|
* Advanced Mode
|
|
241
248
|
* https://developers.cloudflare.com/pages/platform/functions/#advanced-mode
|
|
242
249
|
*
|
|
243
|
-
* When using a _worker.js file, the entire /functions directory is ignored
|
|
250
|
+
* When using a _worker.js file or _worker.js/ directory, the entire /functions directory is ignored
|
|
244
251
|
* – this includes its routing and middleware characteristics.
|
|
245
252
|
*/
|
|
246
|
-
if (
|
|
253
|
+
if (_workerJSIsDirectory) {
|
|
254
|
+
workerBundle = await traverseAndBuildWorkerJSDirectory({
|
|
255
|
+
workerJSDirectory: _workerPath,
|
|
256
|
+
buildOutputDirectory: directory,
|
|
257
|
+
d1Databases,
|
|
258
|
+
nodejsCompat,
|
|
259
|
+
});
|
|
260
|
+
} else if (_workerJS) {
|
|
247
261
|
if (bundle) {
|
|
248
262
|
const outfile = join(tmpdir(), `./bundledWorker-${Math.random()}.mjs`);
|
|
249
263
|
workerBundle = await buildRawWorker({
|
|
250
|
-
workerScriptPath,
|
|
264
|
+
workerScriptPath: _workerPath,
|
|
251
265
|
outfile,
|
|
252
|
-
directory
|
|
266
|
+
directory,
|
|
253
267
|
local: false,
|
|
254
268
|
sourcemap: true,
|
|
255
269
|
watch: false,
|
|
@@ -258,17 +272,19 @@ export async function publish({
|
|
|
258
272
|
nodejsCompat,
|
|
259
273
|
});
|
|
260
274
|
} else {
|
|
261
|
-
await checkRawWorker(
|
|
262
|
-
// TODO:
|
|
275
|
+
await checkRawWorker(_workerPath, () => {});
|
|
276
|
+
// TODO: Let users configure this in the future.
|
|
263
277
|
workerBundle = {
|
|
264
278
|
modules: [],
|
|
265
279
|
dependencies: {},
|
|
266
280
|
stop: undefined,
|
|
267
|
-
resolvedEntryPointPath:
|
|
281
|
+
resolvedEntryPointPath: _workerPath,
|
|
268
282
|
bundleType: "esm",
|
|
269
283
|
};
|
|
270
284
|
}
|
|
285
|
+
}
|
|
271
286
|
|
|
287
|
+
if (_workerJS || _workerJSIsDirectory) {
|
|
272
288
|
const workerBundleContents = await createUploadWorkerBundleContents(
|
|
273
289
|
workerBundle as BundleResult
|
|
274
290
|
);
|
|
@@ -302,7 +318,7 @@ export async function publish({
|
|
|
302
318
|
* Pages Functions
|
|
303
319
|
* https://developers.cloudflare.com/pages/platform/functions/
|
|
304
320
|
*/
|
|
305
|
-
if (builtFunctions && !_workerJS) {
|
|
321
|
+
if (builtFunctions && !_workerJS && !_workerJSIsDirectory) {
|
|
306
322
|
const workerBundleContents = await createUploadWorkerBundleContents(
|
|
307
323
|
workerBundle as BundleResult
|
|
308
324
|
);
|
package/src/bundle.ts
CHANGED
|
@@ -7,11 +7,12 @@ import NodeModulesPolyfills from "@esbuild-plugins/node-modules-polyfill";
|
|
|
7
7
|
import * as esbuild from "esbuild";
|
|
8
8
|
import tmp from "tmp-promise";
|
|
9
9
|
import createModuleCollector from "./module-collection";
|
|
10
|
-
import { getBasePath
|
|
10
|
+
import { getBasePath } from "./paths";
|
|
11
11
|
import type { Config } from "./config";
|
|
12
12
|
import type { DurableObjectBindings } from "./config/environment";
|
|
13
13
|
import type { WorkerRegistry } from "./dev-registry";
|
|
14
14
|
import type { Entry } from "./entry";
|
|
15
|
+
import type { SourceMapMetadata } from "./inspect";
|
|
15
16
|
import type { CfModule } from "./worker";
|
|
16
17
|
|
|
17
18
|
export const COMMON_ESBUILD_OPTIONS = {
|
|
@@ -27,6 +28,7 @@ export type BundleResult = {
|
|
|
27
28
|
bundleType: "esm" | "commonjs";
|
|
28
29
|
stop: (() => void) | undefined;
|
|
29
30
|
sourceMapPath?: string | undefined;
|
|
31
|
+
sourceMapMetadata?: SourceMapMetadata | undefined;
|
|
30
32
|
};
|
|
31
33
|
|
|
32
34
|
type StaticAssetsConfig =
|
|
@@ -77,15 +79,25 @@ export function isBuildFailure(err: unknown): err is esbuild.BuildFailure {
|
|
|
77
79
|
* Rewrites esbuild BuildFailures for failing to resolve Node built-in modules
|
|
78
80
|
* to suggest enabling Node compat as opposed to `platform: "node"`.
|
|
79
81
|
*/
|
|
80
|
-
export function rewriteNodeCompatBuildFailure(
|
|
82
|
+
export function rewriteNodeCompatBuildFailure(
|
|
83
|
+
err: esbuild.BuildFailure,
|
|
84
|
+
forPages = false
|
|
85
|
+
) {
|
|
81
86
|
for (const error of err.errors) {
|
|
82
87
|
const match = nodeBuiltinResolveErrorText.exec(error.text);
|
|
83
88
|
if (match !== null) {
|
|
89
|
+
const issue = `The package "${match[1]}" wasn't found on the file system but is built into node.`;
|
|
90
|
+
|
|
91
|
+
const instructionForUser = `${
|
|
92
|
+
forPages
|
|
93
|
+
? 'Add the "nodejs_compat" compatibility flag to your Pages project'
|
|
94
|
+
: 'Add "node_compat = true" to your wrangler.toml file'
|
|
95
|
+
} to enable Node.js compatibility.`;
|
|
96
|
+
|
|
84
97
|
error.notes = [
|
|
85
98
|
{
|
|
86
99
|
location: null,
|
|
87
|
-
text:
|
|
88
|
-
Add "node_compat = true" to your wrangler.toml file to enable Node compatibility.`,
|
|
100
|
+
text: `${issue}\n${instructionForUser}`,
|
|
89
101
|
},
|
|
90
102
|
];
|
|
91
103
|
}
|
|
@@ -117,6 +129,8 @@ export async function bundleWorker(
|
|
|
117
129
|
entry: Entry,
|
|
118
130
|
destination: string,
|
|
119
131
|
options: {
|
|
132
|
+
// When `bundle` is set to false, we apply shims to the Worker, but won't pull in any imports
|
|
133
|
+
bundle?: boolean;
|
|
120
134
|
serveAssetsFromWorker: boolean;
|
|
121
135
|
assets?: StaticAssetsConfig;
|
|
122
136
|
betaD1Shims?: string[];
|
|
@@ -143,12 +157,15 @@ export async function bundleWorker(
|
|
|
143
157
|
loader?: Record<string, string>;
|
|
144
158
|
sourcemap?: esbuild.CommonOptions["sourcemap"];
|
|
145
159
|
plugins?: esbuild.Plugin[];
|
|
160
|
+
additionalModules?: CfModule[];
|
|
146
161
|
// TODO: Rip these out https://github.com/cloudflare/workers-sdk/issues/2153
|
|
147
162
|
disableModuleCollection?: boolean;
|
|
148
163
|
isOutfile?: boolean;
|
|
164
|
+
forPages?: boolean;
|
|
149
165
|
}
|
|
150
166
|
): Promise<BundleResult> {
|
|
151
167
|
const {
|
|
168
|
+
bundle = true,
|
|
152
169
|
serveAssetsFromWorker,
|
|
153
170
|
betaD1Shims,
|
|
154
171
|
doBindings,
|
|
@@ -176,6 +193,8 @@ export async function bundleWorker(
|
|
|
176
193
|
plugins,
|
|
177
194
|
disableModuleCollection,
|
|
178
195
|
isOutfile,
|
|
196
|
+
forPages,
|
|
197
|
+
additionalModules = [],
|
|
179
198
|
} = options;
|
|
180
199
|
|
|
181
200
|
// We create a temporary directory for any oneoff files we
|
|
@@ -350,7 +369,7 @@ export async function bundleWorker(
|
|
|
350
369
|
|
|
351
370
|
const buildOptions: esbuild.BuildOptions & { metafile: true } = {
|
|
352
371
|
entryPoints: [inputEntry.file],
|
|
353
|
-
bundle
|
|
372
|
+
bundle,
|
|
354
373
|
absWorkingDir: entry.directory,
|
|
355
374
|
outdir: destination,
|
|
356
375
|
entryNames: entryName || path.parse(entry.file).name,
|
|
@@ -362,10 +381,10 @@ export async function bundleWorker(
|
|
|
362
381
|
}
|
|
363
382
|
: {}),
|
|
364
383
|
inject,
|
|
365
|
-
external: ["__STATIC_CONTENT_MANIFEST"],
|
|
384
|
+
external: bundle ? ["__STATIC_CONTENT_MANIFEST"] : undefined,
|
|
366
385
|
format: entry.format === "modules" ? "esm" : "iife",
|
|
367
386
|
target: COMMON_ESBUILD_OPTIONS.target,
|
|
368
|
-
sourcemap: sourcemap ?? true,
|
|
387
|
+
sourcemap: sourcemap ?? true,
|
|
369
388
|
// Include a reference to the output folder in the sourcemap.
|
|
370
389
|
// This is omitted by default, but we need it to properly resolve source paths in error output.
|
|
371
390
|
sourceRoot: destination,
|
|
@@ -409,7 +428,7 @@ export async function bundleWorker(
|
|
|
409
428
|
result = await esbuild.build(buildOptions);
|
|
410
429
|
} catch (e) {
|
|
411
430
|
if (!legacyNodeCompat && isBuildFailure(e))
|
|
412
|
-
rewriteNodeCompatBuildFailure(e);
|
|
431
|
+
rewriteNodeCompatBuildFailure(e, forPages);
|
|
413
432
|
throw e;
|
|
414
433
|
}
|
|
415
434
|
|
|
@@ -440,21 +459,34 @@ export async function bundleWorker(
|
|
|
440
459
|
entryPointOutputs[0][0]
|
|
441
460
|
);
|
|
442
461
|
|
|
462
|
+
// A collision between additionalModules and moduleCollector.modules is incredibly unlikely because moduleCollector hashes the modules it collects.
|
|
463
|
+
// However, if it happens, let's trust the explicitly provided additionalModules over the ones we discovered.
|
|
464
|
+
const modules = dedupeModulesByName([
|
|
465
|
+
...moduleCollector.modules,
|
|
466
|
+
...additionalModules,
|
|
467
|
+
]);
|
|
468
|
+
|
|
443
469
|
// copy all referenced modules into the output bundle directory
|
|
444
|
-
for (const module of
|
|
445
|
-
|
|
446
|
-
path.
|
|
447
|
-
module.
|
|
470
|
+
for (const module of modules) {
|
|
471
|
+
const modulePath = path.join(
|
|
472
|
+
path.dirname(resolvedEntryPointPath),
|
|
473
|
+
module.name
|
|
448
474
|
);
|
|
475
|
+
fs.mkdirSync(path.dirname(modulePath), { recursive: true });
|
|
476
|
+
fs.writeFileSync(modulePath, module.content);
|
|
449
477
|
}
|
|
450
478
|
|
|
451
479
|
return {
|
|
452
|
-
modules
|
|
480
|
+
modules,
|
|
453
481
|
dependencies,
|
|
454
482
|
resolvedEntryPointPath,
|
|
455
483
|
bundleType,
|
|
456
484
|
stop: result.stop,
|
|
457
485
|
sourceMapPath,
|
|
486
|
+
sourceMapMetadata: {
|
|
487
|
+
tmpDir: tmpDir.path,
|
|
488
|
+
entryDirectory: entry.directory,
|
|
489
|
+
},
|
|
458
490
|
};
|
|
459
491
|
}
|
|
460
492
|
|
|
@@ -599,7 +631,7 @@ async function applyMiddlewareLoaderFacade(
|
|
|
599
631
|
...Object.fromEntries(
|
|
600
632
|
middleware.map((val, index) => [
|
|
601
633
|
middlewareIdentifiers[index],
|
|
602
|
-
|
|
634
|
+
path.resolve(getBasePath(), val.path),
|
|
603
635
|
])
|
|
604
636
|
),
|
|
605
637
|
}),
|
|
@@ -905,4 +937,16 @@ function listEntryPoints(
|
|
|
905
937
|
return outputs.map(([_input, output]) => output.entryPoint).join("\n");
|
|
906
938
|
}
|
|
907
939
|
|
|
940
|
+
/**
|
|
941
|
+
* Prefer modules towards the end of the array in the case of a collision by name.
|
|
942
|
+
*/
|
|
943
|
+
export function dedupeModulesByName(modules: CfModule[]): CfModule[] {
|
|
944
|
+
return Object.values(
|
|
945
|
+
modules.reduce((moduleMap, module) => {
|
|
946
|
+
moduleMap[module.name] = module;
|
|
947
|
+
return moduleMap;
|
|
948
|
+
}, {} as Record<string, CfModule>)
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
|
|
908
952
|
type ValueOf<T> = T[keyof T];
|
package/src/cfetch/internal.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { fetch, File, Headers } from "undici";
|
|
3
|
+
import { Response } from "undici";
|
|
3
4
|
import { version as wranglerVersion } from "../../package.json";
|
|
4
5
|
import { getCloudflareApiBaseUrl } from "../environment-variables/misc-variables";
|
|
5
6
|
import { logger } from "../logger";
|
|
@@ -7,7 +8,7 @@ import { ParseError, parseJSON } from "../parse";
|
|
|
7
8
|
import { loginOrRefreshIfRequired, requireApiToken } from "../user";
|
|
8
9
|
import type { ApiCredentials } from "../user";
|
|
9
10
|
import type { URLSearchParams } from "node:url";
|
|
10
|
-
import type { RequestInit, HeadersInit
|
|
11
|
+
import type { RequestInit, HeadersInit } from "undici";
|
|
11
12
|
|
|
12
13
|
/*
|
|
13
14
|
* performApiFetch does everything required to make a CF API request,
|
|
@@ -217,19 +218,20 @@ export async function fetchR2Objects(
|
|
|
217
218
|
export async function fetchDashboardScript(
|
|
218
219
|
resource: string,
|
|
219
220
|
bodyInit: RequestInit = {}
|
|
220
|
-
): Promise<
|
|
221
|
+
): Promise<File[]> {
|
|
221
222
|
await requireLoggedIn();
|
|
222
223
|
const auth = requireApiToken();
|
|
223
224
|
const headers = cloneHeaders(bodyInit.headers);
|
|
224
225
|
addAuthorizationHeaderIfUnspecified(headers, auth);
|
|
225
226
|
addUserAgent(headers);
|
|
226
227
|
|
|
227
|
-
|
|
228
|
+
let response = await fetch(`${getCloudflareApiBaseUrl()}${resource}`, {
|
|
228
229
|
...bodyInit,
|
|
229
230
|
headers,
|
|
230
231
|
});
|
|
231
232
|
|
|
232
233
|
if (!response.ok || !response.body) {
|
|
234
|
+
console.error(response.ok, response.body);
|
|
233
235
|
throw new Error(
|
|
234
236
|
`Failed to fetch ${resource} - ${response.status}: ${response.statusText});`
|
|
235
237
|
);
|
|
@@ -240,19 +242,22 @@ export async function fetchDashboardScript(
|
|
|
240
242
|
?.startsWith("multipart");
|
|
241
243
|
|
|
242
244
|
if (usesModules) {
|
|
243
|
-
//
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if (entries.length > 1)
|
|
247
|
-
throw new RangeError("Expected only one entry in multipart response");
|
|
248
|
-
const [_, file] = entries[0];
|
|
249
|
-
|
|
250
|
-
if (file instanceof File) {
|
|
251
|
-
return await file.text();
|
|
245
|
+
// For testing purposes only, sorry not sorry -- msw doesn't implement Response#formData
|
|
246
|
+
if (!response.formData) {
|
|
247
|
+
response = new Response(await response.text(), response);
|
|
252
248
|
}
|
|
253
249
|
|
|
254
|
-
|
|
250
|
+
const form = await response.formData();
|
|
251
|
+
const files = Array.from(form.entries()).map(([filename, contents]) =>
|
|
252
|
+
contents instanceof File ? contents : new File([contents], filename)
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
return files;
|
|
255
256
|
} else {
|
|
256
|
-
|
|
257
|
+
const contents = await response.text();
|
|
258
|
+
const filename = response.headers.get("cf-entrypoint") ?? "index.js";
|
|
259
|
+
const file = new File([contents], filename, { type: "text" });
|
|
260
|
+
|
|
261
|
+
return [file];
|
|
257
262
|
}
|
|
258
263
|
}
|
|
@@ -265,6 +265,13 @@ interface EnvironmentInheritable {
|
|
|
265
265
|
* @inheritable
|
|
266
266
|
*/
|
|
267
267
|
logpush: boolean | undefined;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Specify how the worker should be located to minimize round-trip time.
|
|
271
|
+
*
|
|
272
|
+
* More details: https://developers.cloudflare.com/workers/platform/smart-placement/
|
|
273
|
+
*/
|
|
274
|
+
placement: { mode: "off" | "smart" } | undefined;
|
|
268
275
|
}
|
|
269
276
|
|
|
270
277
|
export type DurableObjectBindings = {
|
|
@@ -448,6 +455,22 @@ interface EnvironmentNonInheritable {
|
|
|
448
455
|
database_internal_env?: string;
|
|
449
456
|
}[];
|
|
450
457
|
|
|
458
|
+
/**
|
|
459
|
+
* Specifies Constellation projects that are bound to this Worker environment.
|
|
460
|
+
*
|
|
461
|
+
* NOTE: This field is not automatically inherited from the top level environment,
|
|
462
|
+
* and so must be specified in every named environment.
|
|
463
|
+
*
|
|
464
|
+
* @default `[]`
|
|
465
|
+
* @nonInheritable
|
|
466
|
+
*/
|
|
467
|
+
constellation: {
|
|
468
|
+
/** The binding name used to refer to the project in the worker. */
|
|
469
|
+
binding: string;
|
|
470
|
+
/** The id of the project. */
|
|
471
|
+
project_id: string;
|
|
472
|
+
}[];
|
|
473
|
+
|
|
451
474
|
/**
|
|
452
475
|
* Specifies service bindings (worker-to-worker) that are bound to this Worker environment.
|
|
453
476
|
*
|
|
@@ -484,6 +507,15 @@ interface EnvironmentNonInheritable {
|
|
|
484
507
|
dataset?: string;
|
|
485
508
|
}[];
|
|
486
509
|
|
|
510
|
+
/**
|
|
511
|
+
* A browser that will be usable from the worker.
|
|
512
|
+
*/
|
|
513
|
+
browser:
|
|
514
|
+
| {
|
|
515
|
+
binding: string;
|
|
516
|
+
}
|
|
517
|
+
| undefined;
|
|
518
|
+
|
|
487
519
|
/**
|
|
488
520
|
* "Unsafe" tables for features that aren't directly supported by wrangler.
|
|
489
521
|
*
|
|
@@ -519,6 +551,8 @@ interface EnvironmentNonInheritable {
|
|
|
519
551
|
/** The uuid of the uploaded mTLS certificate */
|
|
520
552
|
certificate_id: string;
|
|
521
553
|
}[];
|
|
554
|
+
|
|
555
|
+
tail_consumers?: TailConsumer[];
|
|
522
556
|
}
|
|
523
557
|
|
|
524
558
|
/**
|
|
@@ -616,3 +650,10 @@ export type ConfigModuleRuleType =
|
|
|
616
650
|
| "CompiledWasm"
|
|
617
651
|
| "Text"
|
|
618
652
|
| "Data";
|
|
653
|
+
|
|
654
|
+
export type TailConsumer = {
|
|
655
|
+
/** The name of the service tail events will be forwarded to. */
|
|
656
|
+
service: string;
|
|
657
|
+
/** (Optional) The environt of the service. */
|
|
658
|
+
environment?: string;
|
|
659
|
+
};
|
package/src/config/index.ts
CHANGED
|
@@ -100,11 +100,13 @@ export function printBindings(bindings: CfWorkerInit["bindings"]) {
|
|
|
100
100
|
send_email,
|
|
101
101
|
queues,
|
|
102
102
|
d1_databases,
|
|
103
|
+
constellation,
|
|
103
104
|
r2_buckets,
|
|
104
105
|
logfwdr,
|
|
105
106
|
services,
|
|
106
107
|
analytics_engine_datasets,
|
|
107
108
|
text_blobs,
|
|
109
|
+
browser,
|
|
108
110
|
unsafe,
|
|
109
111
|
vars,
|
|
110
112
|
wasm_modules,
|
|
@@ -207,6 +209,18 @@ export function printBindings(bindings: CfWorkerInit["bindings"]) {
|
|
|
207
209
|
});
|
|
208
210
|
}
|
|
209
211
|
|
|
212
|
+
if (constellation !== undefined && constellation.length > 0) {
|
|
213
|
+
output.push({
|
|
214
|
+
type: "Constellation Projects",
|
|
215
|
+
entries: constellation.map(({ binding, project_id }) => {
|
|
216
|
+
return {
|
|
217
|
+
key: binding,
|
|
218
|
+
value: project_id,
|
|
219
|
+
};
|
|
220
|
+
}),
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
210
224
|
if (r2_buckets !== undefined && r2_buckets.length > 0) {
|
|
211
225
|
output.push({
|
|
212
226
|
type: "R2 Buckets",
|
|
@@ -273,6 +287,13 @@ export function printBindings(bindings: CfWorkerInit["bindings"]) {
|
|
|
273
287
|
});
|
|
274
288
|
}
|
|
275
289
|
|
|
290
|
+
if (browser !== undefined) {
|
|
291
|
+
output.push({
|
|
292
|
+
type: "Browser",
|
|
293
|
+
entries: [{ key: "Name", value: browser.binding }],
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
|
|
276
297
|
if (unsafe?.bindings !== undefined && unsafe.bindings.length > 0) {
|
|
277
298
|
output.push({
|
|
278
299
|
type: "Unsafe",
|