Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(astro): Add CSR support #3911

Merged
Merged
Show file tree
Hide file tree
Changes from 93 commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
68d1181
chore(astro): Use shared data attribute builder for hotloading
wobsoriano Jul 10, 2024
832d2dd
chore(astro): Use shared clerk-js hotload script
wobsoriano Jul 10, 2024
982d455
chore(astro): Clean up type ignores
wobsoriano Jul 10, 2024
22e7ceb
chore(astro): Fix merge conflicts
wobsoriano Jul 30, 2024
98456b9
chore(astro): Fix incorrect file name
wobsoriano Jul 30, 2024
062cb9b
chore(shared): Allow custom package version
wobsoriano Jul 30, 2024
ddbd13a
test(shared): Handle custom package versions for versionSelector
wobsoriano Jul 31, 2024
470e945
chore(astro): Use shared clerk-js hotload script
wobsoriano Jul 31, 2024
dd0c8f4
chore(shared): Update internal package version property name
wobsoriano Jul 31, 2024
af076d3
chore(astro): Remove unused file
wobsoriano Aug 1, 2024
c78912f
chore(shared): Make options optional in loadClerkJsScript and throw i…
wobsoriano Aug 5, 2024
e0d683b
chore(shared,astro,react,nextjs): Use built-in error thrower when Cle…
wobsoriano Aug 7, 2024
7a4911b
test(shared): Use clerk-js major version from package.json when testi…
wobsoriano Aug 7, 2024
d8b1ac6
chore(shared): Add nonce prop to to load script
wobsoriano Aug 8, 2024
097035c
chore(shared): Remove extra folder
wobsoriano Aug 8, 2024
a3a29d9
feat(astro): Add CSR support to control components
wobsoriano Aug 5, 2024
b489b41
chore(astro): Use dynamic components
wobsoriano Aug 5, 2024
5cdebf7
chore(astro): Type fix
wobsoriano Aug 5, 2024
bc64acd
chore(astro): formatting update
wobsoriano Aug 5, 2024
6890da2
chore(astro): Simplify Protect slots
wobsoriano Aug 5, 2024
ad714b7
chore(astro): Add initial changeset
wobsoriano Aug 6, 2024
19af4a7
test(astro): Add initial CSR e2e test
wobsoriano Aug 6, 2024
604bec8
test(astro): Add astro-static to template map
wobsoriano Aug 6, 2024
e82f4a7
chore(astrp): Use hidden attribute for CSR component toggling
wobsoriano Aug 6, 2024
63e2b24
test(astro): Clean up
wobsoriano Aug 6, 2024
6f71f03
test(astro): More clean ups
wobsoriano Aug 7, 2024
03a1e73
chore(astro): Add vite plugin for dynamic control components
wobsoriano Aug 8, 2024
8be568b
chore(astro): Use hidden attribute for toggling visibility in Protect…
wobsoriano Aug 8, 2024
ce1b5fb
test(astro): Remove client props
wobsoriano Aug 8, 2024
982d0d1
chore(astro): Add type for virtual module
wobsoriano Aug 8, 2024
f97124b
test(astro): Add SignedIn, SignedOut and Protect e2e tests
wobsoriano Aug 8, 2024
ae02d48
test(astro): Clean up static config
wobsoriano Aug 8, 2024
7887e26
chore(astro): File location clean up
wobsoriano Aug 8, 2024
095c199
chore(astro): Remove unused bundled folder
wobsoriano Aug 8, 2024
5a41ab1
chore(astro): Update virtual module to include hybrid mode
wobsoriano Aug 8, 2024
783f4db
chore(astro): Run formatter
wobsoriano Aug 8, 2024
3d5943f
test(astro): Improve visibility tests
wobsoriano Aug 8, 2024
5d91dd0
chore(astro): Add back adapter missing error message
wobsoriano Aug 8, 2024
5e363d2
chore(astro): Run prettier format
wobsoriano Aug 9, 2024
2928bf6
chore(astro): Revert hotload script build logic
wobsoriano Aug 9, 2024
05f848f
chore(astro): Remove duplicate import
wobsoriano Aug 9, 2024
026b7e4
chore(astro): Reuse ProtectProps and publish types file
wobsoriano Aug 9, 2024
ce97965
chore(astro): Fix incorrect variable name
wobsoriano Aug 12, 2024
ac7d460
chore(astro): pre-bundle client stores export
wobsoriano Aug 13, 2024
c99bc75
chore(astro): Update vite plugin to set hybrid component initial to s…
wobsoriano Aug 13, 2024
466ba97
chore(astro): Update vite plugin to set hybrid component initial to s…
wobsoriano Aug 13, 2024
29957bb
chore(astro): Remove duplicate env vars in vite
wobsoriano Aug 13, 2024
d4b02ff
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano Aug 13, 2024
3dae9b2
chore(astro): Update changeset
wobsoriano Aug 13, 2024
c895c7b
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano Aug 13, 2024
5624586
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano Aug 14, 2024
0c8d0f3
chore(astro): Dynamically export control components
wobsoriano Aug 14, 2024
dd30100
chore(astro): Prettier formatting
wobsoriano Aug 14, 2024
656272e
chore(astro): Fix protect csr fallback slot
wobsoriano Aug 14, 2024
2f67e98
chore(astro): Working tests and separate custom element declarations
wobsoriano Aug 15, 2024
db2dfe6
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano Aug 15, 2024
edbe5ad
chore(astro): Add base element for CSR web components
wobsoriano Aug 15, 2024
aa3112c
chore(astro): Remove unnecessary optimized dep
wobsoriano Aug 15, 2024
dfb9826
chore(astro): Perform clean ups
wobsoriano Aug 15, 2024
4b2e495
chore(astro): Slot clean up
wobsoriano Aug 15, 2024
b4ce8ff
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano Aug 15, 2024
ed6f7f1
chore(astro): Update changeset
wobsoriano Aug 16, 2024
f3f36fc
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano Aug 16, 2024
ccecf05
chore(astro): Fix incorrect output
wobsoriano Aug 16, 2024
6582e64
chore(astro): Use authorization checker function from session object
wobsoriano Aug 16, 2024
2dca843
fix(astro): Do not ignore astro files in tsconfig
wobsoriano Aug 16, 2024
29e1190
chore(astro): Run prettier format
wobsoriano Aug 16, 2024
f182753
chore(astro): Add isStatic prop definition
wobsoriano Aug 16, 2024
85e257a
chore(astro): Revert previous commit
wobsoriano Aug 16, 2024
42a830b
chore(astro): type fixes
wobsoriano Aug 16, 2024
0ee00ff
chore(astro): Put web component declarations inside CSR components
wobsoriano Aug 17, 2024
edad853
chore(astro): Fix flickering when rendering signed in and signed out …
wobsoriano Aug 18, 2024
46a3426
chore(astro): Test type fix
wobsoriano Aug 18, 2024
7985b29
chore(astro): Format tsconfig
wobsoriano Aug 18, 2024
a87bc9c
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano Aug 18, 2024
93be93d
chore(astro): Remove unnecessary ts config
wobsoriano Aug 18, 2024
009bfa3
chore(astro): Update test preset comment
wobsoriano Aug 18, 2024
76aae65
test(astro): Use react component in static test
wobsoriano Aug 18, 2024
e57b449
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano Aug 19, 2024
71c3070
chore(astro): Make sure hidden attributes are not overridable
wobsoriano Aug 19, 2024
e2f8279
chore(astro): Make sure hidden attributes are not overridable in prot…
wobsoriano Aug 19, 2024
ef87390
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano Aug 19, 2024
24df6df
test(astro): Fix protect CSR tests
wobsoriano Aug 19, 2024
0ae1248
chore(astro): Formatting fix
wobsoriano Aug 19, 2024
506bce7
chore(astro): Remove unused util file
wobsoriano Aug 20, 2024
17a4abb
chore(astro): Set initial resource values to undefined
wobsoriano Aug 20, 2024
a188cc8
chore(astro): Ignore ts files in components folder
wobsoriano Aug 21, 2024
db66adc
chore(astro): TS errors clean up
wobsoriano Aug 21, 2024
0b65ac6
test(astro): Update static test to hybrid
wobsoriano Aug 21, 2024
6e1beeb
chore(astro): Update eslint ignores
wobsoriano Aug 21, 2024
eb0647c
chore(astro): Simplify ignored files in tsconfig
wobsoriano Aug 21, 2024
fa723e4
chore(astro): Add JSDoc to vite plugin
wobsoriano Aug 21, 2024
7f20b12
chore(astro): Add classes to control components wrappers
wobsoriano Aug 21, 2024
d21a98a
Merge branch 'main' into rob/eco-17-explore-our-options-for-csr-only-…
wobsoriano Aug 22, 2024
aadf639
test(astro): Rename hybrid test description
wobsoriano Aug 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/proud-horses-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clerk/astro": minor
---

