Compare commits

...

35 Commits

Author SHA1 Message Date
Guido D'Orsi
d7895504a4 Merge pull request #1896 from garden-co/changeset-release/main
Version Packages
2025-04-11 17:28:50 +02:00
github-actions[bot]
699db46ed6 Version Packages 2025-04-11 15:15:37 +00:00
Guido D'Orsi
d303be6709 Merge pull request #1898 from garden-co/fix/unavailable-messages-error
fix(inbox): gracefully handle unavailable messages error
2025-04-11 17:12:42 +02:00
Guido D'Orsi
fe6f561afd chore: changeset 2025-04-11 17:11:46 +02:00
Guido D'Orsi
93c7f6c253 Merge remote-tracking branch 'origin/main' into fix/unavailable-messages-error 2025-04-11 15:58:14 +02:00
Guido D'Orsi
3b2831f7de Merge pull request #1895 from garden-co/fix/inbox-messages-upload
fix(inbox): ensure that the message is fully uploaded before sharing the id with the worker
2025-04-11 15:57:59 +02:00
Guido D'Orsi
902e539f56 fix(inbox): gracefully handle unavailable messages error 2025-04-11 15:56:23 +02:00
Anselm Eickhoff
9e9946cf48 Merge pull request #1874 from garden-co/create-jazz-app-git-monorepo-init
Initialize git for a scaffolded project only if not inside a monorepo
2025-04-11 14:21:31 +01:00
Trisha Lim
051e6c497e Merge pull request #1897 from garden-co/fix/hide-headings
fix: TOC is showing hidden headings on clerk react native docs
2025-04-11 16:25:48 +07:00
Trisha Lim
9b2a73b900 create separate mdx for react native clerk docs 2025-04-11 16:00:12 +07:00
Guido D'Orsi
dd8ed599f7 Merge pull request #1846 from garden-co/fix/inspector-invalid-html
fix(inspector): invalid html, set z-index to 999
2025-04-11 10:41:10 +02:00
Guido D'Orsi
33e51267e3 Merge pull request #1894 from garden-co/1438-release
Bumps version for release
2025-04-11 10:16:09 +02:00
Guido D'Orsi
59251a58c4 fix(inbox): ensure that the message is fully uploaded before sharing the id with the worker 2025-04-11 10:12:23 +02:00
Benjamin S. Leveritt
e090b3992d Bumps version for release
Closes #1438
2025-04-11 09:08:29 +01:00
Guido D'Orsi
31794684a0 test(music-player): fix loginButton selector 2025-04-11 09:26:30 +02:00
Guido D'Orsi
14fcc8dde5 test: add wait for the visibility checks 2025-04-11 09:16:01 +02:00
Benjamin S. Leveritt
13f1821c04 Merge pull request #1880 from garden-co/remove-catchall-for-docs
Remove catchall-route for docs
2025-04-11 07:09:51 +01:00
Trisha Lim
4c3b85abcd fix logo size on docs intro page 2025-04-11 11:52:48 +07:00
Trisha Lim
4b0544fd0d shorten error message 2025-04-11 11:46:50 +07:00
Trisha Lim
568674a7fa lint fixes 2025-04-11 11:44:51 +07:00
Trisha Lim
ef012f07aa fix coming soon page 2025-04-11 11:41:19 +07:00
Guido D'Orsi
eee2330325 Merge pull request #1891 from garden-co/changeset-release/main
Version Packages
2025-04-10 19:49:47 +02:00
github-actions[bot]
b83ec05ccc Version Packages 2025-04-10 17:36:24 +00:00
Guido D'Orsi
386525db48 Merge pull request #1886 from garden-co/fix/clerk-auth
fix: handle Clerk expiration and fix logout
2025-04-10 19:34:01 +02:00
Guido D'Orsi
a8809d840c test: add logout test on music-player 2025-04-10 19:26:28 +02:00
Guido D'Orsi
005fc1f8c9 fix: restore logOut when logOutReplacement is not passed 2025-04-10 19:07:34 +02:00
Guido D'Orsi
3129982582 fix: handle Clerk expiration and fix logout 2025-04-10 18:22:52 +02:00
Benjamin S. Leveritt
5d7bb70c7d Fix pages with empty TOCs 2025-04-10 16:29:50 +01:00
Anselm
1a7a84f71b Get rid of table-of-contents context workaround 2025-04-10 14:46:19 +01:00
Anselm
1d51bdc016 Establish new content folder, get rid of docs catchall segment 2025-04-10 14:46:19 +01:00
pax-k
94cb615a38 chore: cleanup 2025-04-10 13:22:42 +03:00
pax-k
b130f46b6c chore: changeset 2025-04-10 13:20:39 +03:00
pax-k
989d59f978 fix(create-jazz-app): initialize git only if not inside a monorepo 2025-04-10 13:19:23 +03:00
Trisha Lim
785fc893ee set z-index of embedded inspector to 999 2025-04-09 16:51:18 +07:00
Trisha Lim
08ae9b295f fix: invalid html 2025-04-09 15:15:50 +07:00
220 changed files with 1874 additions and 578 deletions

View File

