victorgarciaesgi / nuxt-typed-router

🚦Provide autocompletion and typecheck to Nuxt router
https://nuxt-typed-router.vercel.app
MIT License
347 stars 12 forks source link

Unhandled Rejection - Server doesn't start #142

Open SkyLissh opened 3 months ago

SkyLissh commented 3 months ago

Describe the bug Just when I install the package and I added it to the nuxt config and try to start the server, it gives me an error message about an unhandled rejection

Expected behavior That the server start without any errors

Screenshots image

Environnement infos


Your pages folder structure

pages ├── index.vue └── team └── [name].vue

Your nuxt.config.ts nuxt.config.ts

export default defineNuxtConfig({
  devtools: { enabled: true },
  typescript: { strict: true, typeCheck: true },
  components: [{ path: "~/components", pathPrefix: false }],
  css: [
    "primevue/resources/themes/lara-light-pink/theme.css",
    "primevue/resources/themes/lara-dark-pink/theme.css",
  ],
  modules: [
    "@nuxtjs/tailwindcss",
    "@nuxtjs/google-fonts",
    "@nuxtjs/eslint-module",
    "nuxt-primevue",
    "@nuxt/image",
    "@nuxtjs/i18n",
    "nuxt-icon",
    "nuxt-typed-router",
  ],
  i18n: { vueI18n: "./i18n.config.ts", defaultLocale: "es" },
  googleFonts: {
    families: {
      Lato: [400, 500, 700],
    },
  },
  primevue: {
    cssLayerOrder: "tailwind-base, primevue, tailwind-utilities",
  },
});

i18n.config.ts

import es from "./i18n/es.json";

export default defineI18nConfig(() => ({
  legacy: false,
  locale: "es",
  messages: { es },
}));
victorgarciaesgi commented 3 months ago

Hi! I think it's not related to nuxt-typed-router. Have you tried removing some other modules?

mseeley commented 3 months ago

Is this #135?

BlueBazze commented 3 months ago

Had the same error. Only had the index page. Added a test page, and the error were gone. Had to manually yeet .nuxt after adding the new page

victorgarciaesgi commented 3 months ago

Thanks for the report, the error is only when there i a single index.vue then? Will try to reproduce, Nuxt does breaking changes on router sometimes 😅 I'll try when I have time

BlueBazze commented 3 months ago

Thanks for the report, the error is only when there i a single index.vue then? Will try to reproduce, Nuxt does breaking changes on router sometimes 😅 I'll try when I have time

Yes, at least that is what i experienced.

BlueBazze commented 1 month ago

Ran into this issue in another project.

Tried debugging it a bit. Somewhere the prettier formatting is puking while generating the __paths file.

The raw text prettier is trying to format

\n        \n  // @ts-nocheck\n  // eslint-disable\n  // ---------------------------------------------------\n  // 🚗🚦 Generated by nuxt-typed-router. Do not modify !\n  // ---------------------------------------------------\n  \n  \n \n\n\n        \n    \n  export type RoutePathSchema = \n    "/"|"/dashboard"|"/de/dashboard"|"/de"|"/de/test"|"/en/dashboard"|"/en"|"/en/test"|"/test"\n  ;\n\n  export type LocaleRoutePathSchema = \n    any\n  \n\n  type ValidStringPath<T> = T extends ${string} ${string} ? false : T extends \'\' ? false : true;\n\n  type ValidParam<T, R extends boolean = true> = T extends ${infer A}/${infer B}\n  ? A extends ${string} ${string}\n    ? false\n    : A extends ?${string}\n    ? false\n    : A extends ${string} ${string}\n    ? false\n    : A extends \'\'\n    ? B extends \'\'\n      ? true\n  
    : false\n    : B extends ?${string}\n    ? false\n    : B extends #${string}\n    ? true\n    : B extends \'\'\n    ? true\n    : false\n  : R extends true\n  ? T extends \'\'\n    ? false\n    : ValidParam<T, false>\n  : T 
