wrangler 2.1.6 → 2.1.8
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 +5 -20
- package/package.json +14 -3
- package/src/__tests__/api-dev.test.ts +20 -0
- package/src/__tests__/configuration.test.ts +125 -22
- package/src/__tests__/dev.test.tsx +0 -2
- package/src/__tests__/helpers/mock-oauth-flow.ts +4 -2
- package/src/__tests__/index.test.ts +2 -0
- package/src/__tests__/paths.test.ts +23 -1
- package/src/__tests__/publish.test.ts +8 -10
- package/src/__tests__/user.test.ts +4 -4
- package/src/__tests__/whoami.test.tsx +0 -1
- package/src/__tests__/worker-namespace.test.ts +102 -112
- package/src/api/dev.ts +12 -12
- package/src/bundle.ts +59 -1
- package/src/cfetch/internal.ts +37 -21
- package/src/config/environment.ts +20 -0
- package/src/config/index.ts +32 -0
- package/src/config/validation.ts +59 -0
- package/src/config-cache.ts +1 -1
- package/src/create-worker-upload-form.ts +9 -0
- package/src/d1/backups.tsx +212 -0
- package/src/d1/create.tsx +54 -0
- package/src/d1/delete.tsx +56 -0
- package/src/d1/execute.tsx +294 -0
- package/src/d1/formatTimeAgo.ts +14 -0
- package/src/d1/index.ts +75 -0
- package/src/d1/list.tsx +48 -0
- package/src/d1/options.ts +12 -0
- package/src/d1/types.tsx +14 -0
- package/src/d1/utils.ts +39 -0
- package/src/dev/dev.tsx +30 -3
- package/src/dev/get-local-persistence-path.tsx +31 -0
- package/src/dev/local.tsx +73 -11
- package/src/dev/start-server.ts +6 -3
- package/src/dev/use-esbuild.ts +12 -1
- package/src/dev.tsx +48 -29
- package/src/dialogs.tsx +4 -0
- package/src/environment-variables.ts +17 -2
- package/src/index.tsx +18 -16
- package/src/logger.ts +11 -4
- package/src/miniflare-cli/index.ts +11 -16
- package/src/pages/dev.tsx +13 -9
- package/src/paths.ts +30 -4
- package/src/proxy.ts +21 -1
- package/src/publish.ts +7 -0
- package/src/user/user.tsx +1 -0
- package/src/worker.ts +30 -0
- package/templates/d1-beta-facade.js +174 -0
- package/templates/experimental-local-cache-stubs.js +27 -0
- package/wrangler-dist/cli.d.ts +438 -7
- package/wrangler-dist/cli.js +11679 -3911
- package/src/miniflare-cli/enum-keys.ts +0 -17
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { rest } from "msw";
|
|
1
2
|
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
|
|
2
|
-
import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
|
|
3
3
|
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
4
|
+
import { msw } from "./helpers/msw";
|
|
4
5
|
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
5
6
|
import { runWrangler } from "./helpers/run-wrangler";
|
|
6
7
|
|
|
@@ -10,10 +11,6 @@ describe("dispatch-namespace", () => {
|
|
|
10
11
|
mockAccountId();
|
|
11
12
|
mockApiToken();
|
|
12
13
|
|
|
13
|
-
afterEach(() => {
|
|
14
|
-
unsetAllMocks();
|
|
15
|
-
});
|
|
16
|
-
|
|
17
14
|
it("should should display a list of available subcommands, for dispatch-namespace with no subcommand", async () => {
|
|
18
15
|
await runWrangler("dispatch-namespace");
|
|
19
16
|
|
|
@@ -45,31 +42,30 @@ describe("dispatch-namespace", () => {
|
|
|
45
42
|
});
|
|
46
43
|
|
|
47
44
|
describe("create namespace", () => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
45
|
+
const namespaceName = "my-namespace";
|
|
46
|
+
let counter = 0;
|
|
47
|
+
msw.use(
|
|
48
|
+
rest.post(
|
|
49
|
+
"/accounts/:accountId/workers/dispatch/namespaces/:namespaceNameParam",
|
|
50
|
+
(req, res, cxt) => {
|
|
51
|
+
counter++;
|
|
52
|
+
const { namespaceNameParam } = req.params;
|
|
53
|
+
expect(counter).toBe(1);
|
|
54
|
+
expect(namespaceNameParam).toBe(namespaceName);
|
|
55
|
+
return res.once(
|
|
56
|
+
cxt.status(200),
|
|
57
|
+
cxt.json({
|
|
58
|
+
namespace_id: "some-namespace-id",
|
|
59
|
+
namespace_name: "namespace-name",
|
|
60
|
+
created_on: "2022-06-29T14:30:08.16152Z",
|
|
61
|
+
created_by: "1fc1df98cc4420fe00367c3ab68c1639",
|
|
62
|
+
modified_on: "2022-06-29T14:30:08.16152Z",
|
|
63
|
+
modified_by: "1fc1df98cc4420fe00367c3ab68c1639",
|
|
64
|
+
})
|
|
65
|
+
);
|
|
69
66
|
}
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
}
|
|
67
|
+
)
|
|
68
|
+
);
|
|
73
69
|
|
|
74
70
|
it("should display help for create", async () => {
|
|
75
71
|
await expect(
|
|
@@ -95,10 +91,7 @@ describe("dispatch-namespace", () => {
|
|
|
95
91
|
});
|
|
96
92
|
|
|
97
93
|
it("should attempt to create the given namespace", async () => {
|
|
98
|
-
const namespaceName = "my-namespace";
|
|
99
|
-
const requests = mockCreateRequest(namespaceName);
|
|
100
94
|
await runWrangler(`dispatch-namespace create ${namespaceName}`);
|
|
101
|
-
expect(requests.count).toEqual(1);
|
|
102
95
|
|
|
103
96
|
expect(std.out).toMatchInlineSnapshot(
|
|
104
97
|
`"Created dispatch namespace \\"my-namespace\\" with ID \\"some-namespace-id\\""`
|
|
@@ -107,21 +100,20 @@ describe("dispatch-namespace", () => {
|
|
|
107
100
|
});
|
|
108
101
|
|
|
109
102
|
describe("delete namespace", () => {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
expect(
|
|
119
|
-
|
|
120
|
-
return null;
|
|
103
|
+
const namespaceName = "my-namespace";
|
|
104
|
+
let counter = 0;
|
|
105
|
+
msw.use(
|
|
106
|
+
rest.delete(
|
|
107
|
+
"/accounts/:accountId/workers/dispatch/namespaces/:namespaceNameParam",
|
|
108
|
+
(req, res, cxt) => {
|
|
109
|
+
counter++;
|
|
110
|
+
const { namespaceNameParam } = req.params;
|
|
111
|
+
expect(counter).toBe(1);
|
|
112
|
+
expect(namespaceNameParam).toBe(namespaceName);
|
|
113
|
+
return res.once(cxt.status(200), cxt.json(null));
|
|
121
114
|
}
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
}
|
|
115
|
+
)
|
|
116
|
+
);
|
|
125
117
|
|
|
126
118
|
it("should display help for delete", async () => {
|
|
127
119
|
await expect(
|
|
@@ -147,10 +139,7 @@ describe("dispatch-namespace", () => {
|
|
|
147
139
|
});
|
|
148
140
|
|
|
149
141
|
it("should try to delete the given namespace", async () => {
|
|
150
|
-
const namespaceName = "my-namespace";
|
|
151
|
-
const requests = mockDeleteRequest(namespaceName);
|
|
152
142
|
await runWrangler(`dispatch-namespace delete ${namespaceName}`);
|
|
153
|
-
expect(requests.count).toBe(1);
|
|
154
143
|
|
|
155
144
|
expect(std.out).toMatchInlineSnapshot(
|
|
156
145
|
`"Deleted dispatch namespace \\"my-namespace\\""`
|
|
@@ -159,27 +148,30 @@ describe("dispatch-namespace", () => {
|
|
|
159
148
|
});
|
|
160
149
|
|
|
161
150
|
describe("get namespace", () => {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
151
|
+
const namespaceName = "my-namespace";
|
|
152
|
+
let counter = 0;
|
|
153
|
+
msw.use(
|
|
154
|
+
rest.get(
|
|
155
|
+
"/accounts/:accountId/workers/dispatch/namespaces/:namespaceNameParam",
|
|
156
|
+
(req, res, cxt) => {
|
|
157
|
+
counter++;
|
|
158
|
+
const { namespaceNameParam } = req.params;
|
|
159
|
+
expect(counter).toBe(1);
|
|
160
|
+
expect(namespaceNameParam).toBe(namespaceName);
|
|
161
|
+
return res.once(
|
|
162
|
+
cxt.status(200),
|
|
163
|
+
cxt.json({
|
|
164
|
+
namespace_id: "some-namespace-id",
|
|
165
|
+
namespace_name: "namespace-name",
|
|
166
|
+
created_on: "2022-06-29T14:30:08.16152Z",
|
|
167
|
+
created_by: "1fc1df98cc4420fe00367c3ab68c1639",
|
|
168
|
+
modified_on: "2022-06-29T14:30:08.16152Z",
|
|
169
|
+
modified_by: "1fc1df98cc4420fe00367c3ab68c1639",
|
|
170
|
+
})
|
|
171
|
+
);
|
|
179
172
|
}
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
}
|
|
173
|
+
)
|
|
174
|
+
);
|
|
183
175
|
|
|
184
176
|
it("should display help for get", async () => {
|
|
185
177
|
await expect(
|
|
@@ -205,10 +197,7 @@ describe("dispatch-namespace", () => {
|
|
|
205
197
|
});
|
|
206
198
|
|
|
207
199
|
it("should attempt to get info for the given namespace", async () => {
|
|
208
|
-
const namespaceName = "my-namespace";
|
|
209
|
-
const requests = mockInfoRequest(namespaceName);
|
|
210
200
|
await runWrangler(`dispatch-namespace get ${namespaceName}`);
|
|
211
|
-
expect(requests.count).toBe(1);
|
|
212
201
|
|
|
213
202
|
expect(std.out).toMatchInlineSnapshot(`
|
|
214
203
|
"{
|
|
@@ -224,32 +213,33 @@ describe("dispatch-namespace", () => {
|
|
|
224
213
|
});
|
|
225
214
|
|
|
226
215
|
describe("list namespaces", () => {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
216
|
+
const namespaceName = "my-namespace";
|
|
217
|
+
let counter = 0;
|
|
218
|
+
msw.use(
|
|
219
|
+
rest.get(
|
|
220
|
+
"/accounts/:accountId/workers/dispatch/namespaces/:namespaceNameParam",
|
|
221
|
+
(req, res, cxt) => {
|
|
222
|
+
counter++;
|
|
223
|
+
const { namespaceNameParam } = req.params;
|
|
224
|
+
expect(counter).toBe(1);
|
|
225
|
+
expect(namespaceNameParam).toBe(namespaceName);
|
|
226
|
+
return res.once(
|
|
227
|
+
cxt.status(200),
|
|
228
|
+
cxt.json({
|
|
236
229
|
namespace_id: "some-namespace-id",
|
|
237
230
|
namespace_name: "namespace-name",
|
|
238
231
|
created_on: "2022-06-29T14:30:08.16152Z",
|
|
239
232
|
created_by: "1fc1df98cc4420fe00367c3ab68c1639",
|
|
240
233
|
modified_on: "2022-06-29T14:30:08.16152Z",
|
|
241
234
|
modified_by: "1fc1df98cc4420fe00367c3ab68c1639",
|
|
242
|
-
}
|
|
243
|
-
|
|
235
|
+
})
|
|
236
|
+
);
|
|
244
237
|
}
|
|
245
|
-
)
|
|
246
|
-
|
|
247
|
-
}
|
|
238
|
+
)
|
|
239
|
+
);
|
|
248
240
|
|
|
249
241
|
it("should list all namespaces", async () => {
|
|
250
|
-
const requests = mockListRequest();
|
|
251
242
|
await runWrangler("dispatch-namespace list");
|
|
252
|
-
expect(requests.count).toBe(1);
|
|
253
243
|
expect(std.out).toMatchInlineSnapshot(`
|
|
254
244
|
"[
|
|
255
245
|
{
|
|
@@ -266,28 +256,30 @@ describe("dispatch-namespace", () => {
|
|
|
266
256
|
});
|
|
267
257
|
|
|
268
258
|
describe("rename namespace", () => {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
expect(
|
|
278
|
-
|
|
279
|
-
return
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
259
|
+
const namespaceName = "my-namespace";
|
|
260
|
+
let counter = 0;
|
|
261
|
+
msw.use(
|
|
262
|
+
rest.put(
|
|
263
|
+
"/accounts/:accountId/workers/dispatch/namespaces/:namespaceNameParam",
|
|
264
|
+
(req, res, cxt) => {
|
|
265
|
+
counter++;
|
|
266
|
+
const { namespaceNameParam } = req.params;
|
|
267
|
+
expect(counter).toBe(1);
|
|
268
|
+
expect(namespaceNameParam).toBe(namespaceName);
|
|
269
|
+
return res.once(
|
|
270
|
+
cxt.status(200),
|
|
271
|
+
cxt.json({
|
|
272
|
+
namespace_id: "some-namespace-id",
|
|
273
|
+
namespace_name: "namespace-name",
|
|
274
|
+
created_on: "2022-06-29T14:30:08.16152Z",
|
|
275
|
+
created_by: "1fc1df98cc4420fe00367c3ab68c1639",
|
|
276
|
+
modified_on: "2022-06-29T14:30:08.16152Z",
|
|
277
|
+
modified_by: "1fc1df98cc4420fe00367c3ab68c1639",
|
|
278
|
+
})
|
|
279
|
+
);
|
|
287
280
|
}
|
|
288
|
-
)
|
|
289
|
-
|
|
290
|
-
}
|
|
281
|
+
)
|
|
282
|
+
);
|
|
291
283
|
|
|
292
284
|
it("should display help for rename", async () => {
|
|
293
285
|
await expect(
|
|
@@ -314,13 +306,11 @@ describe("dispatch-namespace", () => {
|
|
|
314
306
|
});
|
|
315
307
|
|
|
316
308
|
it("should attempt to rename the given namespace", async () => {
|
|
317
|
-
const namespaceName = "my-namespace";
|
|
318
309
|
const newName = "new-namespace";
|
|
319
|
-
const requests = mockRenameRequest(namespaceName);
|
|
320
310
|
await runWrangler(
|
|
321
311
|
`dispatch-namespace rename ${namespaceName} ${newName}`
|
|
322
312
|
);
|
|
323
|
-
|
|
313
|
+
|
|
324
314
|
expect(std.out).toMatchInlineSnapshot(
|
|
325
315
|
`"Renamed dispatch namespace \\"my-namespace\\" to \\"new-namespace\\""`
|
|
326
316
|
);
|
package/src/api/dev.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { fetch, Request } from "undici";
|
|
|
2
2
|
import { startApiDev, startDev } from "../dev";
|
|
3
3
|
import { logger } from "../logger";
|
|
4
4
|
|
|
5
|
+
import type { Environment } from "../config";
|
|
5
6
|
import type { EnablePagesAssetsServiceBindingOptions } from "../miniflare-cli";
|
|
6
7
|
import type { RequestInit, Response, RequestInfo } from "undici";
|
|
7
8
|
|
|
@@ -10,7 +11,7 @@ interface DevOptions {
|
|
|
10
11
|
env?: string;
|
|
11
12
|
ip?: string;
|
|
12
13
|
port?: number;
|
|
13
|
-
|
|
14
|
+
bundle?: boolean;
|
|
14
15
|
inspectorPort?: number;
|
|
15
16
|
localProtocol?: "http" | "https";
|
|
16
17
|
assets?: string;
|
|
@@ -43,8 +44,9 @@ interface DevOptions {
|
|
|
43
44
|
bucket_name: string;
|
|
44
45
|
preview_bucket_name?: string;
|
|
45
46
|
}[];
|
|
47
|
+
d1Databases?: Environment["d1_databases"];
|
|
46
48
|
showInteractiveDevSession?: boolean;
|
|
47
|
-
logLevel?: "none" | "error" | "log" | "warn" | "debug";
|
|
49
|
+
logLevel?: "none" | "info" | "error" | "log" | "warn" | "debug";
|
|
48
50
|
logPrefix?: string;
|
|
49
51
|
inspect?: boolean;
|
|
50
52
|
forceLocal?: boolean;
|
|
@@ -60,25 +62,20 @@ interface DevApiOptions {
|
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
export interface UnstableDevWorker {
|
|
65
|
+
port: number;
|
|
66
|
+
address: string;
|
|
63
67
|
stop: () => Promise<void>;
|
|
64
|
-
fetch: (
|
|
65
|
-
input?: RequestInfo,
|
|
66
|
-
init?: RequestInit
|
|
67
|
-
) => Promise<Response | undefined>;
|
|
68
|
+
fetch: (input?: RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
68
69
|
waitUntilExit: () => Promise<void>;
|
|
69
70
|
}
|
|
70
71
|
/**
|
|
71
72
|
* unstable_dev starts a wrangler dev server, and returns a promise that resolves with utility functions to interact with it.
|
|
72
|
-
* @param {string} script
|
|
73
|
-
* @param {DevOptions} options
|
|
74
|
-
* @param {DevApiOptions} apiOptions
|
|
75
|
-
* @returns {Promise<UnstableDev>}
|
|
76
73
|
*/
|
|
77
74
|
export async function unstable_dev(
|
|
78
75
|
script: string,
|
|
79
76
|
options?: DevOptions,
|
|
80
77
|
apiOptions?: DevApiOptions
|
|
81
|
-
) {
|
|
78
|
+
): Promise<UnstableDevWorker> {
|
|
82
79
|
const { testMode = true, disableExperimentalWarning = false } =
|
|
83
80
|
apiOptions || {};
|
|
84
81
|
if (!disableExperimentalWarning) {
|
|
@@ -116,6 +113,8 @@ export async function unstable_dev(
|
|
|
116
113
|
// now that the inner promise has resolved, we can resolve the outer promise
|
|
117
114
|
// with an object that lets you fetch and stop the dev server
|
|
118
115
|
resolve({
|
|
116
|
+
port: readyPort,
|
|
117
|
+
address: readyAddress,
|
|
119
118
|
stop: devServer.stop,
|
|
120
119
|
fetch: async (input?: RequestInfo, init?: RequestInit) => {
|
|
121
120
|
return await fetch(
|
|
@@ -144,7 +143,6 @@ export async function unstable_dev(
|
|
|
144
143
|
const devServer = startDev({
|
|
145
144
|
script: script,
|
|
146
145
|
inspect: false,
|
|
147
|
-
logLevel: "none",
|
|
148
146
|
showInteractiveDevSession: false,
|
|
149
147
|
_: [],
|
|
150
148
|
$0: "",
|
|
@@ -158,6 +156,8 @@ export async function unstable_dev(
|
|
|
158
156
|
});
|
|
159
157
|
}).then((devServer) => {
|
|
160
158
|
resolve({
|
|
159
|
+
port: readyPort,
|
|
160
|
+
address: readyAddress,
|
|
161
161
|
stop: devServer.stop,
|
|
162
162
|
fetch: async (input?: RequestInfo, init?: RequestInit) => {
|
|
163
163
|
return await fetch(
|
package/src/bundle.ts
CHANGED
|
@@ -63,6 +63,7 @@ export async function bundleWorker(
|
|
|
63
63
|
options: {
|
|
64
64
|
serveAssetsFromWorker: boolean;
|
|
65
65
|
assets: StaticAssetsConfig;
|
|
66
|
+
betaD1Shims?: string[];
|
|
66
67
|
jsxFactory: string | undefined;
|
|
67
68
|
jsxFragment: string | undefined;
|
|
68
69
|
rules: Config["rules"];
|
|
@@ -76,11 +77,14 @@ export async function bundleWorker(
|
|
|
76
77
|
workerDefinitions: WorkerRegistry | undefined;
|
|
77
78
|
firstPartyWorkerDevFacade: boolean | undefined;
|
|
78
79
|
targetConsumer: "dev" | "publish";
|
|
80
|
+
local: boolean;
|
|
79
81
|
testScheduled?: boolean | undefined;
|
|
82
|
+
experimentalLocalStubCache: boolean | undefined;
|
|
80
83
|
}
|
|
81
84
|
): Promise<BundleResult> {
|
|
82
85
|
const {
|
|
83
86
|
serveAssetsFromWorker,
|
|
87
|
+
betaD1Shims,
|
|
84
88
|
jsxFactory,
|
|
85
89
|
jsxFragment,
|
|
86
90
|
rules,
|
|
@@ -89,12 +93,14 @@ export async function bundleWorker(
|
|
|
89
93
|
minify,
|
|
90
94
|
nodeCompat,
|
|
91
95
|
checkFetch,
|
|
96
|
+
local,
|
|
92
97
|
assets,
|
|
93
98
|
workerDefinitions,
|
|
94
99
|
services,
|
|
95
100
|
firstPartyWorkerDevFacade,
|
|
96
101
|
targetConsumer,
|
|
97
102
|
testScheduled,
|
|
103
|
+
experimentalLocalStubCache,
|
|
98
104
|
} = options;
|
|
99
105
|
|
|
100
106
|
// We create a temporary directory for any oneoff files we
|
|
@@ -188,6 +194,12 @@ export async function bundleWorker(
|
|
|
188
194
|
return applyFirstPartyWorkerDevFacade(currentEntry, tmpDir.path);
|
|
189
195
|
}),
|
|
190
196
|
|
|
197
|
+
Array.isArray(betaD1Shims) &&
|
|
198
|
+
betaD1Shims.length > 0 &&
|
|
199
|
+
((currentEntry: Entry) => {
|
|
200
|
+
return applyD1BetaFacade(currentEntry, tmpDir.path, betaD1Shims, local);
|
|
201
|
+
}),
|
|
202
|
+
|
|
191
203
|
// Middleware loader: to add middleware, we add the path to the middleware
|
|
192
204
|
// Currently for demonstration purposes we have two example middlewares
|
|
193
205
|
// Middlewares are togglable by changing the `publish` (default=false) and `dev` (default=true) options
|
|
@@ -223,12 +235,20 @@ export async function bundleWorker(
|
|
|
223
235
|
|
|
224
236
|
// At this point, inputEntry points to the entry point we want to build.
|
|
225
237
|
|
|
238
|
+
const inject: string[] = [];
|
|
239
|
+
if (checkFetch) inject.push(checkedFetchFileToInject);
|
|
240
|
+
if (experimentalLocalStubCache) {
|
|
241
|
+
inject.push(
|
|
242
|
+
path.resolve(getBasePath(), "templates/experimental-local-cache-stubs.js")
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
226
246
|
const result = await esbuild.build({
|
|
227
247
|
entryPoints: [inputEntry.file],
|
|
228
248
|
bundle: true,
|
|
229
249
|
absWorkingDir: entry.directory,
|
|
230
250
|
outdir: destination,
|
|
231
|
-
inject
|
|
251
|
+
inject,
|
|
232
252
|
external: ["__STATIC_CONTENT_MANIFEST"],
|
|
233
253
|
format: entry.format === "modules" ? "esm" : "iife",
|
|
234
254
|
target: "es2020",
|
|
@@ -686,6 +706,44 @@ async function applyFirstPartyWorkerDevFacade(
|
|
|
686
706
|
};
|
|
687
707
|
}
|
|
688
708
|
|
|
709
|
+
/**
|
|
710
|
+
* A middleware that injects the beta D1 API in JS.
|
|
711
|
+
*
|
|
712
|
+
* This code be removed from here when the API is in Workers core,
|
|
713
|
+
* but moved inside Miniflare for simulating D1.
|
|
714
|
+
*/
|
|
715
|
+
|
|
716
|
+
async function applyD1BetaFacade(
|
|
717
|
+
entry: Entry,
|
|
718
|
+
tmpDirPath: string,
|
|
719
|
+
betaD1Shims: string[],
|
|
720
|
+
local: boolean
|
|
721
|
+
): Promise<Entry> {
|
|
722
|
+
const targetPath = path.join(tmpDirPath, "d1-beta-facade.entry.js");
|
|
723
|
+
|
|
724
|
+
await esbuild.build({
|
|
725
|
+
entryPoints: [path.resolve(getBasePath(), "templates/d1-beta-facade.js")],
|
|
726
|
+
bundle: true,
|
|
727
|
+
format: "esm",
|
|
728
|
+
sourcemap: true,
|
|
729
|
+
plugins: [
|
|
730
|
+
esbuildAliasExternalPlugin({
|
|
731
|
+
__ENTRY_POINT__: entry.file,
|
|
732
|
+
}),
|
|
733
|
+
],
|
|
734
|
+
define: {
|
|
735
|
+
__D1_IMPORTS__: JSON.stringify(betaD1Shims),
|
|
736
|
+
__LOCAL_MODE__: JSON.stringify(local),
|
|
737
|
+
},
|
|
738
|
+
outfile: targetPath,
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
return {
|
|
742
|
+
...entry,
|
|
743
|
+
file: targetPath,
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
|
|
689
747
|
/**
|
|
690
748
|
* Generate a string that describes the entry-points that were identified by esbuild.
|
|
691
749
|
*/
|
package/src/cfetch/internal.ts
CHANGED
|
@@ -19,21 +19,18 @@ export const getCloudflareAPIBaseURL = getEnvironmentVariableFactory({
|
|
|
19
19
|
defaultValue: "https://api.cloudflare.com/client/v4",
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
|
|
28
|
-
*
|
|
29
|
-
* This function should not be used directly, instead use the functions in `cfetch/index.ts`.
|
|
30
|
-
*/
|
|
31
|
-
export async function fetchInternal<ResponseType>(
|
|
22
|
+
/*
|
|
23
|
+
* performApiFetch does everything required to make a CF API request,
|
|
24
|
+
* but doesn't parse the response as JSON. For normal V4 API responses,
|
|
25
|
+
* use `fetchInternal`
|
|
26
|
+
* */
|
|
27
|
+
export async function performApiFetch(
|
|
32
28
|
resource: string,
|
|
33
29
|
init: RequestInit = {},
|
|
34
30
|
queryParams?: URLSearchParams,
|
|
35
31
|
abortSignal?: AbortSignal
|
|
36
|
-
)
|
|
32
|
+
) {
|
|
33
|
+
const method = init.method ?? "GET";
|
|
37
34
|
assert(
|
|
38
35
|
resource.startsWith("/"),
|
|
39
36
|
`CF API fetch - resource path must start with a "/" but got "${resource}"`
|
|
@@ -45,22 +42,41 @@ export async function fetchInternal<ResponseType>(
|
|
|
45
42
|
addUserAgent(headers);
|
|
46
43
|
|
|
47
44
|
const queryString = queryParams ? `?${queryParams.toString()}` : "";
|
|
48
|
-
const method = init.method ?? "GET";
|
|
49
|
-
|
|
50
45
|
logger.debug(
|
|
51
46
|
`-- START CF API REQUEST: ${method} ${getCloudflareAPIBaseURL()}${resource}${queryString}`
|
|
52
47
|
);
|
|
53
48
|
logger.debug("HEADERS:", JSON.stringify(headers, null, 2));
|
|
54
49
|
logger.debug("INIT:", JSON.stringify(init, null, 2));
|
|
55
50
|
logger.debug("-- END CF API REQUEST");
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
51
|
+
return await fetch(`${getCloudflareAPIBaseURL()}${resource}${queryString}`, {
|
|
52
|
+
method,
|
|
53
|
+
...init,
|
|
54
|
+
headers,
|
|
55
|
+
signal: abortSignal,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Make a fetch request to the Cloudflare API.
|
|
61
|
+
*
|
|
62
|
+
* This function handles acquiring the API token and logging the caller in, as necessary.
|
|
63
|
+
*
|
|
64
|
+
* Check out https://api.cloudflare.com/ for API docs.
|
|
65
|
+
*
|
|
66
|
+
* This function should not be used directly, instead use the functions in `cfetch/index.ts`.
|
|
67
|
+
*/
|
|
68
|
+
export async function fetchInternal<ResponseType>(
|
|
69
|
+
resource: string,
|
|
70
|
+
init: RequestInit = {},
|
|
71
|
+
queryParams?: URLSearchParams,
|
|
72
|
+
abortSignal?: AbortSignal
|
|
73
|
+
): Promise<ResponseType> {
|
|
74
|
+
const method = init.method ?? "GET";
|
|
75
|
+
const response = await performApiFetch(
|
|
76
|
+
resource,
|
|
77
|
+
init,
|
|
78
|
+
queryParams,
|
|
79
|
+
abortSignal
|
|
64
80
|
);
|
|
65
81
|
const jsonText = await response.text();
|
|
66
82
|
logger.debug(
|
|
@@ -343,6 +343,26 @@ interface EnvironmentNonInheritable {
|
|
|
343
343
|
preview_bucket_name?: string;
|
|
344
344
|
}[];
|
|
345
345
|
|
|
346
|
+
/**
|
|
347
|
+
* Specifies D1 databases that are bound to this Worker environment.
|
|
348
|
+
*
|
|
349
|
+
* NOTE: This field is not automatically inherited from the top level environment,
|
|
350
|
+
* and so must be specified in every named environment.
|
|
351
|
+
*
|
|
352
|
+
* @default `[]`
|
|
353
|
+
* @nonInheritable
|
|
354
|
+
*/
|
|
355
|
+
d1_databases: {
|
|
356
|
+
/** The binding name used to refer to the D1 database in the worker. */
|
|
357
|
+
binding: string;
|
|
358
|
+
/** The name of this D1 database. */
|
|
359
|
+
database_name: string;
|
|
360
|
+
/** The UUID of this D1 database (not required). */
|
|
361
|
+
database_id: string;
|
|
362
|
+
/** The UUID of this D1 database for Wrangler Dev (if specified). */
|
|
363
|
+
preview_database_id?: string;
|
|
364
|
+
}[];
|
|
365
|
+
|
|
346
366
|
/**
|
|
347
367
|
* Specifies service bindings (worker-to-worker) that are bound to this Worker environment.
|
|
348
368
|
*
|
package/src/config/index.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { findUpSync } from "find-up";
|
|
2
2
|
import { logger } from "../logger";
|
|
3
3
|
import { parseTOML, readFileSync } from "../parse";
|
|
4
|
+
import { removeD1BetaPrefix } from "../worker";
|
|
4
5
|
import { normalizeAndValidateConfig } from "./validation";
|
|
5
6
|
import type { CfWorkerInit } from "../worker";
|
|
6
7
|
import type { Config, RawConfig } from "./config";
|
|
8
|
+
import type { CamelCaseKey } from "yargs";
|
|
7
9
|
|
|
8
10
|
export type {
|
|
9
11
|
Config,
|
|
@@ -84,6 +86,7 @@ export function printBindings(bindings: CfWorkerInit["bindings"]) {
|
|
|
84
86
|
data_blobs,
|
|
85
87
|
durable_objects,
|
|
86
88
|
kv_namespaces,
|
|
89
|
+
d1_databases,
|
|
87
90
|
r2_buckets,
|
|
88
91
|
logfwdr,
|
|
89
92
|
services,
|
|
@@ -138,6 +141,20 @@ export function printBindings(bindings: CfWorkerInit["bindings"]) {
|
|
|
138
141
|
});
|
|
139
142
|
}
|
|
140
143
|
|
|
144
|
+
if (d1_databases !== undefined && d1_databases.length > 0) {
|
|
145
|
+
output.push({
|
|
146
|
+
type: "D1 Databases",
|
|
147
|
+
entries: d1_databases.map(({ binding, database_name, database_id }) => {
|
|
148
|
+
return {
|
|
149
|
+
key: removeD1BetaPrefix(binding),
|
|
150
|
+
value: database_name
|
|
151
|
+
? `${database_name} (${database_id})`
|
|
152
|
+
: database_id,
|
|
153
|
+
};
|
|
154
|
+
}),
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
141
158
|
if (r2_buckets !== undefined && r2_buckets.length > 0) {
|
|
142
159
|
output.push({
|
|
143
160
|
type: "R2 Buckets",
|
|
@@ -249,3 +266,18 @@ export function printBindings(bindings: CfWorkerInit["bindings"]) {
|
|
|
249
266
|
|
|
250
267
|
logger.log(message);
|
|
251
268
|
}
|
|
269
|
+
|
|
270
|
+
type CamelCase<T> = {
|
|
271
|
+
[key in keyof T as key | CamelCaseKey<key>]: T[key];
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
export function withConfig<T extends { config?: string }>(
|
|
275
|
+
handler: (
|
|
276
|
+
t: Omit<CamelCase<T>, "config"> & { config: Config }
|
|
277
|
+
) => Promise<void>
|
|
278
|
+
) {
|
|
279
|
+
return (t: CamelCase<T>) => {
|
|
280
|
+
const { config: configPath, ...rest } = t;
|
|
281
|
+
return handler({ ...rest, config: readConfig(configPath, rest) });
|
|
282
|
+
};
|
|
283
|
+
}
|