wrangler 0.0.0-e29a241 → 0.0.0-e2f9bb2
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 +25 -14
- package/bin/wrangler.js +13 -1
- package/miniflare-dist/index.mjs +4828 -21
- package/package.json +29 -24
- package/pages/functions/buildPlugin.ts +92 -0
- package/pages/functions/buildWorker.ts +80 -4
- package/pages/functions/filepath-routing.test.ts +11 -0
- package/pages/functions/filepath-routing.ts +8 -0
- package/pages/functions/routes.ts +6 -1
- package/pages/functions/template-plugin.ts +146 -0
- package/pages/functions/template-worker.ts +21 -8
- package/src/__tests__/config-cache.test.ts +36 -0
- package/src/__tests__/configuration.test.ts +692 -321
- package/src/__tests__/dev.test.tsx +284 -18
- package/src/__tests__/guess-worker-format.test.ts +28 -1
- package/src/__tests__/helpers/mock-cfetch.ts +5 -1
- package/src/__tests__/helpers/mock-console.ts +20 -3
- package/src/__tests__/helpers/mock-dialogs.ts +24 -0
- package/src/__tests__/helpers/mock-http-server.ts +46 -0
- package/src/__tests__/helpers/mock-istty.ts +27 -0
- package/src/__tests__/helpers/mock-oauth-flow.ts +255 -0
- package/src/__tests__/helpers/run-in-tmp.ts +7 -0
- package/src/__tests__/helpers/write-worker-source.ts +31 -0
- package/src/__tests__/https-options.test.ts +5 -2
- package/src/__tests__/index.test.ts +27 -769
- package/src/__tests__/init.test.ts +1042 -0
- package/src/__tests__/jest.setup.ts +4 -4
- package/src/__tests__/kv.test.ts +133 -61
- package/src/__tests__/logger.test.ts +115 -0
- package/src/__tests__/pages.test.ts +311 -26
- package/src/__tests__/publish.test.ts +2789 -618
- package/src/__tests__/r2.test.ts +26 -10
- package/src/__tests__/route.test.ts +4 -4
- package/src/__tests__/secret.test.ts +55 -34
- package/src/__tests__/tail.test.ts +146 -20
- package/src/__tests__/user.test.ts +131 -0
- package/src/__tests__/whoami.test.tsx +14 -9
- package/src/bundle.ts +30 -3
- package/src/cfetch/internal.ts +0 -2
- package/src/cli.ts +5 -11
- package/src/config/README.md +1 -1
- package/src/config/config.ts +13 -53
- package/src/config/environment.ts +88 -4
- package/src/config/index.ts +11 -4
- package/src/config/validation-helpers.ts +96 -7
- package/src/config/validation.ts +407 -79
- package/src/config-cache.ts +45 -0
- package/src/create-worker-preview.ts +22 -13
- package/src/create-worker-upload-form.ts +32 -9
- package/src/dev/dev-vars.ts +36 -0
- package/src/dev/dev.tsx +132 -78
- package/src/dev/local.tsx +115 -29
- package/src/dev/remote.tsx +23 -13
- package/src/dev/use-esbuild.ts +23 -5
- package/src/dialogs.tsx +16 -6
- package/src/entry.ts +83 -24
- package/src/environment-variables.ts +3 -1
- package/src/errors.ts +11 -0
- package/src/https-options.ts +3 -2
- package/src/index.tsx +619 -377
- package/src/inspect.ts +17 -11
- package/src/intl-polyfill.d.ts +139 -0
- package/src/logger.ts +66 -0
- package/src/miniflare-cli/index.ts +4 -0
- package/src/miniflare-cli/request-context.ts +40 -0
- package/src/module-collection.ts +7 -7
- package/src/open-in-browser.ts +5 -4
- package/src/package-manager.ts +9 -8
- package/src/pages.tsx +883 -62
- package/src/parse.ts +1 -1
- package/src/proxy.ts +25 -11
- package/src/publish.ts +263 -141
- package/src/sites.tsx +27 -14
- package/src/tail/index.ts +2 -2
- package/src/tail/printing.ts +13 -8
- package/src/update-check.ts +19 -0
- package/src/user.tsx +116 -41
- package/src/whoami.tsx +2 -1
- package/src/worker.ts +15 -6
- package/templates/gitignore +171 -0
- package/templates/static-asset-facade.js +1 -1
- package/wrangler-dist/cli.js +21167 -50229
- package/miniflare-dist/index.mjs.map +0 -7
- package/src/__tests__/dev2.test.tsx +0 -154
- package/src/__tests__/logout.test.ts +0 -52
- package/src/__tests__/sentry.test.ts +0 -146
- package/src/reporting.ts +0 -131
- package/wrangler-dist/cli.js.map +0 -7
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { render } from "ink-testing-library";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { writeAuthConfigFile } from "../user";
|
|
4
4
|
import { getUserInfo, WhoAmI } from "../whoami";
|
|
5
5
|
import { setMockResponse } from "./helpers/mock-cfetch";
|
|
6
6
|
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
7
|
+
import { useMockIsTTY } from "./helpers/mock-istty";
|
|
7
8
|
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
8
9
|
import type { UserInfo } from "../whoami";
|
|
9
10
|
|
|
10
11
|
describe("getUserInfo()", () => {
|
|
11
12
|
runInTempDir({ homedir: "./home" });
|
|
12
13
|
const std = mockConsoleMethods();
|
|
14
|
+
const { setIsTTY } = useMockIsTTY();
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
setIsTTY(true);
|
|
18
|
+
});
|
|
13
19
|
|
|
14
20
|
it("should return undefined if there is no config file", async () => {
|
|
15
21
|
const userInfo = await getUserInfo();
|
|
@@ -18,16 +24,12 @@ describe("getUserInfo()", () => {
|
|
|
18
24
|
|
|
19
25
|
it("should return undefined if there is an empty config file", async () => {
|
|
20
26
|
writeAuthConfigFile({});
|
|
21
|
-
// Now that we have changed the auth tokens in the wrangler.toml we must reinitialize the user auth state.
|
|
22
|
-
reinitialiseAuthTokens();
|
|
23
27
|
const userInfo = await getUserInfo();
|
|
24
28
|
expect(userInfo).toBeUndefined();
|
|
25
29
|
});
|
|
26
30
|
|
|
27
31
|
it("should return the user's email and accounts if authenticated via config token", async () => {
|
|
28
32
|
writeAuthConfigFile({ oauth_token: "some-oauth-token" });
|
|
29
|
-
// Now that we have changed the auth tokens in the wrangler.toml we must reinitialize the user auth state.
|
|
30
|
-
reinitialiseAuthTokens();
|
|
31
33
|
|
|
32
34
|
setMockResponse("/user", () => {
|
|
33
35
|
return { email: "user@example.com" };
|
|
@@ -56,12 +58,15 @@ describe("getUserInfo()", () => {
|
|
|
56
58
|
|
|
57
59
|
it("should display a warning message if the config file contains a legacy api_token field", async () => {
|
|
58
60
|
writeAuthConfigFile({ api_token: "API_TOKEN" });
|
|
59
|
-
await reinitialiseAuthTokens();
|
|
60
61
|
await getUserInfo();
|
|
61
62
|
expect(std.warn).toMatchInlineSnapshot(`
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
"[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mIt looks like you have used Wrangler 1's \`config\` command to login with an API token.[0m
|
|
64
|
+
|
|
65
|
+
This is no longer supported in the current version of Wrangler.
|
|
66
|
+
If you wish to authenticate via an API token then please set the \`CLOUDFLARE_API_TOKEN\`
|
|
67
|
+
environment variable.
|
|
68
|
+
|
|
69
|
+
"
|
|
65
70
|
`);
|
|
66
71
|
});
|
|
67
72
|
});
|
package/src/bundle.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
+
import NodeGlobalsPolyfills from "@esbuild-plugins/node-globals-polyfill";
|
|
5
|
+
import NodeModulesPolyfills from "@esbuild-plugins/node-modules-polyfill";
|
|
4
6
|
import * as esbuild from "esbuild";
|
|
5
7
|
import createModuleCollector from "./module-collection";
|
|
6
8
|
import type { Config } from "./config";
|
|
@@ -26,10 +28,21 @@ export async function bundleWorker(
|
|
|
26
28
|
jsxFragment: string | undefined;
|
|
27
29
|
rules: Config["rules"];
|
|
28
30
|
watch?: esbuild.WatchMode;
|
|
31
|
+
tsconfig: string | undefined;
|
|
32
|
+
minify: boolean | undefined;
|
|
33
|
+
nodeCompat: boolean | undefined;
|
|
29
34
|
}
|
|
30
35
|
): Promise<BundleResult> {
|
|
31
|
-
const {
|
|
32
|
-
|
|
36
|
+
const {
|
|
37
|
+
serveAssetsFromWorker,
|
|
38
|
+
jsxFactory,
|
|
39
|
+
jsxFragment,
|
|
40
|
+
rules,
|
|
41
|
+
watch,
|
|
42
|
+
tsconfig,
|
|
43
|
+
minify,
|
|
44
|
+
nodeCompat,
|
|
45
|
+
} = options;
|
|
33
46
|
const entryDirectory = path.dirname(entry.file);
|
|
34
47
|
const moduleCollector = createModuleCollector({
|
|
35
48
|
wrangler1xlegacyModuleReferences: {
|
|
@@ -54,17 +67,31 @@ export async function bundleWorker(
|
|
|
54
67
|
outdir: destination,
|
|
55
68
|
external: ["__STATIC_CONTENT_MANIFEST"],
|
|
56
69
|
format: "esm",
|
|
70
|
+
target: "es2020",
|
|
57
71
|
sourcemap: true,
|
|
72
|
+
minify,
|
|
58
73
|
metafile: true,
|
|
59
74
|
conditions: ["worker", "browser"],
|
|
75
|
+
...(process.env.NODE_ENV && {
|
|
76
|
+
define: {
|
|
77
|
+
"process.env.NODE_ENV": `"${process.env.NODE_ENV}"`,
|
|
78
|
+
...(nodeCompat ? { global: "globalThis" } : {}),
|
|
79
|
+
},
|
|
80
|
+
}),
|
|
60
81
|
loader: {
|
|
61
82
|
".js": "jsx",
|
|
62
83
|
".mjs": "jsx",
|
|
63
84
|
".cjs": "jsx",
|
|
64
85
|
},
|
|
65
|
-
plugins: [
|
|
86
|
+
plugins: [
|
|
87
|
+
moduleCollector.plugin,
|
|
88
|
+
...(nodeCompat
|
|
89
|
+
? [NodeGlobalsPolyfills({ buffer: true }), NodeModulesPolyfills()]
|
|
90
|
+
: []),
|
|
91
|
+
],
|
|
66
92
|
...(jsxFactory && { jsxFactory }),
|
|
67
93
|
...(jsxFragment && { jsxFragment }),
|
|
94
|
+
...(tsconfig && { tsconfig }),
|
|
68
95
|
watch,
|
|
69
96
|
});
|
|
70
97
|
|
package/src/cfetch/internal.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { fetch, Headers } from "undici";
|
|
2
2
|
import { getEnvironmentVariableFactory } from "../environment-variables";
|
|
3
3
|
import { ParseError, parseJSON } from "../parse";
|
|
4
|
-
import { reportError } from "../reporting";
|
|
5
4
|
import { getAPIToken, loginOrRefreshIfRequired } from "../user";
|
|
6
5
|
import type { URLSearchParams } from "node:url";
|
|
7
6
|
import type { RequestInit, HeadersInit } from "undici";
|
|
@@ -48,7 +47,6 @@ export async function fetchInternal<ResponseType>(
|
|
|
48
47
|
try {
|
|
49
48
|
return parseJSON(jsonText) as ResponseType;
|
|
50
49
|
} catch (err) {
|
|
51
|
-
await reportError(err as Error);
|
|
52
50
|
throw new ParseError({
|
|
53
51
|
text: "Received a malformed response from the API",
|
|
54
52
|
notes: [
|
package/src/cli.ts
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
|
+
import "dotenv/config"; // Grab locally specified env params from a `.env` file.
|
|
1
2
|
import process from "process";
|
|
2
3
|
import { hideBin } from "yargs/helpers";
|
|
3
|
-
import {
|
|
4
|
+
import { FatalError } from "./errors";
|
|
4
5
|
import { main } from ".";
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
initReporting();
|
|
8
|
-
} catch (error) {}
|
|
9
|
-
|
|
10
|
-
process.on("uncaughtExceptionMonitor", async (err, origin) => {
|
|
11
|
-
await reportError(err, origin);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
main(hideBin(process.argv)).catch(() => {
|
|
7
|
+
main(hideBin(process.argv)).catch((e) => {
|
|
15
8
|
// The logging of any error that was thrown from `main()` is handled in the `yargs.fail()` handler.
|
|
16
9
|
// Here we just want to ensure that the process exits with a non-zero code.
|
|
17
10
|
// We don't want to do this inside the `main()` function, since that would kill the process when running our tests.
|
|
18
|
-
|
|
11
|
+
const exitCode = (e instanceof FatalError && e.code) || 1;
|
|
12
|
+
process.exit(exitCode);
|
|
19
13
|
});
|
package/src/config/README.md
CHANGED
|
@@ -48,7 +48,7 @@ This function will return:
|
|
|
48
48
|
- a `Diagnostics` object, which contains any errors or warnings from the validation process
|
|
49
49
|
|
|
50
50
|
The field values may have been parsed directly from the `RawConfig`, inherited into a named environment from the top-level environment, or given a default value.
|
|
51
|
-
Generally, if there are any warnings they should be presented to the user via `
|
|
51
|
+
Generally, if there are any warnings they should be presented to the user via `logger.warn()` messages,
|
|
52
52
|
and if there are any errors then an `Error` should be thrown describing these errors.
|
|
53
53
|
|
|
54
54
|
The `Diagnostics` object is hierarchical: each `Diagnostics` instance can contain a collection of child `Diagnostics` instance.
|
package/src/config/config.ts
CHANGED
|
@@ -137,26 +137,15 @@ export interface ConfigFields<Dev extends RawDevConfig> {
|
|
|
137
137
|
| undefined;
|
|
138
138
|
|
|
139
139
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* for more details.
|
|
144
|
-
*
|
|
145
|
-
* @default {}
|
|
140
|
+
* A list of data files that your worker should be bound to. This is
|
|
141
|
+
* the "legacy" way of binding to a data file. ES module workers should
|
|
142
|
+
* do proper module imports.
|
|
146
143
|
*/
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
/** The directory to watch for changes while using wrangler dev, defaults to the current working directory */
|
|
153
|
-
watch_dir?: string;
|
|
154
|
-
/**
|
|
155
|
-
* Deprecated field previously used to configure the build and upload of the script.
|
|
156
|
-
* @deprecated
|
|
157
|
-
*/
|
|
158
|
-
upload?: DeprecatedUpload;
|
|
159
|
-
};
|
|
144
|
+
data_blobs:
|
|
145
|
+
| {
|
|
146
|
+
[key: string]: string;
|
|
147
|
+
}
|
|
148
|
+
| undefined;
|
|
160
149
|
}
|
|
161
150
|
|
|
162
151
|
export interface DevConfig {
|
|
@@ -164,7 +153,6 @@ export interface DevConfig {
|
|
|
164
153
|
* IP address for the local dev server to listen on,
|
|
165
154
|
*
|
|
166
155
|
* @default `localhost`
|
|
167
|
-
* @todo this needs to be implemented
|
|
168
156
|
*/
|
|
169
157
|
ip: string;
|
|
170
158
|
|
|
@@ -179,7 +167,6 @@ export interface DevConfig {
|
|
|
179
167
|
* Protocol that local wrangler dev server listens to requests on.
|
|
180
168
|
*
|
|
181
169
|
* @default `http`
|
|
182
|
-
* @todo this needs to be implemented
|
|
183
170
|
*/
|
|
184
171
|
local_protocol: "http" | "https";
|
|
185
172
|
|
|
@@ -190,13 +177,14 @@ export interface DevConfig {
|
|
|
190
177
|
* See https://github.com/cloudflare/wrangler2/issues/583
|
|
191
178
|
*
|
|
192
179
|
* @default `https`
|
|
180
|
+
* @todo this needs to be implemented https://github.com/cloudflare/wrangler2/issues/583
|
|
193
181
|
*/
|
|
194
182
|
upstream_protocol: "https" | "http";
|
|
195
183
|
|
|
196
184
|
/**
|
|
197
|
-
* Host to forward requests to, defaults to the
|
|
185
|
+
* Host to forward requests to, defaults to the host of the first route of project
|
|
198
186
|
*/
|
|
199
|
-
host:
|
|
187
|
+
host: Config["route"];
|
|
200
188
|
}
|
|
201
189
|
|
|
202
190
|
export type RawDevConfig = Partial<DevConfig>;
|
|
@@ -219,40 +207,12 @@ export interface DeprecatedConfigFields {
|
|
|
219
207
|
* @breaking
|
|
220
208
|
*/
|
|
221
209
|
webpack_config?: string;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Deprecated upload configuration.
|
|
226
|
-
*/
|
|
227
|
-
export interface DeprecatedUpload {
|
|
228
|
-
/**
|
|
229
|
-
* The format of the Worker script.
|
|
230
|
-
*
|
|
231
|
-
* @deprecated We infer the format automatically now.
|
|
232
|
-
*/
|
|
233
|
-
format?: "modules" | "service-worker";
|
|
234
210
|
|
|
235
211
|
/**
|
|
236
|
-
*
|
|
237
|
-
* relative to the wrangler.toml file.
|
|
238
|
-
*
|
|
239
|
-
* Defaults to the directory containing the wrangler.toml file.
|
|
240
|
-
*
|
|
212
|
+
* Configuration only used by a standalone use of the miniflare binary.
|
|
241
213
|
* @deprecated
|
|
242
214
|
*/
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* The path to the Worker script, relative to `upload.dir`.
|
|
247
|
-
*
|
|
248
|
-
* @deprecated This will be replaced by a command line argument.
|
|
249
|
-
*/
|
|
250
|
-
main?: string;
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* @deprecated This is now defined at the top level `rules` field.
|
|
254
|
-
*/
|
|
255
|
-
rules?: Environment["rules"];
|
|
215
|
+
miniflare?: unknown;
|
|
256
216
|
}
|
|
257
217
|
|
|
258
218
|
interface EnvironmentMap {
|
|
@@ -64,7 +64,7 @@ interface EnvironmentInheritable {
|
|
|
64
64
|
* @breaking
|
|
65
65
|
* @inheritable
|
|
66
66
|
*/
|
|
67
|
-
workers_dev: boolean;
|
|
67
|
+
workers_dev: boolean | undefined;
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
70
|
* A list of routes that your worker should be published to.
|
|
@@ -74,7 +74,13 @@ interface EnvironmentInheritable {
|
|
|
74
74
|
*
|
|
75
75
|
* @inheritable
|
|
76
76
|
*/
|
|
77
|
-
routes:
|
|
77
|
+
routes:
|
|
78
|
+
| (
|
|
79
|
+
| string
|
|
80
|
+
| { pattern: string; zone_id: string }
|
|
81
|
+
| { pattern: string; zone_name: string }
|
|
82
|
+
)[]
|
|
83
|
+
| undefined;
|
|
78
84
|
|
|
79
85
|
/**
|
|
80
86
|
* A route that your worker should be published to. Literally
|
|
@@ -85,7 +91,18 @@ interface EnvironmentInheritable {
|
|
|
85
91
|
*
|
|
86
92
|
* @inheritable
|
|
87
93
|
*/
|
|
88
|
-
route:
|
|
94
|
+
route:
|
|
95
|
+
| (
|
|
96
|
+
| string
|
|
97
|
+
| { pattern: string; zone_id: string }
|
|
98
|
+
| { pattern: string; zone_name: string }
|
|
99
|
+
)
|
|
100
|
+
| undefined;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Path to a custom tsconfig
|
|
104
|
+
*/
|
|
105
|
+
tsconfig: string | undefined;
|
|
89
106
|
|
|
90
107
|
/**
|
|
91
108
|
* The function to use to replace jsx syntax.
|
|
@@ -126,7 +143,7 @@ interface EnvironmentInheritable {
|
|
|
126
143
|
*
|
|
127
144
|
* @inheritable
|
|
128
145
|
*/
|
|
129
|
-
usage_model:
|
|
146
|
+
usage_model: "bundled" | "unbound" | undefined;
|
|
130
147
|
|
|
131
148
|
/**
|
|
132
149
|
* An ordered list of rules that define which modules to import,
|
|
@@ -138,6 +155,39 @@ interface EnvironmentInheritable {
|
|
|
138
155
|
*/
|
|
139
156
|
rules: Rule[];
|
|
140
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Configures a custom build step to be run by Wrangler when building your Worker.
|
|
160
|
+
*
|
|
161
|
+
* Refer to the [custom builds documentation](https://developers.cloudflare.com/workers/cli-wrangler/configuration#build)
|
|
162
|
+
* for more details.
|
|
163
|
+
*
|
|
164
|
+
* @default {}
|
|
165
|
+
*/
|
|
166
|
+
build: {
|
|
167
|
+
/** The command used to build your Worker. On Linux and macOS, the command is executed in the `sh` shell and the `cmd` shell for Windows. The `&&` and `||` shell operators may be used. */
|
|
168
|
+
command?: string;
|
|
169
|
+
/** The directory in which the command is executed. */
|
|
170
|
+
cwd?: string;
|
|
171
|
+
/** The directory to watch for changes while using wrangler dev, defaults to the current working directory */
|
|
172
|
+
watch_dir?: string;
|
|
173
|
+
/**
|
|
174
|
+
* Deprecated field previously used to configure the build and upload of the script.
|
|
175
|
+
* @deprecated
|
|
176
|
+
*/
|
|
177
|
+
upload?: DeprecatedUpload;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Minify the script before uploading.
|
|
182
|
+
* @inheritable
|
|
183
|
+
*/
|
|
184
|
+
minify: boolean | undefined;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Add polyfills for node builtin modules and globals
|
|
188
|
+
*/
|
|
189
|
+
node_compat: boolean | undefined;
|
|
190
|
+
|
|
141
191
|
/**
|
|
142
192
|
* TODO: remove this as it has been deprecated.
|
|
143
193
|
*
|
|
@@ -282,6 +332,40 @@ interface EnvironmentDeprecated {
|
|
|
282
332
|
}[];
|
|
283
333
|
}
|
|
284
334
|
|
|
335
|
+
/**
|
|
336
|
+
* Deprecated upload configuration.
|
|
337
|
+
*/
|
|
338
|
+
export interface DeprecatedUpload {
|
|
339
|
+
/**
|
|
340
|
+
* The format of the Worker script.
|
|
341
|
+
*
|
|
342
|
+
* @deprecated We infer the format automatically now.
|
|
343
|
+
*/
|
|
344
|
+
format?: "modules" | "service-worker";
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* The directory you wish to upload your worker from,
|
|
348
|
+
* relative to the wrangler.toml file.
|
|
349
|
+
*
|
|
350
|
+
* Defaults to the directory containing the wrangler.toml file.
|
|
351
|
+
*
|
|
352
|
+
* @deprecated
|
|
353
|
+
*/
|
|
354
|
+
dir?: string;
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* The path to the Worker script, relative to `upload.dir`.
|
|
358
|
+
*
|
|
359
|
+
* @deprecated This will be replaced by a command line argument.
|
|
360
|
+
*/
|
|
361
|
+
main?: string;
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* @deprecated This is now defined at the top level `rules` field.
|
|
365
|
+
*/
|
|
366
|
+
rules?: Environment["rules"];
|
|
367
|
+
}
|
|
368
|
+
|
|
285
369
|
/**
|
|
286
370
|
* The raw environment configuration that we read from the config file.
|
|
287
371
|
*
|
package/src/config/index.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { findUpSync } from "find-up";
|
|
2
|
+
import { logger } from "../logger";
|
|
2
3
|
import { parseTOML, readFileSync } from "../parse";
|
|
3
4
|
import { normalizeAndValidateConfig } from "./validation";
|
|
4
5
|
import type { Config, RawConfig } from "./config";
|
|
5
6
|
|
|
6
|
-
export type {
|
|
7
|
+
export type {
|
|
8
|
+
Config,
|
|
9
|
+
RawConfig,
|
|
10
|
+
ConfigFields,
|
|
11
|
+
DevConfig,
|
|
12
|
+
RawDevConfig,
|
|
13
|
+
} from "./config";
|
|
7
14
|
export type {
|
|
8
15
|
Environment,
|
|
9
16
|
RawEnvironment,
|
|
@@ -15,7 +22,7 @@ export type {
|
|
|
15
22
|
*/
|
|
16
23
|
export function readConfig(
|
|
17
24
|
configPath: string | undefined,
|
|
18
|
-
|
|
25
|
+
args: unknown
|
|
19
26
|
): Config {
|
|
20
27
|
let rawConfig: RawConfig = {};
|
|
21
28
|
if (!configPath) {
|
|
@@ -31,11 +38,11 @@ export function readConfig(
|
|
|
31
38
|
const { config, diagnostics } = normalizeAndValidateConfig(
|
|
32
39
|
rawConfig,
|
|
33
40
|
configPath,
|
|
34
|
-
|
|
41
|
+
args
|
|
35
42
|
);
|
|
36
43
|
|
|
37
44
|
if (diagnostics.hasWarnings()) {
|
|
38
|
-
|
|
45
|
+
logger.warn(diagnostics.renderWarnings());
|
|
39
46
|
}
|
|
40
47
|
if (diagnostics.hasErrors()) {
|
|
41
48
|
throw new Error(diagnostics.renderErrors());
|
|
@@ -14,13 +14,15 @@ export function deprecated<T extends object>(
|
|
|
14
14
|
fieldPath: DeepKeyOf<T>,
|
|
15
15
|
message: string,
|
|
16
16
|
remove: boolean,
|
|
17
|
-
|
|
17
|
+
title = "Deprecation",
|
|
18
|
+
type: "warning" | "error" = "warning"
|
|
18
19
|
): void {
|
|
20
|
+
const BOLD = "\x1b[1m";
|
|
21
|
+
const NORMAL = "\x1b[0m";
|
|
22
|
+
const diagnosticMessage = `${BOLD}${title}${NORMAL}: "${fieldPath}":\n${message}`;
|
|
19
23
|
const result = unwindPropertyPath(config, fieldPath);
|
|
20
24
|
if (result !== undefined && result.field in result.container) {
|
|
21
|
-
|
|
22
|
-
`DEPRECATION: "${fieldPath}":\n${message}`
|
|
23
|
-
);
|
|
25
|
+
diagnostics[`${type}s`].push(diagnosticMessage);
|
|
24
26
|
if (remove) {
|
|
25
27
|
delete (result.container as Record<string, unknown>)[result.field];
|
|
26
28
|
}
|
|
@@ -58,11 +60,14 @@ export function inheritable<K extends keyof Environment>(
|
|
|
58
60
|
rawEnv: RawEnvironment,
|
|
59
61
|
field: K,
|
|
60
62
|
validate: ValidatorFn,
|
|
61
|
-
defaultValue: Environment[K]
|
|
63
|
+
defaultValue: Environment[K],
|
|
64
|
+
transformFn: TransformFn<Environment[K]> = (v) => v
|
|
62
65
|
): Environment[K] {
|
|
63
66
|
validate(diagnostics, field, rawEnv[field], topLevelEnv);
|
|
64
67
|
return (
|
|
65
|
-
(rawEnv[field] as Environment[K]) ??
|
|
68
|
+
(rawEnv[field] as Environment[K]) ??
|
|
69
|
+
transformFn(topLevelEnv?.[field]) ??
|
|
70
|
+
defaultValue
|
|
66
71
|
);
|
|
67
72
|
}
|
|
68
73
|
|
|
@@ -76,6 +81,7 @@ export function inheritableInLegacyEnvironments<K extends keyof Environment>(
|
|
|
76
81
|
rawEnv: RawEnvironment,
|
|
77
82
|
field: K,
|
|
78
83
|
validate: ValidatorFn,
|
|
84
|
+
transformFn: TransformFn<Environment[K]> = (v) => v,
|
|
79
85
|
defaultValue: Environment[K]
|
|
80
86
|
): Environment[K] {
|
|
81
87
|
return topLevelEnv === undefined || isLegacyEnv === true
|
|
@@ -85,7 +91,8 @@ export function inheritableInLegacyEnvironments<K extends keyof Environment>(
|
|
|
85
91
|
rawEnv,
|
|
86
92
|
field,
|
|
87
93
|
validate,
|
|
88
|
-
defaultValue
|
|
94
|
+
defaultValue,
|
|
95
|
+
transformFn
|
|
89
96
|
)
|
|
90
97
|
: notAllowedInNamedServiceEnvironment(
|
|
91
98
|
diagnostics,
|
|
@@ -95,6 +102,19 @@ export function inheritableInLegacyEnvironments<K extends keyof Environment>(
|
|
|
95
102
|
);
|
|
96
103
|
}
|
|
97
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Type of function that is used to transform an inheritable environment field.
|
|
107
|
+
*/
|
|
108
|
+
type TransformFn<T> = (fieldValue: T | undefined) => T | undefined;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Transform an environment field by appending current environment name to it.
|
|
112
|
+
*/
|
|
113
|
+
export const appendEnvName =
|
|
114
|
+
(envName: string): TransformFn<string | undefined> =>
|
|
115
|
+
(fieldValue) =>
|
|
116
|
+
fieldValue ? `${fieldValue}-${envName}` : undefined;
|
|
117
|
+
|
|
98
118
|
/**
|
|
99
119
|
* Log an error if this named environment is trying to override the value in the top-level
|
|
100
120
|
* environment, which is not allow for this field.
|
|
@@ -207,6 +227,25 @@ export const isString: ValidatorFn = (diagnostics, field, value) => {
|
|
|
207
227
|
return true;
|
|
208
228
|
};
|
|
209
229
|
|
|
230
|
+
/**
|
|
231
|
+
* Validate that the `name` field is compliant with EWC constraints.
|
|
232
|
+
*/
|
|
233
|
+
export const isValidName: ValidatorFn = (diagnostics, field, value) => {
|
|
234
|
+
if (
|
|
235
|
+
(typeof value === "string" && /^$|^[a-z0-9_ ][a-z0-9-_ ]*$/.test(value)) ||
|
|
236
|
+
value === undefined
|
|
237
|
+
) {
|
|
238
|
+
return true;
|
|
239
|
+
} else {
|
|
240
|
+
diagnostics.errors.push(
|
|
241
|
+
`Expected "${field}" to be of type string, alphanumeric and lowercase with dashes only but got ${JSON.stringify(
|
|
242
|
+
value
|
|
243
|
+
)}.`
|
|
244
|
+
);
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
210
249
|
/**
|
|
211
250
|
* Validate that the field is an array of strings.
|
|
212
251
|
*/
|
|
@@ -484,3 +523,53 @@ export const validateAdditionalProperties = (
|
|
|
484
523
|
}
|
|
485
524
|
return true;
|
|
486
525
|
};
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Get the names of the bindings collection in `value`.
|
|
529
|
+
*
|
|
530
|
+
* Will return an empty array if it doesn't understand the value
|
|
531
|
+
* passed in, so another form of validation should be
|
|
532
|
+
* performed externally.
|
|
533
|
+
*/
|
|
534
|
+
export const getBindingNames = (value: unknown): string[] => {
|
|
535
|
+
if (typeof value !== "object" || value === null) {
|
|
536
|
+
return [];
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
if (isBindingList(value)) {
|
|
540
|
+
return value.bindings.map(({ name }) => name);
|
|
541
|
+
} else if (isNamespaceList(value)) {
|
|
542
|
+
return value.map(({ binding }) => binding);
|
|
543
|
+
} else if (isRecord(value)) {
|
|
544
|
+
return Object.keys(value);
|
|
545
|
+
} else {
|
|
546
|
+
return [];
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
|
|
550
|
+
const isBindingList = (
|
|
551
|
+
value: unknown
|
|
552
|
+
): value is {
|
|
553
|
+
bindings: {
|
|
554
|
+
name: string;
|
|
555
|
+
}[];
|
|
556
|
+
} =>
|
|
557
|
+
isRecord(value) &&
|
|
558
|
+
"bindings" in value &&
|
|
559
|
+
Array.isArray(value.bindings) &&
|
|
560
|
+
value.bindings.every(
|
|
561
|
+
(binding) =>
|
|
562
|
+
isRecord(binding) && "name" in binding && typeof binding.name === "string"
|
|
563
|
+
);
|
|
564
|
+
|
|
565
|
+
const isNamespaceList = (value: unknown): value is { binding: string }[] =>
|
|
566
|
+
Array.isArray(value) &&
|
|
567
|
+
value.every(
|
|
568
|
+
(entry) =>
|
|
569
|
+
isRecord(entry) && "binding" in entry && typeof entry.binding === "string"
|
|
570
|
+
);
|
|
571
|
+
|
|
572
|
+
const isRecord = (
|
|
573
|
+
value: unknown
|
|
574
|
+
): value is Record<string | number | symbol, unknown> =>
|
|
575
|
+
typeof value === "object" && value !== null && !Array.isArray(value);
|