wrangler 0.0.0-beta.6 → 0.0.0-bf67bf2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wrangler",
3
- "version": "0.0.0-beta.6",
3
+ "version": "0.0.0-bf67bf2",
4
4
  "author": "wrangler@cloudflare.com",
5
5
  "description": "Command-line interface for all things Cloudflare Workers",
6
6
  "bin": {
@@ -36,11 +36,13 @@
36
36
  "cli"
37
37
  ],
38
38
  "dependencies": {
39
- "@cloudflare/pages-functions-compiler": "0.3.5",
40
- "esbuild": "0.13.12",
39
+ "@cloudflare/pages-functions-compiler": "0.3.7",
40
+ "esbuild": "0.14.1",
41
41
  "miniflare": "2.0.0-rc.2",
42
42
  "semiver": "^1.1.0",
43
- "serve": "^13.0.2"
43
+ "serve": "^13.0.2",
44
+ "@esbuild-plugins/node-globals-polyfill": "^0.1.1",
45
+ "@esbuild-plugins/node-modules-polyfill": "^0.1.2"
44
46
  },
45
47
  "optionalDependencies": {
46
48
  "fsevents": "~2.3.2"
@@ -49,13 +51,13 @@
49
51
  "@iarna/toml": "^2.2.5",
50
52
  "@types/cloudflare": "^2.7.6",
51
53
  "@types/express": "^4.17.13",
52
- "@types/react": "^17.0.34",
54
+ "@types/react": "^17.0.37",
53
55
  "@types/signal-exit": "^3.0.1",
54
- "@types/ws": "^8.2.0",
55
- "@types/yargs": "^17.0.5",
56
+ "@types/ws": "^8.2.1",
57
+ "@types/yargs": "^17.0.7",
56
58
  "clipboardy": "^3.0.0",
57
59
  "command-exists": "^1.2.9",
58
- "execa": "^5.1.1",
60
+ "execa": "^6.0.0",
59
61
  "express": "^4.17.1",
60
62
  "finalhandler": "^1.1.2",
61
63
  "find-up": "^6.2.0",
@@ -63,18 +65,18 @@
63
65
  "http-proxy": "^1.18.1",
64
66
  "http-proxy-middleware": "^2.0.1",
65
67
  "ink": "^3.2.0",
66
- "ink-select-input": "^4.2.0",
68
+ "ink-select-input": "^4.2.1",
67
69
  "ink-table": "^3.0.0",
68
- "ink-text-input": "^4.0.1",
70
+ "ink-text-input": "^4.0.2",
69
71
  "node-fetch": "^3.1.0",
70
72
  "open": "^8.4.0",
71
73
  "path-to-regexp": "^6.2.0",
72
74
  "react": "^17.0.2",
73
75
  "serve-static": "^1.14.1",
74
- "signal-exit": "^3.0.5",
76
+ "signal-exit": "^3.0.6",
75
77
  "tmp-promise": "^3.0.3",
76
- "ws": "^8.2.3",
77
- "yargs": "^17.2.1"
78
+ "ws": "^8.3.0",
79
+ "yargs": "^17.3.0"
78
80
  },
79
81
  "files": [
80
82
  "src",
@@ -98,7 +100,7 @@
98
100
  "jest": {
99
101
  "testRegex": ".*.(test|spec)\\.[jt]sx?$",
100
102
  "transformIgnorePatterns": [
101
- "node_modules/(?!node-fetch|fetch-blob|find-up|locate-path|p-locate|p-limit|yocto-queue|path-exists|data-uri-to-buffer|formdata-polyfill)"
103
+ "node_modules/(?!node-fetch|fetch-blob|find-up|locate-path|p-locate|p-limit|yocto-queue|path-exists|data-uri-to-buffer|formdata-polyfill|execa|strip-final-newline|npm-run-path|path-key|onetime|mimic-fn|human-signals|is-stream)"
102
104
  ],
103
105
  "moduleNameMapper": {
104
106
  "clipboardy": "<rootDir>/src/__tests__/clipboardy-mock.js"
@@ -112,4 +114,4 @@
112
114
  ]
113
115
  }
114
116
  }
115
- }
117
+ }
@@ -110,7 +110,7 @@ describe("wrangler", () => {
110
110
  return { id: "some-namespace-id" };
111
111
  });
