wrangler 0.0.0-e7a0cd5b → 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/README.md +3 -3
- package/bin/wrangler.js +30 -10
- package/miniflare-dist/index.mjs +254 -128
- package/package.json +27 -19
- package/src/__tests__/api-dev.test.ts +65 -36
- package/src/__tests__/api-devregistry.test.ts +121 -0
- package/src/__tests__/api.test.ts +27 -5
- package/src/__tests__/configuration.test.ts +797 -98
- package/src/__tests__/constellation.test.ts +371 -0
- package/src/__tests__/d1/d1.test.ts +82 -0
- package/src/__tests__/d1/execute.test.ts +66 -0
- package/src/__tests__/d1/migrate.test.ts +257 -0
- package/src/__tests__/d1/splitter.test.ts +255 -0
- package/src/__tests__/delete.test.ts +91 -49
- package/src/__tests__/deployments.test.ts +330 -56
- package/src/__tests__/dev.test.tsx +198 -90
- package/src/__tests__/generate.test.ts +12 -10
- package/src/__tests__/guess-worker-format.test.ts +35 -0
- package/src/__tests__/helpers/end-event-loop.ts +6 -0
- package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
- package/src/__tests__/helpers/mock-console.ts +6 -0
- package/src/__tests__/helpers/mock-dialogs.ts +71 -85
- package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
- package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -5
- package/src/__tests__/helpers/mock-known-routes.ts +7 -2
- package/src/__tests__/helpers/mock-kv.ts +29 -16
- package/src/__tests__/helpers/mock-oauth-flow.ts +103 -92
- package/src/__tests__/helpers/mock-process.ts +8 -13
- package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
- package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
- package/src/__tests__/helpers/msw/handlers/deployments.ts +128 -27
- package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
- package/src/__tests__/helpers/msw/handlers/oauth.ts +13 -18
- package/src/__tests__/helpers/msw/handlers/r2.ts +14 -34
- package/src/__tests__/helpers/msw/handlers/script.ts +9 -28
- package/src/__tests__/helpers/msw/handlers/user.ts +13 -24
- package/src/__tests__/helpers/msw/handlers/zones.ts +6 -8
- package/src/__tests__/helpers/msw/index.ts +32 -1
- package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
- package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
- package/src/__tests__/helpers/worker-scripts/parent-worker.js +4 -1
- package/src/__tests__/index.test.ts +92 -72
- package/src/__tests__/init.test.ts +1033 -631
- package/src/__tests__/jest.setup.ts +19 -42
- package/src/__tests__/kv.test.ts +355 -231
- package/src/__tests__/logger.test.ts +68 -2
- package/src/__tests__/logout.test.ts +47 -0
- package/src/__tests__/metrics.test.ts +94 -51
- package/src/__tests__/middleware.scheduled.test.ts +42 -32
- package/src/__tests__/middleware.test.ts +212 -122
- package/src/__tests__/mtls-certificates.test.ts +589 -0
- package/src/__tests__/pages/deployment-list.test.ts +80 -0
- package/src/__tests__/pages/functions-build.test.ts +529 -0
- package/src/__tests__/pages/pages.test.ts +81 -0
- package/src/__tests__/pages/project-create.test.ts +63 -0
- package/src/__tests__/pages/project-list.test.ts +110 -0
- package/src/__tests__/pages/project-upload.test.ts +500 -0
- package/src/__tests__/pages/publish.test.ts +2864 -0
- package/src/__tests__/pages-deployment-tail.test.ts +957 -0
- package/src/__tests__/parse.test.ts +106 -0
- package/src/__tests__/publish.test.ts +2227 -1005
- package/src/__tests__/pubsub.test.ts +226 -100
- package/src/__tests__/queues.test.ts +238 -77
- package/src/__tests__/r2.test.ts +55 -57
- package/src/__tests__/secret.test.ts +179 -130
- package/src/__tests__/tail.test.ts +313 -113
- package/src/__tests__/test-old-node-version.js +3 -3
- package/src/__tests__/traverse-module-graph.test.ts +220 -0
- package/src/__tests__/tsconfig-sanity.ts +12 -0
- package/src/__tests__/tsconfig.json +8 -0
- package/src/__tests__/tsconfig.tsbuildinfo +1 -0
- package/src/__tests__/type-generation.test.ts +43 -26
- package/src/__tests__/unstableDev.test.ts +61 -0
- package/src/__tests__/user.test.ts +35 -72
- package/src/__tests__/whoami.test.tsx +8 -114
- package/src/__tests__/worker-namespace.test.ts +83 -69
- package/src/api/dev.ts +180 -60
- package/src/api/index.ts +10 -1
- package/src/api/mtls-certificate.ts +148 -0
- package/src/api/pages/create-worker-bundle-contents.ts +80 -0
- package/src/api/pages/index.ts +5 -0
- package/src/api/pages/publish.tsx +371 -0
- package/src/bundle.ts +315 -148
- package/src/cfetch/index.ts +0 -2
- package/src/cfetch/internal.ts +33 -33
- package/src/cli.ts +4 -4
- package/src/config/config.ts +14 -7
- package/src/config/environment.ts +120 -24
- package/src/config/index.ts +117 -35
- package/src/config/validation-helpers.ts +1 -1
- package/src/config/validation.ts +430 -19
- 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-preview.ts +19 -8
- package/src/create-worker-upload-form.ts +81 -18
- package/src/d1/backups.tsx +47 -46
- package/src/d1/constants.ts +5 -0
- package/src/d1/create.tsx +85 -37
- package/src/d1/{delete.tsx → delete.ts} +12 -15
- package/src/d1/execute.tsx +228 -156
- package/src/d1/index.ts +31 -7
- package/src/d1/list.tsx +27 -13
- package/src/d1/migrations/apply.tsx +235 -0
- package/src/d1/migrations/create.tsx +79 -0
- package/src/d1/migrations/helpers.ts +171 -0
- package/src/d1/migrations/index.ts +3 -0
- package/src/d1/migrations/list.tsx +95 -0
- package/src/d1/migrations/options.ts +23 -0
- package/src/d1/options.ts +12 -2
- package/src/d1/splitter.ts +161 -0
- package/src/d1/types.ts +32 -0
- package/src/d1/utils.ts +12 -2
- package/src/delete.ts +8 -16
- package/src/deployments.ts +340 -46
- package/src/deprecated/index.ts +8 -302
- package/src/dev/dev.tsx +66 -46
- package/src/dev/local.tsx +339 -104
- package/src/dev/remote.tsx +36 -3
- package/src/dev/start-server.ts +146 -101
- package/src/dev/use-esbuild.ts +82 -56
- package/src/dev/validate-dev-props.ts +9 -0
- package/src/{dev-registry.tsx → dev-registry.ts} +13 -1
- package/src/dev.tsx +202 -125
- package/src/dialogs.ts +136 -0
- package/src/dispatch-namespace.ts +21 -17
- package/src/docs/helpers.ts +50 -0
- package/src/docs/index.ts +54 -0
- package/src/entry.ts +26 -11
- package/src/environment-variables/factory.ts +89 -0
- package/src/environment-variables/misc-variables.ts +30 -0
- package/src/generate/index.ts +303 -0
- package/src/git-client.ts +15 -4
- package/src/{index.tsx → index.ts} +148 -63
- package/src/init.ts +301 -197
- package/src/inspect.ts +122 -6
- package/src/jest.d.ts +4 -0
- package/src/kv/helpers.ts +7 -4
- package/src/kv/index.ts +15 -17
- package/src/logger.ts +36 -5
- package/src/metrics/metrics-config.ts +3 -3
- package/src/metrics/send-event.ts +6 -1
- package/src/miniflare-cli/assets.ts +64 -28
- package/src/miniflare-cli/index.ts +6 -9
- package/src/miniflare-cli/tsconfig.json +9 -0
- package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
- package/src/miniflare-cli/types.ts +11 -0
- package/src/module-collection.ts +92 -26
- package/src/mtls-certificate/cli.ts +155 -0
- package/src/pages/build.ts +423 -0
- package/src/pages/buildFunctions.ts +140 -0
- package/src/pages/deployment-tails.ts +281 -0
- package/src/pages/deployments.tsx +11 -33
- package/src/pages/{dev.tsx → dev.ts} +192 -126
- package/src/pages/errors.ts +1 -0
- package/src/pages/functions/buildPlugin.ts +73 -69
- package/src/pages/functions/buildWorker.ts +342 -117
- package/src/pages/functions/tsconfig.json +8 -0
- package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
- package/src/pages/{functions.tsx → functions.ts} +8 -4
- package/src/pages/{index.tsx → index.ts} +11 -3
- package/src/pages/projects.tsx +12 -22
- package/src/pages/prompt-select-project.tsx +31 -0
- package/src/pages/publish.tsx +45 -214
- package/src/pages/types.ts +6 -9
- package/src/pages/upload.tsx +58 -14
- package/src/pages/utils.ts +14 -3
- package/src/parse.ts +23 -1
- package/src/paths.ts +1 -1
- package/src/proxy.ts +5 -0
- package/src/publish/index.ts +20 -16
- package/src/publish/publish.ts +81 -48
- package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
- package/src/queues/cli/commands/consumer/add.ts +24 -24
- package/src/queues/cli/commands/consumer/index.ts +3 -6
- package/src/queues/cli/commands/consumer/remove.ts +11 -18
- package/src/queues/cli/commands/create.ts +8 -8
- package/src/queues/cli/commands/delete.ts +8 -8
- package/src/queues/cli/commands/index.ts +6 -4
- package/src/queues/cli/commands/list.ts +8 -8
- package/src/queues/client.ts +1 -0
- package/src/queues/utils.ts +18 -0
- package/src/r2/constants.ts +4 -0
- package/src/r2/helpers.ts +1 -0
- package/src/r2/index.ts +40 -28
- package/src/secret/index.ts +18 -17
- package/src/{sites.tsx → sites.ts} +165 -53
- package/src/tail/createTail.ts +103 -3
- package/src/tail/filters.ts +1 -1
- package/src/tail/index.ts +8 -11
- package/src/tail/printing.ts +27 -0
- package/src/traverse-module-graph.ts +54 -0
- package/src/tsconfig-sanity.ts +16 -0
- package/src/type-generation.ts +85 -57
- package/src/user/access.ts +0 -1
- package/src/user/auth-variables.ts +113 -0
- package/src/user/choose-account.tsx +1 -31
- package/src/user/index.ts +0 -1
- package/src/user/{user.tsx → user.ts} +124 -82
- package/src/utils/render.ts +93 -0
- package/src/{whoami.tsx → whoami.ts} +37 -71
- package/src/worker.ts +61 -3
- package/src/yargs-types.ts +22 -5
- package/templates/__tests__/tsconfig-sanity.ts +12 -0
- package/templates/__tests__/tsconfig.json +8 -0
- package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
- package/templates/checked-fetch.js +9 -3
- package/templates/d1-beta-facade.js +95 -25
- package/templates/facade.d.ts +14 -0
- package/templates/first-party-worker-module-facade.ts +4 -3
- package/templates/format-dev-errors.ts +8 -6
- package/templates/gitignore +1 -0
- package/templates/init-tests/test-jest-new-worker.js +3 -5
- package/templates/init-tests/test-vitest-new-worker.js +3 -5
- package/templates/init-tests/test-vitest-new-worker.ts +25 -0
- package/templates/middleware/loader-modules.ts +2 -2
- package/templates/middleware/loader-sw.ts +51 -31
- package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
- package/templates/new-worker.ts +3 -0
- package/templates/pages-dev-pipeline.ts +4 -1
- package/templates/pages-dev-util.ts +4 -1
- package/templates/pages-shim.ts +4 -1
- package/templates/pages-template-plugin.ts +19 -10
- package/templates/serve-static-assets.ts +17 -14
- package/templates/service-bindings-module-facade.js +1 -0
- package/templates/tsconfig-sanity.ts +11 -0
- package/templates/tsconfig.init.json +105 -0
- package/templates/tsconfig.json +5 -103
- package/templates/tsconfig.tsbuildinfo +1 -0
- package/wrangler-dist/cli.d.ts +902 -77
- package/wrangler-dist/cli.js +131685 -140615
- package/wrangler-dist/wasm-sync.wasm +0 -0
- package/src/__tests__/api-devregistry.test.js +0 -57
- package/src/__tests__/d1.test.ts +0 -72
- package/src/__tests__/dialogs.test.tsx +0 -40
- package/src/__tests__/helpers/mock-cfetch.ts +0 -333
- package/src/__tests__/pages.test.ts +0 -2223
- package/src/d1/types.tsx +0 -14
- package/src/dialogs.tsx +0 -163
- package/src/environment-variables.ts +0 -50
- package/src/pages/build.tsx +0 -238
- package/src/user/env-vars.ts +0 -46
- package/templates/experimental-local-cache-stubs.js +0 -27
- /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
- /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
- /package/src/pages/{hash.tsx → hash.ts} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import assert from "node:assert";
|
|
2
2
|
import { readdir, readFile, stat } from "node:fs/promises";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
+
import chalk from "chalk";
|
|
4
5
|
import ignore from "ignore";
|
|
5
6
|
import xxhash from "xxhash-wasm";
|
|
6
7
|
import {
|
|
@@ -9,8 +10,10 @@ import {
|
|
|
9
10
|
listKVNamespaces,
|
|
10
11
|
putKVBulkKeyValue,
|
|
11
12
|
deleteKVBulkKeyValue,
|
|
13
|
+
BATCH_KEY_MAX,
|
|
14
|
+
formatNumber,
|
|
12
15
|
} from "./kv/helpers";
|
|
13
|
-
import { logger } from "./logger";
|
|
16
|
+
import { logger, LOGGER_LEVELS } from "./logger";
|
|
14
17
|
import type { Config } from "./config";
|
|
15
18
|
import type { KeyValue } from "./kv/helpers";
|
|
16
19
|
import type { XXHashAPI } from "xxhash-wasm";
|
|
@@ -56,7 +59,7 @@ function hashFileContent(hasher: XXHashAPI, content: string): string {
|
|
|
56
59
|
* Create a hashed asset key for the given asset.
|
|
57
60
|
*
|
|
58
61
|
* The key will change if the file path or content of the asset changes.
|
|
59
|
-
* The algorithm used here matches that of Wrangler
|
|
62
|
+
* The algorithm used here matches that of Wrangler v1.
|
|
60
63
|
*/
|
|
61
64
|
function hashAsset(
|
|
62
65
|
hasher: XXHashAPI,
|
|
@@ -92,6 +95,15 @@ async function createKVNamespaceIfNotAlreadyExisting(
|
|
|
92
95
|
};
|
|
93
96
|
}
|
|
94
97
|
|
|
98
|
+
const MAX_DIFF_LINES = 100;
|
|
99
|
+
const MAX_BUCKET_SIZE = 98 * 1000 * 1000;
|
|
100
|
+
const MAX_BUCKET_KEYS = BATCH_KEY_MAX;
|
|
101
|
+
const MAX_BATCH_OPERATIONS = 5;
|
|
102
|
+
|
|
103
|
+
function pluralise(count: number) {
|
|
104
|
+
return count === 1 ? "" : "s";
|
|
105
|
+
}
|
|
106
|
+
|
|
95
107
|
/**
|
|
96
108
|
* Upload the assets found within the `dirPath` directory to the sites assets KV namespace for
|
|
97
109
|
* the worker given by `scriptName`.
|
|
@@ -116,13 +128,13 @@ export async function syncAssets(
|
|
|
116
128
|
if (siteAssets === undefined) {
|
|
117
129
|
return { manifest: undefined, namespace: undefined };
|
|
118
130
|
}
|
|
119
|
-
|
|
120
131
|
if (dryRun) {
|
|
121
132
|
logger.log("(Note: doing a dry run, not uploading or deleting anything.)");
|
|
122
133
|
return { manifest: undefined, namespace: undefined };
|
|
123
134
|
}
|
|
124
135
|
assert(accountId, "Missing accountId");
|
|
125
136
|
|
|
137
|
+
// Create assets namespace if it doesn't exist
|
|
126
138
|
const title = `__${scriptName}-workers_sites_assets${
|
|
127
139
|
preview ? "_preview" : ""
|
|
128
140
|
}`;
|
|
@@ -131,55 +143,81 @@ export async function syncAssets(
|
|
|
131
143
|
title,
|
|
132
144
|
accountId
|
|
133
145
|
);
|
|
134
|
-
|
|
135
|
-
|
|
146
|
+
// Get all existing keys in asset namespace
|
|
147
|
+
logger.info("Fetching list of already uploaded assets...");
|
|
136
148
|
const namespaceKeysResponse = await listKVNamespaceKeys(accountId, namespace);
|
|
137
149
|
const namespaceKeys = new Set(namespaceKeysResponse.map((x) => x.name));
|
|
138
150
|
|
|
139
|
-
const manifest: Record<string, string> = {};
|
|
140
|
-
|
|
141
|
-
// A batch of uploads where each bucket has to be less than 98mb
|
|
142
|
-
const uploadBuckets: KeyValue[][] = [];
|
|
143
|
-
// The "live" bucket that we'll keep filling until it's just below 98mb
|
|
144
|
-
let uploadBucket: KeyValue[] = [];
|
|
145
|
-
// A size counter for the live bucket
|
|
146
|
-
let uploadBucketSize = 0;
|
|
147
|
-
|
|
148
|
-
const include = createPatternMatcher(siteAssets.includePatterns, false);
|
|
149
|
-
const exclude = createPatternMatcher(siteAssets.excludePatterns, true);
|
|
150
|
-
const hasher = await xxhash();
|
|
151
|
-
|
|
152
151
|
const assetDirectory = path.join(
|
|
153
152
|
siteAssets.baseDirectory,
|
|
154
153
|
siteAssets.assetDirectory
|
|
155
154
|
);
|
|
155
|
+
const include = createPatternMatcher(siteAssets.includePatterns, false);
|
|
156
|
+
const exclude = createPatternMatcher(siteAssets.excludePatterns, true);
|
|
157
|
+
const hasher = await xxhash();
|
|
158
|
+
|
|
159
|
+
// Find and validate all assets before we make any changes (can't store base64
|
|
160
|
+
// contents in memory for upload as users may have *lots* of files, and we
|
|
161
|
+
// don't want to OOM: https://github.com/cloudflare/workers-sdk/issues/2223)
|
|
162
|
+
|
|
163
|
+
const manifest: Record<string, string> = {};
|
|
164
|
+
type PathKey = [path: string, key: string];
|
|
165
|
+
// A batch of uploads where each bucket has to be less than 100 MiB and
|
|
166
|
+
// contain less than 10,000 keys (although we limit to 98 MB and 5000 keys)
|
|
167
|
+
const uploadBuckets: PathKey[][] = [];
|
|
168
|
+
// The "live" bucket we'll keep filling until it's just below the size limit
|
|
169
|
+
let uploadBucket: PathKey[] = [];
|
|
170
|
+
// Current size of the live bucket in bytes (just base64 encoded values)
|
|
171
|
+
let uploadBucketSize = 0;
|
|
172
|
+
|
|
173
|
+
let uploadCount = 0;
|
|
174
|
+
let skipCount = 0;
|
|
175
|
+
|
|
176
|
+
// Always log the first MAX_DIFF_LINES lines, then require the debug log level
|
|
177
|
+
let diffCount = 0;
|
|
178
|
+
function logDiff(line: string) {
|
|
179
|
+
const level = logger.loggerLevel;
|
|
180
|
+
if (LOGGER_LEVELS[level] >= LOGGER_LEVELS.debug) {
|
|
181
|
+
// If we're logging as debug level, we want *all* diff lines to be logged
|
|
182
|
+
// at debug level, not just the first MAX_DIFF_LINES
|
|
183
|
+
logger.debug(line);
|
|
184
|
+
} else if (diffCount < MAX_DIFF_LINES) {
|
|
185
|
+
// Otherwise, log the first MAX_DIFF_LINES diffs at info level...
|
|
186
|
+
logger.info(line);
|
|
187
|
+
} else if (diffCount === MAX_DIFF_LINES) {
|
|
188
|
+
// ...and warn when we start to truncate it
|
|
189
|
+
const msg =
|
|
190
|
+
" (truncating changed assets log, set `WRANGLER_LOG=debug` environment variable to see full diff)";
|
|
191
|
+
logger.info(chalk.dim(msg));
|
|
192
|
+
}
|
|
193
|
+
diffCount++;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
logger.info("Building list of assets to upload...");
|
|
156
197
|
for await (const absAssetFile of getFilesInFolder(assetDirectory)) {
|
|
157
198
|
const assetFile = path.relative(assetDirectory, absAssetFile);
|
|
158
|
-
if (!include(assetFile))
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
if (exclude(assetFile)) {
|
|
162
|
-
continue;
|
|
163
|
-
}
|
|
199
|
+
if (!include(assetFile) || exclude(assetFile)) continue;
|
|
164
200
|
|
|
165
|
-
logger.log(`Reading ${assetFile}...`);
|
|
166
201
|
const content = await readFile(absAssetFile, "base64");
|
|
167
|
-
|
|
168
|
-
// while KV accepts files that are 25 MiB **before** b64 encoding
|
|
202
|
+
// While KV accepts files that are 25 MiB **before** b64 encoding
|
|
169
203
|
// the overall bucket size must be below 100 MB **after** b64 encoding
|
|
170
|
-
const assetSize = Buffer.
|
|
204
|
+
const assetSize = Buffer.byteLength(content);
|
|
205
|
+
await validateAssetSize(absAssetFile, assetFile);
|
|
171
206
|
const assetKey = hashAsset(hasher, assetFile, content);
|
|
172
207
|
validateAssetKey(assetKey);
|
|
173
208
|
|
|
174
|
-
// now put each of the files into kv
|
|
175
209
|
if (!namespaceKeys.has(assetKey)) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if
|
|
181
|
-
|
|
182
|
-
|
|
210
|
+
logDiff(
|
|
211
|
+
chalk.green(` + ${assetKey} (uploading new version of ${assetFile})`)
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
// Check if adding this asset to the bucket would push it over the KV
|
|
215
|
+
// bulk API limits
|
|
216
|
+
if (
|
|
217
|
+
uploadBucketSize + assetSize > MAX_BUCKET_SIZE ||
|
|
218
|
+
uploadBucket.length + 1 > MAX_BUCKET_KEYS
|
|
219
|
+
) {
|
|
220
|
+
// If so, record the current bucket and reset it
|
|
183
221
|
uploadBuckets.push(uploadBucket);
|
|
184
222
|
uploadBucketSize = 0;
|
|
185
223
|
uploadBucket = [];
|
|
@@ -187,13 +225,11 @@ export async function syncAssets(
|
|
|
187
225
|
|
|
188
226
|
// Update the bucket and the size counter
|
|
189
227
|
uploadBucketSize += assetSize;
|
|
190
|
-
uploadBucket.push(
|
|
191
|
-
|
|
192
|
-
value: content,
|
|
193
|
-
base64: true,
|
|
194
|
-
});
|
|
228
|
+
uploadBucket.push([absAssetFile, assetKey]);
|
|
229
|
+
uploadCount++;
|
|
195
230
|
} else {
|
|
196
|
-
|
|
231
|
+
logDiff(chalk.dim(` = ${assetKey} (already uploaded ${assetFile})`));
|
|
232
|
+
skipCount++;
|
|
197
233
|
}
|
|
198
234
|
|
|
199
235
|
// Remove the key from the set so we know what we've already uploaded
|
|
@@ -203,23 +239,99 @@ export async function syncAssets(
|
|
|
203
239
|
const manifestKey = urlSafe(path.relative(assetDirectory, absAssetFile));
|
|
204
240
|
manifest[manifestKey] = assetKey;
|
|
205
241
|
}
|
|
242
|
+
// Add the last (potentially only or empty) bucket to the batch
|
|
243
|
+
if (uploadBucket.length > 0) uploadBuckets.push(uploadBucket);
|
|
206
244
|
|
|
207
|
-
// Add the last (potentially only) bucket to the batch
|
|
208
|
-
uploadBuckets.push(uploadBucket);
|
|
209
|
-
|
|
210
|
-
// keys now contains all the files we're deleting
|
|
211
245
|
for (const key of namespaceKeys) {
|
|
212
|
-
|
|
246
|
+
logDiff(chalk.red(` - ${key} (removing as stale)`));
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Upload new assets, with 5 concurrent uploaders
|
|
250
|
+
if (uploadCount > 0) {
|
|
251
|
+
const s = pluralise(uploadCount);
|
|
252
|
+
logger.info(`Uploading ${formatNumber(uploadCount)} new asset${s}...`);
|
|
253
|
+
}
|
|
254
|
+
if (skipCount > 0) {
|
|
255
|
+
const s = pluralise(skipCount);
|
|
256
|
+
logger.info(
|
|
257
|
+
`Skipped uploading ${formatNumber(skipCount)} existing asset${s}.`
|
|
258
|
+
);
|
|
213
259
|
}
|
|
260
|
+
let uploadedCount = 0;
|
|
261
|
+
const controller = new AbortController();
|
|
262
|
+
const uploaders = Array.from(Array(MAX_BATCH_OPERATIONS)).map(async () => {
|
|
263
|
+
while (!controller.signal.aborted) {
|
|
264
|
+
// Get the next bucket to upload. If there is none, stop this uploader.
|
|
265
|
+
// JavaScript is single(ish)-threaded, so we don't need to worry about
|
|
266
|
+
// parallel access here.
|
|
267
|
+
const nextBucket = uploadBuckets.shift();
|
|
268
|
+
if (nextBucket === undefined) break;
|
|
269
|
+
|
|
270
|
+
// Read all files in the bucket as base64
|
|
271
|
+
// TODO(perf): consider streaming the bulk upload body, rather than
|
|
272
|
+
// buffering all base64 contents then JSON-stringifying. This probably
|
|
273
|
+
// doesn't matter *too* much: we know buckets will be about 100MB, so
|
|
274
|
+
// with 5 uploaders, we could load about 500MB into memory (+ extra
|
|
275
|
+
// object keys/tags/copies/etc).
|
|
276
|
+
const bucket: KeyValue[] = [];
|
|
277
|
+
for (const [absAssetFile, assetKey] of nextBucket) {
|
|
278
|
+
bucket.push({
|
|
279
|
+
key: assetKey,
|
|
280
|
+
value: await readFile(absAssetFile, "base64"),
|
|
281
|
+
base64: true,
|
|
282
|
+
});
|
|
283
|
+
if (controller.signal.aborted) break;
|
|
284
|
+
}
|
|
214
285
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
286
|
+
// Upload the bucket to the KV namespace, suppressing logs, we do our own
|
|
287
|
+
try {
|
|
288
|
+
await putKVBulkKeyValue(
|
|
289
|
+
accountId,
|
|
290
|
+
namespace,
|
|
291
|
+
bucket,
|
|
292
|
+
/* quiet */ true,
|
|
293
|
+
controller.signal
|
|
294
|
+
);
|
|
295
|
+
} catch (e) {
|
|
296
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/DOMException#error_names
|
|
297
|
+
// https://github.com/nodejs/undici/blob/a3efc9814447001a43a976f1c64adc41995df7e3/lib/core/errors.js#L89
|
|
298
|
+
if (
|
|
299
|
+
typeof e === "object" &&
|
|
300
|
+
e !== null &&
|
|
301
|
+
"name" in e &&
|
|
302
|
+
// @ts-expect-error `e.name` should be typed `unknown`, fixed in
|
|
303
|
+
// TypeScript 4.9
|
|
304
|
+
e.name === "AbortError"
|
|
305
|
+
) {
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
throw e;
|
|
309
|
+
}
|
|
310
|
+
uploadedCount += nextBucket.length;
|
|
311
|
+
const percent = Math.floor((100 * uploadedCount) / uploadCount);
|
|
312
|
+
logger.info(
|
|
313
|
+
`Uploaded ${percent}% [${formatNumber(
|
|
314
|
+
uploadedCount
|
|
315
|
+
)} out of ${formatNumber(uploadCount)}]`
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
try {
|
|
320
|
+
// Wait for all uploaders to complete, or one to fail
|
|
321
|
+
await Promise.all(uploaders);
|
|
322
|
+
} catch (e) {
|
|
323
|
+
// If any uploader fails, abort the others
|
|
324
|
+
logger.info(`Upload failed, aborting...`);
|
|
325
|
+
controller.abort();
|
|
326
|
+
throw e;
|
|
219
327
|
}
|
|
220
|
-
await Promise.all(bucketsToPut);
|
|
221
328
|
|
|
222
|
-
//
|
|
329
|
+
// Delete stale assets
|
|
330
|
+
const deleteCount = namespaceKeys.size;
|
|
331
|
+
if (deleteCount > 0) {
|
|
332
|
+
const s = pluralise(deleteCount);
|
|
333
|
+
logger.info(`Removing ${formatNumber(deleteCount)} stale asset${s}...`);
|
|
334
|
+
}
|
|
223
335
|
await deleteKVBulkKeyValue(accountId, namespace, Array.from(namespaceKeys));
|
|
224
336
|
|
|
225
337
|
logger.log("↗️ Done syncing assets");
|
package/src/tail/createTail.ts
CHANGED
|
@@ -7,6 +7,8 @@ export { translateCLICommandToFilterMessage } from "./filters";
|
|
|
7
7
|
export { jsonPrintLogs, prettyPrintLogs } from "./printing";
|
|
8
8
|
import type { Request } from "undici";
|
|
9
9
|
|
|
10
|
+
const TRACE_VERSION = "trace-v1";
|
|
11
|
+
|
|
10
12
|
/**
|
|
11
13
|
* When creating a Tail, the response from the API contains
|
|
12
14
|
* - an ID used for identifying the tail
|
|
@@ -59,6 +61,68 @@ function makeDeleteTailUrl(
|
|
|
59
61
|
: `/accounts/${accountId}/workers/scripts/${workerName}/tails/${tailId}`;
|
|
60
62
|
}
|
|
61
63
|
|
|
64
|
+
interface CreatePagesTailOptions {
|
|
65
|
+
accountId: string;
|
|
66
|
+
projectName: string;
|
|
67
|
+
deploymentId: string;
|
|
68
|
+
filters: TailFilterMessage;
|
|
69
|
+
debug?: boolean;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Create and connect to a Pages Function Tail.
|
|
74
|
+
*
|
|
75
|
+
* Under the hood, this function
|
|
76
|
+
* - Registers a new Tail with the API
|
|
77
|
+
* - Connects to the tail worker
|
|
78
|
+
* - Sends any filters over the connection
|
|
79
|
+
*
|
|
80
|
+
* @returns a websocket connection, an expiration, and a function to call to delete the tail
|
|
81
|
+
*/
|
|
82
|
+
export async function createPagesTail({
|
|
83
|
+
accountId,
|
|
84
|
+
projectName,
|
|
85
|
+
deploymentId,
|
|
86
|
+
filters,
|
|
87
|
+
debug = false,
|
|
88
|
+
}: CreatePagesTailOptions) {
|
|
89
|
+
const tailRecord = await fetchResult<TailCreationApiResponse>(
|
|
90
|
+
`/accounts/${accountId}/pages/projects/${projectName}/deployments/${deploymentId}/tails`,
|
|
91
|
+
{
|
|
92
|
+
method: "POST",
|
|
93
|
+
body: JSON.stringify(filters),
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const deleteTail = async () =>
|
|
98
|
+
fetchResult(
|
|
99
|
+
`/accounts/${accountId}/pages/projects/${projectName}/deployments/${deploymentId}/tails/${tailRecord.id}`,
|
|
100
|
+
{ method: "DELETE" }
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const tail = new WebSocket(tailRecord.url, TRACE_VERSION, {
|
|
104
|
+
headers: {
|
|
105
|
+
"Sec-WebSocket-Protocol": TRACE_VERSION, // needs to be `trace-v1` to be accepted
|
|
106
|
+
"User-Agent": `wrangler-js/${packageVersion}`,
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// send filters when we open up
|
|
111
|
+
tail.on("open", () => {
|
|
112
|
+
tail.send(
|
|
113
|
+
JSON.stringify({ debug: debug }),
|
|
114
|
+
{ binary: false, compress: false, mask: false, fin: true },
|
|
115
|
+
(err) => {
|
|
116
|
+
if (err) {
|
|
117
|
+
throw err;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
return { tail, deleteTail, expiration: tailRecord.expires_at };
|
|
124
|
+
}
|
|
125
|
+
|
|
62
126
|
/**
|
|
63
127
|
* Create and connect to a tail.
|
|
64
128
|
*
|
|
@@ -102,9 +166,9 @@ export async function createTail(
|
|
|
102
166
|
}
|
|
103
167
|
|
|
104
168
|
// connect to the tail
|
|
105
|
-
const tail = new WebSocket(websocketUrl,
|
|
169
|
+
const tail = new WebSocket(websocketUrl, TRACE_VERSION, {
|
|
106
170
|
headers: {
|
|
107
|
-
"Sec-WebSocket-Protocol":
|
|
171
|
+
"Sec-WebSocket-Protocol": TRACE_VERSION, // needs to be `trace-v1` to be accepted
|
|
108
172
|
"User-Agent": `wrangler-js/${packageVersion}`,
|
|
109
173
|
},
|
|
110
174
|
});
|
|
@@ -178,11 +242,19 @@ export type TailEventMessage = {
|
|
|
178
242
|
* The event that triggered the worker. In the case of an HTTP request,
|
|
179
243
|
* this will be a RequestEvent. If it's a cron trigger, it'll be a
|
|
180
244
|
* ScheduledEvent. If it's a durable object alarm, it's an AlarmEvent.
|
|
245
|
+
* If it's a email, it'a an EmailEvent
|
|
181
246
|
*
|
|
182
247
|
* Until workers-types exposes individual types for export, we'll have
|
|
183
248
|
* to just re-define these types ourselves.
|
|
184
249
|
*/
|
|
185
|
-
event:
|
|
250
|
+
event:
|
|
251
|
+
| RequestEvent
|
|
252
|
+
| ScheduledEvent
|
|
253
|
+
| AlarmEvent
|
|
254
|
+
| EmailEvent
|
|
255
|
+
| TailInfo
|
|
256
|
+
| undefined
|
|
257
|
+
| null;
|
|
186
258
|
};
|
|
187
259
|
|
|
188
260
|
/**
|
|
@@ -313,3 +385,31 @@ export type AlarmEvent = {
|
|
|
313
385
|
*/
|
|
314
386
|
scheduledTime: string;
|
|
315
387
|
};
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* An event that was triggered from an email
|
|
391
|
+
*/
|
|
392
|
+
export type EmailEvent = {
|
|
393
|
+
/**
|
|
394
|
+
* Who sent the email
|
|
395
|
+
*/
|
|
396
|
+
mailFrom: string;
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Who was the email sent to
|
|
400
|
+
*/
|
|
401
|
+
rcptTo: string;
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Size of the email in bytes
|
|
405
|
+
*/
|
|
406
|
+
rawSize: number;
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Message from tail with information about the tail itself
|
|
411
|
+
*/
|
|
412
|
+
export type TailInfo = {
|
|
413
|
+
message: string;
|
|
414
|
+
type: string;
|
|
415
|
+
};
|
package/src/tail/filters.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* These are the filters we accept in the CLI. They
|
|
10
|
-
* were copied directly from
|
|
10
|
+
* were copied directly from Wrangler v1 in order to
|
|
11
11
|
* maintain compatability, so they aren't actually the exact
|
|
12
12
|
* filters we need to send up to the tail worker. They generally map 1:1,
|
|
13
13
|
* but often require some transformation or
|
package/src/tail/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import onExit from "signal-exit";
|
|
|
3
3
|
|
|
4
4
|
import { fetchResult, fetchScriptContent } from "../cfetch";
|
|
5
5
|
import { readConfig } from "../config";
|
|
6
|
-
import {
|
|
6
|
+
import { confirm } from "../dialogs";
|
|
7
7
|
import {
|
|
8
8
|
isLegacyEnv,
|
|
9
9
|
printWranglerBanner,
|
|
@@ -20,16 +20,14 @@ import {
|
|
|
20
20
|
translateCLICommandToFilterMessage,
|
|
21
21
|
} from "./createTail";
|
|
22
22
|
import type { WorkerMetadata } from "../create-worker-upload-form";
|
|
23
|
-
import type { ConfigPath } from "../index";
|
|
24
23
|
import type {
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
CommonYargsArgv,
|
|
25
|
+
StrictYargsOptionsToInterface,
|
|
27
26
|
} from "../yargs-types";
|
|
28
27
|
import type { TailCLIFilters } from "./createTail";
|
|
29
28
|
import type { RawData } from "ws";
|
|
30
|
-
import type { Argv } from "yargs";
|
|
31
29
|
|
|
32
|
-
export function tailOptions(yargs:
|
|
30
|
+
export function tailOptions(yargs: CommonYargsArgv) {
|
|
33
31
|
return yargs
|
|
34
32
|
.positional("worker", {
|
|
35
33
|
describe: "Name or route of the worker to tail",
|
|
@@ -86,13 +84,13 @@ export function tailOptions(yargs: Argv<CommonYargsOptions>) {
|
|
|
86
84
|
});
|
|
87
85
|
}
|
|
88
86
|
|
|
89
|
-
type TailArgs =
|
|
87
|
+
type TailArgs = StrictYargsOptionsToInterface<typeof tailOptions>;
|
|
90
88
|
|
|
91
89
|
export async function tailHandler(args: TailArgs) {
|
|
92
90
|
if (args.format === "pretty") {
|
|
93
91
|
await printWranglerBanner();
|
|
94
92
|
}
|
|
95
|
-
const config = readConfig(args.config
|
|
93
|
+
const config = readConfig(args.config, args);
|
|
96
94
|
await metrics.sendMetricsEvent("begin log stream", {
|
|
97
95
|
sendMetrics: config.send_metrics,
|
|
98
96
|
});
|
|
@@ -121,7 +119,7 @@ export async function tailHandler(args: TailArgs) {
|
|
|
121
119
|
status: args.status as ("ok" | "error" | "canceled")[] | undefined,
|
|
122
120
|
header: args.header,
|
|
123
121
|
method: args.method,
|
|
124
|
-
samplingRate: args
|
|
122
|
+
samplingRate: args.samplingRate,
|
|
125
123
|
search: args.search,
|
|
126
124
|
clientIp: args.ip,
|
|
127
125
|
};
|
|
@@ -144,8 +142,7 @@ export async function tailHandler(args: TailArgs) {
|
|
|
144
142
|
`Beginning log collection requires restarting the Durable Objects associated with ${scriptName}. Any WebSocket connections or other non-persisted state will be lost as part of this restart.`
|
|
145
143
|
);
|
|
146
144
|
|
|
147
|
-
|
|
148
|
-
if (!shouldContinue) {
|
|
145
|
+
if (!(await confirm("Would you like to continue?"))) {
|
|
149
146
|
return;
|
|
150
147
|
}
|
|
151
148
|
}
|
package/src/tail/printing.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
1
2
|
import { logger } from "../logger";
|
|
2
3
|
import type {
|
|
3
4
|
AlarmEvent,
|
|
5
|
+
EmailEvent,
|
|
4
6
|
RequestEvent,
|
|
5
7
|
ScheduledEvent,
|
|
8
|
+
TailInfo,
|
|
6
9
|
TailEventMessage,
|
|
7
10
|
} from "./createTail";
|
|
8
11
|
import type { Outcome } from "./filters";
|
|
@@ -30,6 +33,16 @@ export function prettyPrintLogs(data: WebSocket.RawData): void {
|
|
|
30
33
|
? `${requestMethod} ${url} - ${outcome} @ ${datetime}`
|
|
31
34
|
: `[missing request] - ${outcome} @ ${datetime}`
|
|
32
35
|
);
|
|
36
|
+
} else if (isEmailEvent(eventMessage.event)) {
|
|
37
|
+
const outcome = prettifyOutcome(eventMessage.outcome);
|
|
38
|
+
const datetime = new Date(eventMessage.eventTimestamp).toLocaleString();
|
|
39
|
+
const mailFrom = eventMessage.event.mailFrom;
|
|
40
|
+
const rcptTo = eventMessage.event.rcptTo;
|
|
41
|
+
const rawSize = eventMessage.event.rawSize;
|
|
42
|
+
|
|
43
|
+
logger.log(
|
|
44
|
+
`Email from:${mailFrom} to:${rcptTo} size:${rawSize} @ ${datetime} - ${outcome}`
|
|
45
|
+
);
|
|
33
46
|
} else if (isAlarmEvent(eventMessage.event)) {
|
|
34
47
|
const outcome = prettifyOutcome(eventMessage.outcome);
|
|
35
48
|
const datetime = new Date(
|
|
@@ -37,6 +50,12 @@ export function prettyPrintLogs(data: WebSocket.RawData): void {
|
|
|
37
50
|
).toLocaleString();
|
|
38
51
|
|
|
39
52
|
logger.log(`Alarm @ ${datetime} - ${outcome}`);
|
|
53
|
+
} else if (isTailInfo(eventMessage.event)) {
|
|
54
|
+
if (eventMessage.event.type === "overload") {
|
|
55
|
+
logger.log(`${chalk.red.bold(eventMessage.event.message)}`);
|
|
56
|
+
} else if (eventMessage.event.type === "overload-stop") {
|
|
57
|
+
logger.log(`${chalk.yellow.bold(eventMessage.event.message)}`);
|
|
58
|
+
}
|
|
40
59
|
} else {
|
|
41
60
|
// Unknown event type
|
|
42
61
|
const outcome = prettifyOutcome(eventMessage.outcome);
|
|
@@ -74,6 +93,10 @@ function isScheduledEvent(
|
|
|
74
93
|
return Boolean(event && "cron" in event);
|
|
75
94
|
}
|
|
76
95
|
|
|
96
|
+
function isEmailEvent(event: TailEventMessage["event"]): event is EmailEvent {
|
|
97
|
+
return Boolean(event && "mailFrom" in event);
|
|
98
|
+
}
|
|
99
|
+
|
|
77
100
|
/**
|
|
78
101
|
* Check to see if an event sent from a worker is an AlarmEvent.
|
|
79
102
|
*
|
|
@@ -88,6 +111,10 @@ function isAlarmEvent(event: TailEventMessage["event"]): event is AlarmEvent {
|
|
|
88
111
|
return Boolean(event && "scheduledTime" in event && !("cron" in event));
|
|
89
112
|
}
|
|
90
113
|
|
|
114
|
+
function isTailInfo(event: TailEventMessage["event"]): event is TailInfo {
|
|
115
|
+
return Boolean(event && "message" in event && "type" in event);
|
|
116
|
+
}
|
|
117
|
+
|
|
91
118
|
function prettifyOutcome(outcome: Outcome): string {
|
|
92
119
|
switch (outcome) {
|
|
93
120
|
case "ok":
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { readdir } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { logger } from "./logger";
|
|
5
|
+
import { matchFiles, parseRules } from "./module-collection";
|
|
6
|
+
import type { BundleResult } from "./bundle";
|
|
7
|
+
import type { Config } from "./config";
|
|
8
|
+
import type { Entry } from "./entry";
|
|
9
|
+
|
|
10
|
+
async function getFiles(root: string, relativeTo: string): Promise<string[]> {
|
|
11
|
+
const files = [];
|
|
12
|
+
for (const file of await readdir(root, { withFileTypes: true })) {
|
|
13
|
+
if (file.isDirectory()) {
|
|
14
|
+
files.push(...(await getFiles(path.join(root, file.name), relativeTo)));
|
|
15
|
+
} else {
|
|
16
|
+
files.push(path.relative(relativeTo, path.join(root, file.name)));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return files;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default async function traverseModuleGraph(
|
|
23
|
+
entry: Entry,
|
|
24
|
+
rules: Config["rules"]
|
|
25
|
+
): Promise<BundleResult> {
|
|
26
|
+
const files = await getFiles(entry.moduleRoot, entry.moduleRoot);
|
|
27
|
+
const relativeEntryPoint = path.relative(entry.moduleRoot, entry.file);
|
|
28
|
+
|
|
29
|
+
const modules = (await matchFiles(files, entry.moduleRoot, parseRules(rules)))
|
|
30
|
+
.filter((m) => m.name !== relativeEntryPoint)
|
|
31
|
+
.map((m) => ({
|
|
32
|
+
...m,
|
|
33
|
+
name: m.name,
|
|
34
|
+
}));
|
|
35
|
+
|
|
36
|
+
const bundleType = entry.format === "modules" ? "esm" : "commonjs";
|
|
37
|
+
|
|
38
|
+
if (modules.length > 0) {
|
|
39
|
+
logger.info(`Attaching additional modules:`);
|
|
40
|
+
modules.forEach(({ name, type }) => {
|
|
41
|
+
logger.info(`- ${chalk.blue(name)} (${chalk.green(type ?? "")})`);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
modules,
|
|
47
|
+
dependencies: {},
|
|
48
|
+
resolvedEntryPointPath: entry.file,
|
|
49
|
+
bundleType,
|
|
50
|
+
stop: undefined,
|
|
51
|
+
sourceMapPath: undefined,
|
|
52
|
+
sourceMapMetadata: undefined,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// `@types/node` should be included
|
|
2
|
+
Buffer.from("test");
|
|
3
|
+
|
|
4
|
+
// @ts-expect-error `@types/jest` should NOT be included
|
|
5
|
+
test("test");
|
|
6
|
+
|
|
7
|
+
// @ts-expect-error `@cloudflare/workers-types` should NOT be included
|
|
8
|
+
const _handler: ExportedHandler = {};
|
|
9
|
+
// @ts-expect-error `@cloudflare/workers-types` should NOT be included
|
|
10
|
+
new HTMLRewriter();
|
|
11
|
+
|
|
12
|
+
// @ts-expect-error `fetch` should NOT be included as our minimum supported
|
|
13
|
+
// Node version is 16.13.0 which does not include `fetch` on the global scope
|
|
14
|
+
void fetch("http://localhost/");
|
|
15
|
+
|
|
16
|
+
export {};
|