Add support for Astro `static` and `hybrid` outputs.
5 changes: 4 additions & 1 deletion integration/presets/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ const astroNode = applicationConfig()
.addDependency('@clerk/types', clerkTypesLocal)
.addDependency('@clerk/localizations', clerkLocalizationLocal);

const astroStatic = astroNode.clone().setName('astro-hybrid').useTemplate(templates['astro-hybrid']);

export const astro = {
node: astroNode,
};
static: astroStatic,
} as const;
1 change: 1 addition & 0 deletions integration/presets/longRunningApps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const createLongRunningApps = () => {
{ id: 'quickstart.next.appRouter', config: next.appRouterQuickstart, env: envs.withEmailCodesQuickstart },
{ id: 'elements.next.appRouter', config: elements.nextAppRouter, env: envs.withEmailCodes },
{ id: 'astro.node.withCustomRoles', config: astro.node, env: envs.withCustomRoles },
{ id: 'astro.static.withCustomRoles', config: astro.static, env: envs.withCustomRoles },
{ id: 'expo.expo-web', config: expo.expoWeb, env: envs.withEmailCodes },
] as const;

Expand Down
24 changes: 24 additions & 0 deletions integration/templates/astro-hybrid/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# build output
dist/

# generated types
.astro/

# dependencies
node_modules/

# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# environment variables
.env
.env.production

# macOS-specific files
.DS_Store

# jetbrains setting folder
.idea/
11 changes: 11 additions & 0 deletions integration/templates/astro-hybrid/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineConfig } from 'astro/config';
import clerk from '@clerk/astro';
import react from '@astrojs/react';

export default defineConfig({
output: 'hybrid',
integrations: [clerk(), react()],
server: {
port: Number(process.env.PORT),
},
});
23 changes: 23 additions & 0 deletions integration/templates/astro-hybrid/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "astro-clerk-hybrid-playground",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev --port $PORT",
"build": "astro check && astro build",
"preview": "astro preview --port $PORT",
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "^0.7.0",
"@astrojs/react": "^3.6.0",
"@astrojs/node": "^8.3.2",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"astro": "^4.11.5",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"typescript": "^5.5.3"
}
}
9 changes: 9 additions & 0 deletions integration/templates/astro-hybrid/public/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions integration/templates/astro-hybrid/src/layouts/Layout.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
interface Props {
title: string;
}

const { title } = Astro.props;
---

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="description" content="Astro description" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
</head>
<body>
<main>
<slot />
</main>
</body>
</html>
3 changes: 3 additions & 0 deletions integration/templates/astro-hybrid/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { clerkMiddleware } from '@clerk/astro/server';

export const onRequest = clerkMiddleware();
19 changes: 19 additions & 0 deletions integration/templates/astro-hybrid/src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
import { UserButton, SignInButton, SignedIn, SignedOut } from "@clerk/astro/components";
import { OrganizationSwitcher } from "@clerk/astro/react";
import Layout from "../layouts/Layout.astro";

export const prerender = true;
---