112
112
 
113
- await w('kv:namespace create "UnitTestNamespace"');
113
+ await w("kv:namespace create UnitTestNamespace");
114
114
  expect(
115
115
  KVNamespaces.find((ns) => ns.title === `worker-UnitTestNamespace`)
116
116
  ).toBeTruthy();
@@ -3,8 +3,6 @@ import type {
3
3
  CfModuleType,
4
4
  CfVariable,
5
5
  CfModule,
6
- CfKvNamespace,
7
- CfCryptoKey,
8
6
  } from "./worker.js";
9
7
  import { FormData, Blob } from "formdata-node";
10
8
 
@@ -27,12 +25,26 @@ function toBinding(
27
25
  return { name, type: "plain_text", text: variable };
28
26
  }
29
27
 
30
- const { namespaceId } = variable as CfKvNamespace;
31
- if (namespaceId) {
32
- return { name, type: "kv_namespace", namespace_id: namespaceId };
28
+ if ("namespaceId" in variable) {
29
+ return {
30
+ name,
31
+ type: "kv_namespace",
32
+ namespace_id: variable.namespaceId,
33
+ };
33
34
  }
34
35
 
35
- const { format, algorithm, usages, data } = variable as CfCryptoKey;
36
+ if ("class_name" in variable) {
37
+ return {
38
+ name,
39
+ type: "durable_object_namespace",
40
+ class_name: variable.class_name,
41
+ ...(variable.script_name && {
42
+ script_name: variable.script_name,
43
+ }),
44
+ };
45
+ }
46
+
47
+ const { format, algorithm, usages, data } = variable;
36
48
  if (format) {
37
49
  let key_base64;
38
50
  let key_jwk;
@@ -84,7 +96,15 @@ function toModule(module: CfModule, entryType?: CfModuleType): Blob {
84
96
  */
85
97
  export function toFormData(worker: CfWorkerInit): FormData {
86
98
  const formData = new FormData();
87
- const { main, modules, variables, usage_model, compatibility_date } = worker;
99
+ const {
100
+ main,
101
+ modules,
102
+ variables,
103
+ migrations,
104
+ usage_model,
105
+ compatibility_date,
106
+ compatibility_flags,
107
+ } = worker;
88
108
  const { name, type: mainType } = main;
89
109
 
90
110
  const bindings = [];
@@ -93,23 +113,36 @@ export function toFormData(worker: CfWorkerInit): FormData {
93
113
  bindings.push(binding);
94
114
  }
95
115
 
96
- const singleton = mainType === "commonjs";
97
- const metadata = {
98
- main_module: singleton ? undefined : name,
99
- body_part: singleton ? name : undefined,
100
- bindings,
101
- };
116
+ const metadata =
117
+ mainType !== "commonjs"
118
+ ? {
119
+ main_module: name,
120
+ bindings,
121
+ }
122
+ : {
123
+ body_part: name,
124
+ bindings,
125
+ };
102
126
  if (compatibility_date) {
103
127
  // @ts-expect-error - we should type metadata
104
128
  metadata.compatibility_date = compatibility_date;
105
129
  }
130
+ if (compatibility_flags) {
131
+ // @ts-expect-error - we should type metadata
132
+ metadata.compatibility_flags = compatibility_flags;
133
+ }
106
134
  if (usage_model) {
107
135
  // @ts-expect-error - we should type metadata
108
136
  metadata.usage_model = usage_model;
109
137
  }
138
+ if (migrations) {
139
+ // @ts-expect-error - we should type metadata
140
+ metadata.migrations = migrations;
141
+ }
142
+
110
143
  formData.set("metadata", JSON.stringify(metadata));
111
144
 
112
- if (singleton && modules && modules.length > 0) {
145
+ if (mainType === "commonjs" && modules && modules.length > 0) {
113
146
  throw new TypeError(
114
147
  "More than one module can only be specified when type = 'esm'"
115
148
  );
package/src/api/worker.ts CHANGED
@@ -72,6 +72,21 @@ export interface CfKvNamespace {
72
72
  namespaceId: string;
73
73
  }
74
74
 
75
+ export interface CfDurableObject {
76
+ class_name: string;
77
+ script_name?: string;
78
+ }
79
+
80
+ interface CfDOMigrations {
81
+ old_tag?: string;
82
+ new_tag: string;
83
+ steps: {
84
+ new_classes?: string[];
85
+ renamed_classes?: string[];
86
+ deleted_classes?: string[];
87
+ }[];
88
+ }
89
+
75
90
  /**
76
91
  * A `WebCrypto` key.
77
92
  *
@@ -99,7 +114,7 @@ export interface CfCryptoKey {
99
114
  /**
100
115
  * A variable (aka. environment variable).
101
116
  */
102
- export type CfVariable = string | CfKvNamespace | CfCryptoKey;
117
+ export type CfVariable = string | CfKvNamespace | CfCryptoKey | CfDurableObject;
103
118
 
104
119
  /**
105
120
  * Options for creating a `CfWorker`.
@@ -117,8 +132,10 @@ export interface CfWorkerInit {
117
132
  * The map of names to variables. (aka. environment variables)
118
133
  */
119
134
  variables?: { [name: string]: CfVariable };
120
- compatibility_date?: string;
121
- usage_model?: void | "bundled" | "unbound";
135
+ migrations: void | CfDOMigrations;
136
+ compatibility_date: string | void;
137
+ compatibility_flags: void | string[];
138
+ usage_model: void | "bundled" | "unbound";
122
139
  }
123
140
 
124
141
  /**
package/src/config.ts CHANGED
@@ -1,6 +1,13 @@
1
1
  // we're going to manually write both the type definition AND
2
2
  // the validator for the config, so that we can give better error messages
3
3
 
4
+ type DOMigration = {
5
+ tag: string;
6
+ new_classes?: string[];
7
+ renamed_classes?: string[];
8
+ deleted_classes?: string[];
9
+ };
10
+
4
11
  type Project = "webpack" | "javascript" | "rust";
5
12
 
6
13
  type Site = {
@@ -28,6 +35,12 @@ type KVNamespace = {
28
35
  id: string;
29
36
  };
30
37
 
38
+ type DurableObject = {
39
+ name: string;
40
+ class_name: string;
41
+ script_name?: string;
42
+ };
43
+
31
44
  type Build = {
32
45
  command?: string;
33
46
  cwd?: string;
@@ -59,16 +72,22 @@ type Env = {
59
72
  name?: string; // inherited
60
73
  account_id?: string; // inherited
61
74
  workers_dev?: boolean; // inherited
75
+ compatibility_date?: string; // inherited
76
+ compatibility_flags?: string[]; // inherited
62
77
  zone_id?: string; // inherited
63
78
  routes?: string[]; // inherited
64
79
  route?: string; // inherited
65
80
  webpack_config?: string; // inherited
66
81
  site?: Site;
67
- jsxFactory?: string; // inherited
68
- jsxFragment?: string; // inherited
82
+ jsx_factory?: string; // inherited
83
+ jsx_fragment?: string; // inherited
84
+ polyfill_node?: boolean; //inherited
69
85
  // we should use typescript to parse cron patterns
70
86
  triggers?: { crons: Cron[] }; // inherited
87
+ vars?: Vars;
88
+ durable_objects?: { bindings: DurableObject[] };
71
89
  kv_namespaces?: KVNamespace[];
90
+ usage_model?: UsageModel; // inherited
72
91
  };
73
92
 
74
93
  export type Config = {
@@ -76,6 +95,8 @@ export type Config = {
76
95
  account_id?: string; // inherited
77
96
  // @deprecated Don't use this
78
97
  type?: Project; // top level
98
+ compatibility_date?: string; // inherited
99
+ compatibility_flags?: string[]; // inherited
79
100
  // -- there's some mutually exclusive logic for this next block,
80
101
  // but I didn't bother for now
81
102
  workers_dev?: boolean; // inherited
@@ -85,9 +106,12 @@ export type Config = {
85
106
  // -- end mutually exclusive stuff
86
107
  // @deprecated Don't use this
87
108
  webpack_config?: string; // inherited
88
- jsxFactory?: string; // inherited
89
- jsxFragment?: string; // inherited
109
+ jsx_factory?: string; // inherited
110
+ jsx_fragment?: string; // inherited
111
+ polyfill_node?: boolean; //inherited
90
112
  vars?: Vars;
113
+ migrations?: DOMigration[];
114
+ durable_objects?: { bindings: DurableObject[] };
91
115
  kv_namespaces?: KVNamespace[];
92
116
  site?: Site; // inherited
93
117
  // we should use typescript to parse cron patterns
@@ -96,5 +120,5 @@ export type Config = {
96
120
  usage_model?: UsageModel; // inherited
97
121
  // top level
98
122
  build?: Build;
99
- env?: { [envName: string]: Env };
123
+ env?: { [envName: string]: void | Env };
100
124
  };
package/src/dev.tsx CHANGED
@@ -22,6 +22,8 @@ import commandExists from "command-exists";
22
22
  import assert from "assert";
23
23
  import { getAPIToken } from "./user";
24
24
  import fetch from "node-fetch";
25
+ import NodeModulesPolyfills from "@esbuild-plugins/node-modules-polyfill";
26
+ import NodeGlobalsPolyfills from "@esbuild-plugins/node-globals-polyfill";
25
27
 
26
28
  type CfScriptFormat = void | "modules" | "service-worker";
27
29
 
@@ -37,6 +39,10 @@ type Props = {
37
39
  variables: { [name: string]: CfVariable };
38
40
  public: void | string;
39
41
  site: void | string;
42
+ compatibilityDate: void | string;
43
+ compatibilityFlags: void | string[];
44
+ usageModel: void | "bundled" | "unbound";
45
+ polyfillNode: void | boolean;
40
46
  };
41
47
 
42
48
  export function Dev(props: Props): JSX.Element {
@@ -55,6 +61,7 @@ export function Dev(props: Props): JSX.Element {
55
61
  staticRoot: props.public,
56
62
  jsxFactory: props.jsxFactory,
57
63
  jsxFragment: props.jsxFragment,
64
+ polyfillNode: props.polyfillNode,
58
65
  });
59
66
  if (bundle && bundle.type === "commonjs" && !props.format && props.public) {
60
67
  throw new Error(
@@ -98,6 +105,9 @@ export function Dev(props: Props): JSX.Element {
98
105
  site={props.site}
99
106
  public={props.public}
100
107
  port={props.port}
108
+ compatibilityDate={props.compatibilityDate}
109
+ compatibilityFlags={props.compatibilityFlags}
110
+ usageModel={props.usageModel}
101
111
  />
102
112
  )}
103
113
  <Box borderStyle="round" paddingLeft={1} paddingRight={1}>
@@ -153,6 +163,9 @@ function Remote(props: {
153
163
  accountId: void | string;
154
164
  apiToken: void | string;
155
165
  variables: { [name: string]: CfVariable };
166
+ compatibilityDate: string | void;
167
+ compatibilityFlags: void | string[];
168
+ usageModel: void | "bundled" | "unbound";
156
169
  }) {
157
170
  assert(props.accountId, "accountId is required");
158
171
  assert(props.apiToken, "apiToken is required");
@@ -166,6 +179,9 @@ function Remote(props: {
166
179
  variables: props.variables,
167
180
  sitesFolder: props.site,
168
181
  port: props.port,
182
+ compatibilityDate: props.compatibilityDate,
183
+ compatibilityFlags: props.compatibilityFlags,
184
+ usageModel: props.usageModel,
169
185
  });
170
186
 
171
187
  useProxy({ token, publicRoot: props.public, port: props.port });
@@ -236,6 +252,7 @@ function useLocalWorker(props: {
236
252
  port.toString(),
237
253
  "--kv-persist",
238
254
  "--cache-persist",
255
+ "--do-persist",
239
256
  ...Object.entries(variables)
240
257
  .map(([varKey, varVal]) => {
241
258
  if (typeof varVal === "string") {
@@ -245,6 +262,8 @@ function useLocalWorker(props: {
245
262
  typeof varVal.namespaceId === "string"
246
263
  ) {
247
264
  return `--kv ${varKey}`;
265
+ } else if ("class_name" in varVal) {
266
+ return `--do ${varKey}=${varVal.class_name}`;
248
267
  }
249
268
  })
250
269
  .filter(Boolean),
@@ -262,7 +281,7 @@ function useLocalWorker(props: {
262
281
  }
263
282
  });
264
283
 
265
- local.current.stdout.on("data", (data: string) => {
284
+ local.current.stdout.on("data", (_data: string) => {
266
285
  // console.log(`stdout: ${data}`);
267
286
  });
268
287
 
@@ -277,7 +296,7 @@ function useLocalWorker(props: {
277
296
  }
278
297
  });
279
298
 
280
- removeSignalExitListener.current = onExit((code, signal) => {
299
+ removeSignalExitListener.current = onExit((_code, _signal) => {
281
300
  console.log("⎔ Shutting down local server.");
282
301
  local.current?.kill();
283
302
  local.current = undefined;
@@ -336,8 +355,16 @@ function useEsbuild(props: {
336
355
  staticRoot: void | string;
337
356
  jsxFactory: string | void;
338
357
  jsxFragment: string | void;
358
+ polyfillNode: boolean | void;
339
359
  }): EsbuildBundle | void {
340
- const { entry, destination, staticRoot, jsxFactory, jsxFragment } = props;
360
+ const {
361
+ entry,
362
+ destination,
363
+ staticRoot,
364
+ jsxFactory,
365
+ jsxFragment,
366
+ polyfillNode,
367
+ } = props;
341
368
  const [bundle, setBundle] = useState<EsbuildBundle>();
342
369
  useEffect(() => {
343
370
  let result: esbuild.BuildResult;
@@ -345,6 +372,9 @@ function useEsbuild(props: {
345
372
  if (!destination) return;
346
373
  result = await esbuild.build({
347
374
  entryPoints: [entry],
375
+ define: {
376
+ ...(polyfillNode && { global: "globalThis" }),
377
+ },
348
378
  bundle: true,
349
379
  outdir: destination,
350
380
  metafile: true,
@@ -353,6 +383,9 @@ function useEsbuild(props: {
353
383
  loader: {
354
384
  ".js": "jsx",
355
385
  },
386
+ plugins: polyfillNode
387
+ ? [NodeGlobalsPolyfills({ buffer: true }), NodeModulesPolyfills()]
388
+ : undefined,
356
389
  ...(jsxFactory && { jsxFactory }),
357
390
  ...(jsxFragment && { jsxFragment }),
358
391
  external: ["__STATIC_CONTENT_MANIFEST"],
@@ -385,7 +418,7 @@ function useEsbuild(props: {
385
418
  return () => {
386
419
  result?.stop();
387
420
  };
388
- }, [entry, destination, staticRoot]);
421
+ }, [entry, destination, staticRoot, jsxFactory, jsxFragment, polyfillNode]);
389
422
  return bundle;
390
423
  }
391
424
 
@@ -399,6 +432,9 @@ function useWorker(props: {
399
432
  variables: { [name: string]: CfVariable };
400
433
  sitesFolder: void | string;
401
434
  port: number;
435
+ compatibilityDate: string | void;
436
+ compatibilityFlags: string[] | void;
437
+ usageModel: void | "bundled" | "unbound";
402
438
  }): CfPreviewToken | void {
403
439
  const {
404
440
  name,
@@ -409,6 +445,9 @@ function useWorker(props: {
409
445
  apiToken,
410
446
  variables,
411
447
  sitesFolder,
448
+ compatibilityDate,
449
+ compatibilityFlags,
450
+ usageModel,
412
451
  port,
413
452
  } = props;
414
453
  const [token, setToken] = useState<CfPreviewToken>();
@@ -447,15 +486,10 @@ function useWorker(props: {
447
486
  }; // TODO: cancellable?
448
487
 
449
488
  const content = await readFile(bundle.path, "utf-8");
450
- console.log(content);
451
489
  const init: CfWorkerInit = {
452
490
  main: {
453
491
  name: name || path.basename(bundle.path),
454
- type:
455
- format ||
456
- (bundle.type === "esm" ? "modules" : "service-worker") === "modules"
457
- ? "esm"
458
- : "commonjs",
492
+ type: format || bundle.type === "esm" ? "esm" : "commonjs",
459
493
  content,
460
494
  },
461
495
  modules: assets.manifest
@@ -471,6 +505,10 @@ function useWorker(props: {
471
505
  __STATIC_CONTENT: { namespaceId: assets.namespace },
472
506
  }
473
507
  : variables,
508
+ migrations: undefined, // no migrations in dev
509
+ compatibility_date: compatibilityDate,
510
+ compatibility_flags: compatibilityFlags,
511
+ usage_model: usageModel,
474
512
  };
475
513
  setToken(
476
514
  await createWorker(init, {
@@ -481,7 +519,18 @@ function useWorker(props: {
481
519
  console.log(`⬣ Listening at http://localhost:${port}`);
482
520
  }
483
521
  start();
484
- }, [name, bundle, format, accountId, apiToken, port, sitesFolder]);
522
+ }, [
523
+ name,
524
+ bundle,
525
+ format,
526
+ accountId,
527
+ apiToken,
528
+ port,
529
+ sitesFolder,
530
+ compatibilityDate,
531
+ compatibilityFlags,
532
+ usageModel,
533
+ ]);
485
534
  return token;
486
535
  }
487
536
 
@@ -606,7 +655,7 @@ function useTunnel(toggle: boolean) {
606
655
  }
607
656
  });
608
657
 
609
- removeSignalExitListener.current = onExit((code, signal) => {
658
+ removeSignalExitListener.current = onExit((_code, _signal) => {
610
659
  console.log("⎔ Shutting down local tunnel.");
611
660
  tunnel.current?.kill();
612
661
  tunnel.current = undefined;
package/src/index.tsx CHANGED
@@ -40,7 +40,7 @@ import { createTail } from "./tail";
40
40
  import onExit from "signal-exit";
41
41
  import { setTimeout } from "node:timers/promises";
42
42
  import * as fs from "node:fs";
43
- import execa from "execa";
43
+ import { execa } from "execa";
44
44
 
45
45
  async function readConfig(path?: string): Promise<Config> {
46
46
  const config: Config = {};
@@ -59,11 +59,14 @@ async function readConfig(path?: string): Promise<Config> {
59
59
  "name",
60
60
  "account_id",
61
61
  "workers_dev",
62
+ "compatibility_date",
63
+ "compatibility_flags",
62
64
  "zone_id",
63
65
  "routes",
64
66
  "route",
65
- "jsxFactory",
66
- "jsxFragment",
67
+ "jsx_factory",
68
+ "jsx_fragment",
69
+ "polyfill_node",
67
70
  "site",
68
71
  "triggers",
69
72
  "usage_model",
@@ -82,7 +85,7 @@ async function readConfig(path?: string): Promise<Config> {
82
85
  mirroredFields.forEach((field) => {
83
86
  // if it exists on top level, it should exist on env defns
84
87
  Object.keys(config[field] || {}).forEach((fieldKey) => {
85
- if (!config.env[env][field]?.[fieldKey]) {
88
+ if (!(fieldKey in config.env[env][field])) {
86
89
  console.error(
87
90
  `In your configuration, "${field}.${fieldKey}" exists at a top level, but not on "env.${env}". This is not what you probably want, since the field "${field}" is not inherited by environments. Please add "${field}.${fieldKey}" to "env.${env}".`
88
91
  );
@@ -191,8 +194,7 @@ export async function main(argv: string[]): Promise<void> {
191
194
  try {
192
195
  await writeFile(
193
196
  destination,
194
- `compatibility_date = "${compatibilityDate}"
195
- `
197
+ `compatibility_date = "${compatibilityDate}"` + "\n"
196
198
  );
197
199
  console.log(`✨ Succesfully created wrangler.toml`);
198
200
  // TODO: suggest next steps?
@@ -420,6 +422,10 @@ export async function main(argv: string[]): Promise<void> {
420
422
  .option("jsx-fragment", {
421
423
  describe: "The function that is called for each JSX fragment",
422
424
  type: "string",
425
+ })
426
+ .option("polyfill-node", {
427
+ describe: "Try to polyfill node builtins",
428
+ type: "boolean",
423
429
  });
424
430
  },
425
431
  async (args) => {
@@ -446,7 +452,14 @@ export async function main(argv: string[]): Promise<void> {
446
452
 
447
453
  // -- snip, end --
448
454
 
449
- const envRootObj = args.env ? config[`env.${args.env}`] : config;
455
+ const envRootObj = args.env ? config.env[args.env] || {} : config;
456
+
457
+ const polyfillNode = args["polyfill-node"] ?? config.polyfill_node;
458
+ if (polyfillNode) {
459
+ console.warn(
460
+ "Using polyfills for node builtin modules. These are not meant to be completely reliable, and have serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details."
461
+ );
462
+ }
450
463
 
451
464
  render(
452
465
  <Dev
@@ -454,12 +467,16 @@ export async function main(argv: string[]): Promise<void> {
454
467
  entry={filename}
455
468
  format={format}
456
469
  initialMode={args.local ? "local" : "remote"}
457
- jsxFactory={args["jsx-factory"] || envRootObj.jsxFactory}
458
- jsxFragment={args["jsx-fragment"] || envRootObj.jsxFragment}
470
+ jsxFactory={args["jsx-factory"] || envRootObj?.jsx_factory}
471
+ jsxFragment={args["jsx-fragment"] || envRootObj?.jsx_fragment}
459
472
  accountId={config.account_id}
460
473
  site={args.site || config.site?.bucket}
461
474
  port={args.port || config.dev?.port}
475
+ polyfillNode={polyfillNode}
462
476
  public={args.public}
477
+ compatibilityDate={config.compatibility_date}
478
+ compatibilityFlags={config.compatibility_flags}
479
+ usageModel={config.usage_model}
463
480
  variables={{
464
481
  ...(envRootObj?.vars || {}),
465
482
  ...(envRootObj?.kv_namespaces || []).reduce(
@@ -475,6 +492,12 @@ export async function main(argv: string[]): Promise<void> {
475
492
  },
476
493
  {}
477
494
  ),
495
+ ...(envRootObj?.durable_objects?.bindings || []).reduce(
496
+ (obj, { name, class_name, script_name }) => {
497
+ return { ...obj, [name]: { class_name, script_name } };
498
+ },
499
+ {}
500
+ ),
478
501
  }}
479
502
  />
480
503
  );
@@ -530,6 +553,10 @@ export async function main(argv: string[]): Promise<void> {
530
553
  .option("jsx-fragment", {
531
554
  describe: "The function that is called for each JSX fragment",
532
555
  type: "string",
556
+ })
557
+ .option("polyfill-node", {
558
+ describe: "Try to polyfill node builtins",
559
+ type: "boolean",
533
560
  });
534
561
  },
535
562
  async (args) => {
@@ -558,6 +585,13 @@ export async function main(argv: string[]): Promise<void> {
558
585
 
559
586
  // -- snip, end --
560
587
 
588
+ const polyfillNode = args["polyfill-node"] ?? config.polyfill_node;
589
+ if (polyfillNode) {
590
+ console.warn(
591
+ "Using polyfills for node builtin modules. These are not meant to be completely reliable, and have serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details."
592
+ );
593
+ }
594
+
561
595
  await publish({
562
596
  config: args.config as Config,
563
597
  name: args.name,
@@ -566,6 +600,7 @@ export async function main(argv: string[]): Promise<void> {
566
600
  triggers: args.triggers,
567
601
  jsxFactory: args["jsx-factory"],
568
602
  jsxFragment: args["jsx-fragment"],
603
+ polyfillNode: args["polyfill-node"],
569
604
  routes: args.routes,
570
605
  public: args.public,
571
606
  site: args.site,
@@ -1151,7 +1186,7 @@ export async function main(argv: string[]): Promise<void> {
1151
1186
  console.log(
1152
1187
  `{ binding = "${args.namespace}", ${
1153
1188
  args.preview ? "preview_" : ""
1154
- }id = ${response.id} }`
1189
+ }id = "${response.id}" }`
1155
1190
  );
1156
1191
  }
1157
1192
  )
@@ -1231,7 +1266,7 @@ export async function main(argv: string[]): Promise<void> {
1231
1266
  const id =
1232
1267
  args["namespace-id"] ||
1233
1268
  (args.env
1234
- ? config[`env.${args.env}`]
1269
+ ? config.env[args.env] || {}
1235
1270
  : config
1236
1271
  ).kv_namespaces.find(
1237
1272
  (namespace) => namespace.binding === args.binding