wrangler 2.0.28 → 2.0.29

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/src/dev.tsx CHANGED
@@ -8,6 +8,7 @@ import { findWranglerToml, printBindings, readConfig } from "./config";
8
8
  import Dev from "./dev/dev";
9
9
  import { getVarsForDev } from "./dev/dev-vars";
10
10
 
11
+ import { startDevServer } from "./dev/start-server";
11
12
  import { getEntry } from "./entry";
12
13
  import { logger } from "./logger";
13
14
  import * as metrics from "./metrics";
@@ -333,11 +334,17 @@ export async function startDev(args: StartDevOptions) {
333
334
  });
334
335
  }
335
336
 
336
- const entry = await getEntry(
337
- { assets: args.assets, script: args.script },
338
- config,
339
- "dev"
340
- );
337
+ const {
338
+ entry,
339
+ nodeCompat,
340
+ upstreamProtocol,
341
+ zoneId,
342
+ host,
343
+ routes,
344
+ getLocalPort,
345
+ getInspectorPort,
346
+ cliDefines,
347
+ } = await validateDevServerSettings(args, config);
341
348
 
342
349
  await metrics.sendMetricsEvent(
343
350
  "run dev",
@@ -348,196 +355,60 @@ export async function startDev(args: StartDevOptions) {
348
355
  { sendMetrics: config.send_metrics, offline: args.local }
349
356
  );
350
357
 
351
- if (config.services && config.services.length > 0) {
352
- logger.warn(
353
- `This worker is bound to live services: ${config.services
354
- .map(
355
- (service) =>
356
- `${service.binding} (${service.service}${
357
- service.environment ? `@${service.environment}` : ""
358
- })`
359
- )
360
- .join(", ")}`
361
- );
362
- }
363
-
364
- if (args.inspect) {
365
- //devtools are enabled by default, but we still need to disable them if the caller doesn't want them
366
- logger.warn(
367
- "Passing --inspect is unnecessary, now you can always connect to devtools."
368
- );
369
- }
370
-
371
- if (args["experimental-public"]) {
372
- throw new Error(
373
- "The --experimental-public field has been renamed to --assets"
374
- );
375
- }
376
-
377
- if (args.public) {
378
- throw new Error("The --public field has been renamed to --assets");
379
- }
380
-
381
- if ((args.assets || config.assets) && (args.site || config.site)) {
382
- throw new Error(
383
- "Cannot use Assets and Workers Sites in the same Worker."
384
- );
385
- }
386
-
387
- if (args.assets) {
388
- logger.warn(
389
- "The --assets argument is experimental and may change or break at any time"
390
- );
391
- }
392
-
393
- const upstreamProtocol =
394
- args["upstream-protocol"] || config.dev.upstream_protocol;
395
- if (upstreamProtocol === "http") {
396
- logger.warn(
397
- "Setting upstream-protocol to http is not currently implemented.\n" +
398
- "If this is required in your project, please add your use case to the following issue:\n" +
399
- "https://github.com/cloudflare/wrangler2/issues/583."
400
- );
401
- }
402
-
403
- // TODO: if worker_dev = false and no routes, then error (only for dev)
404
-
405
- // Compute zone info from the `host` and `route` args and config;
406
- let host = args.host || config.dev.host;
407
- let zoneId: string | undefined;
408
- const routes: Route[] | undefined =
409
- args.routes || (config.route && [config.route]) || config.routes;
410
-
411
- if (args.forceLocal) {
412
- args.local = true;
413
- }
414
-
415
- if (!args.local) {
416
- if (host) {
417
- zoneId = await getZoneIdFromHost(host);
418
- }
419
- if (!zoneId && routes) {
420
- const firstRoute = routes[0];
421
- const zone = await getZoneForRoute(firstRoute);
422
- if (zone) {
423
- zoneId = zone.id;
424
- host = zone.host;
425
- }
426
- }
427
- } else if (!host) {
428
- if (routes) {
429
- const firstRoute = routes[0];
430
- host = getHostFromRoute(firstRoute);
431
- }
432
- }
433
-
434
- const nodeCompat = args.nodeCompat ?? config.node_compat;
435
- if (nodeCompat) {
436
- logger.warn(
437
- "Enabling node.js compatibility mode for built-ins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details."
438
- );
439
- }
440
-
441
- const getLocalPort = memoizeGetPort(DEFAULT_LOCAL_PORT);
442
- const getInspectorPort = memoizeGetPort(DEFAULT_INSPECTOR_PORT);
443
-
444
- const cliVars =
445
- args.var?.reduce<Record<string, string>>((collectVars, v) => {
446
- const [key, ...value] = v.split(":");
447
- collectVars[key] = value.join("");
448
- return collectVars;
449
- }, {}) || {};
450
-
451
- const cliDefines =
452
- args.define?.reduce<Record<string, string>>((collectDefines, d) => {
453
- const [key, ...value] = d.split(":");
454
- collectDefines[key] = value.join("");
455
- return collectDefines;
456
- }, {}) || {};
457
-
458
358
  // eslint-disable-next-line no-inner-declarations
459
359
  async function getDevReactElement(configParam: Config) {
460
- // now log all available bindings into the terminal
461
- const bindings = await getBindings(configParam, {
462
- kv: args.kv,
463
- vars: { ...args.vars, ...cliVars },
464
- durableObjects: args.durableObjects,
465
- r2: args.r2,
466
- });
467
-
468
- // mask anything that was overridden in .dev.vars or cli args
469
- // so that we don't log potential secrets into the terminal
470
- const maskedVars = { ...bindings.vars };
471
- for (const key of Object.keys(maskedVars)) {
472
- if (maskedVars[key] !== configParam.vars[key]) {
473
- // This means it was overridden in .dev.vars or cli args
474
- // so let's mask it
475
- maskedVars[key] = "(hidden)";
476
- }
477
- }
478
-
479
- printBindings({
480
- ...bindings,
481
- vars: maskedVars,
482
- });
483
-
484
- const assetPaths =
485
- args.assets || config.assets
486
- ? getAssetPaths(config, args.assets)
487
- : getSiteAssetPaths(
488
- config,
489
- args.site,
490
- args.siteInclude,
491
- args.siteExclude
492
- );
360
+ const { assetPaths, bindings } = await getBindingsAndAssetPaths(
361
+ args,
362
+ configParam
363
+ );
493
364
 
494
365
  return (
495
366
  <Dev
496
- name={getScriptName({ name: args.name, env: args.env }, config)}
497
- noBundle={!(args.bundle ?? !config.no_bundle)}
367
+ name={getScriptName({ name: args.name, env: args.env }, configParam)}
368
+ noBundle={!(args.bundle ?? !configParam.no_bundle)}
498
369
  entry={entry}
499
370
  env={args.env}
500
371
  zone={zoneId}
501
372
  host={host}
502
373
  routes={routes}
503
- rules={getRules(config)}
504
- legacyEnv={isLegacyEnv(config)}
505
- minify={args.minify ?? config.minify}
374
+ rules={getRules(configParam)}
375
+ legacyEnv={isLegacyEnv(configParam)}
376
+ minify={args.minify ?? configParam.minify}
506
377
  nodeCompat={nodeCompat}
507
- build={config.build || {}}
508
- define={{ ...config.define, ...cliDefines }}
378
+ build={configParam.build || {}}
379
+ define={{ ...configParam.define, ...cliDefines }}
509
380
  initialMode={args.local ? "local" : "remote"}
510
- jsxFactory={args["jsx-factory"] || config.jsx_factory}
511
- jsxFragment={args["jsx-fragment"] || config.jsx_fragment}
512
- tsconfig={args.tsconfig ?? config.tsconfig}
381
+ jsxFactory={args["jsx-factory"] || configParam.jsx_factory}
382
+ jsxFragment={args["jsx-fragment"] || configParam.jsx_fragment}
383
+ tsconfig={args.tsconfig ?? configParam.tsconfig}
513
384
  upstreamProtocol={upstreamProtocol}
514
- localProtocol={args.localProtocol || config.dev.local_protocol}
385
+ localProtocol={args.localProtocol || configParam.dev.local_protocol}
515
386
  localUpstream={args["local-upstream"] || host}
516
387
  enableLocalPersistence={
517
388
  args.experimentalEnableLocalPersistence || false
518
389
  }
519
390
  liveReload={args.liveReload || false}
520
- accountId={config.account_id || getAccountFromCache()?.id}
391
+ accountId={configParam.account_id || getAccountFromCache()?.id}
521
392
  assetPaths={assetPaths}
522
- assetsConfig={config.assets}
523
- port={args.port || config.dev.port || (await getLocalPort())}
524
- ip={args.ip || config.dev.ip}
393
+ assetsConfig={configParam.assets}
394
+ port={args.port || configParam.dev.port || (await getLocalPort())}
395
+ ip={args.ip || configParam.dev.ip}
525
396
  inspectorPort={
526
397
  args.inspectorPort ||
527
- config.dev.inspector_port ||
398
+ configParam.dev.inspector_port ||
528
399
  (await getInspectorPort())
529
400
  }
530
- isWorkersSite={Boolean(args.site || config.site)}
401
+ isWorkersSite={Boolean(args.site || configParam.site)}
531
402
  compatibilityDate={getDevCompatibilityDate(
532
- config,
403
+ configParam,
533
404
  args.compatibilityDate
534
405
  )}
535
406
  compatibilityFlags={
536
- args.compatibilityFlags || config.compatibility_flags
407
+ args.compatibilityFlags || configParam.compatibility_flags
537
408
  }
538
- usageModel={config.usage_model}
409
+ usageModel={configParam.usage_model}
539
410
  bindings={bindings}
540
- crons={config.triggers.crons}
411
+ crons={configParam.triggers.crons}
541
412
  logLevel={args.logLevel}
542
413
  logPrefix={args.logPrefix}
543
414
  onReady={args.onReady}
@@ -545,8 +416,8 @@ export async function startDev(args: StartDevOptions) {
545
416
  showInteractiveDevSession={args.showInteractiveDevSession}
546
417
  forceLocal={args.forceLocal}
547
418
  enablePagesAssetsServiceBinding={args.enablePagesAssetsServiceBinding}
548
- firstPartyWorker={config.first_party_worker}
549
- sendMetrics={config.send_metrics}
419
+ firstPartyWorker={configParam.first_party_worker}
420
+ sendMetrics={configParam.send_metrics}
550
421
  />
551
422
  );
552
423
  }
@@ -560,7 +431,6 @@ export async function startDev(args: StartDevOptions) {
560
431
  await watcher?.close();
561
432
  },
562
433
  fetch: async (init?: RequestInit) => {
563
- //TODO: we are not guaranteed to be assigned this port, we should fix this ASAP
564
434
  const port = args.port || config.dev.port || (await getLocalPort());
565
435
  const address = args.ip || config.dev.ip || "localhost";
566
436
 
@@ -572,6 +442,116 @@ export async function startDev(args: StartDevOptions) {
572
442
  }
573
443
  }
574
444
 
445
+ export async function startApiDev(args: StartDevOptions) {
446
+ if (args.logLevel) {
447
+ // we don't define a "none" logLevel, so "error" will do for now.
448
+ logger.loggerLevel = args.logLevel === "none" ? "error" : args.logLevel;
449
+ }
450
+ await printWranglerBanner();
451
+
452
+ const configPath =
453
+ (args.config as ConfigPath) ||
454
+ ((args.script &&
455
+ findWranglerToml(path.dirname(args.script))) as ConfigPath);
456
+ const config = readConfig(configPath, args);
457
+
458
+ const {
459
+ entry,
460
+ nodeCompat,
461
+ upstreamProtocol,
462
+ zoneId,
463
+ host,
464
+ routes,
465
+ getLocalPort,
466
+ getInspectorPort,
467
+ cliDefines,
468
+ } = await validateDevServerSettings(args, config);
469
+
470
+ await metrics.sendMetricsEvent(
471
+ "run dev (api)",
472
+ { local: args.local },
473
+ { sendMetrics: config.send_metrics, offline: args.local }
474
+ );
475
+
476
+ // eslint-disable-next-line no-inner-declarations
477
+ async function getDevServer(configParam: Config) {
478
+ const { assetPaths, bindings } = await getBindingsAndAssetPaths(
479
+ args,
480
+ configParam
481
+ );
482
+
483
+ return await startDevServer({
484
+ name: getScriptName({ name: args.name, env: args.env }, configParam),
485
+ noBundle: !(args.bundle ?? !configParam.no_bundle),
486
+ entry: entry,
487
+ env: args.env,
488
+ zone: zoneId,
489
+ host: host,
490
+ routes: routes,
491
+ rules: getRules(configParam),
492
+ legacyEnv: isLegacyEnv(configParam),
493
+ minify: args.minify ?? configParam.minify,
494
+ nodeCompat: nodeCompat,
495
+ build: configParam.build || {},
496
+ define: { ...config.define, ...cliDefines },
497
+ initialMode: args.local ? "local" : "remote",
498
+ jsxFactory: args["jsx-factory"] || configParam.jsx_factory,
499
+ jsxFragment: args["jsx-fragment"] || configParam.jsx_fragment,
500
+ tsconfig: args.tsconfig ?? configParam.tsconfig,
501
+ upstreamProtocol: upstreamProtocol,
502
+ localProtocol: args.localProtocol || configParam.dev.local_protocol,
503
+ localUpstream: args["local-upstream"] || host,
504
+ enableLocalPersistence: args.experimentalEnableLocalPersistence || false,
505
+ liveReload: args.liveReload || false,
506
+ accountId: configParam.account_id || getAccountFromCache()?.id,
507
+ assetPaths: assetPaths,
508
+ assetsConfig: configParam.assets,
509
+ port: args.port || configParam.dev.port || (await getLocalPort()),
510
+ ip: args.ip || configParam.dev.ip,
511
+ inspectorPort:
512
+ args["inspector-port"] ||
513
+ configParam.dev.inspector_port ||
514
+ (await getInspectorPort()),
515
+ isWorkersSite: Boolean(args.site || configParam.site),
516
+ compatibilityDate: getDevCompatibilityDate(
517
+ config,
518
+ args["compatibility-date"]
519
+ ),
520
+ compatibilityFlags:
521
+ args["compatibility-flags"] || configParam.compatibility_flags,
522
+ usageModel: configParam.usage_model,
523
+ bindings: bindings,
524
+ crons: configParam.triggers.crons,
525
+ logLevel: args.logLevel,
526
+ logPrefix: args.logPrefix,
527
+ onReady: args.onReady,
528
+ inspect: args.inspect ?? true,
529
+ showInteractiveDevSession: args.showInteractiveDevSession,
530
+ forceLocal: args.forceLocal,
531
+ enablePagesAssetsServiceBinding: args.enablePagesAssetsServiceBinding,
532
+ local: true,
533
+ firstPartyWorker: undefined,
534
+ sendMetrics: undefined,
535
+ });
536
+ }
537
+
538
+ const devServer = await getDevServer(config);
539
+ if (!devServer) {
540
+ throw logger.error("Failed to start dev server.");
541
+ }
542
+
543
+ return {
544
+ stop: async () => {
545
+ await devServer.stop();
546
+ },
547
+ fetch: async (init?: RequestInit) => {
548
+ const port = args.port || config.dev.port || (await getLocalPort());
549
+ const address = args.ip || config.dev.ip || "localhost";
550
+
551
+ return await fetch(`http://${address}:${port}/`, init);
552
+ },
553
+ };
554
+ }
575
555
  /**
576
556
  * Avoiding calling `getPort()` multiple times by memoizing the first result.
577
557
  */
@@ -581,6 +561,182 @@ function memoizeGetPort(defaultPort: number) {
581
561
  return portValue || (portValue = await getPort({ port: defaultPort }));
582
562
  };
583
563
  }
564
+ /**
565
+ * mask anything that was overridden in .dev.vars
566
+ * so that we don't log potential secrets into the terminal
567
+ */
568
+ function maskVars(bindings: CfWorkerInit["bindings"], configParam: Config) {
569
+ const maskedVars = { ...bindings.vars };
570
+ for (const key of Object.keys(maskedVars)) {
571
+ if (maskedVars[key] !== configParam.vars[key]) {
572
+ // This means it was overridden in .dev.vars
573
+ // so let's mask it
574
+ maskedVars[key] = "(hidden)";
575
+ }
576
+ }
577
+ return maskedVars;
578
+ }
579
+
580
+ async function getZoneIdHostAndRoutes(args: StartDevOptions, config: Config) {
581
+ // TODO: if worker_dev = false and no routes, then error (only for dev)
582
+ // Compute zone info from the `host` and `route` args and config;
583
+ let host = args.host || config.dev.host;
584
+ let zoneId: string | undefined;
585
+ const routes: Route[] | undefined =
586
+ args.routes || (config.route && [config.route]) || config.routes;
587
+
588
+ if (args.forceLocal) {
589
+ args.local = true;
590
+ }
591
+
592
+ if (!args.local) {
593
+ if (host) {
594
+ zoneId = await getZoneIdFromHost(host);
595
+ }
596
+ if (!zoneId && routes) {
597
+ const firstRoute = routes[0];
598
+ const zone = await getZoneForRoute(firstRoute);
599
+ if (zone) {
600
+ zoneId = zone.id;
601
+ host = zone.host;
602
+ }
603
+ }
604
+ } else if (!host) {
605
+ if (routes) {
606
+ const firstRoute = routes[0];
607
+ host = getHostFromRoute(firstRoute);
608
+ }
609
+ }
610
+ return { host, routes, zoneId };
611
+ }
612
+
613
+ async function validateDevServerSettings(
614
+ args: StartDevOptions,
615
+ config: Config
616
+ ) {
617
+ const entry = await getEntry(
618
+ { assets: args.assets, script: args.script },
619
+ config,
620
+ "dev"
621
+ );
622
+
623
+ const { zoneId, host, routes } = await getZoneIdHostAndRoutes(args, config);
624
+ const getLocalPort = memoizeGetPort(DEFAULT_LOCAL_PORT);
625
+ const getInspectorPort = memoizeGetPort(DEFAULT_INSPECTOR_PORT);
626
+
627
+ if (config.services && config.services.length > 0) {
628
+ logger.warn(
629
+ `This worker is bound to live services: ${config.services
630
+ .map(
631
+ (service) =>
632
+ `${service.binding} (${service.service}${
633
+ service.environment ? `@${service.environment}` : ""
634
+ })`
635
+ )
636
+ .join(", ")}`
637
+ );
638
+ }
639
+
640
+ if (args.inspect) {
641
+ //devtools are enabled by default, but we still need to disable them if the caller doesn't want them
642
+ logger.warn(
643
+ "Passing --inspect is unnecessary, now you can always connect to devtools."
644
+ );
645
+ }
646
+
647
+ if (args["experimental-public"]) {
648
+ throw new Error(
649
+ "The --experimental-public field has been renamed to --assets"
650
+ );
651
+ }
652
+
653
+ if (args.public) {
654
+ throw new Error("The --public field has been renamed to --assets");
655
+ }
656
+
657
+ if ((args.assets || config.assets) && (args.site || config.site)) {
658
+ throw new Error("Cannot use Assets and Workers Sites in the same Worker.");
659
+ }
660
+
661
+ if (args.assets) {
662
+ logger.warn(
663
+ "The --assets argument is experimental and may change or break at any time"
664
+ );
665
+ }
666
+
667
+ const upstreamProtocol =
668
+ args["upstream-protocol"] || config.dev.upstream_protocol;
669
+ if (upstreamProtocol === "http") {
670
+ logger.warn(
671
+ "Setting upstream-protocol to http is not currently implemented.\n" +
672
+ "If this is required in your project, please add your use case to the following issue:\n" +
673
+ "https://github.com/cloudflare/wrangler2/issues/583."
674
+ );
675
+ }
676
+ const nodeCompat = args.nodeCompat ?? config.node_compat;
677
+ if (nodeCompat) {
678
+ logger.warn(
679
+ "Enabling node.js compatibility mode for built-ins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details."
680
+ );
681
+ }
682
+
683
+ const cliDefines =
684
+ args.define?.reduce<Record<string, string>>((collectDefines, d) => {
685
+ const [key, ...value] = d.split(":");
686
+ collectDefines[key] = value.join("");
687
+ return collectDefines;
688
+ }, {}) || {};
689
+
690
+ return {
691
+ entry,
692
+ upstreamProtocol,
693
+ nodeCompat,
694
+ getLocalPort,
695
+ getInspectorPort,
696
+ zoneId,
697
+ host,
698
+ routes,
699
+ cliDefines,
700
+ };
701
+ }
702
+
703
+ async function getBindingsAndAssetPaths(
704
+ args: StartDevOptions,
705
+ configParam: Config
706
+ ) {
707
+ const cliVars =
708
+ args.var?.reduce<Record<string, string>>((collectVars, v) => {
709
+ const [key, ...value] = v.split(":");
710
+ collectVars[key] = value.join("");
711
+ return collectVars;
712
+ }, {}) || {};
713
+
714
+ // now log all available bindings into the terminal
715
+ const bindings = await getBindings(configParam, {
716
+ kv: args.kv,
717
+ vars: { ...args.vars, ...cliVars },
718
+ durableObjects: args.durableObjects,
719
+ r2: args.r2,
720
+ });
721
+
722
+ const maskedVars = maskVars(bindings, configParam);
723
+
724
+ printBindings({
725
+ ...bindings,
726
+ vars: maskedVars,
727
+ });
728
+
729
+ const assetPaths =
730
+ args.assets || configParam.assets
731
+ ? getAssetPaths(configParam, args.assets)
732
+ : getSiteAssetPaths(
733
+ configParam,
734
+ args.site,
735
+ args.siteInclude,
736
+ args.siteExclude
737
+ );
738
+ return { assetPaths, bindings };
739
+ }
584
740
 
585
741
  async function getBindings(
586
742
  configParam: Config,
package/src/entry.ts CHANGED
@@ -4,6 +4,7 @@ import path from "node:path";
4
4
  import * as esbuild from "esbuild";
5
5
  import { execaCommand } from "execa";
6
6
  import { logger } from "./logger";
7
+ import { getBasePath } from "./paths";
7
8
  import type { Config } from "./config";
8
9
  import type { CfScriptFormat } from "./worker";
9
10
  import type { Metafile } from "esbuild";
@@ -40,7 +41,7 @@ export async function getEntry(
40
41
  : // site.entry-point could be a directory
41
42
  path.resolve(config.site?.["entry-point"], "index.js");
42
43
  } else if (args.assets || config.assets) {
43
- file = path.resolve(__dirname, "../templates/no-op-worker.js");
44
+ file = path.resolve(getBasePath(), "templates/no-op-worker.js");
44
45
  } else {
45
46
  throw new Error(
46
47
  `Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler ${command} path/to/script\`) or the \`main\` config field.`
package/src/init.ts CHANGED
@@ -12,10 +12,10 @@ import { initializeGit, isGitInstalled, isInsideGitRepo } from "./git-client";
12
12
  import { logger } from "./logger";
13
13
  import { getPackageManager } from "./package-manager";
14
14
  import { parsePackageJSON, parseTOML, readFileSync } from "./parse";
15
+ import { getBasePath } from "./paths";
15
16
  import { requireAuth } from "./user";
16
17
  import { CommandLineArgsError, printWranglerBanner } from "./index";
17
18
  import type { ConfigPath } from "./index";
18
-
19
19
  import type { Argv, ArgumentsCamelCase } from "yargs";
20
20
 
21
21
  export async function initOptions(yargs: Argv) {
@@ -162,7 +162,7 @@ export async function initHandler(args: ArgumentsCamelCase<InitArgs>) {
162
162
  await initializeGit(creationDirectory);
163
163
  await writeFile(
164
164
  path.join(creationDirectory, ".gitignore"),
165
- readFileSync(path.join(__dirname, "../templates/gitignore"))
165
+ readFileSync(path.join(getBasePath(), "templates/gitignore"))
166
166
  );
167
167
  logger.log(
168
168
  args.name && args.name !== "."
@@ -254,7 +254,7 @@ export async function initHandler(args: ArgumentsCamelCase<InitArgs>) {
254
254
  isTypescriptProject = true;
255
255
  await writeFile(
256
256
  path.join(creationDirectory, "./tsconfig.json"),
257
- readFileSync(path.join(__dirname, "../templates/tsconfig.json"))
257
+ readFileSync(path.join(getBasePath(), "templates/tsconfig.json"))
258
258
  );
259
259
  devDepsToInstall.push("@cloudflare/workers-types");
260
260
  devDepsToInstall.push("typescript");
@@ -495,7 +495,7 @@ export async function initHandler(args: ArgumentsCamelCase<InitArgs>) {
495
495
  });
496
496
  await writeFile(
497
497
  path.join(creationDirectory, "./src/index.ts"),
498
- readFileSync(path.join(__dirname, `../templates/${template}`))
498
+ readFileSync(path.join(getBasePath(), `templates/${template}`))
499
499
  );
500
500
 
501
501
  logger.log(
@@ -561,7 +561,7 @@ export async function initHandler(args: ArgumentsCamelCase<InitArgs>) {
561
561
  });
562
562
  await writeFile(
563
563
  path.join(creationDirectory, "./src/index.js"),
564
- readFileSync(path.join(__dirname, `../templates/${template}`))
564
+ readFileSync(path.join(getBasePath(), `templates/${template}`))
565
565
  );
566
566
 
567
567
  logger.log(
@@ -51,6 +51,7 @@ export type EventNames =
51
51
  | "list pages deployments"
52
52
  | "build pages functions"
53
53
  | "run dev"
54
+ | "run dev (api)"
54
55
  | "run pages dev";
55
56
 
56
57
  /**