<Layout title="Home">
<SignedOut>
<h1>Signed out</h1>
<SignInButton mode="modal" fallbackRedirectUrl="/" />
</SignedOut>
<SignedIn>
<h1>Signed in</h1>
<UserButton />
<OrganizationSwitcher client:only="react" />
</SignedIn>
</Layout>
13 changes: 13 additions & 0 deletions integration/templates/astro-hybrid/src/pages/only-admins.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
import { Protect } from "@clerk/astro/components";
import Layout from "../layouts/Layout.astro";

export const prerender = true;
---

<Layout title="Protected">
<Protect role="admin">
<h1>I'm an admin</h1>
<h1 slot="fallback">Not an admin</h1>
</Protect>
</Layout>
13 changes: 13 additions & 0 deletions integration/templates/astro-hybrid/src/pages/only-members.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
import { Protect } from "@clerk/astro/components";
import Layout from "../layouts/Layout.astro";

export const prerender = false;
---

<Layout title="Protected">
<Protect role="basic_member" isStatic={false}>
<h1>I'm a member</h1>
<h1 slot="fallback">Not a member</h1>
</Protect>
</Layout>
19 changes: 19 additions & 0 deletions integration/templates/astro-hybrid/src/pages/ssr.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
import { UserButton, SignInButton, SignedIn, SignedOut } from "@clerk/astro/components";
import { OrganizationSwitcher } from "@clerk/astro/react";
import Layout from "../layouts/Layout.astro";

export const prerender = false;
---

<Layout title="Home">
<SignedOut isStatic={false}>
<h1>Signed out</h1>
<SignInButton mode="modal" fallbackRedirectUrl="/" />
</SignedOut>
<SignedIn isStatic={false}>
<h1>Signed in</h1>
<UserButton />
<OrganizationSwitcher client:load />
</SignedIn>
</Layout>
7 changes: 7 additions & 0 deletions integration/templates/astro-hybrid/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "astro/tsconfigs/strict",
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "react"
}
}
1 change: 1 addition & 0 deletions integration/templates/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const templates = {
'remix-node': resolve(__dirname, './remix-node'),
'elements-next': resolve(__dirname, './elements-next'),
'astro-node': resolve(__dirname, './astro-node'),
'astro-hybrid': resolve(__dirname, './astro-hybrid'),
'expo-web': resolve(__dirname, './expo-web'),
} as const;

Expand Down
114 changes: 114 additions & 0 deletions integration/tests/astro/hybrid.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { expect, test } from '@playwright/test';

import type { FakeOrganization, FakeUser } from '../../testUtils';
import { createTestUtils, testAgainstRunningApps } from '../../testUtils';

testAgainstRunningApps({ withPattern: ['astro.static.withCustomRoles'] })(
'basic flows for @astro static output',
({ app }) => {
test.describe.configure({ mode: 'serial' });

let fakeAdmin: FakeUser;
let fakeOrganization: FakeOrganization;
let fakeAdmin2: FakeUser;
let fakeOrganization2: FakeOrganization;

test.beforeAll(async () => {
const m = createTestUtils({ app });
fakeAdmin = m.services.users.createFakeUser();
const admin = await m.services.users.createBapiUser(fakeAdmin);
fakeOrganization = await m.services.users.createFakeOrganization(admin.id);

fakeAdmin2 = m.services.users.createFakeUser();
const admin2 = await m.services.users.createBapiUser(fakeAdmin2);
fakeOrganization2 = await m.services.users.createFakeOrganization(admin2.id);
});

test.afterAll(async () => {
await fakeOrganization.delete();
await fakeAdmin.deleteIfExists();

await fakeOrganization2.delete();
await fakeAdmin2.deleteIfExists();
await app.teardown();
});

test('render SignedIn and SignedOut contents (prerendered)', async ({ page, context }) => {
const u = createTestUtils({ app, page, context });
await u.page.goToAppHome();

await u.page.waitForClerkJsLoaded();

await u.po.expect.toBeSignedOut();
await expect(u.page.getByText('Signed out')).toBeVisible();
await expect(u.page.getByText('Signed in')).toBeHidden();

await u.page.getByRole('button', { name: /Sign in/i }).click();

await u.po.signIn.waitForMounted();
await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeAdmin.email, password: fakeAdmin.password });
await u.po.expect.toBeSignedIn();

await expect(u.page.getByText('Signed out')).toBeHidden();
await expect(u.page.getByText('Signed in')).toBeVisible();
});

