wrangler 0.0.0-e14e589 → 0.0.0-e1c615f
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 +51 -0
- package/package.json +39 -26
- package/pages/functions/buildWorker.ts +57 -0
- package/pages/functions/filepath-routing.test.ts +39 -0
- package/pages/functions/filepath-routing.ts +221 -0
- package/pages/functions/identifiers.ts +78 -0
- package/pages/functions/routes.ts +158 -0
- package/pages/functions/template-worker.ts +137 -0
- package/src/__tests__/dev.test.tsx +66 -0
- package/src/__tests__/index.test.ts +254 -120
- package/src/__tests__/jest.setup.ts +22 -0
- package/src/__tests__/kv.test.ts +1098 -0
- package/src/__tests__/mock-cfetch.ts +171 -0
- package/src/__tests__/mock-dialogs.ts +65 -0
- package/src/__tests__/run-in-tmp.ts +19 -0
- package/src/__tests__/run-wrangler.ts +32 -0
- package/src/api/form_data.ts +78 -72
- package/src/api/inspect.ts +0 -11
- package/src/api/preview.ts +29 -24
- package/src/api/worker.ts +46 -31
- package/src/cfetch/index.ts +102 -0
- package/src/cfetch/internal.ts +69 -0
- package/src/cli.ts +6 -7
- package/src/config.ts +39 -4
- package/src/dev.tsx +332 -128
- package/src/dialogs.tsx +4 -12
- package/src/index.tsx +397 -222
- package/src/kv.tsx +101 -45
- package/src/module-collection.ts +64 -0
- package/src/pages.tsx +839 -211
- package/src/proxy.ts +103 -0
- package/src/publish.ts +117 -45
- package/src/sites.tsx +6 -7
- package/src/tail.tsx +6 -4
- package/src/user.tsx +9 -16
- package/wrangler-dist/cli.js +123794 -528
- package/wrangler-dist/cli.js.map +3 -3
- package/src/__tests__/fixtures/init/.gitkeep +0 -0
- package/src/__tests__/mock-cfetch.js +0 -46
- package/src/cfetch.ts +0 -72
- package/src/util/fetch.ts +0 -74
package/src/proxy.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { connect } from "node:http2";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import type { Server, IncomingHttpHeaders, RequestListener } from "node:http";
|
|
4
|
+
import WebSocket from "faye-websocket";
|
|
5
|
+
import serveStatic from "serve-static";
|
|
6
|
+
|
|
7
|
+
export interface HttpProxyInit {
|
|
8
|
+
host: string;
|
|
9
|
+
assetPath?: string | null;
|
|
10
|
+
onRequest?: (headers: IncomingHttpHeaders) => void;
|
|
11
|
+
onResponse?: (headers: IncomingHttpHeaders) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Creates a HTTP/1 proxy that sends requests over HTTP/2.
|
|
16
|
+
*/
|
|
17
|
+
export function createHttpProxy(init: HttpProxyInit): Server {
|
|
18
|
+
const { host, assetPath, onRequest = () => {}, onResponse = () => {} } = init;
|
|
19
|
+
const remote = connect(`https://${host}`);
|
|
20
|
+
const local = createServer();
|
|
21
|
+
// HTTP/2 -> HTTP/2
|
|
22
|
+
local.on("stream", (stream, headers: IncomingHttpHeaders) => {
|
|
23
|
+
onRequest(headers);
|
|
24
|
+
headers[":authority"] = host;
|
|
25
|
+
const request = stream.pipe(remote.request(headers));
|
|
26
|
+
request.on("response", (responseHeaders: IncomingHttpHeaders) => {
|
|
27
|
+
onResponse(responseHeaders);
|
|
28
|
+
stream.respond(responseHeaders);
|
|
29
|
+
request.pipe(stream, { end: true });
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
// HTTP/1 -> HTTP/2
|
|
33
|
+
const handleRequest: RequestListener = (message, response) => {
|
|
34
|
+
const { httpVersionMajor, headers, method, url } = message;
|
|
35
|
+
if (httpVersionMajor >= 2) {
|
|
36
|
+
return; // Already handled by the "stream" event.
|
|
37
|
+
}
|
|
38
|
+
onRequest(headers);
|
|
39
|
+
headers[":method"] = method;
|
|
40
|
+
headers[":path"] = url;
|
|
41
|
+
headers[":authority"] = host;
|
|
42
|
+
headers[":scheme"] = "https";
|
|
43
|
+
for (const name of Object.keys(headers)) {
|
|
44
|
+
if (HTTP1_HEADERS.has(name.toLowerCase())) {
|
|
45
|
+
delete headers[name];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const request = message.pipe(remote.request(headers));
|
|
49
|
+
request.on("response", (responseHeaders) => {
|
|
50
|
+
const status = responseHeaders[":status"];
|
|
51
|
+
onResponse(responseHeaders);
|
|
52
|
+
for (const name of Object.keys(responseHeaders)) {
|
|
53
|
+
if (name.startsWith(":")) {
|
|
54
|
+
delete responseHeaders[name];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
response.writeHead(status, responseHeaders);
|
|
58
|
+
request.pipe(response, { end: true });
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
// If an asset path is defined, check the file system
|
|
62
|
+
// for a file first and serve if it exists.
|
|
63
|
+
if (assetPath) {
|
|
64
|
+
const handleAsset = serveStatic(assetPath, {
|
|
65
|
+
cacheControl: false,
|
|
66
|
+
});
|
|
67
|
+
local.on("request", (request, response) => {
|
|
68
|
+
handleAsset(request, response, () => {
|
|
69
|
+
handleRequest(request, response);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
} else {
|
|
73
|
+
local.on("request", handleRequest);
|
|
74
|
+
}
|
|
75
|
+
// HTTP/1 -> WebSocket (over HTTP/1)
|
|
76
|
+
local.on("upgrade", (message, socket, body) => {
|
|
77
|
+
const { headers, url } = message;
|
|
78
|
+
onRequest(headers);
|
|
79
|
+
headers["host"] = host;
|
|
80
|
+
const localWebsocket = new WebSocket(message, socket, body);
|
|
81
|
+
// TODO(soon): Custom WebSocket protocol is not working?
|
|
82
|
+
const remoteWebsocketClient = new WebSocket.Client(
|
|
83
|
+
`wss://${host}${url}`,
|
|
84
|
+
[],
|
|
85
|
+
{ headers }
|
|
86
|
+
);
|
|
87
|
+
localWebsocket.pipe(remoteWebsocketClient).pipe(localWebsocket);
|
|
88
|
+
});
|
|
89
|
+
remote.on("close", () => {
|
|
90
|
+
local.close();
|
|
91
|
+
});
|
|
92
|
+
return local;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const HTTP1_HEADERS = new Set([
|
|
96
|
+
"host",
|
|
97
|
+
"connection",
|
|
98
|
+
"upgrade",
|
|
99
|
+
"keep-alive",
|
|
100
|
+
"proxy-connection",
|
|
101
|
+
"transfer-encoding",
|
|
102
|
+
"http2-settings",
|
|
103
|
+
]);
|
package/src/publish.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import assert from "node:assert";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
3
4
|
import esbuild from "esbuild";
|
|
5
|
+
import { execa } from "execa";
|
|
4
6
|
import tmp from "tmp-promise";
|
|
7
|
+
import type { CfWorkerInit } from "./api/worker";
|
|
8
|
+
import { toFormData } from "./api/form_data";
|
|
9
|
+
import { fetchResult } from "./cfetch";
|
|
5
10
|
import type { Config } from "./config";
|
|
6
|
-
import
|
|
7
|
-
import { readFile } from "fs/promises";
|
|
8
|
-
import cfetch from "./cfetch";
|
|
9
|
-
import assert from "node:assert";
|
|
11
|
+
import makeModuleCollector from "./module-collection";
|
|
10
12
|
import { syncAssets } from "./sites";
|
|
11
13
|
|
|
12
14
|
type CfScriptFormat = void | "modules" | "service-worker";
|
|
@@ -22,6 +24,8 @@ type Props = {
|
|
|
22
24
|
triggers?: (string | number)[];
|
|
23
25
|
routes?: (string | number)[];
|
|
24
26
|
legacyEnv?: boolean;
|
|
27
|
+
jsxFactory: void | string;
|
|
28
|
+
jsxFragment: void | string;
|
|
25
29
|
};
|
|
26
30
|
|
|
27
31
|
function sleep(ms: number) {
|
|
@@ -47,19 +51,25 @@ export default async function publish(props: Props): Promise<void> {
|
|
|
47
51
|
const triggers = props.triggers || config.triggers?.crons;
|
|
48
52
|
const routes = props.routes || config.routes;
|
|
49
53
|
|
|
54
|
+
const jsxFactory = props.jsxFactory || config.jsx_factory;
|
|
55
|
+
const jsxFragment = props.jsxFragment || config.jsx_fragment;
|
|
56
|
+
|
|
50
57
|
assert(config.account_id, "missing account id");
|
|
51
58
|
|
|
59
|
+
let scriptName = props.name || config.name;
|
|
60
|
+
assert(
|
|
61
|
+
scriptName,
|
|
62
|
+
'You need to provide a name when publishing a worker. Either pass it as a cli arg with `--name <name>` or in your config file as `name = "<name>"`'
|
|
63
|
+
);
|
|
64
|
+
|
|
52
65
|
let file: string;
|
|
53
66
|
if (props.script) {
|
|
54
67
|
file = props.script;
|
|
55
|
-
assert(props.name, "name is required when using script");
|
|
56
68
|
} else {
|
|
57
69
|
assert(build?.upload?.main, "missing main file");
|
|
58
|
-
assert(config.name, "missing name");
|
|
59
70
|
file = path.join(path.dirname(__path__), build.upload.main);
|
|
60
71
|
}
|
|
61
72
|
|
|
62
|
-
let scriptName = props.script ? props.name : config.name;
|
|
63
73
|
if (props.legacyEnv) {
|
|
64
74
|
scriptName += props.env ? `-${props.env}` : "";
|
|
65
75
|
}
|
|
@@ -67,6 +77,18 @@ export default async function publish(props: Props): Promise<void> {
|
|
|
67
77
|
|
|
68
78
|
const destination = await tmp.dir({ unsafeCleanup: true });
|
|
69
79
|
|
|
80
|
+
if (props.config.build?.command) {
|
|
81
|
+
// TODO: add a deprecation message here?
|
|
82
|
+
console.log("running:", props.config.build.command);
|
|
83
|
+
const buildCommandPieces = props.config.build.command.split(" ");
|
|
84
|
+
await execa(buildCommandPieces[0], buildCommandPieces.slice(1), {
|
|
85
|
+
stdout: "inherit",
|
|
86
|
+
stderr: "inherit",
|
|
87
|
+
...(props.config.build?.cwd && { cwd: props.config.build.cwd }),
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const moduleCollector = makeModuleCollector();
|
|
70
92
|
const result = await esbuild.build({
|
|
71
93
|
...(props.public
|
|
72
94
|
? {
|
|
@@ -89,6 +111,13 @@ export default async function publish(props: Props): Promise<void> {
|
|
|
89
111
|
format: "esm",
|
|
90
112
|
sourcemap: true,
|
|
91
113
|
metafile: true,
|
|
114
|
+
conditions: ["worker", "browser"],
|
|
115
|
+
loader: {
|
|
116
|
+
".js": "jsx",
|
|
117
|
+
},
|
|
118
|
+
plugins: [moduleCollector.plugin],
|
|
119
|
+
...(jsxFactory && { jsxFactory }),
|
|
120
|
+
...(jsxFragment && { jsxFragment }),
|
|
92
121
|
});
|
|
93
122
|
|
|
94
123
|
const chunks = Object.entries(result.metafile.outputs).find(
|
|
@@ -120,7 +149,47 @@ export default async function publish(props: Props): Promise<void> {
|
|
|
120
149
|
}
|
|
121
150
|
|
|
122
151
|
const content = await readFile(chunks[0], { encoding: "utf-8" });
|
|
123
|
-
destination.cleanup();
|
|
152
|
+
await destination.cleanup();
|
|
153
|
+
|
|
154
|
+
// if config.migrations
|
|
155
|
+
// get current migration tag
|
|
156
|
+
let migrations;
|
|
157
|
+
if ("migrations" in config) {
|
|
158
|
+
const scripts = await fetchResult<{ id: string; migration_tag: string }[]>(
|
|
159
|
+
`/accounts/${accountId}/workers/scripts`
|
|
160
|
+
);
|
|
161
|
+
const script = scripts.find(({ id }) => id === scriptName);
|
|
162
|
+
if (script?.migration_tag) {
|
|
163
|
+
// was already published once
|
|
164
|
+
const foundIndex = config.migrations.findIndex(
|
|
165
|
+
(migration) => migration.tag === script.migration_tag
|
|
166
|
+
);
|
|
167
|
+
if (foundIndex === -1) {
|
|
168
|
+
console.warn(
|
|
169
|
+
`The published script ${scriptName} has a migration tag "${script.migration_tag}, which was not found in wrangler.toml. You may have already deleted it. Applying all available migrations to the script...`
|
|
170
|
+
);
|
|
171
|
+
migrations = {
|
|
172
|
+
old_tag: script.migration_tag,
|
|
173
|
+
new_tag: config.migrations[config.migrations.length - 1].tag,
|
|
174
|
+
steps: config.migrations.map(({ tag: _tag, ...rest }) => rest),
|
|
175
|
+
};
|
|
176
|
+
} else {
|
|
177
|
+
migrations = {
|
|
178
|
+
old_tag: script.migration_tag,
|
|
179
|
+
new_tag: config.migrations[config.migrations.length - 1].tag,
|
|
180
|
+
steps: config.migrations
|
|
181
|
+
.slice(foundIndex + 1)
|
|
182
|
+
.map(({ tag: _tag, ...rest }) => rest),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
} else {
|
|
186
|
+
migrations = {
|
|
187
|
+
new_tag: config.migrations[config.migrations.length - 1].tag,
|
|
188
|
+
steps: config.migrations.map(({ tag: _tag, ...rest }) => rest),
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
124
193
|
const assets =
|
|
125
194
|
props.public || props.site || props.config.site?.bucket // TODO: allow both
|
|
126
195
|
? await syncAssets(
|
|
@@ -131,42 +200,45 @@ export default async function publish(props: Props): Promise<void> {
|
|
|
131
200
|
)
|
|
132
201
|
: { manifest: undefined, namespace: undefined };
|
|
133
202
|
|
|
134
|
-
const envRootObj = props.env ? config[
|
|
203
|
+
const envRootObj = props.env ? config.env[props.env] || {} : config;
|
|
204
|
+
const bindings: CfWorkerInit["bindings"] = {
|
|
205
|
+
kv_namespaces: envRootObj.kv_namespaces?.concat(
|
|
206
|
+
assets.namespace
|
|
207
|
+
? { binding: "__STATIC_CONTENT", id: assets.namespace }
|
|
208
|
+
: []
|
|
209
|
+
),
|
|
210
|
+
vars: envRootObj.vars,
|
|
211
|
+
durable_objects: envRootObj.durable_objects,
|
|
212
|
+
services: envRootObj.experimental_services,
|
|
213
|
+
};
|
|
135
214
|
|
|
136
215
|
const worker: CfWorkerInit = {
|
|
216
|
+
name: scriptName,
|
|
137
217
|
main: {
|
|
138
|
-
name:
|
|
218
|
+
name: path.basename(chunks[0]),
|
|
139
219
|
content: content,
|
|
140
|
-
type:
|
|
141
|
-
(bundle.type === "esm" ? "modules" : "service-worker") === "modules"
|
|
142
|
-
? "esm"
|
|
143
|
-
: "commonjs",
|
|
220
|
+
type: bundle.type === "esm" ? "esm" : "commonjs",
|
|
144
221
|
},
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
name: "__STATIC_CONTENT_MANIFEST",
|
|
160
|
-
content: JSON.stringify(assets.manifest),
|
|
161
|
-
type: "text",
|
|
162
|
-
})
|
|
163
|
-
: [],
|
|
222
|
+
bindings,
|
|
223
|
+
...(migrations && { migrations }),
|
|
224
|
+
modules: moduleCollector.modules.concat(
|
|
225
|
+
assets.manifest
|
|
226
|
+
? {
|
|
227
|
+
name: "__STATIC_CONTENT_MANIFEST",
|
|
228
|
+
content: JSON.stringify(assets.manifest),
|
|
229
|
+
type: "text",
|
|
230
|
+
}
|
|
231
|
+
: []
|
|
232
|
+
),
|
|
233
|
+
compatibility_date: config.compatibility_date,
|
|
234
|
+
compatibility_flags: config.compatibility_flags,
|
|
235
|
+
usage_model: config.usage_model,
|
|
164
236
|
};
|
|
165
237
|
|
|
166
238
|
const start = Date.now();
|
|
167
|
-
|
|
239
|
+
function formatTime(duration: number) {
|
|
168
240
|
return `(${(duration / 1000).toFixed(2)} sec)`;
|
|
169
|
-
}
|
|
241
|
+
}
|
|
170
242
|
|
|
171
243
|
const notProd = !props.legacyEnv && props.env;
|
|
172
244
|
const workerName = notProd ? `${scriptName} (${envName})` : scriptName;
|
|
@@ -174,8 +246,8 @@ export default async function publish(props: Props): Promise<void> {
|
|
|
174
246
|
? `/accounts/${accountId}/workers/services/${scriptName}/environments/${envName}`
|
|
175
247
|
: `/accounts/${accountId}/workers/scripts/${scriptName}`;
|
|
176
248
|
|
|
177
|
-
// Upload the script so it has time to
|
|
178
|
-
const { available_on_subdomain } = await
|
|
249
|
+
// Upload the script so it has time to propagate.
|
|
250
|
+
const { available_on_subdomain } = await fetchResult(
|
|
179
251
|
`${workerUrl}?available_on_subdomain=true`,
|
|
180
252
|
{
|
|
181
253
|
method: "PUT",
|
|
@@ -189,7 +261,7 @@ export default async function publish(props: Props): Promise<void> {
|
|
|
189
261
|
const deployments: Promise<string[]>[] = [];
|
|
190
262
|
|
|
191
263
|
const userSubdomain = (
|
|
192
|
-
await
|
|
264
|
+
await fetchResult<{ subdomain: string }>(
|
|
193
265
|
`/accounts/${accountId}/workers/subdomain`
|
|
194
266
|
)
|
|
195
267
|
).subdomain;
|
|
@@ -203,7 +275,7 @@ export default async function publish(props: Props): Promise<void> {
|
|
|
203
275
|
// TODO: Make this configurable.
|
|
204
276
|
if (!available_on_subdomain) {
|
|
205
277
|
deployments.push(
|
|
206
|
-
|
|
278
|
+
fetchResult(`${workerUrl}/subdomain`, {
|
|
207
279
|
method: "POST",
|
|
208
280
|
body: JSON.stringify({ enabled: true }),
|
|
209
281
|
headers: {
|
|
@@ -215,8 +287,8 @@ export default async function publish(props: Props): Promise<void> {
|
|
|
215
287
|
// This is to prevent an issue where a negative cache-hit
|
|
216
288
|
// causes the subdomain to be unavailable for 30 seconds.
|
|
217
289
|
// This is a temporary measure until we fix this on the edge.
|
|
218
|
-
.then((url) => {
|
|
219
|
-
sleep(3000);
|
|
290
|
+
.then(async (url) => {
|
|
291
|
+
await sleep(3000);
|
|
220
292
|
return url;
|
|
221
293
|
})
|
|
222
294
|
);
|
|
@@ -227,7 +299,7 @@ export default async function publish(props: Props): Promise<void> {
|
|
|
227
299
|
// Update routing table for the script.
|
|
228
300
|
if (routes && routes.length) {
|
|
229
301
|
deployments.push(
|
|
230
|
-
|
|
302
|
+
fetchResult(`${workerUrl}/routes`, {
|
|
231
303
|
// TODO: PATCH will not delete previous routes on this script,
|
|
232
304
|
// whereas PUT will. We need to decide on the default behaviour
|
|
233
305
|
// and how to configure it.
|
|
@@ -252,7 +324,7 @@ export default async function publish(props: Props): Promise<void> {
|
|
|
252
324
|
// TODO: rename this to `schedules`?
|
|
253
325
|
if (triggers && triggers.length) {
|
|
254
326
|
deployments.push(
|
|
255
|
-
|
|
327
|
+
fetchResult(`${workerUrl}/schedules`, {
|
|
256
328
|
// TODO: Unlike routes, this endpoint does not support PATCH.
|
|
257
329
|
// So technically, this will override any previous schedules.
|
|
258
330
|
// We should change the endpoint to support PATCH.
|
package/src/sites.tsx
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
2
|
import { createReadStream } from "node:fs";
|
|
3
|
-
import
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
5
|
+
import { fetchResult } from "./cfetch";
|
|
4
6
|
import { listNamespaceKeys, listNamespaces, putBulkKeyValue } from "./kv";
|
|
5
7
|
|
|
6
|
-
import * as path from "path";
|
|
7
|
-
import crypto from "node:crypto";
|
|
8
|
-
|
|
9
8
|
async function* getFilesInFolder(dirPath: string): AsyncIterable<string> {
|
|
10
9
|
const files = await readdir(dirPath, { withFileTypes: true });
|
|
11
10
|
for (const file of files) {
|
|
@@ -54,7 +53,7 @@ async function createKVNamespaceIfNotAlreadyExisting(
|
|
|
54
53
|
|
|
55
54
|
// else we make the namespace
|
|
56
55
|
// TODO: use an export from ./kv
|
|
57
|
-
const json = await
|
|
56
|
+
const json = await fetchResult<{ id: string }>(
|
|
58
57
|
`/accounts/${accountId}/storage/kv/namespaces`,
|
|
59
58
|
{
|
|
60
59
|
method: "POST",
|
|
@@ -76,7 +75,7 @@ export async function syncAssets(
|
|
|
76
75
|
scriptName: string,
|
|
77
76
|
dirPath: string,
|
|
78
77
|
preview: boolean,
|
|
79
|
-
|
|
78
|
+
_env?: string
|
|
80
79
|
) {
|
|
81
80
|
const title = `__${scriptName}_sites_assets${preview ? "_preview" : ""}`;
|
|
82
81
|
const { id: namespace } = await createKVNamespaceIfNotAlreadyExisting(
|
package/src/tail.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import WebSocket from "ws";
|
|
2
|
-
import cfetch from "./cfetch";
|
|
3
2
|
import { version as packageVersion } from "../package.json";
|
|
3
|
+
import { fetchResult } from "./cfetch";
|
|
4
4
|
|
|
5
5
|
export type TailApiResponse = {
|
|
6
6
|
id: string;
|
|
@@ -27,13 +27,15 @@ async function createTailButDontConnect(
|
|
|
27
27
|
): Promise<TailApiResponse> {
|
|
28
28
|
const createTailUrl = makeCreateTailUrl(accountId, workerName);
|
|
29
29
|
/// https://api.cloudflare.com/#worker-tail-logs-start-tail
|
|
30
|
-
return await
|
|
30
|
+
return await fetchResult<TailApiResponse>(createTailUrl, {
|
|
31
|
+
method: "POST",
|
|
32
|
+
});
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
export async function createTail(
|
|
34
36
|
accountId: string,
|
|
35
37
|
workerName: string,
|
|
36
|
-
|
|
38
|
+
_filters: Filters
|
|
37
39
|
): Promise<{
|
|
38
40
|
tail: WebSocket;
|
|
39
41
|
expiration: Date;
|
|
@@ -48,7 +50,7 @@ export async function createTail(
|
|
|
48
50
|
|
|
49
51
|
// deletes the tail
|
|
50
52
|
async function deleteTail() {
|
|
51
|
-
await
|
|
53
|
+
await fetchResult(deleteUrl, { method: "DELETE" });
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
const tail = new WebSocket(websocketUrl, "trace-v1", {
|
package/src/user.tsx
CHANGED
|
@@ -578,19 +578,16 @@ export async function getAuthURL(scopes?: string[]): Promise<string> {
|
|
|
578
578
|
* Refresh an access token from the remote service.
|
|
579
579
|
*/
|
|
580
580
|
async function exchangeRefreshTokenForAccessToken(): Promise<AccessContext> {
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
if (!refreshToken) {
|
|
581
|
+
if (!LocalState.refreshToken) {
|
|
584
582
|
console.warn("No refresh token is present.");
|
|
585
583
|
}
|
|
586
584
|
|
|
587
|
-
const url = TOKEN_URL;
|
|
588
585
|
const body =
|
|
589
586
|
`grant_type=refresh_token&` +
|
|
590
|
-
`refresh_token=${refreshToken?.value}&` +
|
|
587
|
+
`refresh_token=${LocalState.refreshToken?.value}&` +
|
|
591
588
|
`client_id=${CLIENT_ID}`;
|
|
592
589
|
|
|
593
|
-
const response = await fetch(
|
|
590
|
+
const response = await fetch(TOKEN_URL, {
|
|
594
591
|
method: "POST",
|
|
595
592
|
body,
|
|
596
593
|
headers: {
|
|
@@ -617,10 +614,9 @@ async function exchangeRefreshTokenForAccessToken(): Promise<AccessContext> {
|
|
|
617
614
|
LocalState.accessToken = accessToken;
|
|
618
615
|
|
|
619
616
|
if (refresh_token) {
|
|
620
|
-
|
|
617
|
+
LocalState.refreshToken = {
|
|
621
618
|
value: refresh_token,
|
|
622
619
|
};
|
|
623
|
-
LocalState.refreshToken = refreshToken;
|
|
624
620
|
}
|
|
625
621
|
|
|
626
622
|
if (scope) {
|
|
@@ -666,7 +662,6 @@ async function exchangeAuthCodeForAccessToken(): Promise<AccessContext> {
|
|
|
666
662
|
console.warn("No authorization grant code is being passed.");
|
|
667
663
|
}
|
|
668
664
|
|
|
669
|
-
const url = TOKEN_URL;
|
|
670
665
|
const body =
|
|
671
666
|
`grant_type=authorization_code&` +
|
|
672
667
|
`code=${encodeURIComponent(authorizationCode || "")}&` +
|
|
@@ -674,7 +669,7 @@ async function exchangeAuthCodeForAccessToken(): Promise<AccessContext> {
|
|
|
674
669
|
`client_id=${encodeURIComponent(CLIENT_ID)}&` +
|
|
675
670
|
`code_verifier=${codeVerifier}`;
|
|
676
671
|
|
|
677
|
-
const response = await fetch(
|
|
672
|
+
const response = await fetch(TOKEN_URL, {
|
|
678
673
|
method: "POST",
|
|
679
674
|
body,
|
|
680
675
|
headers: {
|
|
@@ -709,10 +704,9 @@ async function exchangeAuthCodeForAccessToken(): Promise<AccessContext> {
|
|
|
709
704
|
LocalState.accessToken = accessToken;
|
|
710
705
|
|
|
711
706
|
if (refresh_token) {
|
|
712
|
-
|
|
707
|
+
LocalState.refreshToken = {
|
|
713
708
|
value: refresh_token,
|
|
714
709
|
};
|
|
715
|
-
LocalState.refreshToken = refreshToken;
|
|
716
710
|
}
|
|
717
711
|
|
|
718
712
|
if (scope) {
|
|
@@ -816,7 +810,7 @@ export async function loginOrRefreshIfRequired(): Promise<boolean> {
|
|
|
816
810
|
|
|
817
811
|
export async function login(props?: LoginProps): Promise<boolean> {
|
|
818
812
|
const urlToOpen = await getAuthURL(props?.scopes);
|
|
819
|
-
open(urlToOpen);
|
|
813
|
+
await open(urlToOpen);
|
|
820
814
|
// TODO: log url only if on system where it's unreliable/unavailable
|
|
821
815
|
// console.log(`💁 Opened ${urlToOpen}`);
|
|
822
816
|
let server;
|
|
@@ -921,15 +915,14 @@ export async function refreshToken(): Promise<boolean> {
|
|
|
921
915
|
|
|
922
916
|
export async function logout(): Promise<void> {
|
|
923
917
|
throwIfNotInitialised();
|
|
924
|
-
|
|
925
|
-
if (!refreshToken) {
|
|
918
|
+
if (!LocalState.refreshToken) {
|
|
926
919
|
console.log("Not logged in, exiting...");
|
|
927
920
|
return;
|
|
928
921
|
}
|
|
929
922
|
const body =
|
|
930
923
|
`client_id=${encodeURIComponent(CLIENT_ID)}&` +
|
|
931
924
|
`token_type_hint=refresh_token&` +
|
|
932
|
-
`token=${encodeURIComponent(refreshToken?.value || "")}`;
|
|
925
|
+
`token=${encodeURIComponent(LocalState.refreshToken?.value || "")}`;
|
|
933
926
|
|
|
934
927
|
const response = await fetch(REVOKE_URL, {
|
|
935
928
|
method: "POST",
|