Repository: remix-run/remix
Pull request #3619 (2022-06-30 13:48:15)

fix(remix-dev/create): check for undefined `--token`
i'm quite interested in why our tests all passed without this...

<!--

👋 Hey, thanks for your interest in contributing to Remix!

If this is a simple docs change, go ahead and delete all this.

**Please ask first before starting work on any significant new features.**

It's never a fun experience to have your pull request declined after investing a
lot of time and effort into a new feature. To avoid this from happening, we
request that contributors create a
[Feature Request discussion](https://github.com/remix-run/remix/discussions/new?category=ideas)
to first discuss any significant new features.

https://github.com/remix-run/remix/blob/main/CONTRIBUTING.md

Please fill in or delete each item below:

-->

Closes: #3618

- [ ] Docs
- [ ] Tests

Testing Strategy:

<!--
Please explain how you tested this. For example:

> This test covers this code: <link to test>

Or

> I opened up my windows machine and ran this script:
>
> ```
> npx create-remix@0.0.0-experimental-7e420ee3 --template remix my-test
> cd my-test
> npm run dev
> ```
-->



Patch:
diff --git a/contributors.yml b/contributors.yml
index a708c85da..1aaefc480 100644
--- a/contributors.yml
+++ b/contributors.yml
@@ -62,6 +62,7 @@
 - chenxsan
 - chiangs
 - christianhg
+- christophertrudel
 - christophgockel
 - clarkmitchell
 - cliffordfajardo
diff --git a/docs/api/conventions.md b/docs/api/conventions.md
index ef7a9028e..493183d75 100644
--- a/docs/api/conventions.md
+++ b/docs/api/conventions.md
@@ -158,6 +158,16 @@ module.exports = {
 };
 ```
 
+### watchPaths
+
+A function for defining custom directories to watch while running [remix dev][remix-dev], in addition to [`appDirectory`][app-directory].
+
+```tsx
+exports.watchPaths = async () => {
+  return ["/some/path/*"];
+};
+```
+
 ## File Name Conventions
 
 There are a few conventions that Remix uses you should be aware of.
@@ -1458,3 +1468,5 @@ export default function Page() {
 [http-equiv-tag]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta#attr-http-equiv
 [error-boundaries]: https://reactjs.org/docs/error-boundaries.html
 [use-matches]: ./remix#usematches
+[remix-dev]: https://remix.run/docs/en/v1/other-api/dev#remix-dev
+[app-directory]: #appDirectory
diff --git a/packages/remix-dev/cli/create.ts b/packages/remix-dev/cli/create.ts
index 5761f35d1..008aa7b6d 100644
--- a/packages/remix-dev/cli/create.ts
+++ b/packages/remix-dev/cli/create.ts
@@ -639,10 +639,13 @@ export async function validateTemplate(
         method = "GET";
       }
       try {
-        response = await fetch(apiUrl, {
-          method,
-          headers: { Authorization: `token ${options?.githubToken}` },
-        });
+        let headers: Record<string, string> = {};
+        if (options?.githubToken) {
+          headers = {
+            Authorization: `token ${options.githubToken}`,
+          };
+        }
+        response = await fetch(apiUrl, { method, headers });
       } catch (_) {
         throw Error(
           "🚨 There was a problem fetching the template. Please ensure you " +
@@ -674,7 +677,7 @@ export async function validateTemplate(
           return;
         case 401:
           throw Error(
-            "🚨 The template could not be verified because you do are not " +
+            "🚨 The template could not be verified because you are not " +
               "authorized to access that repository. Please double check the " +
               "access rights of the repo or consider passing a `--token`"
           );
diff --git a/packages/remix-dev/compiler.ts b/packages/remix-dev/compiler.ts
index 39209f2bc..b74de1b85 100644
--- a/packages/remix-dev/compiler.ts
+++ b/packages/remix-dev/compiler.ts
@@ -222,6 +222,10 @@ export async function watch(
     toWatch.push(config.serverEntryPoint);
   }
 
+  config.watchPaths?.forEach((watchPath) => {
+    toWatch.push(watchPath);
+  });
+
   let watcher = chokidar
     .watch(toWatch, {
       persistent: true,
diff --git a/packages/remix-dev/config.ts b/packages/remix-dev/config.ts
index fae6c171b..4318375d7 100644
--- a/packages/remix-dev/config.ts
+++ b/packages/remix-dev/config.ts
@@ -147,6 +147,14 @@ export interface AppConfig {
    * in a CJS build.
    */
   serverDependenciesToBundle?: Array<string | RegExp>;
+
+  /**
+   * A function for defining custom directories to watch while running `remix dev`, in addition to `appDirectory`.
+   */
+  watchPaths?:
+    | string
+    | string[]
+    | (() => Promise<string | string[]> | string | string[]);
 }
 
 /**
@@ -250,6 +258,11 @@ export interface RemixConfig {
    * in a CJS build.
    */
   serverDependenciesToBundle: Array<string | RegExp>;
+
+  /**
+   * A list of directories to watch.
+   */
+  watchPaths: string[];
 }
 
 /**
@@ -395,6 +408,20 @@ export async function readConfig(
     }
   }
 
+  let watchPaths: string[] = [];
+  if (typeof appConfig.watchPaths === "function") {
+    let directories = await appConfig.watchPaths();
+    watchPaths = watchPaths.concat(
+      Array.isArray(directories) ? directories : [directories]
+    );
+  } else if (appConfig.watchPaths) {
+    watchPaths = watchPaths.concat(
+      Array.isArray(appConfig.watchPaths)
+        ? appConfig.watchPaths
+        : [appConfig.watchPaths]
+    );
+  }
+
   let serverBuildTargetEntryModule = `export * from ${JSON.stringify(
     serverBuildVirtualModule.id
   )};`;
@@ -421,6 +448,7 @@ export async function readConfig(
     serverEntryPoint: customServerEntryPoint,
     serverDependenciesToBundle,
     mdx,
+    watchPaths,
   };
 }
 


Test patch:
diff --git a/packages/remix-dev/__tests__/readConfig-test.ts b/packages/remix-dev/__tests__/readConfig-test.ts
index 92af7767d..5164cc960 100644
--- a/packages/remix-dev/__tests__/readConfig-test.ts
+++ b/packages/remix-dev/__tests__/readConfig-test.ts
@@ -48,6 +48,7 @@ describe("readConfig", () => {
         "serverMode": "production",
         "serverModuleFormat": "cjs",
         "serverPlatform": "node",
+        "watchPaths": Array [],
       }
     `
     );