test('render SignedIn and SignedOut contents (SSR)', async ({ page, context }) => {
const u = createTestUtils({ app, page, context });
await u.page.goToRelative('/ssr');

await u.page.waitForClerkJsLoaded();

await u.po.expect.toBeSignedOut();
await expect(u.page.getByText('Signed out')).toBeVisible();
await expect(u.page.getByText('Signed in')).toBeHidden();

await u.page.getByRole('button', { name: /Sign in/i }).click();

await u.po.signIn.waitForMounted();
await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeAdmin.email, password: fakeAdmin.password });
await u.po.expect.toBeSignedIn();

await expect(u.page.getByText('Signed out')).toBeHidden();
await expect(u.page.getByText('Signed in')).toBeVisible();
});

test('render Protect contents for admin', async ({ page, context }) => {
const u = createTestUtils({ app, page, context });
await u.page.goToAppHome();

await u.page.waitForClerkJsLoaded();

// Sign in
await u.page.getByRole('button', { name: /Sign in/i }).click();
await u.po.signIn.waitForMounted();
await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeAdmin.email, password: fakeAdmin.password });
await u.po.expect.toBeSignedIn();

// Select an organization
await u.po.organizationSwitcher.waitForMounted();
await u.po.organizationSwitcher.waitForAnOrganizationToSelected();

await u.page.goToRelative('/only-admins');

await expect(u.page.getByText("I'm an admin")).toBeVisible();
});

test('render Protect fallback', async ({ page, context }) => {
const u = createTestUtils({ app, page, context });
await u.page.goToAppHome();

await u.page.waitForClerkJsLoaded();

// Sign in
await u.page.getByRole('button', { name: /Sign in/i }).click();
await u.po.signIn.waitForMounted();
await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeAdmin.email, password: fakeAdmin.password });
await u.po.expect.toBeSignedIn();

await u.page.goToRelative('/only-members');

await expect(u.page.getByText('Not a member')).toBeVisible();
});
},
);
2 changes: 1 addition & 1 deletion packages/astro/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module.exports = {
rules: {
'import/no-unresolved': ['error', { ignore: ['^#'] }],
},
ignorePatterns: ['src/astro-components/index.ts', 'src/astro-components/interactive/UserButton/index.ts'],
ignorePatterns: ['src/astro-components/**/*.ts'],
overrides: [
{
files: ['./env.d.ts'],
Expand Down
1 change: 1 addition & 0 deletions packages/astro/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ astro-components/
components/
!src/components/
.output/
/types.ts

.vscode/
.idea/
Expand Down
3 changes: 0 additions & 3 deletions packages/astro/bundled/package.json

This file was deleted.

6 changes: 3 additions & 3 deletions packages/astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@
"dev": "tsup --watch --onSuccess \"npm run build:dts\"",
"build": "tsup --onSuccess \"npm run build:dts\" && npm run copy:components",
"build:dts": "tsc --emitDeclarationOnly --declaration",
"copy:components": "rm -rf ./components && mkdir -p ./components/ && cp -r ./src/astro-components/* ./components/",
"copy:components": "rm -rf ./components && mkdir -p ./components/ && cp -r ./src/astro-components/* ./components/ && cp ./src/types.ts ./",
wobsoriano marked this conversation as resolved.
Show resolved Hide resolved
"lint": "eslint src/",
"lint:attw": "attw --pack .",
"lint:publint": "publint",
"publish:local": "npx yalc push --replace --sig"
},
"files": [
"dist",
"bundled",
"client",
"server",
"internal",
"components",
"env.d.ts"
"env.d.ts",
"types.ts"
],
"exports": {
".": {
Expand Down
Loading
Loading