wrangler 2.0.9 → 2.0.14

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.
Files changed (61) hide show
  1. package/kv-asset-handler.js +1 -0
  2. package/package.json +4 -2
  3. package/src/__tests__/configuration.test.ts +255 -142
  4. package/src/__tests__/dev.test.tsx +27 -0
  5. package/src/__tests__/index.test.ts +2 -1
  6. package/src/__tests__/jest.setup.ts +30 -0
  7. package/src/__tests__/publish.test.ts +393 -160
  8. package/src/__tests__/user.test.ts +1 -0
  9. package/src/bundle.ts +9 -5
  10. package/src/config/environment.ts +1 -1
  11. package/src/config/validation-helpers.ts +10 -1
  12. package/src/config/validation.ts +22 -13
  13. package/src/dev/dev.tsx +29 -45
  14. package/src/dev/local.tsx +10 -7
  15. package/src/dev/remote.tsx +4 -1
  16. package/src/dev/use-esbuild.ts +1 -4
  17. package/src/generate-auth-url.ts +33 -0
  18. package/src/generate-random-state.ts +16 -0
  19. package/src/index.tsx +234 -179
  20. package/src/open-in-browser.ts +1 -3
  21. package/src/pages.tsx +295 -240
  22. package/src/parse.ts +2 -1
  23. package/src/proxy.ts +19 -6
  24. package/src/publish.ts +6 -1
  25. package/src/sites.tsx +49 -18
  26. package/src/user.tsx +12 -24
  27. package/templates/static-asset-facade.js +2 -6
  28. package/wrangler-dist/cli.js +73627 -73462
  29. package/vendor/@cloudflare/kv-asset-handler/CHANGELOG.md +0 -332
  30. package/vendor/@cloudflare/kv-asset-handler/LICENSE_APACHE +0 -176
  31. package/vendor/@cloudflare/kv-asset-handler/LICENSE_MIT +0 -25
  32. package/vendor/@cloudflare/kv-asset-handler/README.md +0 -245
  33. package/vendor/@cloudflare/kv-asset-handler/dist/index.d.ts +0 -32
  34. package/vendor/@cloudflare/kv-asset-handler/dist/index.js +0 -354
  35. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.d.ts +0 -13
  36. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.js +0 -148
  37. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.d.ts +0 -1
  38. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.js +0 -436
  39. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.d.ts +0 -1
  40. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.js +0 -40
  41. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.d.ts +0 -1
  42. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.js +0 -42
  43. package/vendor/@cloudflare/kv-asset-handler/dist/types.d.ts +0 -26
  44. package/vendor/@cloudflare/kv-asset-handler/dist/types.js +0 -31
  45. package/vendor/@cloudflare/kv-asset-handler/package.json +0 -52
  46. package/vendor/@cloudflare/kv-asset-handler/src/index.ts +0 -296
  47. package/vendor/@cloudflare/kv-asset-handler/src/mocks.ts +0 -136
  48. package/vendor/@cloudflare/kv-asset-handler/src/test/getAssetFromKV.ts +0 -464
  49. package/vendor/@cloudflare/kv-asset-handler/src/test/mapRequestToAsset.ts +0 -33
  50. package/vendor/@cloudflare/kv-asset-handler/src/test/serveSinglePageApp.ts +0 -42
  51. package/vendor/@cloudflare/kv-asset-handler/src/types.ts +0 -39
  52. package/vendor/wrangler-mime/CHANGELOG.md +0 -289
  53. package/vendor/wrangler-mime/LICENSE +0 -21
  54. package/vendor/wrangler-mime/Mime.js +0 -97
  55. package/vendor/wrangler-mime/README.md +0 -187
  56. package/vendor/wrangler-mime/cli.js +0 -46
  57. package/vendor/wrangler-mime/index.js +0 -4
  58. package/vendor/wrangler-mime/lite.js +0 -4
  59. package/vendor/wrangler-mime/package.json +0 -52
  60. package/vendor/wrangler-mime/types/other.js +0 -1
  61. package/vendor/wrangler-mime/types/standard.js +0 -1
