wrangler 0.0.0-e95bea2 → 0.0.0-e95e5a0

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 (93) hide show
  1. package/README.md +25 -14
  2. package/bin/wrangler.js +13 -1
  3. package/miniflare-dist/index.mjs +4886 -0
  4. package/package.json +33 -25
  5. package/pages/functions/buildPlugin.ts +92 -0
  6. package/pages/functions/buildWorker.ts +80 -4
  7. package/pages/functions/filepath-routing.test.ts +136 -25
  8. package/pages/functions/filepath-routing.ts +14 -3
  9. package/pages/functions/routes.ts +6 -1
  10. package/pages/functions/template-plugin.ts +146 -0
  11. package/pages/functions/template-worker.ts +21 -8
  12. package/src/__tests__/config-cache.test.ts +36 -0
  13. package/src/__tests__/configuration.test.ts +1179 -271
  14. package/src/__tests__/dev.test.tsx +382 -25
  15. package/src/__tests__/guess-worker-format.test.ts +28 -1
  16. package/src/__tests__/helpers/mock-account-id.ts +4 -0
  17. package/src/__tests__/helpers/mock-cfetch.ts +5 -1
  18. package/src/__tests__/helpers/mock-console.ts +20 -3
  19. package/src/__tests__/helpers/mock-dialogs.ts +26 -1
  20. package/src/__tests__/helpers/mock-http-server.ts +46 -0
  21. package/src/__tests__/helpers/mock-istty.ts +27 -0
  22. package/src/__tests__/helpers/mock-kv.ts +9 -16
  23. package/src/__tests__/helpers/mock-oauth-flow.ts +255 -0
  24. package/src/__tests__/helpers/run-in-tmp.ts +10 -0
  25. package/src/__tests__/helpers/write-worker-source.ts +31 -0
  26. package/src/__tests__/https-options.test.ts +5 -2
  27. package/src/__tests__/index.test.ts +27 -769
  28. package/src/__tests__/init.test.ts +1516 -0
  29. package/src/__tests__/jest.setup.ts +4 -4
  30. package/src/__tests__/kv.test.ts +172 -126
  31. package/src/__tests__/logger.test.ts +115 -0
  32. package/src/__tests__/pages.test.ts +311 -26
  33. package/src/__tests__/publish.test.ts +2946 -524
  34. package/src/__tests__/r2.test.ts +26 -10
  35. package/src/__tests__/route.test.ts +4 -4
  36. package/src/__tests__/secret.test.ts +55 -34
  37. package/src/__tests__/tail.test.ts +146 -20
  38. package/src/__tests__/user.test.ts +131 -0
  39. package/src/__tests__/whoami.test.tsx +26 -7
  40. package/src/bundle.ts +30 -3
  41. package/src/cfetch/internal.ts +9 -7
  42. package/src/cli.ts +5 -11
  43. package/src/config/README.md +7 -7
  44. package/src/config/config.ts +33 -78
  45. package/src/config/environment.ts +93 -4
  46. package/src/config/index.ts +15 -4
  47. package/src/config/validation-helpers.ts +202 -15
  48. package/src/config/validation.ts +530 -133
  49. package/src/config-cache.ts +45 -0
  50. package/src/create-worker-preview.ts +22 -13
  51. package/src/create-worker-upload-form.ts +32 -9
  52. package/src/dev/dev-vars.ts +36 -0
  53. package/src/dev/dev.tsx +136 -75
  54. package/src/dev/local.tsx +196 -125
  55. package/src/dev/remote.tsx +25 -13
  56. package/src/dev/use-esbuild.ts +23 -5
  57. package/src/dialogs.tsx +16 -6
  58. package/src/entry.ts +119 -11
  59. package/src/environment-variables.ts +3 -1
  60. package/src/errors.ts +11 -0
  61. package/src/https-options.ts +3 -2
  62. package/src/index.tsx +739 -400
  63. package/src/inspect.ts +17 -11
  64. package/src/intl-polyfill.d.ts +139 -0
  65. package/src/{kv/index.tsx → kv.ts} +8 -28
  66. package/src/logger.ts +66 -0
  67. package/src/miniflare-cli/README.md +30 -0
  68. package/src/miniflare-cli/enum-keys.ts +17 -0
  69. package/src/miniflare-cli/index.ts +41 -0
  70. package/src/miniflare-cli/request-context.ts +40 -0
  71. package/src/module-collection.ts +63 -58
  72. package/src/open-in-browser.ts +5 -4
  73. package/src/package-manager.ts +9 -8
  74. package/src/pages.tsx +883 -62
  75. package/src/parse.ts +1 -1
  76. package/src/proxy.ts +32 -21
  77. package/src/publish.ts +276 -161
  78. package/src/sites.tsx +88 -33
  79. package/src/tail/index.ts +2 -2
  80. package/src/tail/printing.ts +13 -8
  81. package/src/update-check.ts +19 -0
  82. package/src/user.tsx +231 -103
  83. package/src/whoami.tsx +2 -1
  84. package/src/worker.ts +15 -6
  85. package/templates/gitignore +171 -0
  86. package/templates/static-asset-facade.js +1 -1
  87. package/wrangler-dist/cli.js +22087 -49340
  88. package/src/__tests__/dev2.test.tsx +0 -152
  89. package/src/__tests__/helpers/mock-user.ts +0 -27
  90. package/src/__tests__/logout.test.ts +0 -50
  91. package/src/__tests__/sentry.test.ts +0 -146
  92. package/src/reporting.ts +0 -131
  93. package/wrangler-dist/cli.js.map +0 -7
