Compare commits
91 Commits
jazz-react
...
repro/prog
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a4c78f21f | ||
|
|
201e2fd015 | ||
|
|
56974412df | ||
|
|
adaedd2da2 | ||
|
|
2939790335 | ||
|
|
48c29435bc | ||
|
|
8668906376 | ||
|
|
6d84e9e83f | ||
|
|
1fea0ef69c | ||
|
|
e4314accb6 | ||
|
|
ee3a4048ef | ||
|
|
9ee1edef3b | ||
|
|
8ab5a09a86 | ||
|
|
2624442903 | ||
|
|
2d199089d5 | ||
|
|
683c170b9d | ||
|
|
ce0e9f0102 | ||
|
|
518406e23d | ||
|
|
4dcbafa058 | ||
|
|
7ae9e01848 | ||
|
|
dd9ecf660d | ||
|
|
4f849050dc | ||
|
|
681600220f | ||
|
|
384e239ad5 | ||
|
|
54e1a09a46 | ||
|
|
392a9c5aac | ||
|
|
478334eabf | ||
|
|
479f9b0113 | ||
|
|
812622b161 | ||
|
|
8b35fae4b6 | ||
|
|
9e2ecb0378 | ||
|
|
fe908b5300 | ||
|
|
1f99807971 | ||
|
|
47f54c4d81 | ||
|
|
814f65acaf | ||
|
|
78fd4c86a1 | ||
|
|
678f326bc1 | ||
|
|
ea33ad4864 | ||
|
|
57b6d5efb4 | ||
|
|
15929b121d | ||
|
|
6edd061202 | ||
|
|
eb4cef196c | ||
|
|
85703f9241 | ||
|
|
865d5385e9 | ||
|
|
5bb12523ee | ||
|
|
190cb1efb2 | ||
|
|
46ab1f6db2 | ||
|
|
a44fc6fc6d | ||
|
|
2376a8d3b2 | ||
|
|
2c3ec2fea6 | ||
|
|
da6f6ec4d5 | ||
|
|
8c78b37bfb | ||
|
|
5f382309de | ||
|
|
aa7eb3cf2c | ||
|
|
9b41762e96 | ||
|
|
28be460286 | ||
|
|
df8af06814 | ||
|
|
2ef460fccf | ||
|
|
9660e2c03c | ||
|
|
908645e4b7 | ||
|
|
f3ca37ed5e | ||
|
|
a9d0fd14c4 | ||
|
|
c496f49bb0 | ||
|
|
b26666ab4c | ||
|
|
9088a349a0 | ||
|
|
54b12dcb7a | ||
|
|
a998f94789 | ||
|
|
d17eecfe16 | ||
|
|
71b9a5ce25 | ||
|
|
8ebfbc86db | ||
|
|
abad8e762f | ||
|
|
037e16392e | ||
|
|
49ac65c123 | ||
|
|
3510fb1273 | ||
|
|
bc3efe7ca0 | ||
|
|
3b06a7809e | ||
|
|
58aa04bb10 | ||
|
|
afb94ef043 | ||
|
|
7554dd9f88 | ||
|
|
4f0fb6c27f | ||
|
|
034bd20b39 | ||
|
|
87f82ac7cd | ||
|
|
e8c1a3535a | ||
|
|
b05878962b | ||
|
|
54b4595f23 | ||
|
|
99a2d9be00 | ||
|
|
bf1fbdc8c4 | ||
|
|
14b3aa29c7 | ||
|
|
bfaadb9d67 | ||
|
|
cb770e565d | ||
|
|
a50a9e6c9b |
6
.changeset/empty-pears-carry.md
Normal file
6
.changeset/empty-pears-carry.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"jazz-example-music-player": patch
|
||||
"jazz-tools": patch
|
||||
---
|
||||
|
||||
Deprecated `Group.extend` and `Group.revokeExtend` (use `Group.addMember` and `Group.removeMember` respectively)
|
||||
5
.changeset/shaggy-cycles-carry.md
Normal file
5
.changeset/shaggy-cycles-carry.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"create-jazz-app": patch
|
||||
---
|
||||
|
||||
use new svelte starter
|
||||
2
.github/workflows/build-starters.yaml
vendored
2
.github/workflows/build-starters.yaml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2204
|
||||
strategy:
|
||||
matrix:
|
||||
starter: ["react-passkey-auth"]
|
||||
starter: ["react-passkey-auth", "svelte-passkey-auth"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
3
.github/workflows/playwright-homepage.yml
vendored
3
.github/workflows/playwright-homepage.yml
vendored
@@ -22,6 +22,9 @@ jobs:
|
||||
- name: Setup Source Code
|
||||
uses: ./.github/actions/source-code/
|
||||
|
||||
- name: Install root dependencies
|
||||
run: pnpm install && pnpm turbo build
|
||||
|
||||
- name: Install project dependencies
|
||||
run: pnpm install
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
22
.github/workflows/playwright.yml
vendored
22
.github/workflows/playwright.yml
vendored
@@ -13,7 +13,21 @@ jobs:
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
project: ["tests/e2e", "examples/chat", "examples/clerk", "examples/betterauth", "examples/file-share-svelte", "examples/form", "examples/music-player", "examples/organization", "examples/pets", "starters/react-passkey-auth"]
|
||||
project: [
|
||||
"tests/e2e",
|
||||
"examples/chat",
|
||||
"examples/clerk",
|
||||
"examples/betterauth",
|
||||
"examples/file-share-svelte",
|
||||
"examples/form",
|
||||
"examples/inspector",
|
||||
"examples/music-player",
|
||||
"examples/organization",
|
||||
"examples/pets",
|
||||
"starters/react-passkey-auth",
|
||||
"starters/svelte-passkey-auth",
|
||||
"packages/jazz-svelte"
|
||||
]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -24,7 +38,11 @@ jobs:
|
||||
uses: ./.github/actions/source-code/
|
||||
|
||||
- name: Pnpm Build
|
||||
run: pnpm turbo build
|
||||
run: |
|
||||
if [ -f .env.test ]; then
|
||||
cp .env.test .env
|
||||
fi
|
||||
pnpm turbo build
|
||||
working-directory: ./${{ matrix.project }}
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"**/android/**",
|
||||
"packages/jazz-svelte/**",
|
||||
"examples/*svelte*/**",
|
||||
"starters/*svelte*/**",
|
||||
"examples/jazz-paper-scissors/src/routeTree.gen.ts",
|
||||
"homepage/homepage/**",
|
||||
"**/package.json"
|
||||
|
||||
6
examples/betterauth/.gitignore
vendored
6
examples/betterauth/.gitignore
vendored
@@ -36,8 +36,10 @@ yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# env files (can opt-in for committing if needed)
|
||||
.env*
|
||||
!.env
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
@@ -5,10 +5,12 @@ This example demonstrates how to integrate [Better Auth](https://www.better-auth
|
||||
## Getting started
|
||||
|
||||
To run this example, you may either:
|
||||
* Clone the Jazz monorepo and run this example from within.
|
||||
* Create a new Jazz project using this example as a template, and run that new project.
|
||||
|
||||
- Clone the Jazz monorepo and run this example from within.
|
||||
- Create a new Jazz project using this example as a template, and run that new project.
|
||||
|
||||
### Setting environment variables
|
||||
|
||||
- `NEXT_PUBLIC_AUTH_BASE_URL`: A URL to a Better Auth server. If undefined, the example will self-host a Better Auth server.
|
||||
- `BETTER_AUTH_SECRET`: The encryption secret used by the self-hosted Better Auth server (required only if `NEXT_PUBLIC_AUTH_BASE_URL` is undefined)
|
||||
- `GITHUB_CLIENT_ID`: The client ID for the GitHub OAuth provider used by the self-hosted Better Auth server (required only if `NEXT_PUBLIC_AUTH_BASE_URL` is undefined)
|
||||
@@ -17,38 +19,64 @@ To run this example, you may either:
|
||||
### Using this example as a template
|
||||
|
||||
1. Create a new Jazz project, and use this example as a template.
|
||||
|
||||
```sh
|
||||
npx create-jazz-app@latest betterauth-app --example betterauth
|
||||
```
|
||||
2. Navigate to the new project and start the development server.
|
||||
|
||||
2. Navigate to the new project and install dependencies.
|
||||
|
||||
```sh
|
||||
cd betterauth-app
|
||||
pnpm install
|
||||
```
|
||||
|
||||
3. Create a .env file (don't forget to set your [BETTER_AUTH_SECRET](https://www.better-auth.com/docs/installation#set-environment-variables)!)
|
||||
|
||||
```sh
|
||||
mv .env.example .env
|
||||
```
|
||||
|
||||
4. Start the development server
|
||||
|
||||
```sh
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
https://www.better-auth.com/docs/installation#set-environment-variables
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Go to the example directory.
|
||||
|
||||
```bash
|
||||
cd jazz/examples/betterauth/
|
||||
```
|
||||
|
||||
Create a .env file (don't forget to set your [BETTER_AUTH_SECRET](https://www.better-auth.com/docs/installation#set-environment-variables)!)
|
||||
|
||||
```sh
|
||||
mv .env.example .env
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_ZXZpZGVudC1kYW5lLTg5LmNsZXJrLmFjY291bnRzLmRldiQ
|
||||
1
examples/chat-rn-expo-clerk/.env.example
Normal file
1
examples/chat-rn-expo-clerk/.env.example
Normal file
@@ -0,0 +1 @@
|
||||
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=
|
||||
6
examples/chat-rn-expo-clerk/.gitignore
vendored
6
examples/chat-rn-expo-clerk/.gitignore
vendored
@@ -15,3 +15,9 @@ web-build/
|
||||
|
||||
ios
|
||||
android
|
||||
|
||||
# Env
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -8,9 +8,12 @@ First, install dependencies and build the project:
|
||||
|
||||
```bash
|
||||
pnpm i
|
||||
mv .env.example .env
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
Don't forget to update `VITE_CLERK_PUBLISHABLE_KEY` in `.env` with your [Publishable Key](https://clerk.com/docs/deployments/clerk-environment-variables#clerk-publishable-and-secret-keys) from Clerk.
|
||||
|
||||
### 2. Inside the `examples/chat-rn-expo-clerk` Directory
|
||||
|
||||
Next, navigate to the specific example project and run the following commands:
|
||||
|
||||
7
examples/chat-rn-expo/.gitignore
vendored
7
examples/chat-rn-expo/.gitignore
vendored
@@ -36,4 +36,9 @@ yarn-error.*
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
android/
|
||||
ios/
|
||||
ios/
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -11,18 +11,22 @@
|
||||
"dependencies": {
|
||||
"@azure/core-asynciterator-polyfill": "^1.0.2",
|
||||
"@bacons/text-decoder": "^0.0.0",
|
||||
"@bam.tech/react-native-image-resizer": "^3.0.11",
|
||||
"@craftzdog/react-native-buffer": "^6.0.5",
|
||||
"@react-native-community/netinfo": "11.4.1",
|
||||
"expo": "~53.0.9",
|
||||
"expo-clipboard": "^7.1.4",
|
||||
"expo-image-picker": "~16.1.4",
|
||||
"expo-secure-store": "~14.2.3",
|
||||
"expo-sqlite": "~15.2.10",
|
||||
"expo-status-bar": "~2.2.3",
|
||||
"jazz-expo": "workspace:*",
|
||||
"jazz-react-native-media-images": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
"react-native": "0.79.2",
|
||||
"react-native-get-random-values": "^1.11.0",
|
||||
"react-native-svg": "^15.12.0",
|
||||
"readable-stream": "^4.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { JazzProvider } from "jazz-expo";
|
||||
import React, { StrictMode } from "react";
|
||||
import { apiKey } from "./apiKey";
|
||||
import ChatScreen from "./chat";
|
||||
import { ChatAccount } from "./schema";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
@@ -10,6 +11,7 @@ export default function App() {
|
||||
sync={{
|
||||
peer: `wss://cloud.jazz.tools/?key=${apiKey}`,
|
||||
}}
|
||||
AccountSchema={ChatAccount}
|
||||
>
|
||||
<ChatScreen />
|
||||
</JazzProvider>
|
||||
|
||||
97
examples/chat-rn-expo/src/background.tsx
Normal file
97
examples/chat-rn-expo/src/background.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
import * as ImagePicker from "expo-image-picker";
|
||||
import { ProgressiveImg } from "jazz-expo";
|
||||
import { createImage } from "jazz-react-native-media-images";
|
||||
import { Group, ImageDefinition } from "jazz-tools";
|
||||
import React, { useState } from "react";
|
||||
import { Dimensions, Pressable, StyleSheet, Text, View } from "react-native";
|
||||
import Svg, { Defs, Mask, Path, Image as SvgImage } from "react-native-svg";
|
||||
import { ChatAccount } from "./schema";
|
||||
|
||||
function MaskedBackgroundPhoto({ imageUri }: { imageUri: string }) {
|
||||
const windowWidth = Dimensions.get("window").width;
|
||||
const height = Dimensions.get("window").height * 0.4;
|
||||
|
||||
return (
|
||||
<View style={[styles.backgroundContainer, { width: windowWidth, height }]}>
|
||||
<Svg height={height} width={windowWidth}>
|
||||
<Defs>
|
||||
<Mask id="mask" x="0" y="0" height="100%" width="100%">
|
||||
<Path
|
||||
d={`M0 0 L${windowWidth} 0 L${windowWidth} ${height - 40} Q${windowWidth / 2} ${height + 50} 0 ${height - 40} Z`}
|
||||
fill="white"
|
||||
/>
|
||||
</Mask>
|
||||
</Defs>
|
||||
<SvgImage
|
||||
width="100%"
|
||||
height="100%"
|
||||
href={{ uri: imageUri }}
|
||||
preserveAspectRatio="xMidYMid slice"
|
||||
mask="url(#mask)"
|
||||
/>
|
||||
</Svg>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export function BackgroundPhoto({
|
||||
image,
|
||||
owner,
|
||||
}: {
|
||||
image: ImageDefinition | null;
|
||||
owner: ChatAccount | Group | undefined | null;
|
||||
}) {
|
||||
const [img, setImg] = useState<ImageDefinition | null>(image);
|
||||
|
||||
const handleImageUpload = async () => {
|
||||
try {
|
||||
const result = await ImagePicker.launchImageLibraryAsync({
|
||||
mediaTypes: ["images"],
|
||||
base64: true,
|
||||
quality: 0.8,
|
||||
});
|
||||
if (!result.canceled && owner && result.assets[0].base64) {
|
||||
const base64Uri = `data:image/jpeg;base64,${result.assets[0].base64}`;
|
||||
const img = await createImage(base64Uri, {
|
||||
owner,
|
||||
maxSize: 2048,
|
||||
});
|
||||
setImg(img);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to upload image:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Pressable onPress={handleImageUpload}>
|
||||
{img ? (
|
||||
<ProgressiveImg
|
||||
image={img}
|
||||
targetWidth={Dimensions.get("window").width}
|
||||
>
|
||||
{({ src }) => (src ? <MaskedBackgroundPhoto imageUri={src} /> : null)}
|
||||
</ProgressiveImg>
|
||||
) : (
|
||||
<View style={styles.noPhotoContainer}>
|
||||
<Text style={styles.noPhotoText}>No background photo</Text>
|
||||
</View>
|
||||
)}
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
backgroundContainer: {
|
||||
position: "relative",
|
||||
},
|
||||
noPhotoContainer: {
|
||||
width: "100%",
|
||||
height: Dimensions.get("window").height * 0.2,
|
||||
backgroundColor: "lightgray",
|
||||
justifyContent: "center",
|
||||
},
|
||||
noPhotoText: {
|
||||
textAlign: "center",
|
||||
},
|
||||
});
|
||||
@@ -1,24 +1,26 @@
|
||||
import * as Clipboard from "expo-clipboard";
|
||||
import { Account, Group } from "jazz-tools";
|
||||
import { useAccount, useCoState } from "jazz-expo";
|
||||
import { Group } from "jazz-tools";
|
||||
import { useState } from "react";
|
||||
import React, {
|
||||
Alert,
|
||||
Button,
|
||||
FlatList,
|
||||
KeyboardAvoidingView,
|
||||
SafeAreaView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
Alert,
|
||||
StyleSheet,
|
||||
} from "react-native";
|
||||
|
||||
import { useAccount, useCoState } from "jazz-expo";
|
||||
import { Chat, Message } from "./schema";
|
||||
import { BackgroundPhoto } from "./background";
|
||||
import { Chat, ChatAccount, Message } from "./schema";
|
||||
|
||||
export default function ChatScreen() {
|
||||
const { me, logOut } = useAccount(Account, { resolve: { profile: true } });
|
||||
const { me, logOut } = useAccount(ChatAccount, {
|
||||
resolve: { profile: true },
|
||||
});
|
||||
const [chatId, setChatId] = useState<string>();
|
||||
const [chatIdInput, setChatIdInput] = useState<string>();
|
||||
const loadedChat = useCoState(Chat, chatId, { resolve: { $each: true } });
|
||||
@@ -96,6 +98,10 @@ export default function ChatScreen() {
|
||||
<View style={styles.container}>
|
||||
{!loadedChat ? (
|
||||
<View style={styles.welcomeContainer}>
|
||||
<BackgroundPhoto
|
||||
image={me?.profile.backgroundPhoto ?? null}
|
||||
owner={me}
|
||||
/>
|
||||
<Text style={styles.usernameTitle}>Username</Text>
|
||||
<TextInput
|
||||
style={styles.usernameInput}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { co, z } from "jazz-tools";
|
||||
import { ImageDefinition } from "jazz-tools";
|
||||
|
||||
export const Message = co.map({
|
||||
text: z.string(),
|
||||
@@ -7,3 +8,11 @@ export type Message = co.loaded<typeof Message>;
|
||||
|
||||
export const Chat = co.list(Message);
|
||||
export type Chat = co.loaded<typeof Chat>;
|
||||
|
||||
export const ChatAccount = co.account({
|
||||
root: co.map({}),
|
||||
profile: co.profile({
|
||||
backgroundPhoto: z.optional(ImageDefinition),
|
||||
}),
|
||||
});
|
||||
export type ChatAccount = co.loaded<typeof ChatAccount>;
|
||||
|
||||
6
examples/chat-rn/.gitignore
vendored
6
examples/chat-rn/.gitignore
vendored
@@ -73,3 +73,9 @@ yarn-error.log
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
7
examples/chat-vue/.gitignore
vendored
7
examples/chat-vue/.gitignore
vendored
@@ -1 +1,6 @@
|
||||
dist
|
||||
dist
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
6
examples/chat/.gitignore
vendored
6
examples/chat/.gitignore
vendored
@@ -29,3 +29,9 @@ sync-db/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
1
examples/clerk/.env.example
Normal file
1
examples/clerk/.env.example
Normal file
@@ -0,0 +1 @@
|
||||
VITE_CLERK_PUBLISHABLE_KEY=
|
||||
@@ -1 +1 @@
|
||||
VITE_CLERK_PUBLISHABLE_KEY=pk_test_ZXZpZGVudC1kYW5lLTg5LmNsZXJrLmFjY291bnRzLmRldiQ
|
||||
VITE_CLERK_PUBLISHABLE_KEY=pk_test_ZXZpZGVudC1kYW5lLTg5LmNsZXJrLmFjY291bnRzLmRldiQ
|
||||
8
examples/clerk/.gitignore
vendored
8
examples/clerk/.gitignore
vendored
@@ -23,4 +23,10 @@ dist-ssr
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
playwright-report
|
||||
playwright-report
|
||||
|
||||
# Env
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -7,23 +7,34 @@ Live version: [https://clerk-demo.jazz.tools](https://clerk-demo.jazz.tools)
|
||||
## Getting started
|
||||
|
||||
You can either
|
||||
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
|
||||
```bash
|
||||
npx create-jazz-app@latest clerk-app --example clerk
|
||||
```
|
||||
|
||||
Go to the new project directory.
|
||||
|
||||
```bash
|
||||
cd clerk-app
|
||||
```
|
||||
|
||||
Rename .env.example to .env
|
||||
|
||||
```bash
|
||||
mv .env.example .env
|
||||
```
|
||||
|
||||
Update `VITE_CLERK_PUBLISHABLE_KEY` with your [Publishable Key](https://clerk.com/docs/deployments/clerk-environment-variables#clerk-publishable-and-secret-keys) from Clerk.
|
||||
|
||||
Run the dev server.
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
@@ -33,21 +44,33 @@ npm run dev
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Go to the example directory.
|
||||
|
||||
```bash
|
||||
cd jazz/examples/clerk/
|
||||
```
|
||||
|
||||
Rename .env.example to .env
|
||||
|
||||
```bash
|
||||
mv .env.example .env
|
||||
```
|
||||
|
||||
Update `VITE_CLERK_PUBLISHABLE_KEY` with your [Publishable Key](https://clerk.com/docs/deployments/clerk-environment-variables#clerk-publishable-and-secret-keys) from Clerk.
|
||||
|
||||
Start the dev server.
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
@@ -57,4 +80,3 @@ Open [http://localhost:5173](http://localhost:5173) with your browser to see the
|
||||
## Questions / problems / feedback
|
||||
|
||||
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@clerk/clerk-react": "^5.4.1",
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-react-auth-clerk": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
|
||||
@@ -3,6 +3,7 @@ import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import App from "./App.tsx";
|
||||
import "./index.css";
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { JazzProviderWithClerk } from "jazz-react-auth-clerk";
|
||||
import { ReactNode } from "react";
|
||||
import { apiKey } from "./apiKey";
|
||||
@@ -44,6 +45,7 @@ if (location.search.includes("expirationTest")) {
|
||||
<ClerkProvider publishableKey={PUBLISHABLE_KEY} afterSignOutUrl="/">
|
||||
<JazzProvider>
|
||||
<App />
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
</ClerkProvider>
|
||||
</StrictMode>,
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
<script lang="ts" module>
|
||||
declare module 'jazz-svelte' {
|
||||
interface Register {
|
||||
Account: typeof FileShareAccount;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { JazzProvider } from 'jazz-svelte';
|
||||
import "jazz-inspector-element"
|
||||
|
||||
8
examples/filestream/.gitignore
vendored
8
examples/filestream/.gitignore
vendored
@@ -25,4 +25,10 @@ dist-ssr
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
playwright-report
|
||||
playwright-report
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
6
examples/form/.gitignore
vendored
6
examples/form/.gitignore
vendored
@@ -25,3 +25,9 @@ dist-ssr
|
||||
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"hash-slash": "workspace:*",
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
@@ -15,6 +16,7 @@ createRoot(document.getElementById("root")!).render(
|
||||
AccountSchema={JazzAccount}
|
||||
>
|
||||
<App />
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
6
examples/image-upload/.gitignore
vendored
6
examples/image-upload/.gitignore
vendored
@@ -22,3 +22,9 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"format-and-lint:fix": "biome check . --write"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
@@ -15,6 +16,7 @@ createRoot(document.getElementById("root")!).render(
|
||||
AccountSchema={JazzAccount}
|
||||
>
|
||||
<App />
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
8
examples/inspector/.gitignore
vendored
8
examples/inspector/.gitignore
vendored
@@ -23,4 +23,10 @@ dist-ssr
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
sync-db/
|
||||
sync-db/
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -5,24 +5,25 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"test": "playwright test",
|
||||
"test:headed": "playwright test --headed",
|
||||
"format-and-lint": "biome check .",
|
||||
"format-and-lint:fix": "biome check . --write",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"clsx": "^2.0.0",
|
||||
"cojson": "workspace:*",
|
||||
"cojson-transport-ws": "workspace:*",
|
||||
"hash-slash": "workspace:*",
|
||||
"lucide-react": "^0.274.0",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react-router": "^6.16.0",
|
||||
"react-router-dom": "^6.16.0",
|
||||
"react-use": "^17.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
"@vitejs/plugin-react-swc": "^3.10.1",
|
||||
|
||||
46
examples/inspector/playwright.config.ts
Normal file
46
examples/inspector/playwright.config.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { defineConfig, devices } from "@playwright/test";
|
||||
import isCI from "is-ci";
|
||||
|
||||
/**
|
||||
* 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,
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -35,6 +35,7 @@ interface JazzLoggedInSecret {
|
||||
}
|
||||
|
||||
export default function CoJsonViewerApp() {
|
||||
const [errors, setErrors] = useState<string | null>(null);
|
||||
const [accounts, setAccounts] = useState<Account[]>(() => {
|
||||
const storedAccounts = localStorage.getItem("inspectorAccounts");
|
||||
return storedAccounts ? JSON.parse(storedAccounts) : [];
|
||||
@@ -80,23 +81,46 @@ export default function CoJsonViewerApp() {
|
||||
websocket: new WebSocket("wss://cloud.jazz.tools"),
|
||||
role: "server",
|
||||
});
|
||||
const node = await LocalNode.withLoadedAccount({
|
||||
accountID: currentAccount.id,
|
||||
accountSecret: currentAccount.secret,
|
||||
sessionID: crypto.newRandomSessionID(currentAccount.id),
|
||||
peersToLoadFrom: [wsPeer],
|
||||
crypto,
|
||||
migration: async () => {
|
||||
console.log("Not running any migration in inspector");
|
||||
},
|
||||
});
|
||||
let node;
|
||||
try {
|
||||
node = await LocalNode.withLoadedAccount({
|
||||
accountID: currentAccount.id,
|
||||
accountSecret: currentAccount.secret,
|
||||
sessionID: crypto.newRandomSessionID(currentAccount.id),
|
||||
peersToLoadFrom: [wsPeer],
|
||||
crypto,
|
||||
migration: async () => {
|
||||
console.log("Not running any migration in inspector");
|
||||
},
|
||||
});
|
||||
} catch (err: any) {
|
||||
if (err.toString().includes("invalid id")) {
|
||||
setAccounts(accounts.filter((acc) => acc.id !== currentAccount.id));
|
||||
//remove from localStorage
|
||||
localStorage.removeItem("lastSelectedAccountId");
|
||||
localStorage.setItem(
|
||||
"inspectorAccounts",
|
||||
JSON.parse(localStorage.inspectorAccounts).filter(
|
||||
(acc: Account) => acc.id != currentAccount.id,
|
||||
),
|
||||
);
|
||||
setCurrentAccount(null);
|
||||
setErrors("Trying to load covalue with invalid id");
|
||||
} else {
|
||||
setErrors("The account could not be loaded");
|
||||
}
|
||||
setLocalNode(null);
|
||||
goToIndex(-1);
|
||||
return;
|
||||
}
|
||||
setLocalNode(node);
|
||||
});
|
||||
}, [currentAccount, goToIndex, path]);
|
||||
}, [currentAccount, accounts, goToIndex, path]);
|
||||
|
||||
const addAccount = (id: RawAccountID, secret: AgentSecret) => {
|
||||
const newAccount = { id, secret };
|
||||
const accountExists = accounts.some((account) => account.id === id);
|
||||
//todo: ideally there would be some validation here so we don't have to manually remove a non existent account from localStorage
|
||||
if (!accountExists) {
|
||||
setAccounts([...accounts, newAccount]);
|
||||
}
|
||||
@@ -174,7 +198,9 @@ export default function CoJsonViewerApp() {
|
||||
goBack={goBack}
|
||||
addPages={addPages}
|
||||
>
|
||||
{!currentAccount && <AddAccountForm addAccount={addAccount} />}
|
||||
{!currentAccount && (
|
||||
<AddAccountForm addAccount={addAccount} errors={errors} />
|
||||
)}
|
||||
|
||||
{currentAccount && path.length <= 0 && (
|
||||
<form
|
||||
@@ -270,8 +296,10 @@ function AccountSwitcher({
|
||||
|
||||
function AddAccountForm({
|
||||
addAccount,
|
||||
errors,
|
||||
}: {
|
||||
addAccount: (id: RawAccountID, secret: AgentSecret) => void;
|
||||
errors: string | null;
|
||||
}) {
|
||||
const [id, setId] = useState("");
|
||||
const [secret, setSecret] = useState("");
|
||||
@@ -305,8 +333,17 @@ function AddAccountForm({
|
||||
return (
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
className="flex flex-col gap-3 max-w-md mx-auto h-full justify-center"
|
||||
className={`flex flex-col max-w-[30rem] mx-auto justify-center ${errors == null ? "h-full" : ""}`}
|
||||
>
|
||||
{errors != null && (
|
||||
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mt-4 font-mono whitespace-pre-wrap break-words mb-8">
|
||||
<h3>Error</h3>
|
||||
<pre className="whitespace-pre-wrap break-words overflow-hidden">
|
||||
{errors}
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h2 className="text-2xl font-medium text-gray-900 dark:text-white">
|
||||
Add an account to inspect
|
||||
</h2>
|
||||
|
||||
91
examples/inspector/tests/data.ts
Normal file
91
examples/inspector/tests/data.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { co, z } from "jazz-tools";
|
||||
|
||||
const projectsData: {
|
||||
name: string;
|
||||
description: string;
|
||||
issues: {
|
||||
title: string;
|
||||
status: "open" | "closed";
|
||||
labels: string[];
|
||||
}[];
|
||||
}[] = [
|
||||
{
|
||||
name: "Jazz",
|
||||
description: "Jazz is a framework for building collaborative apps.",
|
||||
issues: [
|
||||
{
|
||||
title: "Issue 1",
|
||||
status: "open",
|
||||
labels: [
|
||||
"bug",
|
||||
"feature",
|
||||
"enhancement",
|
||||
"documentation",
|
||||
"homepage",
|
||||
"help needed",
|
||||
"requested",
|
||||
"blocked",
|
||||
"high priority",
|
||||
"urgent",
|
||||
],
|
||||
},
|
||||
{ title: "Issue 2", status: "closed", labels: ["bug"] },
|
||||
{ title: "Issue 3", status: "open", labels: ["feature", "enhancement"] },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Waffle",
|
||||
description: "Start waffling",
|
||||
issues: [],
|
||||
},
|
||||
{
|
||||
name: "Garden",
|
||||
description: "Grow your garden",
|
||||
issues: [],
|
||||
},
|
||||
{
|
||||
name: "Tilescape",
|
||||
description: "",
|
||||
issues: [],
|
||||
},
|
||||
];
|
||||
|
||||
const Issue = co.map({
|
||||
title: z.string(),
|
||||
status: z.enum(["open", "closed"]),
|
||||
labels: co.list(z.string()),
|
||||
});
|
||||
|
||||
const Project = co.map({
|
||||
name: z.string(),
|
||||
description: z.string(),
|
||||
issues: co.list(Issue),
|
||||
});
|
||||
|
||||
const Organization = co.map({
|
||||
name: z.string(),
|
||||
projects: co.list(Project),
|
||||
});
|
||||
|
||||
export const createOrganization = () => {
|
||||
return Organization.create({
|
||||
name: "Garden Computing",
|
||||
projects: co.list(Project).create(
|
||||
projectsData.map((project) =>
|
||||
Project.create({
|
||||
name: project.name,
|
||||
description: project.description,
|
||||
issues: co.list(Issue).create(
|
||||
project.issues.map((issue) =>
|
||||
Issue.create({
|
||||
title: issue.title,
|
||||
status: issue.status,
|
||||
labels: co.list(z.string()).create(issue.labels),
|
||||
}),
|
||||
),
|
||||
),
|
||||
}),
|
||||
),
|
||||
),
|
||||
});
|
||||
};
|
||||
82
examples/inspector/tests/inspector.spec.ts
Normal file
82
examples/inspector/tests/inspector.spec.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { createOrganization } from "./data";
|
||||
import { createAccount, initializeKvStore } from "./lib";
|
||||
|
||||
initializeKvStore();
|
||||
const { account, accountID, accountSecret } = await createAccount();
|
||||
|
||||
test("should add and delete account in dropdown", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
await page.getByLabel("Account ID").fill(accountID);
|
||||
await page.getByLabel("Account secret").fill(accountSecret);
|
||||
await page.getByRole("button", { name: "Add account" }).click();
|
||||
|
||||
await expect(page.getByText("Jazz CoValue Inspector")).toBeVisible();
|
||||
await page
|
||||
.getByLabel("Account to inspect")
|
||||
.selectOption(`Inspector test account <${accountID}>`);
|
||||
|
||||
await page.getByRole("button", { name: "Remove account" }).click();
|
||||
await expect(page.getByText("Jazz CoValue Inspector")).not.toBeVisible();
|
||||
await expect(page.getByText("Add an account to inspect")).toBeVisible();
|
||||
await expect(
|
||||
page.getByText(`Inspector test account <${accountID}>`),
|
||||
).not.toBeVisible();
|
||||
});
|
||||
|
||||
test("should inspect account", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
await page.getByLabel("Account ID").fill(accountID);
|
||||
await page.getByLabel("Account secret").fill(accountSecret);
|
||||
await page.getByRole("button", { name: "Add account" }).click();
|
||||
await page.getByRole("button", { name: "Inspect my account" }).click();
|
||||
|
||||
await expect(page.getByRole("heading", { name: accountID })).toBeVisible();
|
||||
await expect(page.getByText("👤 Account")).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "profile {} CoMap name:" }).click();
|
||||
await expect(page.getByText("Role: admin")).toBeVisible();
|
||||
});
|
||||
|
||||
test("should inspect CoValue", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
await page.getByLabel("Account ID").fill(accountID);
|
||||
await page.getByLabel("Account secret").fill(accountSecret);
|
||||
await page.getByRole("button", { name: "Add account" }).click();
|
||||
|
||||
const organization = createOrganization();
|
||||
|
||||
await account.waitForAllCoValuesSync(); // Ensures that the organization is uploaded
|
||||
|
||||
await page.getByLabel("CoValue ID").fill(organization.id);
|
||||
await page.getByRole("button", { name: "Inspect CoValue" }).click();
|
||||
|
||||
await expect(page.getByText(/Garden Computing/)).toHaveCount(2);
|
||||
await expect(
|
||||
page.getByRole("heading", { name: organization.id }),
|
||||
).toBeVisible();
|
||||
await expect(page.getByText("Role: admin")).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: /projects/ }).click();
|
||||
await expect(page.getByText("Showing 4 of 4")).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "View" }).first().click();
|
||||
await expect(
|
||||
page.getByText("Jazz is a framework for building collaborative apps."),
|
||||
).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: /issues/ }).click();
|
||||
await expect(page.getByText("Showing 3 of 3")).toBeVisible();
|
||||
await page.getByRole("button", { name: "View" }).first().click();
|
||||
|
||||
await page.getByRole("button", { name: /labels/ }).click();
|
||||
// currently broken:
|
||||
// await expect(page.getByText("Showing 10 of 10")).toBeVisible();
|
||||
await expect(page.getByRole("table").getByRole("row")).toHaveCount(11);
|
||||
|
||||
await page.getByRole("button", { name: "issues" }).click();
|
||||
await expect(page.getByRole("table").getByRole("row")).toHaveCount(4);
|
||||
|
||||
await page.getByRole("button", { name: "projects" }).click();
|
||||
await expect(page.getByRole("table").getByRole("row")).toHaveCount(5);
|
||||
});
|
||||
43
examples/inspector/tests/lib.ts
Normal file
43
examples/inspector/tests/lib.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { createWebSocketPeer } from "cojson-transport-ws";
|
||||
import { WasmCrypto } from "cojson/crypto/WasmCrypto";
|
||||
import {
|
||||
AuthSecretStorage,
|
||||
InMemoryKVStore,
|
||||
KvStoreContext,
|
||||
co,
|
||||
createJazzContext,
|
||||
randomSessionProvider,
|
||||
z,
|
||||
} from "jazz-tools";
|
||||
|
||||
export const initializeKvStore = () => {
|
||||
const kvStore = new InMemoryKVStore();
|
||||
KvStoreContext.getInstance().initialize(kvStore);
|
||||
};
|
||||
|
||||
export async function createAccount() {
|
||||
const { account, authSecretStorage } = await createJazzContext({
|
||||
defaultProfileName: "Inspector test account",
|
||||
crypto: await WasmCrypto.create(),
|
||||
sessionProvider: randomSessionProvider,
|
||||
authSecretStorage: new AuthSecretStorage(),
|
||||
peersToLoadFrom: [
|
||||
createWebSocketPeer({
|
||||
id: "upstream",
|
||||
role: "server",
|
||||
websocket: new WebSocket(
|
||||
"wss://cloud.jazz.tools/?key=inspector-test@jazz.tools",
|
||||
),
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
await account.waitForAllCoValuesSync();
|
||||
|
||||
const credentials = await authSecretStorage.get();
|
||||
if (!credentials) {
|
||||
throw new Error("No credentials found");
|
||||
}
|
||||
|
||||
return { account, ...credentials };
|
||||
}
|
||||
6
examples/jazz-nextjs/.gitignore
vendored
6
examples/jazz-nextjs/.gitignore
vendored
@@ -39,3 +39,9 @@ yarn-error.log*
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"next": "15.3.2",
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-tools": "workspace:*"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
|
||||
export function Jazz({ children }: { children: React.ReactNode }) {
|
||||
@@ -11,6 +12,7 @@ export function Jazz({ children }: { children: React.ReactNode }) {
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
);
|
||||
}
|
||||
|
||||
6
examples/jazz-paper-scissors/.gitignore
vendored
6
examples/jazz-paper-scissors/.gitignore
vendored
@@ -1,3 +1,7 @@
|
||||
dist
|
||||
|
||||
.env
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
VITE_CURSOR_FEED_ID=multi-cursors-250425-1708
|
||||
VITE_GROUP_ID=co_zXE8C8sd9QxEbxnt3neRvFRPFUc
|
||||
VITE_OLD_CURSOR_AGE_SECONDS=5
|
||||
7
examples/multi-cursors/.gitignore
vendored
7
examples/multi-cursors/.gitignore
vendored
@@ -25,4 +25,9 @@ dist-ssr
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
playwright-report
|
||||
playwright-report
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -6,58 +6,80 @@ Live version: [https://multi-cursors.demo.jazz.tools/](https://multi-cursors.dem
|
||||
## Getting started
|
||||
|
||||
You can either
|
||||
|
||||
1. Clone the jazz repository, and run the app within the monorepo.
|
||||
2. Or create a new Jazz project using this example as a template.
|
||||
|
||||
|
||||
### Using the example as a template
|
||||
|
||||
Create a new Jazz project, and use this example as a template.
|
||||
|
||||
```bash
|
||||
npx create-jazz-app@latest multi-cursors-app --example multi-cursors
|
||||
```
|
||||
|
||||
Go to the new project directory.
|
||||
|
||||
```bash
|
||||
cd multi-cursors-app
|
||||
```
|
||||
|
||||
Run the dev server.
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
If you want to persist the cursors between server restarts, you'll need to update your .env file. Check your console logs for the correct values to add to your .env file.
|
||||
|
||||
```
|
||||
VITE_CURSOR_FEED_ID=
|
||||
VITE_GROUP_ID=
|
||||
VITE_OLD_CURSOR_AGE_SECONDS=5
|
||||
```
|
||||
|
||||
### Using the monorepo
|
||||
|
||||
This requires `pnpm` to be installed, see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
Clone the jazz repository.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
Install and build dependencies.
|
||||
|
||||
```bash
|
||||
pnpm i && npx turbo build
|
||||
```
|
||||
|
||||
Go to the example directory.
|
||||
|
||||
```bash
|
||||
cd jazz/examples/multi-cursors/
|
||||
```
|
||||
|
||||
Start the dev server.
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
||||
|
||||
If you want to persist the cursors between server restarts, you'll need to update your .env file. Check your console logs for the correct values to add to your .env file.
|
||||
|
||||
```
|
||||
VITE_CURSOR_FEED_ID=
|
||||
VITE_GROUP_ID=
|
||||
VITE_OLD_CURSOR_AGE_SECONDS=5
|
||||
```
|
||||
|
||||
## Questions / problems / feedback
|
||||
|
||||
If you have feedback, let us know on [Discord](https://discord.gg/utDMjHYg42) or open an issue or PR to fix something that seems wrong.
|
||||
|
||||
|
||||
## Configuration: sync server
|
||||
|
||||
By default, the example app uses [Jazz Cloud](https://jazz.tools/cloud) (`wss://cloud.jazz.tools`) - so cross-device use, invites and collaboration should just work.
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-spring/web": "^9.7.5",
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
@@ -16,6 +17,7 @@ createRoot(document.getElementById("root")!).render(
|
||||
AccountSchema={CursorAccount}
|
||||
>
|
||||
<App />
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
VITE_CLERK_PUBLISHABLE_KEY=pk_test_ZXZpZGVudC1kYW5lLTg5LmNsZXJrLmFjY291bnRzLmRldiQ
|
||||
1
examples/multiauth/.env.example
Normal file
1
examples/multiauth/.env.example
Normal file
@@ -0,0 +1 @@
|
||||
VITE_CLERK_PUBLISHABLE_KEY=
|
||||
6
examples/multiauth/.gitignore
vendored
6
examples/multiauth/.gitignore
vendored
@@ -22,3 +22,9 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# Env
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -5,19 +5,35 @@ This example demonstrates using Jazz with multiple authentication methods; in th
|
||||
## Getting started
|
||||
|
||||
To run this example, you may either:
|
||||
* Clone the Jazz monorepo and run this example from within.
|
||||
* Create a new Jazz project using this example as a template, and run that new project.
|
||||
|
||||
- Clone the Jazz monorepo and run this example from within.
|
||||
- Create a new Jazz project using this example as a template, and run that new project.
|
||||
|
||||
### Using this example as a template
|
||||
|
||||
1. Create a new Jazz project, and use this example as a template.
|
||||
|
||||
```bash
|
||||
npx create-jazz-app@latest multiauth-app --example multiauth
|
||||
```
|
||||
2. Navigate to the new project and start the development server.
|
||||
|
||||
2. Navigate to the new project.
|
||||
|
||||
```bash
|
||||
cd multiauth-app
|
||||
```
|
||||
|
||||
3. Rename .env.example to .env
|
||||
|
||||
```bash
|
||||
mv .env.example .env
|
||||
```
|
||||
|
||||
4. Update `VITE_CLERK_PUBLISHABLE_KEY` with your [Publishable Key](https://clerk.com/docs/deployments/clerk-environment-variables#clerk-publishable-and-secret-keys) from Clerk.
|
||||
|
||||
5. Run the development server
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
@@ -26,17 +42,35 @@ npm run dev
|
||||
This requires `pnpm` to be installed; see [https://pnpm.io/installation](https://pnpm.io/installation).
|
||||
|
||||
1. Clone the `jazz` repository.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/garden-co/jazz.git
|
||||
```
|
||||
|
||||
2. Install dependencies.
|
||||
|
||||
```bash
|
||||
cd jazz
|
||||
pnpm install
|
||||
```
|
||||
|
||||
3. Navigate to the example and start the development server.
|
||||
|
||||
```bash
|
||||
cd examples/multiauth
|
||||
```
|
||||
|
||||
4. Rename .env.example to .env
|
||||
|
||||
```bash
|
||||
mv .env.example .env
|
||||
```
|
||||
|
||||
5. Update `VITE_CLERK_PUBLISHABLE_KEY` with your [Publishable Key](https://clerk.com/docs/deployments/clerk-environment-variables#clerk-publishable-and-secret-keys) from Clerk.
|
||||
|
||||
6. Run the development server
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"dependencies": {
|
||||
"@clerk/clerk-react": "^5.4.1",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react-auth-clerk": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ClerkProvider } from "@clerk/clerk-react";
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import App from "./App";
|
||||
@@ -22,6 +23,7 @@ createRoot(document.getElementById("root")!).render(
|
||||
}}
|
||||
>
|
||||
<App />
|
||||
<JazzInspector />
|
||||
</OmniAuth>
|
||||
</ClerkProvider>
|
||||
</StrictMode>,
|
||||
|
||||
8
examples/music-player/.gitignore
vendored
8
examples/music-player/.gitignore
vendored
@@ -28,4 +28,10 @@ dist-ssr
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
|
||||
sync-db/
|
||||
sync-db/
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -110,7 +110,7 @@ export async function addTrackToPlaylist(
|
||||
* visible to the Playlist user
|
||||
*/
|
||||
const trackGroup = track._owner;
|
||||
trackGroup.extend(playlist._owner);
|
||||
trackGroup.addMember(playlist._owner);
|
||||
|
||||
playlist.tracks?.push(track);
|
||||
return;
|
||||
@@ -129,7 +129,7 @@ export async function removeTrackFromPlaylist(
|
||||
|
||||
if (track._owner._type === "Group" && playlist._owner._type === "Group") {
|
||||
const trackGroup = track._owner;
|
||||
await trackGroup.revokeExtend(playlist._owner);
|
||||
await trackGroup.removeMember(playlist._owner);
|
||||
|
||||
const index =
|
||||
playlist.tracks?.findIndex(
|
||||
|
||||
8
examples/organization/.gitignore
vendored
8
examples/organization/.gitignore
vendored
@@ -23,4 +23,10 @@ dist-ssr
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
playwright-report
|
||||
playwright-report
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"test:e2e:ui": "playwright test --ui"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"lucide-react": "^0.274.0",
|
||||
@@ -21,8 +22,8 @@
|
||||
"react-router-dom": "^6.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@playwright/test": "^1.50.1",
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
"@types/react": "19.0.0",
|
||||
"@types/react-dom": "19.0.0",
|
||||
|
||||
@@ -7,16 +7,9 @@ import { Organization } from "../schema.ts";
|
||||
export function InviteLink({
|
||||
organization,
|
||||
}: { organization: Loaded<typeof Organization> }) {
|
||||
const [inviteLink, setInviteLink] = useState<string>();
|
||||
let [copyCount, setCopyCount] = useState(0);
|
||||
let copied = copyCount > 0;
|
||||
|
||||
useEffect(() => {
|
||||
if (organization) {
|
||||
setInviteLink(createInviteLink(organization, "writer"));
|
||||
}
|
||||
}, [organization.id]);
|
||||
|
||||
useEffect(() => {
|
||||
if (copyCount > 0) {
|
||||
let timeout = setTimeout(() => setCopyCount(0), 1000);
|
||||
@@ -27,11 +20,10 @@ export function InviteLink({
|
||||
}, [copyCount]);
|
||||
|
||||
const copyUrl = () => {
|
||||
if (inviteLink) {
|
||||
navigator.clipboard.writeText(inviteLink).then(() => {
|
||||
setCopyCount((count) => count + 1);
|
||||
});
|
||||
}
|
||||
const inviteLink = createInviteLink(organization, "writer");
|
||||
navigator.clipboard.writeText(inviteLink).then(() => {
|
||||
setCopyCount((count) => count + 1);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
@@ -37,6 +38,7 @@ createRoot(document.getElementById("root")!).render(
|
||||
}}
|
||||
>
|
||||
<Router />
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
6
examples/passkey/.gitignore
vendored
6
examples/passkey/.gitignore
vendored
@@ -22,3 +22,9 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"format-and-lint:fix": "biome check . --write"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { JazzProvider, PasskeyAuthBasicUI } from "jazz-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
@@ -15,6 +16,7 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
<PasskeyAuthBasicUI appName="Jazz Minimal Auth Passkey Example">
|
||||
{children}
|
||||
</PasskeyAuthBasicUI>
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
);
|
||||
}
|
||||
|
||||
6
examples/passphrase/.gitignore
vendored
6
examples/passphrase/.gitignore
vendored
@@ -22,3 +22,9 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"format-and-lint:fix": "biome check . --write"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { JazzProvider, usePassphraseAuth } from "jazz-react";
|
||||
import { StrictMode, useState } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
@@ -150,6 +151,7 @@ function JazzAndAuth({ children }: { children: React.ReactNode }) {
|
||||
>
|
||||
{children}
|
||||
</PassphraseAuthBasicUI>
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
);
|
||||
}
|
||||
|
||||
6
examples/password-manager/.gitignore
vendored
6
examples/password-manager/.gitignore
vendored
@@ -22,3 +22,9 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"clean-install": "rm -rf node_modules pnpm-lock.yaml && pnpm install"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { JazzProvider, PasskeyAuthBasicUI } from "jazz-react";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
@@ -25,6 +26,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<React.StrictMode>
|
||||
<JazzAndAuth>
|
||||
<App />
|
||||
<JazzInspector />
|
||||
</JazzAndAuth>
|
||||
</React.StrictMode>,
|
||||
);
|
||||
|
||||
8
examples/pets/.gitignore
vendored
8
examples/pets/.gitignore
vendored
@@ -27,4 +27,10 @@ dist-ssr
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
|
||||
sync-db/
|
||||
sync-db/
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"lucide-react": "^0.274.0",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import {
|
||||
@@ -47,6 +48,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<PasskeyAuthBasicUI appName={appName}>
|
||||
<App />
|
||||
</PasskeyAuthBasicUI>
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
|
||||
6
examples/reactions/.gitignore
vendored
6
examples/reactions/.gitignore
vendored
@@ -22,3 +22,9 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"hash-slash": "workspace:*",
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"react": "19.0.0",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { JazzProvider, PasskeyAuthBasicUI } from "jazz-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
@@ -15,6 +16,7 @@ createRoot(document.getElementById("root")!).render(
|
||||
<PasskeyAuthBasicUI appName="Jazz Reactions Example">
|
||||
<App />
|
||||
</PasskeyAuthBasicUI>
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
36
examples/richtext-prosekit/.gitignore
vendored
Normal file
36
examples/richtext-prosekit/.gitignore
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
|
||||
sync-db/
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
@@ -8,6 +8,7 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-richtext-prosemirror": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import "./app.css";
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
@@ -15,6 +16,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
AccountSchema={JazzAccount}
|
||||
>
|
||||
<App />
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
</React.StrictMode>,
|
||||
);
|
||||
|
||||
36
examples/richtext-prosemirror/.gitignore
vendored
Normal file
36
examples/richtext-prosemirror/.gitignore
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
|
||||
sync-db/
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
@@ -12,6 +12,7 @@
|
||||
"format-and-lint:fix": "biome check . --write"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-richtext-prosemirror": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
@@ -21,6 +22,7 @@ createRoot(document.getElementById("root")!).render(
|
||||
AccountSchema={JazzAccount}
|
||||
>
|
||||
<App />
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
36
examples/richtext-tiptap/.gitignore
vendored
Normal file
36
examples/richtext-tiptap/.gitignore
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
|
||||
sync-db/
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
@@ -20,6 +20,7 @@
|
||||
"@tiptap/react": "^2.12.0",
|
||||
"@tiptap/starter-kit": "^2.12.0",
|
||||
"clsx": "^2.1.1",
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-richtext-tiptap": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import { JazzProvider } from "jazz-react";
|
||||
import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
@@ -21,6 +22,7 @@ createRoot(document.getElementById("root")!).render(
|
||||
AccountSchema={JazzAccount}
|
||||
>
|
||||
<App />
|
||||
<JazzInspector />
|
||||
</JazzProvider>
|
||||
</StrictMode>,
|
||||
);
|
||||
|
||||
8
examples/todo-vue/.gitignore
vendored
8
examples/todo-vue/.gitignore
vendored
@@ -1 +1,7 @@
|
||||
dist
|
||||
dist
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"format-and-lint:fix": "biome check . --write"
|
||||
},
|
||||
"dependencies": {
|
||||
"jazz-inspector-element": "workspace:*",
|
||||
"jazz-browser": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"jazz-vue": "workspace:*",
|
||||
|
||||
8
examples/todo/.gitignore
vendored
8
examples/todo/.gitignore
vendored
@@ -23,4 +23,10 @@ dist-ssr
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
sync-db/
|
||||
sync-db/
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"@radix-ui/react-toast": "^1.1.4",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.0.0",
|
||||
"jazz-inspector": "workspace:*",
|
||||
"jazz-react": "workspace:*",
|
||||
"jazz-tools": "workspace:*",
|
||||
"lucide-react": "^0.274.0",
|
||||
|
||||
@@ -6,13 +6,13 @@ import {
|
||||
} from "react-router-dom";
|
||||
import "./index.css";
|
||||
|
||||
import { JazzInspector } from "jazz-inspector";
|
||||
import {
|
||||
JazzProvider,
|
||||
PassphraseAuthBasicUI,
|
||||
useAcceptInvite,
|
||||
useAccount,
|
||||
} from "jazz-react";
|
||||
|
||||
import React from "react";
|
||||
import { TodoAccount, TodoProject } from "./1_schema.ts";
|
||||
import { NewProjectForm } from "./3_NewProjectForm.tsx";
|
||||
@@ -62,6 +62,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
<App />
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
<JazzInspector />
|
||||
</JazzAndAuth>
|
||||
</React.StrictMode>,
|
||||
);
|
||||
|
||||
6
examples/version-history/.gitignore
vendored
6
examples/version-history/.gitignore
vendored
@@ -22,3 +22,9 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
"jazz-react": "link:../../packages/jazz-react",
|
||||
"jazz-tools": "link:../../packages/jazz-tools",
|
||||
"lucide-react": "^0.436.0",
|
||||
"next": "14.2.7",
|
||||
"next": "15.2.1",
|
||||
"next-themes": "^0.2.1",
|
||||
"postcss": "^8",
|
||||
"radix-ui": "^1.4.2",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:",
|
||||
"resend": "^4.0.0",
|
||||
"tailwind-merge": "^1.14.0",
|
||||
"tailwindcss": "^3.4.17",
|
||||
@@ -34,8 +34,8 @@
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@csstools/postcss-oklab-function": "^3.0.6",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"@types/react": "catalog:",
|
||||
"@types/react-dom": "catalog:",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"@components/*": ["./src/components/*"]
|
||||
}
|
||||
},
|
||||
"target": "ES2017"
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
|
||||
@@ -12,5 +12,6 @@
|
||||
"persistent": true,
|
||||
"dependsOn": ["^build"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"extends": ["//"]
|
||||
}
|
||||
|
||||
@@ -10,8 +10,15 @@ import { Metadata } from "next";
|
||||
import Image from "next/image";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
type Params = {
|
||||
params: Promise<{
|
||||
slug: string;
|
||||
}>;
|
||||
};
|
||||
|
||||
export default async function Post({ params }: Params) {
|
||||
const post = getPostBySlug(params.slug);
|
||||
const { slug } = await params;
|
||||
const post = getPostBySlug(slug);
|
||||
|
||||
if (!post) {
|
||||
return notFound();
|
||||
@@ -65,14 +72,9 @@ export default async function Post({ params }: Params) {
|
||||
);
|
||||
}
|
||||
|
||||
type Params = {
|
||||
params: {
|
||||
slug: string;
|
||||
};
|
||||
};
|
||||
|
||||
export function generateMetadata({ params }: Params): Metadata {
|
||||
const post = getPostBySlug(params.slug);
|
||||
export async function generateMetadata({ params }: Params): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const post = getPostBySlug(slug);
|
||||
|
||||
if (!post) {
|
||||
return notFound();
|
||||
|
||||
@@ -18,15 +18,17 @@ const membersNameToInfoMap = {
|
||||
brad: "Bradley Kowalski",
|
||||
};
|
||||
|
||||
export default function TeamMemberPage({
|
||||
export default async function TeamMemberPage({
|
||||
params,
|
||||
}: { params: { member: string } }) {
|
||||
if (!(params.member in membersNameToInfoMap)) {
|
||||
}: { params: Promise<{ member: string }> }) {
|
||||
const { member } = await params;
|
||||
|
||||
if (!(member in membersNameToInfoMap)) {
|
||||
Router.push("/team");
|
||||
}
|
||||
|
||||
const memberName =
|
||||
membersNameToInfoMap[params.member as keyof typeof membersNameToInfoMap];
|
||||
membersNameToInfoMap[member as keyof typeof membersNameToInfoMap];
|
||||
const memberInfo = team.find(
|
||||
(m: { name: string }) => m.name.toLowerCase() === memberName.toLowerCase(),
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user