Skip to content

Commit

Permalink
Merge pull request #1865 from undb-io/release/v1.0.0-5
Browse files Browse the repository at this point in the history
Release version v1.0.0-5
  • Loading branch information
nichenqin authored Aug 10, 2024
2 parents 5663637 + bb83125 commit cafcbd7
Show file tree
Hide file tree
Showing 115 changed files with 1,367 additions and 571 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
# Changelog


## v1.0.0-5


### 🩹 Fixes

- Fix on value change ([07adf8e](https://github.com/undb-io/undb/commit/07adf8e))

### ❤️ Contributors

- Nichenqin ([@nichenqin](http://github.com/nichenqin))

## v1.0.0-4


Expand Down
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,21 @@ UNDB is a no-code platform that can also serve as a Backend as a Service (BaaS).

- ⚡ No-code platform, easy to use
- 🗄️ Based on SQLite, a lightweight database
- 🔐 Private and local first
- 📦 Can be packaged into a binary file using Bun
- 🪜 Progressive deployment, from local in single file to cloud complicated stacks.
- 🐳 Supports Docker deployment
- 🛠️ Provides a UI for table management

## Quick start

```bash
docker run -p 3721:3721 ghcr.io/undb-io/undb:v1.0.0-1
docker run -p 3721:3721 ghcr.io/undb-io/undb:latest
```

## Installation and Usage
## Development

### Docker compose development

```bash
docker compose up -d
```

then visit `http://localhost:3721`

### Prerequisites

- [Bun](https://bun.sh) - Bun is a fast JavaScript runtime and package manager

### Local Development
### Local Development (Recommended)

1. **Install Bun**

Expand All @@ -64,6 +54,16 @@ then visit `http://localhost:3721`
bun run dev
```

### Docker compose development

```bash
docker compose up -d
```

then visit `http://localhost:3721`

## Build

### Packaging into a Binary File

1. **Build**
Expand Down
1 change: 1 addition & 0 deletions apps/backend/src/modules/auth/auth.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const createLuciaWithAdapter = (adapter: Adapter) => {
sessionCookie: {
attributes: {
secure: Bun.env.NODE_ENV === "PRODUCTION", // set `Secure` flag in HTTPS
domain: Bun.env.UNDB_COOKIE_DOMAIN,
},
},
getSessionAttributes: (attributes) => {
Expand Down
10 changes: 7 additions & 3 deletions apps/backend/src/modules/auth/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,14 @@ export class Auth {
emailVerified: user!.emailVerified,
avatar: user!.avatar,
})

const m = member ? { role: member.role, spaceId: member.spaceId } : null
setContextValue("member", m)

return {
user,
session,
member: member ? { role: member.role, spaceId: member.spaceId } : null,
member: m,
}
}
}
Expand Down Expand Up @@ -236,7 +240,7 @@ export class Auth {
})
.execute()

const space = await this.spaceService.createPersonalSpace(username!)
const space = await this.spaceService.createSpace({ name: username! })
await this.spaceMemberService.createMember(userId, space.id.value, "owner")
if (invitation.isSome()) {
await this.spaceMemberService.createMember(
Expand Down Expand Up @@ -309,7 +313,7 @@ export class Auth {
let space = await this.spaceService.getSpace({ userId: user.id })
if (space.isSome()) {
} else {
space = Some(await this.spaceService.createPersonalSpace(user.username))
space = Some(await this.spaceService.createSpace({ name: user.username }))
await this.spaceMemberService.createMember(user.id, space.unwrap().id.value, "owner")
}
const session = await this.lucia.createSession(user.id, { space_id: space.unwrap().id.value })
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/modules/auth/oauth/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export class GithubOAuth {
provider_user_id: githubUserResult.id.toString(),
})
.execute()
const space = await this.spaceService.createPersonalSpace(githubUserResult.login)
const space = await this.spaceService.createSpace({ name: githubUserResult.login })
await this.spaceMemberService.createMember(userId, space.id.value, "owner")

return space
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/modules/auth/oauth/google.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export class GoogleOAuth {
provider_user_id: googleUserResult.id.toString(),
})
.execute()
const space = await this.spaceService.createPersonalSpace(googleUserResult.name)
const space = await this.spaceService.createSpace({ name: googleUserResult.name })
await this.spaceMemberService.createMember(userId, space.id.value, "owner")

return space
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { injectSpaceMemberService, type ISpaceMemberService } from "@undb/authz"
import { type IBaseRepository, injectBaseRepository } from "@undb/base"
import {
BulkDeleteRecordsCommand,
BulkDuplicateRecordsCommand,
Expand All @@ -8,28 +10,26 @@ import {
DuplicateRecordCommand,
UpdateRecordCommand,
} from "@undb/commands"
import { executionContext, getCurrentUser, getCurrentUserId, setContextValue } from "@undb/context/server"
import { executionContext, getCurrentUserId, setContextValue } from "@undb/context/server"
import { CommandBus, QueryBus } from "@undb/cqrs"
import { inject, singleton } from "@undb/di"
import { type ICommandBus, None, PaginatedDTO, type IQueryBus, Some } from "@undb/domain"
import { type ICommandBus, type IQueryBus, None, PaginatedDTO, Some } from "@undb/domain"
import { createLogger } from "@undb/logger"
import { API_TOKEN_HEADER_NAME, createOpenApiSpec, type IApiTokenService, injectApiTokenService } from "@undb/openapi"
import { injectQueryBuilder, type IQueryBuilder } from "@undb/persistence"
import { GetReadableRecordByIdQuery, GetReadableRecordsQuery } from "@undb/queries"
import { injectSpaceService, type ISpaceService } from "@undb/space"
import {
injectRecordRepository,
injectTableRepository,
withUniqueTable,
type IRecordReadableValueDTO,
type IRecordRepository,
type ITableRepository,
withUniqueTable,
} from "@undb/table"
import { injectUserService, type IUserService } from "@undb/user"
import Elysia, { t } from "elysia"
import { withTransaction } from "../../db"
import { type IBaseRepository, injectBaseRepository } from "@undb/base"
import { injectUserService, type IUserService } from "@undb/user"
import { injectSpaceMemberService, type ISpaceMemberService } from "@undb/authz"
import { injectSpaceService, type ISpaceService } from "@undb/space"

@singleton()
export class OpenAPI {
Expand Down
44 changes: 27 additions & 17 deletions apps/backend/src/modules/space/space.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { checkPermission } from "@undb/authz"
import { DeleteSpaceCommand } from "@undb/commands"
import { getCurrentUserId } from "@undb/context/server"
import { getCurrentMember, getCurrentUserId } from "@undb/context/server"
import { CommandBus } from "@undb/cqrs"
import { inject, singleton } from "@undb/di"
import { injectQueryBuilder, type IQueryBuilder } from "@undb/persistence"
Expand Down Expand Up @@ -59,25 +60,34 @@ export class SpaceModule {
}),
},
)
.delete("/api/space", async (ctx) => {
return withTransaction(this.qb)(async () => {
await this.commandBus.execute(new DeleteSpaceCommand({}))
.delete(
"/api/space",
async (ctx) => {
return withTransaction(this.qb)(async () => {
await this.commandBus.execute(new DeleteSpaceCommand({}))

const userId = getCurrentUserId()
const userId = getCurrentUserId()

await this.lucia.invalidateSession(userId)
const space = (await this.spaceService.getSpace({ userId })).expect("Space not found")
await this.lucia.invalidateSession(userId)
const space = (await this.spaceService.getSpace({ userId })).expect("Space not found")

const updatedSession = await this.lucia.createSession(userId, { space_id: space.id.value })
const sessionCookie = this.lucia.createSessionCookie(updatedSession.id)
return new Response(null, {
status: 200,
headers: {
Location: "/",
"Set-Cookie": sessionCookie.serialize(),
},
const updatedSession = await this.lucia.createSession(userId, { space_id: space.id.value })
const sessionCookie = this.lucia.createSessionCookie(updatedSession.id)
return new Response(null, {
status: 200,
headers: {
Location: "/",
"Set-Cookie": sessionCookie.serialize(),
},
})
})
})
})
},
{
beforeHandle(context) {
const role = getCurrentMember().role
checkPermission(role, ["space:delete"])
},
},
)
}
}
1 change: 1 addition & 0 deletions apps/frontend/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ enum FieldType {
string
updatedAt
updatedBy
url
user
}

Expand Down
48 changes: 25 additions & 23 deletions apps/frontend/src/lib/components/blocks/base/base-detail.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,38 @@
import { DatabaseIcon, ImportIcon, PlusCircleIcon, PlusIcon } from "lucide-svelte"
import * as Table from "$lib/components/ui/table"
import { goto } from "$app/navigation"
import { page } from "$app/stores"
import { hasPermission } from "$lib/store/space-member.store"
export let base: GetBaseQuery$result["base"]
</script>

<main class="h-full flex-1 px-4 py-4">
<div class="flex items-center gap-4">
<button
type="button"
class="flex h-32 w-80 flex-col justify-between rounded-lg bg-gray-100 px-4 py-7 text-left transition-all hover:bg-gray-200/50 hover:shadow-lg"
on:click={() => {
toggleModal(CREATE_TABLE_MODAL)
}}
>
<PlusCircleIcon class="text-muted-foreground" />
{#if $hasPermission("table:create")}
<div class="flex items-center gap-4">
<button
type="button"
class="flex h-32 w-80 flex-col justify-between rounded-lg border bg-gray-100 px-4 py-7 text-left transition-all hover:bg-gray-200/50 hover:shadow-lg"
on:click={() => {
toggleModal(CREATE_TABLE_MODAL)
}}
>
<PlusCircleIcon class="text-muted-foreground" />

Create New Table
</button>
<button
type="button"
class="flex h-32 w-80 flex-col justify-between rounded-lg bg-gray-100 px-4 py-7 text-left transition-all hover:bg-gray-200/50 hover:shadow-lg"
on:click={() => {
toggleModal(IMPORT_TABLE_MODAL)
}}
>
<ImportIcon class="text-muted-foreground" />
Create New Table
</button>
<button
type="button"
class="flex h-32 w-80 flex-col justify-between rounded-lg border bg-gray-100 px-4 py-7 text-left transition-all hover:bg-gray-200/50 hover:shadow-lg"
on:click={() => {
toggleModal(IMPORT_TABLE_MODAL)
}}
>
<ImportIcon class="text-muted-foreground" />

Import Table
</button>
</div>
Import Table
</button>
</div>
{/if}

<section class="pt-3">
<h3 class="text-xl font-normal text-gray-600">Tables</h3>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { Button } from "$lib/components/ui/button"
import { CREATE_BASE_MODAL, toggleModal } from "$lib/store/modal.store"
import { hasPermission } from "$lib/store/workspace-member.store"
import { hasPermission } from "$lib/store/space-member.store"
</script>

{#if $hasPermission("base:create")}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@
import * as Sheet from "$lib/components/ui/sheet"
import { PencilIcon } from "lucide-svelte"
import BulkUpdateRecords from "./bulk-update-records.svelte"
import { hasPermission } from "$lib/store/space-member.store"
let open = false
</script>

<Sheet.Root bind:open>
<Sheet.Trigger asChild let:builder>
<Button size="sm" variant="outline" builders={[builder]}>
<PencilIcon class="mr-2 h-3 w-3" />
Bulk Update
</Button>
</Sheet.Trigger>
<Sheet.Content class="sm:max-w-1/2 flex h-full w-2/3 flex-col gap-0 px-0 pb-0 pt-4 transition-all">
<Sheet.Header class="border-b px-4 pb-4">
<Sheet.Title>Bulk Update Records</Sheet.Title>
</Sheet.Header>
{#if $hasPermission("record:update")}
<Sheet.Root bind:open>
<Sheet.Trigger asChild let:builder>
<Button size="sm" variant="outline" builders={[builder]}>
<PencilIcon class="mr-2 h-3 w-3" />
Bulk Update
</Button>
</Sheet.Trigger>
<Sheet.Content class="sm:max-w-1/2 flex h-full w-2/3 flex-col gap-0 px-0 pb-0 pt-4 transition-all">
<Sheet.Header class="border-b px-4 pb-4">
<Sheet.Title>Bulk Update Records</Sheet.Title>
</Sheet.Header>

<BulkUpdateRecords onSuccess={() => (open = false)} />
</Sheet.Content>
</Sheet.Root>
<BulkUpdateRecords onSuccess={() => (open = false)} />
</Sheet.Content>
</Sheet.Root>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { toast } from "svelte-sonner"
import { CREATE_BASE_MODAL, closeModal } from "$lib/store/modal.store"
import { goto } from "$app/navigation"
import { LoaderCircleIcon } from "lucide-svelte"
const mutation = createMutation({
mutationFn: trpc.base.create.mutate,
Expand Down Expand Up @@ -36,6 +37,7 @@
dataType: "json",
validators: zodClient(schema),
resetForm: false,
delayMs: 200,
invalidateAll: true,
onUpdate(event) {
if (!event.form.valid) return
Expand All @@ -45,7 +47,7 @@
},
)
const { form: formData, enhance } = form
const { form: formData, enhance, delayed } = form
</script>

<form id="createTable" class="space-y-2 px-1" method="POST" use:enhance>
Expand All @@ -61,7 +63,12 @@
<Form.FormButton type="button" variant="secondary" on:click={() => closeModal(CREATE_BASE_MODAL)}>
Cancel
</Form.FormButton>
<Form.FormButton>Create</Form.FormButton>
<Form.FormButton>
{#if $delayed}
<LoaderCircleIcon class="mr-2 h-5 w-5 animate-spin" />
{/if}
Create
</Form.FormButton>
</div>
</form>

Expand Down
Loading

0 comments on commit cafcbd7

Please sign in to comment.