solidjs-community / mediakit

A set of utilities to use with your Solid apps.
https://mediakit-taupe.vercel.app
144 stars 15 forks source link

`protected$` fails to import `query` from @solidjs/router #144

Open jtmueller opened 23 hours ago

jtmueller commented 23 hours ago

Pages configured with the protected$ function were failing to render, and the following error was showing in the logs:

4:44:56 PM [vite] Error when evaluating SSR module /Users/me/dev/nav-portal/src/routes/tasks.tsx?pick=default&pick=$css:
|- ReferenceError: query is not defined
    at eval (/Users/me/dev/nav-portal/src/routes/tasks.tsx?pick=default&pick=$css:31:20)
    at async instantiateModule (file:///Users/me/dev/nav-portal/node_modules/.pnpm/vite@5.4.11_@types+node@22.10.1_terser@5.36.0/node_modules/vite/dist/node/chunks/dep-CB_7IfJ-.js:52972:5)

Using the log option for authVite shows me this generated code, where, indeed, query is not defined:

/Users/me/dev/nav-portal/src/routes/tasks.tsx?pick=default&pick=$css var _temp;
import { redirect } from "@solidjs/router";
import { authOptions } from "~/lib/server/auth";
import { Show } from "solid-js";
import { getSession } from "@solid-mediakit/auth";
import { getRequestEvent } from "solid-js/web";
import { createAsync } from "@solidjs/router";
import { cache } from "@solidjs/router";
import { protected$ } from '@solid-mediakit/auth';
import { A } from '@solidjs/router';
import Counter from '~/components/Counter';
const _$$getUser = query(async () => {
  'use server';

  const event = getRequestEvent();
  const session = await getSession(event.request, authOptions);
  if (!session) {
    throw redirect("/login");
  }
  return session;
}, "media-user");
export default () => {
  const _$$session = createAsync(() => _$$getUser(), {
    deferStream: true
  });
  const _$$RenderProtected = () => {
    return <main class="mx-auto p-4 text-center text-gray-700">
      <h1 class="max-6-xs my-16 font-thin text-6xl text-sky-700 uppercase">About Page</h1>
      <Counter />
      <p class="mt-8 text-midnight-900 dark:text-white">
        Visit{' '}
        <a href="https://solidjs.com" target="_blank" class="text-sky-600 hover:underline" rel="noreferrer">
          solidjs.com
        </a>{' '}
        to learn how to build Solid apps.
      </p>
      <p class="my-4 text-midnight-900 dark:text-white">
        <A href="/" class="text-sky-600 hover:underline">
          Home
        </A>
        {' - '}
        <span>About Page</span>
      </p>
    </main>;
  };
  return <Show when={_$$session()?.user}><_$$RenderProtected /></Show>;
};

If I add this line to the source file, I get a warning about an unused import, but it fixes the problem:

import { query } from '@solidjs/router';

It looks like the fix is probably to change this already-injected line to also import query:

import { redirect } from "@solidjs/router";

jtmueller commented 21 hours ago

This same error occurs when trying to unit-test pages that use protected$ and in this case the workaround of adding the missing import to the source page does not seem to help. Incidentally, how would you recommend simulating the signed-in state for such a test? Is there a way to provide a user to the SessionProvider?

src/route-tests/tasks.spec.tsx
ReferenceError: query is not defined
 - /src/routes/tasks.tsx:12:20
 - /src/route-tests/tasks.spec.tsx:7:31

Test file:

import { SessionProvider } from '@solid-mediakit/auth/client';
import { MetaProvider } from '@solidjs/meta';
import { Router } from '@solidjs/router';
import { render } from '@solidjs/testing-library';
import { expect, test } from 'vitest';
import Tasks from '~/routes/tasks';

test('renders', () => {
  const { getByText } = render(() => <Tasks />, {
    wrapper: props => (
      <MetaProvider>
        <SessionProvider>
          <Router root={() => props.children} />
        </SessionProvider>
      </MetaProvider>
    ),
  });
  expect(getByText('Tasks for')).toBeInTheDocument();
});

Route file:

import { protected$ } from '@solid-mediakit/auth';
import { Title } from '@solidjs/meta';
// biome-ignore lint/correctness/noUnusedImports: temporary workaround for https://github.com/solidjs-community/mediakit/issues/144
import { query } from '@solidjs/router';

export default protected$(function Tasks(session$) {
  return (
    <>
      <Title>Tasks</Title>
      <main class="mx-auto p-4 text-center text-gray-700">
        <h1 class="max-6-xs my-16 font-thin text-6xl text-sky-700 uppercase">
          <div>Tasks for</div>
          <div>{session$.user?.name}</div>
        </h1>
      </main>
    </>
  );
});
thatgurkangurk commented 1 hour ago

this is fixed in #142, just waiting for @OrJDev to merge the changeset

OrJDev commented 1 hour ago

Oops, forgot to merge it. Merged now, ty for @ me

OrJDev commented 1 hour ago

Released, please use latest version of the auth plugin and lmk if its fixed