package/src/sites.tsx CHANGED
@@ -137,7 +137,13 @@ export async function syncAssets(
137
137
  const namespaceKeys = new Set(namespaceKeysResponse.map((x) => x.name));
138
138
 
139
139
  const manifest: Record<string, string> = {};
140
- const toUpload: KeyValue[] = [];
140
+
141
+ // A batch of uploads where each bucket has to be less than 100mb
142
+ const uploadBuckets: KeyValue[][] = [];
143
+ // The "live" bucket that we'll keep filling until it's just below 100mb
144
+ let uploadBucket: KeyValue[] = [];
145
+ // A size counter for the live bucket
146
+ let uploadBucketSize = 0;
141
147
 
142
148
  const include = createPatternMatcher(siteAssets.includePatterns, false);
143
149
  const exclude = createPatternMatcher(siteAssets.excludePatterns, true);
@@ -148,7 +154,7 @@ export async function syncAssets(
148
154
  siteAssets.assetDirectory
149
155
  );
150
156
  for await (const absAssetFile of getFilesInFolder(assetDirectory)) {
151
- const assetFile = path.relative(siteAssets.baseDirectory, absAssetFile);
157
+ const assetFile = path.relative(assetDirectory, absAssetFile);
152
158
  if (!include(assetFile)) {
153
159
  continue;
154
160
  }
@@ -156,17 +162,32 @@ export async function syncAssets(
156
162
  continue;
157
163
  }
158
164
 
159
- await validateAssetSize(absAssetFile, assetFile);
160
165
  logger.log(`Reading ${assetFile}...`);
161
166
  const content = await readFile(absAssetFile, "base64");
162
-
167
+ await validateAssetSize(absAssetFile, assetFile);
168
+ // while KV accepts files that are 25 MiB **before** b64 encoding
169
+ // the overall bucket size must be below 100 MiB **after** b64 encoding
170
+ const assetSize = Buffer.from(content).length;
163
171
  const assetKey = hashAsset(hasher, assetFile, content);
164
172
  validateAssetKey(assetKey);
165
173
 
166
174
  // now put each of the files into kv
167
175
  if (!namespaceKeys.has(assetKey)) {
168
176
  logger.log(`Uploading as ${assetKey}...`);
169
- toUpload.push({
177
+
178
+ // Check if adding this asset to the bucket would
179
+ // push it over the 100 MiB limit KV bulk API limit
180
+ if (uploadBucketSize + assetSize > 100 * 1024 * 1024) {
181
+ // If so, move the current bucket into the batch,
182
+ // and reset the counter/bucket
183
+ uploadBuckets.push(uploadBucket);
184
+ uploadBucketSize = 0;
185
+ uploadBucket = [];
186
+ }
187
+
188
+ // Update the bucket and the size counter
189
+ uploadBucketSize += assetSize;
190
+ uploadBucket.push({
170
191
  key: assetKey,
171
192
  value: content,
172
193
  base64: true,
@@ -175,27 +196,31 @@ export async function syncAssets(
175
196
  logger.log(`Skipping - already uploaded.`);
176
197
  }
177
198
 
178
- // remove the key from the set so we know what we've already uploaded
199
+ // Remove the key from the set so we know what we've already uploaded
179
200
  namespaceKeys.delete(assetKey);
180
201
 
181
- // prevent causing different manifest keys on windows
182
- const maifestKey = urlSafe(
183
- path.relative(siteAssets.assetDirectory, absAssetFile)
184
- );
185
- manifest[maifestKey] = assetKey;
202
+ // Prevent different manifest keys on windows
203
+ const manifestKey = urlSafe(path.relative(assetDirectory, absAssetFile));
204
+ manifest[manifestKey] = assetKey;
186
205
  }
187
206
 
207
+ // Add the last (potentially only) bucket to the batch
208
+ uploadBuckets.push(uploadBucket);
209
+
188
210
  // keys now contains all the files we're deleting
189
211
  for (const key of namespaceKeys) {
190
212
  logger.log(`Deleting ${key} from the asset store...`);
191
213
  }
192
214
 
193
- await Promise.all([
194
- // upload all the new assets
195
- putKVBulkKeyValue(accountId, namespace, toUpload),
196
- // delete all the unused assets
197
- deleteKVBulkKeyValue(accountId, namespace, Array.from(namespaceKeys)),
198
- ]);
215
+ // upload each bucket in parallel
216
+ const bucketsToPut = [];
217
+ for (const bucket of uploadBuckets) {
218
+ bucketsToPut.push(putKVBulkKeyValue(accountId, namespace, bucket));
219
+ }
220
+ await Promise.all(bucketsToPut);
221
+
222
+ // then delete all the assets that aren't used anymore
223
+ await deleteKVBulkKeyValue(accountId, namespace, Array.from(namespaceKeys));
199
224
 
200
225
  logger.log("↗️ Done syncing assets");
201
226
 
@@ -214,10 +239,16 @@ function createPatternMatcher(
214
239
  }
215
240
  }
216
241
 
242
+ /**
243
+ * validate that the passed-in file is below 25 MiB
244
+ * **PRIOR** to base64 encoding. 25 MiB is a KV limit
245
+ * @param absFilePath
246
+ * @param relativeFilePath
247
+ */
217
248
  async function validateAssetSize(
218
249
  absFilePath: string,
219
250
  relativeFilePath: string
220
- ) {
251
+ ): Promise<void> {
221
252
  const { size } = await stat(absFilePath);
222
253
  if (size > 25 * 1024 * 1024) {
223
254
  throw new Error(
package/src/user.tsx CHANGED
@@ -223,6 +223,8 @@ import { fetch } from "undici";
223
223
  import { getCloudflareApiBaseUrl } from "./cfetch";
224
224
  import { purgeConfigCaches } from "./config-cache";
225
225
  import { getEnvironmentVariableFactory } from "./environment-variables";
226
+ import { generateAuthUrl } from "./generate-auth-url";
227
+ import { generateRandomState } from "./generate-random-state";
226
228
  import { logger } from "./logger";
227
229
  import openInBrowser from "./open-in-browser";
228
230
  import { parseTOML, readFileSync } from "./parse";
@@ -591,7 +593,7 @@ const RECOMMENDED_STATE_LENGTH = 32;
591
593
  /**
592
594
  * Character set to generate code verifier defined in rfc7636.
593
595
  */
594
- const PKCE_CHARSET =
596
+ export const PKCE_CHARSET =
595
597
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
596
598
 
597
599
  /**
@@ -641,17 +643,14 @@ export async function getAuthURL(scopes = ScopeKeys): Promise<string> {
641
643
  stateQueryParam,
642
644
  });
643
645
 
644
- return (
645
- AUTH_URL +
646
- `?response_type=code&` +
647
- `client_id=${encodeURIComponent(CLIENT_ID)}&` +
648
- `redirect_uri=${encodeURIComponent(CALLBACK_URL)}&` +
649
- // we add offline_access manually for every request
650
- `scope=${encodeURIComponent([...scopes, "offline_access"].join(" "))}&` +
651
- `state=${stateQueryParam}&` +
652
- `code_challenge=${encodeURIComponent(codeChallenge)}&` +
653
- `code_challenge_method=S256`
654
- );
646
+ return generateAuthUrl({
647
+ authUrl: AUTH_URL,
648
+ clientId: CLIENT_ID,
649
+ callbackUrl: CALLBACK_URL,
650
+ scopes,
651
+ stateQueryParam,
652
+ codeChallenge,
653
+ });
655
654
  }
656
655
 
657
656
  type TokenResponse =
@@ -863,18 +862,6 @@ async function generatePKCECodes(): Promise<PKCECodes> {
863
862
  return { codeChallenge, codeVerifier };
864
863
  }
865
864
 
866
- /**
867
- * Generates random state to be passed for anti-csrf.
868
- */
869
- function generateRandomState(lengthOfState: number): string {
870
- const output = new Uint32Array(lengthOfState);
871
- // @ts-expect-error crypto's types aren't there yet
872
- crypto.getRandomValues(output);
873
- return Array.from(output)
874
- .map((num: number) => PKCE_CHARSET[num % PKCE_CHARSET.length])
875
- .join("");
876
- }
877
-
878
865
  /**
879
866
  * Writes a a wrangler config file (auth credentials) to disk,
880
867
  * and updates the user auth state with the new credentials.
@@ -1013,6 +1000,7 @@ export async function login(props?: LoginProps): Promise<boolean> {
1013
1000
  server.listen(8976);
1014
1001
  });
1015
1002
 
1003
+ logger.log(`Opening a link in your default browser: ${urlToOpen}`);
1016
1004
  await openInBrowser(urlToOpen);
1017
1005
 
1018
1006
  return Promise.race([timerPromise, loginPromise]);
@@ -1,13 +1,9 @@
1
1
  // DO NOT IMPORT THIS DIRECTLY
2
2
  import worker from "__ENTRY_POINT__";
3
- import { getAssetFromKV } from "@cloudflare/kv-asset-handler";
3
+ import { getAssetFromKV } from "__KV_ASSET_HANDLER__";
4
4
  import manifest from "__STATIC_CONTENT_MANIFEST";
5
5
  const ASSET_MANIFEST = JSON.parse(manifest);
6
6
 
7
- // TODO: remove this
8
- globalThis.__STATIC_CONTENT = undefined;
9
- globalThis.__STATIC_CONTENT_MANIFEST = undefined;
10
-
11
7
  export default {
12
8
  async fetch(request, env, ctx) {
13
9
  let options = {
@@ -39,7 +35,7 @@ export default {
39
35
  } catch (e) {
40
36
  console.error(e);
41
37
  // if an error is thrown then serve from actual worker
42
- return worker.fetch(request);
38
+ return worker.fetch(request, env, ctx);
43
39
  // TODO: throw here if worker is not available
44
40
  // (which implies it may be a service-worker)
45
41
  }