@@ -1,4 +1,4 @@
1
- import type { Config, RawConfig } from "./config";
1
+ import type { RawConfig } from "./config";
2
2
  import type { Diagnostics } from "./diagnostics";
3
3
  import type { Environment, RawEnvironment } from "./environment";
4
4
 
@@ -14,13 +14,15 @@ export function deprecated<T extends object>(
14
14
  fieldPath: DeepKeyOf<T>,
15
15
  message: string,
16
16
  remove: boolean,
17
- breaking = false
17
+ title = "Deprecation",
18
+ type: "warning" | "error" = "warning"
18
19
  ): void {
20
+ const BOLD = "\x1b[1m";
21
+ const NORMAL = "\x1b[0m";
22
+ const diagnosticMessage = `${BOLD}${title}${NORMAL}: "${fieldPath}":\n${message}`;
19
23
  const result = unwindPropertyPath(config, fieldPath);
20
24
  if (result !== undefined && result.field in result.container) {
21
- (breaking ? diagnostics.errors : diagnostics.warnings).push(
22
- `DEPRECATION: "${fieldPath}":\n${message}`
23
- );
25
+ diagnostics[`${type}s`].push(diagnosticMessage);
24
26
  if (remove) {
25
27
  delete (result.container as Record<string, unknown>)[result.field];
26
28
  }
@@ -54,14 +56,82 @@ export function experimental<T extends object>(
54
56
  */
55
57
  export function inheritable<K extends keyof Environment>(
56
58
  diagnostics: Diagnostics,
57
- config: Config | undefined,
59
+ topLevelEnv: Environment | undefined,
60
+ rawEnv: RawEnvironment,
61
+ field: K,
62
+ validate: ValidatorFn,
63
+ defaultValue: Environment[K],
64
+ transformFn: TransformFn<Environment[K]> = (v) => v
65
+ ): Environment[K] {
66
+ validate(diagnostics, field, rawEnv[field], topLevelEnv);
67
+ return (
68
+ (rawEnv[field] as Environment[K]) ??
69
+ transformFn(topLevelEnv?.[field]) ??
70
+ defaultValue
71
+ );
72
+ }
73
+
74
+ /**
75
+ * Get an inheritable environment field, but only if we are in legacy environments
76
+ */
77
+ export function inheritableInLegacyEnvironments<K extends keyof Environment>(
78
+ diagnostics: Diagnostics,
79
+ isLegacyEnv: boolean | undefined,
80
+ topLevelEnv: Environment | undefined,
58
81
  rawEnv: RawEnvironment,
59
82
  field: K,
60
83
  validate: ValidatorFn,
84
+ transformFn: TransformFn<Environment[K]> = (v) => v,
61
85
  defaultValue: Environment[K]
62
86
  ): Environment[K] {
63
- validate(diagnostics, field, rawEnv[field], config);
64
- return (rawEnv[field] as Environment[K]) ?? config?.[field] ?? defaultValue;
87
+ return topLevelEnv === undefined || isLegacyEnv === true
88
+ ? inheritable(
89
+ diagnostics,
90
+ topLevelEnv,
91
+ rawEnv,
92
+ field,
93
+ validate,
94
+ defaultValue,
95
+ transformFn
96
+ )
97
+ : notAllowedInNamedServiceEnvironment(
98
+ diagnostics,
99
+ topLevelEnv,
100
+ rawEnv,
101
+ field
102
+ );
103
+ }
104
+
105
+ /**
106
+ * Type of function that is used to transform an inheritable environment field.
107
+ */
108
+ type TransformFn<T> = (fieldValue: T | undefined) => T | undefined;
109
+
110
+ /**
111
+ * Transform an environment field by appending current environment name to it.
112
+ */
113
+ export const appendEnvName =
114
+ (envName: string): TransformFn<string | undefined> =>
115
+ (fieldValue) =>
116
+ fieldValue ? `${fieldValue}-${envName}` : undefined;
117
+
118
+ /**
119
+ * Log an error if this named environment is trying to override the value in the top-level
120
+ * environment, which is not allow for this field.
121
+ */
122
+ function notAllowedInNamedServiceEnvironment<K extends keyof Environment>(
123
+ diagnostics: Diagnostics,
124
+ topLevelEnv: Environment,
125
+ rawEnv: RawEnvironment,
126
+ field: K
127
+ ): Environment[K] {
128
+ if (field in rawEnv) {
129
+ diagnostics.errors.push(
130
+ `The "${field}" field is not allowed in named service environments.\n` +
131
+ `Please remove the field from this environment.`
132
+ );
133
+ }
134
+ return topLevelEnv[field];
65
135
  }
66
136
 
67
137
  /**
@@ -72,7 +142,7 @@ export function inheritable<K extends keyof Environment>(
72
142
  */
73
143
  export function notInheritable<K extends keyof Environment>(
74
144
  diagnostics: Diagnostics,
75
- config: Config | undefined,
145
+ topLevelEnv: Environment | undefined,
76
146
  rawConfig: RawConfig | undefined,
77
147
  rawEnv: RawEnvironment,
78
148
  envName: string,
@@ -81,7 +151,7 @@ export function notInheritable<K extends keyof Environment>(
81
151
  defaultValue: Environment[K]
82
152
  ): Environment[K] {
83
153
  if (rawEnv[field] !== undefined) {
84
- validate(diagnostics, field, rawEnv[field], config);
154
+ validate(diagnostics, field, rawEnv[field], topLevelEnv);
85
155
  } else {
86
156
  if (rawConfig?.[field] !== undefined) {
87
157
  diagnostics.warnings.push(
@@ -139,7 +209,7 @@ export type ValidatorFn = (
139
209
  diagnostics: Diagnostics,
140
210
  field: string,
141
211
  value: unknown,
142
- config: Config | undefined
212
+ topLevelEnv: Environment | undefined
143
213
  ) => boolean;
144
214
 
145
215
  /**
@@ -148,7 +218,7 @@ export type ValidatorFn = (
148
218
  export const isString: ValidatorFn = (diagnostics, field, value) => {
149
219
  if (value !== undefined && typeof value !== "string") {
150
220
  diagnostics.errors.push(
151
- `Expected "${field}" field to be a string but got ${JSON.stringify(
221
+ `Expected "${field}" to be of type string but got ${JSON.stringify(
152
222
  value
153
223
  )}.`
154
224
  );
@@ -157,6 +227,25 @@ export const isString: ValidatorFn = (diagnostics, field, value) => {
157
227
  return true;
158
228
  };
159
229
 
230
+ /**
231
+ * Validate that the `name` field is compliant with EWC constraints.
232
+ */
233
+ export const isValidName: ValidatorFn = (diagnostics, field, value) => {
234
+ if (
235
+ (typeof value === "string" && /^$|^[a-z0-9_ ][a-z0-9-_ ]*$/.test(value)) ||
236
+ value === undefined
237
+ ) {
238
+ return true;
239
+ } else {
240
+ diagnostics.errors.push(
241
+ `Expected "${field}" to be of type string, alphanumeric and lowercase with dashes only but got ${JSON.stringify(
242
+ value
243
+ )}.`
244
+ );
245
+ return false;
246
+ }
247
+ };
248
+
160
249
  /**
161
250
  * Validate that the field is an array of strings.
162
251
  */
@@ -166,7 +255,7 @@ export const isStringArray: ValidatorFn = (diagnostics, field, value) => {
166
255
  (!Array.isArray(value) || value.some((item) => typeof item !== "string"))
167
256
  ) {
168
257
  diagnostics.errors.push(
169
- `Expected "${field}" field to be an array of strings but got ${JSON.stringify(
258
+ `Expected "${field}" to be of type string array but got ${JSON.stringify(
170
259
  value
171
260
  )}.`
172
261
  );
@@ -188,7 +277,7 @@ export const isObjectWith =
188
277
  !properties.every((prop) => prop in value))
189
278
  ) {
190
279
  diagnostics.errors.push(
191
- `Expected "${field}" field to be an object containing properties ${properties} but got ${JSON.stringify(
280
+ `Expected "${field}" to be of type object, containing properties ${properties}, but got ${JSON.stringify(
192
281
  value
193
282
  )}.`
194
283
  );
@@ -214,13 +303,61 @@ export const isOneOf =
214
303
  return true;
215
304
  };
216
305
 
306
+ /**
307
+ * Aggregate multiple validator functions
308
+ */
309
+ export const all = (...validations: ValidatorFn[]): ValidatorFn => {
310
+ return (diagnostics, field, value, config) => {
311
+ let passedValidations = true;
312
+
313
+ for (const validate of validations) {
314
+ if (!validate(diagnostics, field, value, config)) {
315
+ passedValidations = false;
316
+ }
317
+ }
318
+
319
+ return passedValidations;
320
+ };
321
+ };
322
+
323
+ /**
324
+ * Check that the field is mutually exclusive with a list of other fields.
325
+ *
326
+ * @param container the container of the fields to check against.
327
+ * @param fields the names of the fields to check against.
328
+ */
329
+ export const isMutuallyExclusiveWith = <T extends RawEnvironment | RawConfig>(
330
+ container: T,
331
+ ...fields: (keyof T)[]
332
+ ): ValidatorFn => {
333
+ return (diagnostics, field, value) => {
334
+ if (value === undefined) {
335
+ return true;
336
+ }
337
+
338
+ for (const exclusiveWith of fields) {
339
+ if (container[exclusiveWith] !== undefined) {
340
+ diagnostics.errors.push(
341
+ `Expected exactly one of the following fields ${JSON.stringify([
342
+ field,
343
+ ...fields,
344
+ ])}.`
345
+ );
346
+ return false;
347
+ }
348
+ }
349
+
350
+ return true;
351
+ };
352
+ };
353
+
217
354
  /**
218
355
  * Validate that the field is a boolean.
219
356
  */
220
357
  export const isBoolean: ValidatorFn = (diagnostics, field, value) => {
221
358
  if (value !== undefined && typeof value !== "boolean") {
222
359
  diagnostics.errors.push(
223
- `Expected "${field}" field to be a boolean but got ${JSON.stringify(
360
+ `Expected "${field}" to be of type boolean but got ${JSON.stringify(
224
361
  value
225
362
  )}.`
226
363
  );
@@ -386,3 +523,53 @@ export const validateAdditionalProperties = (
386
523
  }
387
524
  return true;
388
525
  };
526
+
527
+ /**
528
+ * Get the names of the bindings collection in `value`.
529
+ *
530
+ * Will return an empty array if it doesn't understand the value
531
+ * passed in, so another form of validation should be
532
+ * performed externally.
533
+ */
534
+ export const getBindingNames = (value: unknown): string[] => {
535
+ if (typeof value !== "object" || value === null) {
536
+ return [];
537
+ }
538
+
539
+ if (isBindingList(value)) {
540
+ return value.bindings.map(({ name }) => name);
541
+ } else if (isNamespaceList(value)) {
542
+ return value.map(({ binding }) => binding);
543
+ } else if (isRecord(value)) {
544
+ return Object.keys(value);
545
+ } else {
546
+ return [];
547
+ }
548
+ };
549
+
550
+ const isBindingList = (
551
+ value: unknown
552
+ ): value is {
553
+ bindings: {
554
+ name: string;
555
+ }[];
556
+ } =>
557
+ isRecord(value) &&
558
+ "bindings" in value &&
559
+ Array.isArray(value.bindings) &&
560
+ value.bindings.every(
561
+ (binding) =>
562
+ isRecord(binding) && "name" in binding && typeof binding.name === "string"
563
+ );
564
+
565
+ const isNamespaceList = (value: unknown): value is { binding: string }[] =>
566
+ Array.isArray(value) &&
567
+ value.every(
568
+ (entry) =>
569
+ isRecord(entry) && "binding" in entry && typeof entry.binding === "string"
570
+ );
571
+
572
+ const isRecord = (
573
+ value: unknown
574
+ ): value is Record<string | number | symbol, unknown> =>
575
+ typeof value === "object" && value !== null && !Array.isArray(value);