mirror of
https://github.com/get-drexa/drive.git
synced 2025-12-01 05:51:39 +00:00
refactor[db]: store time as unix ms
Co-authored-by: Ona <no-reply@ona.com>
This commit is contained in:
1
bun.lock
1
bun.lock
@@ -13,6 +13,7 @@
|
|||||||
"name": "@fileone/convex",
|
"name": "@fileone/convex",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fileone/path": "workspace:*",
|
"@fileone/path": "workspace:*",
|
||||||
|
"convex-helpers": "^0.1.104",
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"convex": "^1.27.0",
|
"convex": "^1.27.0",
|
||||||
|
|||||||
90
packages/convex/README.md
Normal file
90
packages/convex/README.md
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
# Welcome to your Convex functions directory!
|
||||||
|
|
||||||
|
Write your Convex functions here.
|
||||||
|
See https://docs.convex.dev/functions for more.
|
||||||
|
|
||||||
|
A query function that takes two arguments looks like:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// convex/myFunctions.ts
|
||||||
|
import { query } from "./_generated/server";
|
||||||
|
import { v } from "convex/values";
|
||||||
|
|
||||||
|
export const myQueryFunction = query({
|
||||||
|
// Validators for arguments.
|
||||||
|
args: {
|
||||||
|
first: v.number(),
|
||||||
|
second: v.string(),
|
||||||
|
},
|
||||||
|
|
||||||
|
// Function implementation.
|
||||||
|
handler: async (ctx, args) => {
|
||||||
|
// Read the database as many times as you need here.
|
||||||
|
// See https://docs.convex.dev/database/reading-data.
|
||||||
|
const documents = await ctx.db.query("tablename").collect();
|
||||||
|
|
||||||
|
// Arguments passed from the client are properties of the args object.
|
||||||
|
console.log(args.first, args.second);
|
||||||
|
|
||||||
|
// Write arbitrary JavaScript here: filter, aggregate, build derived data,
|
||||||
|
// remove non-public properties, or create new objects.
|
||||||
|
return documents;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Using this query function in a React component looks like:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const data = useQuery(api.myFunctions.myQueryFunction, {
|
||||||
|
first: 10,
|
||||||
|
second: "hello",
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
A mutation function looks like:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// convex/myFunctions.ts
|
||||||
|
import { mutation } from "./_generated/server";
|
||||||
|
import { v } from "convex/values";
|
||||||
|
|
||||||
|
export const myMutationFunction = mutation({
|
||||||
|
// Validators for arguments.
|
||||||
|
args: {
|
||||||
|
first: v.string(),
|
||||||
|
second: v.string(),
|
||||||
|
},
|
||||||
|
|
||||||
|
// Function implementation.
|
||||||
|
handler: async (ctx, args) => {
|
||||||
|
// Insert or modify documents in the database here.
|
||||||
|
// Mutations can also read from the database like queries.
|
||||||
|
// See https://docs.convex.dev/database/writing-data.
|
||||||
|
const message = { body: args.first, author: args.second };
|
||||||
|
const id = await ctx.db.insert("messages", message);
|
||||||
|
|
||||||
|
// Optionally, return a value from your mutation.
|
||||||
|
return await ctx.db.get(id);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Using this mutation function in a React component looks like:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const mutation = useMutation(api.myFunctions.myMutationFunction);
|
||||||
|
function handleButtonPress() {
|
||||||
|
// fire and forget, the most common way to use mutations
|
||||||
|
mutation({ first: "Hello!", second: "me" });
|
||||||
|
// OR
|
||||||
|
// use the result once the mutation has completed
|
||||||
|
mutation({ first: "Hello!", second: "me" }).then((result) =>
|
||||||
|
console.log(result),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the Convex CLI to push your functions to a deployment. See everything
|
||||||
|
the Convex CLI can do by running `npx convex -h` in your project root
|
||||||
|
directory. To learn more, launch the docs with `npx convex docs`.
|
||||||
2
packages/convex/_generated/api.d.ts
vendored
2
packages/convex/_generated/api.d.ts
vendored
@@ -13,6 +13,7 @@ import type {
|
|||||||
FilterApi,
|
FilterApi,
|
||||||
FunctionReference,
|
FunctionReference,
|
||||||
} from "convex/server";
|
} from "convex/server";
|
||||||
|
import type * as admin from "../admin.js";
|
||||||
import type * as files from "../files.js";
|
import type * as files from "../files.js";
|
||||||
import type * as filesystem from "../filesystem.js";
|
import type * as filesystem from "../filesystem.js";
|
||||||
import type * as functions from "../functions.js";
|
import type * as functions from "../functions.js";
|
||||||
@@ -32,6 +33,7 @@ import type * as users from "../users.js";
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
declare const fullApi: ApiFromModules<{
|
declare const fullApi: ApiFromModules<{
|
||||||
|
admin: typeof admin;
|
||||||
files: typeof files;
|
files: typeof files;
|
||||||
filesystem: typeof filesystem;
|
filesystem: typeof filesystem;
|
||||||
functions: typeof functions;
|
functions: typeof functions;
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export const saveFile = authenticatedMutation({
|
|||||||
mimeType: v.optional(v.string()),
|
mimeType: v.optional(v.string()),
|
||||||
},
|
},
|
||||||
handler: async (ctx, { name, storageId, directoryId, size, mimeType }) => {
|
handler: async (ctx, { name, storageId, directoryId, size, mimeType }) => {
|
||||||
const now = new Date().toISOString()
|
const now = Date.now()
|
||||||
|
|
||||||
await ctx.db.insert("files", {
|
await ctx.db.insert("files", {
|
||||||
name,
|
name,
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export const moveToTrash = authenticatedMutation({
|
|||||||
case FileType.File:
|
case FileType.File:
|
||||||
return ctx.db
|
return ctx.db
|
||||||
.patch(handle.id, {
|
.patch(handle.id, {
|
||||||
deletedAt: new Date().toISOString(),
|
deletedAt: Date.now(),
|
||||||
})
|
})
|
||||||
.then(() => handle)
|
.then(() => handle)
|
||||||
case FileType.Directory:
|
case FileType.Directory:
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ export async function create(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const now = new Date().toISOString()
|
const now = Date.now()
|
||||||
return await ctx.db.insert("directories", {
|
return await ctx.db.insert("directories", {
|
||||||
name,
|
name,
|
||||||
parentId,
|
parentId,
|
||||||
@@ -216,7 +216,7 @@ export async function move(
|
|||||||
ignoredHandles.add(handle)
|
ignoredHandles.add(handle)
|
||||||
} else {
|
} else {
|
||||||
promises.push(
|
promises.push(
|
||||||
ctx.db.patch(handle.id, { parentId: targetDirectory.id }),
|
ctx.db.patch(handle.id, { parentId: targetDirectory.id, updatedAt: Date.now() }),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -239,7 +239,7 @@ export async function moveToTrashRecursive(
|
|||||||
ctx: AuthenticatedMutationCtx,
|
ctx: AuthenticatedMutationCtx,
|
||||||
handle: DirectoryHandle,
|
handle: DirectoryHandle,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const now = new Date().toISOString()
|
const now = Date.now()
|
||||||
|
|
||||||
const filesToDelete: Id<"files">[] = []
|
const filesToDelete: Id<"files">[] = []
|
||||||
const directoriesToDelete: Id<"directories">[] = []
|
const directoriesToDelete: Id<"directories">[] = []
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export async function renameFile(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
await ctx.db.patch(itemId, { name: newName })
|
await ctx.db.patch(itemId, { name: newName, updatedAt: Date.now() })
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function move(
|
export async function move(
|
||||||
@@ -90,7 +90,7 @@ export async function move(
|
|||||||
|
|
||||||
const results = await Promise.allSettled(
|
const results = await Promise.allSettled(
|
||||||
okFiles.map((handle) =>
|
okFiles.map((handle) =>
|
||||||
ctx.db.patch(handle.id, { directoryId: targetDirectoryHandle.id }),
|
ctx.db.patch(handle.id, { directoryId: targetDirectoryHandle.id, updatedAt: Date.now() }),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export async function userOrThrow(ctx: QueryCtx | MutationCtx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function register(ctx: AuthenticatedMutationCtx) {
|
export async function register(ctx: AuthenticatedMutationCtx) {
|
||||||
const now = new Date().toISOString()
|
const now = Date.now()
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
ctx.db.insert("users", {
|
ctx.db.insert("users", {
|
||||||
jwtSubject: ctx.identity.subject,
|
jwtSubject: ctx.identity.subject,
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ const schema = defineSchema({
|
|||||||
name: v.string(),
|
name: v.string(),
|
||||||
size: v.number(),
|
size: v.number(),
|
||||||
mimeType: v.optional(v.string()),
|
mimeType: v.optional(v.string()),
|
||||||
createdAt: v.string(),
|
createdAt: v.number(),
|
||||||
updatedAt: v.string(),
|
updatedAt: v.number(),
|
||||||
deletedAt: v.optional(v.string()),
|
deletedAt: v.optional(v.number()),
|
||||||
})
|
})
|
||||||
.index("byDirectoryId", ["userId", "directoryId", "deletedAt"])
|
.index("byDirectoryId", ["userId", "directoryId", "deletedAt"])
|
||||||
.index("byUserId", ["userId", "deletedAt"])
|
.index("byUserId", ["userId", "deletedAt"])
|
||||||
@@ -29,9 +29,9 @@ const schema = defineSchema({
|
|||||||
name: v.string(),
|
name: v.string(),
|
||||||
userId: v.id("users"),
|
userId: v.id("users"),
|
||||||
parentId: v.optional(v.id("directories")),
|
parentId: v.optional(v.id("directories")),
|
||||||
createdAt: v.string(),
|
createdAt: v.number(),
|
||||||
updatedAt: v.string(),
|
updatedAt: v.number(),
|
||||||
deletedAt: v.optional(v.string()),
|
deletedAt: v.optional(v.number()),
|
||||||
})
|
})
|
||||||
.index("byUserId", ["userId", "deletedAt"])
|
.index("byUserId", ["userId", "deletedAt"])
|
||||||
.index("byParentId", ["userId", "parentId", "deletedAt"])
|
.index("byParentId", ["userId", "parentId", "deletedAt"])
|
||||||
|
|||||||
25
packages/convex/tsconfig.json
Normal file
25
packages/convex/tsconfig.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
/* This TypeScript project config describes the environment that
|
||||||
|
* Convex functions run in and is used to typecheck them.
|
||||||
|
* You can modify it, but some settings are required to use Convex.
|
||||||
|
*/
|
||||||
|
"compilerOptions": {
|
||||||
|
/* These settings are not required by Convex and can be modified. */
|
||||||
|
"allowJs": true,
|
||||||
|
"strict": true,
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
|
||||||
|
/* These compiler options are required by Convex */
|
||||||
|
"target": "ESNext",
|
||||||
|
"lib": ["ES2021", "dom"],
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noEmit": true
|
||||||
|
},
|
||||||
|
"include": ["./**/*"],
|
||||||
|
"exclude": ["./_generated"]
|
||||||
|
}
|
||||||
@@ -19,7 +19,6 @@ function RouteComponent() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isLoadingConvexAuth && isAuthenticated && !isSyncingUser) {
|
if (!isLoadingConvexAuth && isAuthenticated && !isSyncingUser) {
|
||||||
console.log({ isLoadingConvexAuth, isAuthenticated, isSyncingUser })
|
|
||||||
syncUser(undefined, {
|
syncUser(undefined, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
navigate({
|
navigate({
|
||||||
|
|||||||
Reference in New Issue
Block a user