@@ -13,7 +13,7 @@ jobs:
continue-on-error: true
strategy:
matrix:
project: ["tests/e2e", "examples/chat", "examples/file-share-svelte", "examples/form", "examples/music-player", "examples/pets", "starters/react-passkey-auth"]
project: ["tests/e2e", "examples/chat", "examples/clerk", "examples/file-share-svelte", "examples/form", "examples/music-player", "examples/pets", "starters/react-passkey-auth"]
steps:
- uses: actions/checkout@v4

View File

@@ -1,5 +1,24 @@
# chat-rn-expo-clerk
## 1.0.98
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-expo@0.13.5
- jazz-react-native-media-images@0.13.5
## 1.0.97
### Patch Changes
- Updated dependencies [3129982]
- Updated dependencies [3129982]
- jazz-expo@0.13.4
- jazz-tools@0.13.4
- jazz-react-native-media-images@0.13.4
## 1.0.96
### Patch Changes

View File

@@ -2,28 +2,39 @@ import "../global.css";
import { ClerkLoaded, ClerkProvider } from "@clerk/clerk-expo";
import { secureStore } from "@clerk/clerk-expo/secure-store";
import { useFonts } from "expo-font";
import { Slot } from "expo-router";
import { Slot, useRouter, useSegments } from "expo-router";
import * as SplashScreen from "expo-splash-screen";
import { useIsAuthenticated, useJazzContext } from "jazz-expo";
import React, { useEffect } from "react";
import { tokenCache } from "../cache";
import { JazzAndAuth } from "../src/auth-context";
SplashScreen.preventAutoHideAsync();
export default function RootLayout() {
const [loaded] = useFonts({
SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
});
function InitialLayout() {
const isAuthenticated = useIsAuthenticated();
const segments = useSegments();
const router = useRouter();
useEffect(() => {
if (loaded) {
SplashScreen.hideAsync();
}
}, [loaded]);
const inAuthGroup = segments[0] === "(auth)";
if (!loaded) {
return null;
}
if (isAuthenticated && inAuthGroup) {
router.replace("/chat");
} else if (!isAuthenticated && !inAuthGroup) {
router.replace("/");
}
SplashScreen.hideAsync();
}, [isAuthenticated, segments, router]);
return <Slot />;
}
export default function RootLayout() {
const [fontsLoaded] = useFonts({
SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
});
const publishableKey = process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY;
@@ -33,6 +44,17 @@ export default function RootLayout() {
);
}
useEffect(() => {
if (fontsLoaded) {
} else {
SplashScreen.preventAutoHideAsync();
}
}, [fontsLoaded]);
if (!fontsLoaded) {
return null;
}
return (
<ClerkProvider
tokenCache={tokenCache}
@@ -41,7 +63,7 @@ export default function RootLayout() {
>
<ClerkLoaded>
<JazzAndAuth>
<Slot />
<InitialLayout />
</JazzAndAuth>
</ClerkLoaded>
</ClerkProvider>

View File

@@ -1,7 +1,7 @@
{
"name": "chat-rn-expo-clerk",
"main": "index.js",
"version": "1.0.96",
"version": "1.0.98",
"scripts": {
"build": "expo export -p ios",
"start": "expo start",

View File

@@ -1,5 +1,22 @@
# chat-rn-expo
## 1.0.85
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-expo@0.13.5
## 1.0.84
### Patch Changes
- Updated dependencies [3129982]
- Updated dependencies [3129982]
- jazz-expo@0.13.4
- jazz-tools@0.13.4
## 1.0.83
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "chat-rn-expo",
"version": "1.0.83",
"version": "1.0.85",
"main": "index.js",
"scripts": {
"build": "expo export -p ios",

View File

@@ -1,5 +1,24 @@
# chat-rn
## 1.0.94
### Patch Changes
- Updated dependencies [e090b39]
- Updated dependencies [fe6f561]
- cojson@0.13.5
- jazz-tools@0.13.5
- cojson-transport-ws@0.13.5
- jazz-react-native@0.13.5
## 1.0.93
### Patch Changes
- Updated dependencies [3129982]
- jazz-tools@0.13.4
- jazz-react-native@0.13.4
## 1.0.92
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "chat-rn",
"version": "1.0.92",
"version": "1.0.94",
"main": "index.js",
"scripts": {
"android": "react-native run-android",

View File

@@ -1,5 +1,23 @@
# chat-vue
## 0.0.78
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-browser@0.13.5
- jazz-vue@0.13.5
## 0.0.77
### Patch Changes
- Updated dependencies [3129982]
- jazz-browser@0.13.4
- jazz-tools@0.13.4
- jazz-vue@0.13.4
## 0.0.76
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "chat-vue",
"version": "0.0.76",
"version": "0.0.78",
"private": true,
"type": "module",
"scripts": {

View File

@@ -1,5 +1,24 @@
# jazz-example-chat
## 0.0.175
### Patch Changes
- Updated dependencies [08ae9b2]
- Updated dependencies [fe6f561]
- jazz-inspector@0.13.5
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.0.174
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
- jazz-inspector@0.13.4
## 0.0.173
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-chat",
"private": true,
"version": "0.0.173",
"version": "0.0.175",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -22,3 +22,5 @@ dist-ssr
*.njsproj
*.sln
*.sw?
playwright-report

View File

@@ -1,5 +1,24 @@
# minimal-auth-clerk
## 0.0.74
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-react@0.13.5
- jazz-react-auth-clerk@0.13.5
## 0.0.73
### Patch Changes
- Updated dependencies [3129982]
- Updated dependencies [3129982]
- jazz-react-auth-clerk@0.13.4
- jazz-react@0.13.4
- jazz-tools@0.13.4
## 0.0.72
### Patch Changes

View File

@@ -1,14 +1,16 @@
{
"name": "clerk",
"private": true,
"version": "0.0.72",
"version": "0.0.74",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview",
"format-and-lint": "biome check .",
"format-and-lint:fix": "biome check . --write"
"format-and-lint:fix": "biome check . --write",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui"
},
"dependencies": {
"@clerk/clerk-react": "^5.4.1",
@@ -19,6 +21,7 @@
"react-dom": "^18.3.1"
},
"devDependencies": {
"@playwright/test": "^1.50.1",
"@biomejs/biome": "1.9.4",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",

View File

@@ -0,0 +1,53 @@
import { defineConfig, devices } from "@playwright/test";
import isCI from "is-ci";
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// import dotenv from 'dotenv';
// dotenv.config({ path: path.resolve(__dirname, '.env') });
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: "./tests",
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: isCI,
/* Retry on CI only */
retries: isCI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: isCI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: "http://localhost:5173/",
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry",
permissions: ["clipboard-read", "clipboard-write"],
},
/* Configure projects for major browsers */
projects: [
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},
],
/* Run your local dev server before starting the tests */
webServer: [
{
command: "pnpm preview --port 5173",
url: "http://localhost:5173/",
reuseExistingServer: !isCI,
},
],
});

View File

@@ -1,8 +1,8 @@
import { SignInButton } from "@clerk/clerk-react";
import { SignInButton, SignOutButton } from "@clerk/clerk-react";
import { useAccount, useIsAuthenticated } from "jazz-react";
function App() {
const { me, logOut } = useAccount();
const { me } = useAccount();
const isAuthenticated = useIsAuthenticated();
@@ -11,7 +11,7 @@ function App() {
<div className="container">
<h1>You're logged in</h1>
<p>Welcome back, {me?.profile?.name}</p>
<button onClick={() => logOut()}>Logout</button>
<SignOutButton>Logout</SignOutButton>
</div>
);
}

View File

@@ -1,4 +1,4 @@
import { ClerkProvider, useClerk } from "@clerk/clerk-react";
import { ClerkProvider, SignOutButton, useClerk } from "@clerk/clerk-react";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
@@ -28,12 +28,23 @@ function JazzProvider({ children }: { children: React.ReactNode }) {
);
}
createRoot(document.getElementById("root")!).render(
<StrictMode>
<ClerkProvider publishableKey={PUBLISHABLE_KEY} afterSignOutUrl="/">
<JazzProvider>
<App />
</JazzProvider>
</ClerkProvider>
</StrictMode>,
);
// Route to test that when the Clerk user expires, the app is logged out
if (location.search.includes("expirationTest")) {
createRoot(document.getElementById("root")!).render(
<StrictMode>
<ClerkProvider publishableKey={PUBLISHABLE_KEY} afterSignOutUrl="/">
<SignOutButton>Simulate expiration</SignOutButton>
</ClerkProvider>
</StrictMode>,
);
} else {
createRoot(document.getElementById("root")!).render(
<StrictMode>
<ClerkProvider publishableKey={PUBLISHABLE_KEY} afterSignOutUrl="/">
<JazzProvider>
<App />
</JazzProvider>
</ClerkProvider>
</StrictMode>,
);
}

View File

@@ -0,0 +1,36 @@
import { expect, test } from "@playwright/test";
test("login & expiration", async ({ page }) => {
await page.goto("/");
expect(page.getByText("You're not logged in")).toBeVisible();
await page.getByRole("button", { name: "Sign in" }).click();
await page
.getByRole("textbox", { name: "Email address" })
.fill("guido+clerk-test@garden.co");
await page.keyboard.press("Enter");
await page
.getByRole("textbox", { name: "Password" })
.fill("guido+clerk-test@garden.co");
await page.keyboard.press("Enter");
await page.waitForURL("/");
await page.getByText("You're logged in").waitFor({ state: "visible" });
expect(page.getByText("You're logged in")).toBeVisible();
await page.goto("/?expirationTest");
// Simulate expiration by logging out outside of Jazz
await page.getByRole("button", { name: "Simulate expiration" }).click();
await page.goto("/");
await page.getByText("You're not logged in").waitFor({ state: "visible" });
});

View File

@@ -0,0 +1,33 @@
import { expect, test } from "@playwright/test";
test("login & logout", async ({ page }) => {
await page.goto("/");
expect(page.getByText("You're not logged in")).toBeVisible();
await page.getByRole("button", { name: "Sign in" }).click();
await page
.getByRole("textbox", { name: "Email address" })
.fill("guido+clerk-test@garden.co");
await page.keyboard.press("Enter");
await page
.getByRole("textbox", { name: "Password" })
.fill("guido+clerk-test@garden.co");
await page.keyboard.press("Enter");
await page.waitForURL("/");
await page.getByText("You're logged in").waitFor({ state: "visible" });
expect(page.getByText("You're logged in")).toBeVisible();
await page.getByRole("button", { name: "Logout" }).click();
await page.getByText("You're not logged in").waitFor({ state: "visible" });
expect(page.getByText("You're not logged in")).toBeVisible();
});

View File

@@ -0,0 +1,33 @@
import { expect, test } from "@playwright/test";
test("login & reload", async ({ page }) => {
await page.goto("/");
expect(page.getByText("You're not logged in")).toBeVisible();
await page.getByRole("button", { name: "Sign in" }).click();
await page
.getByRole("textbox", { name: "Email address" })
.fill("guido+clerk-test@garden.co");
await page.keyboard.press("Enter");
await page
.getByRole("textbox", { name: "Password" })
.fill("guido+clerk-test@garden.co");
await page.keyboard.press("Enter");
await page.waitForURL("/");
await page.getByText("You're logged in").waitFor({ state: "visible" });
expect(page.getByText("You're logged in")).toBeVisible();
await page.reload();
await page.getByText("You're logged in").waitFor({ state: "visible" });
expect(page.getByText("You're logged in")).toBeVisible();
});

View File

@@ -1,5 +1,21 @@
# file-share-svelte
## 0.0.58
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-svelte@0.13.5
## 0.0.57
### Patch Changes
- Updated dependencies [3129982]
- jazz-tools@0.13.4
- jazz-svelte@0.13.4
## 0.0.56
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "file-share-svelte",
"version": "0.0.56",
"version": "0.0.58",
"private": true,
"type": "module",
"scripts": {

View File

@@ -1,5 +1,24 @@
# jazz-tailwind-demo-auth-starter
## 0.0.14
### Patch Changes
- Updated dependencies [08ae9b2]
- Updated dependencies [fe6f561]
- jazz-inspector@0.13.5
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.0.13
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
- jazz-inspector@0.13.4
## 0.0.12
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "filestream",
"private": true,
"version": "0.0.12",
"version": "0.0.14",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,21 @@
# form
## 0.1.16
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.1.15
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
## 0.1.14
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "form",
"private": true,
"version": "0.1.14",
"version": "0.1.16",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,21 @@
# image-upload
## 0.0.72
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.0.71
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
## 0.0.70
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "image-upload",
"private": true,
"version": "0.0.70",
"version": "0.0.72",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,21 @@
# jazz-example-inspector
## 0.0.125
### Patch Changes
- Updated dependencies [08ae9b2]
- Updated dependencies [e090b39]
- jazz-inspector@0.13.5
- cojson@0.13.5
- cojson-transport-ws@0.13.5
## 0.0.124
### Patch Changes
- jazz-inspector@0.13.4
## 0.0.123
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-inspector-app",
"private": true,
"version": "0.0.123",
"version": "0.0.125",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,21 @@
# multi-cursors
## 0.0.68
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.0.67
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
## 0.0.66
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "multi-cursors",
"private": true,
"version": "0.0.66",
"version": "0.0.68",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,24 @@
# multiauth
## 0.0.15
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-react@0.13.5
- jazz-react-auth-clerk@0.13.5
## 0.0.14
### Patch Changes
- Updated dependencies [3129982]
- Updated dependencies [3129982]
- jazz-react-auth-clerk@0.13.4
- jazz-react@0.13.4
- jazz-tools@0.13.4
## 0.0.13
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "multiauth",
"private": true,
"version": "0.0.13",
"version": "0.0.15",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,24 @@
# jazz-example-musicplayer
## 0.0.96
### Patch Changes
- Updated dependencies [08ae9b2]
- Updated dependencies [fe6f561]
- jazz-inspector@0.13.5
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.0.95
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
- jazz-inspector@0.13.4
## 0.0.94
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-music-player",
"private": true,
"version": "0.0.94",
"version": "0.0.96",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -0,0 +1,54 @@
import { BrowserContext, test } from "@playwright/test";
import { HomePage } from "./pages/HomePage";
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
async function mockAuthenticator(context: BrowserContext) {
await context.addInitScript(() => {
Object.defineProperty(window.navigator, "credentials", {
value: {
...window.navigator.credentials,
create: async () => ({
type: "public-key",
id: new Uint8Array([1, 2, 3, 4]),
rawId: new Uint8Array([1, 2, 3, 4]),
response: {
clientDataJSON: new Uint8Array([1]),
attestationObject: new Uint8Array([2]),
},
}),
get: async () => ({
type: "public-key",
id: new Uint8Array([1, 2, 3, 4]),
rawId: new Uint8Array([1, 2, 3, 4]),
response: {
authenticatorData: new Uint8Array([1]),
clientDataJSON: new Uint8Array([2]),
signature: new Uint8Array([3]),
},
}),
},
configurable: true,
});
});
}
// Configure the authenticator
test.beforeEach(async ({ context }) => {
// Enable virtual authenticator environment
await mockAuthenticator(context);
});
test("sign up and log out", async ({ page: marioPage }) => {
await marioPage.goto("/");
const marioHome = new HomePage(marioPage);
await marioHome.signUp("Mario");
await marioHome.logoutButton.waitFor({
state: "visible",
});
await marioHome.logOut();
});

View File

@@ -11,8 +11,12 @@ export class HomePage {
name: "Playlist title",
});
loginButton = this.page.getByRole("button", {
name: "Sign up",
});
logoutButton = this.page.getByRole("button", {
name: "Logout",
name: "Sign out",
});
async expectActiveTrackPlaying() {
@@ -131,12 +135,21 @@ export class HomePage {
await this.page
.getByRole("button", { name: "Sign up with passkey" })
.click();
await expect(
this.page.getByRole("button", { name: "Sign out" }),
).toBeVisible();
await this.logoutButton.waitFor({
state: "visible",
});
await expect(this.logoutButton).toBeVisible();
}
async logout() {
async logOut() {
await this.logoutButton.click();
await this.loginButton.waitFor({
state: "visible",
});
await expect(this.loginButton).toBeVisible();
}
}

View File

@@ -1,5 +1,21 @@
# organization
## 0.0.68
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.0.67
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
## 0.0.66
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "organization",
"private": true,
"version": "0.0.66",
"version": "0.0.68",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,17 @@
# passkey-svelte
## 0.0.62
### Patch Changes
- jazz-svelte@0.13.5
## 0.0.61
### Patch Changes
- jazz-svelte@0.13.4
## 0.0.60
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "passkey-svelte",
"version": "0.0.60",
"version": "0.0.62",
"type": "module",
"private": true,
"scripts": {

View File

@@ -1,5 +1,21 @@
# minimal-auth-passkey
## 0.0.73
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.0.72
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
## 0.0.71
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "passkey",
"private": true,
"version": "0.0.71",
"version": "0.0.73",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,21 @@
# passphrase
## 0.0.70
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.0.69
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
## 0.0.68
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "passphrase",
"private": true,
"version": "0.0.68",
"version": "0.0.70",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,21 @@
# jazz-password-manager
## 0.0.94
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.0.93
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
## 0.0.92
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-password-manager",
"private": true,
"version": "0.0.92",
"version": "0.0.94",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,21 @@
# jazz-example-pets
## 0.0.192
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.0.191
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
## 0.0.190
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-pets",
"private": true,
"version": "0.0.190",
"version": "0.0.192",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,21 @@
# reactions
## 0.0.72
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.0.71
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
## 0.0.70
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "reactions",
"private": true,
"version": "0.0.70",
"version": "0.0.72",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,23 @@
# todo-vue
## 0.0.76
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-browser@0.13.5
- jazz-vue@0.13.5
## 0.0.75
### Patch Changes
- Updated dependencies [3129982]
- jazz-browser@0.13.4
- jazz-tools@0.13.4
- jazz-vue@0.13.4
## 0.0.74
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "todo-vue",
"version": "0.0.74",
"version": "0.0.76",
"private": true,
"type": "module",
"scripts": {

View File

@@ -1,5 +1,21 @@
# jazz-example-todo
## 0.0.191
### Patch Changes
- Updated dependencies [fe6f561]
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.0.190
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
## 0.0.189
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "jazz-example-todo",
"private": true,
"version": "0.0.189",
"version": "0.0.191",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,24 @@
# version-history
## 0.0.69
### Patch Changes
- Updated dependencies [08ae9b2]
- Updated dependencies [fe6f561]
- jazz-inspector@0.13.5
- jazz-tools@0.13.5
- jazz-react@0.13.5
## 0.0.68
### Patch Changes
- Updated dependencies [3129982]
- jazz-react@0.13.4
- jazz-tools@0.13.4
- jazz-inspector@0.13.4
## 0.0.67
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "version-history",
"private": true,
"version": "0.0.67",
"version": "0.0.69",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,5 +1,5 @@
import { PackageDocs } from "@/components/docs/packageDocs";
import { packages } from "@/lib/packages";
import { packages } from "@/content/packages";
import { notFound } from "next/navigation";
interface Props {

View File

@@ -1,4 +1,3 @@
import { TocProvider } from "@/components/TocProvider";
import { ApiNav } from "@/components/docs/ApiNav";
import DocsLayout from "@/components/docs/DocsLayout";
import { Prose } from "gcmp-design-system/src/app/components/molecules/Prose";
@@ -9,10 +8,8 @@ export default function RootLayout({
children: React.ReactNode;
}) {
return (
<TocProvider>
<DocsLayout nav={<ApiNav />} navIcon="package" navName="API Ref">
<Prose className="overflow-x-hidden lg:flex-1 py-10">{children}</Prose>
</DocsLayout>
</TocProvider>
<DocsLayout nav={<ApiNav />} navIcon="package" navName="API Ref">
<Prose className="overflow-x-hidden lg:flex-1 py-10">{children}</Prose>
</DocsLayout>
);
}

View File

@@ -1,4 +1,4 @@
import { packages } from "@/lib/packages";
import { packages } from "@/content/packages";
import { clsx } from "clsx";
import { Icon } from "gcmp-design-system/src/app/components/atoms/Icon";
import type { Metadata } from "next";

View File

@@ -1,117 +0,0 @@
import { TocItemsSetter } from "@/components/docs/TocItemsSetter";
import ComingSoonPage from "@/components/docs/coming-soon.mdx";
import { docNavigationItems } from "@/lib/docNavigationItems.js";
import { Framework, frameworks } from "@/lib/framework";
import type { Toc } from "@stefanprobst/rehype-extract-toc";
async function getMdxSource(framework: string, slugPath?: string) {
// Try to import the framework-specific file first
try {
if (!slugPath) {
return await import("./index.mdx");
}
return await import(`./${slugPath}/${framework}.mdx`);
} catch (error) {
// Fallback to vanilla
return await import(`./${slugPath}.mdx`);
}
}
export async function generateMetadata({
params,
}: { params: Promise<{ slug: string[]; framework: string }> }) {
const { slug, framework } = await params;
const slugPath = slug?.join("/");
try {
const mdxSource = await getMdxSource(framework, slugPath);
const title = mdxSource.tableOfContents?.[0].value || "Documentation";
return {
title,
openGraph: {
title,
},
};
} catch (error) {
return {
title: "Documentation",
openGraph: {
title: "Documentation",
},
};
}
}
export default async function Page({
params,
}: { params: Promise<{ slug: string[]; framework: string }> }) {
const { slug, framework } = await params;
const slugPath = slug?.join("/");
try {
const mdxSource = await getMdxSource(framework, slugPath);
const {
default: Content,
tableOfContents,
headingsFrameworkVisibility,
test,
} = mdxSource;
// Remove items that should not be shown for the current framework
const tocItems = (tableOfContents as Toc).filter(({ id }) =>
id && id in headingsFrameworkVisibility
? headingsFrameworkVisibility[id]?.includes(framework)
: true,
);
return (
<>
<TocItemsSetter items={tocItems} />
<Content />
</>
);
} catch (error) {
return (
<>
<TocItemsSetter items={[]} />
<ComingSoonPage />
</>
);
}
}
// https://nextjs.org/docs/app/api-reference/functions/generate-static-params
export const dynamicParams = false;
export const dynamic = "force-static";
export async function generateStaticParams() {
const paths: Array<{ slug?: string[]; framework: Framework }> = [];
for (const framework of frameworks) {
paths.push({
framework,
slug: [],
});
for (const heading of docNavigationItems) {
for (const item of heading?.items) {
if (item.href && item.href.startsWith("/docs")) {
const slug = item.href
.replace("/docs", "")
.split("/")
.filter(Boolean);
if (slug.length) {
paths.push({
slug,
framework,
});
}
}
}
}
}
return paths;
}

View File

@@ -0,0 +1,57 @@
import { docNavigationItems } from "@/content/docs/docNavigationItems.js";
import { Framework, frameworks } from "@/content/framework";
import { DocPage, getDocMetadata } from "@/lib/docMdxContent";
export async function generateMetadata({
params,
}: {
params: Promise<{ topic: string; subtopic: string; framework: string }>;
}) {
const { topic, subtopic, framework } = await params;
return getDocMetadata(framework, [topic, subtopic]);
}
export default async function Page({
params,
}: {
params: Promise<{ topic: string; subtopic: string; framework: string }>;
}) {
const { topic, subtopic, framework } = await params;
return <DocPage framework={framework} slug={[topic, subtopic]} />;
}
// https://nextjs.org/docs/app/api-reference/functions/generate-static-params
export const dynamicParams = false;
export const dynamic = "force-static";
export async function generateStaticParams() {
const paths: Array<{
topic?: string;
subtopic?: string;
framework: Framework;
}> = [];
for (const framework of frameworks) {
for (const heading of docNavigationItems) {
for (const item of heading?.items) {
if (item.href && item.href.startsWith("/docs")) {
const [topic, subtopic] = item.href
.replace("/docs", "")
.split("/")
.filter(Boolean);
if (topic && subtopic) {
paths.push({
topic,
subtopic,
framework,
});
}
}
}
}
}
return paths;
}

View File

@@ -0,0 +1,52 @@
import { docNavigationItems } from "@/content/docs/docNavigationItems.js";
import { Framework, frameworks } from "@/content/framework";
import { DocPage, getDocMetadata } from "@/lib/docMdxContent";
export async function generateMetadata({
params,
}: {
params: Promise<{ topic: string; framework: string }>;
}) {
const { topic, framework } = await params;
return getDocMetadata(framework, [topic]);
}
export default async function Page({
params,
}: {
params: Promise<{ topic: string; framework: string }>;
}) {
const { topic, framework } = await params;
return <DocPage framework={framework} slug={[topic]} />;
}
// https://nextjs.org/docs/app/api-reference/functions/generate-static-params
export const dynamicParams = false;
export const dynamic = "force-static";
export async function generateStaticParams() {
const paths: Array<{ topic?: string; framework: Framework }> = [];
for (const framework of frameworks) {
for (const heading of docNavigationItems) {
for (const item of heading?.items) {
if (item.href && item.href.startsWith("/docs")) {
const [topic] = item.href
.replace("/docs", "")
.split("/")
.filter(Boolean);
if (topic) {
paths.push({
topic,
framework,
});
}
}
}
}
}
return paths;
}

View File

@@ -0,0 +1,38 @@
import { Framework, frameworks } from "@/content/framework";
import { DocPage, getDocMetadata } from "@/lib/docMdxContent";
export async function generateMetadata({
params,
}: {
params: Promise<{ framework: string }>;
}) {
const { framework } = await params;
return getDocMetadata(framework, []);
}
export default async function Page({
params,
}: {
params: Promise<{ framework: string }>;
}) {
const { framework } = await params;
return <DocPage framework={framework} slug={[]} />;
}
// https://nextjs.org/docs/app/api-reference/functions/generate-static-params
export const dynamicParams = false;
export const dynamic = "force-static";
export async function generateStaticParams() {
const paths: Array<{ framework: Framework }> = [];
for (const framework of frameworks) {
paths.push({
framework,
});
}
return paths;
}

View File

@@ -1,16 +0,0 @@
import { TocProvider } from "@/components/TocProvider";
import DocsLayout from "@/components/docs/DocsLayout";
import { DocNav } from "@/components/docs/nav";
import { Prose } from "gcmp-design-system/src/app/components/molecules/Prose";
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<TocProvider>
<DocsLayout nav={<DocNav />}>
<Prose className="overflow-x-hidden lg:flex-1 py-10 max-w-3xl mx-auto">
{children}
</Prose>
</DocsLayout>
</TocProvider>
);
}

View File

@@ -5,7 +5,7 @@ import { ReactLogo } from "@/components/icons/ReactLogo";
import { ReactNativeLogo } from "@/components/icons/ReactNativeLogo";
import { SvelteLogo } from "@/components/icons/SvelteLogo";
import { VueLogo } from "@/components/icons/VueLogo";
import { Example, features, tech } from "@/lib/example";
import { Example, features, tech } from "@/content/example";
import { clsx } from "clsx";
import { H2 } from "gcmp-design-system/src/app/components/atoms/Headings";
import { Icon } from "gcmp-design-system/src/app/components/atoms/Icon";

View File

@@ -1,4 +1,4 @@
import { products } from "@/lib/showcase";
import { products } from "@/content/showcase";
import { HeroHeader } from "gcmp-design-system/src/app/components/molecules/HeroHeader";
import type { Metadata } from "next";
import Image from "next/image";

View File

@@ -6,9 +6,9 @@ import localFont from "next/font/local";
import { ThemeProvider } from "@/components/ThemeProvider";
import { JazzFooter } from "@/components/footer";
import { marketingCopy } from "@/content/marketingCopy";
import { Analytics } from "@vercel/analytics/react";
import { SpeedInsights } from "@vercel/speed-insights/next";
import { marketingCopy } from "@/lib/marketingCopy";
// If loading a variable font, you don't need to specify the font weight
const manrope = Manrope({

View File

@@ -1,5 +1,5 @@
import { Icon404 } from 'gcmp-design-system/src/app/components/atoms/icons/404'
import { Icon404 } from "gcmp-design-system/src/app/components/atoms/icons/404";
export default function NotFound() {
const text = "Don't Worry 'Bout Me";
@@ -9,5 +9,5 @@ export default function NotFound() {
<h1 className="text-3xl font-semibold my-7">{text}</h1>
<p>Page not found.</p>
</div>
)
}
);
}

View File

@@ -1,5 +1,8 @@
import { marketingCopy } from '@/lib/marketingCopy';
import OpenGraphImage, { imageSize, imageContentType } from 'gcmp-design-system/src/app/components/organisms/OpenGraphImage';
import { marketingCopy } from "@/content/marketingCopy";
import OpenGraphImage, {
imageSize,
imageContentType,
} from "gcmp-design-system/src/app/components/organisms/OpenGraphImage";
export const title = marketingCopy.headline;
export const size = imageSize;
@@ -7,5 +10,5 @@ export const contentType = imageContentType;
export const alt = marketingCopy.headline;
export default async function Image() {
return OpenGraphImage({ title })
return OpenGraphImage({ title });
}

View File

@@ -1,6 +1,6 @@
import { SideNavHeader } from "@/components/SideNavHeader";
import { SideNavItem } from "@/components/SideNavItem";
import { Framework } from "@/lib/framework";
import { Framework } from "@/content/framework";
import { useFramework } from "@/lib/use-framework";
import { clsx } from "clsx";
import { Icon } from "gcmp-design-system/src/app/components/atoms/Icon";

View File

@@ -1,15 +0,0 @@
"use client";
import { TocContext } from "@/lib/TocContext";
import type { Toc, TocEntry } from "@stefanprobst/rehype-extract-toc";
import { useState } from "react";
export function TocProvider({ children }: { children: React.ReactNode }) {
const [tocItems, setTocItems] = useState<Toc>();
return (
<TocContext.Provider value={{ tocItems, setTocItems }}>
{children}
</TocContext.Provider>
);
}

View File

@@ -1,6 +1,6 @@
import { SideNavHeader } from "@/components/SideNavHeader";
import { SideNavItem } from "@/components/SideNavItem";
import { packages } from "@/lib/packages";
import { packages } from "@/content/packages";
import { clsx } from "clsx";
import { Icon } from "gcmp-design-system/src/app/components/atoms/Icon";
import Link from "next/link";

View File

@@ -2,7 +2,7 @@
import { TableOfContents } from "@/components/docs/TableOfContents";
import { JazzNav } from "@/components/nav";
import { useTocItems } from "@/lib/TocContext";
import { TocEntry } from "@stefanprobst/rehype-extract-toc";
import { clsx } from "clsx";
import type { IconName } from "gcmp-design-system/src/app/components/atoms/Icon";
import type { NavSection } from "gcmp-design-system/src/app/components/organisms/Nav";
@@ -12,14 +12,14 @@ export default function DocsLayout({
nav,
navName,
navIcon,
tocItems,
}: {
children: React.ReactNode;
nav?: React.ReactNode;
navName?: string;
navIcon?: IconName;
tocItems?: TocEntry[];
}) {
const { tocItems } = useTocItems();
const navSections: NavSection[] = [
{
name: navName || "Docs",

View File

@@ -1,6 +1,6 @@
"use client";
import { isValidFramework } from "@/lib/framework";
import { isValidFramework } from "@/content/framework";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { AnchorHTMLAttributes, DetailedHTMLProps } from "react";

View File

@@ -1,6 +1,6 @@
"use client";
import { Framework } from "@/lib/framework";
import { Framework } from "@/content/framework";
import { useFramework } from "@/lib/use-framework";
import { Button } from "gcmp-design-system/src/app/components/atoms/Button";
import { Icon } from "gcmp-design-system/src/app/components/atoms/Icon";

View File

@@ -1,15 +0,0 @@
"use client";
import { useTocItems } from "@/lib/TocContext";
import type { TocEntry } from "@stefanprobst/rehype-extract-toc";
import { useEffect } from "react";
export function TocItemsSetter({ items }: { items: TocEntry[] | undefined }) {
const { setTocItems } = useTocItems();
useEffect(() => {
setTocItems(items);
}, [items, setTocItems]);
return null;
}

View File

@@ -3,7 +3,7 @@
import { SideNav } from "@/components/SideNav";
import { SideNavHeader } from "@/components/SideNavHeader";
import { FrameworkSelect } from "@/components/docs/FrameworkSelect";
import { docNavigationItems } from "@/lib/docNavigationItems.js";
import { docNavigationItems } from "@/content/docs/docNavigationItems.js";
import { useFramework } from "@/lib/use-framework";
import { clsx } from "clsx";

View File

@@ -1,6 +1,6 @@
import { ExampleLinks } from "@/components/examples/ExampleLinks";
import { ExampleTags } from "@/components/examples/ExampleTags";
import { Example } from "@/lib/example";
import { Example } from "@/content/example";
import { clsx } from "clsx";
export function ExampleCard({

View File

@@ -1,7 +1,7 @@
import { CodeExampleTabs } from "@/components/examples/CodeExampleTabs";
import { ExampleLinks } from "@/components/examples/ExampleLinks";
import { ExampleTags } from "@/components/examples/ExampleTags";
import { Example } from "@/lib/example";
import { Example } from "@/content/example";
import { GappedGrid } from "gcmp-design-system/src/app/components/molecules/GappedGrid";
export function ExampleDemo({ example }: { example: Example }) {

View File

@@ -1,6 +1,6 @@
"use client";
import { Example } from "@/lib/example";
import { Example } from "@/content/example";
import { InterpolateInCode } from "@/mdx-components";
import { DialogDescription } from "@headlessui/react";
import { Button } from "gcmp-design-system/src/app/components/atoms/Button";

View File

@@ -1,4 +1,4 @@
import { Example } from "@/lib/example";
import { Example } from "@/content/example";
export function ExampleTags({ example }: { example: Example }) {
const { tech, features } = example;

View File

@@ -1,5 +1,5 @@
import { ThemeToggle } from "@/components/ThemeToggle";
import { socials } from "@/lib/socials";
import { socials } from "@/content/socials";
import { GcmpLogo } from "gcmp-design-system/src/app/components/atoms/logos/GcmpLogo";
import { Footer } from "gcmp-design-system/src/app/components/organisms/Footer";

View File

@@ -1,5 +1,5 @@
import CreateJazzApp from "@/components/home/CreateJazzApp.mdx";
import { marketingCopy } from "@/lib/marketingCopy";
import { marketingCopy } from "@/content/marketingCopy";
import { H1 } from "gcmp-design-system/src/app/components/atoms/Headings";
import {
Icon,

View File

@@ -1,5 +1,5 @@
import { ThemeToggle } from "@/components/ThemeToggle";
import { socials } from "@/lib/socials";
import { socials } from "@/content/socials";
import { JazzLogo } from "gcmp-design-system/src/app/components/atoms/logos/JazzLogo";
import {
Nav,

View File

@@ -6,11 +6,6 @@ import { CodeGroup, ContentByFramework } from "@/components/forMdx";
Jazz can be integrated with [Clerk](https://clerk.com/) to authenticate users. This method combines Clerk's comprehensive authentication services with Jazz's local-first capabilities.
<ContentByFramework framework="react-native">
We do not currently support Clerk in React Native, but we do have support for [React Native Expo](/docs/react-native-expo/authentication/clerk).
</ContentByFramework>
<ContentByFramework framework={["react", "react-native-expo", "svelte", "vue", "vanilla"]}>
## How it works
When using Clerk authentication:
@@ -224,4 +219,3 @@ Clerk authentication is ideal when:
- [Clerk Documentation](https://clerk.com/docs)
- [Jazz React Auth Clerk Package](https://npmjs.com/package/jazz-react-auth-clerk)
</ContentByFramework>

View File

@@ -0,0 +1,3 @@
# Clerk Authentication
We do not currently support Clerk in React Native, but we do have support for [React Native Expo](/docs/react-native-expo/authentication/clerk).

View File

@@ -0,0 +1,7 @@
# Documentation coming soon
Grayed out pages on our sidebar indicate that documentation for this feature is still in progress. We're excited to bring you comprehensive guides and tutorials as soon as possible.
This feature has already been released, and we're working hard to provide top-notch support. In the meantime, if you have any questions or need assistance, please don't hesitate to reach out to us on [Discord](https://discord.gg/utDMjHYg42).
We would love to help you get started.

Some files were not shown because too many files have changed in this diff Show More