extends ?${string}\n  ? false\n  : T extends ${string} ${string}\n  ? false\n  : true;\n\n  type ValidEndOfPath<T> = T extends /\n    ? true\n    : T extends \'\'\n    ? true\n    : T extends ${string} ${string}\n    ? false \n 
   : T extends ?${string}\n    ? true\n    : T extends #${string}\n    ? true\n    : false;\n\n  \n    type ValidateDashboard<T> = T extends /dashboard${infer TDashboard}\n    ? ValidEndOfPath<TDashboard> extends false ? "End of path \'/dashboard\' is invalid" : true : false ;\n\ntype ValidateDeDashboard<T> = T extends /de/dashboard${infer TDashboard}\n    ? ValidEndOfPath<TDashboard> extends false ? "End of path \'/de/dashboard\' is invalid" : true : 
false ;\n\ntype ValidateDe<T> = T extends /de${infer TDe}\n    ? ValidEndOfPath<TDe> extends false ? "End of path \'/de\' is invalid" : true : false ;\n\ntype ValidateDeTest<T> = T extends /de/test${infer TTest}\n    ? ValidEndOfPath<TTest> extends false ? "End of path \'/de/test\' is invalid" : true : 
false ;\n\ntype ValidateEnDashboard<T> = T extends /en/dashboard${infer TDashboard}\n    ? ValidEndOfPath<TDashboard> extends false ? "End of path \'/en/dashboard\' is invalid" : true : false ;\n\ntype ValidateEn<T> = T extends 
/en${infer TEn}\n    ? ValidEndOfPath<TEn> extends false ? "End of path \'/en\' is invalid" : true : false ;\n\ntype ValidateEnTest<T> = T extends /en/test${infer TTest}\n    ? ValidEndOfPath<TTest> extends false ? "End of path 
\'/en/test\' is invalid" : true : false ;\n\ntype ValidateTest<T> = T extends /test${infer TTest}\n    ? ValidEndOfPath<TTest> extends false ? "End of path \'/test\' is invalid" : true : false ;\n\n    export type ValidatePath<T extends string> = T extends string \n      ? T extends \'/\' \n        ? T 
\n         :ValidateDashboard<T> extends true ? T: ValidateDeDashboard<T> extends true ? T: ValidateDe<T> extends true ? T: ValidateDeTest<T> extends true ? T: ValidateEnDashboard<T> extends true ? T: ValidateEn<T> extends true 
? T: ValidateEnTest<T> extends true ? T: ValidateTest<T> extends true ? T \n      : string extends T\n      ? T\n      : Error: ${ValidateDashboard<T>|ValidateDeDashboard<T>|ValidateDe<T>|ValidateDeTest<T>|ValidateEnDashboard<T>|ValidateEn<T>|ValidateEnTest<T>|ValidateTest<T>}\n      : never;\n  \n    // RouteNameFromPath, RouteNameFromLocalePath\n    export type RouteNameFromPath<T extends string> = T extends string \n      ? T extends \'/\' \n       
 ? "index"\n         : any : never \n       : never; \n  \n        \n  \n   
 \n\n    export type ValidateLocalePath<T extends string> = T extends string \n      ? T extends \'/\' \n        ? T \n          \n      : string extends T\n      ? T\n      : never\n      : never;\n  \n    // RouteNameFromPath, RouteNameFromLocalePath\n    export type RouteNameFromLocalePath<T extends 
string> = T extends string \n      ? T extends \'/\' \n        ? "index"\n  
       : never \n       : never; \n  \n        \n\n\n  export type TypedPathParameter<T extends string> = ValidatePath<T> | RoutePathSchema;\n  export type TypedLocalePathParameter<T extends string> = ValidateLocalePath<T> | LocaleRoutePathSchema;\n\n  \n    

Did wonder if the \ for ${string} ${string} got lost somewhere Tried addingconsole.log(\``) to the module, and it would print just fine.

Tried adding some try catch statements in my node modules.

