Appwrite 1.0 (#793)

This commit is contained in:
Piotr Rogowski 2022-10-14 12:01:18 +02:00 committed by GitHub
parent 7582896174
commit 3c29b6723e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 89 additions and 134 deletions

62
package-lock.json generated
View File

@ -15,7 +15,7 @@
"@sentry/react": "^7.15.0",
"@sentry/tracing": "^7.15.0",
"antd": "^4.23.5",
"appwrite": "9.0.2",
"appwrite": "10.1.0",
"kbar": "^0.1.0-beta.36",
"lodash.debounce": "^4.0.8",
"mlg-converter": "^0.5.1",
@ -1258,9 +1258,9 @@
"dev": true
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.16",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.16.tgz",
"integrity": "sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==",
"version": "0.3.17",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
"integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "3.1.0",
@ -2079,9 +2079,9 @@
}
},
"node_modules/appwrite": {
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/appwrite/-/appwrite-9.0.2.tgz",
"integrity": "sha512-3mhI9eNzOz8k9d2RDuYQdA9BHCgmT3HvtsVdxHcY20ps8TnEj38jx3NilQ/60G6ALrdMt79u9mYIRsj4ftitTw==",
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/appwrite/-/appwrite-10.1.0.tgz",
"integrity": "sha512-kHtPqKf0X+mxmkS47G3F5vVY5wKMVRv7ZTpTvd9H3m1KBIm3aDAEBCEUt6bGQdE8XKgqLFzhqWFdQWkxX6I0xA==",
"dependencies": {
"cross-fetch": "3.1.5",
"isomorphic-form-data": "2.0.0"
@ -2648,9 +2648,9 @@
"integrity": "sha512-Gj9hZN3a07cbR6zviMUBOMPdWxYhbMI+x+WS0NAIu2zFZmbK8ys9R79g+iG9qLnlCwpFoaB+fKy8Pdv470GsPA=="
},
"node_modules/electron-to-chromium": {
"version": "1.4.281",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.281.tgz",
"integrity": "sha512-yer0w5wCYdFoZytfmbNhwiGI/3cW06+RV7E23ln4490DVMxs7PvYpbsrSmAiBn/V6gode8wvJlST2YfWgvzWIg==",
"version": "1.4.282",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.282.tgz",
"integrity": "sha512-Dki0WhHNh/br/Xi1vAkueU5mtIc9XLHcMKB6tNfQKk+kPG0TEUjRh5QEMAUbRp30/rYNMFD1zKKvbVzwq/4wmg==",
"dev": true
},
"node_modules/emoji-regex": {
@ -6442,9 +6442,9 @@
}
},
"node_modules/rc-virtual-list": {
"version": "3.4.8",
"resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.4.8.tgz",
"integrity": "sha512-qSN+Rv4i/E7RCTvTMr1uZo7f3crJJg/5DekoCagydo9zsXrxj07zsFSxqizqW+ldGA16lwa8So/bIbV9Ofjddg==",
"version": "3.4.10",
"resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.4.10.tgz",
"integrity": "sha512-Jv0cgJxJ+8F/YViW8WGs/jQF2rmT8RUcJ5uDJs5MOFLTYLAvCpM/xU+Zu6EpCun50fmovhXiItQctcfE2UY3Aw==",
"dependencies": {
"classnames": "^2.2.6",
"rc-resize-observer": "^1.0.0",
@ -6638,9 +6638,9 @@
}
},
"node_modules/regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
"version": "0.13.10",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz",
"integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw=="
},
"node_modules/regexp.prototype.flags": {
"version": "1.4.3",
@ -8655,9 +8655,9 @@
"dev": true
},
"@jridgewell/trace-mapping": {
"version": "0.3.16",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.16.tgz",
"integrity": "sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==",
"version": "0.3.17",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
"integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
"dev": true,
"requires": {
"@jridgewell/resolve-uri": "3.1.0",
@ -9245,9 +9245,9 @@
}
},
"appwrite": {
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/appwrite/-/appwrite-9.0.2.tgz",
"integrity": "sha512-3mhI9eNzOz8k9d2RDuYQdA9BHCgmT3HvtsVdxHcY20ps8TnEj38jx3NilQ/60G6ALrdMt79u9mYIRsj4ftitTw==",
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/appwrite/-/appwrite-10.1.0.tgz",
"integrity": "sha512-kHtPqKf0X+mxmkS47G3F5vVY5wKMVRv7ZTpTvd9H3m1KBIm3aDAEBCEUt6bGQdE8XKgqLFzhqWFdQWkxX6I0xA==",
"requires": {
"cross-fetch": "3.1.5",
"isomorphic-form-data": "2.0.0"
@ -9666,9 +9666,9 @@
"integrity": "sha512-Gj9hZN3a07cbR6zviMUBOMPdWxYhbMI+x+WS0NAIu2zFZmbK8ys9R79g+iG9qLnlCwpFoaB+fKy8Pdv470GsPA=="
},
"electron-to-chromium": {
"version": "1.4.281",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.281.tgz",
"integrity": "sha512-yer0w5wCYdFoZytfmbNhwiGI/3cW06+RV7E23ln4490DVMxs7PvYpbsrSmAiBn/V6gode8wvJlST2YfWgvzWIg==",
"version": "1.4.282",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.282.tgz",
"integrity": "sha512-Dki0WhHNh/br/Xi1vAkueU5mtIc9XLHcMKB6tNfQKk+kPG0TEUjRh5QEMAUbRp30/rYNMFD1zKKvbVzwq/4wmg==",
"dev": true
},
"emoji-regex": {
@ -12200,9 +12200,9 @@
}
},
"rc-virtual-list": {
"version": "3.4.8",
"resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.4.8.tgz",
"integrity": "sha512-qSN+Rv4i/E7RCTvTMr1uZo7f3crJJg/5DekoCagydo9zsXrxj07zsFSxqizqW+ldGA16lwa8So/bIbV9Ofjddg==",
"version": "3.4.10",
"resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.4.10.tgz",
"integrity": "sha512-Jv0cgJxJ+8F/YViW8WGs/jQF2rmT8RUcJ5uDJs5MOFLTYLAvCpM/xU+Zu6EpCun50fmovhXiItQctcfE2UY3Aw==",
"requires": {
"classnames": "^2.2.6",
"rc-resize-observer": "^1.0.0",
@ -12332,9 +12332,9 @@
"requires": {}
},
"regenerator-runtime": {
"version": "0.13.9",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
"version": "0.13.10",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz",
"integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw=="
},
"regexp.prototype.flags": {
"version": "1.4.3",

View File

@ -25,7 +25,7 @@
"@sentry/react": "^7.15.0",
"@sentry/tracing": "^7.15.0",
"antd": "^4.23.5",
"appwrite": "9.0.2",
"appwrite": "10.1.0",
"kbar": "^0.1.0-beta.36",
"lodash.debounce": "^4.0.8",
"mlg-converter": "^0.5.1",

View File

@ -10,15 +10,15 @@ const client = new Client();
client
.setEndpoint(fetchEnv('VITE_APPWRITE_ENDPOINT'))
.setProject('hyper-tuner-cloud');
.setProject('hyper-tuner-api');
const account = new Account(client);
const database = new Databases(client, 'public');
const databases = new Databases(client);
const storage = new Storage(client);
export {
client,
account,
database,
databases,
storage,
};

View File

@ -1,3 +1,7 @@
import {
ID,
Models,
} from 'appwrite';
import {
createContext,
ReactNode,
@ -17,84 +21,16 @@ import {
buildRedirectUrl,
} from '../utils/url';
export interface User {
$id: string;
name: string;
registration: number;
status: boolean;
passwordUpdate: number;
email: string;
emailVerification: boolean;
prefs: {};
}
export interface Session {
$id: string;
userId: string;
expire: number;
provider: string;
providerUid: string;
providerAccessToken: string;
providerAccessTokenExpiry: number;
providerRefreshToken: string;
ip: string;
osCode: string;
osName: string;
osVersion: string;
clientType: string;
clientCode: string;
clientName: string;
clientVersion: string;
clientEngine: string;
clientEngineVersion: string;
deviceName: string;
deviceBrand: string;
deviceModel: string;
countryCode: string;
countryName: string;
current: boolean;
};
export interface SessionList {
sessions: Session[];
total: number;
};
export interface Log {
event: string;
userId: string;
userEmail: string;
userName: string;
mode: string;
ip: string;
time: number;
osCode: string;
osName: string;
osVersion: string;
clientType: string;
clientCode: string;
clientName: string;
clientVersion: string;
clientEngine: string;
clientEngineVersion: string;
deviceName: string;
deviceBrand: string;
deviceModel: string;
countryCode: string;
countryName: string;
};
export interface LogList {
logs: Log[];
total: number;
}
export type SessionList = Models.SessionList;
export type LogList = Models.LogList;
export type Account = Models.Account<Models.Preferences>;
interface AuthValue {
currentUser: User | null,
signUp: (email: string, password: string, username: string) => Promise<User>,
login: (email: string, password: string) => Promise<User>,
currentUser: Account | null,
signUp: (email: string, password: string, username: string) => Promise<Account>,
login: (email: string, password: string) => Promise<Account>,
sendMagicLink: (email: string) => Promise<void>,
confirmMagicLink: (userId: string, secret: string) => Promise<User>,
confirmMagicLink: (userId: string, secret: string) => Promise<Account>,
sendEmailVerification: () => Promise<void>,
confirmEmailVerification: (userId: string, secret: string) => Promise<void>,
confirmResetPassword: (userId: string, secret: string, password: string) => Promise<void>,
@ -124,14 +60,14 @@ const useAuth = () => useContext<AuthValue>(AuthContext as any);
const AuthProvider = (props: { children: ReactNode }) => {
const { children } = props;
const [currentUser, setCurrentUser] = useState<User | null>(null);
const [currentUser, setCurrentUser] = useState<Account | null>(null);
const [isLoading, setIsLoading] = useState(true);
const value = useMemo(() => ({
currentUser,
signUp: async (email: string, password: string, username: string) => {
try {
await account.create('unique()', email, password, username);
await account.create(ID.unique(), email, password, username);
await account.createEmailSession(email, password);
const user = await account.get();
setCurrentUser(user);
@ -152,7 +88,7 @@ const AuthProvider = (props: { children: ReactNode }) => {
},
sendMagicLink: async (email: string) => {
try {
await account.createMagicURLSession('unique()', email, MAGIC_LINK_REDIRECT_URL);
await account.createMagicURLSession(ID.unique(), email, MAGIC_LINK_REDIRECT_URL);
return Promise.resolve();
} catch (error) {
return Promise.reject(error);
@ -253,8 +189,8 @@ const AuthProvider = (props: { children: ReactNode }) => {
return Promise.reject(error);
}
},
getSessions: () => account.getSessions(),
getLogs: () => account.getLogs(),
getSessions: () => account.listSessions(),
getLogs: () => account.listLogs(),
}), [currentUser]);
useEffect(() => {

View File

@ -1,9 +1,12 @@
import * as Sentry from '@sentry/browser';
import {
ID,
Models,
Permission,
Query,
Role,
} from 'appwrite';
import { database } from '../appwrite';
import { databases } from '../appwrite';
import {
TuneDbData,
UsersBucket,
@ -12,13 +15,14 @@ import {
} from '../types/dbData';
import { databaseGenericError } from '../pages/auth/notifications';
const DB_ID = 'public';
const COLLECTION_ID_PUBLIC_TUNES = 'tunes';
const COLLECTION_ID_USERS_BUCKETS = 'usersBuckets';
const useDb = () => {
const updateTune = async (documentId: string, data: TuneDbDataPartial) => {
try {
await database.updateDocument(COLLECTION_ID_PUBLIC_TUNES, documentId, data);
await databases.updateDocument(DB_ID, COLLECTION_ID_PUBLIC_TUNES, documentId, data);
return Promise.resolve();
} catch (error) {
@ -32,12 +36,15 @@ const useDb = () => {
const createTune = async (data: TuneDbData) => {
try {
const tune = await database.createDocument(
const tune = await databases.createDocument(
DB_ID,
COLLECTION_ID_PUBLIC_TUNES,
'unique()',
ID.unique(),
data,
['role:all'],
[`user:${data.userId}`],
[
Permission.read(Role.any()),
Permission.write(Role.user(data.userId, 'verified')),
],
);
return Promise.resolve(tune);
@ -52,10 +59,13 @@ const useDb = () => {
const getTune = async (tuneId: string) => {
try {
const tune = await database.listDocuments(
const tune = await databases.listDocuments(
DB_ID,
COLLECTION_ID_PUBLIC_TUNES,
[Query.equal('tuneId', tuneId)],
1,
[
Query.equal('tuneId', tuneId),
Query.limit(1),
],
);
return Promise.resolve(tune.total > 0 ? tune.documents[0] as unknown as TuneDbDocument : null);
@ -70,13 +80,14 @@ const useDb = () => {
const getBucketId = async (userId: string) => {
try {
const buckets = await database.listDocuments(
const buckets = await databases.listDocuments(
DB_ID,
COLLECTION_ID_USERS_BUCKETS,
[
Query.equal('userId', userId),
Query.equal('visibility', 'public'),
Query.limit(1),
],
1,
);
if (buckets.total === 0) {
@ -100,8 +111,8 @@ const useDb = () => {
try {
const list: Models.DocumentList<TuneDbDocument> = await (
search
? database.listDocuments(COLLECTION_ID_PUBLIC_TUNES, [Query.search('textSearch', search)], limit)
: database.listDocuments(COLLECTION_ID_PUBLIC_TUNES, [], limit)
? databases.listDocuments(DB_ID, COLLECTION_ID_PUBLIC_TUNES, [Query.search('textSearch', search), Query.limit(limit)])
: databases.listDocuments(DB_ID, COLLECTION_ID_PUBLIC_TUNES, [Query.limit(limit)])
);
return Promise.resolve(list);

View File

@ -1,6 +1,11 @@
import { notification } from 'antd';
import * as Sentry from '@sentry/browser';
import { Models } from 'appwrite';
import {
ID,
Models,
Permission,
Role,
} from 'appwrite';
import { storage } from '../appwrite';
import { fetchEnv } from '../utils/env';
@ -65,10 +70,12 @@ const useServerStorage = () => {
try {
const createdFile = await storage.createFile(
bucketId,
'unique()',
ID.unique(),
file,
['role:all'],
[`user:${userId}`],
[
Permission.read(Role.any()),
Permission.write(Role.user(userId, 'verified')),
],
);
return Promise.resolve(createdFile);

View File

@ -59,7 +59,7 @@ const Hub = () => {
author: 'John Doe',
displacement: `${tune.displacement}l`,
aspiration: aspirationMapper[tune.aspiration],
publishedAt: new Date(tune.$updatedAt * 1000).toLocaleString(),
publishedAt: new Date(tune.$updatedAt).toLocaleString(),
stars: 0,
})));
setIsLoading(false);

View File

@ -399,6 +399,7 @@ const UploadPage = () => {
form.setFieldsValue(oldTune);
setIsEditMode(true);
setTuneDocumentId(oldTune.$id);
setReadme(oldTune.readme!);
if (oldTune.tuneFileId) {
const file = await getFile(oldTune.tuneFileId, await getBucketId(currentUser!.$id));

View File

@ -79,7 +79,7 @@ const Profile = () => {
const fetchLogs = useCallback(async () => getLogs()
.then((list) => setLogs(list.logs.slice(0, MAX_LIST_SIZE).map((log) => [
new Date(log.time * 1000).toLocaleString(),
new Date(log.time).toLocaleString(),
parseLogEvent(log.event),
log.clientName,
log.clientEngineVersion,