[05.00.15] ✖ Error while saving file at C:/Users/Bazze/Documents/zome-frontend-v2/packages/syncronet-layer/.playground/.nuxt/typed-router/__paths.d.ts TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be of type string 
or an instance of Buffer, TypedArray, or DataView. Received undefined       

[05.00.15]  ERROR  Cannot start nuxt:  The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined 

Which does make sense, if prettier is failing and returning undefined.

But the error being thrown is referring to RouteNameFromLocalePath.

Found this bit https://github.com/victorgarciaesgi/nuxt-typed-router/commit/34f1442cd97aea17f2a3764e58e74392e17d4d84#diff-8d6881a5d61ba44d753b4583902935a332c085f5b9967aac88ee229853cc67b4L78-R80

It is weird, since i got two projects, one it is working, the other is not.

BlueBazze commented 1 month ago

This comment is just the steps i took to fix this issue - Might be very unreadable.

Tried cloning and replicating the problem in playground. Renaming the .playground/src/pages directory to pages_old. Creating a new pages directory with a single index.vue file. And the problem occurs.

Tried digging into the code. Modified prettierFormat.ts

export async function formatOutputWithPrettier(template: string): Promise<string> {
  let prettierFoundOptions = await prettier.resolveConfig(process.cwd());

  if (!prettierFoundOptions) {
    prettierFoundOptions = defaultPrettierOptions;
  }
  // const formatedTemplate = template;

  let formatedTemplate
  try {
    formatedTemplate = await prettier.format(template, {
      ...prettierFoundOptions,
      parser: 'typescript',

    });
  } catch (e) {
  }
  if (!formatedTemplate) {
    return template;
  }

  return formatedTemplate;
}

So it will return the unformatted code if it cant format. Just to see the full output of paths.d.ts - https://gist.github.com/BlueBazze/61cd0403a8eb3a5d0b6a7269669e999d#file-paths-d-ts Vscode shows an error on line 86 So i was wrong in my earlier message. It seems to be a problem with RouteNameFromPath. It has 3 inline else but only 2 inline if's.

The specific part is generated at routes-paths.block.ts:L73-80 Tried logging the different values used.

${JSON.stringify({ routesList, pathConditions, length: pathConditions.filter((f) => routesList.includes(f.routeName)).length })}

Which resulted in

{
  "routesList": ["index"],
  "pathConditions": [
    {
      "typeName": "ValidateEn",
      "condition": "type ValidateEn<T> = T extends `/en${infer TEn}`\n    ? ValidEndOfPath<TEn> extends false ? \"End of path '/en' is invalid\" : true : false ;",
      "routeName": "index___en",
      "isLocale": true
    },
    {
      "typeName": "ValidateZh",
      "condition": "type ValidateZh<T> = T extends `/zh${infer TZh}`\n    ? ValidEndOfPath<TZh> extends false ? \"End of path '/zh' is invalid\" : true : false ;",
      "routeName": "index___zh",
      "isLocale": true
    }
  ],
  "length": 0
}

The routesList does not contain the i18n route names. Meaning it go to the "any" value. Which causing the entire filter thing to return : any : never combined with the : never; after the filtering.

As i am looking at the code, im questioning if the : never on line 80 is intented to be there instead of added onto .join().

I tried moving it to add onto .join

         ${pathConditions.length
      ? `: ${pathConditions.filter((f) => routesList.includes(f.routeName)).length
        ? pathConditions
          .filter((f) => routesList.includes(f.routeName))
          .map((t) => `${t.typeName}<T> extends true ? "${t.routeName}"`)
          .join(': ') + ": never"
        : 'any'
      }`
      : ': never'
    } 

And it would now generate fine with and without i18n enabled.

Then i tried to go back to the old pages folder i renamed to pages_old which also generated just fine..

So thats working. And should logically be working as intended now. Got a pr up - https://github.com/victorgarciaesgi/nuxt-typed-router/pull/148

BlueBazze commented 1 month ago

.............. Just spent a few hours digging through this.... Tried to use my own clone to see if the project i was working on got fixed... Forgot to set the i18n routing strategy! Thats it..