diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 6035c7cb9d2e9..5f8d7ea601259 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,11 +1,11 @@ name: Bug Report -description: Create a report to help us improve +description: If something isn't working as expected labels: [bug] body: - type: markdown attributes: value: | - If you are reporting a new issue, make sure that we do not have any duplicates already open. You can ensure this by searching the issue list for this repository. If there is a duplicate, please close your issue and add a comment to the existing issue instead. + Before submitting a bug report, please check if the issue is already present in the issues. If it is, please add a reaction to the issue. If it isn't, please fill out the form below. - type: textarea attributes: label: Describe the bug @@ -24,8 +24,15 @@ body: 3. See error validations: required: true + - type: input + attributes: + label: The version of Memos you're using + description: | + Provide the version of Memos you're using. + validations: + required: true - type: textarea attributes: label: Screenshots or additional context description: | - Add screenshots or any other context about the problem. + If applicable, add screenshots to help explain your problem. And add any other context about the problem here. Such as the device you're using, etc. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index e9298d19a669a..6a312f56de644 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,28 +1,36 @@ name: Feature Request -description: Suggest an idea for this project +description: If you have a suggestion for a new feature labels: [enhancement] body: - type: markdown attributes: value: | - Thanks for taking the time to suggest an idea for memos! + Before submitting a feature request, please check if the issue is already present in the issues. If it is, please add a reaction to the issue. If it isn't, please fill out the form below. - type: textarea attributes: - label: Is your feature request related to a problem? + label: Describe the solution you'd like description: | - A clear and concise description of what the problem is. + A clear and concise description of what you want to happen. placeholder: | - I'm always frustrated when [...] + It would be great if [...] validations: required: true - - type: textarea + - type: dropdown attributes: - label: Describe the solution you'd like - description: | - A clear and concise description of what you want to happen. + label: Type of feature + description: What type of feature is this? + options: + - User Interface (UI) + - User Experience (UX) + - API + - Documentation + - Integrations + - Other + default: 0 validations: required: true - type: textarea attributes: label: Additional context - description: Add any other context or screenshots about the feature request. + description: | + What are you trying to do? Why is this important to you? diff --git a/.github/workflows/backend-tests.yml b/.github/workflows/backend-tests.yml index 01a50d6f4feda..0573d9c3a9e3b 100644 --- a/.github/workflows/backend-tests.yml +++ b/.github/workflows/backend-tests.yml @@ -17,14 +17,14 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: - go-version: 1.21 + go-version: 1.22 check-latest: true cache: true - name: Verify go.mod is tidy run: | - go mod tidy -go=1.21 + go mod tidy -go=1.22 git diff --exit-code - name: golangci-lint uses: golangci/golangci-lint-action@v3 @@ -37,9 +37,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: - go-version: 1.21 + go-version: 1.22 check-latest: true cache: true - name: Run all tests diff --git a/.github/workflows/build-and-push-release-image.yml b/.github/workflows/build-and-push-release-image.yml index 4fba97afd5bb1..ddb04ca2acaa5 100644 --- a/.github/workflows/build-and-push-release-image.yml +++ b/.github/workflows/build-and-push-release-image.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up QEMU - uses: docker/setup-qemu-action@v2 + uses: docker/setup-qemu-action@v3 - name: Extract build args # Extract version from branch name @@ -25,13 +25,13 @@ jobs: echo "VERSION=${GITHUB_REF_NAME#release/}" >> $GITHUB_ENV - name: Login to Docker Hub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: neosmemo password: ${{ secrets.DOCKER_NEOSMEMO_TOKEN }} - name: Login to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} @@ -39,26 +39,25 @@ jobs: - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v3 with: install: true version: v0.9.1 - name: Docker meta id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@v5 with: images: | neosmemo/memos ghcr.io/usememos/memos tags: | - type=raw,value=latest type=semver,pattern={{version}},value=${{ env.VERSION }} type=semver,pattern={{major}}.{{minor}},value=${{ env.VERSION }} - name: Build and Push id: docker_build - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v5 with: context: ./ file: ./Dockerfile diff --git a/.github/workflows/build-and-push-stable-image.yml b/.github/workflows/build-and-push-stable-image.yml new file mode 100644 index 0000000000000..3c399563790e6 --- /dev/null +++ b/.github/workflows/build-and-push-stable-image.yml @@ -0,0 +1,61 @@ +name: build-and-push-stable-image + +on: + push: + branches: + - "stable" + +jobs: + build-and-push-release-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: neosmemo + password: ${{ secrets.DOCKER_NEOSMEMO_TOKEN }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3 + with: + install: true + version: v0.9.1 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + neosmemo/memos + ghcr.io/usememos/memos + tags: | + type=raw,value=stable + flavor: | + latest=true + + - name: Build and Push + id: docker_build + uses: docker/build-push-action@v5 + with: + context: ./ + file: ./Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/build-and-push-test-image.yml b/.github/workflows/build-and-push-test-image.yml new file mode 100644 index 0000000000000..419dec832fa04 --- /dev/null +++ b/.github/workflows/build-and-push-test-image.yml @@ -0,0 +1,60 @@ +name: build-and-push-test-image + +on: + push: + branches: [main] + +jobs: + build-and-push-test-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: neosmemo + password: ${{ secrets.DOCKER_NEOSMEMO_TOKEN }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3 + with: + install: true + version: v0.9.1 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + neosmemo/memos + ghcr.io/usememos/memos + flavor: | + latest=false + tags: | + type=raw,value=test + + - name: Build and Push + id: docker_build + uses: docker/build-push-action@v5 + with: + context: ./ + file: ./Dockerfile + platforms: linux/amd64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index f5d57eaed2ddd..0000000000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,74 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [main] - pull_request: - # The branches below must be a subset of the branches above - branches: [main] - paths: - - "go.mod" - - "go.sum" - - "**.go" - - "proto/**" - - "web/**" - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: ["go", "javascript"] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Learn more about CodeQL language support at https://git.io/codeql-language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/frontend-tests.yml b/.github/workflows/frontend-tests.yml new file mode 100644 index 0000000000000..af4f5dcb8c3ed --- /dev/null +++ b/.github/workflows/frontend-tests.yml @@ -0,0 +1,48 @@ +name: Frontend Test + +on: + push: + branches: [main] + pull_request: + branches: + - main + - "release/*.*.*" + paths: + - "web/**" + +jobs: + eslint-checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v2.4.0 + with: + version: 8 + - uses: actions/setup-node@v4 + with: + node-version: "20" + cache: pnpm + cache-dependency-path: "web/pnpm-lock.yaml" + - run: pnpm install + working-directory: web + - name: Run eslint check + run: pnpm lint + working-directory: web + + frontend-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v2.4.0 + with: + version: 8 + - uses: actions/setup-node@v4 + with: + node-version: "20" + cache: pnpm + cache-dependency-path: "web/pnpm-lock.yaml" + - run: pnpm install + working-directory: web + - name: Run frontend build + run: pnpm build + working-directory: web diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000000000..f787269dbf50d --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,17 @@ +name: Close Stale Issues + +on: + schedule: + - cron: "0 */8 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + permissions: + issues: write + + steps: + - uses: actions/stale@v9.0.0 + with: + days-before-issue-stale: 14 + days-before-issue-close: 7 diff --git a/.gitignore b/.gitignore index 240621df1419b..17f64ee21ad8a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ tmp # Frontend asset web/dist -server/dist +server/frontend/dist # build folder build @@ -16,4 +16,9 @@ build # Jetbrains .idea +# Docker Compose Environment File +.env + bin/air + +dev-dist diff --git a/.golangci.yaml b/.golangci.yaml index 0c1ba43265965..31aac66c2df25 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -67,6 +67,14 @@ linters-settings: disabled: true - name: early-return disabled: true + - name: use-any + disabled: true + - name: exported + disabled: true + - name: unhandled-error + disabled: true + - name: if-return + disabled: true gocritic: disabled-checks: - ifElseChain diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 12a59cb012e3e..0000000000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "recommendations": ["golang.go"] -} diff --git a/.vscode/project.code-workspace b/.vscode/project.code-workspace deleted file mode 100644 index b27ee896d466d..0000000000000 --- a/.vscode/project.code-workspace +++ /dev/null @@ -1,12 +0,0 @@ -{ - "folders": [ - { - "name": "server", - "path": "../" - }, - { - "name": "web", - "path": "../web" - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index bf4a44ad73aff..0000000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "json.schemaDownload.enable":true, - "go.lintOnSave": "workspace", - "go.lintTool": "golangci-lint", -} diff --git a/Dockerfile b/Dockerfile index 0a5e3d34cc624..effaa8a6e068a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,18 +6,17 @@ COPY . . WORKDIR /frontend-build/web -RUN corepack enable && pnpm i --frozen-lockfile && pnpm type-gen +RUN corepack enable && pnpm i --frozen-lockfile RUN pnpm build # Build backend exec file. -FROM golang:1.21-alpine AS backend +FROM golang:1.22-alpine AS backend WORKDIR /backend-build COPY . . -COPY --from=frontend /frontend-build/web/dist ./server/dist -RUN CGO_ENABLED=0 go build -o memos ./main.go +RUN CGO_ENABLED=0 go build -o memos ./bin/memos/main.go # Make workspace with above generated files. FROM whatwewant/alpine:v3.17-1 AS monolithic @@ -26,6 +25,7 @@ WORKDIR /usr/local/memos RUN apk add --no-cache tzdata ENV TZ="UTC" +COPY --from=frontend /frontend-build/web/dist /usr/local/memos/dist COPY --from=backend /backend-build/memos /usr/local/memos/ EXPOSE 5230 diff --git a/README.md b/README.md index 20f3524607d59..3136668381498 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ -# memos - -✍️ memos +Memos A privacy-first, lightweight note-taking service. Easily capture and share your great thoughts. @@ -10,13 +8,11 @@ A privacy-first, lightweight note-taking service. Easily capture and share your Live Demo

- GitHub stars Docker pull - Translation status Discord

-![demo](https://www.usememos.com/demo.webp) +![demo](https://www.usememos.com/demo.png) ## Key points @@ -29,7 +25,7 @@ A privacy-first, lightweight note-taking service. Easily capture and share your ## Deploy with Docker in seconds ```bash -docker run -d --name memos -p 5230:5230 -v ~/.memos/:/var/opt/memos ghcr.io/usememos/memos:latest +docker run -d --name memos -p 5230:5230 -v ~/.memos/:/var/opt/memos neosmemo/memos:stable ``` > The `~/.memos/` directory will be used as the data directory on your local machine, while `/var/opt/memos` is the directory of the volume in Docker and should not be modified. @@ -41,23 +37,22 @@ Learn more about [other installation methods](https://www.usememos.com/docs/inst Contributions are what make the open-source community such an amazing place to learn, inspire, and create. We greatly appreciate any contributions you make. Thank you for being a part of our community! 🥰 - + ---- +## Internationalization + +Memos supports multiple languages. You can help us translate Memos into your language. We use Weblate to manage translations. -- [Moe Memos](https://memos.moe/) - Third party client for iOS and Android -- [lmm214/memos-bber](https://github.com/lmm214/memos-bber) - Chrome extension -- [Rabithua/memos_wmp](https://github.com/Rabithua/memos_wmp) - WeChat MiniProgram -- [qazxcdswe123/telegramMemoBot](https://github.com/qazxcdswe123/telegramMemoBot) - Telegram bot -- [eallion/memos.top](https://github.com/eallion/memos.top) - Static page rendered with the Memos API -- [eindex/logseq-memos-sync](https://github.com/EINDEX/logseq-memos-sync) - Logseq plugin -- [JakeLaoyu/memos-import-from-flomo](https://github.com/JakeLaoyu/memos-import-from-flomo) - Import data. Support from flomo, wechat reading -- [Quick Memo](https://www.icloud.com/shortcuts/1eaef307112843ed9f91d256f5ee7ad9) - Shortcuts (iOS, iPadOS or macOS) -- [Memos Raycast Extension](https://www.raycast.com/JakeYu/memos) - Raycast extension -- [Memos Desktop](https://github.com/xudaolong/memos-desktop) - Third party client for MacOS and Windows -- [MemosGallery](https://github.com/BarryYangi/MemosGallery) - A static Gallery rendered with the Memos API + +Translation status + ## Star history [![Star History Chart](https://api.star-history.com/svg?repos=usememos/memos&type=Date)](https://star-history.com/#usememos/memos&Date) + +## Other projects + +- [**Slash**](https://github.com/yourselfhosted/slash): An open source, self-hosted bookmarks and link sharing platform. Save and share your links very easily. +- [**Gomark**](https://github.com/yourselfhosted/gomark): A markdown parser written in Go for Memos. And its [WebAssembly version](https://github.com/yourselfhosted/gomark-wasm) is also available. diff --git a/SECURITY.md b/SECURITY.md index af97c79abca7d..48ab17ab2f976 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,4 +4,4 @@ Report security bugs via GitHub [issues](https://github.com/usememos/memos/issues). -For more information, please contact [stevenlgtm@gmail.com](stevenlgtm@gmail.com). +For more information, please contact [usememos@gmail.com](usememos@gmail.com). diff --git a/api/v1/rss.go b/api/v1/rss.go deleted file mode 100644 index 8d8da824d9641..0000000000000 --- a/api/v1/rss.go +++ /dev/null @@ -1,211 +0,0 @@ -package v1 - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "net/http" - "strconv" - "strings" - "time" - - "github.com/gorilla/feeds" - "github.com/labstack/echo/v4" - "github.com/pkg/errors" - "github.com/yuin/goldmark" - - "github.com/usememos/memos/internal/util" - "github.com/usememos/memos/store" -) - -const maxRSSItemCount = 100 -const maxRSSItemTitleLength = 100 - -func (s *APIV1Service) registerRSSRoutes(g *echo.Group) { - g.GET("/explore/rss.xml", s.GetExploreRSS) - g.GET("/u/:id/rss.xml", s.GetUserRSS) -} - -// GetExploreRSS godoc -// -// @Summary Get RSS -// @Tags rss -// @Produce xml -// @Success 200 {object} nil "RSS" -// @Failure 500 {object} nil "Failed to get system customized profile | Failed to find memo list | Failed to generate rss" -// @Router /explore/rss.xml [GET] -func (s *APIV1Service) GetExploreRSS(c echo.Context) error { - ctx := c.Request().Context() - systemCustomizedProfile, err := s.getSystemCustomizedProfile(ctx) - if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, "Failed to get system customized profile").SetInternal(err) - } - - normalStatus := store.Normal - memoFind := store.FindMemo{ - RowStatus: &normalStatus, - VisibilityList: []store.Visibility{store.Public}, - } - memoList, err := s.Store.ListMemos(ctx, &memoFind) - if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find memo list").SetInternal(err) - } - - baseURL := c.Scheme() + "://" + c.Request().Host - rss, err := s.generateRSSFromMemoList(ctx, memoList, baseURL, systemCustomizedProfile) - if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, "Failed to generate rss").SetInternal(err) - } - c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationXMLCharsetUTF8) - return c.String(http.StatusOK, rss) -} - -// GetUserRSS godoc -// -// @Summary Get RSS for a user -// @Tags rss -// @Produce xml -// @Param id path int true "User ID" -// @Success 200 {object} nil "RSS" -// @Failure 400 {object} nil "User id is not a number" -// @Failure 500 {object} nil "Failed to get system customized profile | Failed to find memo list | Failed to generate rss" -// @Router /u/{id}/rss.xml [GET] -func (s *APIV1Service) GetUserRSS(c echo.Context) error { - ctx := c.Request().Context() - id, err := util.ConvertStringToInt32(c.Param("id")) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, "User id is not a number").SetInternal(err) - } - - systemCustomizedProfile, err := s.getSystemCustomizedProfile(ctx) - if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, "Failed to get system customized profile").SetInternal(err) - } - - normalStatus := store.Normal - memoFind := store.FindMemo{ - CreatorID: &id, - RowStatus: &normalStatus, - VisibilityList: []store.Visibility{store.Public}, - } - memoList, err := s.Store.ListMemos(ctx, &memoFind) - if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find memo list").SetInternal(err) - } - - baseURL := c.Scheme() + "://" + c.Request().Host - rss, err := s.generateRSSFromMemoList(ctx, memoList, baseURL, systemCustomizedProfile) - if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, "Failed to generate rss").SetInternal(err) - } - c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationXMLCharsetUTF8) - return c.String(http.StatusOK, rss) -} - -func (s *APIV1Service) generateRSSFromMemoList(ctx context.Context, memoList []*store.Memo, baseURL string, profile *CustomizedProfile) (string, error) { - feed := &feeds.Feed{ - Title: profile.Name, - Link: &feeds.Link{Href: baseURL}, - Description: profile.Description, - Created: time.Now(), - } - - var itemCountLimit = util.Min(len(memoList), maxRSSItemCount) - feed.Items = make([]*feeds.Item, itemCountLimit) - for i := 0; i < itemCountLimit; i++ { - memo := memoList[i] - feed.Items[i] = &feeds.Item{ - Title: getRSSItemTitle(memo.Content), - Link: &feeds.Link{Href: baseURL + "/m/" + fmt.Sprintf("%d", memo.ID)}, - Description: getRSSItemDescription(memo.Content), - Created: time.Unix(memo.CreatedTs, 0), - Enclosure: &feeds.Enclosure{Url: baseURL + "/m/" + fmt.Sprintf("%d", memo.ID) + "/image"}, - } - if len(memo.ResourceIDList) > 0 { - resourceID := memo.ResourceIDList[0] - resource, err := s.Store.GetResource(ctx, &store.FindResource{ - ID: &resourceID, - }) - if err != nil { - return "", err - } - if resource == nil { - return "", errors.Errorf("Resource not found: %d", resourceID) - } - enclosure := feeds.Enclosure{} - if resource.ExternalLink != "" { - enclosure.Url = resource.ExternalLink - } else { - enclosure.Url = baseURL + "/o/r/" + fmt.Sprintf("%d", resource.ID) - } - enclosure.Length = strconv.Itoa(int(resource.Size)) - enclosure.Type = resource.Type - feed.Items[i].Enclosure = &enclosure - } - } - - rss, err := feed.ToRss() - if err != nil { - return "", err - } - return rss, nil -} - -func (s *APIV1Service) getSystemCustomizedProfile(ctx context.Context) (*CustomizedProfile, error) { - systemSetting, err := s.Store.GetSystemSetting(ctx, &store.FindSystemSetting{ - Name: SystemSettingCustomizedProfileName.String(), - }) - if err != nil { - return nil, err - } - customizedProfile := &CustomizedProfile{ - Name: "memos", - LogoURL: "", - Description: "", - Locale: "en", - Appearance: "system", - ExternalURL: "", - } - if systemSetting != nil { - if err := json.Unmarshal([]byte(systemSetting.Value), customizedProfile); err != nil { - return nil, err - } - } - return customizedProfile, nil -} - -func getRSSItemTitle(content string) string { - var title string - if isTitleDefined(content) { - title = strings.Split(content, "\n")[0][2:] - } else { - title = strings.Split(content, "\n")[0] - var titleLengthLimit = util.Min(len(title), maxRSSItemTitleLength) - if titleLengthLimit < len(title) { - title = title[:titleLengthLimit] + "..." - } - } - return title -} - -func getRSSItemDescription(content string) string { - var description string - if isTitleDefined(content) { - var firstLineEnd = strings.Index(content, "\n") - description = strings.Trim(content[firstLineEnd+1:], " ") - } else { - description = content - } - - // TODO: use our `./plugin/gomark` parser to handle markdown-like content. - var buf bytes.Buffer - if err := goldmark.Convert([]byte(description), &buf); err != nil { - panic(err) - } - return buf.String() -} - -func isTitleDefined(content string) bool { - return strings.HasPrefix(content, "# ") -} diff --git a/api/v1/user_setting.go b/api/v1/user_setting.go deleted file mode 100644 index 52ae45803cbb6..0000000000000 --- a/api/v1/user_setting.go +++ /dev/null @@ -1,174 +0,0 @@ -package v1 - -import ( - "encoding/json" - "net/http" - - "github.com/labstack/echo/v4" - "github.com/pkg/errors" - "golang.org/x/exp/slices" - - "github.com/usememos/memos/store" -) - -type UserSettingKey string - -const ( - // UserSettingLocaleKey is the key type for user locale. - UserSettingLocaleKey UserSettingKey = "locale" - // UserSettingAppearanceKey is the key type for user appearance. - UserSettingAppearanceKey UserSettingKey = "appearance" - // UserSettingMemoVisibilityKey is the key type for user preference memo default visibility. - UserSettingMemoVisibilityKey UserSettingKey = "memo-visibility" - // UserSettingTelegramUserIDKey is the key type for telegram UserID of memos user. - UserSettingTelegramUserIDKey UserSettingKey = "telegram-user-id" -) - -// String returns the string format of UserSettingKey type. -func (key UserSettingKey) String() string { - switch key { - case UserSettingLocaleKey: - return "locale" - case UserSettingAppearanceKey: - return "appearance" - case UserSettingMemoVisibilityKey: - return "memo-visibility" - case UserSettingTelegramUserIDKey: - return "telegram-user-id" - } - return "" -} - -var ( - UserSettingLocaleValue = []string{ - "ar", - "de", - "en", - "es", - "fr", - "hi", - "hr", - "it", - "ja", - "ko", - "nl", - "pl", - "pt-BR", - "ru", - "sl", - "sv", - "tr", - "uk", - "vi", - "zh-Hans", - "zh-Hant", - } - UserSettingAppearanceValue = []string{"system", "light", "dark"} - UserSettingMemoVisibilityValue = []Visibility{Private, Protected, Public} -) - -type UserSetting struct { - UserID int32 `json:"userId"` - Key UserSettingKey `json:"key"` - Value string `json:"value"` -} - -type UpsertUserSettingRequest struct { - UserID int32 `json:"-"` - Key UserSettingKey `json:"key"` - Value string `json:"value"` -} - -func (s *APIV1Service) registerUserSettingRoutes(g *echo.Group) { - g.POST("/user/setting", s.UpsertUserSetting) -} - -// UpsertUserSetting godoc -// -// @Summary Upsert user setting -// @Tags user-setting -// @Accept json -// @Produce json -// @Param body body UpsertUserSettingRequest true "Request object." -// @Success 200 {object} store.UserSetting "Created user setting" -// @Failure 400 {object} nil "Malformatted post user setting upsert request | Invalid user setting format" -// @Failure 401 {object} nil "Missing auth session" -// @Failure 500 {object} nil "Failed to upsert user setting" -// @Router /api/v1/user/setting [POST] -func (s *APIV1Service) UpsertUserSetting(c echo.Context) error { - ctx := c.Request().Context() - userID, ok := c.Get(userIDContextKey).(int32) - if !ok { - return echo.NewHTTPError(http.StatusUnauthorized, "Missing auth session") - } - - userSettingUpsert := &UpsertUserSettingRequest{} - if err := json.NewDecoder(c.Request().Body).Decode(userSettingUpsert); err != nil { - return echo.NewHTTPError(http.StatusBadRequest, "Malformatted post user setting upsert request").SetInternal(err) - } - if err := userSettingUpsert.Validate(); err != nil { - return echo.NewHTTPError(http.StatusBadRequest, "Invalid user setting format").SetInternal(err) - } - - userSettingUpsert.UserID = userID - userSetting, err := s.Store.UpsertUserSetting(ctx, &store.UserSetting{ - UserID: userID, - Key: userSettingUpsert.Key.String(), - Value: userSettingUpsert.Value, - }) - if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, "Failed to upsert user setting").SetInternal(err) - } - - userSettingMessage := convertUserSettingFromStore(userSetting) - return c.JSON(http.StatusOK, userSettingMessage) -} - -func (upsert UpsertUserSettingRequest) Validate() error { - if upsert.Key == UserSettingLocaleKey { - localeValue := "en" - err := json.Unmarshal([]byte(upsert.Value), &localeValue) - if err != nil { - return errors.New("failed to unmarshal user setting locale value") - } - if !slices.Contains(UserSettingLocaleValue, localeValue) { - return errors.New("invalid user setting locale value") - } - } else if upsert.Key == UserSettingAppearanceKey { - appearanceValue := "system" - err := json.Unmarshal([]byte(upsert.Value), &appearanceValue) - if err != nil { - return errors.New("failed to unmarshal user setting appearance value") - } - if !slices.Contains(UserSettingAppearanceValue, appearanceValue) { - return errors.New("invalid user setting appearance value") - } - } else if upsert.Key == UserSettingMemoVisibilityKey { - memoVisibilityValue := Private - err := json.Unmarshal([]byte(upsert.Value), &memoVisibilityValue) - if err != nil { - return errors.New("failed to unmarshal user setting memo visibility value") - } - if !slices.Contains(UserSettingMemoVisibilityValue, memoVisibilityValue) { - return errors.New("invalid user setting memo visibility value") - } - } else if upsert.Key == UserSettingTelegramUserIDKey { - var key string - err := json.Unmarshal([]byte(upsert.Value), &key) - if err != nil { - return errors.New("invalid user setting telegram user id value") - } - } else { - return errors.New("invalid user setting key") - } - - return nil -} - -func convertUserSettingFromStore(userSetting *store.UserSetting) *UserSetting { - return &UserSetting{ - UserID: userSetting.UserID, - Key: UserSettingKey(userSetting.Key), - Value: userSetting.Value, - } -} diff --git a/api/v2/acl_config.go b/api/v2/acl_config.go deleted file mode 100644 index 489bc50a0267e..0000000000000 --- a/api/v2/acl_config.go +++ /dev/null @@ -1,26 +0,0 @@ -package v2 - -import "strings" - -var authenticationAllowlistMethods = map[string]bool{ - "/memos.api.v2.SystemService/GetSystemInfo": true, - "/memos.api.v2.UserService/GetUser": true, - "/memos.api.v2.MemoService/ListMemos": true, -} - -// isUnauthorizeAllowedMethod returns whether the method is exempted from authentication. -func isUnauthorizeAllowedMethod(fullMethodName string) bool { - if strings.HasPrefix(fullMethodName, "/grpc.reflection") { - return true - } - return authenticationAllowlistMethods[fullMethodName] -} - -var allowedMethodsOnlyForAdmin = map[string]bool{ - "/memos.api.v2.UserService/CreateUser": true, -} - -// isOnlyForAdminAllowedMethod returns true if the method is allowed to be called only by admin. -func isOnlyForAdminAllowedMethod(methodName string) bool { - return allowedMethodsOnlyForAdmin[methodName] -} diff --git a/api/v2/memo_service.go b/api/v2/memo_service.go deleted file mode 100644 index 2b2bac5aa8f71..0000000000000 --- a/api/v2/memo_service.go +++ /dev/null @@ -1,266 +0,0 @@ -package v2 - -import ( - "context" - - "github.com/google/cel-go/cel" - "github.com/pkg/errors" - v1alpha1 "google.golang.org/genproto/googleapis/api/expr/v1alpha1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - apiv2pb "github.com/usememos/memos/proto/gen/api/v2" - "github.com/usememos/memos/store" -) - -func (s *APIV2Service) CreateMemo(ctx context.Context, request *apiv2pb.CreateMemoRequest) (*apiv2pb.CreateMemoResponse, error) { - user, err := getCurrentUser(ctx, s.Store) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get user") - } - if user == nil { - return nil, status.Errorf(codes.PermissionDenied, "permission denied") - } - - create := &store.Memo{ - CreatorID: user.ID, - Content: request.Content, - Visibility: store.Visibility(request.Visibility.String()), - } - memo, err := s.Store.CreateMemo(ctx, create) - if err != nil { - return nil, err - } - - response := &apiv2pb.CreateMemoResponse{ - Memo: convertMemoFromStore(memo), - } - return response, nil -} - -func (s *APIV2Service) ListMemos(ctx context.Context, request *apiv2pb.ListMemosRequest) (*apiv2pb.ListMemosResponse, error) { - memoFind := &store.FindMemo{} - if request.Filter != "" { - filter, err := parseListMemosFilter(request.Filter) - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "invalid filter: %v", err) - } - if filter.Visibility != nil { - memoFind.VisibilityList = []store.Visibility{*filter.Visibility} - } - if filter.CreatedTsBefore != nil { - memoFind.CreatedTsBefore = filter.CreatedTsBefore - } - if filter.CreatedTsAfter != nil { - memoFind.CreatedTsAfter = filter.CreatedTsAfter - } - } - user, _ := getCurrentUser(ctx, s.Store) - // If the user is not authenticated, only public memos are visible. - if user == nil { - memoFind.VisibilityList = []store.Visibility{store.Public} - } - - if request.CreatorId != nil { - memoFind.CreatorID = request.CreatorId - } - - // Remove the private memos from the list if the user is not the creator. - if user != nil && request.CreatorId != nil && *request.CreatorId != user.ID { - var filteredVisibility []store.Visibility - for _, v := range memoFind.VisibilityList { - if v != store.Private { - filteredVisibility = append(filteredVisibility, v) - } - } - memoFind.VisibilityList = filteredVisibility - } - - if request.PageSize != 0 { - offset := int(request.Page * request.PageSize) - limit := int(request.PageSize) - memoFind.Offset = &offset - memoFind.Limit = &limit - } - memos, err := s.Store.ListMemos(ctx, memoFind) - if err != nil { - return nil, err - } - - memoMessages := make([]*apiv2pb.Memo, len(memos)) - for i, memo := range memos { - memoMessages[i] = convertMemoFromStore(memo) - } - - response := &apiv2pb.ListMemosResponse{ - Memos: memoMessages, - } - return response, nil -} - -func (s *APIV2Service) GetMemo(ctx context.Context, request *apiv2pb.GetMemoRequest) (*apiv2pb.GetMemoResponse, error) { - memo, err := s.Store.GetMemo(ctx, &store.FindMemo{ - ID: &request.Id, - }) - if err != nil { - return nil, err - } - if memo == nil { - return nil, status.Errorf(codes.NotFound, "memo not found") - } - if memo.Visibility != store.Public { - user, err := getCurrentUser(ctx, s.Store) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get user") - } - if user == nil { - return nil, status.Errorf(codes.PermissionDenied, "permission denied") - } - if memo.Visibility == store.Private && memo.CreatorID != user.ID { - return nil, status.Errorf(codes.PermissionDenied, "permission denied") - } - } - - response := &apiv2pb.GetMemoResponse{ - Memo: convertMemoFromStore(memo), - } - return response, nil -} - -func (s *APIV2Service) CreateMemoComment(ctx context.Context, request *apiv2pb.CreateMemoCommentRequest) (*apiv2pb.CreateMemoCommentResponse, error) { - // Create the comment memo first. - createMemoResponse, err := s.CreateMemo(ctx, request.Create) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to create memo") - } - - // Build the relation between the comment memo and the original memo. - memo := createMemoResponse.Memo - _, err = s.Store.UpsertMemoRelation(ctx, &store.MemoRelation{ - MemoID: memo.Id, - RelatedMemoID: request.Id, - Type: store.MemoRelationComment, - }) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to create memo relation") - } - - response := &apiv2pb.CreateMemoCommentResponse{ - Memo: memo, - } - return response, nil -} - -func (s *APIV2Service) ListMemoComments(ctx context.Context, request *apiv2pb.ListMemoCommentsRequest) (*apiv2pb.ListMemoCommentsResponse, error) { - memoRelationComment := store.MemoRelationComment - memoRelations, err := s.Store.ListMemoRelations(ctx, &store.FindMemoRelation{ - RelatedMemoID: &request.Id, - Type: &memoRelationComment, - }) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to list memo relations") - } - - var memos []*apiv2pb.Memo - for _, memoRelation := range memoRelations { - memo, err := s.Store.GetMemo(ctx, &store.FindMemo{ - ID: &memoRelation.MemoID, - }) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get memo") - } - if memo != nil { - memos = append(memos, convertMemoFromStore(memo)) - } - } - - response := &apiv2pb.ListMemoCommentsResponse{ - Memos: memos, - } - return response, nil -} - -// ListMemosFilterCELAttributes are the CEL attributes for ListMemosFilter. -var ListMemosFilterCELAttributes = []cel.EnvOption{ - cel.Variable("visibility", cel.StringType), - cel.Variable("created_ts_before", cel.IntType), - cel.Variable("created_ts_after", cel.IntType), -} - -type ListMemosFilter struct { - Visibility *store.Visibility - CreatedTsBefore *int64 - CreatedTsAfter *int64 -} - -func parseListMemosFilter(expression string) (*ListMemosFilter, error) { - e, err := cel.NewEnv(ListMemosFilterCELAttributes...) - if err != nil { - return nil, err - } - ast, issues := e.Compile(expression) - if issues != nil { - return nil, errors.Errorf("found issue %v", issues) - } - filter := &ListMemosFilter{} - expr, err := cel.AstToParsedExpr(ast) - if err != nil { - return nil, err - } - callExpr := expr.GetExpr().GetCallExpr() - findField(callExpr, filter) - return filter, nil -} - -func findField(callExpr *v1alpha1.Expr_Call, filter *ListMemosFilter) { - if len(callExpr.Args) == 2 { - idExpr := callExpr.Args[0].GetIdentExpr() - if idExpr != nil { - if idExpr.Name == "visibility" { - visibility := store.Visibility(callExpr.Args[1].GetConstExpr().GetStringValue()) - filter.Visibility = &visibility - } - if idExpr.Name == "created_ts_before" { - createdTsBefore := callExpr.Args[1].GetConstExpr().GetInt64Value() - filter.CreatedTsBefore = &createdTsBefore - } - if idExpr.Name == "created_ts_after" { - createdTsAfter := callExpr.Args[1].GetConstExpr().GetInt64Value() - filter.CreatedTsAfter = &createdTsAfter - } - return - } - } - for _, arg := range callExpr.Args { - callExpr := arg.GetCallExpr() - if callExpr != nil { - findField(callExpr, filter) - } - } -} - -func convertMemoFromStore(memo *store.Memo) *apiv2pb.Memo { - return &apiv2pb.Memo{ - Id: int32(memo.ID), - RowStatus: convertRowStatusFromStore(memo.RowStatus), - CreatedTs: memo.CreatedTs, - UpdatedTs: memo.UpdatedTs, - CreatorId: int32(memo.CreatorID), - Content: memo.Content, - Visibility: convertVisibilityFromStore(memo.Visibility), - Pinned: memo.Pinned, - } -} - -func convertVisibilityFromStore(visibility store.Visibility) apiv2pb.Visibility { - switch visibility { - case store.Private: - return apiv2pb.Visibility_PRIVATE - case store.Protected: - return apiv2pb.Visibility_PROTECTED - case store.Public: - return apiv2pb.Visibility_PUBLIC - default: - return apiv2pb.Visibility_VISIBILITY_UNSPECIFIED - } -} diff --git a/api/v2/system_service.go b/api/v2/system_service.go deleted file mode 100644 index af37a22c734c8..0000000000000 --- a/api/v2/system_service.go +++ /dev/null @@ -1,92 +0,0 @@ -package v2 - -import ( - "context" - "strconv" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - apiv2pb "github.com/usememos/memos/proto/gen/api/v2" - "github.com/usememos/memos/store" -) - -func (s *APIV2Service) GetSystemInfo(ctx context.Context, _ *apiv2pb.GetSystemInfoRequest) (*apiv2pb.GetSystemInfoResponse, error) { - defaultSystemInfo := &apiv2pb.SystemInfo{} - - // Get the database size if the user is a host. - currentUser, err := getCurrentUser(ctx, s.Store) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err) - } - if currentUser != nil && currentUser.Role == store.RoleHost { - size, err := s.Store.GetCurrentDBSize(ctx) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get db size: %v", err) - } - defaultSystemInfo.DbSize = size - } - - response := &apiv2pb.GetSystemInfoResponse{ - SystemInfo: defaultSystemInfo, - } - return response, nil -} - -func (s *APIV2Service) UpdateSystemInfo(ctx context.Context, request *apiv2pb.UpdateSystemInfoRequest) (*apiv2pb.UpdateSystemInfoResponse, error) { - user, err := getCurrentUser(ctx, s.Store) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err) - } - if user.Role != store.RoleHost { - return nil, status.Errorf(codes.PermissionDenied, "permission denied") - } - if request.UpdateMask == nil || len(request.UpdateMask.Paths) == 0 { - return nil, status.Errorf(codes.InvalidArgument, "update mask is required") - } - - // Update system settings. - for _, path := range request.UpdateMask.Paths { - if path == "allow_registration" { - _, err := s.Store.UpsertSystemSetting(ctx, &store.SystemSetting{ - Name: "allow-signup", - Value: strconv.FormatBool(request.SystemInfo.AllowRegistration), - }) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to update allow_registration system setting: %v", err) - } - } else if path == "disable_password_login" { - _, err := s.Store.UpsertSystemSetting(ctx, &store.SystemSetting{ - Name: "disable-password-login", - Value: strconv.FormatBool(request.SystemInfo.DisablePasswordLogin), - }) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to update disable_password_login system setting: %v", err) - } - } else if path == "additional_script" { - _, err := s.Store.UpsertSystemSetting(ctx, &store.SystemSetting{ - Name: "additional-script", - Value: request.SystemInfo.AdditionalScript, - }) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to update additional_script system setting: %v", err) - } - } else if path == "additional_style" { - _, err := s.Store.UpsertSystemSetting(ctx, &store.SystemSetting{ - Name: "additional-style", - Value: request.SystemInfo.AdditionalStyle, - }) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to update additional_style system setting: %v", err) - } - } - } - - systemInfo, err := s.GetSystemInfo(ctx, &apiv2pb.GetSystemInfoRequest{}) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get system info: %v", err) - } - return &apiv2pb.UpdateSystemInfoResponse{ - SystemInfo: systemInfo.SystemInfo, - }, nil -} diff --git a/api/v2/tag_service.go b/api/v2/tag_service.go deleted file mode 100644 index f1cd8561a6e1b..0000000000000 --- a/api/v2/tag_service.go +++ /dev/null @@ -1,64 +0,0 @@ -package v2 - -import ( - "context" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - apiv2pb "github.com/usememos/memos/proto/gen/api/v2" - "github.com/usememos/memos/store" -) - -func (s *APIV2Service) UpsertTag(ctx context.Context, request *apiv2pb.UpsertTagRequest) (*apiv2pb.UpsertTagResponse, error) { - user, err := getCurrentUser(ctx, s.Store) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get user") - } - - tag, err := s.Store.UpsertTag(ctx, &store.Tag{ - Name: request.Name, - CreatorID: user.ID, - }) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to upsert tag: %v", err) - } - - return &apiv2pb.UpsertTagResponse{ - Tag: convertTagFromStore(tag), - }, nil -} - -func (s *APIV2Service) ListTags(ctx context.Context, request *apiv2pb.ListTagsRequest) (*apiv2pb.ListTagsResponse, error) { - tags, err := s.Store.ListTags(ctx, &store.FindTag{ - CreatorID: request.CreatorId, - }) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to list tags: %v", err) - } - - response := &apiv2pb.ListTagsResponse{} - for _, tag := range tags { - response.Tags = append(response.Tags, convertTagFromStore(tag)) - } - return response, nil -} - -func (s *APIV2Service) DeleteTag(ctx context.Context, request *apiv2pb.DeleteTagRequest) (*apiv2pb.DeleteTagResponse, error) { - err := s.Store.DeleteTag(ctx, &store.DeleteTag{ - Name: request.Tag.Name, - CreatorID: request.Tag.CreatorId, - }) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to delete tag: %v", err) - } - - return &apiv2pb.DeleteTagResponse{}, nil -} - -func convertTagFromStore(tag *store.Tag) *apiv2pb.Tag { - return &apiv2pb.Tag{ - Name: tag.Name, - CreatorId: int32(tag.CreatorID), - } -} diff --git a/cmd/memos.go b/bin/memos/main.go similarity index 71% rename from cmd/memos.go rename to bin/memos/main.go index c391d35e26c3d..9669d8188f661 100644 --- a/cmd/memos.go +++ b/bin/memos/main.go @@ -1,8 +1,9 @@ -package cmd +package main import ( "context" "fmt" + "log/slog" "net/http" "os" "os/signal" @@ -10,12 +11,10 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "go.uber.org/zap" - "github.com/usememos/memos/internal/log" + "github.com/usememos/memos/internal/jobs" "github.com/usememos/memos/server" _profile "github.com/usememos/memos/server/profile" - "github.com/usememos/memos/server/service/metric" "github.com/usememos/memos/store" "github.com/usememos/memos/store/db" ) @@ -32,14 +31,14 @@ const ( ) var ( - profile *_profile.Profile - mode string - addr string - port int - data string - driver string - dsn string - enableMetric bool + profile *_profile.Profile + mode string + addr string + port int + data string + driver string + dsn string + serveFrontend bool rootCmd = &cobra.Command{ Use: "memos", @@ -49,29 +48,27 @@ var ( dbDriver, err := db.NewDBDriver(profile) if err != nil { cancel() - log.Error("failed to create db driver", zap.Error(err)) + slog.Error("failed to create db driver", err) return } if err := dbDriver.Migrate(ctx); err != nil { cancel() - log.Error("failed to migrate db", zap.Error(err)) + slog.Error("failed to migrate database", err) return } - store := store.New(dbDriver, profile) - s, err := server.NewServer(ctx, profile, store) - if err != nil { + storeInstance := store.New(dbDriver, profile) + if err := storeInstance.MigrateManually(ctx); err != nil { cancel() - log.Error("failed to create server", zap.Error(err)) + slog.Error("failed to migrate manually", err) return } - if profile.Metric { - println("metric collection is enabled") - // nolint - metric.NewMetricClient(s.ID, *profile) - } else { - println("metric collection is disabled") + s, err := server.NewServer(ctx, profile, storeInstance) + if err != nil { + cancel() + slog.Error("failed to create server", err) + return } c := make(chan os.Signal, 1) @@ -80,17 +77,19 @@ var ( // which is taken as the graceful shutdown signal for many systems, eg., Kubernetes, Gunicorn. signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { - sig := <-c - log.Info(fmt.Sprintf("%s received.\n", sig.String())) + <-c s.Shutdown(ctx) cancel() }() printGreetings() + // update (pre-sign) object storage links if applicable + go jobs.RunPreSignLinks(ctx, storeInstance) + if err := s.Start(ctx); err != nil { if err != http.ErrServerClosed { - log.Error("failed to start server", zap.Error(err)) + slog.Error("failed to start server", err) cancel() } } @@ -102,7 +101,6 @@ var ( ) func Execute() error { - defer log.Sync() return rootCmd.Execute() } @@ -115,7 +113,7 @@ func init() { rootCmd.PersistentFlags().StringVarP(&data, "data", "d", "", "data directory") rootCmd.PersistentFlags().StringVarP(&driver, "driver", "", "", "database driver") rootCmd.PersistentFlags().StringVarP(&dsn, "dsn", "", "", "database source name(aka. DSN)") - rootCmd.PersistentFlags().BoolVarP(&enableMetric, "metric", "", true, "allow metric collection") + rootCmd.PersistentFlags().BoolVarP(&serveFrontend, "frontend", "", true, "serve frontend files") err := viper.BindPFlag("mode", rootCmd.PersistentFlags().Lookup("mode")) if err != nil { @@ -141,7 +139,7 @@ func init() { if err != nil { panic(err) } - err = viper.BindPFlag("metric", rootCmd.PersistentFlags().Lookup("metric")) + err = viper.BindPFlag("frontend", rootCmd.PersistentFlags().Lookup("frontend")) if err != nil { panic(err) } @@ -150,7 +148,7 @@ func init() { viper.SetDefault("driver", "sqlite") viper.SetDefault("addr", "") viper.SetDefault("port", 8081) - viper.SetDefault("metric", true) + viper.SetDefault("frontend", true) viper.SetEnvPrefix("memos") } @@ -163,17 +161,18 @@ func initConfig() { return } - println("---") - println("Server profile") - println("data:", profile.Data) - println("dsn:", profile.DSN) - println("addr:", profile.Addr) - println("port:", profile.Port) - println("mode:", profile.Mode) - println("driver:", profile.Driver) - println("version:", profile.Version) - println("metric:", profile.Metric) - println("---") + fmt.Printf(`--- +Server profile +version: %s +data: %s +dsn: %s +addr: %s +port: %d +mode: %s +driver: %s +frontend: %t +--- +`, profile.Version, profile.Data, profile.DSN, profile.Addr, profile.Port, profile.Mode, profile.Driver, profile.Frontend) } func printGreetings() { @@ -183,9 +182,17 @@ func printGreetings() { } else { fmt.Printf("Version %s has been started on address '%s' and port %d\n", profile.Version, profile.Addr, profile.Port) } - println("---") - println("See more in:") - fmt.Printf("👉Website: %s\n", "https://usememos.com") - fmt.Printf("👉GitHub: %s\n", "https://github.com/usememos/memos") - println("---") + fmt.Printf(`--- +See more in: +👉Website: %s +👉GitHub: %s +--- +`, "https://usememos.com", "https://github.com/usememos/memos") +} + +func main() { + err := Execute() + if err != nil { + panic(err) + } } diff --git a/cmd/copydb.go b/cmd/copydb.go deleted file mode 100644 index fed5c1963ed7a..0000000000000 --- a/cmd/copydb.go +++ /dev/null @@ -1,383 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - "strings" - - "github.com/pkg/errors" - "github.com/spf13/cobra" - - _profile "github.com/usememos/memos/server/profile" - "github.com/usememos/memos/store" - "github.com/usememos/memos/store/db" -) - -var ( - copydbCmdFlagFrom = "from" - copydbCmd = &cobra.Command{ - Use: "copydb", // `copydb` is a shortened for 'copy database' - Short: "Copy data between db drivers", - Run: func(cmd *cobra.Command, _ []string) { - s, err := cmd.Flags().GetString(copydbCmdFlagFrom) - if err != nil { - println("fail to get from driver DSN") - println(err) - return - } - ss := strings.Split(s, "://") - if len(ss) != 2 { - println("fail to parse from driver DSN, should be like 'sqlite://memos_prod.db' or 'mysql://user:pass@tcp(host)/memos'") - return - } - - fromProfile := &_profile.Profile{Driver: ss[0], DSN: ss[1]} - - err = copydb(fromProfile, profile) - if err != nil { - fmt.Printf("fail to copydb: %s\n", err) - return - } - - println("done") - }, - } -) - -func init() { - copydbCmd.Flags().String(copydbCmdFlagFrom, "sqlite://memos_prod.db", "From driver DSN") - - rootCmd.AddCommand(copydbCmd) -} - -func copydb(fromProfile, toProfile *_profile.Profile) error { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - toDriver, err := db.NewDBDriver(toProfile) - if err != nil { - return errors.Wrap(err, "fail to create `to` driver") - } - - if err := toDriver.Migrate(ctx); err != nil { - return errors.Wrap(err, "fail to migrate db") - } - - fromDriver, err := db.NewDBDriver(fromProfile) - if err != nil { - return errors.Wrap(err, "fail to create `from` driver") - } - - // Register here if any table is added - copyMap := map[string]func(context.Context, store.Driver, store.Driver) error{ - "activity": copyActivity, - "idp": copyIdp, - "memo": copyMemo, - "memo_organizer": copyMemoOrganizer, - "memo_relation": copyMemoRelation, - "resource": copyResource, - "storage": copyStorage, - "system_setting": copySystemSettings, - "tag": copyTag, - "user": copyUser, - "user_setting": copyUserSettings, - } - - toDb := toDriver.GetDB() - for table := range copyMap { - println("Checking " + table + "...") - var cnt int - err := toDb.QueryRowContext(ctx, "SELECT COUNT(*) FROM "+table).Scan(&cnt) - if err != nil { - return errors.Wrapf(err, "fail to check '%s'", table) - } - if cnt > 0 { - return errors.Errorf("table '%s' is not empty", table) - } - } - - for _, f := range copyMap { - err = f(ctx, fromDriver, toDriver) - if err != nil { - return errors.Wrap(err, "fail to copy data") - } - } - - return nil -} - -func copyActivity(ctx context.Context, fromDriver, toDriver store.Driver) error { - println("Copying Activity...") - list, err := fromDriver.ListActivities(ctx, &store.FindActivity{}) - if err != nil { - return err - } - - fmt.Printf("\tTotal %d records\n", len(list)) - for _, item := range list { - _, err := toDriver.CreateActivity(ctx, &store.Activity{ - ID: item.ID, - CreatorID: item.CreatorID, - CreatedTs: item.CreatedTs, - Level: item.Level, - Type: item.Type, - Payload: item.Payload, - }) - if err != nil { - return err - } - } - - println("\tDONE") - return nil -} - -func copyIdp(ctx context.Context, fromDriver, toDriver store.Driver) error { - println("Copying IdentityProvider...") - list, err := fromDriver.ListIdentityProviders(ctx, &store.FindIdentityProvider{}) - if err != nil { - return err - } - - fmt.Printf("\tTotal %d records\n", len(list)) - for _, item := range list { - _, err := toDriver.CreateIdentityProvider(ctx, &store.IdentityProvider{ - ID: item.ID, - Name: item.Name, - Type: item.Type, - IdentifierFilter: item.IdentifierFilter, - Config: item.Config, - }) - if err != nil { - return err - } - } - - println("\tDONE") - return nil -} - -func copyMemo(ctx context.Context, fromDriver, toDriver store.Driver) error { - println("Copying Memo...") - list, err := fromDriver.ListMemos(ctx, &store.FindMemo{}) - if err != nil { - return err - } - - fmt.Printf("\tTotal %d records\n", len(list)) - for _, item := range list { - _, err := toDriver.CreateMemo(ctx, &store.Memo{ - ID: item.ID, - CreatorID: item.CreatorID, - CreatedTs: item.CreatedTs, - UpdatedTs: item.UpdatedTs, - RowStatus: item.RowStatus, - Content: item.Content, - Visibility: item.Visibility, - }) - if err != nil { - return err - } - } - - println("\tDONE") - return nil -} - -func copyMemoOrganizer(ctx context.Context, fromDriver, toDriver store.Driver) error { - println("Copying MemoOrganizer...") - list, err := fromDriver.ListMemoOrganizer(ctx, &store.FindMemoOrganizer{}) - if err != nil { - return err - } - - fmt.Printf("\tTotal %d records\n", len(list)) - for _, item := range list { - _, err := toDriver.UpsertMemoOrganizer(ctx, &store.MemoOrganizer{ - MemoID: item.MemoID, - UserID: item.UserID, - Pinned: item.Pinned, - }) - if err != nil { - return err - } - } - println("\tDONE") - return nil -} - -func copyMemoRelation(ctx context.Context, fromDriver, toDriver store.Driver) error { - println("Copying MemoRelation...") - list, err := fromDriver.ListMemoRelations(ctx, &store.FindMemoRelation{}) - if err != nil { - return err - } - - fmt.Printf("\tTotal %d records\n", len(list)) - for _, item := range list { - _, err := toDriver.UpsertMemoRelation(ctx, &store.MemoRelation{ - MemoID: item.MemoID, - RelatedMemoID: item.RelatedMemoID, - Type: item.Type, - }) - if err != nil { - return err - } - } - - println("\tDONE") - return nil -} - -func copyResource(ctx context.Context, fromDriver, toDriver store.Driver) error { - println("Copying Resource...") - list, err := fromDriver.ListResources(ctx, &store.FindResource{GetBlob: true}) - if err != nil { - return err - } - - fmt.Printf("\tTotal %d records\n", len(list)) - for _, item := range list { - _, err := toDriver.CreateResource(ctx, &store.Resource{ - ID: item.ID, - CreatorID: item.CreatorID, - CreatedTs: item.CreatedTs, - UpdatedTs: item.UpdatedTs, - Filename: item.Filename, - Blob: item.Blob, - ExternalLink: item.ExternalLink, - Type: item.Type, - Size: item.Size, - InternalPath: item.InternalPath, - MemoID: item.MemoID, - }) - if err != nil { - return err - } - } - - println("\tDONE") - return nil -} - -func copyStorage(ctx context.Context, fromDriver, toDriver store.Driver) error { - println("Copying Storage...") - list, err := fromDriver.ListStorages(ctx, &store.FindStorage{}) - if err != nil { - return err - } - - fmt.Printf("\tTotal %d records\n", len(list)) - for _, item := range list { - _, err := toDriver.CreateStorage(ctx, &store.Storage{ - ID: item.ID, - Name: item.Name, - Type: item.Type, - Config: item.Config, - }) - if err != nil { - return err - } - } - - println("\tDONE") - return nil -} - -func copySystemSettings(ctx context.Context, fromDriver, toDriver store.Driver) error { - println("Copying SystemSettings...") - list, err := fromDriver.ListSystemSettings(ctx, &store.FindSystemSetting{}) - if err != nil { - return err - } - - fmt.Printf("\tTotal %d records\n", len(list)) - for _, item := range list { - _, err := toDriver.UpsertSystemSetting(ctx, &store.SystemSetting{ - Name: item.Name, - Value: item.Value, - Description: item.Description, - }) - if err != nil { - return err - } - } - - println("\tDONE") - return nil -} - -func copyTag(ctx context.Context, fromDriver, toDriver store.Driver) error { - println("Copying Tag...") - list, err := fromDriver.ListTags(ctx, &store.FindTag{}) - if err != nil { - return err - } - - fmt.Printf("\tTotal %d records\n", len(list)) - for _, item := range list { - _, err := toDriver.UpsertTag(ctx, &store.Tag{ - Name: item.Name, - CreatorID: item.CreatorID, - }) - if err != nil { - return err - } - } - - println("\tDONE") - return nil -} - -func copyUser(ctx context.Context, fromDriver, toDriver store.Driver) error { - println("Copying User...") - list, err := fromDriver.ListUsers(ctx, &store.FindUser{}) - if err != nil { - return err - } - - fmt.Printf("\tTotal %d records\n", len(list)) - for _, item := range list { - _, err := toDriver.CreateUser(ctx, &store.User{ - ID: item.ID, - CreatedTs: item.CreatedTs, - UpdatedTs: item.UpdatedTs, - RowStatus: item.RowStatus, - Username: item.Username, - Role: item.Role, - Email: item.Email, - Nickname: item.Nickname, - PasswordHash: item.PasswordHash, - AvatarURL: item.AvatarURL, - }) - if err != nil { - return err - } - } - - println("\tDONE") - return nil -} - -func copyUserSettings(ctx context.Context, fromDriver, toDriver store.Driver) error { - println("Copying UserSettings...") - list, err := fromDriver.ListUserSettings(ctx, &store.FindUserSetting{}) - if err != nil { - return err - } - - fmt.Printf("\tTotal %d records\n", len(list)) - for _, item := range list { - _, err := toDriver.UpsertUserSetting(ctx, &store.UserSetting{ - Key: item.Key, - Value: item.Value, - UserID: item.UserID, - }) - if err != nil { - return err - } - } - - println("\tDONE") - return nil -} diff --git a/cmd/mvrss.go b/cmd/mvrss.go deleted file mode 100644 index 402b42cb0e4c9..0000000000000 --- a/cmd/mvrss.go +++ /dev/null @@ -1,99 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - "os" - "time" - - "github.com/spf13/cobra" - - "github.com/usememos/memos/store" - "github.com/usememos/memos/store/db/sqlite" -) - -var ( - mvrssCmdFlagFrom = "from" - mvrssCmdFlagTo = "to" - mvrssCmd = &cobra.Command{ - Use: "mvrss", // `mvrss` is a shortened for 'means move resource' - Short: "Move resource between storage", - Run: func(cmd *cobra.Command, _ []string) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - from, err := cmd.Flags().GetString(mvrssCmdFlagFrom) - if err != nil { - fmt.Printf("failed to get from storage, error: %+v\n", err) - return - } - - to, err := cmd.Flags().GetString(mvrssCmdFlagTo) - if err != nil { - fmt.Printf("failed to get to storage, error: %+v\n", err) - return - } - - if from != "local" || to != "db" { - fmt.Printf("only local=>db be supported currently\n") - return - } - - driver, err := sqlite.NewDB(profile) - if err != nil { - fmt.Printf("failed to create db driver, error: %+v\n", err) - return - } - if err := driver.Migrate(ctx); err != nil { - fmt.Printf("failed to migrate db, error: %+v\n", err) - return - } - - s := store.New(driver, profile) - resources, err := s.ListResources(ctx, &store.FindResource{}) - if err != nil { - fmt.Printf("failed to list resources, error: %+v\n", err) - return - } - - var emptyString string - for _, res := range resources { - if res.InternalPath == "" { - continue - } - - buf, err := os.ReadFile(res.InternalPath) - if err != nil { - fmt.Printf("Resource %5d failed to read file: %s\n", res.ID, err) - continue - } - - if len(buf) != int(res.Size) { - fmt.Printf("Resource %5d size of file %d != %d\n", res.ID, len(buf), res.Size) - continue - } - - update := store.UpdateResource{ - ID: res.ID, - Blob: buf, - InternalPath: &emptyString, - } - _, err = s.UpdateResource(ctx, &update) - if err != nil { - fmt.Printf("Resource %5d failed to update: %s\n", res.ID, err) - continue - } - - fmt.Printf("Resource %5d copy %12d bytes from %s\n", res.ID, len(buf), res.InternalPath) - } - println("done") - }, - } -) - -func init() { - mvrssCmd.Flags().String(mvrssCmdFlagFrom, "local", "From storage") - mvrssCmd.Flags().String(mvrssCmdFlagTo, "db", "To Storage") - - rootCmd.AddCommand(mvrssCmd) -} diff --git a/cmd/setup.go b/cmd/setup.go deleted file mode 100644 index 3683b46c911c1..0000000000000 --- a/cmd/setup.go +++ /dev/null @@ -1,142 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - "time" - - "github.com/pkg/errors" - "github.com/spf13/cobra" - "golang.org/x/crypto/bcrypt" - - "github.com/usememos/memos/internal/util" - "github.com/usememos/memos/store" - "github.com/usememos/memos/store/db/sqlite" -) - -var ( - setupCmdFlagHostUsername = "host-username" - setupCmdFlagHostPassword = "host-password" - setupCmd = &cobra.Command{ - Use: "setup", - Short: "Make initial setup for memos", - Run: func(cmd *cobra.Command, _ []string) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - hostUsername, err := cmd.Flags().GetString(setupCmdFlagHostUsername) - if err != nil { - fmt.Printf("failed to get owner username, error: %+v\n", err) - return - } - - hostPassword, err := cmd.Flags().GetString(setupCmdFlagHostPassword) - if err != nil { - fmt.Printf("failed to get owner password, error: %+v\n", err) - return - } - - driver, err := sqlite.NewDB(profile) - if err != nil { - fmt.Printf("failed to create db driver, error: %+v\n", err) - return - } - if err := driver.Migrate(ctx); err != nil { - fmt.Printf("failed to migrate db, error: %+v\n", err) - return - } - - store := store.New(driver, profile) - if err := ExecuteSetup(ctx, store, hostUsername, hostPassword); err != nil { - fmt.Printf("failed to setup, error: %+v\n", err) - return - } - }, - } -) - -func init() { - setupCmd.Flags().String(setupCmdFlagHostUsername, "", "Owner username") - setupCmd.Flags().String(setupCmdFlagHostPassword, "", "Owner password") - - rootCmd.AddCommand(setupCmd) -} - -func ExecuteSetup(ctx context.Context, store *store.Store, hostUsername, hostPassword string) error { - s := setupService{store: store} - return s.Setup(ctx, hostUsername, hostPassword) -} - -type setupService struct { - store *store.Store -} - -func (s setupService) Setup(ctx context.Context, hostUsername, hostPassword string) error { - if err := s.makeSureHostUserNotExists(ctx); err != nil { - return err - } - - if err := s.createUser(ctx, hostUsername, hostPassword); err != nil { - return errors.Wrap(err, "create user") - } - return nil -} - -func (s setupService) makeSureHostUserNotExists(ctx context.Context) error { - hostUserType := store.RoleHost - existedHostUsers, err := s.store.ListUsers(ctx, &store.FindUser{Role: &hostUserType}) - if err != nil { - return errors.Wrap(err, "find user list") - } - - if len(existedHostUsers) != 0 { - return errors.New("host user already exists") - } - - return nil -} - -func (s setupService) createUser(ctx context.Context, hostUsername, hostPassword string) error { - userCreate := &store.User{ - Username: hostUsername, - // The new signup user should be normal user by default. - Role: store.RoleHost, - Nickname: hostUsername, - } - - if len(userCreate.Username) < 3 { - return errors.New("username is too short, minimum length is 3") - } - if len(userCreate.Username) > 32 { - return errors.New("username is too long, maximum length is 32") - } - if len(hostPassword) < 3 { - return errors.New("password is too short, minimum length is 3") - } - if len(hostPassword) > 512 { - return errors.New("password is too long, maximum length is 512") - } - if len(userCreate.Nickname) > 64 { - return errors.New("nickname is too long, maximum length is 64") - } - if userCreate.Email != "" { - if len(userCreate.Email) > 256 { - return errors.New("email is too long, maximum length is 256") - } - if !util.ValidateEmail(userCreate.Email) { - return errors.New("invalid email format") - } - } - - passwordHash, err := bcrypt.GenerateFromPassword([]byte(hostPassword), bcrypt.DefaultCost) - if err != nil { - return errors.Wrap(err, "failed to hash password") - } - - userCreate.PasswordHash = string(passwordHash) - if _, err := s.store.CreateUser(ctx, userCreate); err != nil { - return errors.Wrap(err, "failed to create user") - } - - return nil -} diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml deleted file mode 100644 index 2c1e07d978965..0000000000000 --- a/docker-compose.dev.yaml +++ /dev/null @@ -1,70 +0,0 @@ -services: - db: - image: mysql - volumes: - - ./.air/mysql:/var/lib/mysql - api: - image: cosmtrek/air - working_dir: /work - command: ["-c", "./scripts/.air.toml"] - environment: - - "MEMOS_DSN=root@tcp(db)/memos" - - "MEMOS_DRIVER=mysql" - volumes: - - .:/work/ - - .air/go-build:/root/.cache/go-build - - $HOME/go/pkg/:/go/pkg/ # Cache for go mod shared with the host - web: - image: node:18-alpine - working_dir: /work - depends_on: ["api"] - ports: ["3001:3001"] - environment: ["DEV_PROXY_SERVER=http://api:8081/"] - entrypoint: ["/bin/sh", "-c"] - command: ["corepack enable && pnpm install && pnpm dev"] - volumes: - - ./web:/work - - ./.air/node_modules/:/work/node_modules/ # Cache for Node Modules - - # Services below are used for developers to run once - # - # You can just run `docker compose run --rm SERVICE_NAME` to use - # For example: - # To regenerate typescript code of gRPC proto - # Just run `docker compose run --rm buf` - # - # All of theses services belongs to profile 'tools' - # This will prevent to launch by normally `docker compose up` unexpectly - - # Generate typescript code of gRPC proto - buf: - profiles: ["tools"] - image: bufbuild/buf - working_dir: /work/proto - command: generate - volumes: - - ./proto:/work/proto - - ./web/src/types/:/work/web/src/types/ - - # Do golang static code check before create PR - golangci-lint: - profiles: ["tools"] - image: golangci/golangci-lint:v1.54.2 - working_dir: /work/ - entrypoint: golangci-lint - command: run -v - volumes: - - $HOME/go/pkg/:/go/pkg/ # Cache for go mod shared with the host - - .air/go-build:/root/.cache/go-build - - .:/work/ - - # run npm - npm: - profiles: ["tools"] - image: node:18-alpine - working_dir: /work - environment: ["NPM_CONFIG_UPDATE_NOTIFIER=false"] - entrypoint: "npm" - volumes: - - ./web:/work - - ./.air/node_modules/:/work/node_modules/ diff --git a/docs/api/v1.md b/docs/api/v1.md deleted file mode 100644 index 0514b97548d65..0000000000000 --- a/docs/api/v1.md +++ /dev/null @@ -1,1607 +0,0 @@ -# memos API - -A privacy-first, lightweight note-taking service. - -## Version: 1.0 - -**Contact information:** -API Support - - -**License:** [MIT License](https://github.com/usememos/memos/blob/main/LICENSE) - -[Find out more about Memos.](https://usememos.com/) - ---- - -### /api/v1/auth/signin - -#### POST - -##### Summary - -Sign-in to memos. - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | -------------- | -------- | ---------------------- | -| body | body | Sign-in object | Yes | [v1.SignIn](#v1signin) | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------ | -| 200 | User information | [store.User](#storeuser) | -| 400 | Malformatted signin request | | -| 401 | Password login is deactivated \| Incorrect login credentials, please try again | | -| 403 | User has been archived with username %s | | -| 500 | Failed to find system setting \| Failed to unmarshal system setting \| Incorrect login credentials, please try again \| Failed to generate tokens \| Failed to create activity | | - -### /api/v1/auth/signin/sso - -#### POST - -##### Summary - -Sign-in to memos using SSO. - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | ------------------ | -------- | ---------------------------- | -| body | body | SSO sign-in object | Yes | [v1.SSOSignIn](#v1ssosignin) | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| 200 | User information | [store.User](#storeuser) | -| 400 | Malformatted signin request | | -| 401 | Access denied, identifier does not match the filter. | | -| 403 | User has been archived with username {username} | | -| 404 | Identity provider not found | | -| 500 | Failed to find identity provider \| Failed to create identity provider instance \| Failed to exchange token \| Failed to get user info \| Failed to compile identifier filter \| Incorrect login credentials, please try again \| Failed to generate random password \| Failed to generate password hash \| Failed to create user \| Failed to generate tokens \| Failed to create activity | | - -### /api/v1/auth/signout - -#### POST - -##### Summary - -Sign-out from memos. - -##### Responses - -| Code | Description | Schema | -| ---- | ---------------- | ------- | -| 200 | Sign-out success | boolean | - -### /api/v1/auth/signup - -#### POST - -##### Summary - -Sign-up to memos. - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | -------------- | -------- | ---------------------- | -| body | body | Sign-up object | Yes | [v1.SignUp](#v1signup) | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| 200 | User information | [store.User](#storeuser) | -| 400 | Malformatted signup request \| Failed to find users | | -| 401 | signup is disabled | | -| 403 | Forbidden | | -| 404 | Not found | | -| 500 | Failed to find system setting \| Failed to unmarshal system setting allow signup \| Failed to generate password hash \| Failed to create user \| Failed to generate tokens \| Failed to create activity | | - ---- - -### /api/v1/idp - -#### GET - -##### Summary - -Get a list of identity providers - -##### Description - -\*clientSecret is only available for host user - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------ | ---------------------------------------------- | -| 200 | List of available identity providers | [ [v1.IdentityProvider](#v1identityprovider) ] | -| 500 | Failed to find identity provider list \| Failed to find user | | - -#### POST - -##### Summary - -Create Identity Provider - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | ----------------------------- | -------- | -------------------------------------------------------------------- | -| body | body | Identity provider information | Yes | [v1.CreateIdentityProviderRequest](#v1createidentityproviderrequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | --------------------------------------------------------- | ------------------------------------------------ | -| 200 | Identity provider information | [store.IdentityProvider](#storeidentityprovider) | -| 400 | Malformatted post identity provider request | | -| 401 | Missing user in session \| Unauthorized | | -| 500 | Failed to find user \| Failed to create identity provider | | - -### /api/v1/idp/{idpId} - -#### DELETE - -##### Summary - -Delete an identity provider by ID - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ----- | ---------- | -------------------- | -------- | ------- | -| idpId | path | Identity Provider ID | Yes | integer | - -##### Responses - -| Code | Description | Schema | -| ---- | ---------------------------------------------------------------------- | ------- | -| 200 | Identity Provider deleted | boolean | -| 400 | ID is not a number: %s \| Malformatted patch identity provider request | | -| 401 | Missing user in session \| Unauthorized | | -| 500 | Failed to find user \| Failed to patch identity provider | | - -#### GET - -##### Summary - -Get an identity provider by ID - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ----- | ---------- | -------------------- | -------- | ------- | -| idpId | path | Identity provider ID | Yes | integer | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------ | ------------------------------------------------ | -| 200 | Requested identity provider | [store.IdentityProvider](#storeidentityprovider) | -| 400 | ID is not a number: %s | | -| 401 | Missing user in session \| Unauthorized | | -| 404 | Identity provider not found | | -| 500 | Failed to find identity provider list \| Failed to find user | | - -#### PATCH - -##### Summary - -Update an identity provider by ID - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ----- | ---------- | ------------------------------------- | -------- | -------------------------------------------------------------------- | -| idpId | path | Identity Provider ID | Yes | integer | -| body | body | Patched identity provider information | Yes | [v1.UpdateIdentityProviderRequest](#v1updateidentityproviderrequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | ---------------------------------------------------------------------- | ------------------------------------------------ | -| 200 | Patched identity provider | [store.IdentityProvider](#storeidentityprovider) | -| 400 | ID is not a number: %s \| Malformatted patch identity provider request | | -| 401 | Missing user in session \| Unauthorized | | -| 500 | Failed to find user \| Failed to patch identity provider | | - ---- - -### /api/v1/memo - -#### GET - -##### Summary - -Get a list of memos matching optional filters - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| --------------- | ---------- | ------------------------------- | -------- | ------- | -| creatorId | query | Creator ID | No | integer | -| creatorUsername | query | Creator username | No | string | -| rowStatus | query | Row status | No | string | -| pinned | query | Pinned | No | boolean | -| tag | query | Search for tag. Do not append # | No | string | -| content | query | Search for content | No | string | -| limit | query | Limit | No | integer | -| offset | query | Offset | No | integer | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------- | -| 200 | Memo list | [ [store.Memo](#storememo) ] | -| 400 | Missing user to find memo | | -| 500 | Failed to get memo display with updated ts setting value \| Failed to fetch memo list \| Failed to compose memo response | | - -#### POST - -##### Summary - -Create a memo - -##### Description - -Visibility can be PUBLIC, PROTECTED or PRIVATE -\*You should omit fields to use their default values - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | --------------- | -------- | -------------------------------------------- | -| body | body | Request object. | Yes | [v1.CreateMemoRequest](#v1creatememorequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| 200 | Stored memo | [store.Memo](#storememo) | -| 400 | Malformatted post memo request \| Content size overflow, up to 1MB | | -| 401 | Missing user in session | | -| 404 | User not found \| Memo not found: %d | | -| 500 | Failed to find user setting \| Failed to unmarshal user setting value \| Failed to find system setting \| Failed to unmarshal system setting \| Failed to find user \| Failed to create memo \| Failed to create activity \| Failed to upsert memo resource \| Failed to upsert memo relation \| Failed to compose memo \| Failed to compose memo response | | - -### /api/v1/memo/{memoId} - -#### DELETE - -##### Summary - -Delete memo by ID - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ------ | ---------- | ----------------- | -------- | ------- | -| memoId | path | Memo ID to delete | Yes | integer | - -##### Responses - -| Code | Description | Schema | -| ---- | --------------------------------------------------- | ------- | -| 200 | Memo deleted | boolean | -| 400 | ID is not a number: %s | | -| 401 | Missing user in session \| Unauthorized | | -| 404 | Memo not found: %d | | -| 500 | Failed to find memo \| Failed to delete memo ID: %v | | - -#### GET - -##### Summary - -Get memo by ID - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ------ | ---------- | ----------- | -------- | ------- | -| memoId | path | Memo ID | Yes | integer | - -##### Responses - -| Code | Description | Schema | -| ---- | ---------------------------------------------------------------------------- | ---------------------------- | -| 200 | Memo list | [ [store.Memo](#storememo) ] | -| 400 | ID is not a number: %s | | -| 401 | Missing user in session | | -| 403 | this memo is private only \| this memo is protected, missing user in session | | -| 404 | Memo not found: %d | | -| 500 | Failed to find memo by ID: %v \| Failed to compose memo response | | - -#### PATCH - -##### Summary - -Update a memo - -##### Description - -Visibility can be PUBLIC, PROTECTED or PRIVATE -\*You should omit fields to use their default values - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ------ | ---------- | -------------------- | -------- | ------------------------------------------ | -| memoId | path | ID of memo to update | Yes | integer | -| body | body | Patched object. | Yes | [v1.PatchMemoRequest](#v1patchmemorequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| 200 | Stored memo | [store.Memo](#storememo) | -| 400 | ID is not a number: %s \| Malformatted patch memo request \| Content size overflow, up to 1MB | | -| 401 | Missing user in session \| Unauthorized | | -| 404 | Memo not found: %d | | -| 500 | Failed to find memo \| Failed to patch memo \| Failed to upsert memo resource \| Failed to delete memo resource \| Failed to compose memo response | | - -### /api/v1/memo/all - -#### GET - -##### Summary - -Get a list of public memos matching optional filters - -##### Description - -This should also list protected memos if the user is logged in -Authentication is optional - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ------ | ---------- | ----------- | -------- | ------- | -| limit | query | Limit | No | integer | -| offset | query | Offset | No | integer | - -##### Responses - -| Code | Description | Schema | -| ---- | ---------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -| 200 | Memo list | [ [store.Memo](#storememo) ] | -| 500 | Failed to get memo display with updated ts setting value \| Failed to fetch all memo list \| Failed to compose memo response | | - -### /api/v1/memo/stats - -#### GET - -##### Summary - -Get memo stats by creator ID or username - -##### Description - -Used to generate the heatmap - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| --------------- | ---------- | ---------------- | -------- | ------- | -| creatorId | query | Creator ID | No | integer | -| creatorUsername | query | Creator username | No | string | - -##### Responses - -| Code | Description | Schema | -| ---- | ----------------------------------------------------------------------------------------------------------------------- | ----------- | -| 200 | Memo createdTs list | [ integer ] | -| 400 | Missing user id to find memo | | -| 500 | Failed to get memo display with updated ts setting value \| Failed to find memo list \| Failed to compose memo response | | - ---- - -### /api/v1/memo/{memoId}/organizer - -#### POST - -##### Summary - -Organize memo (pin/unpin) - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ------ | ---------- | ---------------------- | -------- | -------------------------------------------------------------- | -| memoId | path | ID of memo to organize | Yes | integer | -| body | body | Memo organizer object | Yes | [v1.UpsertMemoOrganizerRequest](#v1upsertmemoorganizerrequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| 200 | Memo information | [store.Memo](#storememo) | -| 400 | ID is not a number: %s \| Malformatted post memo organizer request | | -| 401 | Missing user in session \| Unauthorized | | -| 404 | Memo not found: %v | | -| 500 | Failed to find memo \| Failed to upsert memo organizer \| Failed to find memo by ID: %v \| Failed to compose memo response | | - ---- - -### /api/v1/memo/{memoId}/relation - -#### GET - -##### Summary - -Get a list of Memo Relations - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ------ | ---------- | ---------------------------- | -------- | ------- | -| memoId | path | ID of memo to find relations | Yes | integer | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------ | -------------------------------------------- | -| 200 | Memo relation information list | [ [store.MemoRelation](#storememorelation) ] | -| 400 | ID is not a number: %s | | -| 500 | Failed to list memo relations | | - -#### POST - -##### Summary - -Create Memo Relation - -##### Description - -Create a relation between two memos - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ------ | ---------- | -------------------- | -------- | ------------------------------------------------------------ | -| memoId | path | ID of memo to relate | Yes | integer | -| body | body | Memo relation object | Yes | [v1.UpsertMemoRelationRequest](#v1upsertmemorelationrequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | ----------------------------------------------------------------- | ---------------------------------------- | -| 200 | Memo relation information | [store.MemoRelation](#storememorelation) | -| 400 | ID is not a number: %s \| Malformatted post memo relation request | | -| 500 | Failed to upsert memo relation | | - -### /api/v1/memo/{memoId}/relation/{relatedMemoId}/type/{relationType} - -#### DELETE - -##### Summary - -Delete a Memo Relation - -##### Description - -Removes a relation between two memos - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ------------- | ---------- | -------------------------------- | -------- | ------- | -| memoId | path | ID of memo to find relations | Yes | integer | -| relatedMemoId | path | ID of memo to remove relation to | Yes | integer | -| relationType | path | Type of relation to remove | Yes | string | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------------ | ------- | -| 200 | Memo relation deleted | boolean | -| 400 | Memo ID is not a number: %s \| Related memo ID is not a number: %s | | -| 500 | Failed to delete memo relation | | - ---- - -### /api/v1/ping - -#### GET - -##### Summary - -Ping the system - -##### Responses - -| Code | Description | Schema | -| ---- | ----------------------------- | ------- | -| 200 | If succeed to ping the system | boolean | - -### /api/v1/status - -#### GET - -##### Summary - -Get system GetSystemStatus - -##### Responses - -| Code | Description | Schema | -| ---- | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- | -| 200 | System GetSystemStatus | [v1.SystemStatus](#v1systemstatus) | -| 401 | Missing user in session \| Unauthorized | | -| 500 | Failed to find host user \| Failed to find system setting list \| Failed to unmarshal system setting customized profile value | | - -### /api/v1/system/vacuum - -#### POST - -##### Summary - -Vacuum the database - -##### Responses - -| Code | Description | Schema | -| ---- | ---------------------------------------------------- | ------- | -| 200 | Database vacuumed | boolean | -| 401 | Missing user in session \| Unauthorized | | -| 500 | Failed to find user \| Failed to ExecVacuum database | | - ---- - -### /api/v1/resource - -#### GET - -##### Summary - -Get a list of resources - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ------ | ---------- | ----------- | -------- | ------- | -| limit | query | Limit | No | integer | -| offset | query | Offset | No | integer | - -##### Responses - -| Code | Description | Schema | -| ---- | ----------------------------- | ------------------------------------ | -| 200 | Resource list | [ [store.Resource](#storeresource) ] | -| 401 | Missing user in session | | -| 500 | Failed to fetch resource list | | - -#### POST - -##### Summary - -Create resource - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | --------------- | -------- | ---------------------------------------------------- | -| body | body | Request object. | Yes | [v1.CreateResourceRequest](#v1createresourcerequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | -| 200 | Created resource | [store.Resource](#storeresource) | -| 400 | Malformatted post resource request \| Invalid external link \| Invalid external link scheme \| Failed to request %s \| Failed to read %s \| Failed to read mime from %s | | -| 401 | Missing user in session | | -| 500 | Failed to save resource \| Failed to create resource \| Failed to create activity | | - -### /api/v1/resource/{resourceId} - -#### DELETE - -##### Summary - -Delete a resource - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---------- | ---------- | ----------- | -------- | ------- | -| resourceId | path | Resource ID | Yes | integer | - -##### Responses - -| Code | Description | Schema | -| ---- | ---------------------------------------------------- | ------- | -| 200 | Resource deleted | boolean | -| 400 | ID is not a number: %s | | -| 401 | Missing user in session | | -| 404 | Resource not found: %d | | -| 500 | Failed to find resource \| Failed to delete resource | | - -#### PATCH - -##### Summary - -Update a resource - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---------- | ---------- | ---------------------- | -------- | ---------------------------------------------------- | -| resourceId | path | Resource ID | Yes | integer | -| patch | body | Patch resource request | Yes | [v1.UpdateResourceRequest](#v1updateresourcerequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------- | -------------------------------- | -| 200 | Updated resource | [store.Resource](#storeresource) | -| 400 | ID is not a number: %s \| Malformatted patch resource request | | -| 401 | Missing user in session \| Unauthorized | | -| 404 | Resource not found: %d | | -| 500 | Failed to find resource \| Failed to patch resource | | - -### /api/v1/resource/blob - -#### POST - -##### Summary - -Upload resource - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | -------------- | -------- | ------ | -| file | formData | File to upload | Yes | file | - -##### Responses - -| Code | Description | Schema | -| ---- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | -| 200 | Created resource | [store.Resource](#storeresource) | -| 400 | Upload file not found \| File size exceeds allowed limit of %d MiB \| Failed to parse upload data | | -| 401 | Missing user in session | | -| 500 | Failed to get uploading file \| Failed to open file \| Failed to save resource \| Failed to create resource \| Failed to create activity | | - -### /o/r/{resourceId} - -#### GET - -##### Summary - -Stream a resource - -##### Description - -\*Swagger UI may have problems displaying other file types than images - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---------- | ---------- | ----------- | -------- | ------- | -| resourceId | path | Resource ID | Yes | integer | -| thumbnail | query | Thumbnail | No | integer | - -##### Responses - -| Code | Description | -| ---- | ------------------------------------------------------------------------------------------------------------------- | -| 200 | Requested resource | -| 400 | ID is not a number: %s \| Failed to get resource visibility | -| 401 | Resource visibility not match | -| 404 | Resource not found: %d | -| 500 | Failed to find resource by ID: %v \| Failed to open the local resource: %s \| Failed to read the local resource: %s | - ---- - -### /api/v1/storage - -#### GET - -##### Summary - -Get a list of storages - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------ | ---------------------------------- | -| 200 | List of storages | [ [store.Storage](#storestorage) ] | -| 401 | Missing user in session \| Unauthorized | | -| 500 | Failed to find user \| Failed to convert storage | | - -#### POST - -##### Summary - -Create storage - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | --------------- | -------- | -------------------------------------------------- | -| body | body | Request object. | Yes | [v1.CreateStorageRequest](#v1createstoragerequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | ---------------------------------------------------------------------------- | ------------------------------ | -| 200 | Created storage | [store.Storage](#storestorage) | -| 400 | Malformatted post storage request | | -| 401 | Missing user in session | | -| 500 | Failed to find user \| Failed to create storage \| Failed to convert storage | | - -### /api/v1/storage/{storageId} - -#### DELETE - -##### Summary - -Delete a storage - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| --------- | ---------- | ----------- | -------- | ------- | -| storageId | path | Storage ID | Yes | integer | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------------------------------------------------------------- | ------- | -| 200 | Storage deleted | boolean | -| 400 | ID is not a number: %s \| Storage service %d is using | | -| 401 | Missing user in session \| Unauthorized | | -| 500 | Failed to find user \| Failed to find storage \| Failed to unmarshal storage service id \| Failed to delete storage | | - -#### PATCH - -##### Summary - -Update a storage - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| --------- | ---------- | ------------- | -------- | -------------------------------------------------- | -| storageId | path | Storage ID | Yes | integer | -| patch | body | Patch request | Yes | [v1.UpdateStorageRequest](#v1updatestoragerequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------------------------------------------- | ------------------------------ | -| 200 | Updated resource | [store.Storage](#storestorage) | -| 400 | ID is not a number: %s \| Malformatted patch storage request \| Malformatted post storage request | | -| 401 | Missing user in session \| Unauthorized | | -| 500 | Failed to find user \| Failed to patch storage \| Failed to convert storage | | - ---- - -### /api/v1/system/setting - -#### GET - -##### Summary - -Get a list of system settings - -##### Responses - -| Code | Description | Schema | -| ---- | --------------------------------------------------------- | ---------------------------------------- | -| 200 | System setting list | [ [v1.SystemSetting](#v1systemsetting) ] | -| 401 | Missing user in session \| Unauthorized | | -| 500 | Failed to find user \| Failed to find system setting list | | - -#### POST - -##### Summary - -Create system setting - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | --------------- | -------- | -------------------------------------------------------------- | -| body | body | Request object. | Yes | [v1.UpsertSystemSettingRequest](#v1upsertsystemsettingrequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------------- | ------------------------------------------ | -| 200 | Created system setting | [store.SystemSetting](#storesystemsetting) | -| 400 | Malformatted post system setting request \| invalid system setting | | -| 401 | Missing user in session \| Unauthorized | | -| 403 | Cannot disable passwords if no SSO identity provider is configured. | | -| 500 | Failed to find user \| Failed to upsert system setting | | - ---- - -### /api/v1/tag - -#### GET - -##### Summary - -Get a list of tags - -##### Responses - -| Code | Description | Schema | -| ---- | --------------------------- | ---------- | -| 200 | Tag list | [ string ] | -| 400 | Missing user id to find tag | | -| 500 | Failed to find tag list | | - -#### POST - -##### Summary - -Create a tag - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | --------------- | -------- | ------------------------------------------ | -| body | body | Request object. | Yes | [v1.UpsertTagRequest](#v1upserttagrequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------ | ------ | -| 200 | Created tag name | string | -| 400 | Malformatted post tag request \| Tag name shouldn't be empty | | -| 401 | Missing user in session | | -| 500 | Failed to upsert tag \| Failed to create activity | | - -### /api/v1/tag/delete - -#### POST - -##### Summary - -Delete a tag - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | --------------- | -------- | ------------------------------------------ | -| body | body | Request object. | Yes | [v1.DeleteTagRequest](#v1deletetagrequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------ | ------- | -| 200 | Tag deleted | boolean | -| 400 | Malformatted post tag request \| Tag name shouldn't be empty | | -| 401 | Missing user in session | | -| 500 | Failed to delete tag name: %v | | - -### /api/v1/tag/suggestion - -#### GET - -##### Summary - -Get a list of tags suggested from other memos contents - -##### Responses - -| Code | Description | Schema | -| ---- | --------------------------------------------------- | ---------- | -| 200 | Tag list | [ string ] | -| 400 | Missing user session | | -| 500 | Failed to find memo list \| Failed to find tag list | | - ---- - -### /api/v1/user - -#### GET - -##### Summary - -Get a list of users - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------- | ---------------------------- | -| 200 | User list | [ [store.User](#storeuser) ] | -| 500 | Failed to fetch user list | | - -#### POST - -##### Summary - -Create a user - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | -------------- | -------- | -------------------------------------------- | -| body | body | Request object | Yes | [v1.CreateUserRequest](#v1createuserrequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| 200 | Created user | [store.User](#storeuser) | -| 400 | Malformatted post user request \| Invalid user create format | | -| 401 | Missing auth session \| Unauthorized to create user | | -| 403 | Could not create host user | | -| 500 | Failed to find user by id \| Failed to generate password hash \| Failed to create user \| Failed to create activity | | - -### /api/v1/user/{id} - -#### DELETE - -##### Summary - -Delete a user - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | ----------- | -------- | ------ | -| id | path | User ID | Yes | string | - -##### Responses - -| Code | Description | Schema | -| ---- | -------------------------------------------------------------------- | ------- | -| 200 | User deleted | boolean | -| 400 | ID is not a number: %s \| Current session user not found with ID: %d | | -| 401 | Missing user in session | | -| 403 | Unauthorized to delete user | | -| 500 | Failed to find user \| Failed to delete user | | - -#### GET - -##### Summary - -Get user by id - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | ----------- | -------- | ------- | -| id | path | User ID | Yes | integer | - -##### Responses - -| Code | Description | Schema | -| ---- | -------------------- | ------------------------ | -| 200 | Requested user | [store.User](#storeuser) | -| 400 | Malformatted user id | | -| 404 | User not found | | -| 500 | Failed to find user | | - -#### PATCH - -##### Summary - -Update a user - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ----- | ---------- | ------------- | -------- | -------------------------------------------- | -| id | path | User ID | Yes | string | -| patch | body | Patch request | Yes | [v1.UpdateUserRequest](#v1updateuserrequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -| 200 | Updated user | [store.User](#storeuser) | -| 400 | ID is not a number: %s \| Current session user not found with ID: %d \| Malformatted patch user request \| Invalid update user request | | -| 401 | Missing user in session | | -| 403 | Unauthorized to update user | | -| 500 | Failed to find user \| Failed to generate password hash \| Failed to patch user \| Failed to find userSettingList | | - -### /api/v1/user/me - -#### GET - -##### Summary - -Get current user - -##### Responses - -| Code | Description | Schema | -| ---- | ----------------------------------------------------- | ------------------------ | -| 200 | Current user | [store.User](#storeuser) | -| 401 | Missing auth session | | -| 500 | Failed to find user \| Failed to find userSettingList | | - -### /api/v1/user/name/{username} - -#### GET - -##### Summary - -Get user by username - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| -------- | ---------- | ----------- | -------- | ------ | -| username | path | Username | Yes | string | - -##### Responses - -| Code | Description | Schema | -| ---- | ------------------- | ------------------------ | -| 200 | Requested user | [store.User](#storeuser) | -| 404 | User not found | | -| 500 | Failed to find user | | - ---- - -### /api/v1/user/setting - -#### POST - -##### Summary - -Upsert user setting - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | --------------- | -------- | ---------------------------------------------------------- | -| body | body | Request object. | Yes | [v1.UpsertUserSettingRequest](#v1upsertusersettingrequest) | - -##### Responses - -| Code | Description | Schema | -| ---- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | -| 200 | Created user setting | [github_com_usememos_memos_store.UserSetting](#github_com_usememos_memos_storeusersetting) | -| 400 | Malformatted post user setting upsert request \| Invalid user setting format | | -| 401 | Missing auth session | | -| 500 | Failed to upsert user setting | | - ---- - -### /explore/rss.xml - -#### GET - -##### Summary - -Get RSS - -##### Responses - -| Code | Description | -| ---- | --------------------------------------------------------------------------------------------- | -| 200 | RSS | -| 500 | Failed to get system customized profile \| Failed to find memo list \| Failed to generate rss | - -### /u/{id}/rss.xml - -#### GET - -##### Summary - -Get RSS for a user - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | ----------- | -------- | ------- | -| id | path | User ID | Yes | integer | - -##### Responses - -| Code | Description | -| ---- | --------------------------------------------------------------------------------------------- | -| 200 | RSS | -| 400 | User id is not a number | -| 500 | Failed to get system customized profile \| Failed to find memo list \| Failed to generate rss | - ---- - -### /o/get/GetImage - -#### GET - -##### Summary - -Get GetImage from URL - -##### Parameters - -| Name | Located in | Description | Required | Schema | -| ---- | ---------- | ----------- | -------- | ------ | -| url | query | Image url | Yes | string | - -##### Responses - -| Code | Description | -| ---- | ------------------------------------------------------------------- | -| 200 | Image | -| 400 | Missing GetImage url \| Wrong url \| Failed to get GetImage url: %s | -| 500 | Failed to write GetImage blob | - ---- - -### Models - -#### github_com_usememos_memos_store.UserSetting - -| Name | Type | Description | Required | -| ------ | ------- | ----------- | -------- | -| key | string | | No | -| userID | integer | | No | -| value | string | | No | - -#### profile.Profile - -| Name | Type | Description | Required | -| ------- | ------ | --------------------------------------------- | -------- | -| driver | string | Driver is the database driver sqlite, mysql | No | -| dsn | string | DSN points to where Memos stores its own data | No | -| mode | string | Mode can be "prod" or "dev" or "demo" | No | -| version | string | Version is the current version of server | No | - -#### store.FieldMapping - -| Name | Type | Description | Required | -| ----------- | ------ | ----------- | -------- | -| displayName | string | | No | -| email | string | | No | -| identifier | string | | No | - -#### store.IdentityProvider - -| Name | Type | Description | Required | -| ---------------- | ------------------------------------------------------------ | ----------- | -------- | -| config | [store.IdentityProviderConfig](#storeidentityproviderconfig) | | No | -| id | integer | | No | -| identifierFilter | string | | No | -| name | string | | No | -| type | [store.IdentityProviderType](#storeidentityprovidertype) | | No | - -#### store.IdentityProviderConfig - -| Name | Type | Description | Required | -| ------------ | ------------------------------------------------------------------------ | ----------- | -------- | -| oauth2Config | [store.IdentityProviderOAuth2Config](#storeidentityprovideroauth2config) | | No | - -#### store.IdentityProviderOAuth2Config - -| Name | Type | Description | Required | -| ------------ | ---------------------------------------- | ----------- | -------- | -| authUrl | string | | No | -| clientId | string | | No | -| clientSecret | string | | No | -| fieldMapping | [store.FieldMapping](#storefieldmapping) | | No | -| scopes | [ string ] | | No | -| tokenUrl | string | | No | -| userInfoUrl | string | | No | - -#### store.IdentityProviderType - -| Name | Type | Description | Required | -| -------------------------- | ------ | ----------- | -------- | -| store.IdentityProviderType | string | | | - -#### store.Memo - -| Name | Type | Description | Required | -| -------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | -| content | string | Domain specific fields | No | -| createdTs | integer | | No | -| creatorID | integer | | No | -| id | integer | | No | -| parentID | integer | Composed fields For those comment memos, the parent ID is the memo ID of the memo being commented. If the parent ID is nil, then this memo is not a comment. | No | -| pinned | boolean | | No | -| relationList | [ [store.MemoRelation](#storememorelation) ] | | No | -| resourceIDList | [ integer ] | | No | -| rowStatus | [store.RowStatus](#storerowstatus) | Standard fields | No | -| updatedTs | integer | | No | -| visibility | [store.Visibility](#storevisibility) | | No | - -#### store.MemoRelation - -| Name | Type | Description | Required | -| ------------- | ------------------------------------------------ | ----------- | -------- | -| memoID | integer | | No | -| relatedMemoID | integer | | No | -| type | [store.MemoRelationType](#storememorelationtype) | | No | - -#### store.MemoRelationType - -| Name | Type | Description | Required | -| ---------------------- | ------ | ----------- | -------- | -| store.MemoRelationType | string | | | - -#### store.Resource - -| Name | Type | Description | Required | -| ------------ | ----------- | ---------------------- | -------- | -| blob | [ integer ] | | No | -| createdTs | integer | | No | -| creatorID | integer | Standard fields | No | -| externalLink | string | | No | -| filename | string | Domain specific fields | No | -| id | integer | | No | -| internalPath | string | | No | -| memoID | integer | | No | -| size | integer | | No | -| type | string | | No | -| updatedTs | integer | | No | - -#### store.Role - -| Name | Type | Description | Required | -| ---------- | ------ | ----------- | -------- | -| store.Role | string | | | - -#### store.RowStatus - -| Name | Type | Description | Required | -| --------------- | ------ | ----------- | -------- | -| store.RowStatus | string | | | - -#### store.Storage - -| Name | Type | Description | Required | -| ------ | ------- | ----------- | -------- | -| config | string | | No | -| id | integer | | No | -| name | string | | No | -| type | string | | No | - -#### store.SystemSetting - -| Name | Type | Description | Required | -| ----------- | ------ | ----------- | -------- | -| description | string | | No | -| name | string | | No | -| value | string | | No | - -#### store.User - -| Name | Type | Description | Required | -| ------------ | ---------------------------------- | ---------------------- | -------- | -| avatarURL | string | | No | -| createdTs | integer | | No | -| email | string | | No | -| id | integer | | No | -| nickname | string | | No | -| passwordHash | string | | No | -| role | [store.Role](#storerole) | | No | -| rowStatus | [store.RowStatus](#storerowstatus) | Standard fields | No | -| updatedTs | integer | | No | -| username | string | Domain specific fields | No | - -#### store.Visibility - -| Name | Type | Description | Required | -| ---------------- | ------ | ----------- | -------- | -| store.Visibility | string | | | - -#### v1.CreateIdentityProviderRequest - -| Name | Type | Description | Required | -| ---------------- | ------------------------------------------------------ | ----------- | -------- | -| config | [v1.IdentityProviderConfig](#v1identityproviderconfig) | | No | -| identifierFilter | string | | No | -| name | string | | No | -| type | [v1.IdentityProviderType](#v1identityprovidertype) | | No | - -#### v1.CreateMemoRequest - -| Name | Type | Description | Required | -| -------------- | ---------------------------------------------------------------- | ---------------------- | -------- | -| content | string | | No | -| createdTs | integer | | No | -| relationList | [ [v1.UpsertMemoRelationRequest](#v1upsertmemorelationrequest) ] | | No | -| resourceIdList | [ integer ] | Related fields | No | -| visibility | [v1.Visibility](#v1visibility) | Domain specific fields | No | - -#### v1.CreateResourceRequest - -| Name | Type | Description | Required | -| ------------ | ------ | ----------- | -------- | -| externalLink | string | | No | -| filename | string | | No | -| type | string | | No | - -#### v1.CreateStorageRequest - -| Name | Type | Description | Required | -| ------ | ------------------------------------ | ----------- | -------- | -| config | [v1.StorageConfig](#v1storageconfig) | | No | -| name | string | | No | -| type | [v1.StorageType](#v1storagetype) | | No | - -#### v1.CreateUserRequest - -| Name | Type | Description | Required | -| -------- | ------------------ | ----------- | -------- | -| email | string | | No | -| nickname | string | | No | -| password | string | | No | -| role | [v1.Role](#v1role) | | No | -| username | string | | No | - -#### v1.CustomizedProfile - -| Name | Type | Description | Required | -| ----------- | ------ | ----------------------------------------------------------------------- | -------- | -| appearance | string | Appearance is the server default appearance. | No | -| description | string | Description is the server description. | No | -| externalUrl | string | ExternalURL is the external url of server. e.g. | No | -| locale | string | Locale is the server default locale. | No | -| logoUrl | string | LogoURL is the url of logo image. | No | -| name | string | Name is the server name, default is `memos` | No | - -#### v1.DeleteTagRequest - -| Name | Type | Description | Required | -| ---- | ------ | ----------- | -------- | -| name | string | | No | - -#### v1.FieldMapping - -| Name | Type | Description | Required | -| ----------- | ------ | ----------- | -------- | -| displayName | string | | No | -| email | string | | No | -| identifier | string | | No | - -#### v1.IdentityProvider - -| Name | Type | Description | Required | -| ---------------- | ------------------------------------------------------ | ----------- | -------- | -| config | [v1.IdentityProviderConfig](#v1identityproviderconfig) | | No | -| id | integer | | No | -| identifierFilter | string | | No | -| name | string | | No | -| type | [v1.IdentityProviderType](#v1identityprovidertype) | | No | - -#### v1.IdentityProviderConfig - -| Name | Type | Description | Required | -| ------------ | ------------------------------------------------------------------ | ----------- | -------- | -| oauth2Config | [v1.IdentityProviderOAuth2Config](#v1identityprovideroauth2config) | | No | - -#### v1.IdentityProviderOAuth2Config - -| Name | Type | Description | Required | -| ------------ | ---------------------------------- | ----------- | -------- | -| authUrl | string | | No | -| clientId | string | | No | -| clientSecret | string | | No | -| fieldMapping | [v1.FieldMapping](#v1fieldmapping) | | No | -| scopes | [ string ] | | No | -| tokenUrl | string | | No | -| userInfoUrl | string | | No | - -#### v1.IdentityProviderType - -| Name | Type | Description | Required | -| ----------------------- | ------ | ----------- | -------- | -| v1.IdentityProviderType | string | | | - -#### v1.MemoRelationType - -| Name | Type | Description | Required | -| ------------------- | ------ | ----------- | -------- | -| v1.MemoRelationType | string | | | - -#### v1.PatchMemoRequest - -| Name | Type | Description | Required | -| -------------- | ---------------------------------------------------------------- | ---------------------- | -------- | -| content | string | Domain specific fields | No | -| createdTs | integer | Standard fields | No | -| relationList | [ [v1.UpsertMemoRelationRequest](#v1upsertmemorelationrequest) ] | | No | -| resourceIdList | [ integer ] | Related fields | No | -| rowStatus | [v1.RowStatus](#v1rowstatus) | | No | -| updatedTs | integer | | No | -| visibility | [v1.Visibility](#v1visibility) | | No | - -#### v1.Role - -| Name | Type | Description | Required | -| ------- | ------ | ----------- | -------- | -| v1.Role | string | | | - -#### v1.RowStatus - -| Name | Type | Description | Required | -| ------------ | ------ | ----------- | -------- | -| v1.RowStatus | string | | | - -#### v1.SSOSignIn - -| Name | Type | Description | Required | -| ------------------ | ------- | ----------- | -------- | -| code | string | | No | -| identityProviderId | integer | | No | -| redirectUri | string | | No | - -#### v1.SignIn - -| Name | Type | Description | Required | -| -------- | ------ | ----------- | -------- | -| password | string | | No | -| username | string | | No | - -#### v1.SignUp - -| Name | Type | Description | Required | -| -------- | ------ | ----------- | -------- | -| password | string | | No | -| username | string | | No | - -#### v1.StorageConfig - -| Name | Type | Description | Required | -| -------- | ---------------------------------------- | ----------- | -------- | -| s3Config | [v1.StorageS3Config](#v1storages3config) | | No | - -#### v1.StorageS3Config - -| Name | Type | Description | Required | -| --------- | ------ | ----------- | -------- | -| accessKey | string | | No | -| bucket | string | | No | -| endPoint | string | | No | -| path | string | | No | -| region | string | | No | -| secretKey | string | | No | -| urlPrefix | string | | No | -| urlSuffix | string | | No | - -#### v1.StorageType - -| Name | Type | Description | Required | -| -------------- | ------ | ----------- | -------- | -| v1.StorageType | string | | | - -#### v1.SystemSetting - -| Name | Type | Description | Required | -| ----------- | -------------------------------------------- | ---------------------------------------- | -------- | -| description | string | | No | -| name | [v1.SystemSettingName](#v1systemsettingname) | | No | -| value | string | Value is a JSON string with basic value. | No | - -#### v1.SystemSettingName - -| Name | Type | Description | Required | -| -------------------- | ------ | ----------- | -------- | -| v1.SystemSettingName | string | | | - -#### v1.SystemStatus - -| Name | Type | Description | Required | -| ------------------------ | -------------------------------------------- | ------------------------------------------------------------------ | -------- | -| additionalScript | string | Additional script. | No | -| additionalStyle | string | Additional style. | No | -| allowSignUp | boolean | System settings Allow sign up. | No | -| autoBackupInterval | integer | Auto Backup Interval. | No | -| customizedProfile | [v1.CustomizedProfile](#v1customizedprofile) | Customized server profile, including server name and external url. | No | -| dbSize | integer | | No | -| disablePasswordLogin | boolean | Disable password login. | No | -| disablePublicMemos | boolean | Disable public memos. | No | -| host | [v1.User](#v1user) | | No | -| localStoragePath | string | Local storage path. | No | -| maxUploadSizeMiB | integer | Max upload size. | No | -| memoDisplayWithUpdatedTs | boolean | Memo display with updated timestamp. | No | -| profile | [profile.Profile](#profileprofile) | | No | -| storageServiceId | integer | Storage service ID. | No | - -#### v1.UpdateIdentityProviderRequest - -| Name | Type | Description | Required | -| ---------------- | ------------------------------------------------------ | ----------- | -------- | -| config | [v1.IdentityProviderConfig](#v1identityproviderconfig) | | No | -| identifierFilter | string | | No | -| name | string | | No | -| type | [v1.IdentityProviderType](#v1identityprovidertype) | | No | - -#### v1.UpdateResourceRequest - -| Name | Type | Description | Required | -| -------- | ------ | ----------- | -------- | -| filename | string | | No | - -#### v1.UpdateStorageRequest - -| Name | Type | Description | Required | -| ------ | ------------------------------------ | ----------- | -------- | -| config | [v1.StorageConfig](#v1storageconfig) | | No | -| name | string | | No | -| type | [v1.StorageType](#v1storagetype) | | No | - -#### v1.UpdateUserRequest - -| Name | Type | Description | Required | -| --------- | ---------------------------- | ----------- | -------- | -| avatarUrl | string | | No | -| email | string | | No | -| nickname | string | | No | -| password | string | | No | -| rowStatus | [v1.RowStatus](#v1rowstatus) | | No | -| username | string | | No | - -#### v1.UpsertMemoOrganizerRequest - -| Name | Type | Description | Required | -| ------ | ------- | ----------- | -------- | -| pinned | boolean | | No | - -#### v1.UpsertMemoRelationRequest - -| Name | Type | Description | Required | -| ------------- | ------------------------------------------ | ----------- | -------- | -| relatedMemoId | integer | | No | -| type | [v1.MemoRelationType](#v1memorelationtype) | | No | - -#### v1.UpsertSystemSettingRequest - -| Name | Type | Description | Required | -| ----------- | -------------------------------------------- | ----------- | -------- | -| description | string | | No | -| name | [v1.SystemSettingName](#v1systemsettingname) | | No | -| value | string | | No | - -#### v1.UpsertTagRequest - -| Name | Type | Description | Required | -| ---- | ------ | ----------- | -------- | -| name | string | | No | - -#### v1.UpsertUserSettingRequest - -| Name | Type | Description | Required | -| ----- | -------------------------------------- | ----------- | -------- | -| key | [v1.UserSettingKey](#v1usersettingkey) | | No | -| value | string | | No | - -#### v1.User - -| Name | Type | Description | Required | -| --------------- | ------------------------------------ | ---------------------- | -------- | -| avatarUrl | string | | No | -| createdTs | integer | | No | -| email | string | | No | -| id | integer | | No | -| nickname | string | | No | -| role | [v1.Role](#v1role) | | No | -| rowStatus | [v1.RowStatus](#v1rowstatus) | Standard fields | No | -| updatedTs | integer | | No | -| userSettingList | [ [v1.UserSetting](#v1usersetting) ] | | No | -| username | string | Domain specific fields | No | - -#### v1.UserSetting - -| Name | Type | Description | Required | -| ------ | -------------------------------------- | ----------- | -------- | -| key | [v1.UserSettingKey](#v1usersettingkey) | | No | -| userId | integer | | No | -| value | string | | No | - -#### v1.UserSettingKey - -| Name | Type | Description | Required | -| ----------------- | ------ | ----------- | -------- | -| v1.UserSettingKey | string | | | - -#### v1.Visibility - -| Name | Type | Description | Required | -| ------------- | ------ | ----------- | -------- | -| v1.Visibility | string | | | diff --git a/docs/development-windows.md b/docs/development-windows.md index ba3f88bd4a261..097ed7a16c066 100644 --- a/docs/development-windows.md +++ b/docs/development-windows.md @@ -56,12 +56,12 @@ Memos should now be running at [http://localhost:3001](http://localhost:3001) an ## Building -Frontend must be built before backend. The built frontend must be placed in the backend ./server/dist directory. Otherwise, you will get a "No frontend embeded" error. +Frontend must be built before backend. The built frontend must be placed in the backend ./server/frontend/dist directory. Otherwise, you will get a "No frontend embedded" error. ### Frontend ```powershell -Move-Item "./server/dist" "./server/dist.bak" +Move-Item "./server/frontend/dist" "./server/frontend/dist.bak" cd web; pnpm i --frozen-lockfile; pnpm build; cd ..; Move-Item "./web/dist" "./server/" -Force ``` @@ -69,7 +69,7 @@ Move-Item "./web/dist" "./server/" -Force ### Backend ```powershell -go build -o ./build/memos.exe ./main.go +go build -o ./build/memos.exe ./bin/memos/main.go ``` ## ❕ Notes diff --git a/docs/development.md b/docs/development.md index 711886ccc9573..53511ab963a3d 100644 --- a/docs/development.md +++ b/docs/development.md @@ -21,7 +21,7 @@ Memos is built with a curated tech stack. It is optimized for developer experien git clone https://github.com/usememos/memos ``` -2. Start backend server with `air`(with live reload) +2. Start backend server with [`air`](https://github.com/cosmtrek/air) (with live reload) ```bash air -c scripts/.air.toml @@ -30,7 +30,7 @@ Memos is built with a curated tech stack. It is optimized for developer experien 3. Install frontend dependencies and generate TypeScript code from protobuf ``` - cd web && pnpm i && pnpm type-gen + cd web && pnpm i ``` 4. Start the dev server of frontend diff --git a/docs/documenting-the-api.md b/docs/documenting-the-api.md deleted file mode 100644 index 7eac6bbef08c4..0000000000000 --- a/docs/documenting-the-api.md +++ /dev/null @@ -1,113 +0,0 @@ -# Documenting the API - -## Principles - -- The documentation is generated by [swaggo/swag](https://github.com/swaggo/swag) from comments in the API code. - -- Documentation is written using [Declarative Comments Format](https://github.com/swaggo/swag#declarative-comments-format). - -- The documentation is generated in the `./api/v1` folder as `docs.go`. - -- [echo-swagger](https://github.com/swaggo/echo-swagger) is used to integrate with Echo framework and serve the documentation with [Swagger-UI](https://swagger.io/tools/swagger-ui/) at `http://memos.host:5230/api/index.html` - -## Updating the documentation - -1. Update or add API-related comments in the code. Make sure to follow the [Declarative Comments Format](https://github.com/swaggo/swag#declarative-comments-format): - - ```go - // signIn godoc - // - // @Summary Sign-in to memos. - // @Tags auth - // @Accept json - // @Produce json - // @Param body body SignIn true "Sign-in object" - // @Success 200 {object} store.User "User information" - // @Failure 400 {object} nil "Malformatted signin request" - // @Failure 401 {object} nil "Password login is deactivated | Incorrect login credentials, please try again" - // @Failure 403 {object} nil "User has been archived with username {username}" - // @Failure 500 {object} nil "Failed to find system setting | Failed to unmarshal system setting | Incorrect login credentials, please try again | Failed to generate tokens | Failed to create activity" - // @Router /api/v1/auth/signin [POST] - func (s *APIV1Service) signIn(c echo.Context) error { - ... - ``` - - > Sample from [api/v1/auth.go](https://github.com/usememos/memos/tree/main/api/v1/auth.go) - > You can check existing comments at [api/v1](https://github.com/usememos/memos/tree/main/api/v1) - -2. Run one of the following provided scripts: - - - Linux: `./scripts/gen-api-v1-docs.sh` (remember to `chmod +x` the script first) - - Windows: `./scripts/gen-api-v1-docs.ps1` - - > The scripts will install swag if needed (via go install), then run `swag fmt` and `swag init` commands. - -3. That's it! The documentation is updated. You can check it at `http://memos.host:5230/api/index.html` - -### Extra tips - -- If you reference a custom Go struct from outside the API file, use a relative definition, like `store.IdentityProvider`. This works because `./` is passed to swag at `--dir` argument. If swag can't resolve the reference, it will fail. - -- If the API grows or you need to reference some type from another location, remember to update ./scripts/gen-api-v1-docs.cfg file with the new paths. - -- It's possible to list multiple errors for the same code using enum-like structs, that will show a proper, spec-conformant model with all entries at Swagger-UI. The drawback is that this approach requires a major refactoring and will add a lot of boilerplate code, as there are inconsistencies between API methods error responses. - - ```go - type signInInternalServerError string - - const signInErrorFailedToFindSystemSetting signInInternalServerError = "Failed to find system setting" - const signInErrorFailedToUnmarshalSystemSetting signInInternalServerError = "Failed to unmarshal system setting" - const signInErrorIncorrectLoginCredentials signInInternalServerError = "Incorrect login credentials, please try again" - const signInErrorFailedToGenerateTokens signInInternalServerError = "Failed to generate tokens" - const signInErrorFailedToCreateActivity signInInternalServerError = "Failed to create activity" - - type signInUnauthorized string - - const signInErrorPasswordLoginDeactivated signInUnauthorized = "Password login is deactivated" - const signInErrorIncorrectCredentials signInUnauthorized = "Incorrect login credentials, please try again" - - // signIn godoc - // - // @Summary Sign-in to memos. - // @Tags auth - // @Accept json - // @Produce json - // @Param body body SignIn true "Sign-in object" - // @Success 200 {object} store.User "User information" - // @Failure 400 {object} nil "Malformatted signin request" - // @Failure 401 {object} signInUnauthorized - // @Failure 403 {object} nil "User has been archived with username {username}" - // @Failure 500 {object} signInInternalServerError - // @Router /api/v1/auth/signin [POST] - func (s *APIV1Service) signIn(c echo.Context) error { - ... - ``` - -### Step-by-step (no scripts) - -#### Required tools - -```bash -# Swag v1.8.12 or newer -# Also updates swag if needed -$ go install github.com/swaggo/swag/cmd/swag@latest -``` - -If `$HOME/go/bin` is not in your `PATH`, you can call `swag` directly at `$HOME/go/bin/swag`. - -#### Generate the documentation - -1. Run `swag fmt` to format the comments - - ```bash - swag fmt --dir ./api/v1 && go fmt - ``` - -2. Run `swag init` to generate the documentation - - ```bash - cd - swag init --output ./api/v1 --generalInfo ./api/v1/v1.go --dir ./,./api/v1 - ``` - -> If the API gets a new version, you'll need to add the file system path to swag's `--dir` parameter. diff --git a/docs/windows-service.md b/docs/windows-service.md deleted file mode 100644 index f0e98c878c0d9..0000000000000 --- a/docs/windows-service.md +++ /dev/null @@ -1,98 +0,0 @@ -# Installing memos as a service on Windows - -While memos first-class support is for Docker, you may also install memos as a Windows service. It will run under SYSTEM account and start automatically at system boot. - -❗ All service management methods requires admin privileges. Use [gsudo](https://gerardog.github.io/gsudo/docs/install), or open a new PowerShell terminal as admin: - -```powershell -Start-Process powershell -Verb RunAs -``` - -## Choose one of the following methods - -### 1. Using [NSSM](https://nssm.cc/download) - -NSSM is a lightweight service wrapper. - -You may put `nssm.exe` in the same directory as `memos.exe`, or add its directory to your system PATH. Prefer the latest 64-bit version of `nssm.exe`. - -```powershell -# Install memos as a service -nssm install memos "C:\path\to\memos.exe" --mode prod --port 5230 - -# Delay auto start -nssm set memos DisplayName "memos service" - -# Configure extra service parameters -nssm set memos Description "A lightweight, self-hosted memo hub. https://usememos.com/" - -# Delay auto start -nssm set memos Start SERVICE_DELAYED_AUTO_START - -# Edit service using NSSM GUI -nssm edit memos - -# Start the service -nssm start memos - -# Remove the service, if ever needed -nssm remove memos confirm -``` - -### 2. Using [WinSW](https://github.com/winsw/winsw) - -Find the latest release tag and download the asset `WinSW-net46x.exe`. Then, put it in the same directory as `memos.exe` and rename it to `memos-service.exe`. - -Now, in the same directory, create the service configuration file `memos-service.xml`: - -```xml - - memos - memos service - A lightweight, self-hosted memo hub. https://usememos.com/ - - %BASE%\memos.exe - --mode prod --port 5230 - true - - -``` - -Then, install the service: - -```powershell -# Install the service -.\memos-service.exe install - -# Start the service -.\memos-service.exe start - -# Remove the service, if ever needed -.\memos-service.exe uninstall -``` - -### Manage the service - -You may use the `net` command to manage the service: - -```powershell -net start memos -net stop memos -``` - -Also, by using one of the provided methods, the service will appear in the Windows Services Manager `services.msc`. - -## Notes - -- On Windows, memos store its data in the following directory: - - ```powershell - $env:ProgramData\memos - # Typically, this will resolve to C:\ProgramData\memos - ``` - - You may specify a custom directory by appending `--data ` to the service command line. - -- If the service fails to start, you should inspect the Windows Event Viewer `eventvwr.msc`. - -- Memos will be accessible at [http://localhost:5230](http://localhost:5230) by default. diff --git a/go.mod b/go.mod index 62a1ec3ce6aac..492641f46e569 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,13 @@ module github.com/usememos/memos -go 1.21 +go 1.22 require ( - github.com/aws/aws-sdk-go-v2 v1.21.2 - github.com/aws/aws-sdk-go-v2/config v1.19.1 - github.com/aws/aws-sdk-go-v2/credentials v1.13.43 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.92 - github.com/aws/aws-sdk-go-v2/service/s3 v1.40.2 + github.com/aws/aws-sdk-go-v2 v1.25.0 + github.com/aws/aws-sdk-go-v2/config v1.27.0 + github.com/aws/aws-sdk-go-v2/credentials v1.17.0 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.2 + github.com/aws/aws-sdk-go-v2/service/s3 v1.50.1 github.com/disintegration/imaging v1.6.2 github.com/go-sql-driver/mysql v1.7.1 github.com/go-zoox/connect-middleware-for-echo v1.0.0 @@ -18,24 +18,25 @@ require ( github.com/gorilla/feeds v1.1.1 github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 github.com/improbable-eng/grpc-web v0.15.0 - github.com/labstack/echo/v4 v4.11.2 + github.com/joho/godotenv v1.5.1 + github.com/labstack/echo/v4 v4.11.4 + github.com/lib/pq v1.10.9 + github.com/lithammer/shortuuid/v4 v4.0.0 github.com/microcosm-cc/bluemonday v1.0.26 github.com/pkg/errors v0.9.1 - github.com/spf13/cobra v1.7.0 - github.com/spf13/viper v1.17.0 + github.com/spf13/cobra v1.8.0 + github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.8.4 - github.com/swaggo/echo-swagger v1.4.1 - github.com/swaggo/swag v1.16.2 - github.com/yuin/goldmark v1.5.6 - go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.14.0 - golang.org/x/exp v0.0.0-20231006140011-7918f672742d - golang.org/x/mod v0.13.0 - golang.org/x/net v0.17.0 - golang.org/x/oauth2 v0.13.0 - google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b - google.golang.org/grpc v1.59.0 - modernc.org/sqlite v1.26.0 + github.com/swaggo/swag v1.16.3 + github.com/yourselfhosted/gomark v0.0.0-20240228170507-6a73bfad2eb6 + golang.org/x/crypto v0.19.0 + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a + golang.org/x/mod v0.15.0 + golang.org/x/net v0.21.0 + golang.org/x/oauth2 v0.17.0 + google.golang.org/genproto/googleapis/api v0.0.0-20240213162025-012b6fc9bca9 + google.golang.org/grpc v1.61.1 + modernc.org/sqlite v1.29.1 ) require ( @@ -45,7 +46,6 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/ghodss/yaml v1.0.0 // indirect github.com/go-openapi/jsonpointer v0.20.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/spec v0.20.9 // indirect @@ -57,76 +57,71 @@ require ( github.com/go-zoox/datetime v1.2.2 // indirect github.com/go-zoox/jwt v1.3.0 // indirect github.com/gorilla/css v1.0.0 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/ncruces/go-strftime v0.1.9 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rs/cors v1.10.1 // indirect - github.com/sagikazarmark/locafero v0.3.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect - github.com/swaggo/files/v2 v2.0.0 // indirect - golang.org/x/image v0.13.0 // indirect - golang.org/x/tools v0.14.0 // indirect - google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - lukechampine.com/uint128 v1.3.0 // indirect - modernc.org/cc/v3 v3.41.0 // indirect - modernc.org/ccgo/v3 v3.16.15 // indirect - modernc.org/libc v1.28.0 // indirect + golang.org/x/image v0.15.0 // indirect + golang.org/x/tools v0.18.0 // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240213162025-012b6fc9bca9 // indirect + modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect + modernc.org/libc v1.41.0 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.7.2 // indirect - modernc.org/opt v0.1.3 // indirect modernc.org/strutil v1.2.0 // indirect modernc.org/token v1.1.0 // indirect nhooyr.io/websocket v1.8.10 // indirect ) require ( - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.6 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.15 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.15.2 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.23.2 // indirect - github.com/aws/smithy-go v1.15.0 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.19.0 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.27.0 // indirect + github.com/aws/smithy-go v1.20.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/golang-jwt/jwt/v4 v4.5.0 + github.com/golang-jwt/jwt/v5 v5.2.0 github.com/golang/protobuf v1.5.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/labstack/gommon v0.4.0 // indirect + github.com/labstack/gommon v0.4.2 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.1.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/posthog/posthog-go v0.0.0-20230801140217-d607812dee69 - github.com/spf13/afero v1.10.0 // indirect - github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.5.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/protobuf v1.31.0 + google.golang.org/protobuf v1.32.0 gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index f049036267918..adc6953920d83 100644 --- a/go.sum +++ b/go.sum @@ -1,40 +1,5 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -61,44 +26,44 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.21.2 h1:+LXZ0sgo8quN9UOKXXzAWRT3FWd4NxeXWOZom9pE7GA= -github.com/aws/aws-sdk-go-v2 v1.21.2/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14 h1:Sc82v7tDQ/vdU1WtuSyzZ1I7y/68j//HJ6uozND1IDs= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.14/go.mod h1:9NCTOURS8OpxvoAVHq79LK81/zC78hfRWFn+aL0SPcY= -github.com/aws/aws-sdk-go-v2/config v1.19.1 h1:oe3vqcGftyk40icfLymhhhNysAwk0NfiwkDi2GTPMXs= -github.com/aws/aws-sdk-go-v2/config v1.19.1/go.mod h1:ZwDUgFnQgsazQTnWfeLWk5GjeqTQTL8lMkoE1UXzxdE= -github.com/aws/aws-sdk-go-v2/credentials v1.13.43 h1:LU8vo40zBlo3R7bAvBVy/ku4nxGEyZe9N8MqAeFTzF8= -github.com/aws/aws-sdk-go-v2/credentials v1.13.43/go.mod h1:zWJBz1Yf1ZtX5NGax9ZdNjhhI4rgjfgsyk6vTY1yfVg= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 h1:PIktER+hwIG286DqXyvVENjgLTAwGgoeriLDD5C+YlQ= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13/go.mod h1:f/Ib/qYjhV2/qdsf79H3QP/eRE4AkVyEf6sk7XfZ1tg= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.92 h1:nLA7dGFC6v4P6b+hzqt5GqIGmIuN+jTJzojfdOLXWFE= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.92/go.mod h1:h+ei9z19AhoN+Dac92DwkzfbJ4mFUea92xgl5pKSG0Q= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43 h1:nFBQlGtkbPzp/NjZLuFxRqmT91rLJkgvsEQs68h962Y= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37 h1:JRVhO25+r3ar2mKGP7E0LDl8K9/G36gjlqca5iQbaqc= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.37/go.mod h1:Qe+2KtKml+FEsQF/DHmDV+xjtche/hwoF75EG4UlHW8= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45 h1:hze8YsjSh8Wl1rYa1CJpRmXP21BvOBuc76YhW0HsuQ4= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.45/go.mod h1:lD5M20o09/LCuQ2mE62Mb/iSdSlCNuj6H5ci7tW7OsE= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.6 h1:wmGLw2i8ZTlHLw7a9ULGfQbuccw8uIiNr6sol5bFzc8= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.6/go.mod h1:Q0Hq2X/NuL7z8b1Dww8rmOFl+jzusKEcyvkKspwdpyc= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.15 h1:7R8uRYyXzdD71KWVCL78lJZltah6VVznXBazvKjfH58= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.15/go.mod h1:26SQUPcTNgV1Tapwdt4a1rOsYRsnBsJHLMPoxK2b0d8= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38 h1:skaFGzv+3kA+v2BPKhuekeb1Hbb105+44r8ASC+q5SE= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.38/go.mod h1:epIZoRSSbRIwLPJU5F+OldHhwZPBdpDeQkRdCeY3+00= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37 h1:WWZA/I2K4ptBS1kg0kV1JbBtG/umed0vwHRrmcr9z7k= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.37/go.mod h1:vBmDnwWXWxNPFRMmG2m/3MKOe+xEcMDo1tanpaWCcck= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6 h1:9ulSU5ClouoPIYhDQdg9tpl83d5Yb91PXTKK+17q+ow= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.6/go.mod h1:lnc2taBsR9nTlz9meD+lhFZZ9EWY712QHrRflWpTcOA= -github.com/aws/aws-sdk-go-v2/service/s3 v1.40.2 h1:Ll5/YVCOzRB+gxPqs2uD0R7/MyATC0w85626glSKmp4= -github.com/aws/aws-sdk-go-v2/service/s3 v1.40.2/go.mod h1:Zjfqt7KhQK+PO1bbOsFNzKgaq7TcxzmEoDWN8lM0qzQ= -github.com/aws/aws-sdk-go-v2/service/sso v1.15.2 h1:JuPGc7IkOP4AaqcZSIcyqLpFSqBWK32rM9+a1g6u73k= -github.com/aws/aws-sdk-go-v2/service/sso v1.15.2/go.mod h1:gsL4keucRCgW+xA85ALBpRFfdSLH4kHOVSnLMSuBECo= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3 h1:HFiiRkf1SdaAmV3/BHOFZ9DjFynPHj8G/UIO1lQS+fk= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.3/go.mod h1:a7bHA82fyUXOm+ZSWKU6PIoBxrjSprdLoM8xPYvzYVg= -github.com/aws/aws-sdk-go-v2/service/sts v1.23.2 h1:0BkLfgeDjfZnZ+MhB3ONb01u9pwFYTCZVhlsSSBvlbU= -github.com/aws/aws-sdk-go-v2/service/sts v1.23.2/go.mod h1:Eows6e1uQEsc4ZaHANmsPRzAKcVDrcmjjWiih2+HUUQ= -github.com/aws/smithy-go v1.15.0 h1:PS/durmlzvAFpQHDs4wi4sNNP9ExsqZh6IlfdHXgKK8= -github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/aws-sdk-go-v2 v1.25.0 h1:sv7+1JVJxOu/dD/sz/csHX7jFqmP001TIY7aytBWDSQ= +github.com/aws/aws-sdk-go-v2 v1.25.0/go.mod h1:G104G1Aho5WqF+SR3mDIobTABQzpYV0WxMsKxlMggOA= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0 h1:2UO6/nT1lCZq1LqM67Oa4tdgP1CvL1sLSxvuD+VrOeE= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0/go.mod h1:5zGj2eA85ClyedTDK+Whsu+w9yimnVIZvhvBKrDquM8= +github.com/aws/aws-sdk-go-v2/config v1.27.0 h1:J5sdGCAHuWKIXLeXiqr8II/adSvetkx0qdZwdbXXpb0= +github.com/aws/aws-sdk-go-v2/config v1.27.0/go.mod h1:cfh8v69nuSUohNFMbIISP2fhmblGmYEOKs5V53HiHnk= +github.com/aws/aws-sdk-go-v2/credentials v1.17.0 h1:lMW2x6sKBsiAJrpi1doOXqWFyEPoE886DTb1X0wb7So= +github.com/aws/aws-sdk-go-v2/credentials v1.17.0/go.mod h1:uT41FIH8cCIxOdUYIL0PYyHlL1NoneDuDSCwg5VE/5o= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0 h1:xWCwjjvVz2ojYTP4kBKUuUh9ZrXfcAXpflhOUUeXg1k= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0/go.mod h1:j3fACuqXg4oMTQOR2yY7m0NmJY0yBK4L4sLsRXq1Ins= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.2 h1:VEekE/fJWqAWYozxFQ07B+h8NdvTPAYhV13xIBenuO0= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.2/go.mod h1:8vozqAHmDNmoD4YbuDKIfpnLbByzngczL4My1RELLVo= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0 h1:NPs/EqVO+ajwOoq56EfcGKa3L3ruWuazkIw1BqxwOPw= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0/go.mod h1:D+duLy2ylgatV+yTlQ8JTuLfDD0BnFvnQRc+o6tbZ4M= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0 h1:ks7KGMVUMoDzcxNWUlEdI+/lokMFD136EL6DWmUOV80= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0/go.mod h1:hL6BWM/d/qz113fVitZjbXR0E+RCTU1+x+1Idyn5NgE= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.0 h1:TkbRExyKSVHELwG9gz2+gql37jjec2R5vus9faTomwE= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.0/go.mod h1:T3/9xMKudHhnj8it5EqIrhvv11tVZqWYkKcot+BFStc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0 h1:a33HuFlO0KsveiP90IUJh8Xr/cx9US2PqkSroaLc+o8= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0/go.mod h1:SxIkWpByiGbhbHYTo9CMTUnx2G4p4ZQMrDPcRRy//1c= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.0 h1:UiSyK6ent6OKpkMJN3+k5HZ4sk4UfchEaaW5wv7SblQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.0/go.mod h1:l7kzl8n8DXoRyFz5cIMG70HnPauWa649TUhgw8Rq6lo= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0 h1:SHN/umDLTmFTmYfI+gkanz6da3vK8Kvj/5wkqnTHbuA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0/go.mod h1:l8gPU5RYGOFHJqWEpPMoRTP0VoaWQSkJdKo+hwWnnDA= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.0 h1:l5puwOHr7IxECuPMIuZG7UKOzAnF24v6t4l+Z5Moay4= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.0/go.mod h1:Oov79flWa/n7Ni+lQC3z+VM7PoRM47omRqbJU9B5Y7E= +github.com/aws/aws-sdk-go-v2/service/s3 v1.50.1 h1:bjpWJEXch7moIt3PX2r5XpGROsletl7enqG1Q3Te1Dc= +github.com/aws/aws-sdk-go-v2/service/s3 v1.50.1/go.mod h1:1o/W6JFUuREj2ExoQ21vHJgO7wakvjhol91M9eknFgs= +github.com/aws/aws-sdk-go-v2/service/sso v1.19.0 h1:u6OkVDxtBPnxPkZ9/63ynEe+8kHbtS5IfaC4PzVxzWM= +github.com/aws/aws-sdk-go-v2/service/sso v1.19.0/go.mod h1:YqbU3RS/pkDVu+v+Nwxvn0i1WB0HkNWEePWbmODEbbs= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.0 h1:6DL0qu5+315wbsAEEmzK+P9leRwNbkp+lGjPC+CEvb8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.0/go.mod h1:olUAyg+FaoFaL/zFaeQQONjOZ9HXoxgvI/c7mQTYz7M= +github.com/aws/aws-sdk-go-v2/service/sts v1.27.0 h1:cjTRjh700H36MQ8M0LnDn33W3JmwC77mdxIIyPWCdpM= +github.com/aws/aws-sdk-go-v2/service/sts v1.27.0/go.mod h1:nXfOBMWPokIbOY+Gi7a1psWMSvskUCemZzI+SMB7Akc= +github.com/aws/smithy-go v1.20.0 h1:6+kZsCXZwKxZS9RfISnPc4EXlHoyAkm2hPuM8X2BrrQ= +github.com/aws/smithy-go v1.20.0/go.mod h1:uo5RKksAl4PzhqaAbjd4rLgFoq5koTsQKYuGe7dklGc= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -112,21 +77,16 @@ github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqy github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -149,23 +109,18 @@ github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4s github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -225,27 +180,18 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= +github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -268,40 +214,18 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= @@ -334,6 +258,8 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= @@ -342,8 +268,6 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -355,6 +279,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -364,20 +290,15 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -387,13 +308,17 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/labstack/echo/v4 v4.11.2 h1:T+cTLQxWCDfqDEoydYm5kCobjmHwOwcv4OJAPHilmdE= -github.com/labstack/echo/v4 v4.11.2/go.mod h1:UcGuQ8V6ZNRmSweBIJkPvGfwCMIlFmiqrPqiEBfPYws= -github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= -github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8= +github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8= +github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= +github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lithammer/shortuuid/v4 v4.0.0 h1:QRbbVkfgNippHOS8PXDkti4NaWeyYfcBTHtw7k08o4c= +github.com/lithammer/shortuuid/v4 v4.0.0/go.mod h1:Zs8puNcrvf2rV9rTH51ZLLcj7ZXqQI3lv67aw4KiB1Y= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= @@ -403,13 +328,11 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= @@ -444,6 +367,8 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= @@ -463,8 +388,8 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= +github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -473,13 +398,10 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posthog/posthog-go v0.0.0-20230801140217-d607812dee69 h1:01dHVodha5BzrMtVmcpPeA4VYbZEsTXQ6m4123zQXJk= -github.com/posthog/posthog-go v0.0.0-20230801140217-d607812dee69/go.mod h1:migYMxlAqcnQy+3eN8mcL0b2tpKy6R+8Zc0lxwk4dKM= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= @@ -515,8 +437,8 @@ github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ= -github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= @@ -532,18 +454,18 @@ github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4k github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= -github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= -github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= -github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= -github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -556,7 +478,6 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -566,12 +487,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/swaggo/echo-swagger v1.4.1 h1:Yf0uPaJWp1uRtDloZALyLnvdBeoEL5Kc7DtnjzO/TUk= -github.com/swaggo/echo-swagger v1.4.1/go.mod h1:C8bSi+9yH2FLZsnhqMZLIZddpUxZdBYuNHbtaS1Hljc= -github.com/swaggo/files/v2 v2.0.0 h1:hmAt8Dkynw7Ssz46F6pn8ok6YmGZqHSVLZ+HQM7i0kw= -github.com/swaggo/files/v2 v2.0.0/go.mod h1:24kk2Y9NYEJ5lHuCra6iVwkMjIekMCaFq/0JQj66kyM= -github.com/swaggo/swag v1.16.2 h1:28Pp+8DkQoV+HLzLx8RGJZXNGKbFqnuvSbAAtoxiY04= -github.com/swaggo/swag v1.16.2/go.mod h1:6YzXnDcpr0767iOejs318CwYkCQqyGer6BizOg03f+E= +github.com/swaggo/swag v1.16.3 h1:PnCYjPCah8FK4I26l2F/KQ4yz3sILcVUN3cTlBFA9Pg= +github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31 h1:OXcKh35JaYsGMRzpvFkLv/MEyPuL49CThT1pZ8aSml4= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= @@ -579,35 +496,22 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yourselfhosted/gomark v0.0.0-20240228170507-6a73bfad2eb6 h1:6h74aOL7vOgWX1TG2zwrUgSWm+isZhSKpmoOygO7Wlg= +github.com/yourselfhosted/gomark v0.0.0-20240228170507-6a73bfad2eb6/go.mod h1:dfl9FHGIw1oISjPc16u8n6/H/dngiVfdVRtS5+WJ4Js= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.5.6 h1:COmQAWTCcGetChm3Ig7G/t8AFAN00t+o8Mt4cf7JpwA= -github.com/yuin/goldmark v1.5.6/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -615,63 +519,38 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg= -golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk= +golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= +golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -684,63 +563,28 @@ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= -golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -754,232 +598,98 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b h1:+YaDE2r2OG8t/z5qmsh7Y+XXwCbvadxxZ0YY6mTdrVA= -google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI= -google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k= -google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20240213162025-012b6fc9bca9 h1:4++qSzdWBUy9/2x8L5KZgwZw+mjJZ2yDSCGMVM0YzRs= +google.golang.org/genproto/googleapis/api v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:PVreiBMirk8ypES6aw9d4p6iiBNSIfZEBqr3UGoAi2E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240213162025-012b6fc9bca9 h1:hZB7eLIaYlW9qXRfCq/qDaPdbeY3757uARz5Vvfv+cY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:YUWgXUFRPfoYK1IHMuxH5K6nPEXSCzIMljnQ59lLRCk= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= +google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -992,8 +702,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1026,45 +736,24 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= -lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= -modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= -modernc.org/ccgo/v3 v3.16.15 h1:KbDR3ZAVU+wiLyMESPtbtE/Add4elztFyfsWoNTgxS0= -modernc.org/ccgo/v3 v3.16.15/go.mod h1:yT7B+/E2m43tmMOT51GMoM98/MtHIcQQSleGnddkUNI= -modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= -modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= -modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= -modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= -modernc.org/libc v1.28.0 h1:kHB6LtDBV8DEAK7aZT1vWvP92abW9fb8cjb1P9UTpUE= -modernc.org/libc v1.28.0/go.mod h1:DaG/4Q3LRRdqpiLyP0C2m1B8ZMGkQ+cCgOIjEtQlYhQ= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= +modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= -modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= -modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.26.0 h1:SocQdLRSYlA8W99V8YH0NES75thx19d9sB/aFc4R8Lw= -modernc.org/sqlite v1.26.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU= +modernc.org/sqlite v1.29.1 h1:19GY2qvWB4VPw0HppFlZCPAbmxFU41r+qjKZQdQ1ryA= +modernc.org/sqlite v1.29.1/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= -modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY= -modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY= -modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/internal/jobs/presign_link.go b/internal/jobs/presign_link.go new file mode 100644 index 0000000000000..187610069df48 --- /dev/null +++ b/internal/jobs/presign_link.go @@ -0,0 +1,138 @@ +package jobs + +import ( + "context" + "encoding/json" + "log/slog" + "strings" + "time" + + "github.com/pkg/errors" + + "github.com/usememos/memos/plugin/storage/s3" + apiv1 "github.com/usememos/memos/server/route/api/v1" + "github.com/usememos/memos/store" +) + +// RunPreSignLinks is a background job that pre-signs external links stored in the database. +// It uses S3 client to generate presigned URLs and updates the corresponding resources in the store. +func RunPreSignLinks(ctx context.Context, dataStore *store.Store) { + for { + if err := signExternalLinks(ctx, dataStore); err != nil { + slog.Error("failed to pre-sign links", err) + } else { + slog.Debug("pre-signed links") + } + select { + case <-time.After(s3.LinkLifetime / 2): + case <-ctx.Done(): + return + } + } +} + +func signExternalLinks(ctx context.Context, dataStore *store.Store) error { + const pageSize = 32 + + objectStore, err := findObjectStorage(ctx, dataStore) + if err != nil { + return errors.Wrapf(err, "find object storage") + } + if objectStore == nil || !objectStore.Config.PreSign { + // object storage not set or not supported + return nil + } + + var offset int + var limit = pageSize + for { + resources, err := dataStore.ListResources(ctx, &store.FindResource{ + GetBlob: false, + Limit: &limit, + Offset: &offset, + }) + if err != nil { + return errors.Wrapf(err, "list resources, offset %d", offset) + } + + for _, res := range resources { + if res.ExternalLink == "" { + // not for object store + continue + } + if strings.Contains(res.ExternalLink, "?") && time.Since(time.Unix(res.UpdatedTs, 0)) < s3.LinkLifetime/2 { + // resource not signed (hack for migration) + // resource was recently updated - skipping + continue + } + newLink, err := objectStore.PreSignLink(ctx, res.ExternalLink) + if err != nil { + slog.Error("failed to pre-sign link", err) + continue // do not fail - we may want update left over links too + } + now := time.Now().Unix() + // we may want to use here transaction and batch update in the future + _, err = dataStore.UpdateResource(ctx, &store.UpdateResource{ + ID: res.ID, + UpdatedTs: &now, + ExternalLink: &newLink, + }) + if err != nil { + // something with DB - better to stop here + return errors.Wrapf(err, "update resource %d link to %q", res.ID, newLink) + } + } + + offset += limit + if len(resources) < limit { + break + } + } + return nil +} + +// findObjectStorage returns current default storage if it's S3-compatible or nil otherwise. +// Returns error only in case of internal problems (ie: database or configuration issues). +// May return nil client and nil error. +func findObjectStorage(ctx context.Context, dataStore *store.Store) (*s3.Client, error) { + systemSettingStorageServiceID, err := dataStore.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{Name: apiv1.SystemSettingStorageServiceIDName.String()}) + if err != nil { + return nil, errors.Wrap(err, "Failed to find SystemSettingStorageServiceIDName") + } + + storageServiceID := apiv1.DefaultStorage + if systemSettingStorageServiceID != nil { + err = json.Unmarshal([]byte(systemSettingStorageServiceID.Value), &storageServiceID) + if err != nil { + return nil, errors.Wrap(err, "Failed to unmarshal storage service id") + } + } + storage, err := dataStore.GetStorage(ctx, &store.FindStorage{ID: &storageServiceID}) + if err != nil { + return nil, errors.Wrap(err, "Failed to find StorageServiceID") + } + + if storage == nil { + return nil, nil // storage not configured - not an error, just return empty ref + } + storageMessage, err := apiv1.ConvertStorageFromStore(storage) + + if err != nil { + return nil, errors.Wrap(err, "Failed to ConvertStorageFromStore") + } + if storageMessage.Type != apiv1.StorageS3 { + return nil, nil + } + + s3Config := storageMessage.Config.S3Config + return s3.NewClient(ctx, &s3.Config{ + AccessKey: s3Config.AccessKey, + SecretKey: s3Config.SecretKey, + EndPoint: s3Config.EndPoint, + Region: s3Config.Region, + Bucket: s3Config.Bucket, + URLPrefix: s3Config.URLPrefix, + URLSuffix: s3Config.URLSuffix, + PreSign: s3Config.PreSign, + }) +} diff --git a/internal/log/logger.go b/internal/log/logger.go deleted file mode 100644 index c83952141977d..0000000000000 --- a/internal/log/logger.go +++ /dev/null @@ -1,66 +0,0 @@ -package log - -import ( - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -var ( - // `gl` is the global logger. - // Other packages should use public methods such as Info/Error to do the logging. - // For other types of logging, e.g. logging to a separate file, they should use their own loggers. - gl *zap.Logger - gLevel zap.AtomicLevel -) - -// Initializes the global console logger. -func init() { - gLevel = zap.NewAtomicLevelAt(zap.InfoLevel) - gl, _ = zap.Config{ - Level: gLevel, - Development: true, - // Use "console" to print readable stacktrace. - Encoding: "console", - EncoderConfig: zap.NewDevelopmentEncoderConfig(), - OutputPaths: []string{"stderr"}, - ErrorOutputPaths: []string{"stderr"}, - }.Build( - // Skip one caller stack to locate the correct caller. - zap.AddCallerSkip(1), - ) -} - -// SetLevel wraps the zap Level's SetLevel method. -func SetLevel(level zapcore.Level) { - gLevel.SetLevel(level) -} - -// EnabledLevel wraps the zap Level's Enabled method. -func EnabledLevel(level zapcore.Level) bool { - return gLevel.Enabled(level) -} - -// Debug wraps the zap Logger's Debug method. -func Debug(msg string, fields ...zap.Field) { - gl.Debug(msg, fields...) -} - -// Info wraps the zap Logger's Info method. -func Info(msg string, fields ...zap.Field) { - gl.Info(msg, fields...) -} - -// Warn wraps the zap Logger's Warn method. -func Warn(msg string, fields ...zap.Field) { - gl.Warn(msg, fields...) -} - -// Error wraps the zap Logger's Error method. -func Error(msg string, fields ...zap.Field) { - gl.Error(msg, fields...) -} - -// Sync wraps the zap Logger's Sync method. -func Sync() { - _ = gl.Sync() -} diff --git a/internal/util/resource_name.go b/internal/util/resource_name.go new file mode 100644 index 0000000000000..6fc10c6660f35 --- /dev/null +++ b/internal/util/resource_name.go @@ -0,0 +1,7 @@ +package util + +import "regexp" + +var ( + ResourceNameMatcher = regexp.MustCompile("^[a-zA-Z0-9]([a-zA-Z0-9-]{1,30}[a-zA-Z0-9])$") +) diff --git a/main.go b/main.go deleted file mode 100644 index 8d53abe07836e..0000000000000 --- a/main.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - _ "github.com/go-sql-driver/mysql" - _ "modernc.org/sqlite" - - "github.com/usememos/memos/cmd" -) - -func main() { - err := cmd.Execute() - if err != nil { - panic(err) - } -} diff --git a/plugin/gomark/README.md b/plugin/gomark/README.md deleted file mode 100644 index 2a6f148072dfe..0000000000000 --- a/plugin/gomark/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# gomark - -A markdown parser for memos. WIP diff --git a/plugin/gomark/ast/ast.go b/plugin/gomark/ast/ast.go deleted file mode 100644 index e2ba029cdce8e..0000000000000 --- a/plugin/gomark/ast/ast.go +++ /dev/null @@ -1,19 +0,0 @@ -package ast - -type Node struct { - Type string - Text string - Children []*Node -} - -type Document struct { - Nodes []*Node -} - -func NewDocument() *Document { - return &Document{} -} - -func (d *Document) AddNode(node *Node) { - d.Nodes = append(d.Nodes, node) -} diff --git a/plugin/gomark/ast/node.go b/plugin/gomark/ast/node.go deleted file mode 100644 index 0ef0259d839ba..0000000000000 --- a/plugin/gomark/ast/node.go +++ /dev/null @@ -1,12 +0,0 @@ -package ast - -func NewNode(tp, text string) *Node { - return &Node{ - Type: tp, - Text: text, - } -} - -func (n *Node) AddChild(child *Node) { - n.Children = append(n.Children, child) -} diff --git a/plugin/gomark/gomark.go b/plugin/gomark/gomark.go deleted file mode 100644 index b7f941d5f902f..0000000000000 --- a/plugin/gomark/gomark.go +++ /dev/null @@ -1 +0,0 @@ -package gomark diff --git a/plugin/gomark/parser/bold.go b/plugin/gomark/parser/bold.go deleted file mode 100644 index 6b38a0b0f2fb5..0000000000000 --- a/plugin/gomark/parser/bold.go +++ /dev/null @@ -1,49 +0,0 @@ -package parser - -import ( - "github.com/usememos/memos/plugin/gomark/parser/tokenizer" -) - -type BoldParser struct { - ContentTokens []*tokenizer.Token -} - -func NewBoldParser() *BoldParser { - return &BoldParser{} -} - -func (*BoldParser) Match(tokens []*tokenizer.Token) *BoldParser { - if len(tokens) < 5 { - return nil - } - - prefixTokens := tokens[:2] - if prefixTokens[0].Type != prefixTokens[1].Type { - return nil - } - prefixTokenType := prefixTokens[0].Type - if prefixTokenType != tokenizer.Star && prefixTokenType != tokenizer.Underline { - return nil - } - - contentTokens := []*tokenizer.Token{} - cursor, matched := 2, false - for ; cursor < len(tokens)-1; cursor++ { - token, nextToken := tokens[cursor], tokens[cursor+1] - if token.Type == tokenizer.Newline || nextToken.Type == tokenizer.Newline { - return nil - } - if token.Type == prefixTokenType && nextToken.Type == prefixTokenType { - matched = true - break - } - contentTokens = append(contentTokens, token) - } - if !matched { - return nil - } - - return &BoldParser{ - ContentTokens: contentTokens, - } -} diff --git a/plugin/gomark/parser/bold_test.go b/plugin/gomark/parser/bold_test.go deleted file mode 100644 index 511bb70e07c49..0000000000000 --- a/plugin/gomark/parser/bold_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package parser - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/usememos/memos/plugin/gomark/parser/tokenizer" -) - -func TestBoldParser(t *testing.T) { - tests := []struct { - text string - bold *BoldParser - }{ - { - text: "*Hello world!", - bold: nil, - }, - { - text: "**Hello**", - bold: &BoldParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Text, - Value: "Hello", - }, - }, - }, - }, - { - text: "** Hello **", - bold: &BoldParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Space, - Value: " ", - }, - { - Type: tokenizer.Text, - Value: "Hello", - }, - { - Type: tokenizer.Space, - Value: " ", - }, - }, - }, - }, - { - text: "** Hello * *", - bold: nil, - }, - { - text: "* * Hello **", - bold: nil, - }, - { - text: `** Hello -**`, - bold: nil, - }, - { - text: `**Hello \n**`, - bold: &BoldParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Text, - Value: "Hello", - }, - { - Type: tokenizer.Space, - Value: " ", - }, - { - Type: tokenizer.Text, - Value: `\n`, - }, - }, - }, - }, - } - - for _, test := range tests { - tokens := tokenizer.Tokenize(test.text) - bold := NewBoldParser() - require.Equal(t, test.bold, bold.Match(tokens)) - } -} diff --git a/plugin/gomark/parser/code.go b/plugin/gomark/parser/code.go deleted file mode 100644 index 6eae650c4b12a..0000000000000 --- a/plugin/gomark/parser/code.go +++ /dev/null @@ -1,38 +0,0 @@ -package parser - -import "github.com/usememos/memos/plugin/gomark/parser/tokenizer" - -type CodeParser struct { - Content string -} - -func NewCodeParser() *CodeParser { - return &CodeParser{} -} - -func (*CodeParser) Match(tokens []*tokenizer.Token) *CodeParser { - if len(tokens) < 3 { - return nil - } - if tokens[0].Type != tokenizer.Backtick { - return nil - } - - content, matched := "", false - for _, token := range tokens[1:] { - if token.Type == tokenizer.Newline { - return nil - } - if token.Type == tokenizer.Backtick { - matched = true - break - } - content += token.Value - } - if !matched || len(content) == 0 { - return nil - } - return &CodeParser{ - Content: content, - } -} diff --git a/plugin/gomark/parser/code_block.go b/plugin/gomark/parser/code_block.go deleted file mode 100644 index 4bf4fcacaa9a4..0000000000000 --- a/plugin/gomark/parser/code_block.go +++ /dev/null @@ -1,52 +0,0 @@ -package parser - -import "github.com/usememos/memos/plugin/gomark/parser/tokenizer" - -type CodeBlockParser struct { - Language string - Content string -} - -func NewCodeBlockParser() *CodeBlockParser { - return &CodeBlockParser{} -} - -func (*CodeBlockParser) Match(tokens []*tokenizer.Token) *CodeBlockParser { - if len(tokens) < 9 { - return nil - } - - if tokens[0].Type != tokenizer.Backtick || tokens[1].Type != tokenizer.Backtick || tokens[2].Type != tokenizer.Backtick { - return nil - } - if tokens[3].Type != tokenizer.Newline && tokens[4].Type != tokenizer.Newline { - return nil - } - cursor, language := 4, "" - if tokens[3].Type != tokenizer.Newline { - language = tokens[3].Value - cursor = 5 - } - - content, matched := "", false - for ; cursor < len(tokens)-3; cursor++ { - if tokens[cursor].Type == tokenizer.Newline && tokens[cursor+1].Type == tokenizer.Backtick && tokens[cursor+2].Type == tokenizer.Backtick && tokens[cursor+3].Type == tokenizer.Backtick { - if cursor+3 == len(tokens)-1 { - matched = true - break - } else if tokens[cursor+4].Type == tokenizer.Newline { - matched = true - break - } - } - content += tokens[cursor].Value - } - if !matched { - return nil - } - - return &CodeBlockParser{ - Language: language, - Content: content, - } -} diff --git a/plugin/gomark/parser/code_block_test.go b/plugin/gomark/parser/code_block_test.go deleted file mode 100644 index cbfbf6bdfd33c..0000000000000 --- a/plugin/gomark/parser/code_block_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package parser - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/usememos/memos/plugin/gomark/parser/tokenizer" -) - -func TestCodeBlockParser(t *testing.T) { - tests := []struct { - text string - codeBlock *CodeBlockParser - }{ - { - text: "```Hello world!```", - codeBlock: nil, - }, - { - text: "```\nHello\n```", - codeBlock: &CodeBlockParser{ - Language: "", - Content: "Hello", - }, - }, - { - text: "```\nHello world!\n```", - codeBlock: &CodeBlockParser{ - Language: "", - Content: "Hello world!", - }, - }, - { - text: "```java\nHello \n world!\n```", - codeBlock: &CodeBlockParser{ - Language: "java", - Content: "Hello \n world!", - }, - }, - { - text: "```java\nHello \n world!\n```111", - codeBlock: nil, - }, - { - text: "```java\nHello \n world!\n``` 111", - codeBlock: nil, - }, - { - text: "```java\nHello \n world!\n```\n123123", - codeBlock: &CodeBlockParser{ - Language: "java", - Content: "Hello \n world!", - }, - }, - } - - for _, test := range tests { - tokens := tokenizer.Tokenize(test.text) - codeBlock := NewCodeBlockParser() - require.Equal(t, test.codeBlock, codeBlock.Match(tokens)) - } -} diff --git a/plugin/gomark/parser/code_test.go b/plugin/gomark/parser/code_test.go deleted file mode 100644 index 8e4fed41a87de..0000000000000 --- a/plugin/gomark/parser/code_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package parser - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/usememos/memos/plugin/gomark/parser/tokenizer" -) - -func TestCodeParser(t *testing.T) { - tests := []struct { - text string - code *CodeParser - }{ - { - text: "`Hello world!", - code: nil, - }, - { - text: "`Hello world!`", - code: &CodeParser{ - Content: "Hello world!", - }, - }, - { - text: "`Hello \nworld!`", - code: nil, - }, - } - - for _, test := range tests { - tokens := tokenizer.Tokenize(test.text) - code := NewCodeParser() - require.Equal(t, test.code, code.Match(tokens)) - } -} diff --git a/plugin/gomark/parser/heading.go b/plugin/gomark/parser/heading.go deleted file mode 100644 index c9c26323f7732..0000000000000 --- a/plugin/gomark/parser/heading.go +++ /dev/null @@ -1,53 +0,0 @@ -package parser - -import ( - "github.com/usememos/memos/plugin/gomark/parser/tokenizer" -) - -type HeadingParser struct { - Level int - ContentTokens []*tokenizer.Token -} - -func NewHeadingParser() *HeadingParser { - return &HeadingParser{} -} - -func (*HeadingParser) Match(tokens []*tokenizer.Token) *HeadingParser { - cursor := 0 - for _, token := range tokens { - if token.Type == tokenizer.Hash { - cursor++ - } else { - break - } - } - if len(tokens) <= cursor+1 { - return nil - } - if tokens[cursor].Type != tokenizer.Space { - return nil - } - level := cursor - if level == 0 || level > 6 { - return nil - } - - cursor++ - contentTokens := []*tokenizer.Token{} - for _, token := range tokens[cursor:] { - if token.Type == tokenizer.Newline { - break - } - contentTokens = append(contentTokens, token) - cursor++ - } - if len(contentTokens) == 0 { - return nil - } - - return &HeadingParser{ - Level: level, - ContentTokens: contentTokens, - } -} diff --git a/plugin/gomark/parser/heading_test.go b/plugin/gomark/parser/heading_test.go deleted file mode 100644 index b9ef4a5e631f3..0000000000000 --- a/plugin/gomark/parser/heading_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package parser - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/usememos/memos/plugin/gomark/parser/tokenizer" -) - -func TestHeadingParser(t *testing.T) { - tests := []struct { - text string - heading *HeadingParser - }{ - { - text: "*Hello world", - heading: nil, - }, - { - text: "## Hello World", - heading: &HeadingParser{ - Level: 2, - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Text, - Value: "Hello", - }, - { - Type: tokenizer.Space, - Value: " ", - }, - { - Type: tokenizer.Text, - Value: "World", - }, - }, - }, - }, - { - text: "# # Hello World", - heading: &HeadingParser{ - Level: 1, - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Hash, - Value: "#", - }, - { - Type: tokenizer.Space, - Value: " ", - }, - { - Type: tokenizer.Text, - Value: "Hello", - }, - { - Type: tokenizer.Space, - Value: " ", - }, - { - Type: tokenizer.Text, - Value: "World", - }, - }, - }, - }, - { - text: " # 123123 Hello World", - heading: nil, - }, - { - text: `# 123 -Hello World`, - heading: &HeadingParser{ - Level: 1, - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Text, - Value: "123", - }, - { - Type: tokenizer.Space, - Value: " ", - }, - }, - }, - }, - } - - for _, test := range tests { - tokens := tokenizer.Tokenize(test.text) - heading := NewHeadingParser() - require.Equal(t, test.heading, heading.Match(tokens)) - } -} diff --git a/plugin/gomark/parser/image.go b/plugin/gomark/parser/image.go deleted file mode 100644 index def7d2af37d29..0000000000000 --- a/plugin/gomark/parser/image.go +++ /dev/null @@ -1,55 +0,0 @@ -package parser - -import "github.com/usememos/memos/plugin/gomark/parser/tokenizer" - -type ImageParser struct { - AltText string - URL string -} - -func NewImageParser() *ImageParser { - return &ImageParser{} -} - -func (*ImageParser) Match(tokens []*tokenizer.Token) *ImageParser { - if len(tokens) < 5 { - return nil - } - if tokens[0].Type != tokenizer.ExclamationMark { - return nil - } - if tokens[1].Type != tokenizer.LeftSquareBracket { - return nil - } - cursor, altText := 2, "" - for ; cursor < len(tokens)-2; cursor++ { - if tokens[cursor].Type == tokenizer.Newline { - return nil - } - if tokens[cursor].Type == tokenizer.RightSquareBracket { - break - } - altText += tokens[cursor].Value - } - if tokens[cursor+1].Type != tokenizer.LeftParenthesis { - return nil - } - matched, url := false, "" - for _, token := range tokens[cursor+2:] { - if token.Type == tokenizer.Newline || token.Type == tokenizer.Space { - return nil - } - if token.Type == tokenizer.RightParenthesis { - matched = true - break - } - url += token.Value - } - if !matched || url == "" { - return nil - } - return &ImageParser{ - AltText: altText, - URL: url, - } -} diff --git a/plugin/gomark/parser/image_test.go b/plugin/gomark/parser/image_test.go deleted file mode 100644 index cdcbfa2a98149..0000000000000 --- a/plugin/gomark/parser/image_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package parser - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/usememos/memos/plugin/gomark/parser/tokenizer" -) - -func TestImageParser(t *testing.T) { - tests := []struct { - text string - image *ImageParser - }{ - { - text: "![](https://example.com)", - image: &ImageParser{ - AltText: "", - URL: "https://example.com", - }, - }, - { - text: "! [](https://example.com)", - image: nil, - }, - { - text: "![alte]( htt ps :/ /example.com)", - image: nil, - }, - { - text: "![al te](https://example.com)", - image: &ImageParser{ - AltText: "al te", - URL: "https://example.com", - }, - }, - } - for _, test := range tests { - tokens := tokenizer.Tokenize(test.text) - require.Equal(t, test.image, NewImageParser().Match(tokens)) - } -} diff --git a/plugin/gomark/parser/italic.go b/plugin/gomark/parser/italic.go deleted file mode 100644 index 3ab01f9357503..0000000000000 --- a/plugin/gomark/parser/italic.go +++ /dev/null @@ -1,42 +0,0 @@ -package parser - -import "github.com/usememos/memos/plugin/gomark/parser/tokenizer" - -type ItalicParser struct { - ContentTokens []*tokenizer.Token -} - -func NewItalicParser() *ItalicParser { - return &ItalicParser{} -} - -func (*ItalicParser) Match(tokens []*tokenizer.Token) *ItalicParser { - if len(tokens) < 3 { - return nil - } - - prefixTokens := tokens[:1] - if prefixTokens[0].Type != tokenizer.Star && prefixTokens[0].Type != tokenizer.Underline { - return nil - } - prefixTokenType := prefixTokens[0].Type - contentTokens := []*tokenizer.Token{} - matched := false - for _, token := range tokens[1:] { - if token.Type == tokenizer.Newline { - return nil - } - if token.Type == prefixTokenType { - matched = true - break - } - contentTokens = append(contentTokens, token) - } - if !matched || len(contentTokens) == 0 { - return nil - } - - return &ItalicParser{ - ContentTokens: contentTokens, - } -} diff --git a/plugin/gomark/parser/italic_test.go b/plugin/gomark/parser/italic_test.go deleted file mode 100644 index 116616bf17660..0000000000000 --- a/plugin/gomark/parser/italic_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package parser - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/usememos/memos/plugin/gomark/parser/tokenizer" -) - -func TestItalicParser(t *testing.T) { - tests := []struct { - text string - italic *ItalicParser - }{ - { - text: "*Hello world!", - italic: nil, - }, - { - text: "*Hello*", - italic: &ItalicParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Text, - Value: "Hello", - }, - }, - }, - }, - { - text: "* Hello *", - italic: &ItalicParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Space, - Value: " ", - }, - { - Type: tokenizer.Text, - Value: "Hello", - }, - { - Type: tokenizer.Space, - Value: " ", - }, - }, - }, - }, - { - text: "** Hello * *", - italic: nil, - }, - { - text: "*1* Hello * *", - italic: &ItalicParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Text, - Value: "1", - }, - }, - }, - }, - { - text: `* \n * Hello * *`, - italic: &ItalicParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Space, - Value: " ", - }, - { - Type: tokenizer.Text, - Value: `\n`, - }, - { - Type: tokenizer.Space, - Value: " ", - }, - }, - }, - }, - { - text: "* \n * Hello * *", - italic: nil, - }, - } - - for _, test := range tests { - tokens := tokenizer.Tokenize(test.text) - italic := NewItalicParser() - require.Equal(t, test.italic, italic.Match(tokens)) - } -} diff --git a/plugin/gomark/parser/link.go b/plugin/gomark/parser/link.go deleted file mode 100644 index a1c8b74499be9..0000000000000 --- a/plugin/gomark/parser/link.go +++ /dev/null @@ -1,58 +0,0 @@ -package parser - -import "github.com/usememos/memos/plugin/gomark/parser/tokenizer" - -type LinkParser struct { - ContentTokens []*tokenizer.Token - URL string -} - -func NewLinkParser() *LinkParser { - return &LinkParser{} -} - -func (*LinkParser) Match(tokens []*tokenizer.Token) *LinkParser { - if len(tokens) < 4 { - return nil - } - if tokens[0].Type != tokenizer.LeftSquareBracket { - return nil - } - cursor, contentTokens := 1, []*tokenizer.Token{} - for ; cursor < len(tokens)-2; cursor++ { - if tokens[cursor].Type == tokenizer.Newline { - return nil - } - if tokens[cursor].Type == tokenizer.RightSquareBracket { - break - } - contentTokens = append(contentTokens, tokens[cursor]) - } - if tokens[cursor+1].Type != tokenizer.LeftParenthesis { - return nil - } - matched, url := false, "" - for _, token := range tokens[cursor+2:] { - if token.Type == tokenizer.Newline || token.Type == tokenizer.Space { - return nil - } - if token.Type == tokenizer.RightParenthesis { - matched = true - break - } - url += token.Value - } - if !matched || url == "" { - return nil - } - if len(contentTokens) == 0 { - contentTokens = append(contentTokens, &tokenizer.Token{ - Type: tokenizer.Text, - Value: url, - }) - } - return &LinkParser{ - ContentTokens: contentTokens, - URL: url, - } -} diff --git a/plugin/gomark/parser/link_test.go b/plugin/gomark/parser/link_test.go deleted file mode 100644 index ab4f5c7dc2591..0000000000000 --- a/plugin/gomark/parser/link_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package parser - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/usememos/memos/plugin/gomark/parser/tokenizer" -) - -func TestLinkParser(t *testing.T) { - tests := []struct { - text string - link *LinkParser - }{ - { - text: "[](https://example.com)", - link: &LinkParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Text, - Value: "https://example.com", - }, - }, - URL: "https://example.com", - }, - }, - { - text: "! [](https://example.com)", - link: nil, - }, - { - text: "[alte]( htt ps :/ /example.com)", - link: nil, - }, - { - text: "[hello world](https://example.com)", - link: &LinkParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Text, - Value: "hello", - }, - { - Type: tokenizer.Space, - Value: " ", - }, - { - Type: tokenizer.Text, - Value: "world", - }, - }, - URL: "https://example.com", - }, - }, - } - for _, test := range tests { - tokens := tokenizer.Tokenize(test.text) - require.Equal(t, test.link, NewLinkParser().Match(tokens)) - } -} diff --git a/plugin/gomark/parser/paragraph.go b/plugin/gomark/parser/paragraph.go deleted file mode 100644 index 2b7849e3a4a35..0000000000000 --- a/plugin/gomark/parser/paragraph.go +++ /dev/null @@ -1,30 +0,0 @@ -package parser - -import "github.com/usememos/memos/plugin/gomark/parser/tokenizer" - -type ParagraphParser struct { - ContentTokens []*tokenizer.Token -} - -func NewParagraphParser() *ParagraphParser { - return &ParagraphParser{} -} - -func (*ParagraphParser) Match(tokens []*tokenizer.Token) *ParagraphParser { - contentTokens := []*tokenizer.Token{} - cursor := 0 - for ; cursor < len(tokens); cursor++ { - token := tokens[cursor] - if token.Type == tokenizer.Newline { - break - } - contentTokens = append(contentTokens, token) - } - if len(contentTokens) == 0 { - return nil - } - - return &ParagraphParser{ - ContentTokens: contentTokens, - } -} diff --git a/plugin/gomark/parser/paragraph_test.go b/plugin/gomark/parser/paragraph_test.go deleted file mode 100644 index d3e0f55b63633..0000000000000 --- a/plugin/gomark/parser/paragraph_test.go +++ /dev/null @@ -1,86 +0,0 @@ -package parser - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/usememos/memos/plugin/gomark/parser/tokenizer" -) - -func TestParagraphParser(t *testing.T) { - tests := []struct { - text string - paragraph *ParagraphParser - }{ - { - text: "", - paragraph: nil, - }, - { - text: "Hello world", - paragraph: &ParagraphParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Text, - Value: "Hello", - }, - { - Type: tokenizer.Space, - Value: " ", - }, - { - Type: tokenizer.Text, - Value: "world", - }, - }, - }, - }, - { - text: `Hello -world`, - paragraph: &ParagraphParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Text, - Value: "Hello", - }, - { - Type: tokenizer.Space, - Value: " ", - }, - }, - }, - }, - { - text: `Hello \n -world`, - paragraph: &ParagraphParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Text, - Value: "Hello", - }, - { - Type: tokenizer.Space, - Value: " ", - }, - { - Type: tokenizer.Text, - Value: `\n`, - }, - { - Type: tokenizer.Space, - Value: " ", - }, - }, - }, - }, - } - - for _, test := range tests { - tokens := tokenizer.Tokenize(test.text) - paragraph := NewParagraphParser() - require.Equal(t, test.paragraph, paragraph.Match(tokens)) - } -} diff --git a/plugin/gomark/parser/parser.go b/plugin/gomark/parser/parser.go deleted file mode 100644 index 0bfe2c257e491..0000000000000 --- a/plugin/gomark/parser/parser.go +++ /dev/null @@ -1 +0,0 @@ -package parser diff --git a/plugin/gomark/parser/tag.go b/plugin/gomark/parser/tag.go deleted file mode 100644 index c33fcd0b43891..0000000000000 --- a/plugin/gomark/parser/tag.go +++ /dev/null @@ -1,34 +0,0 @@ -package parser - -import "github.com/usememos/memos/plugin/gomark/parser/tokenizer" - -type TagParser struct { - ContentTokens []*tokenizer.Token -} - -func NewTagParser() *TagParser { - return &TagParser{} -} - -func (*TagParser) Match(tokens []*tokenizer.Token) *TagParser { - if len(tokens) < 2 { - return nil - } - if tokens[0].Type != tokenizer.Hash { - return nil - } - contentTokens := []*tokenizer.Token{} - for _, token := range tokens[1:] { - if token.Type == tokenizer.Newline || token.Type == tokenizer.Space || token.Type == tokenizer.Hash { - break - } - contentTokens = append(contentTokens, token) - } - if len(contentTokens) == 0 { - return nil - } - - return &TagParser{ - ContentTokens: contentTokens, - } -} diff --git a/plugin/gomark/parser/tag_test.go b/plugin/gomark/parser/tag_test.go deleted file mode 100644 index 7066027f5bced..0000000000000 --- a/plugin/gomark/parser/tag_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package parser - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/usememos/memos/plugin/gomark/parser/tokenizer" -) - -func TestTagParser(t *testing.T) { - tests := []struct { - text string - tag *TagParser - }{ - { - text: "*Hello world", - tag: nil, - }, - { - text: "# Hello World", - tag: nil, - }, - { - text: "#tag", - tag: &TagParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Text, - Value: "tag", - }, - }, - }, - }, - { - text: "#tag/subtag", - tag: &TagParser{ - ContentTokens: []*tokenizer.Token{ - { - Type: tokenizer.Text, - Value: "tag/subtag", - }, - }, - }, - }, - } - - for _, test := range tests { - tokens := tokenizer.Tokenize(test.text) - require.Equal(t, test.tag, NewTagParser().Match(tokens)) - } -} diff --git a/plugin/gomark/parser/tokenizer/tokenizer.go b/plugin/gomark/parser/tokenizer/tokenizer.go deleted file mode 100644 index e73b0ff062d00..0000000000000 --- a/plugin/gomark/parser/tokenizer/tokenizer.go +++ /dev/null @@ -1,74 +0,0 @@ -package tokenizer - -type TokenType = string - -const ( - Underline TokenType = "_" - Star TokenType = "*" - Hash TokenType = "#" - Backtick TokenType = "`" - LeftSquareBracket TokenType = "[" - RightSquareBracket TokenType = "]" - LeftParenthesis TokenType = "(" - RightParenthesis TokenType = ")" - ExclamationMark TokenType = "!" - Newline TokenType = "\n" - Space TokenType = " " -) - -const ( - Text TokenType = "" -) - -type Token struct { - Type TokenType - Value string -} - -func NewToken(tp, text string) *Token { - return &Token{ - Type: tp, - Value: text, - } -} - -func Tokenize(text string) []*Token { - tokens := []*Token{} - for _, c := range text { - switch c { - case '_': - tokens = append(tokens, NewToken(Underline, "_")) - case '*': - tokens = append(tokens, NewToken(Star, "*")) - case '#': - tokens = append(tokens, NewToken(Hash, "#")) - case '`': - tokens = append(tokens, NewToken(Backtick, "`")) - case '[': - tokens = append(tokens, NewToken(LeftSquareBracket, "[")) - case ']': - tokens = append(tokens, NewToken(RightSquareBracket, "]")) - case '(': - tokens = append(tokens, NewToken(LeftParenthesis, "(")) - case ')': - tokens = append(tokens, NewToken(RightParenthesis, ")")) - case '!': - tokens = append(tokens, NewToken(ExclamationMark, "!")) - case '\n': - tokens = append(tokens, NewToken(Newline, "\n")) - case ' ': - tokens = append(tokens, NewToken(Space, " ")) - default: - var lastToken *Token - if len(tokens) > 0 { - lastToken = tokens[len(tokens)-1] - } - if lastToken == nil || lastToken.Type != Text { - tokens = append(tokens, NewToken(Text, string(c))) - } else { - lastToken.Value += string(c) - } - } - } - return tokens -} diff --git a/plugin/gomark/parser/tokenizer/tokenizer_test.go b/plugin/gomark/parser/tokenizer/tokenizer_test.go deleted file mode 100644 index 8010fe4f643a8..0000000000000 --- a/plugin/gomark/parser/tokenizer/tokenizer_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package tokenizer - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestTokenize(t *testing.T) { - tests := []struct { - text string - tokens []*Token - }{ - { - text: "*Hello world!", - tokens: []*Token{ - { - Type: Star, - Value: "*", - }, - { - Type: Text, - Value: "Hello", - }, - { - Type: Space, - Value: " ", - }, - { - Type: Text, - Value: "world", - }, - { - Type: ExclamationMark, - Value: "!", - }, - }, - }, - { - text: `# hello - world`, - tokens: []*Token{ - { - Type: Hash, - Value: "#", - }, - { - Type: Space, - Value: " ", - }, - { - Type: Text, - Value: "hello", - }, - { - Type: Space, - Value: " ", - }, - { - Type: Newline, - Value: "\n", - }, - { - Type: Space, - Value: " ", - }, - { - Type: Text, - Value: "world", - }, - }, - }, - } - - for _, test := range tests { - result := Tokenize(test.text) - require.Equal(t, test.tokens, result) - } -} diff --git a/plugin/gomark/renderer/renderer.go b/plugin/gomark/renderer/renderer.go deleted file mode 100644 index 35803f645a57e..0000000000000 --- a/plugin/gomark/renderer/renderer.go +++ /dev/null @@ -1 +0,0 @@ -package renderer diff --git a/plugin/storage/s3/s3.go b/plugin/storage/s3/s3.go index 10b05392a52a5..0398bb6db711e 100644 --- a/plugin/storage/s3/s3.go +++ b/plugin/storage/s3/s3.go @@ -2,10 +2,11 @@ package s3 import ( "context" - "errors" "fmt" "io" + "net/url" "strings" + "time" "github.com/aws/aws-sdk-go-v2/aws" s3config "github.com/aws/aws-sdk-go-v2/config" @@ -13,8 +14,11 @@ import ( "github.com/aws/aws-sdk-go-v2/feature/s3/manager" awss3 "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" + "github.com/pkg/errors" ) +const LinkLifetime = 24 * time.Hour + type Config struct { AccessKey string SecretKey string @@ -23,6 +27,7 @@ type Config struct { Region string URLPrefix string URLSuffix string + PreSign bool } type Client struct { @@ -49,6 +54,7 @@ func NewClient(ctx context.Context, config *Config) (*Client, error) { awsConfig, err := s3config.LoadDefaultConfig(ctx, s3config.WithEndpointResolverWithOptions(resolver), s3config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(config.AccessKey, config.SecretKey, "")), + s3config.WithRegion(config.Region), ) if err != nil { return nil, err @@ -64,13 +70,17 @@ func NewClient(ctx context.Context, config *Config) (*Client, error) { func (client *Client) UploadFile(ctx context.Context, filename string, fileType string, src io.Reader) (string, error) { uploader := manager.NewUploader(client.Client) - uploadOutput, err := uploader.Upload(ctx, &awss3.PutObjectInput{ + putInput := awss3.PutObjectInput{ Bucket: aws.String(client.Config.Bucket), Key: aws.String(filename), Body: src, ContentType: aws.String(fileType), - ACL: types.ObjectCannedACL(*aws.String("public-read")), - }) + } + // Set ACL according to if url prefix is set. + if client.Config.URLPrefix == "" && !client.Config.PreSign { + putInput.ACL = types.ObjectCannedACL(*aws.String("public-read")) + } + uploadOutput, err := uploader.Upload(ctx, &putInput) if err != nil { return "", err } @@ -78,10 +88,61 @@ func (client *Client) UploadFile(ctx context.Context, filename string, fileType link := uploadOutput.Location // If url prefix is set, use it as the file link. if client.Config.URLPrefix != "" { - link = fmt.Sprintf("%s/%s%s", client.Config.URLPrefix, filename, client.Config.URLSuffix) + parts := strings.Split(filename, "/") + for i := range parts { + parts[i] = url.PathEscape(parts[i]) + } + link = fmt.Sprintf("%s/%s%s", client.Config.URLPrefix, strings.Join(parts, "/"), client.Config.URLSuffix) } if link == "" { return "", errors.New("failed to get file link") } + if client.Config.PreSign { + return client.PreSignLink(ctx, link) + } return link, nil } + +// PreSignLink generates a pre-signed URL for the given sourceLink. +// If the link does not belong to the configured storage endpoint, it is returned as-is. +// If the link belongs to the storage, the function generates a pre-signed URL using the AWS S3 client. +func (client *Client) PreSignLink(ctx context.Context, sourceLink string) (string, error) { + u, err := url.Parse(sourceLink) + if err != nil { + return "", errors.Wrapf(err, "parse URL") + } + // if link doesn't belong to storage, then return as-is. + // the empty hostname is corner-case for AWS native endpoint. + endpointURL, err := url.Parse(client.Config.EndPoint) + if err != nil { + return "", errors.Wrapf(err, "parse Endpoint URL") + } + endpointHost := endpointURL.Hostname() + if client.Config.Bucket != "" && !strings.Contains(endpointHost, client.Config.Bucket) { + endpointHost = fmt.Sprintf("%s.%s", client.Config.Bucket, endpointHost) + } + if client.Config.EndPoint != "" && !strings.Contains(endpointHost, u.Hostname()) { + return sourceLink, nil + } + + filename := u.Path + if prefixLen := len(client.Config.URLPrefix); len(filename) >= prefixLen { + filename = filename[prefixLen:] + } + if suffixLen := len(client.Config.URLSuffix); len(filename) >= suffixLen { + filename = filename[:len(filename)-suffixLen] + } + filename = strings.Trim(filename, "/") + if strings.HasPrefix(filename, client.Config.Bucket) { + filename = strings.Trim(filename[len(client.Config.Bucket):], "/") + } + + req, err := awss3.NewPresignClient(client.Client).PresignGetObject(ctx, &awss3.GetObjectInput{ + Bucket: aws.String(client.Config.Bucket), + Key: aws.String(filename), + }, awss3.WithPresignExpires(LinkLifetime)) + if err != nil { + return "", errors.Wrapf(err, "pre-sign link") + } + return req.URL, nil +} diff --git a/plugin/telegram/attachment.go b/plugin/telegram/attachment.go index e252f3f06b52f..4917307a25bce 100644 --- a/plugin/telegram/attachment.go +++ b/plugin/telegram/attachment.go @@ -1,11 +1,8 @@ package telegram import ( - "path" - - "go.uber.org/zap" - - "github.com/usememos/memos/internal/log" + "log/slog" + "path/filepath" ) type Attachment struct { @@ -27,11 +24,9 @@ func (b Attachment) GetMimeType() string { return b.MimeType } - mime, ok := mimeTypes[path.Ext(b.FileName)] + mime, ok := mimeTypes[filepath.Ext(b.FileName)] if !ok { - // Handle unknown file extension - log.Warn("Unknown file type for ", zap.String("filename", b.FileName)) - + slog.Warn("Unknown file extension", slog.String("file", b.FileName)) return "application/octet-stream" } diff --git a/plugin/telegram/bot.go b/plugin/telegram/bot.go index aa08f96115dc9..de8bc8e60072f 100644 --- a/plugin/telegram/bot.go +++ b/plugin/telegram/bot.go @@ -3,13 +3,9 @@ package telegram import ( "context" "errors" - "fmt" + "log/slog" "strings" "time" - - "go.uber.org/zap" - - "github.com/usememos/memos/internal/log" ) type Handler interface { @@ -41,7 +37,6 @@ func (b *Bot) Start(ctx context.Context) { continue } if err != nil { - log.Warn("fail to telegram.GetUpdates", zap.Error(err)) time.Sleep(errRetryWait) continue } @@ -56,7 +51,7 @@ func (b *Bot) Start(ctx context.Context) { if update.CallbackQuery != nil { err := b.handler.CallbackQueryHandle(ctx, b, *update.CallbackQuery) if err != nil { - log.Error("fail to handle CallbackQuery", zap.Error(err)) + slog.Error("fail to handle callback query", err) } continue @@ -70,7 +65,7 @@ func (b *Bot) Start(ctx context.Context) { if !message.IsSupported() { _, err := b.SendReplyMessage(ctx, message.Chat.ID, message.MessageID, "Supported messages: animation, audio, text, document, photo, video, video note, voice, other messages with caption") if err != nil { - log.Error(fmt.Sprintf("fail to telegram.SendReplyMessage for messageID=%d", message.MessageID), zap.Error(err)) + slog.Error("fail to send reply message", err) } continue } @@ -88,12 +83,12 @@ func (b *Bot) Start(ctx context.Context) { err = b.handleSingleMessages(ctx, singleMessages) if err != nil { - log.Error("fail to handle singleMessage", zap.Error(err)) + slog.Error("fail to handle plain text message", err) } err = b.handleGroupMessages(ctx, groupMessages) if err != nil { - log.Error("fail to handle plain text message", zap.Error(err)) + slog.Error("fail to handle media group message", err) } } } diff --git a/plugin/telegram/handle.go b/plugin/telegram/handle.go index d5581a782d968..ca77e7c76588c 100644 --- a/plugin/telegram/handle.go +++ b/plugin/telegram/handle.go @@ -13,7 +13,6 @@ func (b *Bot) handleSingleMessages(ctx context.Context, messages []Message) erro if err != nil { return err } - if attachment != nil { attachments = append(attachments, *attachment) } @@ -33,7 +32,7 @@ func (b *Bot) handleGroupMessages(ctx context.Context, groupMessages []Message) messages := make(map[string]Message, len(groupMessages)) attachments := make(map[string][]Attachment, len(groupMessages)) - // Group all captions, blobs and messages + // Group all captions, blobs and messages. for _, message := range groupMessages { groupID := *message.MediaGroupID @@ -53,9 +52,9 @@ func (b *Bot) handleGroupMessages(ctx context.Context, groupMessages []Message) } } - // Handle each group message + // Handle each group message. for groupID, message := range messages { - // replace Caption with all Caption in the group + // replace Caption with all Caption in the group. caption := captions[groupID] message.Caption = &caption err := b.handler.MessageHandle(ctx, b, message, attachments[groupID]) diff --git a/plugin/telegram/message_entity.go b/plugin/telegram/message_entity.go index ebc66d161790d..8809e28c8aab2 100644 --- a/plugin/telegram/message_entity.go +++ b/plugin/telegram/message_entity.go @@ -16,6 +16,7 @@ const ( Strikethrough = "strikethrough" // “strikethrough” (strikethrough text) Code = "code" // “code” (monowidth string) Pre = "pre" // “pre” (monowidth block) + Spoiler = "spoiler" // “spoiler” (hidden text) TextLink = "text_link" // “text_link” (for clickable text URLs) TextMention = "text_mention" // “text_mention” (for users without usernames) ) diff --git a/plugin/webhook/webhook.go b/plugin/webhook/webhook.go new file mode 100644 index 0000000000000..aadc5344df2bf --- /dev/null +++ b/plugin/webhook/webhook.go @@ -0,0 +1,112 @@ +package webhook + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + "time" + + "github.com/pkg/errors" +) + +var ( + // timeout is the timeout for webhook request. Default to 30 seconds. + timeout = 30 * time.Second +) + +type Memo struct { + ID int32 `json:"id"` + CreatorID int32 `json:"creatorId"` + CreatedTs int64 `json:"createdTs"` + UpdatedTs int64 `json:"updatedTs"` + + // Domain specific fields + Content string `json:"content"` + Visibility string `json:"visibility"` + Pinned bool `json:"pinned"` + ResourceList []*Resource `json:"resourceList"` + RelationList []*MemoRelation `json:"relationList"` +} + +type Resource struct { + ID int32 `json:"id"` + + // Standard fields + CreatorID int32 `json:"creatorId"` + CreatedTs int64 `json:"createdTs"` + UpdatedTs int64 `json:"updatedTs"` + + // Domain specific fields + Filename string `json:"filename"` + InternalPath string `json:"internalPath"` + ExternalLink string `json:"externalLink"` + Type string `json:"type"` + Size int64 `json:"size"` +} + +type MemoRelation struct { + MemoID int32 `json:"memoId"` + RelatedMemoID int32 `json:"relatedMemoId"` + Type string `json:"type"` +} + +// WebhookPayload is the payload of webhook request. +// nolint +type WebhookPayload struct { + URL string `json:"url"` + ActivityType string `json:"activityType"` + CreatorID int32 `json:"creatorId"` + CreatedTs int64 `json:"createdTs"` + Memo *Memo `json:"memo"` +} + +// WebhookResponse is the response of webhook request. +// nolint +type WebhookResponse struct { + Code int `json:"code"` + Message string `json:"message"` +} + +// Post posts the message to webhook endpoint. +func Post(payload WebhookPayload) error { + body, err := json.Marshal(&payload) + if err != nil { + return errors.Wrapf(err, "failed to marshal webhook request to %s", payload.URL) + } + req, err := http.NewRequest("POST", + payload.URL, bytes.NewBuffer(body)) + if err != nil { + return errors.Wrapf(err, "failed to construct webhook request to %s", payload.URL) + } + + req.Header.Set("Content-Type", "application/json") + client := &http.Client{ + Timeout: timeout, + } + resp, err := client.Do(req) + if err != nil { + return errors.Wrapf(err, "failed to post webhook to %s", payload.URL) + } + + b, err := io.ReadAll(resp.Body) + if err != nil { + return errors.Wrapf(err, "failed to read webhook response from %s", payload.URL) + } + defer resp.Body.Close() + + if resp.StatusCode < 200 || resp.StatusCode > 299 { + return errors.Errorf("failed to post webhook %s, status code: %d, response body: %s", payload.URL, resp.StatusCode, b) + } + + response := &WebhookResponse{} + if err := json.Unmarshal(b, response); err != nil { + return errors.Wrapf(err, "failed to unmarshal webhook response from %s", payload.URL) + } + + if response.Code != 0 { + return errors.Errorf("receive error code sent by webhook server, code %d, msg: %s", response.Code, response.Message) + } + + return nil +} diff --git a/plugin/webhook/webhook_test.go b/plugin/webhook/webhook_test.go new file mode 100644 index 0000000000000..d770c2c079976 --- /dev/null +++ b/plugin/webhook/webhook_test.go @@ -0,0 +1 @@ +package webhook diff --git a/proto/README.md b/proto/README.md index 6f191ab664b74..6360cadb2f148 100644 --- a/proto/README.md +++ b/proto/README.md @@ -2,7 +2,7 @@ ## Prerequisites -- Install [buf](https://docs.buf.build/installation) +- [buf](https://docs.buf.build/installation) ## Generate diff --git a/proto/api/v2/activity_service.proto b/proto/api/v2/activity_service.proto index 8d7ebb49021c9..83f22977e7922 100644 --- a/proto/api/v2/activity_service.proto +++ b/proto/api/v2/activity_service.proto @@ -3,13 +3,16 @@ syntax = "proto3"; package memos.api.v2; import "google/api/annotations.proto"; +import "google/api/client.proto"; import "google/protobuf/timestamp.proto"; option go_package = "gen/api/v2"; service ActivityService { + // GetActivity returns the activity with the given id. rpc GetActivity(GetActivityRequest) returns (GetActivityResponse) { - option (google.api.http) = {get: "/v2/activities"}; + option (google.api.http) = {get: "/v2/activities/{id}"}; + option (google.api.method_signature) = "id"; } } @@ -32,8 +35,13 @@ message ActivityMemoCommentPayload { int32 related_memo_id = 2; } +message ActivityVersionUpdatePayload { + string version = 1; +} + message ActivityPayload { ActivityMemoCommentPayload memo_comment = 1; + ActivityVersionUpdatePayload version_update = 2; } message GetActivityRequest { diff --git a/proto/api/v2/auth_service.proto b/proto/api/v2/auth_service.proto new file mode 100644 index 0000000000000..7dbc898190cb3 --- /dev/null +++ b/proto/api/v2/auth_service.proto @@ -0,0 +1,70 @@ +syntax = "proto3"; + +package memos.api.v2; + +import "api/v2/user_service.proto"; +import "google/api/annotations.proto"; + +option go_package = "gen/api/v2"; + +service AuthService { + // GetAuthStatus returns the current auth status of the user. + rpc GetAuthStatus(GetAuthStatusRequest) returns (GetAuthStatusResponse) { + option (google.api.http) = {post: "/api/v2/auth/status"}; + } + // SignIn signs in the user with the given username and password. + rpc SignIn(SignInRequest) returns (SignInResponse) { + option (google.api.http) = {post: "/api/v2/auth/signin"}; + } + // SignInWithSSO signs in the user with the given SSO code. + rpc SignInWithSSO(SignInWithSSORequest) returns (SignInWithSSOResponse) { + option (google.api.http) = {post: "/api/v2/auth/signin/sso"}; + } + // SignUp signs up the user with the given username and password. + rpc SignUp(SignUpRequest) returns (SignUpResponse) { + option (google.api.http) = {post: "/api/v2/auth/signup"}; + } + // SignOut signs out the user. + rpc SignOut(SignOutRequest) returns (SignOutResponse) { + option (google.api.http) = {post: "/api/v2/auth/signout"}; + } +} + +message GetAuthStatusRequest {} + +message GetAuthStatusResponse { + User user = 1; +} + +message SignInRequest { + string username = 1; + string password = 2; + bool never_expire = 3; +} + +message SignInResponse { + User user = 1; +} + +message SignInWithSSORequest { + int32 idp_id = 1; + string code = 2; + string redirect_uri = 3; +} + +message SignInWithSSOResponse { + User user = 1; +} + +message SignUpRequest { + string username = 1; + string password = 2; +} + +message SignUpResponse { + User user = 1; +} + +message SignOutRequest {} + +message SignOutResponse {} diff --git a/proto/api/v2/common.proto b/proto/api/v2/common.proto index 532e8eb73916a..1a09183974c7b 100644 --- a/proto/api/v2/common.proto +++ b/proto/api/v2/common.proto @@ -11,3 +11,9 @@ enum RowStatus { ARCHIVED = 2; } + +// Used internally for obfuscating the page token. +message PageToken { + int32 limit = 1; + int32 offset = 2; +} diff --git a/proto/api/v2/inbox_service.proto b/proto/api/v2/inbox_service.proto index 001a44fb8faba..bb937ca10d195 100644 --- a/proto/api/v2/inbox_service.proto +++ b/proto/api/v2/inbox_service.proto @@ -10,27 +10,28 @@ import "google/protobuf/timestamp.proto"; option go_package = "gen/api/v2"; service InboxService { + // ListInboxes lists inboxes for a user. rpc ListInboxes(ListInboxesRequest) returns (ListInboxesResponse) { option (google.api.http) = {get: "/api/v2/inboxes"}; } - + // UpdateInbox updates an inbox. rpc UpdateInbox(UpdateInboxRequest) returns (UpdateInboxResponse) { option (google.api.http) = { - patch: "/v2/inboxes" + patch: "/api/v2/{inbox.name=inboxes/*}" body: "inbox" }; option (google.api.method_signature) = "inbox,update_mask"; } - + // DeleteInbox deletes an inbox. rpc DeleteInbox(DeleteInboxRequest) returns (DeleteInboxResponse) { - option (google.api.http) = {delete: "/v2/{name=inboxes/*}"}; + option (google.api.http) = {delete: "/api/v2/{name=inboxes/*}"}; option (google.api.method_signature) = "name"; } } message Inbox { // The name of the inbox. - // Format: inboxes/{id} + // Format: inboxes/{uid} string name = 1; // Format: users/{username} string sender = 2; @@ -49,6 +50,7 @@ message Inbox { enum Type { TYPE_UNSPECIFIED = 0; TYPE_MEMO_COMMENT = 1; + TYPE_VERSION_UPDATE = 2; } Type type = 6; @@ -76,7 +78,7 @@ message UpdateInboxResponse { message DeleteInboxRequest { // The name of the inbox to delete. - // Format: inboxes/{inbox} + // Format: inboxes/{uid} string name = 1; } diff --git a/proto/api/v2/link_service.proto b/proto/api/v2/link_service.proto new file mode 100644 index 0000000000000..47b80a8234ba6 --- /dev/null +++ b/proto/api/v2/link_service.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package memos.api.v2; + +import "google/api/annotations.proto"; + +option go_package = "gen/api/v2"; + +service LinkService { + rpc GetLinkMetadata(GetLinkMetadataRequest) returns (GetLinkMetadataResponse) { + option (google.api.http) = {get: "/api/v2/metadata"}; + } +} + +message LinkMetadata { + string title = 1; + string description = 2; + string image = 3; +} + +message GetLinkMetadataRequest { + string link = 1; +} + +message GetLinkMetadataResponse { + LinkMetadata metadata = 1; +} diff --git a/proto/api/v2/memo_relation_service.proto b/proto/api/v2/memo_relation_service.proto new file mode 100644 index 0000000000000..8bd9175742c82 --- /dev/null +++ b/proto/api/v2/memo_relation_service.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package memos.api.v2; + +option go_package = "gen/api/v2"; + +message MemoRelation { + int32 memo_id = 1; + int32 related_memo_id = 2; + + enum Type { + TYPE_UNSPECIFIED = 0; + REFERENCE = 1; + COMMENT = 2; + } + Type type = 3; +} diff --git a/proto/api/v2/memo_service.proto b/proto/api/v2/memo_service.proto index 222ede7444149..4ec5dad5fadb9 100644 --- a/proto/api/v2/memo_service.proto +++ b/proto/api/v2/memo_service.proto @@ -3,34 +3,112 @@ syntax = "proto3"; package memos.api.v2; import "api/v2/common.proto"; +import "api/v2/memo_relation_service.proto"; +import "api/v2/reaction_service.proto"; +import "api/v2/resource_service.proto"; import "google/api/annotations.proto"; import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/protobuf/field_mask.proto"; +import "google/protobuf/timestamp.proto"; option go_package = "gen/api/v2"; service MemoService { + // CreateMemo creates a memo. rpc CreateMemo(CreateMemoRequest) returns (CreateMemoResponse) { - option (google.api.http) = {post: "/api/v2/memos"}; + option (google.api.http) = { + post: "/api/v2/memos" + body: "*" + }; } - + // ListMemos lists memos with pagination and filter. rpc ListMemos(ListMemosRequest) returns (ListMemosResponse) { option (google.api.http) = {get: "/api/v2/memos"}; } - + // GetMemo gets a memo by id. rpc GetMemo(GetMemoRequest) returns (GetMemoResponse) { option (google.api.http) = {get: "/api/v2/memos/{id}"}; option (google.api.method_signature) = "id"; } - + // GetMemoByName gets a memo by name. + rpc GetMemoByName(GetMemoByNameRequest) returns (GetMemoByNameResponse) { + option (google.api.http) = {get: "/api/v2/memos/name/{name}"}; + option (google.api.method_signature) = "name"; + } + // UpdateMemo updates a memo. + rpc UpdateMemo(UpdateMemoRequest) returns (UpdateMemoResponse) { + option (google.api.http) = { + patch: "/api/v2/memos/{memo.id}" + body: "memo" + }; + option (google.api.method_signature) = "memo,update_mask"; + } + // DeleteMemo deletes a memo by id. + rpc DeleteMemo(DeleteMemoRequest) returns (DeleteMemoResponse) { + option (google.api.http) = {delete: "/api/v2/memos/{id}"}; + option (google.api.method_signature) = "id"; + } + // ExportMemos exports memos. + rpc ExportMemos(ExportMemosRequest) returns (ExportMemosResponse) { + option (google.api.http) = {post: "/api/v2/memos:export"}; + } + // SetMemoResources sets resources for a memo. + rpc SetMemoResources(SetMemoResourcesRequest) returns (SetMemoResourcesResponse) { + option (google.api.http) = { + post: "/api/v2/memos/{id}/resources" + body: "*" + }; + option (google.api.method_signature) = "id"; + } + // ListMemoResources lists resources for a memo. + rpc ListMemoResources(ListMemoResourcesRequest) returns (ListMemoResourcesResponse) { + option (google.api.http) = {get: "/api/v2/memos/{id}/resources"}; + option (google.api.method_signature) = "id"; + } + // SetMemoRelations sets relations for a memo. + rpc SetMemoRelations(SetMemoRelationsRequest) returns (SetMemoRelationsResponse) { + option (google.api.http) = { + post: "/api/v2/memos/{id}/relations" + body: "*" + }; + option (google.api.method_signature) = "id"; + } + // ListMemoRelations lists relations for a memo. + rpc ListMemoRelations(ListMemoRelationsRequest) returns (ListMemoRelationsResponse) { + option (google.api.http) = {get: "/api/v2/memos/{id}/relations"}; + option (google.api.method_signature) = "id"; + } + // CreateMemoComment creates a comment for a memo. rpc CreateMemoComment(CreateMemoCommentRequest) returns (CreateMemoCommentResponse) { option (google.api.http) = {post: "/api/v2/memos/{id}/comments"}; option (google.api.method_signature) = "id"; } - + // ListMemoComments lists comments for a memo. rpc ListMemoComments(ListMemoCommentsRequest) returns (ListMemoCommentsResponse) { option (google.api.http) = {get: "/api/v2/memos/{id}/comments"}; option (google.api.method_signature) = "id"; } + // GetUserMemosStats gets stats of memos for a user. + rpc GetUserMemosStats(GetUserMemosStatsRequest) returns (GetUserMemosStatsResponse) { + option (google.api.http) = {get: "/api/v2/memos/stats"}; + option (google.api.method_signature) = "username"; + } + // ListMemoReactions lists reactions for a memo. + rpc ListMemoReactions(ListMemoReactionsRequest) returns (ListMemoReactionsResponse) { + option (google.api.http) = {get: "/api/v2/memos/{id}/reactions"}; + option (google.api.method_signature) = "id"; + } + // UpsertMemoReaction upserts a reaction for a memo. + rpc UpsertMemoReaction(UpsertMemoReactionRequest) returns (UpsertMemoReactionResponse) { + option (google.api.http) = {post: "/api/v2/memos/{id}/reactions"}; + option (google.api.method_signature) = "id"; + } + // DeleteMemoReaction deletes a reaction for a memo. + rpc DeleteMemoReaction(DeleteMemoReactionRequest) returns (DeleteMemoReactionResponse) { + option (google.api.http) = {delete: "/api/v2/memos/{id}/reactions/{reaction_id}"}; + option (google.api.method_signature) = "id,reaction_id"; + } } enum Visibility { @@ -44,21 +122,39 @@ enum Visibility { } message Memo { + // id is the system generated unique identifier. int32 id = 1; - RowStatus row_status = 2; + // name is the user provided name. + string name = 2; + + RowStatus row_status = 3; - int32 creator_id = 3; + // The name of the creator. + // Format: users/{username} + string creator = 4; - int64 created_ts = 4; + int32 creator_id = 5; - int64 updated_ts = 5; + google.protobuf.Timestamp create_time = 6; - string content = 6; + google.protobuf.Timestamp update_time = 7; - Visibility visibility = 7; + google.protobuf.Timestamp display_time = 8; - bool pinned = 8; + string content = 9; + + Visibility visibility = 10; + + bool pinned = 11; + + optional int32 parent_id = 12 [(google.api.field_behavior) = OUTPUT_ONLY]; + + repeated Resource resources = 13 [(google.api.field_behavior) = OUTPUT_ONLY]; + + repeated MemoRelation relations = 14 [(google.api.field_behavior) = OUTPUT_ONLY]; + + repeated Reaction reactions = 15 [(google.api.field_behavior) = OUTPUT_ONLY]; } message CreateMemoRequest { @@ -72,18 +168,24 @@ message CreateMemoResponse { } message ListMemosRequest { - int32 page = 1; + // The maximum number of memos to return. + int32 page_size = 1; - int32 page_size = 2; + // A page token, received from a previous `ListMemos` call. + // Provide this to retrieve the subsequent page. + string page_token = 2; // Filter is used to filter memos returned in the list. + // Format: "creator == users/{username} && visibilities == ['PUBLIC', 'PROTECTED']" string filter = 3; - - optional int32 creator_id = 4; } message ListMemosResponse { repeated Memo memos = 1; + + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + string next_page_token = 2; } message GetMemoRequest { @@ -94,6 +196,71 @@ message GetMemoResponse { Memo memo = 1; } +message GetMemoByNameRequest { + string name = 1; +} + +message GetMemoByNameResponse { + Memo memo = 1; +} + +message UpdateMemoRequest { + Memo memo = 1; + + google.protobuf.FieldMask update_mask = 2; +} + +message UpdateMemoResponse { + Memo memo = 1; +} + +message DeleteMemoRequest { + int32 id = 1; +} + +message DeleteMemoResponse {} + +message ExportMemosRequest { + // Same as ListMemosRequest.filter + string filter = 1; +} + +message ExportMemosResponse { + bytes content = 1; +} + +message SetMemoResourcesRequest { + int32 id = 1; + + repeated Resource resources = 2; +} + +message SetMemoResourcesResponse {} + +message ListMemoResourcesRequest { + int32 id = 1; +} + +message ListMemoResourcesResponse { + repeated Resource resources = 1; +} + +message SetMemoRelationsRequest { + int32 id = 1; + + repeated MemoRelation relations = 2; +} + +message SetMemoRelationsResponse {} + +message ListMemoRelationsRequest { + int32 id = 1; +} + +message ListMemoRelationsResponse { + repeated MemoRelation relations = 1; +} + message CreateMemoCommentRequest { // id is the memo id to create comment for. int32 id = 1; @@ -112,3 +279,49 @@ message ListMemoCommentsRequest { message ListMemoCommentsResponse { repeated Memo memos = 1; } + +message GetUserMemosStatsRequest { + // name is the name of the user to get stats for. + // Format: users/{username} + string name = 1; + + // timezone location + // Format: uses tz identifier + // https://en.wikipedia.org/wiki/List_of_tz_database_time_zones + string timezone = 2; + + // Same as ListMemosRequest.filter + string filter = 3; +} + +message GetUserMemosStatsResponse { + // stats is the stats of memo creating/updating activities. + // key is the year-month-day string. e.g. "2020-01-01". + map stats = 1; +} + +message ListMemoReactionsRequest { + int32 id = 1; +} + +message ListMemoReactionsResponse { + repeated Reaction reactions = 1; +} + +message UpsertMemoReactionRequest { + int32 id = 1; + + Reaction reaction = 2; +} + +message UpsertMemoReactionResponse { + Reaction reaction = 1; +} + +message DeleteMemoReactionRequest { + int32 id = 1; + + int32 reaction_id = 2; +} + +message DeleteMemoReactionResponse {} diff --git a/proto/api/v2/reaction_service.proto b/proto/api/v2/reaction_service.proto new file mode 100644 index 0000000000000..0ca68382bd3ef --- /dev/null +++ b/proto/api/v2/reaction_service.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package memos.api.v2; + +option go_package = "gen/api/v2"; + +message Reaction { + int32 id = 1; + + string creator = 2; + + string content_id = 3; + + enum Type { + TYPE_UNSPECIFIED = 0; + THUMBS_UP = 1; + THUMBS_DOWN = 2; + HEART = 3; + FIRE = 4; + CLAPPING_HANDS = 5; + LAUGH = 6; + OK_HAND = 7; + ROCKET = 8; + EYES = 9; + THINKING_FACE = 10; + CLOWN_FACE = 11; + QUESTION_MARK = 12; + } + Type reaction_type = 4; +} diff --git a/proto/api/v2/resource_service.proto b/proto/api/v2/resource_service.proto index 4c75a7ac123ca..79198c8575829 100644 --- a/proto/api/v2/resource_service.proto +++ b/proto/api/v2/resource_service.proto @@ -10,12 +10,25 @@ import "google/protobuf/timestamp.proto"; option go_package = "gen/api/v2"; service ResourceService { + // CreateResource creates a new resource. rpc CreateResource(CreateResourceRequest) returns (CreateResourceResponse) { option (google.api.http) = {post: "/api/v2/resources"}; } + // ListResources lists all resources. rpc ListResources(ListResourcesRequest) returns (ListResourcesResponse) { option (google.api.http) = {get: "/api/v2/resources"}; } + // GetResource returns a resource by id. + rpc GetResource(GetResourceRequest) returns (GetResourceResponse) { + option (google.api.http) = {get: "/api/v2/resources/{id}"}; + option (google.api.method_signature) = "id"; + } + // GetResourceByName returns a resource by name. + rpc GetResourceByName(GetResourceByNameRequest) returns (GetResourceByNameResponse) { + option (google.api.http) = {get: "/api/v2/resources/name/{name}"}; + option (google.api.method_signature) = "name"; + } + // UpdateResource updates a resource. rpc UpdateResource(UpdateResourceRequest) returns (UpdateResourceResponse) { option (google.api.http) = { patch: "/api/v2/resources/{resource.id}", @@ -23,20 +36,31 @@ service ResourceService { }; option (google.api.method_signature) = "resource,update_mask"; } + // DeleteResource deletes a resource by id. rpc DeleteResource(DeleteResourceRequest) returns (DeleteResourceResponse) { - option (google.api.http) = {get: "/api/v2/resources/{id}"}; + option (google.api.http) = {delete: "/api/v2/resources/{id}"}; option (google.api.method_signature) = "id"; } } message Resource { + // id is the system generated unique identifier. int32 id = 1; - google.protobuf.Timestamp created_ts = 2; - string filename = 3; - string external_link = 4; - string type = 5; - int64 size = 6; - optional int32 memo_id = 7; + + // name is the user provided name. + string name = 2; + + google.protobuf.Timestamp create_time = 3; + + string filename = 4; + + string external_link = 5; + + string type = 6; + + int64 size = 7; + + optional int32 memo_id = 8; } message CreateResourceRequest { @@ -56,6 +80,22 @@ message ListResourcesResponse { repeated Resource resources = 1; } +message GetResourceRequest { + int32 id = 1; +} + +message GetResourceResponse { + Resource resource = 1; +} + +message GetResourceByNameRequest { + string name = 1; +} + +message GetResourceByNameResponse { + Resource resource = 1; +} + message UpdateResourceRequest { Resource resource = 1; diff --git a/proto/api/v2/system_service.proto b/proto/api/v2/system_service.proto deleted file mode 100644 index 1af7ed17f2776..0000000000000 --- a/proto/api/v2/system_service.proto +++ /dev/null @@ -1,48 +0,0 @@ -syntax = "proto3"; - -package memos.api.v2; - -import "google/api/annotations.proto"; -import "google/api/client.proto"; -import "google/protobuf/field_mask.proto"; - -option go_package = "gen/api/v2"; - -service SystemService { - rpc GetSystemInfo(GetSystemInfoRequest) returns (GetSystemInfoResponse) { - option (google.api.http) = {get: "/api/v2/system/info"}; - } - rpc UpdateSystemInfo(UpdateSystemInfoRequest) returns (UpdateSystemInfoResponse) { - option (google.api.http) = { - patch: "/api/v2/system/info", - body: "system_info" - }; - option (google.api.method_signature) = "system_info,update_mask"; - } -} - -message SystemInfo { - string version = 1; - string mode = 2; - bool allow_registration = 3; - bool disable_password_login = 4; - string additional_script = 5; - string additional_style = 6; - int64 db_size = 7; -} - -message GetSystemInfoRequest {} - -message GetSystemInfoResponse { - SystemInfo system_info = 1; -} - -message UpdateSystemInfoRequest { - // System info is the updated data. - SystemInfo system_info = 1; - google.protobuf.FieldMask update_mask = 2; -} - -message UpdateSystemInfoResponse { - SystemInfo system_info = 1; -} diff --git a/proto/api/v2/tag_service.proto b/proto/api/v2/tag_service.proto index ebcc50b3b6954..5646bcf656f02 100644 --- a/proto/api/v2/tag_service.proto +++ b/proto/api/v2/tag_service.proto @@ -7,20 +7,38 @@ import "google/api/annotations.proto"; option go_package = "gen/api/v2"; service TagService { + // UpsertTag upserts a tag. rpc UpsertTag(UpsertTagRequest) returns (UpsertTagResponse) { option (google.api.http) = {post: "/api/v2/tags"}; } + // BatchUpsertTag upserts multiple tags. + rpc BatchUpsertTag(BatchUpsertTagRequest) returns (BatchUpsertTagResponse) { + option (google.api.http) = {post: "/api/v2/tags:batchUpsert"}; + } + // ListTags lists tags. rpc ListTags(ListTagsRequest) returns (ListTagsResponse) { option (google.api.http) = {get: "/api/v2/tags"}; } + // RenameTag renames a tag. + // All related memos will be updated. + rpc RenameTag(RenameTagRequest) returns (RenameTagResponse) { + option (google.api.http) = {patch: "/api/v2/tags:rename"}; + } + // DeleteTag deletes a tag. rpc DeleteTag(DeleteTagRequest) returns (DeleteTagResponse) { option (google.api.http) = {delete: "/api/v2/tags"}; } + // GetTagSuggestions gets tag suggestions from the user's memos. + rpc GetTagSuggestions(GetTagSuggestionsRequest) returns (GetTagSuggestionsResponse) { + option (google.api.http) = {get: "/api/v2/tags/suggestion"}; + } } message Tag { string name = 1; - int32 creator_id = 2; + // The creator of tags. + // Format: users/{username} + string creator = 2; } message UpsertTagRequest { @@ -31,16 +49,46 @@ message UpsertTagResponse { Tag tag = 1; } +message BatchUpsertTagRequest { + repeated UpsertTagRequest requests = 1; +} + +message BatchUpsertTagResponse {} + message ListTagsRequest { - int32 creator_id = 1; + // The creator of tags. + // Format: users/{username} + string user = 1; } message ListTagsResponse { repeated Tag tags = 1; } +message RenameTagRequest { + // The creator of tags. + // Format: users/{username} + string user = 1; + string old_name = 2; + string new_name = 3; +} + +message RenameTagResponse { + Tag tag = 1; +} + message DeleteTagRequest { Tag tag = 1; } message DeleteTagResponse {} + +message GetTagSuggestionsRequest { + // The creator of tags. + // Format: users/{username} + string user = 1; +} + +message GetTagSuggestionsResponse { + repeated string tags = 1; +} diff --git a/proto/api/v2/user_service.proto b/proto/api/v2/user_service.proto index fbce9267c9e9d..e5372a2101cea 100644 --- a/proto/api/v2/user_service.proto +++ b/proto/api/v2/user_service.proto @@ -12,48 +12,75 @@ import "google/protobuf/timestamp.proto"; option go_package = "gen/api/v2"; service UserService { + // ListUsers returns a list of users. + rpc ListUsers(ListUsersRequest) returns (ListUsersResponse) { + option (google.api.http) = {get: "/api/v2/users"}; + } + // GetUser gets a user by name. rpc GetUser(GetUserRequest) returns (GetUserResponse) { - option (google.api.http) = {get: "/api/v2/users/{username}"}; - option (google.api.method_signature) = "username"; + option (google.api.http) = {get: "/api/v2/{name=users/*}"}; + option (google.api.method_signature) = "name"; } + // CreateUser creates a new user. rpc CreateUser(CreateUserRequest) returns (CreateUserResponse) { option (google.api.http) = { - post: "/v1/users" + post: "/api/v2/users" body: "user" }; option (google.api.method_signature) = "user"; } + // UpdateUser updates a user. rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse) { option (google.api.http) = { - patch: "/api/v2/users/{user.username}" + patch: "/api/v2/{user.name=users/*}" body: "user" }; option (google.api.method_signature) = "user,update_mask"; } + // DeleteUser deletes a user. + rpc DeleteUser(DeleteUserRequest) returns (DeleteUserResponse) { + option (google.api.http) = {delete: "/api/v2/{name=users/*}"}; + option (google.api.method_signature) = "name"; + } + // GetUserSetting gets the setting of a user. + rpc GetUserSetting(GetUserSettingRequest) returns (GetUserSettingResponse) { + option (google.api.http) = {get: "/api/v2/{name=users/*}/setting"}; + option (google.api.method_signature) = "name"; + } + // UpdateUserSetting updates the setting of a user. + rpc UpdateUserSetting(UpdateUserSettingRequest) returns (UpdateUserSettingResponse) { + option (google.api.http) = { + patch: "/api/v2/{setting.name=users/*/setting}" + body: "setting" + }; + option (google.api.method_signature) = "setting,update_mask"; + } // ListUserAccessTokens returns a list of access tokens for a user. rpc ListUserAccessTokens(ListUserAccessTokensRequest) returns (ListUserAccessTokensResponse) { - option (google.api.http) = {get: "/api/v2/users/{username}/access_tokens"}; - option (google.api.method_signature) = "username"; + option (google.api.http) = {get: "/api/v2/{name=users/*}/access_tokens"}; + option (google.api.method_signature) = "name"; } // CreateUserAccessToken creates a new access token for a user. rpc CreateUserAccessToken(CreateUserAccessTokenRequest) returns (CreateUserAccessTokenResponse) { option (google.api.http) = { - post: "/api/v2/users/{username}/access_tokens" + post: "/api/v2/{name=users/*}/access_tokens" body: "*" }; - option (google.api.method_signature) = "username"; + option (google.api.method_signature) = "name"; } // DeleteUserAccessToken deletes an access token for a user. rpc DeleteUserAccessToken(DeleteUserAccessTokenRequest) returns (DeleteUserAccessTokenResponse) { - option (google.api.http) = {delete: "/api/v2/users/{username}/access_tokens/{access_token}"}; - option (google.api.method_signature) = "username,access_token"; + option (google.api.http) = {delete: "/api/v2/{name=users/*}/access_tokens/{access_token}"}; + option (google.api.method_signature) = "name,access_token"; } } message User { - int32 id = 1; + // The name of the user. + // Format: users/{username} + string name = 1; - string username = 2; + int32 id = 2; enum Role { ROLE_UNSPECIFIED = 0; @@ -63,23 +90,33 @@ message User { } Role role = 3; - string email = 4; + string username = 4; + + string email = 5; + + string nickname = 6; - string nickname = 5; + string avatar_url = 7; - string avatar_url = 6; + string password = 8 [(google.api.field_behavior) = INPUT_ONLY]; - string password = 7 [(google.api.field_behavior) = INPUT_ONLY]; + RowStatus row_status = 9; - RowStatus row_status = 8; + google.protobuf.Timestamp create_time = 10; + + google.protobuf.Timestamp update_time = 11; +} - google.protobuf.Timestamp create_time = 9; +message ListUsersRequest {} - google.protobuf.Timestamp update_time = 10; +message ListUsersResponse { + repeated User users = 1; } message GetUserRequest { - string username = 1; + // The name of the user. + // Format: users/{username} + string name = 1; } message GetUserResponse { @@ -104,8 +141,59 @@ message UpdateUserResponse { User user = 1; } +message DeleteUserRequest { + // The name of the user. + // Format: users/{username} + string name = 1; +} + +message DeleteUserResponse {} + +message UserSetting { + // The name of the user. + // Format: users/{username} + string name = 1; + // The preferred locale of the user. + string locale = 2; + // The preferred appearance of the user. + string appearance = 3; + // The default visibility of the memo. + string memo_visibility = 4; + // The telegram user id of the user. + string telegram_user_id = 5; +} + +message GetUserSettingRequest { + // The name of the user. + // Format: users/{username} + string name = 1; +} + +message GetUserSettingResponse { + UserSetting setting = 1; +} + +message UpdateUserSettingRequest { + UserSetting setting = 1 [(google.api.field_behavior) = REQUIRED]; + + google.protobuf.FieldMask update_mask = 2; +} + +message UpdateUserSettingResponse { + UserSetting setting = 1; +} + +message UserAccessToken { + string access_token = 1; + string description = 2; + google.protobuf.Timestamp issued_at = 3; + google.protobuf.Timestamp expires_at = 4; +} + message ListUserAccessTokensRequest { - string username = 1; + // The name of the user. + // Format: users/{username} + string name = 1; } message ListUserAccessTokensResponse { @@ -113,7 +201,9 @@ message ListUserAccessTokensResponse { } message CreateUserAccessTokenRequest { - string username = 1; + // The name of the user. + // Format: users/{username} + string name = 1; string description = 2; @@ -125,16 +215,11 @@ message CreateUserAccessTokenResponse { } message DeleteUserAccessTokenRequest { - string username = 1; + // The name of the user. + // Format: users/{username} + string name = 1; // access_token is the access token to delete. string access_token = 2; } message DeleteUserAccessTokenResponse {} - -message UserAccessToken { - string access_token = 1; - string description = 2; - google.protobuf.Timestamp issued_at = 3; - google.protobuf.Timestamp expires_at = 4; -} diff --git a/proto/api/v2/webhook_service.proto b/proto/api/v2/webhook_service.proto new file mode 100644 index 0000000000000..1364a1818471d --- /dev/null +++ b/proto/api/v2/webhook_service.proto @@ -0,0 +1,101 @@ +syntax = "proto3"; + +package memos.api.v2; + +import "api/v2/common.proto"; +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/protobuf/field_mask.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "gen/api/v2"; + +service WebhookService { + // CreateWebhook creates a new webhook. + rpc CreateWebhook(CreateWebhookRequest) returns (CreateWebhookResponse) { + option (google.api.http) = { + post: "/api/v2/webhooks" + body: "*" + }; + } + // GetWebhook returns a webhook by id. + rpc GetWebhook(GetWebhookRequest) returns (GetWebhookResponse) { + option (google.api.http) = {get: "/api/v2/webhooks/{id}"}; + option (google.api.method_signature) = "id"; + } + // ListWebhooks returns a list of webhooks. + rpc ListWebhooks(ListWebhooksRequest) returns (ListWebhooksResponse) { + option (google.api.http) = {get: "/api/v2/webhooks"}; + } + // UpdateWebhook updates a webhook. + rpc UpdateWebhook(UpdateWebhookRequest) returns (UpdateWebhookResponse) { + option (google.api.http) = { + patch: "/api/v2/webhooks/{webhook.id}" + body: "webhook" + }; + option (google.api.method_signature) = "webhook,update_mask"; + } + // DeleteWebhook deletes a webhook by id. + rpc DeleteWebhook(DeleteWebhookRequest) returns (DeleteWebhookResponse) { + option (google.api.http) = {delete: "/api/v2/webhooks/{id}"}; + option (google.api.method_signature) = "id"; + } +} + +message Webhook { + int32 id = 1; + + int32 creator_id = 2; + + google.protobuf.Timestamp created_time = 3; + + google.protobuf.Timestamp updated_time = 4; + + RowStatus row_status = 5; + + string name = 6; + + string url = 7; +} + +message CreateWebhookRequest { + string name = 1; + + string url = 2; +} + +message CreateWebhookResponse { + Webhook webhook = 1; +} + +message GetWebhookRequest { + int32 id = 1; +} + +message GetWebhookResponse { + Webhook webhook = 1; +} + +message ListWebhooksRequest { + int32 creator_id = 1; +} + +message ListWebhooksResponse { + repeated Webhook webhooks = 1; +} + +message UpdateWebhookRequest { + Webhook webhook = 1; + + google.protobuf.FieldMask update_mask = 2; +} + +message UpdateWebhookResponse { + Webhook webhook = 1; +} + +message DeleteWebhookRequest { + int32 id = 1; +} + +message DeleteWebhookResponse {} diff --git a/proto/api/v2/workspace_service.proto b/proto/api/v2/workspace_service.proto new file mode 100644 index 0000000000000..680c4b4fc4d39 --- /dev/null +++ b/proto/api/v2/workspace_service.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; + +package memos.api.v2; + +import "google/api/annotations.proto"; + +option go_package = "gen/api/v2"; + +service WorkspaceService { + // GetWorkspaceProfile returns the workspace profile. + rpc GetWorkspaceProfile(GetWorkspaceProfileRequest) returns (GetWorkspaceProfileResponse) { + option (google.api.http) = {get: "/api/v2/workspace/profile"}; + } +} + +message WorkspaceProfile { + // version is the current version of instance + string version = 1; + // mode is the instance mode (e.g. "prod", "dev" or "demo"). + string mode = 2; + // allow_registration is whether the registration is allowed. + bool allow_registration = 3; + // allow_password_login is whether the password login is allowed. + bool disable_password_login = 4; + // additional_script is the additional script. + string additional_script = 5; + // additional_style is the additional style. + string additional_style = 6; +} + +message GetWorkspaceProfileRequest {} + +message GetWorkspaceProfileResponse { + WorkspaceProfile workspace_profile = 1; +} diff --git a/proto/api/v2/workspace_setting_service.proto b/proto/api/v2/workspace_setting_service.proto new file mode 100644 index 0000000000000..3d82175df47cf --- /dev/null +++ b/proto/api/v2/workspace_setting_service.proto @@ -0,0 +1,67 @@ +syntax = "proto3"; + +package memos.api.v2; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; + +option go_package = "gen/api/v2"; + +service WorkspaceSettingService { + // GetWorkspaceSetting returns the setting by name. + rpc GetWorkspaceSetting(GetWorkspaceSettingRequest) returns (GetWorkspaceSettingResponse) { + option (google.api.http) = {get: "/api/v2/workspace/{name=settings/*}"}; + option (google.api.method_signature) = "name"; + } + // SetWorkspaceSetting updates the setting. + rpc SetWorkspaceSetting(SetWorkspaceSettingRequest) returns (SetWorkspaceSettingResponse) { + option (google.api.http) = { + patch: "/api/v2/workspace/{setting.name=settings/*}", + body: "setting" + }; + option (google.api.method_signature) = "setting"; + } +} + +message GetWorkspaceSettingRequest { + // The resource name of the workspace setting. + // Format: settings/{setting} + string name = 1 [(google.api.field_behavior) = REQUIRED]; +} + +message GetWorkspaceSettingResponse { + WorkspaceSetting setting = 1; +} + +message SetWorkspaceSettingRequest { + // setting is the setting to update. + WorkspaceSetting setting = 1; +} + +message SetWorkspaceSettingResponse { + WorkspaceSetting setting = 1; +} + +message WorkspaceSetting { + // name is the name of the setting. + // Format: settings/{setting} + string name = 1; + oneof value { + // general_setting is the general setting of workspace. + WorkspaceGeneralSetting general_setting = 2; + } +} + +message WorkspaceGeneralSetting { + // instance_url is the instance URL. + string instance_url = 1; + // disallow_signup is the flag to disallow signup. + bool disallow_signup = 2; + // disallow_password_login is the flag to disallow password login. + bool disallow_password_login = 3; + // additional_script is the additional script. + string additional_script = 5; + // additional_style is the additional style. + string additional_style = 6; +} diff --git a/proto/buf.gen.yaml b/proto/buf.gen.yaml index f526a35927119..e0988e692267d 100644 --- a/proto/buf.gen.yaml +++ b/proto/buf.gen.yaml @@ -18,6 +18,9 @@ plugins: out: gen opt: - paths=source_relative + - plugin: buf.build/grpc-ecosystem/openapiv2:v2.19.0 + out: ../server/route/api/v2/ + opt: output_format=yaml,allow_merge=true # Build the TypeScript definitions for the web. - plugin: buf.build/community/stephenh-ts-proto:v1.152.1 out: ../web/src/types/proto @@ -29,6 +32,7 @@ plugins: - outputJsonMethods=false - useExactTypes=false - esModuleInterop=true + - stringEnums=true - plugin: buf.build/community/pseudomuto-doc:v1.5.1 out: gen opt: diff --git a/proto/buf.lock b/proto/buf.lock index 2c703b6f49ca3..d029c4dc77881 100644 --- a/proto/buf.lock +++ b/proto/buf.lock @@ -4,10 +4,10 @@ deps: - remote: buf.build owner: googleapis repository: googleapis - commit: 711e289f6a384c4caeebaff7c6931ade - digest: shake256:e08fb55dad7469f69df00304eed31427d2d1576e9aab31e6bf86642688e04caaf0372f15fe6974cf79432779a635b3ea401ca69c943976dc42749524e4c25d94 + commit: a86849a25cc04f4dbe9b15ddddfbc488 + digest: shake256:e19143328f8cbfe13fc226aeee5e63773ca494693a72740a7560664270039a380d94a1344234b88c7691311460df9a9b1c2982190d0a2612eae80368718e1943 - remote: buf.build owner: grpc-ecosystem repository: grpc-gateway - commit: fed2dcdcfd694403ad51cd3c94957830 - digest: shake256:ed076a21e3d772892fc465ced0e4dd50f9dba86fdd4473920eaa25efa4807644e8e021be423dcfcee74bf4242e7e57422393f9b1abb10acb18ea1a5df509bb19 + commit: 3f42134f4c564983838425bc43c7a65f + digest: shake256:3d11d4c0fe5e05fda0131afefbce233940e27f0c31c5d4e385686aea58ccd30f72053f61af432fa83f1fc11cda57f5f18ca3da26a29064f73c5a0d076bba8d92 diff --git a/proto/gen/api/v2/README.md b/proto/gen/api/v2/README.md index e2d55fc6914c0..ae9bb542aa7eb 100644 --- a/proto/gen/api/v2/README.md +++ b/proto/gen/api/v2/README.md @@ -7,14 +7,60 @@ - [Activity](#memos-api-v2-Activity) - [ActivityMemoCommentPayload](#memos-api-v2-ActivityMemoCommentPayload) - [ActivityPayload](#memos-api-v2-ActivityPayload) + - [ActivityVersionUpdatePayload](#memos-api-v2-ActivityVersionUpdatePayload) - [GetActivityRequest](#memos-api-v2-GetActivityRequest) - [GetActivityResponse](#memos-api-v2-GetActivityResponse) - [ActivityService](#memos-api-v2-ActivityService) - [api/v2/common.proto](#api_v2_common-proto) + - [PageToken](#memos-api-v2-PageToken) + - [RowStatus](#memos-api-v2-RowStatus) +- [api/v2/user_service.proto](#api_v2_user_service-proto) + - [CreateUserAccessTokenRequest](#memos-api-v2-CreateUserAccessTokenRequest) + - [CreateUserAccessTokenResponse](#memos-api-v2-CreateUserAccessTokenResponse) + - [CreateUserRequest](#memos-api-v2-CreateUserRequest) + - [CreateUserResponse](#memos-api-v2-CreateUserResponse) + - [DeleteUserAccessTokenRequest](#memos-api-v2-DeleteUserAccessTokenRequest) + - [DeleteUserAccessTokenResponse](#memos-api-v2-DeleteUserAccessTokenResponse) + - [DeleteUserRequest](#memos-api-v2-DeleteUserRequest) + - [DeleteUserResponse](#memos-api-v2-DeleteUserResponse) + - [GetUserRequest](#memos-api-v2-GetUserRequest) + - [GetUserResponse](#memos-api-v2-GetUserResponse) + - [GetUserSettingRequest](#memos-api-v2-GetUserSettingRequest) + - [GetUserSettingResponse](#memos-api-v2-GetUserSettingResponse) + - [ListUserAccessTokensRequest](#memos-api-v2-ListUserAccessTokensRequest) + - [ListUserAccessTokensResponse](#memos-api-v2-ListUserAccessTokensResponse) + - [ListUsersRequest](#memos-api-v2-ListUsersRequest) + - [ListUsersResponse](#memos-api-v2-ListUsersResponse) + - [UpdateUserRequest](#memos-api-v2-UpdateUserRequest) + - [UpdateUserResponse](#memos-api-v2-UpdateUserResponse) + - [UpdateUserSettingRequest](#memos-api-v2-UpdateUserSettingRequest) + - [UpdateUserSettingResponse](#memos-api-v2-UpdateUserSettingResponse) + - [User](#memos-api-v2-User) + - [UserAccessToken](#memos-api-v2-UserAccessToken) + - [UserSetting](#memos-api-v2-UserSetting) + + - [User.Role](#memos-api-v2-User-Role) + + - [UserService](#memos-api-v2-UserService) + +- [api/v2/auth_service.proto](#api_v2_auth_service-proto) + - [GetAuthStatusRequest](#memos-api-v2-GetAuthStatusRequest) + - [GetAuthStatusResponse](#memos-api-v2-GetAuthStatusResponse) + - [SignInRequest](#memos-api-v2-SignInRequest) + - [SignInResponse](#memos-api-v2-SignInResponse) + - [SignInWithSSORequest](#memos-api-v2-SignInWithSSORequest) + - [SignInWithSSOResponse](#memos-api-v2-SignInWithSSOResponse) + - [SignOutRequest](#memos-api-v2-SignOutRequest) + - [SignOutResponse](#memos-api-v2-SignOutResponse) + - [SignUpRequest](#memos-api-v2-SignUpRequest) + - [SignUpResponse](#memos-api-v2-SignUpResponse) + + - [AuthService](#memos-api-v2-AuthService) + - [api/v2/inbox_service.proto](#api_v2_inbox_service-proto) - [DeleteInboxRequest](#memos-api-v2-DeleteInboxRequest) - [DeleteInboxResponse](#memos-api-v2-DeleteInboxResponse) @@ -29,28 +75,32 @@ - [InboxService](#memos-api-v2-InboxService) -- [api/v2/memo_service.proto](#api_v2_memo_service-proto) - - [CreateMemoCommentRequest](#memos-api-v2-CreateMemoCommentRequest) - - [CreateMemoCommentResponse](#memos-api-v2-CreateMemoCommentResponse) - - [CreateMemoRequest](#memos-api-v2-CreateMemoRequest) - - [CreateMemoResponse](#memos-api-v2-CreateMemoResponse) - - [GetMemoRequest](#memos-api-v2-GetMemoRequest) - - [GetMemoResponse](#memos-api-v2-GetMemoResponse) - - [ListMemoCommentsRequest](#memos-api-v2-ListMemoCommentsRequest) - - [ListMemoCommentsResponse](#memos-api-v2-ListMemoCommentsResponse) - - [ListMemosRequest](#memos-api-v2-ListMemosRequest) - - [ListMemosResponse](#memos-api-v2-ListMemosResponse) - - [Memo](#memos-api-v2-Memo) +- [api/v2/link_service.proto](#api_v2_link_service-proto) + - [GetLinkMetadataRequest](#memos-api-v2-GetLinkMetadataRequest) + - [GetLinkMetadataResponse](#memos-api-v2-GetLinkMetadataResponse) + - [LinkMetadata](#memos-api-v2-LinkMetadata) - - [Visibility](#memos-api-v2-Visibility) + - [LinkService](#memos-api-v2-LinkService) - - [MemoService](#memos-api-v2-MemoService) +- [api/v2/memo_relation_service.proto](#api_v2_memo_relation_service-proto) + - [MemoRelation](#memos-api-v2-MemoRelation) + + - [MemoRelation.Type](#memos-api-v2-MemoRelation-Type) + +- [api/v2/reaction_service.proto](#api_v2_reaction_service-proto) + - [Reaction](#memos-api-v2-Reaction) + + - [Reaction.Type](#memos-api-v2-Reaction-Type) - [api/v2/resource_service.proto](#api_v2_resource_service-proto) - [CreateResourceRequest](#memos-api-v2-CreateResourceRequest) - [CreateResourceResponse](#memos-api-v2-CreateResourceResponse) - [DeleteResourceRequest](#memos-api-v2-DeleteResourceRequest) - [DeleteResourceResponse](#memos-api-v2-DeleteResourceResponse) + - [GetResourceByNameRequest](#memos-api-v2-GetResourceByNameRequest) + - [GetResourceByNameResponse](#memos-api-v2-GetResourceByNameResponse) + - [GetResourceRequest](#memos-api-v2-GetResourceRequest) + - [GetResourceResponse](#memos-api-v2-GetResourceResponse) - [ListResourcesRequest](#memos-api-v2-ListResourcesRequest) - [ListResourcesResponse](#memos-api-v2-ListResourcesResponse) - [Resource](#memos-api-v2-Resource) @@ -59,45 +109,96 @@ - [ResourceService](#memos-api-v2-ResourceService) -- [api/v2/system_service.proto](#api_v2_system_service-proto) - - [GetSystemInfoRequest](#memos-api-v2-GetSystemInfoRequest) - - [GetSystemInfoResponse](#memos-api-v2-GetSystemInfoResponse) - - [SystemInfo](#memos-api-v2-SystemInfo) - - [UpdateSystemInfoRequest](#memos-api-v2-UpdateSystemInfoRequest) - - [UpdateSystemInfoResponse](#memos-api-v2-UpdateSystemInfoResponse) +- [api/v2/memo_service.proto](#api_v2_memo_service-proto) + - [CreateMemoCommentRequest](#memos-api-v2-CreateMemoCommentRequest) + - [CreateMemoCommentResponse](#memos-api-v2-CreateMemoCommentResponse) + - [CreateMemoRequest](#memos-api-v2-CreateMemoRequest) + - [CreateMemoResponse](#memos-api-v2-CreateMemoResponse) + - [DeleteMemoReactionRequest](#memos-api-v2-DeleteMemoReactionRequest) + - [DeleteMemoReactionResponse](#memos-api-v2-DeleteMemoReactionResponse) + - [DeleteMemoRequest](#memos-api-v2-DeleteMemoRequest) + - [DeleteMemoResponse](#memos-api-v2-DeleteMemoResponse) + - [ExportMemosRequest](#memos-api-v2-ExportMemosRequest) + - [ExportMemosResponse](#memos-api-v2-ExportMemosResponse) + - [GetMemoByNameRequest](#memos-api-v2-GetMemoByNameRequest) + - [GetMemoByNameResponse](#memos-api-v2-GetMemoByNameResponse) + - [GetMemoRequest](#memos-api-v2-GetMemoRequest) + - [GetMemoResponse](#memos-api-v2-GetMemoResponse) + - [GetUserMemosStatsRequest](#memos-api-v2-GetUserMemosStatsRequest) + - [GetUserMemosStatsResponse](#memos-api-v2-GetUserMemosStatsResponse) + - [GetUserMemosStatsResponse.StatsEntry](#memos-api-v2-GetUserMemosStatsResponse-StatsEntry) + - [ListMemoCommentsRequest](#memos-api-v2-ListMemoCommentsRequest) + - [ListMemoCommentsResponse](#memos-api-v2-ListMemoCommentsResponse) + - [ListMemoReactionsRequest](#memos-api-v2-ListMemoReactionsRequest) + - [ListMemoReactionsResponse](#memos-api-v2-ListMemoReactionsResponse) + - [ListMemoRelationsRequest](#memos-api-v2-ListMemoRelationsRequest) + - [ListMemoRelationsResponse](#memos-api-v2-ListMemoRelationsResponse) + - [ListMemoResourcesRequest](#memos-api-v2-ListMemoResourcesRequest) + - [ListMemoResourcesResponse](#memos-api-v2-ListMemoResourcesResponse) + - [ListMemosRequest](#memos-api-v2-ListMemosRequest) + - [ListMemosResponse](#memos-api-v2-ListMemosResponse) + - [Memo](#memos-api-v2-Memo) + - [SetMemoRelationsRequest](#memos-api-v2-SetMemoRelationsRequest) + - [SetMemoRelationsResponse](#memos-api-v2-SetMemoRelationsResponse) + - [SetMemoResourcesRequest](#memos-api-v2-SetMemoResourcesRequest) + - [SetMemoResourcesResponse](#memos-api-v2-SetMemoResourcesResponse) + - [UpdateMemoRequest](#memos-api-v2-UpdateMemoRequest) + - [UpdateMemoResponse](#memos-api-v2-UpdateMemoResponse) + - [UpsertMemoReactionRequest](#memos-api-v2-UpsertMemoReactionRequest) + - [UpsertMemoReactionResponse](#memos-api-v2-UpsertMemoReactionResponse) + + - [Visibility](#memos-api-v2-Visibility) - - [SystemService](#memos-api-v2-SystemService) + - [MemoService](#memos-api-v2-MemoService) - [api/v2/tag_service.proto](#api_v2_tag_service-proto) + - [BatchUpsertTagRequest](#memos-api-v2-BatchUpsertTagRequest) + - [BatchUpsertTagResponse](#memos-api-v2-BatchUpsertTagResponse) - [DeleteTagRequest](#memos-api-v2-DeleteTagRequest) - [DeleteTagResponse](#memos-api-v2-DeleteTagResponse) + - [GetTagSuggestionsRequest](#memos-api-v2-GetTagSuggestionsRequest) + - [GetTagSuggestionsResponse](#memos-api-v2-GetTagSuggestionsResponse) - [ListTagsRequest](#memos-api-v2-ListTagsRequest) - [ListTagsResponse](#memos-api-v2-ListTagsResponse) + - [RenameTagRequest](#memos-api-v2-RenameTagRequest) + - [RenameTagResponse](#memos-api-v2-RenameTagResponse) - [Tag](#memos-api-v2-Tag) - [UpsertTagRequest](#memos-api-v2-UpsertTagRequest) - [UpsertTagResponse](#memos-api-v2-UpsertTagResponse) - [TagService](#memos-api-v2-TagService) -- [api/v2/user_service.proto](#api_v2_user_service-proto) - - [CreateUserAccessTokenRequest](#memos-api-v2-CreateUserAccessTokenRequest) - - [CreateUserAccessTokenResponse](#memos-api-v2-CreateUserAccessTokenResponse) - - [CreateUserRequest](#memos-api-v2-CreateUserRequest) - - [CreateUserResponse](#memos-api-v2-CreateUserResponse) - - [DeleteUserAccessTokenRequest](#memos-api-v2-DeleteUserAccessTokenRequest) - - [DeleteUserAccessTokenResponse](#memos-api-v2-DeleteUserAccessTokenResponse) - - [GetUserRequest](#memos-api-v2-GetUserRequest) - - [GetUserResponse](#memos-api-v2-GetUserResponse) - - [ListUserAccessTokensRequest](#memos-api-v2-ListUserAccessTokensRequest) - - [ListUserAccessTokensResponse](#memos-api-v2-ListUserAccessTokensResponse) - - [UpdateUserRequest](#memos-api-v2-UpdateUserRequest) - - [UpdateUserResponse](#memos-api-v2-UpdateUserResponse) - - [User](#memos-api-v2-User) - - [UserAccessToken](#memos-api-v2-UserAccessToken) +- [api/v2/webhook_service.proto](#api_v2_webhook_service-proto) + - [CreateWebhookRequest](#memos-api-v2-CreateWebhookRequest) + - [CreateWebhookResponse](#memos-api-v2-CreateWebhookResponse) + - [DeleteWebhookRequest](#memos-api-v2-DeleteWebhookRequest) + - [DeleteWebhookResponse](#memos-api-v2-DeleteWebhookResponse) + - [GetWebhookRequest](#memos-api-v2-GetWebhookRequest) + - [GetWebhookResponse](#memos-api-v2-GetWebhookResponse) + - [ListWebhooksRequest](#memos-api-v2-ListWebhooksRequest) + - [ListWebhooksResponse](#memos-api-v2-ListWebhooksResponse) + - [UpdateWebhookRequest](#memos-api-v2-UpdateWebhookRequest) + - [UpdateWebhookResponse](#memos-api-v2-UpdateWebhookResponse) + - [Webhook](#memos-api-v2-Webhook) - - [User.Role](#memos-api-v2-User-Role) + - [WebhookService](#memos-api-v2-WebhookService) - - [UserService](#memos-api-v2-UserService) +- [api/v2/workspace_service.proto](#api_v2_workspace_service-proto) + - [GetWorkspaceProfileRequest](#memos-api-v2-GetWorkspaceProfileRequest) + - [GetWorkspaceProfileResponse](#memos-api-v2-GetWorkspaceProfileResponse) + - [WorkspaceProfile](#memos-api-v2-WorkspaceProfile) + + - [WorkspaceService](#memos-api-v2-WorkspaceService) + +- [api/v2/workspace_setting_service.proto](#api_v2_workspace_setting_service-proto) + - [GetWorkspaceSettingRequest](#memos-api-v2-GetWorkspaceSettingRequest) + - [GetWorkspaceSettingResponse](#memos-api-v2-GetWorkspaceSettingResponse) + - [SetWorkspaceSettingRequest](#memos-api-v2-SetWorkspaceSettingRequest) + - [SetWorkspaceSettingResponse](#memos-api-v2-SetWorkspaceSettingResponse) + - [WorkspaceGeneralSetting](#memos-api-v2-WorkspaceGeneralSetting) + - [WorkspaceSetting](#memos-api-v2-WorkspaceSetting) + + - [WorkspaceSettingService](#memos-api-v2-WorkspaceSettingService) - [Scalar Value Types](#scalar-value-types) @@ -155,6 +256,22 @@ | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | memo_comment | [ActivityMemoCommentPayload](#memos-api-v2-ActivityMemoCommentPayload) | | | +| version_update | [ActivityVersionUpdatePayload](#memos-api-v2-ActivityVersionUpdatePayload) | | | + + + + + + + + +### ActivityVersionUpdatePayload + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| version | [string](#string) | | | @@ -204,7 +321,7 @@ | Method Name | Request Type | Response Type | Description | | ----------- | ------------ | ------------- | ------------| -| GetActivity | [GetActivityRequest](#memos-api-v2-GetActivityRequest) | [GetActivityResponse](#memos-api-v2-GetActivityResponse) | | +| GetActivity | [GetActivityRequest](#memos-api-v2-GetActivityRequest) | [GetActivityResponse](#memos-api-v2-GetActivityResponse) | GetActivity returns the activity with the given id. | @@ -216,6 +333,22 @@ ## api/v2/common.proto + + + +### PageToken +Used internally for obfuscating the page token. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| limit | [int32](#int32) | | | +| offset | [int32](#int32) | | | + + + + + @@ -239,363 +372,378 @@ - +

Top

-## api/v2/inbox_service.proto +## api/v2/user_service.proto - + -### DeleteInboxRequest +### CreateUserAccessTokenRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| name | [string](#string) | | The name of the inbox to delete. Format: inboxes/{inbox} | +| name | [string](#string) | | The name of the user. Format: users/{username} | +| description | [string](#string) | | | +| expires_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | optional | | - + + +### CreateUserAccessTokenResponse -### DeleteInboxResponse +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| access_token | [UserAccessToken](#memos-api-v2-UserAccessToken) | | | - -### Inbox + + +### CreateUserRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| name | [string](#string) | | The name of the inbox. Format: inboxes/{id} | -| sender | [string](#string) | | Format: users/{username} | -| receiver | [string](#string) | | Format: users/{username} | -| status | [Inbox.Status](#memos-api-v2-Inbox-Status) | | | -| create_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | -| type | [Inbox.Type](#memos-api-v2-Inbox-Type) | | | -| activity_id | [int32](#int32) | optional | | +| user | [User](#memos-api-v2-User) | | | - + -### ListInboxesRequest +### CreateUserResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| user | [string](#string) | | Format: users/{username} | +| user | [User](#memos-api-v2-User) | | | - + -### ListInboxesResponse +### DeleteUserAccessTokenRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| inboxes | [Inbox](#memos-api-v2-Inbox) | repeated | | - - +| name | [string](#string) | | The name of the user. Format: users/{username} | +| access_token | [string](#string) | | access_token is the access token to delete. | - -### UpdateInboxRequest + +### DeleteUserAccessTokenResponse -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| inbox | [Inbox](#memos-api-v2-Inbox) | | | -| update_mask | [google.protobuf.FieldMask](#google-protobuf-FieldMask) | | | - + -### UpdateInboxResponse +### DeleteUserRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| inbox | [Inbox](#memos-api-v2-Inbox) | | | +| name | [string](#string) | | The name of the user. Format: users/{username} | - + - +### DeleteUserResponse -### Inbox.Status -| Name | Number | Description | -| ---- | ------ | ----------- | -| STATUS_UNSPECIFIED | 0 | | -| UNREAD | 1 | | -| ARCHIVED | 2 | | - -### Inbox.Type + +### GetUserRequest -| Name | Number | Description | -| ---- | ------ | ----------- | -| TYPE_UNSPECIFIED | 0 | | -| TYPE_MEMO_COMMENT | 1 | | - +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | The name of the user. Format: users/{username} | - - -### InboxService -| Method Name | Request Type | Response Type | Description | -| ----------- | ------------ | ------------- | ------------| -| ListInboxes | [ListInboxesRequest](#memos-api-v2-ListInboxesRequest) | [ListInboxesResponse](#memos-api-v2-ListInboxesResponse) | | -| UpdateInbox | [UpdateInboxRequest](#memos-api-v2-UpdateInboxRequest) | [UpdateInboxResponse](#memos-api-v2-UpdateInboxResponse) | | -| DeleteInbox | [DeleteInboxRequest](#memos-api-v2-DeleteInboxRequest) | [DeleteInboxResponse](#memos-api-v2-DeleteInboxResponse) | | + - +### GetUserResponse - -

Top

+| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| user | [User](#memos-api-v2-User) | | | -## api/v2/memo_service.proto - -### CreateMemoCommentRequest + + + +### GetUserSettingRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| id | [int32](#int32) | | id is the memo id to create comment for. | -| create | [CreateMemoRequest](#memos-api-v2-CreateMemoRequest) | | | +| name | [string](#string) | | The name of the user. Format: users/{username} | - + -### CreateMemoCommentResponse +### GetUserSettingResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| memo | [Memo](#memos-api-v2-Memo) | | | +| setting | [UserSetting](#memos-api-v2-UserSetting) | | | - + -### CreateMemoRequest +### ListUserAccessTokensRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| content | [string](#string) | | | -| visibility | [Visibility](#memos-api-v2-Visibility) | | | +| name | [string](#string) | | The name of the user. Format: users/{username} | - + -### CreateMemoResponse +### ListUserAccessTokensResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| memo | [Memo](#memos-api-v2-Memo) | | | - - +| access_tokens | [UserAccessToken](#memos-api-v2-UserAccessToken) | repeated | | - -### GetMemoRequest + +### ListUsersRequest -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| id | [int32](#int32) | | | - + -### GetMemoResponse +### ListUsersResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| memo | [Memo](#memos-api-v2-Memo) | | | +| users | [User](#memos-api-v2-User) | repeated | | - + -### ListMemoCommentsRequest +### UpdateUserRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| id | [int32](#int32) | | | +| user | [User](#memos-api-v2-User) | | | +| update_mask | [google.protobuf.FieldMask](#google-protobuf-FieldMask) | | | - + -### ListMemoCommentsResponse +### UpdateUserResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| memos | [Memo](#memos-api-v2-Memo) | repeated | | +| user | [User](#memos-api-v2-User) | | | - + -### ListMemosRequest +### UpdateUserSettingRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| page | [int32](#int32) | | | -| page_size | [int32](#int32) | | | -| filter | [string](#string) | | Filter is used to filter memos returned in the list. | -| creator_id | [int32](#int32) | optional | | +| setting | [UserSetting](#memos-api-v2-UserSetting) | | | +| update_mask | [google.protobuf.FieldMask](#google-protobuf-FieldMask) | | | - + -### ListMemosResponse +### UpdateUserSettingResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| memos | [Memo](#memos-api-v2-Memo) | repeated | | +| setting | [UserSetting](#memos-api-v2-UserSetting) | | | - + -### Memo +### User | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | +| name | [string](#string) | | The name of the user. Format: users/{username} | | id | [int32](#int32) | | | +| role | [User.Role](#memos-api-v2-User-Role) | | | +| username | [string](#string) | | | +| email | [string](#string) | | | +| nickname | [string](#string) | | | +| avatar_url | [string](#string) | | | +| password | [string](#string) | | | | row_status | [RowStatus](#memos-api-v2-RowStatus) | | | -| creator_id | [int32](#int32) | | | -| created_ts | [int64](#int64) | | | -| updated_ts | [int64](#int64) | | | -| content | [string](#string) | | | -| visibility | [Visibility](#memos-api-v2-Visibility) | | | -| pinned | [bool](#bool) | | | +| create_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | +| update_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | - + - +### UserAccessToken -### Visibility + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| access_token | [string](#string) | | | +| description | [string](#string) | | | +| issued_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | +| expires_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | + + + + + + + + +### UserSetting + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | The name of the user. Format: users/{username} | +| locale | [string](#string) | | The preferred locale of the user. | +| appearance | [string](#string) | | The preferred appearance of the user. | +| memo_visibility | [string](#string) | | The default visibility of the memo. | +| telegram_user_id | [string](#string) | | The telegram user id of the user. | + + + + + + + + + + +### User.Role | Name | Number | Description | | ---- | ------ | ----------- | -| VISIBILITY_UNSPECIFIED | 0 | | -| PRIVATE | 1 | | -| PROTECTED | 2 | | -| PUBLIC | 3 | | +| ROLE_UNSPECIFIED | 0 | | +| HOST | 1 | | +| ADMIN | 2 | | +| USER | 3 | | @@ -603,81 +751,1390 @@ - + -### MemoService +### UserService | Method Name | Request Type | Response Type | Description | | ----------- | ------------ | ------------- | ------------| -| CreateMemo | [CreateMemoRequest](#memos-api-v2-CreateMemoRequest) | [CreateMemoResponse](#memos-api-v2-CreateMemoResponse) | | -| ListMemos | [ListMemosRequest](#memos-api-v2-ListMemosRequest) | [ListMemosResponse](#memos-api-v2-ListMemosResponse) | | -| GetMemo | [GetMemoRequest](#memos-api-v2-GetMemoRequest) | [GetMemoResponse](#memos-api-v2-GetMemoResponse) | | -| CreateMemoComment | [CreateMemoCommentRequest](#memos-api-v2-CreateMemoCommentRequest) | [CreateMemoCommentResponse](#memos-api-v2-CreateMemoCommentResponse) | | -| ListMemoComments | [ListMemoCommentsRequest](#memos-api-v2-ListMemoCommentsRequest) | [ListMemoCommentsResponse](#memos-api-v2-ListMemoCommentsResponse) | | +| ListUsers | [ListUsersRequest](#memos-api-v2-ListUsersRequest) | [ListUsersResponse](#memos-api-v2-ListUsersResponse) | ListUsers returns a list of users. | +| GetUser | [GetUserRequest](#memos-api-v2-GetUserRequest) | [GetUserResponse](#memos-api-v2-GetUserResponse) | GetUser gets a user by name. | +| CreateUser | [CreateUserRequest](#memos-api-v2-CreateUserRequest) | [CreateUserResponse](#memos-api-v2-CreateUserResponse) | CreateUser creates a new user. | +| UpdateUser | [UpdateUserRequest](#memos-api-v2-UpdateUserRequest) | [UpdateUserResponse](#memos-api-v2-UpdateUserResponse) | UpdateUser updates a user. | +| DeleteUser | [DeleteUserRequest](#memos-api-v2-DeleteUserRequest) | [DeleteUserResponse](#memos-api-v2-DeleteUserResponse) | DeleteUser deletes a user. | +| GetUserSetting | [GetUserSettingRequest](#memos-api-v2-GetUserSettingRequest) | [GetUserSettingResponse](#memos-api-v2-GetUserSettingResponse) | GetUserSetting gets the setting of a user. | +| UpdateUserSetting | [UpdateUserSettingRequest](#memos-api-v2-UpdateUserSettingRequest) | [UpdateUserSettingResponse](#memos-api-v2-UpdateUserSettingResponse) | UpdateUserSetting updates the setting of a user. | +| ListUserAccessTokens | [ListUserAccessTokensRequest](#memos-api-v2-ListUserAccessTokensRequest) | [ListUserAccessTokensResponse](#memos-api-v2-ListUserAccessTokensResponse) | ListUserAccessTokens returns a list of access tokens for a user. | +| CreateUserAccessToken | [CreateUserAccessTokenRequest](#memos-api-v2-CreateUserAccessTokenRequest) | [CreateUserAccessTokenResponse](#memos-api-v2-CreateUserAccessTokenResponse) | CreateUserAccessToken creates a new access token for a user. | +| DeleteUserAccessToken | [DeleteUserAccessTokenRequest](#memos-api-v2-DeleteUserAccessTokenRequest) | [DeleteUserAccessTokenResponse](#memos-api-v2-DeleteUserAccessTokenResponse) | DeleteUserAccessToken deletes an access token for a user. | - +

Top

-## api/v2/resource_service.proto +## api/v2/auth_service.proto + + + + + +### GetAuthStatusRequest - -### CreateResourceRequest + + + + + +### GetAuthStatusResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| filename | [string](#string) | | | -| external_link | [string](#string) | | | -| type | [string](#string) | | | -| memo_id | [int32](#int32) | optional | | +| user | [User](#memos-api-v2-User) | | | + + + + + + + + +### SignInRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| username | [string](#string) | | | +| password | [string](#string) | | | +| never_expire | [bool](#bool) | | | + + + + + + + + +### SignInResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| user | [User](#memos-api-v2-User) | | | + + + + + + + + +### SignInWithSSORequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| idp_id | [int32](#int32) | | | +| code | [string](#string) | | | +| redirect_uri | [string](#string) | | | + + + + + + + + +### SignInWithSSOResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| user | [User](#memos-api-v2-User) | | | + + + + + + + + +### SignOutRequest + + + + + + + + + +### SignOutResponse + + + + + + + + + +### SignUpRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| username | [string](#string) | | | +| password | [string](#string) | | | + + + + + + + + +### SignUpResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| user | [User](#memos-api-v2-User) | | | + + + + + + + + + + + + + + +### AuthService + + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| GetAuthStatus | [GetAuthStatusRequest](#memos-api-v2-GetAuthStatusRequest) | [GetAuthStatusResponse](#memos-api-v2-GetAuthStatusResponse) | GetAuthStatus returns the current auth status of the user. | +| SignIn | [SignInRequest](#memos-api-v2-SignInRequest) | [SignInResponse](#memos-api-v2-SignInResponse) | SignIn signs in the user with the given username and password. | +| SignInWithSSO | [SignInWithSSORequest](#memos-api-v2-SignInWithSSORequest) | [SignInWithSSOResponse](#memos-api-v2-SignInWithSSOResponse) | SignInWithSSO signs in the user with the given SSO code. | +| SignUp | [SignUpRequest](#memos-api-v2-SignUpRequest) | [SignUpResponse](#memos-api-v2-SignUpResponse) | SignUp signs up the user with the given username and password. | +| SignOut | [SignOutRequest](#memos-api-v2-SignOutRequest) | [SignOutResponse](#memos-api-v2-SignOutResponse) | SignOut signs out the user. | + + + + + + +

Top

+ +## api/v2/inbox_service.proto + + + + + +### DeleteInboxRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | The name of the inbox to delete. Format: inboxes/{uid} | + + + + + + + + +### DeleteInboxResponse + + + + + + + + + +### Inbox + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | The name of the inbox. Format: inboxes/{uid} | +| sender | [string](#string) | | Format: users/{username} | +| receiver | [string](#string) | | Format: users/{username} | +| status | [Inbox.Status](#memos-api-v2-Inbox-Status) | | | +| create_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | +| type | [Inbox.Type](#memos-api-v2-Inbox-Type) | | | +| activity_id | [int32](#int32) | optional | | + + + + + + + + +### ListInboxesRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| user | [string](#string) | | Format: users/{username} | + + + + + + + + +### ListInboxesResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| inboxes | [Inbox](#memos-api-v2-Inbox) | repeated | | + + + + + + + + +### UpdateInboxRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| inbox | [Inbox](#memos-api-v2-Inbox) | | | +| update_mask | [google.protobuf.FieldMask](#google-protobuf-FieldMask) | | | + + + + + + + + +### UpdateInboxResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| inbox | [Inbox](#memos-api-v2-Inbox) | | | + + + + + + + + + + +### Inbox.Status + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| STATUS_UNSPECIFIED | 0 | | +| UNREAD | 1 | | +| ARCHIVED | 2 | | + + + + + +### Inbox.Type + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| TYPE_UNSPECIFIED | 0 | | +| TYPE_MEMO_COMMENT | 1 | | +| TYPE_VERSION_UPDATE | 2 | | + + + + + + + + + +### InboxService + + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| ListInboxes | [ListInboxesRequest](#memos-api-v2-ListInboxesRequest) | [ListInboxesResponse](#memos-api-v2-ListInboxesResponse) | ListInboxes lists inboxes for a user. | +| UpdateInbox | [UpdateInboxRequest](#memos-api-v2-UpdateInboxRequest) | [UpdateInboxResponse](#memos-api-v2-UpdateInboxResponse) | UpdateInbox updates an inbox. | +| DeleteInbox | [DeleteInboxRequest](#memos-api-v2-DeleteInboxRequest) | [DeleteInboxResponse](#memos-api-v2-DeleteInboxResponse) | DeleteInbox deletes an inbox. | + + + + + + +

Top

+ +## api/v2/link_service.proto + + + + + +### GetLinkMetadataRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| link | [string](#string) | | | + + + + + + + + +### GetLinkMetadataResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| metadata | [LinkMetadata](#memos-api-v2-LinkMetadata) | | | + + + + + + + + +### LinkMetadata + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| title | [string](#string) | | | +| description | [string](#string) | | | +| image | [string](#string) | | | + + + + + + + + + + + + + + +### LinkService + + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| GetLinkMetadata | [GetLinkMetadataRequest](#memos-api-v2-GetLinkMetadataRequest) | [GetLinkMetadataResponse](#memos-api-v2-GetLinkMetadataResponse) | | + + + + + + +

Top

+ +## api/v2/memo_relation_service.proto + + + + + +### MemoRelation + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| memo_id | [int32](#int32) | | | +| related_memo_id | [int32](#int32) | | | +| type | [MemoRelation.Type](#memos-api-v2-MemoRelation-Type) | | | + + + + + + + + + + +### MemoRelation.Type + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| TYPE_UNSPECIFIED | 0 | | +| REFERENCE | 1 | | +| COMMENT | 2 | | + + + + + + + + + + + +

Top

+ +## api/v2/reaction_service.proto + + + + + +### Reaction + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | +| creator | [string](#string) | | | +| content_id | [string](#string) | | | +| reaction_type | [Reaction.Type](#memos-api-v2-Reaction-Type) | | | + + + + + + + + + + +### Reaction.Type + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| TYPE_UNSPECIFIED | 0 | | +| THUMBS_UP | 1 | | +| THUMBS_DOWN | 2 | | +| HEART | 3 | | +| FIRE | 4 | | +| CLAPPING_HANDS | 5 | | +| LAUGH | 6 | | +| OK_HAND | 7 | | +| ROCKET | 8 | | +| EYES | 9 | | +| THINKING_FACE | 10 | | +| CLOWN_FACE | 11 | | +| QUESTION_MARK | 12 | | + + + + + + + + + + + +

Top

+ +## api/v2/resource_service.proto + + + + + +### CreateResourceRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| filename | [string](#string) | | | +| external_link | [string](#string) | | | +| type | [string](#string) | | | +| memo_id | [int32](#int32) | optional | | + + + + + + + + +### CreateResourceResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| resource | [Resource](#memos-api-v2-Resource) | | | + + + + + + + + +### DeleteResourceRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | + + + + + + + + +### DeleteResourceResponse + + + + + + + + + +### GetResourceByNameRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | | + + + + + + + + +### GetResourceByNameResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| resource | [Resource](#memos-api-v2-Resource) | | | + + + + + + + + +### GetResourceRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | + + + + + + + + +### GetResourceResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| resource | [Resource](#memos-api-v2-Resource) | | | + + + + + + + + +### ListResourcesRequest + + + + + + + + + +### ListResourcesResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| resources | [Resource](#memos-api-v2-Resource) | repeated | | + + + + + + + + +### Resource + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | id is the system generated unique identifier. | +| name | [string](#string) | | name is the user provided name. | +| create_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | +| filename | [string](#string) | | | +| external_link | [string](#string) | | | +| type | [string](#string) | | | +| size | [int64](#int64) | | | +| memo_id | [int32](#int32) | optional | | + + + + + + + + +### UpdateResourceRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| resource | [Resource](#memos-api-v2-Resource) | | | +| update_mask | [google.protobuf.FieldMask](#google-protobuf-FieldMask) | | | + + + + + + + + +### UpdateResourceResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| resource | [Resource](#memos-api-v2-Resource) | | | + + + + + + + + + + + + + + +### ResourceService + + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| CreateResource | [CreateResourceRequest](#memos-api-v2-CreateResourceRequest) | [CreateResourceResponse](#memos-api-v2-CreateResourceResponse) | CreateResource creates a new resource. | +| ListResources | [ListResourcesRequest](#memos-api-v2-ListResourcesRequest) | [ListResourcesResponse](#memos-api-v2-ListResourcesResponse) | ListResources lists all resources. | +| GetResource | [GetResourceRequest](#memos-api-v2-GetResourceRequest) | [GetResourceResponse](#memos-api-v2-GetResourceResponse) | GetResource returns a resource by id. | +| GetResourceByName | [GetResourceByNameRequest](#memos-api-v2-GetResourceByNameRequest) | [GetResourceByNameResponse](#memos-api-v2-GetResourceByNameResponse) | GetResourceByName returns a resource by name. | +| UpdateResource | [UpdateResourceRequest](#memos-api-v2-UpdateResourceRequest) | [UpdateResourceResponse](#memos-api-v2-UpdateResourceResponse) | UpdateResource updates a resource. | +| DeleteResource | [DeleteResourceRequest](#memos-api-v2-DeleteResourceRequest) | [DeleteResourceResponse](#memos-api-v2-DeleteResourceResponse) | DeleteResource deletes a resource by id. | + + + + + + +

Top

+ +## api/v2/memo_service.proto + + + + + +### CreateMemoCommentRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | id is the memo id to create comment for. | +| create | [CreateMemoRequest](#memos-api-v2-CreateMemoRequest) | | | + + + + + + + + +### CreateMemoCommentResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| memo | [Memo](#memos-api-v2-Memo) | | | + + + + + + + + +### CreateMemoRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| content | [string](#string) | | | +| visibility | [Visibility](#memos-api-v2-Visibility) | | | + + + + + + + + +### CreateMemoResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| memo | [Memo](#memos-api-v2-Memo) | | | + + + + + + + + +### DeleteMemoReactionRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | +| reaction_id | [int32](#int32) | | | + + + + + + + + +### DeleteMemoReactionResponse + + + + + + + + + +### DeleteMemoRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | + + + + + + + + +### DeleteMemoResponse + + + + + + + + + +### ExportMemosRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| filter | [string](#string) | | Same as ListMemosRequest.filter | + + + + + + + + +### ExportMemosResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| content | [bytes](#bytes) | | | + + + + + + + + +### GetMemoByNameRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | | + + + + + + + + +### GetMemoByNameResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| memo | [Memo](#memos-api-v2-Memo) | | | + + + + + + + + +### GetMemoRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | + + + + + + + + +### GetMemoResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| memo | [Memo](#memos-api-v2-Memo) | | | + + + + + + + + +### GetUserMemosStatsRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | name is the name of the user to get stats for. Format: users/{username} | +| timezone | [string](#string) | | timezone location Format: uses tz identifier https://en.wikipedia.org/wiki/List_of_tz_database_time_zones | +| filter | [string](#string) | | Same as ListMemosRequest.filter | + + + + + + + + +### GetUserMemosStatsResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| stats | [GetUserMemosStatsResponse.StatsEntry](#memos-api-v2-GetUserMemosStatsResponse-StatsEntry) | repeated | stats is the stats of memo creating/updating activities. key is the year-month-day string. e.g. "2020-01-01". | + + + + + + + + +### GetUserMemosStatsResponse.StatsEntry + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| key | [string](#string) | | | +| value | [int32](#int32) | | | + + + + + + + + +### ListMemoCommentsRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | + + + + + + + + +### ListMemoCommentsResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| memos | [Memo](#memos-api-v2-Memo) | repeated | | + + + + + + + + +### ListMemoReactionsRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | + + + + + + + + +### ListMemoReactionsResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| reactions | [Reaction](#memos-api-v2-Reaction) | repeated | | + + + + + + + + +### ListMemoRelationsRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | + + + + + + + + +### ListMemoRelationsResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| relations | [MemoRelation](#memos-api-v2-MemoRelation) | repeated | | + + + + + + + + +### ListMemoResourcesRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | + + + + + + + + +### ListMemoResourcesResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| resources | [Resource](#memos-api-v2-Resource) | repeated | | + + + + + + + + +### ListMemosRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| page_size | [int32](#int32) | | The maximum number of memos to return. | +| page_token | [string](#string) | | A page token, received from a previous `ListMemos` call. Provide this to retrieve the subsequent page. | +| filter | [string](#string) | | Filter is used to filter memos returned in the list. Format: "creator == users/{username} && visibilities == ['PUBLIC', 'PROTECTED']" | + + + + + + + + +### ListMemosResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| memos | [Memo](#memos-api-v2-Memo) | repeated | | +| next_page_token | [string](#string) | | A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no subsequent pages. | + + + + + + + + +### Memo + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | id is the system generated unique identifier. | +| name | [string](#string) | | name is the user provided name. | +| row_status | [RowStatus](#memos-api-v2-RowStatus) | | | +| creator | [string](#string) | | The name of the creator. Format: users/{username} | +| creator_id | [int32](#int32) | | | +| create_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | +| update_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | +| display_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | +| content | [string](#string) | | | +| visibility | [Visibility](#memos-api-v2-Visibility) | | | +| pinned | [bool](#bool) | | | +| parent_id | [int32](#int32) | optional | | +| resources | [Resource](#memos-api-v2-Resource) | repeated | | +| relations | [MemoRelation](#memos-api-v2-MemoRelation) | repeated | | +| reactions | [Reaction](#memos-api-v2-Reaction) | repeated | | + + + + + + + + +### SetMemoRelationsRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | +| relations | [MemoRelation](#memos-api-v2-MemoRelation) | repeated | | + + + + + + + + +### SetMemoRelationsResponse + + + + + + + + + +### SetMemoResourcesRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | +| resources | [Resource](#memos-api-v2-Resource) | repeated | | + + + + + + + + +### SetMemoResourcesResponse + + + + + + + + + +### UpdateMemoRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| memo | [Memo](#memos-api-v2-Memo) | | | +| update_mask | [google.protobuf.FieldMask](#google-protobuf-FieldMask) | | | + + + + + + + + +### UpdateMemoResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| memo | [Memo](#memos-api-v2-Memo) | | | + + + + + + + + +### UpsertMemoReactionRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | +| reaction | [Reaction](#memos-api-v2-Reaction) | | | + + + + + + + + +### UpsertMemoReactionResponse + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| reaction | [Reaction](#memos-api-v2-Reaction) | | | + + + + + + + + + +### Visibility +| Name | Number | Description | +| ---- | ------ | ----------- | +| VISIBILITY_UNSPECIFIED | 0 | | +| PRIVATE | 1 | | +| PROTECTED | 2 | | +| PUBLIC | 3 | | + - + -### CreateResourceResponse + +### MemoService -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| resource | [Resource](#memos-api-v2-Resource) | | | +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| CreateMemo | [CreateMemoRequest](#memos-api-v2-CreateMemoRequest) | [CreateMemoResponse](#memos-api-v2-CreateMemoResponse) | CreateMemo creates a memo. | +| ListMemos | [ListMemosRequest](#memos-api-v2-ListMemosRequest) | [ListMemosResponse](#memos-api-v2-ListMemosResponse) | ListMemos lists memos with pagination and filter. | +| GetMemo | [GetMemoRequest](#memos-api-v2-GetMemoRequest) | [GetMemoResponse](#memos-api-v2-GetMemoResponse) | GetMemo gets a memo by id. | +| GetMemoByName | [GetMemoByNameRequest](#memos-api-v2-GetMemoByNameRequest) | [GetMemoByNameResponse](#memos-api-v2-GetMemoByNameResponse) | GetMemoByName gets a memo by name. | +| UpdateMemo | [UpdateMemoRequest](#memos-api-v2-UpdateMemoRequest) | [UpdateMemoResponse](#memos-api-v2-UpdateMemoResponse) | UpdateMemo updates a memo. | +| DeleteMemo | [DeleteMemoRequest](#memos-api-v2-DeleteMemoRequest) | [DeleteMemoResponse](#memos-api-v2-DeleteMemoResponse) | DeleteMemo deletes a memo by id. | +| ExportMemos | [ExportMemosRequest](#memos-api-v2-ExportMemosRequest) | [ExportMemosResponse](#memos-api-v2-ExportMemosResponse) | ExportMemos exports memos. | +| SetMemoResources | [SetMemoResourcesRequest](#memos-api-v2-SetMemoResourcesRequest) | [SetMemoResourcesResponse](#memos-api-v2-SetMemoResourcesResponse) | SetMemoResources sets resources for a memo. | +| ListMemoResources | [ListMemoResourcesRequest](#memos-api-v2-ListMemoResourcesRequest) | [ListMemoResourcesResponse](#memos-api-v2-ListMemoResourcesResponse) | ListMemoResources lists resources for a memo. | +| SetMemoRelations | [SetMemoRelationsRequest](#memos-api-v2-SetMemoRelationsRequest) | [SetMemoRelationsResponse](#memos-api-v2-SetMemoRelationsResponse) | SetMemoRelations sets relations for a memo. | +| ListMemoRelations | [ListMemoRelationsRequest](#memos-api-v2-ListMemoRelationsRequest) | [ListMemoRelationsResponse](#memos-api-v2-ListMemoRelationsResponse) | ListMemoRelations lists relations for a memo. | +| CreateMemoComment | [CreateMemoCommentRequest](#memos-api-v2-CreateMemoCommentRequest) | [CreateMemoCommentResponse](#memos-api-v2-CreateMemoCommentResponse) | CreateMemoComment creates a comment for a memo. | +| ListMemoComments | [ListMemoCommentsRequest](#memos-api-v2-ListMemoCommentsRequest) | [ListMemoCommentsResponse](#memos-api-v2-ListMemoCommentsResponse) | ListMemoComments lists comments for a memo. | +| GetUserMemosStats | [GetUserMemosStatsRequest](#memos-api-v2-GetUserMemosStatsRequest) | [GetUserMemosStatsResponse](#memos-api-v2-GetUserMemosStatsResponse) | GetUserMemosStats gets stats of memos for a user. | +| ListMemoReactions | [ListMemoReactionsRequest](#memos-api-v2-ListMemoReactionsRequest) | [ListMemoReactionsResponse](#memos-api-v2-ListMemoReactionsResponse) | ListMemoReactions lists reactions for a memo. | +| UpsertMemoReaction | [UpsertMemoReactionRequest](#memos-api-v2-UpsertMemoReactionRequest) | [UpsertMemoReactionResponse](#memos-api-v2-UpsertMemoReactionResponse) | UpsertMemoReaction upserts a reaction for a memo. | +| DeleteMemoReaction | [DeleteMemoReactionRequest](#memos-api-v2-DeleteMemoReactionRequest) | [DeleteMemoReactionResponse](#memos-api-v2-DeleteMemoReactionResponse) | DeleteMemoReaction deletes a reaction for a memo. | + + +

Top

- +## api/v2/tag_service.proto -### DeleteResourceRequest + + + + +### BatchUpsertTagRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| id | [int32](#int32) | | | +| requests | [UpsertTagRequest](#memos-api-v2-UpsertTagRequest) | repeated | | - + -### DeleteResourceResponse +### BatchUpsertTagResponse @@ -685,183 +2142,163 @@ - + -### ListResourcesRequest +### DeleteTagRequest +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| tag | [Tag](#memos-api-v2-Tag) | | | - -### ListResourcesResponse + +### DeleteTagResponse -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| resources | [Resource](#memos-api-v2-Resource) | repeated | | - + -### Resource +### GetTagSuggestionsRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| id | [int32](#int32) | | | -| created_ts | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | -| filename | [string](#string) | | | -| external_link | [string](#string) | | | -| type | [string](#string) | | | -| size | [int64](#int64) | | | -| memo_id | [int32](#int32) | optional | | +| user | [string](#string) | | The creator of tags. Format: users/{username} | - + -### UpdateResourceRequest +### GetTagSuggestionsResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| resource | [Resource](#memos-api-v2-Resource) | | | -| update_mask | [google.protobuf.FieldMask](#google-protobuf-FieldMask) | | | +| tags | [string](#string) | repeated | | - + -### UpdateResourceResponse +### ListTagsRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| resource | [Resource](#memos-api-v2-Resource) | | | - +| user | [string](#string) | | The creator of tags. Format: users/{username} | - - - - + - +### ListTagsResponse -### ResourceService -| Method Name | Request Type | Response Type | Description | -| ----------- | ------------ | ------------- | ------------| -| CreateResource | [CreateResourceRequest](#memos-api-v2-CreateResourceRequest) | [CreateResourceResponse](#memos-api-v2-CreateResourceResponse) | | -| ListResources | [ListResourcesRequest](#memos-api-v2-ListResourcesRequest) | [ListResourcesResponse](#memos-api-v2-ListResourcesResponse) | | -| UpdateResource | [UpdateResourceRequest](#memos-api-v2-UpdateResourceRequest) | [UpdateResourceResponse](#memos-api-v2-UpdateResourceResponse) | | -| DeleteResource | [DeleteResourceRequest](#memos-api-v2-DeleteResourceRequest) | [DeleteResourceResponse](#memos-api-v2-DeleteResourceResponse) | | +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| tags | [Tag](#memos-api-v2-Tag) | repeated | | - - -

Top

-## api/v2/system_service.proto + +### RenameTagRequest - -### GetSystemInfoRequest +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| user | [string](#string) | | The creator of tags. Format: users/{username} | +| old_name | [string](#string) | | | +| new_name | [string](#string) | | | - + -### GetSystemInfoResponse +### RenameTagResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| system_info | [SystemInfo](#memos-api-v2-SystemInfo) | | | +| tag | [Tag](#memos-api-v2-Tag) | | | - + -### SystemInfo +### Tag | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| version | [string](#string) | | | -| mode | [string](#string) | | | -| allow_registration | [bool](#bool) | | | -| disable_password_login | [bool](#bool) | | | -| additional_script | [string](#string) | | | -| additional_style | [string](#string) | | | -| db_size | [int64](#int64) | | | +| name | [string](#string) | | | +| creator | [string](#string) | | The creator of tags. Format: users/{username} | - + -### UpdateSystemInfoRequest +### UpsertTagRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| system_info | [SystemInfo](#memos-api-v2-SystemInfo) | | System info is the updated data. | -| update_mask | [google.protobuf.FieldMask](#google-protobuf-FieldMask) | | | +| name | [string](#string) | | | - + -### UpdateSystemInfoResponse +### UpsertTagResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| system_info | [SystemInfo](#memos-api-v2-SystemInfo) | | | +| tag | [Tag](#memos-api-v2-Tag) | | | @@ -874,371 +2311,389 @@ - + -### SystemService +### TagService | Method Name | Request Type | Response Type | Description | | ----------- | ------------ | ------------- | ------------| -| GetSystemInfo | [GetSystemInfoRequest](#memos-api-v2-GetSystemInfoRequest) | [GetSystemInfoResponse](#memos-api-v2-GetSystemInfoResponse) | | -| UpdateSystemInfo | [UpdateSystemInfoRequest](#memos-api-v2-UpdateSystemInfoRequest) | [UpdateSystemInfoResponse](#memos-api-v2-UpdateSystemInfoResponse) | | +| UpsertTag | [UpsertTagRequest](#memos-api-v2-UpsertTagRequest) | [UpsertTagResponse](#memos-api-v2-UpsertTagResponse) | UpsertTag upserts a tag. | +| BatchUpsertTag | [BatchUpsertTagRequest](#memos-api-v2-BatchUpsertTagRequest) | [BatchUpsertTagResponse](#memos-api-v2-BatchUpsertTagResponse) | BatchUpsertTag upserts multiple tags. | +| ListTags | [ListTagsRequest](#memos-api-v2-ListTagsRequest) | [ListTagsResponse](#memos-api-v2-ListTagsResponse) | ListTags lists tags. | +| RenameTag | [RenameTagRequest](#memos-api-v2-RenameTagRequest) | [RenameTagResponse](#memos-api-v2-RenameTagResponse) | RenameTag renames a tag. All related memos will be updated. | +| DeleteTag | [DeleteTagRequest](#memos-api-v2-DeleteTagRequest) | [DeleteTagResponse](#memos-api-v2-DeleteTagResponse) | DeleteTag deletes a tag. | +| GetTagSuggestions | [GetTagSuggestionsRequest](#memos-api-v2-GetTagSuggestionsRequest) | [GetTagSuggestionsResponse](#memos-api-v2-GetTagSuggestionsResponse) | GetTagSuggestions gets tag suggestions from the user's memos. | - +

Top

-## api/v2/tag_service.proto +## api/v2/webhook_service.proto - + -### DeleteTagRequest +### CreateWebhookRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| tag | [Tag](#memos-api-v2-Tag) | | | +| name | [string](#string) | | | +| url | [string](#string) | | | - + -### DeleteTagResponse +### CreateWebhookResponse +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| webhook | [Webhook](#memos-api-v2-Webhook) | | | - -### ListTagsRequest + +### DeleteWebhookRequest -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| creator_id | [int32](#int32) | | | +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | - -### ListTagsResponse + +### DeleteWebhookResponse -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| tags | [Tag](#memos-api-v2-Tag) | repeated | | - + -### Tag +### GetWebhookRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| name | [string](#string) | | | -| creator_id | [int32](#int32) | | | +| id | [int32](#int32) | | | - + -### UpsertTagRequest +### GetWebhookResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| name | [string](#string) | | | +| webhook | [Webhook](#memos-api-v2-Webhook) | | | - + -### UpsertTagResponse +### ListWebhooksRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| tag | [Tag](#memos-api-v2-Tag) | | | - - - - +| creator_id | [int32](#int32) | | | - - - - -### TagService + +### ListWebhooksResponse -| Method Name | Request Type | Response Type | Description | -| ----------- | ------------ | ------------- | ------------| -| UpsertTag | [UpsertTagRequest](#memos-api-v2-UpsertTagRequest) | [UpsertTagResponse](#memos-api-v2-UpsertTagResponse) | | -| ListTags | [ListTagsRequest](#memos-api-v2-ListTagsRequest) | [ListTagsResponse](#memos-api-v2-ListTagsResponse) | | -| DeleteTag | [DeleteTagRequest](#memos-api-v2-DeleteTagRequest) | [DeleteTagResponse](#memos-api-v2-DeleteTagResponse) | | - +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| webhooks | [Webhook](#memos-api-v2-Webhook) | repeated | | - -

Top

-## api/v2/user_service.proto - + -### CreateUserAccessTokenRequest +### UpdateWebhookRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| username | [string](#string) | | | -| description | [string](#string) | | | -| expires_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | optional | | +| webhook | [Webhook](#memos-api-v2-Webhook) | | | +| update_mask | [google.protobuf.FieldMask](#google-protobuf-FieldMask) | | | - + -### CreateUserAccessTokenResponse +### UpdateWebhookResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| access_token | [UserAccessToken](#memos-api-v2-UserAccessToken) | | | +| webhook | [Webhook](#memos-api-v2-Webhook) | | | - + -### CreateUserRequest +### Webhook | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| user | [User](#memos-api-v2-User) | | | +| id | [int32](#int32) | | | +| creator_id | [int32](#int32) | | | +| created_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | +| updated_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | +| row_status | [RowStatus](#memos-api-v2-RowStatus) | | | +| name | [string](#string) | | | +| url | [string](#string) | | | + - + -### CreateUserResponse + + -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| user | [User](#memos-api-v2-User) | | | +### WebhookService +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| CreateWebhook | [CreateWebhookRequest](#memos-api-v2-CreateWebhookRequest) | [CreateWebhookResponse](#memos-api-v2-CreateWebhookResponse) | CreateWebhook creates a new webhook. | +| GetWebhook | [GetWebhookRequest](#memos-api-v2-GetWebhookRequest) | [GetWebhookResponse](#memos-api-v2-GetWebhookResponse) | GetWebhook returns a webhook by id. | +| ListWebhooks | [ListWebhooksRequest](#memos-api-v2-ListWebhooksRequest) | [ListWebhooksResponse](#memos-api-v2-ListWebhooksResponse) | ListWebhooks returns a list of webhooks. | +| UpdateWebhook | [UpdateWebhookRequest](#memos-api-v2-UpdateWebhookRequest) | [UpdateWebhookResponse](#memos-api-v2-UpdateWebhookResponse) | UpdateWebhook updates a webhook. | +| DeleteWebhook | [DeleteWebhookRequest](#memos-api-v2-DeleteWebhookRequest) | [DeleteWebhookResponse](#memos-api-v2-DeleteWebhookResponse) | DeleteWebhook deletes a webhook by id. | + - + +

Top

-### DeleteUserAccessTokenRequest +## api/v2/workspace_service.proto -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| username | [string](#string) | | | -| access_token | [string](#string) | | access_token is the access token to delete. | + +### GetWorkspaceProfileRequest - -### DeleteUserAccessTokenResponse + +### GetWorkspaceProfileResponse +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| workspace_profile | [WorkspaceProfile](#memos-api-v2-WorkspaceProfile) | | | - -### GetUserRequest + + + + + +### WorkspaceProfile | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| username | [string](#string) | | | +| version | [string](#string) | | version is the current version of instance | +| mode | [string](#string) | | mode is the instance mode (e.g. "prod", "dev" or "demo"). | +| allow_registration | [bool](#bool) | | allow_registration is whether the registration is allowed. | +| disable_password_login | [bool](#bool) | | allow_password_login is whether the password login is allowed. | +| additional_script | [string](#string) | | additional_script is the additional script. | +| additional_style | [string](#string) | | additional_style is the additional style. | + - + -### GetUserResponse + + -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| user | [User](#memos-api-v2-User) | | | +### WorkspaceService + + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| GetWorkspaceProfile | [GetWorkspaceProfileRequest](#memos-api-v2-GetWorkspaceProfileRequest) | [GetWorkspaceProfileResponse](#memos-api-v2-GetWorkspaceProfileResponse) | GetWorkspaceProfile returns the workspace profile. | + + + +

Top

+## api/v2/workspace_setting_service.proto - -### ListUserAccessTokensRequest + + +### GetWorkspaceSettingRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| username | [string](#string) | | | +| name | [string](#string) | | The resource name of the workspace setting. Format: settings/{setting} | - + -### ListUserAccessTokensResponse +### GetWorkspaceSettingResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| access_tokens | [UserAccessToken](#memos-api-v2-UserAccessToken) | repeated | | +| setting | [WorkspaceSetting](#memos-api-v2-WorkspaceSetting) | | | - + -### UpdateUserRequest +### SetWorkspaceSettingRequest | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| user | [User](#memos-api-v2-User) | | | -| update_mask | [google.protobuf.FieldMask](#google-protobuf-FieldMask) | | | +| setting | [WorkspaceSetting](#memos-api-v2-WorkspaceSetting) | | setting is the setting to update. | - + -### UpdateUserResponse +### SetWorkspaceSettingResponse | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| user | [User](#memos-api-v2-User) | | | +| setting | [WorkspaceSetting](#memos-api-v2-WorkspaceSetting) | | | - + -### User +### WorkspaceGeneralSetting | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| id | [int32](#int32) | | | -| username | [string](#string) | | | -| role | [User.Role](#memos-api-v2-User-Role) | | | -| email | [string](#string) | | | -| nickname | [string](#string) | | | -| avatar_url | [string](#string) | | | -| password | [string](#string) | | | -| row_status | [RowStatus](#memos-api-v2-RowStatus) | | | -| create_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | -| update_time | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | +| instance_url | [string](#string) | | instance_url is the instance URL. | +| disallow_signup | [bool](#bool) | | disallow_signup is the flag to disallow signup. | +| disallow_password_login | [bool](#bool) | | disallow_password_login is the flag to disallow password login. | +| additional_script | [string](#string) | | additional_script is the additional script. | +| additional_style | [string](#string) | | additional_style is the additional style. | - + -### UserAccessToken +### WorkspaceSetting | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| access_token | [string](#string) | | | -| description | [string](#string) | | | -| issued_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | -| expires_at | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | | +| name | [string](#string) | | name is the name of the setting. Format: settings/{setting} | +| general_setting | [WorkspaceGeneralSetting](#memos-api-v2-WorkspaceGeneralSetting) | | general_setting is the general setting of workspace. | @@ -1246,38 +2701,20 @@ - - - -### User.Role - - -| Name | Number | Description | -| ---- | ------ | ----------- | -| ROLE_UNSPECIFIED | 0 | | -| HOST | 1 | | -| ADMIN | 2 | | -| USER | 3 | | - - - + -### UserService +### WorkspaceSettingService | Method Name | Request Type | Response Type | Description | | ----------- | ------------ | ------------- | ------------| -| GetUser | [GetUserRequest](#memos-api-v2-GetUserRequest) | [GetUserResponse](#memos-api-v2-GetUserResponse) | | -| CreateUser | [CreateUserRequest](#memos-api-v2-CreateUserRequest) | [CreateUserResponse](#memos-api-v2-CreateUserResponse) | | -| UpdateUser | [UpdateUserRequest](#memos-api-v2-UpdateUserRequest) | [UpdateUserResponse](#memos-api-v2-UpdateUserResponse) | | -| ListUserAccessTokens | [ListUserAccessTokensRequest](#memos-api-v2-ListUserAccessTokensRequest) | [ListUserAccessTokensResponse](#memos-api-v2-ListUserAccessTokensResponse) | ListUserAccessTokens returns a list of access tokens for a user. | -| CreateUserAccessToken | [CreateUserAccessTokenRequest](#memos-api-v2-CreateUserAccessTokenRequest) | [CreateUserAccessTokenResponse](#memos-api-v2-CreateUserAccessTokenResponse) | CreateUserAccessToken creates a new access token for a user. | -| DeleteUserAccessToken | [DeleteUserAccessTokenRequest](#memos-api-v2-DeleteUserAccessTokenRequest) | [DeleteUserAccessTokenResponse](#memos-api-v2-DeleteUserAccessTokenResponse) | DeleteUserAccessToken deletes an access token for a user. | +| GetWorkspaceSetting | [GetWorkspaceSettingRequest](#memos-api-v2-GetWorkspaceSettingRequest) | [GetWorkspaceSettingResponse](#memos-api-v2-GetWorkspaceSettingResponse) | GetWorkspaceSetting returns the setting by name. | +| SetWorkspaceSetting | [SetWorkspaceSettingRequest](#memos-api-v2-SetWorkspaceSettingRequest) | [SetWorkspaceSettingResponse](#memos-api-v2-SetWorkspaceSettingResponse) | SetWorkspaceSetting updates the setting. | diff --git a/proto/gen/api/v2/activity_service.pb.go b/proto/gen/api/v2/activity_service.pb.go index e4c0af225b88a..a88aec7162620 100644 --- a/proto/gen/api/v2/activity_service.pb.go +++ b/proto/gen/api/v2/activity_service.pb.go @@ -164,18 +164,66 @@ func (x *ActivityMemoCommentPayload) GetRelatedMemoId() int32 { return 0 } +type ActivityVersionUpdatePayload struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` +} + +func (x *ActivityVersionUpdatePayload) Reset() { + *x = ActivityVersionUpdatePayload{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_activity_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ActivityVersionUpdatePayload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActivityVersionUpdatePayload) ProtoMessage() {} + +func (x *ActivityVersionUpdatePayload) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_activity_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ActivityVersionUpdatePayload.ProtoReflect.Descriptor instead. +func (*ActivityVersionUpdatePayload) Descriptor() ([]byte, []int) { + return file_api_v2_activity_service_proto_rawDescGZIP(), []int{2} +} + +func (x *ActivityVersionUpdatePayload) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + type ActivityPayload struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MemoComment *ActivityMemoCommentPayload `protobuf:"bytes,1,opt,name=memo_comment,json=memoComment,proto3" json:"memo_comment,omitempty"` + MemoComment *ActivityMemoCommentPayload `protobuf:"bytes,1,opt,name=memo_comment,json=memoComment,proto3" json:"memo_comment,omitempty"` + VersionUpdate *ActivityVersionUpdatePayload `protobuf:"bytes,2,opt,name=version_update,json=versionUpdate,proto3" json:"version_update,omitempty"` } func (x *ActivityPayload) Reset() { *x = ActivityPayload{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_activity_service_proto_msgTypes[2] + mi := &file_api_v2_activity_service_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -188,7 +236,7 @@ func (x *ActivityPayload) String() string { func (*ActivityPayload) ProtoMessage() {} func (x *ActivityPayload) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_activity_service_proto_msgTypes[2] + mi := &file_api_v2_activity_service_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -201,7 +249,7 @@ func (x *ActivityPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use ActivityPayload.ProtoReflect.Descriptor instead. func (*ActivityPayload) Descriptor() ([]byte, []int) { - return file_api_v2_activity_service_proto_rawDescGZIP(), []int{2} + return file_api_v2_activity_service_proto_rawDescGZIP(), []int{3} } func (x *ActivityPayload) GetMemoComment() *ActivityMemoCommentPayload { @@ -211,6 +259,13 @@ func (x *ActivityPayload) GetMemoComment() *ActivityMemoCommentPayload { return nil } +func (x *ActivityPayload) GetVersionUpdate() *ActivityVersionUpdatePayload { + if x != nil { + return x.VersionUpdate + } + return nil +} + type GetActivityRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -222,7 +277,7 @@ type GetActivityRequest struct { func (x *GetActivityRequest) Reset() { *x = GetActivityRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_activity_service_proto_msgTypes[3] + mi := &file_api_v2_activity_service_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -235,7 +290,7 @@ func (x *GetActivityRequest) String() string { func (*GetActivityRequest) ProtoMessage() {} func (x *GetActivityRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_activity_service_proto_msgTypes[3] + mi := &file_api_v2_activity_service_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -248,7 +303,7 @@ func (x *GetActivityRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActivityRequest.ProtoReflect.Descriptor instead. func (*GetActivityRequest) Descriptor() ([]byte, []int) { - return file_api_v2_activity_service_proto_rawDescGZIP(), []int{3} + return file_api_v2_activity_service_proto_rawDescGZIP(), []int{4} } func (x *GetActivityRequest) GetId() int32 { @@ -269,7 +324,7 @@ type GetActivityResponse struct { func (x *GetActivityResponse) Reset() { *x = GetActivityResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_activity_service_proto_msgTypes[4] + mi := &file_api_v2_activity_service_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -282,7 +337,7 @@ func (x *GetActivityResponse) String() string { func (*GetActivityResponse) ProtoMessage() {} func (x *GetActivityResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_activity_service_proto_msgTypes[4] + mi := &file_api_v2_activity_service_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -295,7 +350,7 @@ func (x *GetActivityResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetActivityResponse.ProtoReflect.Descriptor instead. func (*GetActivityResponse) Descriptor() ([]byte, []int) { - return file_api_v2_activity_service_proto_rawDescGZIP(), []int{4} + return file_api_v2_activity_service_proto_rawDescGZIP(), []int{5} } func (x *GetActivityResponse) GetActivity() *Activity { @@ -312,61 +367,72 @@ var file_api_v2_activity_service_proto_rawDesc = []byte{ 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd9, 0x01, 0x0a, - 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x65, 0x76, - 0x65, 0x6c, 0x12, 0x3b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, - 0x37, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, - 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, - 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x5d, 0x0a, 0x1a, 0x41, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x79, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x50, - 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x49, 0x64, 0x12, - 0x26, 0x0a, 0x0f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, - 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x49, 0x64, 0x22, 0x5e, 0x0a, 0x0f, 0x41, 0x63, 0x74, 0x69, 0x76, - 0x69, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x4b, 0x0a, 0x0c, 0x6d, 0x65, - 0x6d, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x28, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, - 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, - 0x65, 0x6e, 0x74, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, - 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x24, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x41, 0x63, - 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x49, 0x0a, - 0x13, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x08, - 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x32, 0x7d, 0x0a, 0x0f, 0x41, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6a, 0x0a, 0x0b, 0x47, - 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x20, 0x2e, 0x6d, 0x65, 0x6d, - 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, - 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, - 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, - 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x63, 0x74, - 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x42, 0xac, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x14, 0x41, 0x63, - 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, - 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, - 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, - 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, - 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, - 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd9, 0x01, 0x0a, 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, + 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x3b, 0x0a, 0x0b, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, + 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, + 0x64, 0x22, 0x5d, 0x0a, 0x1a, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x4d, 0x65, 0x6d, + 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, + 0x17, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x49, 0x64, + 0x22, 0x38, 0x0a, 0x1c, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xb1, 0x01, 0x0a, 0x0f, 0x41, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x4b, + 0x0a, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x4d, 0x65, 0x6d, 0x6f, + 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x0b, + 0x6d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x51, 0x0a, 0x0e, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, + 0x0d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0x24, + 0x0a, 0x12, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x02, 0x69, 0x64, 0x22, 0x49, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x08, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x32, + 0x87, 0x01, 0x0a, 0x0f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x74, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, + 0x74, 0x79, 0x12, 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x42, 0xac, 0x01, 0x0a, 0x10, 0x63, 0x6f, + 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x14, + 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, + 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, + 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, + 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, + 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -381,27 +447,29 @@ func file_api_v2_activity_service_proto_rawDescGZIP() []byte { return file_api_v2_activity_service_proto_rawDescData } -var file_api_v2_activity_service_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_api_v2_activity_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_api_v2_activity_service_proto_goTypes = []interface{}{ - (*Activity)(nil), // 0: memos.api.v2.Activity - (*ActivityMemoCommentPayload)(nil), // 1: memos.api.v2.ActivityMemoCommentPayload - (*ActivityPayload)(nil), // 2: memos.api.v2.ActivityPayload - (*GetActivityRequest)(nil), // 3: memos.api.v2.GetActivityRequest - (*GetActivityResponse)(nil), // 4: memos.api.v2.GetActivityResponse - (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp + (*Activity)(nil), // 0: memos.api.v2.Activity + (*ActivityMemoCommentPayload)(nil), // 1: memos.api.v2.ActivityMemoCommentPayload + (*ActivityVersionUpdatePayload)(nil), // 2: memos.api.v2.ActivityVersionUpdatePayload + (*ActivityPayload)(nil), // 3: memos.api.v2.ActivityPayload + (*GetActivityRequest)(nil), // 4: memos.api.v2.GetActivityRequest + (*GetActivityResponse)(nil), // 5: memos.api.v2.GetActivityResponse + (*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp } var file_api_v2_activity_service_proto_depIdxs = []int32{ - 5, // 0: memos.api.v2.Activity.create_time:type_name -> google.protobuf.Timestamp - 2, // 1: memos.api.v2.Activity.payload:type_name -> memos.api.v2.ActivityPayload + 6, // 0: memos.api.v2.Activity.create_time:type_name -> google.protobuf.Timestamp + 3, // 1: memos.api.v2.Activity.payload:type_name -> memos.api.v2.ActivityPayload 1, // 2: memos.api.v2.ActivityPayload.memo_comment:type_name -> memos.api.v2.ActivityMemoCommentPayload - 0, // 3: memos.api.v2.GetActivityResponse.activity:type_name -> memos.api.v2.Activity - 3, // 4: memos.api.v2.ActivityService.GetActivity:input_type -> memos.api.v2.GetActivityRequest - 4, // 5: memos.api.v2.ActivityService.GetActivity:output_type -> memos.api.v2.GetActivityResponse - 5, // [5:6] is the sub-list for method output_type - 4, // [4:5] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name + 2, // 3: memos.api.v2.ActivityPayload.version_update:type_name -> memos.api.v2.ActivityVersionUpdatePayload + 0, // 4: memos.api.v2.GetActivityResponse.activity:type_name -> memos.api.v2.Activity + 4, // 5: memos.api.v2.ActivityService.GetActivity:input_type -> memos.api.v2.GetActivityRequest + 5, // 6: memos.api.v2.ActivityService.GetActivity:output_type -> memos.api.v2.GetActivityResponse + 6, // [6:7] is the sub-list for method output_type + 5, // [5:6] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name } func init() { file_api_v2_activity_service_proto_init() } @@ -435,7 +503,7 @@ func file_api_v2_activity_service_proto_init() { } } file_api_v2_activity_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ActivityPayload); i { + switch v := v.(*ActivityVersionUpdatePayload); i { case 0: return &v.state case 1: @@ -447,7 +515,7 @@ func file_api_v2_activity_service_proto_init() { } } file_api_v2_activity_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetActivityRequest); i { + switch v := v.(*ActivityPayload); i { case 0: return &v.state case 1: @@ -459,6 +527,18 @@ func file_api_v2_activity_service_proto_init() { } } file_api_v2_activity_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetActivityRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_activity_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetActivityResponse); i { case 0: return &v.state @@ -477,7 +557,7 @@ func file_api_v2_activity_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_v2_activity_service_proto_rawDesc, NumEnums: 0, - NumMessages: 5, + NumMessages: 6, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gen/api/v2/activity_service.pb.gw.go b/proto/gen/api/v2/activity_service.pb.gw.go index 381512442e2e4..c1a2c0d7d429a 100644 --- a/proto/gen/api/v2/activity_service.pb.gw.go +++ b/proto/gen/api/v2/activity_service.pb.gw.go @@ -31,19 +31,25 @@ var _ = runtime.String var _ = utilities.NewDoubleArray var _ = metadata.Join -var ( - filter_ActivityService_GetActivity_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} -) - func request_ActivityService_GetActivity_0(ctx context.Context, marshaler runtime.Marshaler, client ActivityServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq GetActivityRequest var metadata runtime.ServerMetadata - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ActivityService_GetActivity_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } msg, err := client.GetActivity(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -55,11 +61,21 @@ func local_request_ActivityService_GetActivity_0(ctx context.Context, marshaler var protoReq GetActivityRequest var metadata runtime.ServerMetadata - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_ActivityService_GetActivity_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } msg, err := server.GetActivity(ctx, &protoReq) @@ -81,7 +97,7 @@ func RegisterActivityServiceHandlerServer(ctx context.Context, mux *runtime.Serv inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.ActivityService/GetActivity", runtime.WithHTTPPathPattern("/v2/activities")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.ActivityService/GetActivity", runtime.WithHTTPPathPattern("/v2/activities/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -145,7 +161,7 @@ func RegisterActivityServiceHandlerClient(ctx context.Context, mux *runtime.Serv inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.ActivityService/GetActivity", runtime.WithHTTPPathPattern("/v2/activities")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.ActivityService/GetActivity", runtime.WithHTTPPathPattern("/v2/activities/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -165,7 +181,7 @@ func RegisterActivityServiceHandlerClient(ctx context.Context, mux *runtime.Serv } var ( - pattern_ActivityService_GetActivity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v2", "activities"}, "")) + pattern_ActivityService_GetActivity_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v2", "activities", "id"}, "")) ) var ( diff --git a/proto/gen/api/v2/activity_service_grpc.pb.go b/proto/gen/api/v2/activity_service_grpc.pb.go index 1def9148ced4f..c19172f356c37 100644 --- a/proto/gen/api/v2/activity_service_grpc.pb.go +++ b/proto/gen/api/v2/activity_service_grpc.pb.go @@ -26,6 +26,7 @@ const ( // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type ActivityServiceClient interface { + // GetActivity returns the activity with the given id. GetActivity(ctx context.Context, in *GetActivityRequest, opts ...grpc.CallOption) (*GetActivityResponse, error) } @@ -50,6 +51,7 @@ func (c *activityServiceClient) GetActivity(ctx context.Context, in *GetActivity // All implementations must embed UnimplementedActivityServiceServer // for forward compatibility type ActivityServiceServer interface { + // GetActivity returns the activity with the given id. GetActivity(context.Context, *GetActivityRequest) (*GetActivityResponse, error) mustEmbedUnimplementedActivityServiceServer() } diff --git a/proto/gen/api/v2/auth_service.pb.go b/proto/gen/api/v2/auth_service.pb.go new file mode 100644 index 0000000000000..cc274573180d0 --- /dev/null +++ b/proto/gen/api/v2/auth_service.pb.go @@ -0,0 +1,795 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: api/v2/auth_service.proto + +package apiv2 + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type GetAuthStatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetAuthStatusRequest) Reset() { + *x = GetAuthStatusRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_auth_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAuthStatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAuthStatusRequest) ProtoMessage() {} + +func (x *GetAuthStatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_auth_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAuthStatusRequest.ProtoReflect.Descriptor instead. +func (*GetAuthStatusRequest) Descriptor() ([]byte, []int) { + return file_api_v2_auth_service_proto_rawDescGZIP(), []int{0} +} + +type GetAuthStatusResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *GetAuthStatusResponse) Reset() { + *x = GetAuthStatusResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_auth_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetAuthStatusResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetAuthStatusResponse) ProtoMessage() {} + +func (x *GetAuthStatusResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_auth_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetAuthStatusResponse.ProtoReflect.Descriptor instead. +func (*GetAuthStatusResponse) Descriptor() ([]byte, []int) { + return file_api_v2_auth_service_proto_rawDescGZIP(), []int{1} +} + +func (x *GetAuthStatusResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +type SignInRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + NeverExpire bool `protobuf:"varint,3,opt,name=never_expire,json=neverExpire,proto3" json:"never_expire,omitempty"` +} + +func (x *SignInRequest) Reset() { + *x = SignInRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_auth_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignInRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignInRequest) ProtoMessage() {} + +func (x *SignInRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_auth_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignInRequest.ProtoReflect.Descriptor instead. +func (*SignInRequest) Descriptor() ([]byte, []int) { + return file_api_v2_auth_service_proto_rawDescGZIP(), []int{2} +} + +func (x *SignInRequest) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *SignInRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *SignInRequest) GetNeverExpire() bool { + if x != nil { + return x.NeverExpire + } + return false +} + +type SignInResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *SignInResponse) Reset() { + *x = SignInResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_auth_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignInResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignInResponse) ProtoMessage() {} + +func (x *SignInResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_auth_service_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignInResponse.ProtoReflect.Descriptor instead. +func (*SignInResponse) Descriptor() ([]byte, []int) { + return file_api_v2_auth_service_proto_rawDescGZIP(), []int{3} +} + +func (x *SignInResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +type SignInWithSSORequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IdpId int32 `protobuf:"varint,1,opt,name=idp_id,json=idpId,proto3" json:"idp_id,omitempty"` + Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"` + RedirectUri string `protobuf:"bytes,3,opt,name=redirect_uri,json=redirectUri,proto3" json:"redirect_uri,omitempty"` +} + +func (x *SignInWithSSORequest) Reset() { + *x = SignInWithSSORequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_auth_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignInWithSSORequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignInWithSSORequest) ProtoMessage() {} + +func (x *SignInWithSSORequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_auth_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignInWithSSORequest.ProtoReflect.Descriptor instead. +func (*SignInWithSSORequest) Descriptor() ([]byte, []int) { + return file_api_v2_auth_service_proto_rawDescGZIP(), []int{4} +} + +func (x *SignInWithSSORequest) GetIdpId() int32 { + if x != nil { + return x.IdpId + } + return 0 +} + +func (x *SignInWithSSORequest) GetCode() string { + if x != nil { + return x.Code + } + return "" +} + +func (x *SignInWithSSORequest) GetRedirectUri() string { + if x != nil { + return x.RedirectUri + } + return "" +} + +type SignInWithSSOResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *SignInWithSSOResponse) Reset() { + *x = SignInWithSSOResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_auth_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignInWithSSOResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignInWithSSOResponse) ProtoMessage() {} + +func (x *SignInWithSSOResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_auth_service_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignInWithSSOResponse.ProtoReflect.Descriptor instead. +func (*SignInWithSSOResponse) Descriptor() ([]byte, []int) { + return file_api_v2_auth_service_proto_rawDescGZIP(), []int{5} +} + +func (x *SignInWithSSOResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +type SignUpRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` +} + +func (x *SignUpRequest) Reset() { + *x = SignUpRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_auth_service_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignUpRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignUpRequest) ProtoMessage() {} + +func (x *SignUpRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_auth_service_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignUpRequest.ProtoReflect.Descriptor instead. +func (*SignUpRequest) Descriptor() ([]byte, []int) { + return file_api_v2_auth_service_proto_rawDescGZIP(), []int{6} +} + +func (x *SignUpRequest) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +func (x *SignUpRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +type SignUpResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + User *User `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *SignUpResponse) Reset() { + *x = SignUpResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_auth_service_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignUpResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignUpResponse) ProtoMessage() {} + +func (x *SignUpResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_auth_service_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignUpResponse.ProtoReflect.Descriptor instead. +func (*SignUpResponse) Descriptor() ([]byte, []int) { + return file_api_v2_auth_service_proto_rawDescGZIP(), []int{7} +} + +func (x *SignUpResponse) GetUser() *User { + if x != nil { + return x.User + } + return nil +} + +type SignOutRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SignOutRequest) Reset() { + *x = SignOutRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_auth_service_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignOutRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignOutRequest) ProtoMessage() {} + +func (x *SignOutRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_auth_service_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignOutRequest.ProtoReflect.Descriptor instead. +func (*SignOutRequest) Descriptor() ([]byte, []int) { + return file_api_v2_auth_service_proto_rawDescGZIP(), []int{8} +} + +type SignOutResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SignOutResponse) Reset() { + *x = SignOutResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_auth_service_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignOutResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignOutResponse) ProtoMessage() {} + +func (x *SignOutResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_auth_service_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignOutResponse.ProtoReflect.Descriptor instead. +func (*SignOutResponse) Descriptor() ([]byte, []int) { + return file_api_v2_auth_service_proto_rawDescGZIP(), []int{9} +} + +var File_api_v2_auth_service_proto protoreflect.FileDescriptor + +var file_api_v2_auth_service_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x19, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x16, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3f, 0x0a, 0x15, 0x47, 0x65, + 0x74, 0x41, 0x75, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x6a, 0x0a, 0x0d, 0x53, + 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x5f, 0x65, 0x78, + 0x70, 0x69, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6e, 0x65, 0x76, 0x65, + 0x72, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x22, 0x38, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x49, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, + 0x72, 0x22, 0x64, 0x0a, 0x14, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x53, + 0x53, 0x4f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x69, 0x64, 0x70, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x69, 0x64, 0x70, 0x49, 0x64, + 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x63, 0x6f, 0x64, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x5f, 0x75, 0x72, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x64, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x55, 0x72, 0x69, 0x22, 0x3f, 0x0a, 0x15, 0x53, 0x69, 0x67, 0x6e, 0x49, + 0x6e, 0x57, 0x69, 0x74, 0x68, 0x53, 0x53, 0x4f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x47, 0x0a, 0x0d, 0x53, 0x69, 0x67, 0x6e, + 0x55, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x22, 0x38, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x55, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x10, 0x0a, 0x0e, 0x53, + 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x11, 0x0a, + 0x0f, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x32, 0xa9, 0x04, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x75, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x22, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x15, 0x22, 0x13, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x75, 0x74, 0x68, + 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x60, 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x49, + 0x6e, 0x12, 0x1b, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, + 0x67, 0x6e, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x15, 0x22, 0x13, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x75, + 0x74, 0x68, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x12, 0x79, 0x0a, 0x0d, 0x53, 0x69, 0x67, + 0x6e, 0x49, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x53, 0x53, 0x4f, 0x12, 0x22, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x49, 0x6e, + 0x57, 0x69, 0x74, 0x68, 0x53, 0x53, 0x4f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, + 0x67, 0x6e, 0x49, 0x6e, 0x57, 0x69, 0x74, 0x68, 0x53, 0x53, 0x4f, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x22, 0x17, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, + 0x2f, 0x73, 0x73, 0x6f, 0x12, 0x60, 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x55, 0x70, 0x12, 0x1b, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, + 0x67, 0x6e, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x55, + 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x15, 0x22, 0x13, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2f, + 0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x12, 0x64, 0x0a, 0x07, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, + 0x74, 0x12, 0x1c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, + 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x22, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, + 0x61, 0x75, 0x74, 0x68, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x6f, 0x75, 0x74, 0x42, 0xa8, 0x01, 0x0a, + 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x32, 0x42, 0x10, 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, + 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, + 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, + 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, + 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_v2_auth_service_proto_rawDescOnce sync.Once + file_api_v2_auth_service_proto_rawDescData = file_api_v2_auth_service_proto_rawDesc +) + +func file_api_v2_auth_service_proto_rawDescGZIP() []byte { + file_api_v2_auth_service_proto_rawDescOnce.Do(func() { + file_api_v2_auth_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_v2_auth_service_proto_rawDescData) + }) + return file_api_v2_auth_service_proto_rawDescData +} + +var file_api_v2_auth_service_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_api_v2_auth_service_proto_goTypes = []interface{}{ + (*GetAuthStatusRequest)(nil), // 0: memos.api.v2.GetAuthStatusRequest + (*GetAuthStatusResponse)(nil), // 1: memos.api.v2.GetAuthStatusResponse + (*SignInRequest)(nil), // 2: memos.api.v2.SignInRequest + (*SignInResponse)(nil), // 3: memos.api.v2.SignInResponse + (*SignInWithSSORequest)(nil), // 4: memos.api.v2.SignInWithSSORequest + (*SignInWithSSOResponse)(nil), // 5: memos.api.v2.SignInWithSSOResponse + (*SignUpRequest)(nil), // 6: memos.api.v2.SignUpRequest + (*SignUpResponse)(nil), // 7: memos.api.v2.SignUpResponse + (*SignOutRequest)(nil), // 8: memos.api.v2.SignOutRequest + (*SignOutResponse)(nil), // 9: memos.api.v2.SignOutResponse + (*User)(nil), // 10: memos.api.v2.User +} +var file_api_v2_auth_service_proto_depIdxs = []int32{ + 10, // 0: memos.api.v2.GetAuthStatusResponse.user:type_name -> memos.api.v2.User + 10, // 1: memos.api.v2.SignInResponse.user:type_name -> memos.api.v2.User + 10, // 2: memos.api.v2.SignInWithSSOResponse.user:type_name -> memos.api.v2.User + 10, // 3: memos.api.v2.SignUpResponse.user:type_name -> memos.api.v2.User + 0, // 4: memos.api.v2.AuthService.GetAuthStatus:input_type -> memos.api.v2.GetAuthStatusRequest + 2, // 5: memos.api.v2.AuthService.SignIn:input_type -> memos.api.v2.SignInRequest + 4, // 6: memos.api.v2.AuthService.SignInWithSSO:input_type -> memos.api.v2.SignInWithSSORequest + 6, // 7: memos.api.v2.AuthService.SignUp:input_type -> memos.api.v2.SignUpRequest + 8, // 8: memos.api.v2.AuthService.SignOut:input_type -> memos.api.v2.SignOutRequest + 1, // 9: memos.api.v2.AuthService.GetAuthStatus:output_type -> memos.api.v2.GetAuthStatusResponse + 3, // 10: memos.api.v2.AuthService.SignIn:output_type -> memos.api.v2.SignInResponse + 5, // 11: memos.api.v2.AuthService.SignInWithSSO:output_type -> memos.api.v2.SignInWithSSOResponse + 7, // 12: memos.api.v2.AuthService.SignUp:output_type -> memos.api.v2.SignUpResponse + 9, // 13: memos.api.v2.AuthService.SignOut:output_type -> memos.api.v2.SignOutResponse + 9, // [9:14] is the sub-list for method output_type + 4, // [4:9] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_api_v2_auth_service_proto_init() } +func file_api_v2_auth_service_proto_init() { + if File_api_v2_auth_service_proto != nil { + return + } + file_api_v2_user_service_proto_init() + if !protoimpl.UnsafeEnabled { + file_api_v2_auth_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAuthStatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_auth_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAuthStatusResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_auth_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignInRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_auth_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignInResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_auth_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignInWithSSORequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_auth_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignInWithSSOResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_auth_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignUpRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_auth_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignUpResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_auth_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignOutRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_auth_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignOutResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_v2_auth_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 10, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_api_v2_auth_service_proto_goTypes, + DependencyIndexes: file_api_v2_auth_service_proto_depIdxs, + MessageInfos: file_api_v2_auth_service_proto_msgTypes, + }.Build() + File_api_v2_auth_service_proto = out.File + file_api_v2_auth_service_proto_rawDesc = nil + file_api_v2_auth_service_proto_goTypes = nil + file_api_v2_auth_service_proto_depIdxs = nil +} diff --git a/proto/gen/api/v2/auth_service.pb.gw.go b/proto/gen/api/v2/auth_service.pb.gw.go new file mode 100644 index 0000000000000..f79d1ac8f3ba9 --- /dev/null +++ b/proto/gen/api/v2/auth_service.pb.gw.go @@ -0,0 +1,485 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: api/v2/auth_service.proto + +/* +Package apiv2 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package apiv2 + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +func request_AuthService_GetAuthStatus_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetAuthStatusRequest + var metadata runtime.ServerMetadata + + msg, err := client.GetAuthStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthService_GetAuthStatus_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetAuthStatusRequest + var metadata runtime.ServerMetadata + + msg, err := server.GetAuthStatus(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_AuthService_SignIn_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_AuthService_SignIn_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SignInRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AuthService_SignIn_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.SignIn(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthService_SignIn_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SignInRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AuthService_SignIn_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.SignIn(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_AuthService_SignInWithSSO_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_AuthService_SignInWithSSO_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SignInWithSSORequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AuthService_SignInWithSSO_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.SignInWithSSO(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthService_SignInWithSSO_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SignInWithSSORequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AuthService_SignInWithSSO_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.SignInWithSSO(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_AuthService_SignUp_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_AuthService_SignUp_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SignUpRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AuthService_SignUp_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.SignUp(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthService_SignUp_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SignUpRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AuthService_SignUp_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.SignUp(ctx, &protoReq) + return msg, metadata, err + +} + +func request_AuthService_SignOut_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SignOutRequest + var metadata runtime.ServerMetadata + + msg, err := client.SignOut(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_AuthService_SignOut_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SignOutRequest + var metadata runtime.ServerMetadata + + msg, err := server.SignOut(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterAuthServiceHandlerServer registers the http handlers for service AuthService to "mux". +// UnaryRPC :call AuthServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterAuthServiceHandlerFromEndpoint instead. +func RegisterAuthServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AuthServiceServer) error { + + mux.Handle("POST", pattern_AuthService_GetAuthStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.AuthService/GetAuthStatus", runtime.WithHTTPPathPattern("/api/v2/auth/status")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthService_GetAuthStatus_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_GetAuthStatus_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthService_SignIn_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.AuthService/SignIn", runtime.WithHTTPPathPattern("/api/v2/auth/signin")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthService_SignIn_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_SignIn_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthService_SignInWithSSO_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.AuthService/SignInWithSSO", runtime.WithHTTPPathPattern("/api/v2/auth/signin/sso")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthService_SignInWithSSO_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_SignInWithSSO_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthService_SignUp_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.AuthService/SignUp", runtime.WithHTTPPathPattern("/api/v2/auth/signup")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthService_SignUp_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_SignUp_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthService_SignOut_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.AuthService/SignOut", runtime.WithHTTPPathPattern("/api/v2/auth/signout")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_AuthService_SignOut_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_SignOut_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterAuthServiceHandlerFromEndpoint is same as RegisterAuthServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterAuthServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.DialContext(ctx, endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterAuthServiceHandler(ctx, mux, conn) +} + +// RegisterAuthServiceHandler registers the http handlers for service AuthService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterAuthServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterAuthServiceHandlerClient(ctx, mux, NewAuthServiceClient(conn)) +} + +// RegisterAuthServiceHandlerClient registers the http handlers for service AuthService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AuthServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AuthServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "AuthServiceClient" to call the correct interceptors. +func RegisterAuthServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AuthServiceClient) error { + + mux.Handle("POST", pattern_AuthService_GetAuthStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.AuthService/GetAuthStatus", runtime.WithHTTPPathPattern("/api/v2/auth/status")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthService_GetAuthStatus_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_GetAuthStatus_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthService_SignIn_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.AuthService/SignIn", runtime.WithHTTPPathPattern("/api/v2/auth/signin")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthService_SignIn_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_SignIn_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthService_SignInWithSSO_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.AuthService/SignInWithSSO", runtime.WithHTTPPathPattern("/api/v2/auth/signin/sso")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthService_SignInWithSSO_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_SignInWithSSO_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthService_SignUp_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.AuthService/SignUp", runtime.WithHTTPPathPattern("/api/v2/auth/signup")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthService_SignUp_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_SignUp_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_AuthService_SignOut_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.AuthService/SignOut", runtime.WithHTTPPathPattern("/api/v2/auth/signout")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_AuthService_SignOut_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_AuthService_SignOut_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_AuthService_GetAuthStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v2", "auth", "status"}, "")) + + pattern_AuthService_SignIn_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v2", "auth", "signin"}, "")) + + pattern_AuthService_SignInWithSSO_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"api", "v2", "auth", "signin", "sso"}, "")) + + pattern_AuthService_SignUp_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v2", "auth", "signup"}, "")) + + pattern_AuthService_SignOut_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v2", "auth", "signout"}, "")) +) + +var ( + forward_AuthService_GetAuthStatus_0 = runtime.ForwardResponseMessage + + forward_AuthService_SignIn_0 = runtime.ForwardResponseMessage + + forward_AuthService_SignInWithSSO_0 = runtime.ForwardResponseMessage + + forward_AuthService_SignUp_0 = runtime.ForwardResponseMessage + + forward_AuthService_SignOut_0 = runtime.ForwardResponseMessage +) diff --git a/proto/gen/api/v2/auth_service_grpc.pb.go b/proto/gen/api/v2/auth_service_grpc.pb.go new file mode 100644 index 0000000000000..5ffe9e7e8244b --- /dev/null +++ b/proto/gen/api/v2/auth_service_grpc.pb.go @@ -0,0 +1,267 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: api/v2/auth_service.proto + +package apiv2 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + AuthService_GetAuthStatus_FullMethodName = "/memos.api.v2.AuthService/GetAuthStatus" + AuthService_SignIn_FullMethodName = "/memos.api.v2.AuthService/SignIn" + AuthService_SignInWithSSO_FullMethodName = "/memos.api.v2.AuthService/SignInWithSSO" + AuthService_SignUp_FullMethodName = "/memos.api.v2.AuthService/SignUp" + AuthService_SignOut_FullMethodName = "/memos.api.v2.AuthService/SignOut" +) + +// AuthServiceClient is the client API for AuthService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AuthServiceClient interface { + // GetAuthStatus returns the current auth status of the user. + GetAuthStatus(ctx context.Context, in *GetAuthStatusRequest, opts ...grpc.CallOption) (*GetAuthStatusResponse, error) + // SignIn signs in the user with the given username and password. + SignIn(ctx context.Context, in *SignInRequest, opts ...grpc.CallOption) (*SignInResponse, error) + // SignInWithSSO signs in the user with the given SSO code. + SignInWithSSO(ctx context.Context, in *SignInWithSSORequest, opts ...grpc.CallOption) (*SignInWithSSOResponse, error) + // SignUp signs up the user with the given username and password. + SignUp(ctx context.Context, in *SignUpRequest, opts ...grpc.CallOption) (*SignUpResponse, error) + // SignOut signs out the user. + SignOut(ctx context.Context, in *SignOutRequest, opts ...grpc.CallOption) (*SignOutResponse, error) +} + +type authServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewAuthServiceClient(cc grpc.ClientConnInterface) AuthServiceClient { + return &authServiceClient{cc} +} + +func (c *authServiceClient) GetAuthStatus(ctx context.Context, in *GetAuthStatusRequest, opts ...grpc.CallOption) (*GetAuthStatusResponse, error) { + out := new(GetAuthStatusResponse) + err := c.cc.Invoke(ctx, AuthService_GetAuthStatus_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authServiceClient) SignIn(ctx context.Context, in *SignInRequest, opts ...grpc.CallOption) (*SignInResponse, error) { + out := new(SignInResponse) + err := c.cc.Invoke(ctx, AuthService_SignIn_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authServiceClient) SignInWithSSO(ctx context.Context, in *SignInWithSSORequest, opts ...grpc.CallOption) (*SignInWithSSOResponse, error) { + out := new(SignInWithSSOResponse) + err := c.cc.Invoke(ctx, AuthService_SignInWithSSO_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authServiceClient) SignUp(ctx context.Context, in *SignUpRequest, opts ...grpc.CallOption) (*SignUpResponse, error) { + out := new(SignUpResponse) + err := c.cc.Invoke(ctx, AuthService_SignUp_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *authServiceClient) SignOut(ctx context.Context, in *SignOutRequest, opts ...grpc.CallOption) (*SignOutResponse, error) { + out := new(SignOutResponse) + err := c.cc.Invoke(ctx, AuthService_SignOut_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AuthServiceServer is the server API for AuthService service. +// All implementations must embed UnimplementedAuthServiceServer +// for forward compatibility +type AuthServiceServer interface { + // GetAuthStatus returns the current auth status of the user. + GetAuthStatus(context.Context, *GetAuthStatusRequest) (*GetAuthStatusResponse, error) + // SignIn signs in the user with the given username and password. + SignIn(context.Context, *SignInRequest) (*SignInResponse, error) + // SignInWithSSO signs in the user with the given SSO code. + SignInWithSSO(context.Context, *SignInWithSSORequest) (*SignInWithSSOResponse, error) + // SignUp signs up the user with the given username and password. + SignUp(context.Context, *SignUpRequest) (*SignUpResponse, error) + // SignOut signs out the user. + SignOut(context.Context, *SignOutRequest) (*SignOutResponse, error) + mustEmbedUnimplementedAuthServiceServer() +} + +// UnimplementedAuthServiceServer must be embedded to have forward compatible implementations. +type UnimplementedAuthServiceServer struct { +} + +func (UnimplementedAuthServiceServer) GetAuthStatus(context.Context, *GetAuthStatusRequest) (*GetAuthStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetAuthStatus not implemented") +} +func (UnimplementedAuthServiceServer) SignIn(context.Context, *SignInRequest) (*SignInResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SignIn not implemented") +} +func (UnimplementedAuthServiceServer) SignInWithSSO(context.Context, *SignInWithSSORequest) (*SignInWithSSOResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SignInWithSSO not implemented") +} +func (UnimplementedAuthServiceServer) SignUp(context.Context, *SignUpRequest) (*SignUpResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SignUp not implemented") +} +func (UnimplementedAuthServiceServer) SignOut(context.Context, *SignOutRequest) (*SignOutResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SignOut not implemented") +} +func (UnimplementedAuthServiceServer) mustEmbedUnimplementedAuthServiceServer() {} + +// UnsafeAuthServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AuthServiceServer will +// result in compilation errors. +type UnsafeAuthServiceServer interface { + mustEmbedUnimplementedAuthServiceServer() +} + +func RegisterAuthServiceServer(s grpc.ServiceRegistrar, srv AuthServiceServer) { + s.RegisterService(&AuthService_ServiceDesc, srv) +} + +func _AuthService_GetAuthStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAuthStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).GetAuthStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthService_GetAuthStatus_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).GetAuthStatus(ctx, req.(*GetAuthStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthService_SignIn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SignInRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).SignIn(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthService_SignIn_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).SignIn(ctx, req.(*SignInRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthService_SignInWithSSO_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SignInWithSSORequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).SignInWithSSO(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthService_SignInWithSSO_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).SignInWithSSO(ctx, req.(*SignInWithSSORequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthService_SignUp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SignUpRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).SignUp(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthService_SignUp_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).SignUp(ctx, req.(*SignUpRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _AuthService_SignOut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SignOutRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AuthServiceServer).SignOut(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: AuthService_SignOut_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AuthServiceServer).SignOut(ctx, req.(*SignOutRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// AuthService_ServiceDesc is the grpc.ServiceDesc for AuthService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AuthService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "memos.api.v2.AuthService", + HandlerType: (*AuthServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetAuthStatus", + Handler: _AuthService_GetAuthStatus_Handler, + }, + { + MethodName: "SignIn", + Handler: _AuthService_SignIn_Handler, + }, + { + MethodName: "SignInWithSSO", + Handler: _AuthService_SignInWithSSO_Handler, + }, + { + MethodName: "SignUp", + Handler: _AuthService_SignUp_Handler, + }, + { + MethodName: "SignOut", + Handler: _AuthService_SignOut_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api/v2/auth_service.proto", +} diff --git a/proto/gen/api/v2/common.pb.go b/proto/gen/api/v2/common.pb.go index 02ecea2183c67..0a1e4e3f110a8 100644 --- a/proto/gen/api/v2/common.pb.go +++ b/proto/gen/api/v2/common.pb.go @@ -69,27 +69,86 @@ func (RowStatus) EnumDescriptor() ([]byte, []int) { return file_api_v2_common_proto_rawDescGZIP(), []int{0} } +// Used internally for obfuscating the page token. +type PageToken struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Limit int32 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"` + Offset int32 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"` +} + +func (x *PageToken) Reset() { + *x = PageToken{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_common_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PageToken) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PageToken) ProtoMessage() {} + +func (x *PageToken) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_common_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PageToken.ProtoReflect.Descriptor instead. +func (*PageToken) Descriptor() ([]byte, []int) { + return file_api_v2_common_proto_rawDescGZIP(), []int{0} +} + +func (x *PageToken) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *PageToken) GetOffset() int32 { + if x != nil { + return x.Offset + } + return 0 +} + var File_api_v2_common_proto protoreflect.FileDescriptor var file_api_v2_common_proto_rawDesc = []byte{ 0x0a, 0x13, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x32, 0x2a, 0x41, 0x0a, 0x09, 0x52, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x4f, 0x57, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, - 0x41, 0x43, 0x54, 0x49, 0x56, 0x45, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x52, 0x43, 0x48, - 0x49, 0x56, 0x45, 0x44, 0x10, 0x02, 0x42, 0xa3, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, - 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x0b, 0x43, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, - 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, - 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, - 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, - 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x76, 0x32, 0x22, 0x39, 0x0a, 0x09, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2a, 0x41, + 0x0a, 0x09, 0x52, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x16, 0x52, + 0x4f, 0x57, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x54, 0x49, 0x56, + 0x45, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, 0x45, 0x44, 0x10, + 0x02, 0x42, 0xa3, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, + 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, + 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, + 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, + 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -105,8 +164,10 @@ func file_api_v2_common_proto_rawDescGZIP() []byte { } var file_api_v2_common_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_api_v2_common_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_api_v2_common_proto_goTypes = []interface{}{ - (RowStatus)(0), // 0: memos.api.v2.RowStatus + (RowStatus)(0), // 0: memos.api.v2.RowStatus + (*PageToken)(nil), // 1: memos.api.v2.PageToken } var file_api_v2_common_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -121,19 +182,34 @@ func file_api_v2_common_proto_init() { if File_api_v2_common_proto != nil { return } + if !protoimpl.UnsafeEnabled { + file_api_v2_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PageToken); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_v2_common_proto_rawDesc, NumEnums: 1, - NumMessages: 0, + NumMessages: 1, NumExtensions: 0, NumServices: 0, }, GoTypes: file_api_v2_common_proto_goTypes, DependencyIndexes: file_api_v2_common_proto_depIdxs, EnumInfos: file_api_v2_common_proto_enumTypes, + MessageInfos: file_api_v2_common_proto_msgTypes, }.Build() File_api_v2_common_proto = out.File file_api_v2_common_proto_rawDesc = nil diff --git a/proto/gen/api/v2/inbox_service.pb.go b/proto/gen/api/v2/inbox_service.pb.go index ed34959df39c1..6359d599caa29 100644 --- a/proto/gen/api/v2/inbox_service.pb.go +++ b/proto/gen/api/v2/inbox_service.pb.go @@ -75,8 +75,9 @@ func (Inbox_Status) EnumDescriptor() ([]byte, []int) { type Inbox_Type int32 const ( - Inbox_TYPE_UNSPECIFIED Inbox_Type = 0 - Inbox_TYPE_MEMO_COMMENT Inbox_Type = 1 + Inbox_TYPE_UNSPECIFIED Inbox_Type = 0 + Inbox_TYPE_MEMO_COMMENT Inbox_Type = 1 + Inbox_TYPE_VERSION_UPDATE Inbox_Type = 2 ) // Enum value maps for Inbox_Type. @@ -84,10 +85,12 @@ var ( Inbox_Type_name = map[int32]string{ 0: "TYPE_UNSPECIFIED", 1: "TYPE_MEMO_COMMENT", + 2: "TYPE_VERSION_UPDATE", } Inbox_Type_value = map[string]int32{ - "TYPE_UNSPECIFIED": 0, - "TYPE_MEMO_COMMENT": 1, + "TYPE_UNSPECIFIED": 0, + "TYPE_MEMO_COMMENT": 1, + "TYPE_VERSION_UPDATE": 2, } ) @@ -124,7 +127,7 @@ type Inbox struct { unknownFields protoimpl.UnknownFields // The name of the inbox. - // Format: inboxes/{id} + // Format: inboxes/{uid} Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // Format: users/{username} Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"` @@ -420,7 +423,7 @@ type DeleteInboxRequest struct { unknownFields protoimpl.UnknownFields // The name of the inbox to delete. - // Format: inboxes/{inbox} + // Format: inboxes/{uid} Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } @@ -514,7 +517,7 @@ var file_api_v2_inbox_service_proto_rawDesc = []byte{ 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x95, 0x03, 0x0a, 0x05, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x12, 0x12, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xae, 0x03, 0x0a, 0x05, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, @@ -535,57 +538,60 @@ var file_api_v2_inbox_service_proto_rawDesc = []byte{ 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x4e, 0x52, 0x45, 0x41, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x52, 0x43, - 0x48, 0x49, 0x56, 0x45, 0x44, 0x10, 0x02, 0x22, 0x33, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x48, 0x49, 0x56, 0x45, 0x44, 0x10, 0x02, 0x22, 0x4c, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, - 0x4d, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x42, 0x0e, 0x0a, 0x0c, - 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x22, 0x28, 0x0a, 0x12, - 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x44, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, - 0x62, 0x6f, 0x78, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, - 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x6e, - 0x62, 0x6f, 0x78, 0x52, 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x22, 0x7c, 0x0a, 0x12, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x29, 0x0a, 0x05, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, - 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x05, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x12, 0x3b, 0x0a, - 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x40, 0x0a, 0x13, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x29, 0x0a, 0x05, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, - 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x05, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x22, 0x28, 0x0a, 0x12, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xf9, 0x02, - 0x0a, 0x0c, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6b, - 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x12, 0x20, 0x2e, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x21, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x32, 0x2f, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x12, 0x82, 0x01, 0x0a, 0x0b, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x12, 0x20, 0x2e, 0x6d, 0x65, - 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x4d, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x50, 0x44, + 0x41, 0x54, 0x45, 0x10, 0x02, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, + 0x74, 0x79, 0x5f, 0x69, 0x64, 0x22, 0x28, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, + 0x6f, 0x78, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, + 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, + 0x44, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x07, 0x69, 0x6e, + 0x62, 0x6f, 0x78, 0x65, 0x73, 0x22, 0x7c, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, + 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x05, 0x69, + 0x6e, 0x62, 0x6f, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, + 0x05, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, + 0x61, 0x73, 0x6b, 0x22, 0x40, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, + 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x69, 0x6e, + 0x62, 0x6f, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x05, + 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x22, 0x28, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, + 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x15, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x90, 0x03, 0x0a, 0x0c, 0x49, 0x6e, 0x62, 0x6f, 0x78, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6b, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x49, + 0x6e, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x12, 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x62, 0x6f, + 0x78, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x69, 0x6e, 0x62, + 0x6f, 0x78, 0x65, 0x73, 0x12, 0x95, 0x01, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, + 0x6e, 0x62, 0x6f, 0x78, 0x12, 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, + 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x41, 0xda, 0x41, 0x11, 0x69, 0x6e, + 0x62, 0x6f, 0x78, 0x2c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x3a, 0x05, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x32, 0x1e, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0x7b, 0x0a, 0x0b, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x12, 0x20, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x2e, 0xda, 0x41, 0x11, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x2c, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x3a, 0x05, 0x69, 0x6e, - 0x62, 0x6f, 0x78, 0x32, 0x0b, 0x2f, 0x76, 0x32, 0x2f, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x65, 0x73, - 0x12, 0x77, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x12, - 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x16, 0x2a, 0x14, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x69, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x27, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, + 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x2f, 0x2a, 0x7d, 0x42, 0xa9, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x11, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, diff --git a/proto/gen/api/v2/inbox_service.pb.gw.go b/proto/gen/api/v2/inbox_service.pb.gw.go index b8ca6f1efcf74..78b0cc350945b 100644 --- a/proto/gen/api/v2/inbox_service.pb.gw.go +++ b/proto/gen/api/v2/inbox_service.pb.gw.go @@ -68,7 +68,7 @@ func local_request_InboxService_ListInboxes_0(ctx context.Context, marshaler run } var ( - filter_InboxService_UpdateInbox_0 = &utilities.DoubleArray{Encoding: map[string]int{"inbox": 0}, Base: []int{1, 2, 0, 0}, Check: []int{0, 1, 2, 2}} + filter_InboxService_UpdateInbox_0 = &utilities.DoubleArray{Encoding: map[string]int{"inbox": 0, "name": 1}, Base: []int{1, 4, 5, 2, 0, 0, 0, 0}, Check: []int{0, 1, 1, 2, 4, 2, 2, 3}} ) func request_InboxService_UpdateInbox_0(ctx context.Context, marshaler runtime.Marshaler, client InboxServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -90,6 +90,23 @@ func request_InboxService_UpdateInbox_0(ctx context.Context, marshaler runtime.M } } + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["inbox.name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "inbox.name") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "inbox.name", val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "inbox.name", err) + } + if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -121,6 +138,23 @@ func local_request_InboxService_UpdateInbox_0(ctx context.Context, marshaler run } } + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["inbox.name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "inbox.name") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "inbox.name", val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "inbox.name", err) + } + if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -224,7 +258,7 @@ func RegisterInboxServiceHandlerServer(ctx context.Context, mux *runtime.ServeMu inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.InboxService/UpdateInbox", runtime.WithHTTPPathPattern("/v2/inboxes")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.InboxService/UpdateInbox", runtime.WithHTTPPathPattern("/api/v2/{inbox.name=inboxes/*}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -249,7 +283,7 @@ func RegisterInboxServiceHandlerServer(ctx context.Context, mux *runtime.ServeMu inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.InboxService/DeleteInbox", runtime.WithHTTPPathPattern("/v2/{name=inboxes/*}")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.InboxService/DeleteInbox", runtime.WithHTTPPathPattern("/api/v2/{name=inboxes/*}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -335,7 +369,7 @@ func RegisterInboxServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.InboxService/UpdateInbox", runtime.WithHTTPPathPattern("/v2/inboxes")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.InboxService/UpdateInbox", runtime.WithHTTPPathPattern("/api/v2/{inbox.name=inboxes/*}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -357,7 +391,7 @@ func RegisterInboxServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.InboxService/DeleteInbox", runtime.WithHTTPPathPattern("/v2/{name=inboxes/*}")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.InboxService/DeleteInbox", runtime.WithHTTPPathPattern("/api/v2/{name=inboxes/*}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -379,9 +413,9 @@ func RegisterInboxServiceHandlerClient(ctx context.Context, mux *runtime.ServeMu var ( pattern_InboxService_ListInboxes_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "inboxes"}, "")) - pattern_InboxService_UpdateInbox_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v2", "inboxes"}, "")) + pattern_InboxService_UpdateInbox_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v2", "inboxes", "inbox.name"}, "")) - pattern_InboxService_DeleteInbox_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 2, 5, 2}, []string{"v2", "inboxes", "name"}, "")) + pattern_InboxService_DeleteInbox_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v2", "inboxes", "name"}, "")) ) var ( diff --git a/proto/gen/api/v2/inbox_service_grpc.pb.go b/proto/gen/api/v2/inbox_service_grpc.pb.go index 806ae7ade8350..214addc419754 100644 --- a/proto/gen/api/v2/inbox_service_grpc.pb.go +++ b/proto/gen/api/v2/inbox_service_grpc.pb.go @@ -28,8 +28,11 @@ const ( // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type InboxServiceClient interface { + // ListInboxes lists inboxes for a user. ListInboxes(ctx context.Context, in *ListInboxesRequest, opts ...grpc.CallOption) (*ListInboxesResponse, error) + // UpdateInbox updates an inbox. UpdateInbox(ctx context.Context, in *UpdateInboxRequest, opts ...grpc.CallOption) (*UpdateInboxResponse, error) + // DeleteInbox deletes an inbox. DeleteInbox(ctx context.Context, in *DeleteInboxRequest, opts ...grpc.CallOption) (*DeleteInboxResponse, error) } @@ -72,8 +75,11 @@ func (c *inboxServiceClient) DeleteInbox(ctx context.Context, in *DeleteInboxReq // All implementations must embed UnimplementedInboxServiceServer // for forward compatibility type InboxServiceServer interface { + // ListInboxes lists inboxes for a user. ListInboxes(context.Context, *ListInboxesRequest) (*ListInboxesResponse, error) + // UpdateInbox updates an inbox. UpdateInbox(context.Context, *UpdateInboxRequest) (*UpdateInboxResponse, error) + // DeleteInbox deletes an inbox. DeleteInbox(context.Context, *DeleteInboxRequest) (*DeleteInboxResponse, error) mustEmbedUnimplementedInboxServiceServer() } diff --git a/proto/gen/api/v2/link_service.pb.go b/proto/gen/api/v2/link_service.pb.go new file mode 100644 index 0000000000000..f339c82cdd264 --- /dev/null +++ b/proto/gen/api/v2/link_service.pb.go @@ -0,0 +1,315 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: api/v2/link_service.proto + +package apiv2 + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type LinkMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Image string `protobuf:"bytes,3,opt,name=image,proto3" json:"image,omitempty"` +} + +func (x *LinkMetadata) Reset() { + *x = LinkMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_link_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinkMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinkMetadata) ProtoMessage() {} + +func (x *LinkMetadata) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_link_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinkMetadata.ProtoReflect.Descriptor instead. +func (*LinkMetadata) Descriptor() ([]byte, []int) { + return file_api_v2_link_service_proto_rawDescGZIP(), []int{0} +} + +func (x *LinkMetadata) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *LinkMetadata) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *LinkMetadata) GetImage() string { + if x != nil { + return x.Image + } + return "" +} + +type GetLinkMetadataRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Link string `protobuf:"bytes,1,opt,name=link,proto3" json:"link,omitempty"` +} + +func (x *GetLinkMetadataRequest) Reset() { + *x = GetLinkMetadataRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_link_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetLinkMetadataRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLinkMetadataRequest) ProtoMessage() {} + +func (x *GetLinkMetadataRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_link_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLinkMetadataRequest.ProtoReflect.Descriptor instead. +func (*GetLinkMetadataRequest) Descriptor() ([]byte, []int) { + return file_api_v2_link_service_proto_rawDescGZIP(), []int{1} +} + +func (x *GetLinkMetadataRequest) GetLink() string { + if x != nil { + return x.Link + } + return "" +} + +type GetLinkMetadataResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Metadata *LinkMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` +} + +func (x *GetLinkMetadataResponse) Reset() { + *x = GetLinkMetadataResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_link_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetLinkMetadataResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLinkMetadataResponse) ProtoMessage() {} + +func (x *GetLinkMetadataResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_link_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLinkMetadataResponse.ProtoReflect.Descriptor instead. +func (*GetLinkMetadataResponse) Descriptor() ([]byte, []int) { + return file_api_v2_link_service_proto_rawDescGZIP(), []int{2} +} + +func (x *GetLinkMetadataResponse) GetMetadata() *LinkMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +var File_api_v2_link_service_proto protoreflect.FileDescriptor + +var file_api_v2_link_service_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5c, 0x0a, 0x0c, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x2c, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, + 0x69, 0x6e, 0x6b, 0x22, 0x51, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, + 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, + 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x32, 0x87, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x78, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, + 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x24, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x25, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, + 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x42, 0xa8, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x10, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, + 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, + 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, + 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, + 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, + 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_api_v2_link_service_proto_rawDescOnce sync.Once + file_api_v2_link_service_proto_rawDescData = file_api_v2_link_service_proto_rawDesc +) + +func file_api_v2_link_service_proto_rawDescGZIP() []byte { + file_api_v2_link_service_proto_rawDescOnce.Do(func() { + file_api_v2_link_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_v2_link_service_proto_rawDescData) + }) + return file_api_v2_link_service_proto_rawDescData +} + +var file_api_v2_link_service_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_api_v2_link_service_proto_goTypes = []interface{}{ + (*LinkMetadata)(nil), // 0: memos.api.v2.LinkMetadata + (*GetLinkMetadataRequest)(nil), // 1: memos.api.v2.GetLinkMetadataRequest + (*GetLinkMetadataResponse)(nil), // 2: memos.api.v2.GetLinkMetadataResponse +} +var file_api_v2_link_service_proto_depIdxs = []int32{ + 0, // 0: memos.api.v2.GetLinkMetadataResponse.metadata:type_name -> memos.api.v2.LinkMetadata + 1, // 1: memos.api.v2.LinkService.GetLinkMetadata:input_type -> memos.api.v2.GetLinkMetadataRequest + 2, // 2: memos.api.v2.LinkService.GetLinkMetadata:output_type -> memos.api.v2.GetLinkMetadataResponse + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_api_v2_link_service_proto_init() } +func file_api_v2_link_service_proto_init() { + if File_api_v2_link_service_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_v2_link_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LinkMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_link_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetLinkMetadataRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_link_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetLinkMetadataResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_v2_link_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_api_v2_link_service_proto_goTypes, + DependencyIndexes: file_api_v2_link_service_proto_depIdxs, + MessageInfos: file_api_v2_link_service_proto_msgTypes, + }.Build() + File_api_v2_link_service_proto = out.File + file_api_v2_link_service_proto_rawDesc = nil + file_api_v2_link_service_proto_goTypes = nil + file_api_v2_link_service_proto_depIdxs = nil +} diff --git a/proto/gen/api/v2/link_service.pb.gw.go b/proto/gen/api/v2/link_service.pb.gw.go new file mode 100644 index 0000000000000..e9bed49136992 --- /dev/null +++ b/proto/gen/api/v2/link_service.pb.gw.go @@ -0,0 +1,173 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: api/v2/link_service.proto + +/* +Package apiv2 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package apiv2 + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +var ( + filter_LinkService_GetLinkMetadata_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_LinkService_GetLinkMetadata_0(ctx context.Context, marshaler runtime.Marshaler, client LinkServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetLinkMetadataRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_LinkService_GetLinkMetadata_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetLinkMetadata(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_LinkService_GetLinkMetadata_0(ctx context.Context, marshaler runtime.Marshaler, server LinkServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetLinkMetadataRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_LinkService_GetLinkMetadata_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetLinkMetadata(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterLinkServiceHandlerServer registers the http handlers for service LinkService to "mux". +// UnaryRPC :call LinkServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterLinkServiceHandlerFromEndpoint instead. +func RegisterLinkServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server LinkServiceServer) error { + + mux.Handle("GET", pattern_LinkService_GetLinkMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.LinkService/GetLinkMetadata", runtime.WithHTTPPathPattern("/api/v2/metadata")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_LinkService_GetLinkMetadata_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LinkService_GetLinkMetadata_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterLinkServiceHandlerFromEndpoint is same as RegisterLinkServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterLinkServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.DialContext(ctx, endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterLinkServiceHandler(ctx, mux, conn) +} + +// RegisterLinkServiceHandler registers the http handlers for service LinkService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterLinkServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterLinkServiceHandlerClient(ctx, mux, NewLinkServiceClient(conn)) +} + +// RegisterLinkServiceHandlerClient registers the http handlers for service LinkService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "LinkServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "LinkServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "LinkServiceClient" to call the correct interceptors. +func RegisterLinkServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client LinkServiceClient) error { + + mux.Handle("GET", pattern_LinkService_GetLinkMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.LinkService/GetLinkMetadata", runtime.WithHTTPPathPattern("/api/v2/metadata")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_LinkService_GetLinkMetadata_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_LinkService_GetLinkMetadata_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_LinkService_GetLinkMetadata_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "metadata"}, "")) +) + +var ( + forward_LinkService_GetLinkMetadata_0 = runtime.ForwardResponseMessage +) diff --git a/proto/gen/api/v2/link_service_grpc.pb.go b/proto/gen/api/v2/link_service_grpc.pb.go new file mode 100644 index 0000000000000..eab8cb2866e62 --- /dev/null +++ b/proto/gen/api/v2/link_service_grpc.pb.go @@ -0,0 +1,109 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: api/v2/link_service.proto + +package apiv2 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + LinkService_GetLinkMetadata_FullMethodName = "/memos.api.v2.LinkService/GetLinkMetadata" +) + +// LinkServiceClient is the client API for LinkService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type LinkServiceClient interface { + GetLinkMetadata(ctx context.Context, in *GetLinkMetadataRequest, opts ...grpc.CallOption) (*GetLinkMetadataResponse, error) +} + +type linkServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewLinkServiceClient(cc grpc.ClientConnInterface) LinkServiceClient { + return &linkServiceClient{cc} +} + +func (c *linkServiceClient) GetLinkMetadata(ctx context.Context, in *GetLinkMetadataRequest, opts ...grpc.CallOption) (*GetLinkMetadataResponse, error) { + out := new(GetLinkMetadataResponse) + err := c.cc.Invoke(ctx, LinkService_GetLinkMetadata_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// LinkServiceServer is the server API for LinkService service. +// All implementations must embed UnimplementedLinkServiceServer +// for forward compatibility +type LinkServiceServer interface { + GetLinkMetadata(context.Context, *GetLinkMetadataRequest) (*GetLinkMetadataResponse, error) + mustEmbedUnimplementedLinkServiceServer() +} + +// UnimplementedLinkServiceServer must be embedded to have forward compatible implementations. +type UnimplementedLinkServiceServer struct { +} + +func (UnimplementedLinkServiceServer) GetLinkMetadata(context.Context, *GetLinkMetadataRequest) (*GetLinkMetadataResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLinkMetadata not implemented") +} +func (UnimplementedLinkServiceServer) mustEmbedUnimplementedLinkServiceServer() {} + +// UnsafeLinkServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to LinkServiceServer will +// result in compilation errors. +type UnsafeLinkServiceServer interface { + mustEmbedUnimplementedLinkServiceServer() +} + +func RegisterLinkServiceServer(s grpc.ServiceRegistrar, srv LinkServiceServer) { + s.RegisterService(&LinkService_ServiceDesc, srv) +} + +func _LinkService_GetLinkMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetLinkMetadataRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(LinkServiceServer).GetLinkMetadata(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: LinkService_GetLinkMetadata_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(LinkServiceServer).GetLinkMetadata(ctx, req.(*GetLinkMetadataRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// LinkService_ServiceDesc is the grpc.ServiceDesc for LinkService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var LinkService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "memos.api.v2.LinkService", + HandlerType: (*LinkServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetLinkMetadata", + Handler: _LinkService_GetLinkMetadata_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api/v2/link_service.proto", +} diff --git a/proto/gen/api/v2/memo_relation_service.pb.go b/proto/gen/api/v2/memo_relation_service.pb.go new file mode 100644 index 0000000000000..28d0644dddcb1 --- /dev/null +++ b/proto/gen/api/v2/memo_relation_service.pb.go @@ -0,0 +1,232 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: api/v2/memo_relation_service.proto + +package apiv2 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type MemoRelation_Type int32 + +const ( + MemoRelation_TYPE_UNSPECIFIED MemoRelation_Type = 0 + MemoRelation_REFERENCE MemoRelation_Type = 1 + MemoRelation_COMMENT MemoRelation_Type = 2 +) + +// Enum value maps for MemoRelation_Type. +var ( + MemoRelation_Type_name = map[int32]string{ + 0: "TYPE_UNSPECIFIED", + 1: "REFERENCE", + 2: "COMMENT", + } + MemoRelation_Type_value = map[string]int32{ + "TYPE_UNSPECIFIED": 0, + "REFERENCE": 1, + "COMMENT": 2, + } +) + +func (x MemoRelation_Type) Enum() *MemoRelation_Type { + p := new(MemoRelation_Type) + *p = x + return p +} + +func (x MemoRelation_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (MemoRelation_Type) Descriptor() protoreflect.EnumDescriptor { + return file_api_v2_memo_relation_service_proto_enumTypes[0].Descriptor() +} + +func (MemoRelation_Type) Type() protoreflect.EnumType { + return &file_api_v2_memo_relation_service_proto_enumTypes[0] +} + +func (x MemoRelation_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use MemoRelation_Type.Descriptor instead. +func (MemoRelation_Type) EnumDescriptor() ([]byte, []int) { + return file_api_v2_memo_relation_service_proto_rawDescGZIP(), []int{0, 0} +} + +type MemoRelation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MemoId int32 `protobuf:"varint,1,opt,name=memo_id,json=memoId,proto3" json:"memo_id,omitempty"` + RelatedMemoId int32 `protobuf:"varint,2,opt,name=related_memo_id,json=relatedMemoId,proto3" json:"related_memo_id,omitempty"` + Type MemoRelation_Type `protobuf:"varint,3,opt,name=type,proto3,enum=memos.api.v2.MemoRelation_Type" json:"type,omitempty"` +} + +func (x *MemoRelation) Reset() { + *x = MemoRelation{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_relation_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MemoRelation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MemoRelation) ProtoMessage() {} + +func (x *MemoRelation) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_relation_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MemoRelation.ProtoReflect.Descriptor instead. +func (*MemoRelation) Descriptor() ([]byte, []int) { + return file_api_v2_memo_relation_service_proto_rawDescGZIP(), []int{0} +} + +func (x *MemoRelation) GetMemoId() int32 { + if x != nil { + return x.MemoId + } + return 0 +} + +func (x *MemoRelation) GetRelatedMemoId() int32 { + if x != nil { + return x.RelatedMemoId + } + return 0 +} + +func (x *MemoRelation) GetType() MemoRelation_Type { + if x != nil { + return x.Type + } + return MemoRelation_TYPE_UNSPECIFIED +} + +var File_api_v2_memo_relation_service_proto protoreflect.FileDescriptor + +var file_api_v2_memo_relation_service_proto_rawDesc = []byte{ + 0x0a, 0x22, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x72, 0x65, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x22, 0xbe, 0x01, 0x0a, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0f, + 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x65, + 0x6d, 0x6f, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x38, 0x0a, 0x04, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x45, 0x46, 0x45, 0x52, + 0x45, 0x4e, 0x43, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, + 0x54, 0x10, 0x02, 0x42, 0xb0, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, + 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, + 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, + 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, + 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, + 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, + 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_v2_memo_relation_service_proto_rawDescOnce sync.Once + file_api_v2_memo_relation_service_proto_rawDescData = file_api_v2_memo_relation_service_proto_rawDesc +) + +func file_api_v2_memo_relation_service_proto_rawDescGZIP() []byte { + file_api_v2_memo_relation_service_proto_rawDescOnce.Do(func() { + file_api_v2_memo_relation_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_v2_memo_relation_service_proto_rawDescData) + }) + return file_api_v2_memo_relation_service_proto_rawDescData +} + +var file_api_v2_memo_relation_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_api_v2_memo_relation_service_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_api_v2_memo_relation_service_proto_goTypes = []interface{}{ + (MemoRelation_Type)(0), // 0: memos.api.v2.MemoRelation.Type + (*MemoRelation)(nil), // 1: memos.api.v2.MemoRelation +} +var file_api_v2_memo_relation_service_proto_depIdxs = []int32{ + 0, // 0: memos.api.v2.MemoRelation.type:type_name -> memos.api.v2.MemoRelation.Type + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_api_v2_memo_relation_service_proto_init() } +func file_api_v2_memo_relation_service_proto_init() { + if File_api_v2_memo_relation_service_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_v2_memo_relation_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MemoRelation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_v2_memo_relation_service_proto_rawDesc, + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_v2_memo_relation_service_proto_goTypes, + DependencyIndexes: file_api_v2_memo_relation_service_proto_depIdxs, + EnumInfos: file_api_v2_memo_relation_service_proto_enumTypes, + MessageInfos: file_api_v2_memo_relation_service_proto_msgTypes, + }.Build() + File_api_v2_memo_relation_service_proto = out.File + file_api_v2_memo_relation_service_proto_rawDesc = nil + file_api_v2_memo_relation_service_proto_goTypes = nil + file_api_v2_memo_relation_service_proto_depIdxs = nil +} diff --git a/proto/gen/api/v2/memo_service.pb.go b/proto/gen/api/v2/memo_service.pb.go index adc62e788db2e..ec662e8e03ce1 100644 --- a/proto/gen/api/v2/memo_service.pb.go +++ b/proto/gen/api/v2/memo_service.pb.go @@ -10,6 +10,8 @@ import ( _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -78,14 +80,25 @@ type Memo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - RowStatus RowStatus `protobuf:"varint,2,opt,name=row_status,json=rowStatus,proto3,enum=memos.api.v2.RowStatus" json:"row_status,omitempty"` - CreatorId int32 `protobuf:"varint,3,opt,name=creator_id,json=creatorId,proto3" json:"creator_id,omitempty"` - CreatedTs int64 `protobuf:"varint,4,opt,name=created_ts,json=createdTs,proto3" json:"created_ts,omitempty"` - UpdatedTs int64 `protobuf:"varint,5,opt,name=updated_ts,json=updatedTs,proto3" json:"updated_ts,omitempty"` - Content string `protobuf:"bytes,6,opt,name=content,proto3" json:"content,omitempty"` - Visibility Visibility `protobuf:"varint,7,opt,name=visibility,proto3,enum=memos.api.v2.Visibility" json:"visibility,omitempty"` - Pinned bool `protobuf:"varint,8,opt,name=pinned,proto3" json:"pinned,omitempty"` + // id is the system generated unique identifier. + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // name is the user provided name. + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + RowStatus RowStatus `protobuf:"varint,3,opt,name=row_status,json=rowStatus,proto3,enum=memos.api.v2.RowStatus" json:"row_status,omitempty"` + // The name of the creator. + // Format: users/{username} + Creator string `protobuf:"bytes,4,opt,name=creator,proto3" json:"creator,omitempty"` + CreatorId int32 `protobuf:"varint,5,opt,name=creator_id,json=creatorId,proto3" json:"creator_id,omitempty"` + CreateTime *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` + UpdateTime *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` + DisplayTime *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=display_time,json=displayTime,proto3" json:"display_time,omitempty"` + Content string `protobuf:"bytes,9,opt,name=content,proto3" json:"content,omitempty"` + Visibility Visibility `protobuf:"varint,10,opt,name=visibility,proto3,enum=memos.api.v2.Visibility" json:"visibility,omitempty"` + Pinned bool `protobuf:"varint,11,opt,name=pinned,proto3" json:"pinned,omitempty"` + ParentId *int32 `protobuf:"varint,12,opt,name=parent_id,json=parentId,proto3,oneof" json:"parent_id,omitempty"` + Resources []*Resource `protobuf:"bytes,13,rep,name=resources,proto3" json:"resources,omitempty"` + Relations []*MemoRelation `protobuf:"bytes,14,rep,name=relations,proto3" json:"relations,omitempty"` + Reactions []*Reaction `protobuf:"bytes,15,rep,name=reactions,proto3" json:"reactions,omitempty"` } func (x *Memo) Reset() { @@ -127,6 +140,13 @@ func (x *Memo) GetId() int32 { return 0 } +func (x *Memo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + func (x *Memo) GetRowStatus() RowStatus { if x != nil { return x.RowStatus @@ -134,6 +154,13 @@ func (x *Memo) GetRowStatus() RowStatus { return RowStatus_ROW_STATUS_UNSPECIFIED } +func (x *Memo) GetCreator() string { + if x != nil { + return x.Creator + } + return "" +} + func (x *Memo) GetCreatorId() int32 { if x != nil { return x.CreatorId @@ -141,18 +168,25 @@ func (x *Memo) GetCreatorId() int32 { return 0 } -func (x *Memo) GetCreatedTs() int64 { +func (x *Memo) GetCreateTime() *timestamppb.Timestamp { if x != nil { - return x.CreatedTs + return x.CreateTime } - return 0 + return nil } -func (x *Memo) GetUpdatedTs() int64 { +func (x *Memo) GetUpdateTime() *timestamppb.Timestamp { if x != nil { - return x.UpdatedTs + return x.UpdateTime } - return 0 + return nil +} + +func (x *Memo) GetDisplayTime() *timestamppb.Timestamp { + if x != nil { + return x.DisplayTime + } + return nil } func (x *Memo) GetContent() string { @@ -176,6 +210,34 @@ func (x *Memo) GetPinned() bool { return false } +func (x *Memo) GetParentId() int32 { + if x != nil && x.ParentId != nil { + return *x.ParentId + } + return 0 +} + +func (x *Memo) GetResources() []*Resource { + if x != nil { + return x.Resources + } + return nil +} + +func (x *Memo) GetRelations() []*MemoRelation { + if x != nil { + return x.Relations + } + return nil +} + +func (x *Memo) GetReactions() []*Reaction { + if x != nil { + return x.Reactions + } + return nil +} + type CreateMemoRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -283,11 +345,14 @@ type ListMemosRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Page int32 `protobuf:"varint,1,opt,name=page,proto3" json:"page,omitempty"` - PageSize int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // The maximum number of memos to return. + PageSize int32 `protobuf:"varint,1,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"` + // A page token, received from a previous `ListMemos` call. + // Provide this to retrieve the subsequent page. + PageToken string `protobuf:"bytes,2,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"` // Filter is used to filter memos returned in the list. - Filter string `protobuf:"bytes,3,opt,name=filter,proto3" json:"filter,omitempty"` - CreatorId *int32 `protobuf:"varint,4,opt,name=creator_id,json=creatorId,proto3,oneof" json:"creator_id,omitempty"` + // Format: "creator == users/{username} && visibilities == ['PUBLIC', 'PROTECTED']" + Filter string `protobuf:"bytes,3,opt,name=filter,proto3" json:"filter,omitempty"` } func (x *ListMemosRequest) Reset() { @@ -322,18 +387,18 @@ func (*ListMemosRequest) Descriptor() ([]byte, []int) { return file_api_v2_memo_service_proto_rawDescGZIP(), []int{3} } -func (x *ListMemosRequest) GetPage() int32 { +func (x *ListMemosRequest) GetPageSize() int32 { if x != nil { - return x.Page + return x.PageSize } return 0 } -func (x *ListMemosRequest) GetPageSize() int32 { +func (x *ListMemosRequest) GetPageToken() string { if x != nil { - return x.PageSize + return x.PageToken } - return 0 + return "" } func (x *ListMemosRequest) GetFilter() string { @@ -343,19 +408,15 @@ func (x *ListMemosRequest) GetFilter() string { return "" } -func (x *ListMemosRequest) GetCreatorId() int32 { - if x != nil && x.CreatorId != nil { - return *x.CreatorId - } - return 0 -} - type ListMemosResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Memos []*Memo `protobuf:"bytes,1,rep,name=memos,proto3" json:"memos,omitempty"` + // A token, which can be sent as `page_token` to retrieve the next page. + // If this field is omitted, there are no subsequent pages. + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` } func (x *ListMemosResponse) Reset() { @@ -397,6 +458,13 @@ func (x *ListMemosResponse) GetMemos() []*Memo { return nil } +func (x *ListMemosResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + type GetMemoRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -491,18 +559,16 @@ func (x *GetMemoResponse) GetMemo() *Memo { return nil } -type CreateMemoCommentRequest struct { +type GetMemoByNameRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // id is the memo id to create comment for. - Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Create *CreateMemoRequest `protobuf:"bytes,2,opt,name=create,proto3" json:"create,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } -func (x *CreateMemoCommentRequest) Reset() { - *x = CreateMemoCommentRequest{} +func (x *GetMemoByNameRequest) Reset() { + *x = GetMemoByNameRequest{} if protoimpl.UnsafeEnabled { mi := &file_api_v2_memo_service_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -510,13 +576,13 @@ func (x *CreateMemoCommentRequest) Reset() { } } -func (x *CreateMemoCommentRequest) String() string { +func (x *GetMemoByNameRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CreateMemoCommentRequest) ProtoMessage() {} +func (*GetMemoByNameRequest) ProtoMessage() {} -func (x *CreateMemoCommentRequest) ProtoReflect() protoreflect.Message { +func (x *GetMemoByNameRequest) ProtoReflect() protoreflect.Message { mi := &file_api_v2_memo_service_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -528,26 +594,19 @@ func (x *CreateMemoCommentRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CreateMemoCommentRequest.ProtoReflect.Descriptor instead. -func (*CreateMemoCommentRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use GetMemoByNameRequest.ProtoReflect.Descriptor instead. +func (*GetMemoByNameRequest) Descriptor() ([]byte, []int) { return file_api_v2_memo_service_proto_rawDescGZIP(), []int{7} } -func (x *CreateMemoCommentRequest) GetId() int32 { - if x != nil { - return x.Id - } - return 0 -} - -func (x *CreateMemoCommentRequest) GetCreate() *CreateMemoRequest { +func (x *GetMemoByNameRequest) GetName() string { if x != nil { - return x.Create + return x.Name } - return nil + return "" } -type CreateMemoCommentResponse struct { +type GetMemoByNameResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -555,8 +614,8 @@ type CreateMemoCommentResponse struct { Memo *Memo `protobuf:"bytes,1,opt,name=memo,proto3" json:"memo,omitempty"` } -func (x *CreateMemoCommentResponse) Reset() { - *x = CreateMemoCommentResponse{} +func (x *GetMemoByNameResponse) Reset() { + *x = GetMemoByNameResponse{} if protoimpl.UnsafeEnabled { mi := &file_api_v2_memo_service_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -564,13 +623,13 @@ func (x *CreateMemoCommentResponse) Reset() { } } -func (x *CreateMemoCommentResponse) String() string { +func (x *GetMemoByNameResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CreateMemoCommentResponse) ProtoMessage() {} +func (*GetMemoByNameResponse) ProtoMessage() {} -func (x *CreateMemoCommentResponse) ProtoReflect() protoreflect.Message { +func (x *GetMemoByNameResponse) ProtoReflect() protoreflect.Message { mi := &file_api_v2_memo_service_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -582,28 +641,29 @@ func (x *CreateMemoCommentResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CreateMemoCommentResponse.ProtoReflect.Descriptor instead. -func (*CreateMemoCommentResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use GetMemoByNameResponse.ProtoReflect.Descriptor instead. +func (*GetMemoByNameResponse) Descriptor() ([]byte, []int) { return file_api_v2_memo_service_proto_rawDescGZIP(), []int{8} } -func (x *CreateMemoCommentResponse) GetMemo() *Memo { +func (x *GetMemoByNameResponse) GetMemo() *Memo { if x != nil { return x.Memo } return nil } -type ListMemoCommentsRequest struct { +type UpdateMemoRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Memo *Memo `protobuf:"bytes,1,opt,name=memo,proto3" json:"memo,omitempty"` + UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` } -func (x *ListMemoCommentsRequest) Reset() { - *x = ListMemoCommentsRequest{} +func (x *UpdateMemoRequest) Reset() { + *x = UpdateMemoRequest{} if protoimpl.UnsafeEnabled { mi := &file_api_v2_memo_service_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -611,13 +671,13 @@ func (x *ListMemoCommentsRequest) Reset() { } } -func (x *ListMemoCommentsRequest) String() string { +func (x *UpdateMemoRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListMemoCommentsRequest) ProtoMessage() {} +func (*UpdateMemoRequest) ProtoMessage() {} -func (x *ListMemoCommentsRequest) ProtoReflect() protoreflect.Message { +func (x *UpdateMemoRequest) ProtoReflect() protoreflect.Message { mi := &file_api_v2_memo_service_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -629,28 +689,35 @@ func (x *ListMemoCommentsRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListMemoCommentsRequest.ProtoReflect.Descriptor instead. -func (*ListMemoCommentsRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use UpdateMemoRequest.ProtoReflect.Descriptor instead. +func (*UpdateMemoRequest) Descriptor() ([]byte, []int) { return file_api_v2_memo_service_proto_rawDescGZIP(), []int{9} } -func (x *ListMemoCommentsRequest) GetId() int32 { +func (x *UpdateMemoRequest) GetMemo() *Memo { if x != nil { - return x.Id + return x.Memo } - return 0 + return nil } -type ListMemoCommentsResponse struct { +func (x *UpdateMemoRequest) GetUpdateMask() *fieldmaskpb.FieldMask { + if x != nil { + return x.UpdateMask + } + return nil +} + +type UpdateMemoResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Memos []*Memo `protobuf:"bytes,1,rep,name=memos,proto3" json:"memos,omitempty"` + Memo *Memo `protobuf:"bytes,1,opt,name=memo,proto3" json:"memo,omitempty"` } -func (x *ListMemoCommentsResponse) Reset() { - *x = ListMemoCommentsResponse{} +func (x *UpdateMemoResponse) Reset() { + *x = UpdateMemoResponse{} if protoimpl.UnsafeEnabled { mi := &file_api_v2_memo_service_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -658,13 +725,13 @@ func (x *ListMemoCommentsResponse) Reset() { } } -func (x *ListMemoCommentsResponse) String() string { +func (x *UpdateMemoResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListMemoCommentsResponse) ProtoMessage() {} +func (*UpdateMemoResponse) ProtoMessage() {} -func (x *ListMemoCommentsResponse) ProtoReflect() protoreflect.Message { +func (x *UpdateMemoResponse) ProtoReflect() protoreflect.Message { mi := &file_api_v2_memo_service_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -676,246 +743,1725 @@ func (x *ListMemoCommentsResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListMemoCommentsResponse.ProtoReflect.Descriptor instead. -func (*ListMemoCommentsResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use UpdateMemoResponse.ProtoReflect.Descriptor instead. +func (*UpdateMemoResponse) Descriptor() ([]byte, []int) { return file_api_v2_memo_service_proto_rawDescGZIP(), []int{10} } -func (x *ListMemoCommentsResponse) GetMemos() []*Memo { +func (x *UpdateMemoResponse) GetMemo() *Memo { if x != nil { - return x.Memos + return x.Memo } return nil } -var File_api_v2_memo_service_proto protoreflect.FileDescriptor +type DeleteMemoRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -var file_api_v2_memo_service_proto_rawDesc = []byte{ - 0x0a, 0x19, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x6d, 0x65, 0x6d, - 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x13, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x97, 0x02, 0x0a, 0x04, 0x4d, 0x65, 0x6d, 0x6f, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x36, - 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, - 0x32, 0x2e, 0x52, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x72, 0x6f, 0x77, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, - 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x54, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x64, 0x54, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, - 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x18, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, - 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, - 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x69, 0x6e, 0x6e, 0x65, - 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x22, - 0x67, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x38, - 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, - 0x32, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, - 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x3c, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, - 0x0a, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, - 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, - 0x52, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x22, 0x8e, 0x01, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4d, - 0x65, 0x6d, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, - 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x70, 0x61, 0x67, 0x65, 0x12, - 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x16, 0x0a, 0x06, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x5f, - 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x6f, 0x72, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x22, 0x3d, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x4d, - 0x65, 0x6d, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, - 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, - 0x05, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x22, 0x20, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, - 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x39, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4d, - 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x6d, - 0x65, 0x6d, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, - 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x04, 0x6d, - 0x65, 0x6d, 0x6f, 0x22, 0x63, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, - 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x37, 0x0a, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x52, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x22, 0x43, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x22, 0x29, 0x0a, - 0x17, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x44, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x05, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2a, 0x50, - 0x0a, 0x0a, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x16, - 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, 0x49, 0x56, - 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x52, 0x4f, 0x54, 0x45, 0x43, 0x54, - 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x03, - 0x32, 0xe2, 0x04, 0x0a, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x66, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x12, 0x1f, - 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x22, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x12, 0x63, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x12, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x12, 0x67, 0x0a, - 0x07, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x12, 0x1c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x14, 0x12, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, - 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x8e, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x26, 0x2e, 0x6d, - 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, - 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0xda, - 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x1b, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x63, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x8b, 0x01, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x25, 0x2e, 0x6d, - 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0xda, 0x41, 0x02, - 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6d, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, 0xa8, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, - 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x10, 0x4d, 0x65, 0x6d, 0x6f, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, - 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, - 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, - 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, - 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, - 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, - 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` } -var ( - file_api_v2_memo_service_proto_rawDescOnce sync.Once - file_api_v2_memo_service_proto_rawDescData = file_api_v2_memo_service_proto_rawDesc -) +func (x *DeleteMemoRequest) Reset() { + *x = DeleteMemoRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} -func file_api_v2_memo_service_proto_rawDescGZIP() []byte { - file_api_v2_memo_service_proto_rawDescOnce.Do(func() { - file_api_v2_memo_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_v2_memo_service_proto_rawDescData) - }) - return file_api_v2_memo_service_proto_rawDescData +func (x *DeleteMemoRequest) String() string { + return protoimpl.X.MessageStringOf(x) } -var file_api_v2_memo_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_api_v2_memo_service_proto_msgTypes = make([]protoimpl.MessageInfo, 11) -var file_api_v2_memo_service_proto_goTypes = []interface{}{ - (Visibility)(0), // 0: memos.api.v2.Visibility - (*Memo)(nil), // 1: memos.api.v2.Memo - (*CreateMemoRequest)(nil), // 2: memos.api.v2.CreateMemoRequest - (*CreateMemoResponse)(nil), // 3: memos.api.v2.CreateMemoResponse - (*ListMemosRequest)(nil), // 4: memos.api.v2.ListMemosRequest - (*ListMemosResponse)(nil), // 5: memos.api.v2.ListMemosResponse - (*GetMemoRequest)(nil), // 6: memos.api.v2.GetMemoRequest - (*GetMemoResponse)(nil), // 7: memos.api.v2.GetMemoResponse - (*CreateMemoCommentRequest)(nil), // 8: memos.api.v2.CreateMemoCommentRequest - (*CreateMemoCommentResponse)(nil), // 9: memos.api.v2.CreateMemoCommentResponse - (*ListMemoCommentsRequest)(nil), // 10: memos.api.v2.ListMemoCommentsRequest - (*ListMemoCommentsResponse)(nil), // 11: memos.api.v2.ListMemoCommentsResponse - (RowStatus)(0), // 12: memos.api.v2.RowStatus +func (*DeleteMemoRequest) ProtoMessage() {} + +func (x *DeleteMemoRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var file_api_v2_memo_service_proto_depIdxs = []int32{ - 12, // 0: memos.api.v2.Memo.row_status:type_name -> memos.api.v2.RowStatus - 0, // 1: memos.api.v2.Memo.visibility:type_name -> memos.api.v2.Visibility - 0, // 2: memos.api.v2.CreateMemoRequest.visibility:type_name -> memos.api.v2.Visibility - 1, // 3: memos.api.v2.CreateMemoResponse.memo:type_name -> memos.api.v2.Memo - 1, // 4: memos.api.v2.ListMemosResponse.memos:type_name -> memos.api.v2.Memo - 1, // 5: memos.api.v2.GetMemoResponse.memo:type_name -> memos.api.v2.Memo - 2, // 6: memos.api.v2.CreateMemoCommentRequest.create:type_name -> memos.api.v2.CreateMemoRequest - 1, // 7: memos.api.v2.CreateMemoCommentResponse.memo:type_name -> memos.api.v2.Memo - 1, // 8: memos.api.v2.ListMemoCommentsResponse.memos:type_name -> memos.api.v2.Memo - 2, // 9: memos.api.v2.MemoService.CreateMemo:input_type -> memos.api.v2.CreateMemoRequest - 4, // 10: memos.api.v2.MemoService.ListMemos:input_type -> memos.api.v2.ListMemosRequest - 6, // 11: memos.api.v2.MemoService.GetMemo:input_type -> memos.api.v2.GetMemoRequest - 8, // 12: memos.api.v2.MemoService.CreateMemoComment:input_type -> memos.api.v2.CreateMemoCommentRequest - 10, // 13: memos.api.v2.MemoService.ListMemoComments:input_type -> memos.api.v2.ListMemoCommentsRequest - 3, // 14: memos.api.v2.MemoService.CreateMemo:output_type -> memos.api.v2.CreateMemoResponse - 5, // 15: memos.api.v2.MemoService.ListMemos:output_type -> memos.api.v2.ListMemosResponse - 7, // 16: memos.api.v2.MemoService.GetMemo:output_type -> memos.api.v2.GetMemoResponse - 9, // 17: memos.api.v2.MemoService.CreateMemoComment:output_type -> memos.api.v2.CreateMemoCommentResponse - 11, // 18: memos.api.v2.MemoService.ListMemoComments:output_type -> memos.api.v2.ListMemoCommentsResponse - 14, // [14:19] is the sub-list for method output_type - 9, // [9:14] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + +// Deprecated: Use DeleteMemoRequest.ProtoReflect.Descriptor instead. +func (*DeleteMemoRequest) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{11} } -func init() { file_api_v2_memo_service_proto_init() } -func file_api_v2_memo_service_proto_init() { - if File_api_v2_memo_service_proto != nil { - return +func (x *DeleteMemoRequest) GetId() int32 { + if x != nil { + return x.Id } - file_api_v2_common_proto_init() - if !protoimpl.UnsafeEnabled { - file_api_v2_memo_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Memo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } + return 0 +} + +type DeleteMemoResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteMemoResponse) Reset() { + *x = DeleteMemoResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteMemoResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteMemoResponse) ProtoMessage() {} + +func (x *DeleteMemoResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) } - file_api_v2_memo_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateMemoRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteMemoResponse.ProtoReflect.Descriptor instead. +func (*DeleteMemoResponse) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{12} +} + +type ExportMemosRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Same as ListMemosRequest.filter + Filter string `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` +} + +func (x *ExportMemosRequest) Reset() { + *x = ExportMemosRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExportMemosRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExportMemosRequest) ProtoMessage() {} + +func (x *ExportMemosRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) } - file_api_v2_memo_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateMemoResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExportMemosRequest.ProtoReflect.Descriptor instead. +func (*ExportMemosRequest) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{13} +} + +func (x *ExportMemosRequest) GetFilter() string { + if x != nil { + return x.Filter + } + return "" +} + +type ExportMemosResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Content []byte `protobuf:"bytes,1,opt,name=content,proto3" json:"content,omitempty"` +} + +func (x *ExportMemosResponse) Reset() { + *x = ExportMemosResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExportMemosResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExportMemosResponse) ProtoMessage() {} + +func (x *ExportMemosResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExportMemosResponse.ProtoReflect.Descriptor instead. +func (*ExportMemosResponse) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{14} +} + +func (x *ExportMemosResponse) GetContent() []byte { + if x != nil { + return x.Content + } + return nil +} + +type SetMemoResourcesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Resources []*Resource `protobuf:"bytes,2,rep,name=resources,proto3" json:"resources,omitempty"` +} + +func (x *SetMemoResourcesRequest) Reset() { + *x = SetMemoResourcesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetMemoResourcesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetMemoResourcesRequest) ProtoMessage() {} + +func (x *SetMemoResourcesRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetMemoResourcesRequest.ProtoReflect.Descriptor instead. +func (*SetMemoResourcesRequest) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{15} +} + +func (x *SetMemoResourcesRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *SetMemoResourcesRequest) GetResources() []*Resource { + if x != nil { + return x.Resources + } + return nil +} + +type SetMemoResourcesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SetMemoResourcesResponse) Reset() { + *x = SetMemoResourcesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetMemoResourcesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetMemoResourcesResponse) ProtoMessage() {} + +func (x *SetMemoResourcesResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetMemoResourcesResponse.ProtoReflect.Descriptor instead. +func (*SetMemoResourcesResponse) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{16} +} + +type ListMemoResourcesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *ListMemoResourcesRequest) Reset() { + *x = ListMemoResourcesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListMemoResourcesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListMemoResourcesRequest) ProtoMessage() {} + +func (x *ListMemoResourcesRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListMemoResourcesRequest.ProtoReflect.Descriptor instead. +func (*ListMemoResourcesRequest) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{17} +} + +func (x *ListMemoResourcesRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +type ListMemoResourcesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Resources []*Resource `protobuf:"bytes,1,rep,name=resources,proto3" json:"resources,omitempty"` +} + +func (x *ListMemoResourcesResponse) Reset() { + *x = ListMemoResourcesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListMemoResourcesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListMemoResourcesResponse) ProtoMessage() {} + +func (x *ListMemoResourcesResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListMemoResourcesResponse.ProtoReflect.Descriptor instead. +func (*ListMemoResourcesResponse) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{18} +} + +func (x *ListMemoResourcesResponse) GetResources() []*Resource { + if x != nil { + return x.Resources + } + return nil +} + +type SetMemoRelationsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Relations []*MemoRelation `protobuf:"bytes,2,rep,name=relations,proto3" json:"relations,omitempty"` +} + +func (x *SetMemoRelationsRequest) Reset() { + *x = SetMemoRelationsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetMemoRelationsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetMemoRelationsRequest) ProtoMessage() {} + +func (x *SetMemoRelationsRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetMemoRelationsRequest.ProtoReflect.Descriptor instead. +func (*SetMemoRelationsRequest) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{19} +} + +func (x *SetMemoRelationsRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *SetMemoRelationsRequest) GetRelations() []*MemoRelation { + if x != nil { + return x.Relations + } + return nil +} + +type SetMemoRelationsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SetMemoRelationsResponse) Reset() { + *x = SetMemoRelationsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetMemoRelationsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetMemoRelationsResponse) ProtoMessage() {} + +func (x *SetMemoRelationsResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetMemoRelationsResponse.ProtoReflect.Descriptor instead. +func (*SetMemoRelationsResponse) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{20} +} + +type ListMemoRelationsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *ListMemoRelationsRequest) Reset() { + *x = ListMemoRelationsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListMemoRelationsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListMemoRelationsRequest) ProtoMessage() {} + +func (x *ListMemoRelationsRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListMemoRelationsRequest.ProtoReflect.Descriptor instead. +func (*ListMemoRelationsRequest) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{21} +} + +func (x *ListMemoRelationsRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +type ListMemoRelationsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Relations []*MemoRelation `protobuf:"bytes,1,rep,name=relations,proto3" json:"relations,omitempty"` +} + +func (x *ListMemoRelationsResponse) Reset() { + *x = ListMemoRelationsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListMemoRelationsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListMemoRelationsResponse) ProtoMessage() {} + +func (x *ListMemoRelationsResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListMemoRelationsResponse.ProtoReflect.Descriptor instead. +func (*ListMemoRelationsResponse) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{22} +} + +func (x *ListMemoRelationsResponse) GetRelations() []*MemoRelation { + if x != nil { + return x.Relations + } + return nil +} + +type CreateMemoCommentRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // id is the memo id to create comment for. + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Create *CreateMemoRequest `protobuf:"bytes,2,opt,name=create,proto3" json:"create,omitempty"` +} + +func (x *CreateMemoCommentRequest) Reset() { + *x = CreateMemoCommentRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateMemoCommentRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateMemoCommentRequest) ProtoMessage() {} + +func (x *CreateMemoCommentRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateMemoCommentRequest.ProtoReflect.Descriptor instead. +func (*CreateMemoCommentRequest) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{23} +} + +func (x *CreateMemoCommentRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *CreateMemoCommentRequest) GetCreate() *CreateMemoRequest { + if x != nil { + return x.Create + } + return nil +} + +type CreateMemoCommentResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Memo *Memo `protobuf:"bytes,1,opt,name=memo,proto3" json:"memo,omitempty"` +} + +func (x *CreateMemoCommentResponse) Reset() { + *x = CreateMemoCommentResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateMemoCommentResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateMemoCommentResponse) ProtoMessage() {} + +func (x *CreateMemoCommentResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateMemoCommentResponse.ProtoReflect.Descriptor instead. +func (*CreateMemoCommentResponse) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{24} +} + +func (x *CreateMemoCommentResponse) GetMemo() *Memo { + if x != nil { + return x.Memo + } + return nil +} + +type ListMemoCommentsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *ListMemoCommentsRequest) Reset() { + *x = ListMemoCommentsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListMemoCommentsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListMemoCommentsRequest) ProtoMessage() {} + +func (x *ListMemoCommentsRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListMemoCommentsRequest.ProtoReflect.Descriptor instead. +func (*ListMemoCommentsRequest) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{25} +} + +func (x *ListMemoCommentsRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +type ListMemoCommentsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Memos []*Memo `protobuf:"bytes,1,rep,name=memos,proto3" json:"memos,omitempty"` +} + +func (x *ListMemoCommentsResponse) Reset() { + *x = ListMemoCommentsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListMemoCommentsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListMemoCommentsResponse) ProtoMessage() {} + +func (x *ListMemoCommentsResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListMemoCommentsResponse.ProtoReflect.Descriptor instead. +func (*ListMemoCommentsResponse) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{26} +} + +func (x *ListMemoCommentsResponse) GetMemos() []*Memo { + if x != nil { + return x.Memos + } + return nil +} + +type GetUserMemosStatsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the name of the user to get stats for. + // Format: users/{username} + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // timezone location + // Format: uses tz identifier + // https://en.wikipedia.org/wiki/List_of_tz_database_time_zones + Timezone string `protobuf:"bytes,2,opt,name=timezone,proto3" json:"timezone,omitempty"` + // Same as ListMemosRequest.filter + Filter string `protobuf:"bytes,3,opt,name=filter,proto3" json:"filter,omitempty"` +} + +func (x *GetUserMemosStatsRequest) Reset() { + *x = GetUserMemosStatsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetUserMemosStatsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserMemosStatsRequest) ProtoMessage() {} + +func (x *GetUserMemosStatsRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserMemosStatsRequest.ProtoReflect.Descriptor instead. +func (*GetUserMemosStatsRequest) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{27} +} + +func (x *GetUserMemosStatsRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *GetUserMemosStatsRequest) GetTimezone() string { + if x != nil { + return x.Timezone + } + return "" +} + +func (x *GetUserMemosStatsRequest) GetFilter() string { + if x != nil { + return x.Filter + } + return "" +} + +type GetUserMemosStatsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // stats is the stats of memo creating/updating activities. + // key is the year-month-day string. e.g. "2020-01-01". + Stats map[string]int32 `protobuf:"bytes,1,rep,name=stats,proto3" json:"stats,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` +} + +func (x *GetUserMemosStatsResponse) Reset() { + *x = GetUserMemosStatsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetUserMemosStatsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetUserMemosStatsResponse) ProtoMessage() {} + +func (x *GetUserMemosStatsResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetUserMemosStatsResponse.ProtoReflect.Descriptor instead. +func (*GetUserMemosStatsResponse) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{28} +} + +func (x *GetUserMemosStatsResponse) GetStats() map[string]int32 { + if x != nil { + return x.Stats + } + return nil +} + +type ListMemoReactionsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *ListMemoReactionsRequest) Reset() { + *x = ListMemoReactionsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListMemoReactionsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListMemoReactionsRequest) ProtoMessage() {} + +func (x *ListMemoReactionsRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListMemoReactionsRequest.ProtoReflect.Descriptor instead. +func (*ListMemoReactionsRequest) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{29} +} + +func (x *ListMemoReactionsRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +type ListMemoReactionsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Reactions []*Reaction `protobuf:"bytes,1,rep,name=reactions,proto3" json:"reactions,omitempty"` +} + +func (x *ListMemoReactionsResponse) Reset() { + *x = ListMemoReactionsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListMemoReactionsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListMemoReactionsResponse) ProtoMessage() {} + +func (x *ListMemoReactionsResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListMemoReactionsResponse.ProtoReflect.Descriptor instead. +func (*ListMemoReactionsResponse) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{30} +} + +func (x *ListMemoReactionsResponse) GetReactions() []*Reaction { + if x != nil { + return x.Reactions + } + return nil +} + +type UpsertMemoReactionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Reaction *Reaction `protobuf:"bytes,2,opt,name=reaction,proto3" json:"reaction,omitempty"` +} + +func (x *UpsertMemoReactionRequest) Reset() { + *x = UpsertMemoReactionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpsertMemoReactionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpsertMemoReactionRequest) ProtoMessage() {} + +func (x *UpsertMemoReactionRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpsertMemoReactionRequest.ProtoReflect.Descriptor instead. +func (*UpsertMemoReactionRequest) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{31} +} + +func (x *UpsertMemoReactionRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *UpsertMemoReactionRequest) GetReaction() *Reaction { + if x != nil { + return x.Reaction + } + return nil +} + +type UpsertMemoReactionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Reaction *Reaction `protobuf:"bytes,1,opt,name=reaction,proto3" json:"reaction,omitempty"` +} + +func (x *UpsertMemoReactionResponse) Reset() { + *x = UpsertMemoReactionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpsertMemoReactionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpsertMemoReactionResponse) ProtoMessage() {} + +func (x *UpsertMemoReactionResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpsertMemoReactionResponse.ProtoReflect.Descriptor instead. +func (*UpsertMemoReactionResponse) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{32} +} + +func (x *UpsertMemoReactionResponse) GetReaction() *Reaction { + if x != nil { + return x.Reaction + } + return nil +} + +type DeleteMemoReactionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + ReactionId int32 `protobuf:"varint,2,opt,name=reaction_id,json=reactionId,proto3" json:"reaction_id,omitempty"` +} + +func (x *DeleteMemoReactionRequest) Reset() { + *x = DeleteMemoReactionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteMemoReactionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteMemoReactionRequest) ProtoMessage() {} + +func (x *DeleteMemoReactionRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteMemoReactionRequest.ProtoReflect.Descriptor instead. +func (*DeleteMemoReactionRequest) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{33} +} + +func (x *DeleteMemoReactionRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *DeleteMemoReactionRequest) GetReactionId() int32 { + if x != nil { + return x.ReactionId + } + return 0 +} + +type DeleteMemoReactionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteMemoReactionResponse) Reset() { + *x = DeleteMemoReactionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_memo_service_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteMemoReactionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteMemoReactionResponse) ProtoMessage() {} + +func (x *DeleteMemoReactionResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_memo_service_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteMemoReactionResponse.ProtoReflect.Descriptor instead. +func (*DeleteMemoReactionResponse) Descriptor() ([]byte, []int) { + return file_api_v2_memo_service_proto_rawDescGZIP(), []int{34} +} + +var File_api_v2_memo_service_proto protoreflect.FileDescriptor + +var file_api_v2_memo_service_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x13, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x1d, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1d, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, + 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, + 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xaa, 0x05, 0x0a, 0x04, + 0x4d, 0x65, 0x6d, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6d, + 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x6f, 0x77, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x72, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x0b, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, + 0x69, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x0a, + 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x18, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, + 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x12, 0x25, + 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x05, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x48, 0x00, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x39, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x12, 0x3d, 0x0a, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, + 0x03, 0xe0, 0x41, 0x03, 0x52, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x39, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0f, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x32, 0x2e, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x03, 0xe0, 0x41, 0x03, 0x52, + 0x09, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x22, 0x67, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, + 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x22, 0x3c, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x22, + 0x66, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, + 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, + 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x65, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x6d, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, + 0x05, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, + 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x20, + 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, + 0x22, 0x39, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x22, 0x2a, 0x0a, 0x14, 0x47, + 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3f, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x4d, 0x65, + 0x6d, 0x6f, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x26, 0x0a, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, + 0x6d, 0x6f, 0x52, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x22, 0x78, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, + 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, + 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, + 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, + 0x73, 0x6b, 0x22, 0x3c, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x6d, 0x65, 0x6d, 0x6f, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x04, 0x6d, 0x65, 0x6d, 0x6f, + 0x22, 0x23, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, + 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x0a, 0x12, 0x45, + 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x2f, 0x0a, 0x13, 0x45, 0x78, 0x70, + 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x5f, 0x0a, 0x17, 0x53, 0x65, + 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x34, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x1a, 0x0a, 0x18, 0x53, + 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x02, 0x69, 0x64, 0x22, 0x51, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x34, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x63, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x6d, + 0x6f, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x38, 0x0a, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x1a, 0x0a, 0x18, 0x53, + 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x02, 0x69, 0x64, 0x22, 0x55, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x38, 0x0a, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x63, 0x0a, 0x18, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x37, 0x0a, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x22, + 0x43, 0x0a, 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, + 0x6d, 0x65, 0x6d, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x04, + 0x6d, 0x65, 0x6d, 0x6f, 0x22, 0x29, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, + 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, + 0x44, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x6d, + 0x65, 0x6d, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x05, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x22, 0x62, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, + 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x9f, 0x01, 0x0a, 0x19, 0x47, 0x65, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x6d, + 0x6f, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x73, 0x1a, 0x38, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2a, 0x0a, 0x18, 0x4c, + 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x51, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x09, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x5f, 0x0a, 0x19, 0x55, 0x70, + 0x73, 0x65, 0x72, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x08, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0x0a, 0x1a, 0x55, + 0x70, 0x73, 0x65, 0x72, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x4c, 0x0a, + 0x19, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0a, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x1c, 0x0a, 0x1a, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x50, 0x0a, 0x0a, 0x56, 0x69, 0x73, + 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x49, 0x53, 0x49, 0x42, + 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x01, + 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x52, 0x4f, 0x54, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, + 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x03, 0x32, 0x87, 0x12, 0x0a, 0x0b, + 0x4d, 0x65, 0x6d, 0x6f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x69, 0x0a, 0x0a, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x12, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, + 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, + 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x12, 0x63, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, + 0x6d, 0x6f, 0x73, 0x12, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x12, 0x67, 0x0a, 0x07, 0x47, + 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x12, 0x1c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x1f, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, + 0x12, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, + 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x82, 0x01, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, + 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x42, 0x79, 0x4e, + 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, + 0x6f, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x28, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6e, 0x61, + 0x6d, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0x89, 0x01, 0x0a, 0x0a, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x12, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, + 0x6d, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, + 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0xda, 0x41, 0x10, + 0x6d, 0x65, 0x6d, 0x6f, 0x2c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x32, 0x17, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x6d, + 0x6f, 0x2e, 0x69, 0x64, 0x7d, 0x12, 0x70, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, + 0x65, 0x6d, 0x6f, 0x12, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x14, 0x2a, 0x12, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x70, 0x0a, 0x0b, 0x45, 0x78, 0x70, 0x6f, 0x72, + 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x12, 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x6d, 0x6f, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x65, + 0x6d, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x16, 0x22, 0x14, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x3a, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x8f, 0x01, 0x0a, 0x10, 0x53, 0x65, + 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x25, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, + 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0xda, + 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x01, 0x2a, 0x22, 0x1c, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, + 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x8f, 0x01, 0x0a, 0x11, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x12, 0x26, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, + 0x6f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x29, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12, + 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x7b, + 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x8f, 0x01, + 0x0a, 0x10, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x25, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x32, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x6f, + 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x2c, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x01, + 0x2a, 0x22, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x8f, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x8e, 0x01, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, + 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x26, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, + 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x27, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x22, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, + 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x12, 0x8b, 0x01, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x43, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x25, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x43, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x12, 0x8c, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x6d, 0x6f, + 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x6d, + 0x6f, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0xda, 0x41, 0x08, 0x75, 0x73, 0x65, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x12, + 0x8f, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x92, 0x01, 0x0a, 0x12, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x4d, 0x65, 0x6d, 0x6f, + 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x4d, 0x65, + 0x6d, 0x6f, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x28, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0xda, 0x41, 0x02, + 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x22, 0x1c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, + 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xac, 0x01, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x6f, + 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x43, 0xda, 0x41, 0x0e, 0x69, 0x64, 0x2c, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x2a, 0x2a, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x76, 0x32, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x42, 0xa8, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x10, 0x4d, 0x65, 0x6d, 0x6f, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, + 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, + 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, + 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, + 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_v2_memo_service_proto_rawDescOnce sync.Once + file_api_v2_memo_service_proto_rawDescData = file_api_v2_memo_service_proto_rawDesc +) + +func file_api_v2_memo_service_proto_rawDescGZIP() []byte { + file_api_v2_memo_service_proto_rawDescOnce.Do(func() { + file_api_v2_memo_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_v2_memo_service_proto_rawDescData) + }) + return file_api_v2_memo_service_proto_rawDescData +} + +var file_api_v2_memo_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_api_v2_memo_service_proto_msgTypes = make([]protoimpl.MessageInfo, 36) +var file_api_v2_memo_service_proto_goTypes = []interface{}{ + (Visibility)(0), // 0: memos.api.v2.Visibility + (*Memo)(nil), // 1: memos.api.v2.Memo + (*CreateMemoRequest)(nil), // 2: memos.api.v2.CreateMemoRequest + (*CreateMemoResponse)(nil), // 3: memos.api.v2.CreateMemoResponse + (*ListMemosRequest)(nil), // 4: memos.api.v2.ListMemosRequest + (*ListMemosResponse)(nil), // 5: memos.api.v2.ListMemosResponse + (*GetMemoRequest)(nil), // 6: memos.api.v2.GetMemoRequest + (*GetMemoResponse)(nil), // 7: memos.api.v2.GetMemoResponse + (*GetMemoByNameRequest)(nil), // 8: memos.api.v2.GetMemoByNameRequest + (*GetMemoByNameResponse)(nil), // 9: memos.api.v2.GetMemoByNameResponse + (*UpdateMemoRequest)(nil), // 10: memos.api.v2.UpdateMemoRequest + (*UpdateMemoResponse)(nil), // 11: memos.api.v2.UpdateMemoResponse + (*DeleteMemoRequest)(nil), // 12: memos.api.v2.DeleteMemoRequest + (*DeleteMemoResponse)(nil), // 13: memos.api.v2.DeleteMemoResponse + (*ExportMemosRequest)(nil), // 14: memos.api.v2.ExportMemosRequest + (*ExportMemosResponse)(nil), // 15: memos.api.v2.ExportMemosResponse + (*SetMemoResourcesRequest)(nil), // 16: memos.api.v2.SetMemoResourcesRequest + (*SetMemoResourcesResponse)(nil), // 17: memos.api.v2.SetMemoResourcesResponse + (*ListMemoResourcesRequest)(nil), // 18: memos.api.v2.ListMemoResourcesRequest + (*ListMemoResourcesResponse)(nil), // 19: memos.api.v2.ListMemoResourcesResponse + (*SetMemoRelationsRequest)(nil), // 20: memos.api.v2.SetMemoRelationsRequest + (*SetMemoRelationsResponse)(nil), // 21: memos.api.v2.SetMemoRelationsResponse + (*ListMemoRelationsRequest)(nil), // 22: memos.api.v2.ListMemoRelationsRequest + (*ListMemoRelationsResponse)(nil), // 23: memos.api.v2.ListMemoRelationsResponse + (*CreateMemoCommentRequest)(nil), // 24: memos.api.v2.CreateMemoCommentRequest + (*CreateMemoCommentResponse)(nil), // 25: memos.api.v2.CreateMemoCommentResponse + (*ListMemoCommentsRequest)(nil), // 26: memos.api.v2.ListMemoCommentsRequest + (*ListMemoCommentsResponse)(nil), // 27: memos.api.v2.ListMemoCommentsResponse + (*GetUserMemosStatsRequest)(nil), // 28: memos.api.v2.GetUserMemosStatsRequest + (*GetUserMemosStatsResponse)(nil), // 29: memos.api.v2.GetUserMemosStatsResponse + (*ListMemoReactionsRequest)(nil), // 30: memos.api.v2.ListMemoReactionsRequest + (*ListMemoReactionsResponse)(nil), // 31: memos.api.v2.ListMemoReactionsResponse + (*UpsertMemoReactionRequest)(nil), // 32: memos.api.v2.UpsertMemoReactionRequest + (*UpsertMemoReactionResponse)(nil), // 33: memos.api.v2.UpsertMemoReactionResponse + (*DeleteMemoReactionRequest)(nil), // 34: memos.api.v2.DeleteMemoReactionRequest + (*DeleteMemoReactionResponse)(nil), // 35: memos.api.v2.DeleteMemoReactionResponse + nil, // 36: memos.api.v2.GetUserMemosStatsResponse.StatsEntry + (RowStatus)(0), // 37: memos.api.v2.RowStatus + (*timestamppb.Timestamp)(nil), // 38: google.protobuf.Timestamp + (*Resource)(nil), // 39: memos.api.v2.Resource + (*MemoRelation)(nil), // 40: memos.api.v2.MemoRelation + (*Reaction)(nil), // 41: memos.api.v2.Reaction + (*fieldmaskpb.FieldMask)(nil), // 42: google.protobuf.FieldMask +} +var file_api_v2_memo_service_proto_depIdxs = []int32{ + 37, // 0: memos.api.v2.Memo.row_status:type_name -> memos.api.v2.RowStatus + 38, // 1: memos.api.v2.Memo.create_time:type_name -> google.protobuf.Timestamp + 38, // 2: memos.api.v2.Memo.update_time:type_name -> google.protobuf.Timestamp + 38, // 3: memos.api.v2.Memo.display_time:type_name -> google.protobuf.Timestamp + 0, // 4: memos.api.v2.Memo.visibility:type_name -> memos.api.v2.Visibility + 39, // 5: memos.api.v2.Memo.resources:type_name -> memos.api.v2.Resource + 40, // 6: memos.api.v2.Memo.relations:type_name -> memos.api.v2.MemoRelation + 41, // 7: memos.api.v2.Memo.reactions:type_name -> memos.api.v2.Reaction + 0, // 8: memos.api.v2.CreateMemoRequest.visibility:type_name -> memos.api.v2.Visibility + 1, // 9: memos.api.v2.CreateMemoResponse.memo:type_name -> memos.api.v2.Memo + 1, // 10: memos.api.v2.ListMemosResponse.memos:type_name -> memos.api.v2.Memo + 1, // 11: memos.api.v2.GetMemoResponse.memo:type_name -> memos.api.v2.Memo + 1, // 12: memos.api.v2.GetMemoByNameResponse.memo:type_name -> memos.api.v2.Memo + 1, // 13: memos.api.v2.UpdateMemoRequest.memo:type_name -> memos.api.v2.Memo + 42, // 14: memos.api.v2.UpdateMemoRequest.update_mask:type_name -> google.protobuf.FieldMask + 1, // 15: memos.api.v2.UpdateMemoResponse.memo:type_name -> memos.api.v2.Memo + 39, // 16: memos.api.v2.SetMemoResourcesRequest.resources:type_name -> memos.api.v2.Resource + 39, // 17: memos.api.v2.ListMemoResourcesResponse.resources:type_name -> memos.api.v2.Resource + 40, // 18: memos.api.v2.SetMemoRelationsRequest.relations:type_name -> memos.api.v2.MemoRelation + 40, // 19: memos.api.v2.ListMemoRelationsResponse.relations:type_name -> memos.api.v2.MemoRelation + 2, // 20: memos.api.v2.CreateMemoCommentRequest.create:type_name -> memos.api.v2.CreateMemoRequest + 1, // 21: memos.api.v2.CreateMemoCommentResponse.memo:type_name -> memos.api.v2.Memo + 1, // 22: memos.api.v2.ListMemoCommentsResponse.memos:type_name -> memos.api.v2.Memo + 36, // 23: memos.api.v2.GetUserMemosStatsResponse.stats:type_name -> memos.api.v2.GetUserMemosStatsResponse.StatsEntry + 41, // 24: memos.api.v2.ListMemoReactionsResponse.reactions:type_name -> memos.api.v2.Reaction + 41, // 25: memos.api.v2.UpsertMemoReactionRequest.reaction:type_name -> memos.api.v2.Reaction + 41, // 26: memos.api.v2.UpsertMemoReactionResponse.reaction:type_name -> memos.api.v2.Reaction + 2, // 27: memos.api.v2.MemoService.CreateMemo:input_type -> memos.api.v2.CreateMemoRequest + 4, // 28: memos.api.v2.MemoService.ListMemos:input_type -> memos.api.v2.ListMemosRequest + 6, // 29: memos.api.v2.MemoService.GetMemo:input_type -> memos.api.v2.GetMemoRequest + 8, // 30: memos.api.v2.MemoService.GetMemoByName:input_type -> memos.api.v2.GetMemoByNameRequest + 10, // 31: memos.api.v2.MemoService.UpdateMemo:input_type -> memos.api.v2.UpdateMemoRequest + 12, // 32: memos.api.v2.MemoService.DeleteMemo:input_type -> memos.api.v2.DeleteMemoRequest + 14, // 33: memos.api.v2.MemoService.ExportMemos:input_type -> memos.api.v2.ExportMemosRequest + 16, // 34: memos.api.v2.MemoService.SetMemoResources:input_type -> memos.api.v2.SetMemoResourcesRequest + 18, // 35: memos.api.v2.MemoService.ListMemoResources:input_type -> memos.api.v2.ListMemoResourcesRequest + 20, // 36: memos.api.v2.MemoService.SetMemoRelations:input_type -> memos.api.v2.SetMemoRelationsRequest + 22, // 37: memos.api.v2.MemoService.ListMemoRelations:input_type -> memos.api.v2.ListMemoRelationsRequest + 24, // 38: memos.api.v2.MemoService.CreateMemoComment:input_type -> memos.api.v2.CreateMemoCommentRequest + 26, // 39: memos.api.v2.MemoService.ListMemoComments:input_type -> memos.api.v2.ListMemoCommentsRequest + 28, // 40: memos.api.v2.MemoService.GetUserMemosStats:input_type -> memos.api.v2.GetUserMemosStatsRequest + 30, // 41: memos.api.v2.MemoService.ListMemoReactions:input_type -> memos.api.v2.ListMemoReactionsRequest + 32, // 42: memos.api.v2.MemoService.UpsertMemoReaction:input_type -> memos.api.v2.UpsertMemoReactionRequest + 34, // 43: memos.api.v2.MemoService.DeleteMemoReaction:input_type -> memos.api.v2.DeleteMemoReactionRequest + 3, // 44: memos.api.v2.MemoService.CreateMemo:output_type -> memos.api.v2.CreateMemoResponse + 5, // 45: memos.api.v2.MemoService.ListMemos:output_type -> memos.api.v2.ListMemosResponse + 7, // 46: memos.api.v2.MemoService.GetMemo:output_type -> memos.api.v2.GetMemoResponse + 9, // 47: memos.api.v2.MemoService.GetMemoByName:output_type -> memos.api.v2.GetMemoByNameResponse + 11, // 48: memos.api.v2.MemoService.UpdateMemo:output_type -> memos.api.v2.UpdateMemoResponse + 13, // 49: memos.api.v2.MemoService.DeleteMemo:output_type -> memos.api.v2.DeleteMemoResponse + 15, // 50: memos.api.v2.MemoService.ExportMemos:output_type -> memos.api.v2.ExportMemosResponse + 17, // 51: memos.api.v2.MemoService.SetMemoResources:output_type -> memos.api.v2.SetMemoResourcesResponse + 19, // 52: memos.api.v2.MemoService.ListMemoResources:output_type -> memos.api.v2.ListMemoResourcesResponse + 21, // 53: memos.api.v2.MemoService.SetMemoRelations:output_type -> memos.api.v2.SetMemoRelationsResponse + 23, // 54: memos.api.v2.MemoService.ListMemoRelations:output_type -> memos.api.v2.ListMemoRelationsResponse + 25, // 55: memos.api.v2.MemoService.CreateMemoComment:output_type -> memos.api.v2.CreateMemoCommentResponse + 27, // 56: memos.api.v2.MemoService.ListMemoComments:output_type -> memos.api.v2.ListMemoCommentsResponse + 29, // 57: memos.api.v2.MemoService.GetUserMemosStats:output_type -> memos.api.v2.GetUserMemosStatsResponse + 31, // 58: memos.api.v2.MemoService.ListMemoReactions:output_type -> memos.api.v2.ListMemoReactionsResponse + 33, // 59: memos.api.v2.MemoService.UpsertMemoReaction:output_type -> memos.api.v2.UpsertMemoReactionResponse + 35, // 60: memos.api.v2.MemoService.DeleteMemoReaction:output_type -> memos.api.v2.DeleteMemoReactionResponse + 44, // [44:61] is the sub-list for method output_type + 27, // [27:44] is the sub-list for method input_type + 27, // [27:27] is the sub-list for extension type_name + 27, // [27:27] is the sub-list for extension extendee + 0, // [0:27] is the sub-list for field type_name +} + +func init() { file_api_v2_memo_service_proto_init() } +func file_api_v2_memo_service_proto_init() { + if File_api_v2_memo_service_proto != nil { + return + } + file_api_v2_common_proto_init() + file_api_v2_memo_relation_service_proto_init() + file_api_v2_reaction_service_proto_init() + file_api_v2_resource_service_proto_init() + if !protoimpl.UnsafeEnabled { + file_api_v2_memo_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Memo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateMemoRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateMemoResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: return nil } } @@ -968,7 +2514,7 @@ func file_api_v2_memo_service_proto_init() { } } file_api_v2_memo_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateMemoCommentRequest); i { + switch v := v.(*GetMemoByNameRequest); i { case 0: return &v.state case 1: @@ -980,7 +2526,7 @@ func file_api_v2_memo_service_proto_init() { } } file_api_v2_memo_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateMemoCommentResponse); i { + switch v := v.(*GetMemoByNameResponse); i { case 0: return &v.state case 1: @@ -992,7 +2538,7 @@ func file_api_v2_memo_service_proto_init() { } } file_api_v2_memo_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListMemoCommentsRequest); i { + switch v := v.(*UpdateMemoRequest); i { case 0: return &v.state case 1: @@ -1004,6 +2550,198 @@ func file_api_v2_memo_service_proto_init() { } } file_api_v2_memo_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateMemoResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteMemoRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteMemoResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExportMemosRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExportMemosResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetMemoResourcesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetMemoResourcesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListMemoResourcesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListMemoResourcesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetMemoRelationsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetMemoRelationsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListMemoRelationsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListMemoRelationsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateMemoCommentRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateMemoCommentResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListMemoCommentsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ListMemoCommentsResponse); i { case 0: return &v.state @@ -1015,15 +2753,111 @@ func file_api_v2_memo_service_proto_init() { return nil } } + file_api_v2_memo_service_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetUserMemosStatsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetUserMemosStatsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListMemoReactionsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListMemoReactionsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpsertMemoReactionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpsertMemoReactionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteMemoReactionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_memo_service_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteMemoReactionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } - file_api_v2_memo_service_proto_msgTypes[3].OneofWrappers = []interface{}{} + file_api_v2_memo_service_proto_msgTypes[0].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_v2_memo_service_proto_rawDesc, NumEnums: 1, - NumMessages: 11, + NumMessages: 36, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gen/api/v2/memo_service.pb.gw.go b/proto/gen/api/v2/memo_service.pb.gw.go index 28800d5812299..c6e498f72013a 100644 --- a/proto/gen/api/v2/memo_service.pb.gw.go +++ b/proto/gen/api/v2/memo_service.pb.gw.go @@ -31,18 +31,15 @@ var _ = runtime.String var _ = utilities.NewDoubleArray var _ = metadata.Join -var ( - filter_MemoService_CreateMemo_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} -) - func request_MemoService_CreateMemo_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq CreateMemoRequest var metadata runtime.ServerMetadata - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_CreateMemo_0); err != nil { + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -55,10 +52,11 @@ func local_request_MemoService_CreateMemo_0(ctx context.Context, marshaler runti var protoReq CreateMemoRequest var metadata runtime.ServerMetadata - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_CreateMemo_0); err != nil { + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } @@ -155,12 +153,186 @@ func local_request_MemoService_GetMemo_0(ctx context.Context, marshaler runtime. } +func request_MemoService_GetMemoByName_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetMemoByNameRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := client.GetMemoByName(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_MemoService_GetMemoByName_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetMemoByNameRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := server.GetMemoByName(ctx, &protoReq) + return msg, metadata, err + +} + var ( - filter_MemoService_CreateMemoComment_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 2, 0, 0}, Check: []int{0, 1, 2, 2}} + filter_MemoService_UpdateMemo_0 = &utilities.DoubleArray{Encoding: map[string]int{"memo": 0, "id": 1}, Base: []int{1, 4, 5, 2, 0, 0, 0, 0}, Check: []int{0, 1, 1, 2, 4, 2, 2, 3}} ) -func request_MemoService_CreateMemoComment_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq CreateMemoCommentRequest +func request_MemoService_UpdateMemo_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateMemoRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Memo); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 { + if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Memo); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } else { + protoReq.UpdateMask = fieldMask + } + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["memo.id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "memo.id") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "memo.id", val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "memo.id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_UpdateMemo_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.UpdateMemo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_MemoService_UpdateMemo_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateMemoRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Memo); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 { + if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Memo); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } else { + protoReq.UpdateMask = fieldMask + } + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["memo.id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "memo.id") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "memo.id", val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "memo.id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_UpdateMemo_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.UpdateMemo(ctx, &protoReq) + return msg, metadata, err + +} + +func request_MemoService_DeleteMemo_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteMemoRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.DeleteMemo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_MemoService_DeleteMemo_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteMemoRequest var metadata runtime.ServerMetadata var ( @@ -180,22 +352,59 @@ func request_MemoService_CreateMemoComment_0(ctx context.Context, marshaler runt return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + msg, err := server.DeleteMemo(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_MemoService_ExportMemos_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_MemoService_ExportMemos_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ExportMemosRequest + var metadata runtime.ServerMetadata + if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_CreateMemoComment_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_ExportMemos_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.CreateMemoComment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.ExportMemos(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_MemoService_CreateMemoComment_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq CreateMemoCommentRequest +func local_request_MemoService_ExportMemos_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ExportMemosRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_ExportMemos_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ExportMemos(ctx, &protoReq) + return msg, metadata, err + +} + +func request_MemoService_SetMemoResources_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SetMemoResourcesRequest var metadata runtime.ServerMetadata + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + var ( val string ok bool @@ -213,20 +422,47 @@ func local_request_MemoService_CreateMemoComment_0(ctx context.Context, marshale return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + msg, err := client.SetMemoResources(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_MemoService_SetMemoResources_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SetMemoResourcesRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_CreateMemoComment_0); err != nil { + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := server.CreateMemoComment(ctx, &protoReq) + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.SetMemoResources(ctx, &protoReq) return msg, metadata, err } -func request_MemoService_ListMemoComments_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ListMemoCommentsRequest +func request_MemoService_ListMemoResources_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListMemoResourcesRequest var metadata runtime.ServerMetadata var ( @@ -246,13 +482,13 @@ func request_MemoService_ListMemoComments_0(ctx context.Context, marshaler runti return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } - msg, err := client.ListMemoComments(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.ListMemoResources(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_MemoService_ListMemoComments_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ListMemoCommentsRequest +func local_request_MemoService_ListMemoResources_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListMemoResourcesRequest var metadata runtime.ServerMetadata var ( @@ -272,43 +508,815 @@ func local_request_MemoService_ListMemoComments_0(ctx context.Context, marshaler return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } - msg, err := server.ListMemoComments(ctx, &protoReq) + msg, err := server.ListMemoResources(ctx, &protoReq) return msg, metadata, err } -// RegisterMemoServiceHandlerServer registers the http handlers for service MemoService to "mux". -// UnaryRPC :call MemoServiceServer directly. -// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. -// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterMemoServiceHandlerFromEndpoint instead. -func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server MemoServiceServer) error { +func request_MemoService_SetMemoRelations_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SetMemoRelationsRequest + var metadata runtime.ServerMetadata - mux.Handle("POST", pattern_MemoService_CreateMemo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - var err error - var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/CreateMemo", runtime.WithHTTPPathPattern("/api/v2/memos")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_MemoService_CreateMemo_0(annotatedContext, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) - if err != nil { - runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) - return - } + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } - forward_MemoService_CreateMemo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.SetMemoRelations(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_MemoService_SetMemoRelations_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SetMemoRelationsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.SetMemoRelations(ctx, &protoReq) + return msg, metadata, err + +} + +func request_MemoService_ListMemoRelations_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListMemoRelationsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.ListMemoRelations(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_MemoService_ListMemoRelations_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListMemoRelationsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.ListMemoRelations(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_MemoService_CreateMemoComment_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 2, 0, 0}, Check: []int{0, 1, 2, 2}} +) + +func request_MemoService_CreateMemoComment_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateMemoCommentRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_CreateMemoComment_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CreateMemoComment(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_MemoService_CreateMemoComment_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateMemoCommentRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_CreateMemoComment_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.CreateMemoComment(ctx, &protoReq) + return msg, metadata, err + +} + +func request_MemoService_ListMemoComments_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListMemoCommentsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.ListMemoComments(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_MemoService_ListMemoComments_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListMemoCommentsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.ListMemoComments(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_MemoService_GetUserMemosStats_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_MemoService_GetUserMemosStats_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetUserMemosStatsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_GetUserMemosStats_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetUserMemosStats(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_MemoService_GetUserMemosStats_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetUserMemosStatsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_GetUserMemosStats_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetUserMemosStats(ctx, &protoReq) + return msg, metadata, err + +} + +func request_MemoService_ListMemoReactions_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListMemoReactionsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.ListMemoReactions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_MemoService_ListMemoReactions_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListMemoReactionsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.ListMemoReactions(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_MemoService_UpsertMemoReaction_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 2, 0, 0}, Check: []int{0, 1, 2, 2}} +) + +func request_MemoService_UpsertMemoReaction_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpsertMemoReactionRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_UpsertMemoReaction_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.UpsertMemoReaction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_MemoService_UpsertMemoReaction_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpsertMemoReactionRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_MemoService_UpsertMemoReaction_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.UpsertMemoReaction(ctx, &protoReq) + return msg, metadata, err + +} + +func request_MemoService_DeleteMemoReaction_0(ctx context.Context, marshaler runtime.Marshaler, client MemoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteMemoReactionRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + val, ok = pathParams["reaction_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "reaction_id") + } + + protoReq.ReactionId, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "reaction_id", err) + } + + msg, err := client.DeleteMemoReaction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_MemoService_DeleteMemoReaction_0(ctx context.Context, marshaler runtime.Marshaler, server MemoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteMemoReactionRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + val, ok = pathParams["reaction_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "reaction_id") + } + + protoReq.ReactionId, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "reaction_id", err) + } + + msg, err := server.DeleteMemoReaction(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterMemoServiceHandlerServer registers the http handlers for service MemoService to "mux". +// UnaryRPC :call MemoServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterMemoServiceHandlerFromEndpoint instead. +func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server MemoServiceServer) error { + + mux.Handle("POST", pattern_MemoService_CreateMemo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/CreateMemo", runtime.WithHTTPPathPattern("/api/v2/memos")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_MemoService_CreateMemo_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_CreateMemo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_MemoService_ListMemos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/ListMemos", runtime.WithHTTPPathPattern("/api/v2/memos")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_MemoService_ListMemos_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_ListMemos_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_MemoService_GetMemo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/GetMemo", runtime.WithHTTPPathPattern("/api/v2/memos/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_MemoService_GetMemo_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_GetMemo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_MemoService_GetMemoByName_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/GetMemoByName", runtime.WithHTTPPathPattern("/api/v2/memos/name/{name}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_MemoService_GetMemoByName_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_GetMemoByName_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_MemoService_UpdateMemo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/UpdateMemo", runtime.WithHTTPPathPattern("/api/v2/memos/{memo.id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_MemoService_UpdateMemo_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_UpdateMemo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_MemoService_DeleteMemo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/DeleteMemo", runtime.WithHTTPPathPattern("/api/v2/memos/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_MemoService_DeleteMemo_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_DeleteMemo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_MemoService_ExportMemos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/ExportMemos", runtime.WithHTTPPathPattern("/api/v2/memos:export")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_MemoService_ExportMemos_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_ExportMemos_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_MemoService_SetMemoResources_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/SetMemoResources", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/resources")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_MemoService_SetMemoResources_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_SetMemoResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_MemoService_ListMemoResources_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/ListMemoResources", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/resources")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_MemoService_ListMemoResources_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_ListMemoResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_MemoService_SetMemoRelations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/SetMemoRelations", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/relations")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_MemoService_SetMemoRelations_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_SetMemoRelations_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_MemoService_ListMemoRelations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/ListMemoRelations", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/relations")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_MemoService_ListMemoRelations_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_ListMemoRelations_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_MemoService_CreateMemoComment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/CreateMemoComment", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/comments")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_MemoService_CreateMemoComment_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_CreateMemoComment_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_MemoService_ListMemoComments_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/ListMemoComments", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/comments")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_MemoService_ListMemoComments_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_ListMemoComments_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_MemoService_ListMemos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_MemoService_GetUserMemosStats_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -316,12 +1324,12 @@ func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/ListMemos", runtime.WithHTTPPathPattern("/api/v2/memos")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/GetUserMemosStats", runtime.WithHTTPPathPattern("/api/v2/memos/stats")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_MemoService_ListMemos_0(annotatedContext, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_MemoService_GetUserMemosStats_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { @@ -329,11 +1337,11 @@ func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux return } - forward_MemoService_ListMemos_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_MemoService_GetUserMemosStats_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_MemoService_GetMemo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_MemoService_ListMemoReactions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -341,12 +1349,12 @@ func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/GetMemo", runtime.WithHTTPPathPattern("/api/v2/memos/{id}")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/ListMemoReactions", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/reactions")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_MemoService_GetMemo_0(annotatedContext, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_MemoService_ListMemoReactions_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { @@ -354,11 +1362,11 @@ func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux return } - forward_MemoService_GetMemo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_MemoService_ListMemoReactions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("POST", pattern_MemoService_CreateMemoComment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("POST", pattern_MemoService_UpsertMemoReaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -366,12 +1374,12 @@ func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/CreateMemoComment", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/comments")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/UpsertMemoReaction", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/reactions")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_MemoService_CreateMemoComment_0(annotatedContext, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_MemoService_UpsertMemoReaction_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { @@ -379,11 +1387,11 @@ func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux return } - forward_MemoService_CreateMemoComment_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_MemoService_UpsertMemoReaction_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_MemoService_ListMemoComments_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("DELETE", pattern_MemoService_DeleteMemoReaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -391,12 +1399,12 @@ func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/ListMemoComments", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/comments")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.MemoService/DeleteMemoReaction", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/reactions/{reaction_id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_MemoService_ListMemoComments_0(annotatedContext, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_MemoService_DeleteMemoReaction_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { @@ -404,7 +1412,7 @@ func RegisterMemoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux return } - forward_MemoService_ListMemoComments_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_MemoService_DeleteMemoReaction_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -515,6 +1523,182 @@ func RegisterMemoServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("GET", pattern_MemoService_GetMemoByName_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.MemoService/GetMemoByName", runtime.WithHTTPPathPattern("/api/v2/memos/name/{name}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_MemoService_GetMemoByName_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_GetMemoByName_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_MemoService_UpdateMemo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.MemoService/UpdateMemo", runtime.WithHTTPPathPattern("/api/v2/memos/{memo.id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_MemoService_UpdateMemo_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_UpdateMemo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_MemoService_DeleteMemo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.MemoService/DeleteMemo", runtime.WithHTTPPathPattern("/api/v2/memos/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_MemoService_DeleteMemo_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_DeleteMemo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_MemoService_ExportMemos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.MemoService/ExportMemos", runtime.WithHTTPPathPattern("/api/v2/memos:export")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_MemoService_ExportMemos_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_ExportMemos_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_MemoService_SetMemoResources_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.MemoService/SetMemoResources", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/resources")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_MemoService_SetMemoResources_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_SetMemoResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_MemoService_ListMemoResources_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.MemoService/ListMemoResources", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/resources")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_MemoService_ListMemoResources_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_ListMemoResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_MemoService_SetMemoRelations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.MemoService/SetMemoRelations", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/relations")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_MemoService_SetMemoRelations_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_SetMemoRelations_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_MemoService_ListMemoRelations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.MemoService/ListMemoRelations", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/relations")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_MemoService_ListMemoRelations_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_ListMemoRelations_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_MemoService_CreateMemoComment_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -559,6 +1743,94 @@ func RegisterMemoServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("GET", pattern_MemoService_GetUserMemosStats_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.MemoService/GetUserMemosStats", runtime.WithHTTPPathPattern("/api/v2/memos/stats")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_MemoService_GetUserMemosStats_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_GetUserMemosStats_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_MemoService_ListMemoReactions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.MemoService/ListMemoReactions", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/reactions")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_MemoService_ListMemoReactions_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_ListMemoReactions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_MemoService_UpsertMemoReaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.MemoService/UpsertMemoReaction", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/reactions")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_MemoService_UpsertMemoReaction_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_UpsertMemoReaction_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_MemoService_DeleteMemoReaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.MemoService/DeleteMemoReaction", runtime.WithHTTPPathPattern("/api/v2/memos/{id}/reactions/{reaction_id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_MemoService_DeleteMemoReaction_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_MemoService_DeleteMemoReaction_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -569,9 +1841,33 @@ var ( pattern_MemoService_GetMemo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "memos", "id"}, "")) + pattern_MemoService_GetMemoByName_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "memos", "name"}, "")) + + pattern_MemoService_UpdateMemo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "memos", "memo.id"}, "")) + + pattern_MemoService_DeleteMemo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "memos", "id"}, "")) + + pattern_MemoService_ExportMemos_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "memos"}, "export")) + + pattern_MemoService_SetMemoResources_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "memos", "id", "resources"}, "")) + + pattern_MemoService_ListMemoResources_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "memos", "id", "resources"}, "")) + + pattern_MemoService_SetMemoRelations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "memos", "id", "relations"}, "")) + + pattern_MemoService_ListMemoRelations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "memos", "id", "relations"}, "")) + pattern_MemoService_CreateMemoComment_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "memos", "id", "comments"}, "")) pattern_MemoService_ListMemoComments_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "memos", "id", "comments"}, "")) + + pattern_MemoService_GetUserMemosStats_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v2", "memos", "stats"}, "")) + + pattern_MemoService_ListMemoReactions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "memos", "id", "reactions"}, "")) + + pattern_MemoService_UpsertMemoReaction_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "memos", "id", "reactions"}, "")) + + pattern_MemoService_DeleteMemoReaction_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"api", "v2", "memos", "id", "reactions", "reaction_id"}, "")) ) var ( @@ -581,7 +1877,31 @@ var ( forward_MemoService_GetMemo_0 = runtime.ForwardResponseMessage + forward_MemoService_GetMemoByName_0 = runtime.ForwardResponseMessage + + forward_MemoService_UpdateMemo_0 = runtime.ForwardResponseMessage + + forward_MemoService_DeleteMemo_0 = runtime.ForwardResponseMessage + + forward_MemoService_ExportMemos_0 = runtime.ForwardResponseMessage + + forward_MemoService_SetMemoResources_0 = runtime.ForwardResponseMessage + + forward_MemoService_ListMemoResources_0 = runtime.ForwardResponseMessage + + forward_MemoService_SetMemoRelations_0 = runtime.ForwardResponseMessage + + forward_MemoService_ListMemoRelations_0 = runtime.ForwardResponseMessage + forward_MemoService_CreateMemoComment_0 = runtime.ForwardResponseMessage forward_MemoService_ListMemoComments_0 = runtime.ForwardResponseMessage + + forward_MemoService_GetUserMemosStats_0 = runtime.ForwardResponseMessage + + forward_MemoService_ListMemoReactions_0 = runtime.ForwardResponseMessage + + forward_MemoService_UpsertMemoReaction_0 = runtime.ForwardResponseMessage + + forward_MemoService_DeleteMemoReaction_0 = runtime.ForwardResponseMessage ) diff --git a/proto/gen/api/v2/memo_service_grpc.pb.go b/proto/gen/api/v2/memo_service_grpc.pb.go index 02206ba75980d..1ea896a1a95b0 100644 --- a/proto/gen/api/v2/memo_service_grpc.pb.go +++ b/proto/gen/api/v2/memo_service_grpc.pb.go @@ -19,22 +19,63 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - MemoService_CreateMemo_FullMethodName = "/memos.api.v2.MemoService/CreateMemo" - MemoService_ListMemos_FullMethodName = "/memos.api.v2.MemoService/ListMemos" - MemoService_GetMemo_FullMethodName = "/memos.api.v2.MemoService/GetMemo" - MemoService_CreateMemoComment_FullMethodName = "/memos.api.v2.MemoService/CreateMemoComment" - MemoService_ListMemoComments_FullMethodName = "/memos.api.v2.MemoService/ListMemoComments" + MemoService_CreateMemo_FullMethodName = "/memos.api.v2.MemoService/CreateMemo" + MemoService_ListMemos_FullMethodName = "/memos.api.v2.MemoService/ListMemos" + MemoService_GetMemo_FullMethodName = "/memos.api.v2.MemoService/GetMemo" + MemoService_GetMemoByName_FullMethodName = "/memos.api.v2.MemoService/GetMemoByName" + MemoService_UpdateMemo_FullMethodName = "/memos.api.v2.MemoService/UpdateMemo" + MemoService_DeleteMemo_FullMethodName = "/memos.api.v2.MemoService/DeleteMemo" + MemoService_ExportMemos_FullMethodName = "/memos.api.v2.MemoService/ExportMemos" + MemoService_SetMemoResources_FullMethodName = "/memos.api.v2.MemoService/SetMemoResources" + MemoService_ListMemoResources_FullMethodName = "/memos.api.v2.MemoService/ListMemoResources" + MemoService_SetMemoRelations_FullMethodName = "/memos.api.v2.MemoService/SetMemoRelations" + MemoService_ListMemoRelations_FullMethodName = "/memos.api.v2.MemoService/ListMemoRelations" + MemoService_CreateMemoComment_FullMethodName = "/memos.api.v2.MemoService/CreateMemoComment" + MemoService_ListMemoComments_FullMethodName = "/memos.api.v2.MemoService/ListMemoComments" + MemoService_GetUserMemosStats_FullMethodName = "/memos.api.v2.MemoService/GetUserMemosStats" + MemoService_ListMemoReactions_FullMethodName = "/memos.api.v2.MemoService/ListMemoReactions" + MemoService_UpsertMemoReaction_FullMethodName = "/memos.api.v2.MemoService/UpsertMemoReaction" + MemoService_DeleteMemoReaction_FullMethodName = "/memos.api.v2.MemoService/DeleteMemoReaction" ) // MemoServiceClient is the client API for MemoService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type MemoServiceClient interface { + // CreateMemo creates a memo. CreateMemo(ctx context.Context, in *CreateMemoRequest, opts ...grpc.CallOption) (*CreateMemoResponse, error) + // ListMemos lists memos with pagination and filter. ListMemos(ctx context.Context, in *ListMemosRequest, opts ...grpc.CallOption) (*ListMemosResponse, error) + // GetMemo gets a memo by id. GetMemo(ctx context.Context, in *GetMemoRequest, opts ...grpc.CallOption) (*GetMemoResponse, error) + // GetMemoByName gets a memo by name. + GetMemoByName(ctx context.Context, in *GetMemoByNameRequest, opts ...grpc.CallOption) (*GetMemoByNameResponse, error) + // UpdateMemo updates a memo. + UpdateMemo(ctx context.Context, in *UpdateMemoRequest, opts ...grpc.CallOption) (*UpdateMemoResponse, error) + // DeleteMemo deletes a memo by id. + DeleteMemo(ctx context.Context, in *DeleteMemoRequest, opts ...grpc.CallOption) (*DeleteMemoResponse, error) + // ExportMemos exports memos. + ExportMemos(ctx context.Context, in *ExportMemosRequest, opts ...grpc.CallOption) (*ExportMemosResponse, error) + // SetMemoResources sets resources for a memo. + SetMemoResources(ctx context.Context, in *SetMemoResourcesRequest, opts ...grpc.CallOption) (*SetMemoResourcesResponse, error) + // ListMemoResources lists resources for a memo. + ListMemoResources(ctx context.Context, in *ListMemoResourcesRequest, opts ...grpc.CallOption) (*ListMemoResourcesResponse, error) + // SetMemoRelations sets relations for a memo. + SetMemoRelations(ctx context.Context, in *SetMemoRelationsRequest, opts ...grpc.CallOption) (*SetMemoRelationsResponse, error) + // ListMemoRelations lists relations for a memo. + ListMemoRelations(ctx context.Context, in *ListMemoRelationsRequest, opts ...grpc.CallOption) (*ListMemoRelationsResponse, error) + // CreateMemoComment creates a comment for a memo. CreateMemoComment(ctx context.Context, in *CreateMemoCommentRequest, opts ...grpc.CallOption) (*CreateMemoCommentResponse, error) + // ListMemoComments lists comments for a memo. ListMemoComments(ctx context.Context, in *ListMemoCommentsRequest, opts ...grpc.CallOption) (*ListMemoCommentsResponse, error) + // GetUserMemosStats gets stats of memos for a user. + GetUserMemosStats(ctx context.Context, in *GetUserMemosStatsRequest, opts ...grpc.CallOption) (*GetUserMemosStatsResponse, error) + // ListMemoReactions lists reactions for a memo. + ListMemoReactions(ctx context.Context, in *ListMemoReactionsRequest, opts ...grpc.CallOption) (*ListMemoReactionsResponse, error) + // UpsertMemoReaction upserts a reaction for a memo. + UpsertMemoReaction(ctx context.Context, in *UpsertMemoReactionRequest, opts ...grpc.CallOption) (*UpsertMemoReactionResponse, error) + // DeleteMemoReaction deletes a reaction for a memo. + DeleteMemoReaction(ctx context.Context, in *DeleteMemoReactionRequest, opts ...grpc.CallOption) (*DeleteMemoReactionResponse, error) } type memoServiceClient struct { @@ -72,6 +113,78 @@ func (c *memoServiceClient) GetMemo(ctx context.Context, in *GetMemoRequest, opt return out, nil } +func (c *memoServiceClient) GetMemoByName(ctx context.Context, in *GetMemoByNameRequest, opts ...grpc.CallOption) (*GetMemoByNameResponse, error) { + out := new(GetMemoByNameResponse) + err := c.cc.Invoke(ctx, MemoService_GetMemoByName_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *memoServiceClient) UpdateMemo(ctx context.Context, in *UpdateMemoRequest, opts ...grpc.CallOption) (*UpdateMemoResponse, error) { + out := new(UpdateMemoResponse) + err := c.cc.Invoke(ctx, MemoService_UpdateMemo_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *memoServiceClient) DeleteMemo(ctx context.Context, in *DeleteMemoRequest, opts ...grpc.CallOption) (*DeleteMemoResponse, error) { + out := new(DeleteMemoResponse) + err := c.cc.Invoke(ctx, MemoService_DeleteMemo_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *memoServiceClient) ExportMemos(ctx context.Context, in *ExportMemosRequest, opts ...grpc.CallOption) (*ExportMemosResponse, error) { + out := new(ExportMemosResponse) + err := c.cc.Invoke(ctx, MemoService_ExportMemos_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *memoServiceClient) SetMemoResources(ctx context.Context, in *SetMemoResourcesRequest, opts ...grpc.CallOption) (*SetMemoResourcesResponse, error) { + out := new(SetMemoResourcesResponse) + err := c.cc.Invoke(ctx, MemoService_SetMemoResources_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *memoServiceClient) ListMemoResources(ctx context.Context, in *ListMemoResourcesRequest, opts ...grpc.CallOption) (*ListMemoResourcesResponse, error) { + out := new(ListMemoResourcesResponse) + err := c.cc.Invoke(ctx, MemoService_ListMemoResources_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *memoServiceClient) SetMemoRelations(ctx context.Context, in *SetMemoRelationsRequest, opts ...grpc.CallOption) (*SetMemoRelationsResponse, error) { + out := new(SetMemoRelationsResponse) + err := c.cc.Invoke(ctx, MemoService_SetMemoRelations_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *memoServiceClient) ListMemoRelations(ctx context.Context, in *ListMemoRelationsRequest, opts ...grpc.CallOption) (*ListMemoRelationsResponse, error) { + out := new(ListMemoRelationsResponse) + err := c.cc.Invoke(ctx, MemoService_ListMemoRelations_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *memoServiceClient) CreateMemoComment(ctx context.Context, in *CreateMemoCommentRequest, opts ...grpc.CallOption) (*CreateMemoCommentResponse, error) { out := new(CreateMemoCommentResponse) err := c.cc.Invoke(ctx, MemoService_CreateMemoComment_FullMethodName, in, out, opts...) @@ -90,15 +203,80 @@ func (c *memoServiceClient) ListMemoComments(ctx context.Context, in *ListMemoCo return out, nil } +func (c *memoServiceClient) GetUserMemosStats(ctx context.Context, in *GetUserMemosStatsRequest, opts ...grpc.CallOption) (*GetUserMemosStatsResponse, error) { + out := new(GetUserMemosStatsResponse) + err := c.cc.Invoke(ctx, MemoService_GetUserMemosStats_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *memoServiceClient) ListMemoReactions(ctx context.Context, in *ListMemoReactionsRequest, opts ...grpc.CallOption) (*ListMemoReactionsResponse, error) { + out := new(ListMemoReactionsResponse) + err := c.cc.Invoke(ctx, MemoService_ListMemoReactions_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *memoServiceClient) UpsertMemoReaction(ctx context.Context, in *UpsertMemoReactionRequest, opts ...grpc.CallOption) (*UpsertMemoReactionResponse, error) { + out := new(UpsertMemoReactionResponse) + err := c.cc.Invoke(ctx, MemoService_UpsertMemoReaction_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *memoServiceClient) DeleteMemoReaction(ctx context.Context, in *DeleteMemoReactionRequest, opts ...grpc.CallOption) (*DeleteMemoReactionResponse, error) { + out := new(DeleteMemoReactionResponse) + err := c.cc.Invoke(ctx, MemoService_DeleteMemoReaction_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MemoServiceServer is the server API for MemoService service. // All implementations must embed UnimplementedMemoServiceServer // for forward compatibility type MemoServiceServer interface { + // CreateMemo creates a memo. CreateMemo(context.Context, *CreateMemoRequest) (*CreateMemoResponse, error) + // ListMemos lists memos with pagination and filter. ListMemos(context.Context, *ListMemosRequest) (*ListMemosResponse, error) + // GetMemo gets a memo by id. GetMemo(context.Context, *GetMemoRequest) (*GetMemoResponse, error) + // GetMemoByName gets a memo by name. + GetMemoByName(context.Context, *GetMemoByNameRequest) (*GetMemoByNameResponse, error) + // UpdateMemo updates a memo. + UpdateMemo(context.Context, *UpdateMemoRequest) (*UpdateMemoResponse, error) + // DeleteMemo deletes a memo by id. + DeleteMemo(context.Context, *DeleteMemoRequest) (*DeleteMemoResponse, error) + // ExportMemos exports memos. + ExportMemos(context.Context, *ExportMemosRequest) (*ExportMemosResponse, error) + // SetMemoResources sets resources for a memo. + SetMemoResources(context.Context, *SetMemoResourcesRequest) (*SetMemoResourcesResponse, error) + // ListMemoResources lists resources for a memo. + ListMemoResources(context.Context, *ListMemoResourcesRequest) (*ListMemoResourcesResponse, error) + // SetMemoRelations sets relations for a memo. + SetMemoRelations(context.Context, *SetMemoRelationsRequest) (*SetMemoRelationsResponse, error) + // ListMemoRelations lists relations for a memo. + ListMemoRelations(context.Context, *ListMemoRelationsRequest) (*ListMemoRelationsResponse, error) + // CreateMemoComment creates a comment for a memo. CreateMemoComment(context.Context, *CreateMemoCommentRequest) (*CreateMemoCommentResponse, error) + // ListMemoComments lists comments for a memo. ListMemoComments(context.Context, *ListMemoCommentsRequest) (*ListMemoCommentsResponse, error) + // GetUserMemosStats gets stats of memos for a user. + GetUserMemosStats(context.Context, *GetUserMemosStatsRequest) (*GetUserMemosStatsResponse, error) + // ListMemoReactions lists reactions for a memo. + ListMemoReactions(context.Context, *ListMemoReactionsRequest) (*ListMemoReactionsResponse, error) + // UpsertMemoReaction upserts a reaction for a memo. + UpsertMemoReaction(context.Context, *UpsertMemoReactionRequest) (*UpsertMemoReactionResponse, error) + // DeleteMemoReaction deletes a reaction for a memo. + DeleteMemoReaction(context.Context, *DeleteMemoReactionRequest) (*DeleteMemoReactionResponse, error) mustEmbedUnimplementedMemoServiceServer() } @@ -115,12 +293,48 @@ func (UnimplementedMemoServiceServer) ListMemos(context.Context, *ListMemosReque func (UnimplementedMemoServiceServer) GetMemo(context.Context, *GetMemoRequest) (*GetMemoResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetMemo not implemented") } +func (UnimplementedMemoServiceServer) GetMemoByName(context.Context, *GetMemoByNameRequest) (*GetMemoByNameResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMemoByName not implemented") +} +func (UnimplementedMemoServiceServer) UpdateMemo(context.Context, *UpdateMemoRequest) (*UpdateMemoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateMemo not implemented") +} +func (UnimplementedMemoServiceServer) DeleteMemo(context.Context, *DeleteMemoRequest) (*DeleteMemoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteMemo not implemented") +} +func (UnimplementedMemoServiceServer) ExportMemos(context.Context, *ExportMemosRequest) (*ExportMemosResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExportMemos not implemented") +} +func (UnimplementedMemoServiceServer) SetMemoResources(context.Context, *SetMemoResourcesRequest) (*SetMemoResourcesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetMemoResources not implemented") +} +func (UnimplementedMemoServiceServer) ListMemoResources(context.Context, *ListMemoResourcesRequest) (*ListMemoResourcesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListMemoResources not implemented") +} +func (UnimplementedMemoServiceServer) SetMemoRelations(context.Context, *SetMemoRelationsRequest) (*SetMemoRelationsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetMemoRelations not implemented") +} +func (UnimplementedMemoServiceServer) ListMemoRelations(context.Context, *ListMemoRelationsRequest) (*ListMemoRelationsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListMemoRelations not implemented") +} func (UnimplementedMemoServiceServer) CreateMemoComment(context.Context, *CreateMemoCommentRequest) (*CreateMemoCommentResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateMemoComment not implemented") } func (UnimplementedMemoServiceServer) ListMemoComments(context.Context, *ListMemoCommentsRequest) (*ListMemoCommentsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListMemoComments not implemented") } +func (UnimplementedMemoServiceServer) GetUserMemosStats(context.Context, *GetUserMemosStatsRequest) (*GetUserMemosStatsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetUserMemosStats not implemented") +} +func (UnimplementedMemoServiceServer) ListMemoReactions(context.Context, *ListMemoReactionsRequest) (*ListMemoReactionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListMemoReactions not implemented") +} +func (UnimplementedMemoServiceServer) UpsertMemoReaction(context.Context, *UpsertMemoReactionRequest) (*UpsertMemoReactionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpsertMemoReaction not implemented") +} +func (UnimplementedMemoServiceServer) DeleteMemoReaction(context.Context, *DeleteMemoReactionRequest) (*DeleteMemoReactionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteMemoReaction not implemented") +} func (UnimplementedMemoServiceServer) mustEmbedUnimplementedMemoServiceServer() {} // UnsafeMemoServiceServer may be embedded to opt out of forward compatibility for this service. @@ -188,6 +402,150 @@ func _MemoService_GetMemo_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } +func _MemoService_GetMemoByName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetMemoByNameRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MemoServiceServer).GetMemoByName(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MemoService_GetMemoByName_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MemoServiceServer).GetMemoByName(ctx, req.(*GetMemoByNameRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MemoService_UpdateMemo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateMemoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MemoServiceServer).UpdateMemo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MemoService_UpdateMemo_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MemoServiceServer).UpdateMemo(ctx, req.(*UpdateMemoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MemoService_DeleteMemo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteMemoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MemoServiceServer).DeleteMemo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MemoService_DeleteMemo_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MemoServiceServer).DeleteMemo(ctx, req.(*DeleteMemoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MemoService_ExportMemos_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ExportMemosRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MemoServiceServer).ExportMemos(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MemoService_ExportMemos_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MemoServiceServer).ExportMemos(ctx, req.(*ExportMemosRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MemoService_SetMemoResources_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetMemoResourcesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MemoServiceServer).SetMemoResources(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MemoService_SetMemoResources_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MemoServiceServer).SetMemoResources(ctx, req.(*SetMemoResourcesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MemoService_ListMemoResources_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListMemoResourcesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MemoServiceServer).ListMemoResources(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MemoService_ListMemoResources_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MemoServiceServer).ListMemoResources(ctx, req.(*ListMemoResourcesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MemoService_SetMemoRelations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetMemoRelationsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MemoServiceServer).SetMemoRelations(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MemoService_SetMemoRelations_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MemoServiceServer).SetMemoRelations(ctx, req.(*SetMemoRelationsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MemoService_ListMemoRelations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListMemoRelationsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MemoServiceServer).ListMemoRelations(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MemoService_ListMemoRelations_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MemoServiceServer).ListMemoRelations(ctx, req.(*ListMemoRelationsRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _MemoService_CreateMemoComment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(CreateMemoCommentRequest) if err := dec(in); err != nil { @@ -224,6 +582,78 @@ func _MemoService_ListMemoComments_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _MemoService_GetUserMemosStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUserMemosStatsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MemoServiceServer).GetUserMemosStats(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MemoService_GetUserMemosStats_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MemoServiceServer).GetUserMemosStats(ctx, req.(*GetUserMemosStatsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MemoService_ListMemoReactions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListMemoReactionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MemoServiceServer).ListMemoReactions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MemoService_ListMemoReactions_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MemoServiceServer).ListMemoReactions(ctx, req.(*ListMemoReactionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MemoService_UpsertMemoReaction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpsertMemoReactionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MemoServiceServer).UpsertMemoReaction(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MemoService_UpsertMemoReaction_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MemoServiceServer).UpsertMemoReaction(ctx, req.(*UpsertMemoReactionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MemoService_DeleteMemoReaction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteMemoReactionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MemoServiceServer).DeleteMemoReaction(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MemoService_DeleteMemoReaction_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MemoServiceServer).DeleteMemoReaction(ctx, req.(*DeleteMemoReactionRequest)) + } + return interceptor(ctx, in, info, handler) +} + // MemoService_ServiceDesc is the grpc.ServiceDesc for MemoService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -243,6 +673,38 @@ var MemoService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetMemo", Handler: _MemoService_GetMemo_Handler, }, + { + MethodName: "GetMemoByName", + Handler: _MemoService_GetMemoByName_Handler, + }, + { + MethodName: "UpdateMemo", + Handler: _MemoService_UpdateMemo_Handler, + }, + { + MethodName: "DeleteMemo", + Handler: _MemoService_DeleteMemo_Handler, + }, + { + MethodName: "ExportMemos", + Handler: _MemoService_ExportMemos_Handler, + }, + { + MethodName: "SetMemoResources", + Handler: _MemoService_SetMemoResources_Handler, + }, + { + MethodName: "ListMemoResources", + Handler: _MemoService_ListMemoResources_Handler, + }, + { + MethodName: "SetMemoRelations", + Handler: _MemoService_SetMemoRelations_Handler, + }, + { + MethodName: "ListMemoRelations", + Handler: _MemoService_ListMemoRelations_Handler, + }, { MethodName: "CreateMemoComment", Handler: _MemoService_CreateMemoComment_Handler, @@ -251,6 +713,22 @@ var MemoService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListMemoComments", Handler: _MemoService_ListMemoComments_Handler, }, + { + MethodName: "GetUserMemosStats", + Handler: _MemoService_GetUserMemosStats_Handler, + }, + { + MethodName: "ListMemoReactions", + Handler: _MemoService_ListMemoReactions_Handler, + }, + { + MethodName: "UpsertMemoReaction", + Handler: _MemoService_UpsertMemoReaction_Handler, + }, + { + MethodName: "DeleteMemoReaction", + Handler: _MemoService_DeleteMemoReaction_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "api/v2/memo_service.proto", diff --git a/proto/gen/api/v2/reaction_service.pb.go b/proto/gen/api/v2/reaction_service.pb.go new file mode 100644 index 0000000000000..62260efd00983 --- /dev/null +++ b/proto/gen/api/v2/reaction_service.pb.go @@ -0,0 +1,280 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: api/v2/reaction_service.proto + +package apiv2 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Reaction_Type int32 + +const ( + Reaction_TYPE_UNSPECIFIED Reaction_Type = 0 + Reaction_THUMBS_UP Reaction_Type = 1 + Reaction_THUMBS_DOWN Reaction_Type = 2 + Reaction_HEART Reaction_Type = 3 + Reaction_FIRE Reaction_Type = 4 + Reaction_CLAPPING_HANDS Reaction_Type = 5 + Reaction_LAUGH Reaction_Type = 6 + Reaction_OK_HAND Reaction_Type = 7 + Reaction_ROCKET Reaction_Type = 8 + Reaction_EYES Reaction_Type = 9 + Reaction_THINKING_FACE Reaction_Type = 10 + Reaction_CLOWN_FACE Reaction_Type = 11 + Reaction_QUESTION_MARK Reaction_Type = 12 +) + +// Enum value maps for Reaction_Type. +var ( + Reaction_Type_name = map[int32]string{ + 0: "TYPE_UNSPECIFIED", + 1: "THUMBS_UP", + 2: "THUMBS_DOWN", + 3: "HEART", + 4: "FIRE", + 5: "CLAPPING_HANDS", + 6: "LAUGH", + 7: "OK_HAND", + 8: "ROCKET", + 9: "EYES", + 10: "THINKING_FACE", + 11: "CLOWN_FACE", + 12: "QUESTION_MARK", + } + Reaction_Type_value = map[string]int32{ + "TYPE_UNSPECIFIED": 0, + "THUMBS_UP": 1, + "THUMBS_DOWN": 2, + "HEART": 3, + "FIRE": 4, + "CLAPPING_HANDS": 5, + "LAUGH": 6, + "OK_HAND": 7, + "ROCKET": 8, + "EYES": 9, + "THINKING_FACE": 10, + "CLOWN_FACE": 11, + "QUESTION_MARK": 12, + } +) + +func (x Reaction_Type) Enum() *Reaction_Type { + p := new(Reaction_Type) + *p = x + return p +} + +func (x Reaction_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Reaction_Type) Descriptor() protoreflect.EnumDescriptor { + return file_api_v2_reaction_service_proto_enumTypes[0].Descriptor() +} + +func (Reaction_Type) Type() protoreflect.EnumType { + return &file_api_v2_reaction_service_proto_enumTypes[0] +} + +func (x Reaction_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Reaction_Type.Descriptor instead. +func (Reaction_Type) EnumDescriptor() ([]byte, []int) { + return file_api_v2_reaction_service_proto_rawDescGZIP(), []int{0, 0} +} + +type Reaction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Creator string `protobuf:"bytes,2,opt,name=creator,proto3" json:"creator,omitempty"` + ContentId string `protobuf:"bytes,3,opt,name=content_id,json=contentId,proto3" json:"content_id,omitempty"` + ReactionType Reaction_Type `protobuf:"varint,4,opt,name=reaction_type,json=reactionType,proto3,enum=memos.api.v2.Reaction_Type" json:"reaction_type,omitempty"` +} + +func (x *Reaction) Reset() { + *x = Reaction{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_reaction_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Reaction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Reaction) ProtoMessage() {} + +func (x *Reaction) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_reaction_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Reaction.ProtoReflect.Descriptor instead. +func (*Reaction) Descriptor() ([]byte, []int) { + return file_api_v2_reaction_service_proto_rawDescGZIP(), []int{0} +} + +func (x *Reaction) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Reaction) GetCreator() string { + if x != nil { + return x.Creator + } + return "" +} + +func (x *Reaction) GetContentId() string { + if x != nil { + return x.ContentId + } + return "" +} + +func (x *Reaction) GetReactionType() Reaction_Type { + if x != nil { + return x.ReactionType + } + return Reaction_TYPE_UNSPECIFIED +} + +var File_api_v2_reaction_service_proto protoreflect.FileDescriptor + +var file_api_v2_reaction_service_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x22, 0xe1, 0x02, + 0x0a, 0x08, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0d, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, 0xc9, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, + 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x48, 0x55, 0x4d, 0x42, 0x53, 0x5f, 0x55, + 0x50, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x48, 0x55, 0x4d, 0x42, 0x53, 0x5f, 0x44, 0x4f, + 0x57, 0x4e, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x48, 0x45, 0x41, 0x52, 0x54, 0x10, 0x03, 0x12, + 0x08, 0x0a, 0x04, 0x46, 0x49, 0x52, 0x45, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4c, 0x41, + 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x48, 0x41, 0x4e, 0x44, 0x53, 0x10, 0x05, 0x12, 0x09, 0x0a, + 0x05, 0x4c, 0x41, 0x55, 0x47, 0x48, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x4b, 0x5f, 0x48, + 0x41, 0x4e, 0x44, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x4f, 0x43, 0x4b, 0x45, 0x54, 0x10, + 0x08, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x59, 0x45, 0x53, 0x10, 0x09, 0x12, 0x11, 0x0a, 0x0d, 0x54, + 0x48, 0x49, 0x4e, 0x4b, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x41, 0x43, 0x45, 0x10, 0x0a, 0x12, 0x0e, + 0x0a, 0x0a, 0x43, 0x4c, 0x4f, 0x57, 0x4e, 0x5f, 0x46, 0x41, 0x43, 0x45, 0x10, 0x0b, 0x12, 0x11, + 0x0a, 0x0d, 0x51, 0x55, 0x45, 0x53, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x41, 0x52, 0x4b, 0x10, + 0x0c, 0x42, 0xac, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x14, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, + 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, + 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, + 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, + 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_v2_reaction_service_proto_rawDescOnce sync.Once + file_api_v2_reaction_service_proto_rawDescData = file_api_v2_reaction_service_proto_rawDesc +) + +func file_api_v2_reaction_service_proto_rawDescGZIP() []byte { + file_api_v2_reaction_service_proto_rawDescOnce.Do(func() { + file_api_v2_reaction_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_v2_reaction_service_proto_rawDescData) + }) + return file_api_v2_reaction_service_proto_rawDescData +} + +var file_api_v2_reaction_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_api_v2_reaction_service_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_api_v2_reaction_service_proto_goTypes = []interface{}{ + (Reaction_Type)(0), // 0: memos.api.v2.Reaction.Type + (*Reaction)(nil), // 1: memos.api.v2.Reaction +} +var file_api_v2_reaction_service_proto_depIdxs = []int32{ + 0, // 0: memos.api.v2.Reaction.reaction_type:type_name -> memos.api.v2.Reaction.Type + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_api_v2_reaction_service_proto_init() } +func file_api_v2_reaction_service_proto_init() { + if File_api_v2_reaction_service_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_v2_reaction_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Reaction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_v2_reaction_service_proto_rawDesc, + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_api_v2_reaction_service_proto_goTypes, + DependencyIndexes: file_api_v2_reaction_service_proto_depIdxs, + EnumInfos: file_api_v2_reaction_service_proto_enumTypes, + MessageInfos: file_api_v2_reaction_service_proto_msgTypes, + }.Build() + File_api_v2_reaction_service_proto = out.File + file_api_v2_reaction_service_proto_rawDesc = nil + file_api_v2_reaction_service_proto_goTypes = nil + file_api_v2_reaction_service_proto_depIdxs = nil +} diff --git a/proto/gen/api/v2/resource_service.pb.go b/proto/gen/api/v2/resource_service.pb.go index 790d1b800852f..24c5e356652ec 100644 --- a/proto/gen/api/v2/resource_service.pb.go +++ b/proto/gen/api/v2/resource_service.pb.go @@ -28,13 +28,16 @@ type Resource struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - CreatedTs *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=created_ts,json=createdTs,proto3" json:"created_ts,omitempty"` - Filename string `protobuf:"bytes,3,opt,name=filename,proto3" json:"filename,omitempty"` - ExternalLink string `protobuf:"bytes,4,opt,name=external_link,json=externalLink,proto3" json:"external_link,omitempty"` - Type string `protobuf:"bytes,5,opt,name=type,proto3" json:"type,omitempty"` - Size int64 `protobuf:"varint,6,opt,name=size,proto3" json:"size,omitempty"` - MemoId *int32 `protobuf:"varint,7,opt,name=memo_id,json=memoId,proto3,oneof" json:"memo_id,omitempty"` + // id is the system generated unique identifier. + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // name is the user provided name. + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + CreateTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` + Filename string `protobuf:"bytes,4,opt,name=filename,proto3" json:"filename,omitempty"` + ExternalLink string `protobuf:"bytes,5,opt,name=external_link,json=externalLink,proto3" json:"external_link,omitempty"` + Type string `protobuf:"bytes,6,opt,name=type,proto3" json:"type,omitempty"` + Size int64 `protobuf:"varint,7,opt,name=size,proto3" json:"size,omitempty"` + MemoId *int32 `protobuf:"varint,8,opt,name=memo_id,json=memoId,proto3,oneof" json:"memo_id,omitempty"` } func (x *Resource) Reset() { @@ -76,9 +79,16 @@ func (x *Resource) GetId() int32 { return 0 } -func (x *Resource) GetCreatedTs() *timestamppb.Timestamp { +func (x *Resource) GetName() string { if x != nil { - return x.CreatedTs + return x.Name + } + return "" +} + +func (x *Resource) GetCreateTime() *timestamppb.Timestamp { + if x != nil { + return x.CreateTime } return nil } @@ -321,6 +331,194 @@ func (x *ListResourcesResponse) GetResources() []*Resource { return nil } +type GetResourceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *GetResourceRequest) Reset() { + *x = GetResourceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_resource_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetResourceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetResourceRequest) ProtoMessage() {} + +func (x *GetResourceRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_resource_service_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetResourceRequest.ProtoReflect.Descriptor instead. +func (*GetResourceRequest) Descriptor() ([]byte, []int) { + return file_api_v2_resource_service_proto_rawDescGZIP(), []int{5} +} + +func (x *GetResourceRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +type GetResourceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Resource *Resource `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` +} + +func (x *GetResourceResponse) Reset() { + *x = GetResourceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_resource_service_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetResourceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetResourceResponse) ProtoMessage() {} + +func (x *GetResourceResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_resource_service_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetResourceResponse.ProtoReflect.Descriptor instead. +func (*GetResourceResponse) Descriptor() ([]byte, []int) { + return file_api_v2_resource_service_proto_rawDescGZIP(), []int{6} +} + +func (x *GetResourceResponse) GetResource() *Resource { + if x != nil { + return x.Resource + } + return nil +} + +type GetResourceByNameRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *GetResourceByNameRequest) Reset() { + *x = GetResourceByNameRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_resource_service_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetResourceByNameRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetResourceByNameRequest) ProtoMessage() {} + +func (x *GetResourceByNameRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_resource_service_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetResourceByNameRequest.ProtoReflect.Descriptor instead. +func (*GetResourceByNameRequest) Descriptor() ([]byte, []int) { + return file_api_v2_resource_service_proto_rawDescGZIP(), []int{7} +} + +func (x *GetResourceByNameRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type GetResourceByNameResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Resource *Resource `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` +} + +func (x *GetResourceByNameResponse) Reset() { + *x = GetResourceByNameResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_resource_service_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetResourceByNameResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetResourceByNameResponse) ProtoMessage() {} + +func (x *GetResourceByNameResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_resource_service_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetResourceByNameResponse.ProtoReflect.Descriptor instead. +func (*GetResourceByNameResponse) Descriptor() ([]byte, []int) { + return file_api_v2_resource_service_proto_rawDescGZIP(), []int{8} +} + +func (x *GetResourceByNameResponse) GetResource() *Resource { + if x != nil { + return x.Resource + } + return nil +} + type UpdateResourceRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -333,7 +531,7 @@ type UpdateResourceRequest struct { func (x *UpdateResourceRequest) Reset() { *x = UpdateResourceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_resource_service_proto_msgTypes[5] + mi := &file_api_v2_resource_service_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -346,7 +544,7 @@ func (x *UpdateResourceRequest) String() string { func (*UpdateResourceRequest) ProtoMessage() {} func (x *UpdateResourceRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_resource_service_proto_msgTypes[5] + mi := &file_api_v2_resource_service_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -359,7 +557,7 @@ func (x *UpdateResourceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateResourceRequest.ProtoReflect.Descriptor instead. func (*UpdateResourceRequest) Descriptor() ([]byte, []int) { - return file_api_v2_resource_service_proto_rawDescGZIP(), []int{5} + return file_api_v2_resource_service_proto_rawDescGZIP(), []int{9} } func (x *UpdateResourceRequest) GetResource() *Resource { @@ -387,7 +585,7 @@ type UpdateResourceResponse struct { func (x *UpdateResourceResponse) Reset() { *x = UpdateResourceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_resource_service_proto_msgTypes[6] + mi := &file_api_v2_resource_service_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -400,7 +598,7 @@ func (x *UpdateResourceResponse) String() string { func (*UpdateResourceResponse) ProtoMessage() {} func (x *UpdateResourceResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_resource_service_proto_msgTypes[6] + mi := &file_api_v2_resource_service_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -413,7 +611,7 @@ func (x *UpdateResourceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateResourceResponse.ProtoReflect.Descriptor instead. func (*UpdateResourceResponse) Descriptor() ([]byte, []int) { - return file_api_v2_resource_service_proto_rawDescGZIP(), []int{6} + return file_api_v2_resource_service_proto_rawDescGZIP(), []int{10} } func (x *UpdateResourceResponse) GetResource() *Resource { @@ -434,7 +632,7 @@ type DeleteResourceRequest struct { func (x *DeleteResourceRequest) Reset() { *x = DeleteResourceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_resource_service_proto_msgTypes[7] + mi := &file_api_v2_resource_service_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -447,7 +645,7 @@ func (x *DeleteResourceRequest) String() string { func (*DeleteResourceRequest) ProtoMessage() {} func (x *DeleteResourceRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_resource_service_proto_msgTypes[7] + mi := &file_api_v2_resource_service_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -460,7 +658,7 @@ func (x *DeleteResourceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteResourceRequest.ProtoReflect.Descriptor instead. func (*DeleteResourceRequest) Descriptor() ([]byte, []int) { - return file_api_v2_resource_service_proto_rawDescGZIP(), []int{7} + return file_api_v2_resource_service_proto_rawDescGZIP(), []int{11} } func (x *DeleteResourceRequest) GetId() int32 { @@ -479,7 +677,7 @@ type DeleteResourceResponse struct { func (x *DeleteResourceResponse) Reset() { *x = DeleteResourceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_resource_service_proto_msgTypes[8] + mi := &file_api_v2_resource_service_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -492,7 +690,7 @@ func (x *DeleteResourceResponse) String() string { func (*DeleteResourceResponse) ProtoMessage() {} func (x *DeleteResourceResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_resource_service_proto_msgTypes[8] + mi := &file_api_v2_resource_service_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -505,7 +703,7 @@ func (x *DeleteResourceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteResourceResponse.ProtoReflect.Descriptor instead. func (*DeleteResourceResponse) Descriptor() ([]byte, []int) { - return file_api_v2_resource_service_proto_rawDescGZIP(), []int{8} + return file_api_v2_resource_service_proto_rawDescGZIP(), []int{12} } var File_api_v2_resource_service_proto protoreflect.FileDescriptor @@ -521,106 +719,140 @@ var file_api_v2_resource_service_proto_rawDesc = []byte{ 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe8, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfe, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x54, 0x73, 0x12, - 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4c, 0x69, 0x6e, 0x6b, - 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x6f, - 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x65, 0x6d, - 0x6f, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, - 0x69, 0x64, 0x22, 0x96, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x12, 0x1c, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x05, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, - 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x69, 0x64, 0x22, 0x4c, 0x0a, 0x16, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, - 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x4d, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6c, 0x69, + 0x6e, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, + 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1c, + 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x48, + 0x00, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, + 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x69, 0x64, 0x22, 0x96, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, + 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4c, + 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, + 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, + 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x69, + 0x64, 0x22, 0x4c, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x22, 0x88, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, - 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x3b, - 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, - 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x4c, 0x0a, 0x16, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, - 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x27, 0x0a, 0x15, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, - 0x69, 0x64, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa9, 0x04, 0x0a, - 0x0f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x76, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x12, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, - 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x22, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x73, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x22, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, - 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0xa5, 0x01, - 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x12, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x48, 0xda, 0x41, 0x14, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, - 0x6d, 0x61, 0x73, 0x6b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x3a, 0x08, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x32, 0x1f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2e, 0x69, 0x64, 0x7d, 0x12, 0x80, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x23, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, - 0x12, 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x42, 0xac, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, - 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x14, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, - 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, - 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, - 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, - 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, - 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, + 0x16, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x4d, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x34, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x24, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x49, 0x0a, 0x13, + 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x2e, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x4f, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x88, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, + 0x61, 0x73, 0x6b, 0x22, 0x4c, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x22, 0x27, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xb7, 0x06, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x76, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x23, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x24, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x22, 0x11, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x12, 0x73, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x12, 0x22, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x13, 0x12, 0x11, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x77, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0xda, 0x41, 0x02, 0x69, 0x64, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x92, + 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x79, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, + 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, + 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1f, 0x12, 0x1d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x2f, 0x7b, 0x6e, 0x61, + 0x6d, 0x65, 0x7d, 0x12, 0xa5, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x48, 0xda, 0x41, 0x14, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2c, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, + 0x3a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x32, 0x1f, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x32, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x69, 0x64, 0x7d, 0x12, 0x80, 0x01, 0x0a, 0x0e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x23, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0xda, 0x41, 0x02, 0x69, 0x64, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x2a, 0x16, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x42, 0xac, + 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x42, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, + 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, + 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, + 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, + 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -635,40 +867,50 @@ func file_api_v2_resource_service_proto_rawDescGZIP() []byte { return file_api_v2_resource_service_proto_rawDescData } -var file_api_v2_resource_service_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_api_v2_resource_service_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_api_v2_resource_service_proto_goTypes = []interface{}{ - (*Resource)(nil), // 0: memos.api.v2.Resource - (*CreateResourceRequest)(nil), // 1: memos.api.v2.CreateResourceRequest - (*CreateResourceResponse)(nil), // 2: memos.api.v2.CreateResourceResponse - (*ListResourcesRequest)(nil), // 3: memos.api.v2.ListResourcesRequest - (*ListResourcesResponse)(nil), // 4: memos.api.v2.ListResourcesResponse - (*UpdateResourceRequest)(nil), // 5: memos.api.v2.UpdateResourceRequest - (*UpdateResourceResponse)(nil), // 6: memos.api.v2.UpdateResourceResponse - (*DeleteResourceRequest)(nil), // 7: memos.api.v2.DeleteResourceRequest - (*DeleteResourceResponse)(nil), // 8: memos.api.v2.DeleteResourceResponse - (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp - (*fieldmaskpb.FieldMask)(nil), // 10: google.protobuf.FieldMask + (*Resource)(nil), // 0: memos.api.v2.Resource + (*CreateResourceRequest)(nil), // 1: memos.api.v2.CreateResourceRequest + (*CreateResourceResponse)(nil), // 2: memos.api.v2.CreateResourceResponse + (*ListResourcesRequest)(nil), // 3: memos.api.v2.ListResourcesRequest + (*ListResourcesResponse)(nil), // 4: memos.api.v2.ListResourcesResponse + (*GetResourceRequest)(nil), // 5: memos.api.v2.GetResourceRequest + (*GetResourceResponse)(nil), // 6: memos.api.v2.GetResourceResponse + (*GetResourceByNameRequest)(nil), // 7: memos.api.v2.GetResourceByNameRequest + (*GetResourceByNameResponse)(nil), // 8: memos.api.v2.GetResourceByNameResponse + (*UpdateResourceRequest)(nil), // 9: memos.api.v2.UpdateResourceRequest + (*UpdateResourceResponse)(nil), // 10: memos.api.v2.UpdateResourceResponse + (*DeleteResourceRequest)(nil), // 11: memos.api.v2.DeleteResourceRequest + (*DeleteResourceResponse)(nil), // 12: memos.api.v2.DeleteResourceResponse + (*timestamppb.Timestamp)(nil), // 13: google.protobuf.Timestamp + (*fieldmaskpb.FieldMask)(nil), // 14: google.protobuf.FieldMask } var file_api_v2_resource_service_proto_depIdxs = []int32{ - 9, // 0: memos.api.v2.Resource.created_ts:type_name -> google.protobuf.Timestamp + 13, // 0: memos.api.v2.Resource.create_time:type_name -> google.protobuf.Timestamp 0, // 1: memos.api.v2.CreateResourceResponse.resource:type_name -> memos.api.v2.Resource 0, // 2: memos.api.v2.ListResourcesResponse.resources:type_name -> memos.api.v2.Resource - 0, // 3: memos.api.v2.UpdateResourceRequest.resource:type_name -> memos.api.v2.Resource - 10, // 4: memos.api.v2.UpdateResourceRequest.update_mask:type_name -> google.protobuf.FieldMask - 0, // 5: memos.api.v2.UpdateResourceResponse.resource:type_name -> memos.api.v2.Resource - 1, // 6: memos.api.v2.ResourceService.CreateResource:input_type -> memos.api.v2.CreateResourceRequest - 3, // 7: memos.api.v2.ResourceService.ListResources:input_type -> memos.api.v2.ListResourcesRequest - 5, // 8: memos.api.v2.ResourceService.UpdateResource:input_type -> memos.api.v2.UpdateResourceRequest - 7, // 9: memos.api.v2.ResourceService.DeleteResource:input_type -> memos.api.v2.DeleteResourceRequest - 2, // 10: memos.api.v2.ResourceService.CreateResource:output_type -> memos.api.v2.CreateResourceResponse - 4, // 11: memos.api.v2.ResourceService.ListResources:output_type -> memos.api.v2.ListResourcesResponse - 6, // 12: memos.api.v2.ResourceService.UpdateResource:output_type -> memos.api.v2.UpdateResourceResponse - 8, // 13: memos.api.v2.ResourceService.DeleteResource:output_type -> memos.api.v2.DeleteResourceResponse - 10, // [10:14] is the sub-list for method output_type - 6, // [6:10] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 0, // 3: memos.api.v2.GetResourceResponse.resource:type_name -> memos.api.v2.Resource + 0, // 4: memos.api.v2.GetResourceByNameResponse.resource:type_name -> memos.api.v2.Resource + 0, // 5: memos.api.v2.UpdateResourceRequest.resource:type_name -> memos.api.v2.Resource + 14, // 6: memos.api.v2.UpdateResourceRequest.update_mask:type_name -> google.protobuf.FieldMask + 0, // 7: memos.api.v2.UpdateResourceResponse.resource:type_name -> memos.api.v2.Resource + 1, // 8: memos.api.v2.ResourceService.CreateResource:input_type -> memos.api.v2.CreateResourceRequest + 3, // 9: memos.api.v2.ResourceService.ListResources:input_type -> memos.api.v2.ListResourcesRequest + 5, // 10: memos.api.v2.ResourceService.GetResource:input_type -> memos.api.v2.GetResourceRequest + 7, // 11: memos.api.v2.ResourceService.GetResourceByName:input_type -> memos.api.v2.GetResourceByNameRequest + 9, // 12: memos.api.v2.ResourceService.UpdateResource:input_type -> memos.api.v2.UpdateResourceRequest + 11, // 13: memos.api.v2.ResourceService.DeleteResource:input_type -> memos.api.v2.DeleteResourceRequest + 2, // 14: memos.api.v2.ResourceService.CreateResource:output_type -> memos.api.v2.CreateResourceResponse + 4, // 15: memos.api.v2.ResourceService.ListResources:output_type -> memos.api.v2.ListResourcesResponse + 6, // 16: memos.api.v2.ResourceService.GetResource:output_type -> memos.api.v2.GetResourceResponse + 8, // 17: memos.api.v2.ResourceService.GetResourceByName:output_type -> memos.api.v2.GetResourceByNameResponse + 10, // 18: memos.api.v2.ResourceService.UpdateResource:output_type -> memos.api.v2.UpdateResourceResponse + 12, // 19: memos.api.v2.ResourceService.DeleteResource:output_type -> memos.api.v2.DeleteResourceResponse + 14, // [14:20] is the sub-list for method output_type + 8, // [8:14] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name } func init() { file_api_v2_resource_service_proto_init() } @@ -738,7 +980,7 @@ func file_api_v2_resource_service_proto_init() { } } file_api_v2_resource_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateResourceRequest); i { + switch v := v.(*GetResourceRequest); i { case 0: return &v.state case 1: @@ -750,7 +992,7 @@ func file_api_v2_resource_service_proto_init() { } } file_api_v2_resource_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateResourceResponse); i { + switch v := v.(*GetResourceResponse); i { case 0: return &v.state case 1: @@ -762,7 +1004,7 @@ func file_api_v2_resource_service_proto_init() { } } file_api_v2_resource_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteResourceRequest); i { + switch v := v.(*GetResourceByNameRequest); i { case 0: return &v.state case 1: @@ -774,6 +1016,54 @@ func file_api_v2_resource_service_proto_init() { } } file_api_v2_resource_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetResourceByNameResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_resource_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateResourceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_resource_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateResourceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_resource_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteResourceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_resource_service_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DeleteResourceResponse); i { case 0: return &v.state @@ -794,7 +1084,7 @@ func file_api_v2_resource_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_v2_resource_service_proto_rawDesc, NumEnums: 0, - NumMessages: 9, + NumMessages: 13, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gen/api/v2/resource_service.pb.gw.go b/proto/gen/api/v2/resource_service.pb.gw.go index 3ca23e2c28995..0e980a9efa0aa 100644 --- a/proto/gen/api/v2/resource_service.pb.gw.go +++ b/proto/gen/api/v2/resource_service.pb.gw.go @@ -85,6 +85,110 @@ func local_request_ResourceService_ListResources_0(ctx context.Context, marshale } +func request_ResourceService_GetResource_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetResourceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.GetResource(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ResourceService_GetResource_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetResourceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.GetResource(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ResourceService_GetResourceByName_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetResourceByNameRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := client.GetResourceByName(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ResourceService_GetResourceByName_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetResourceByNameRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := server.GetResourceByName(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_ResourceService_UpdateResource_0 = &utilities.DoubleArray{Encoding: map[string]int{"resource": 0, "id": 1}, Base: []int{1, 4, 5, 2, 0, 0, 0, 0}, Check: []int{0, 1, 1, 2, 4, 2, 2, 3}} ) @@ -293,6 +397,56 @@ func RegisterResourceServiceHandlerServer(ctx context.Context, mux *runtime.Serv }) + mux.Handle("GET", pattern_ResourceService_GetResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.ResourceService/GetResource", runtime.WithHTTPPathPattern("/api/v2/resources/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ResourceService_GetResource_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_GetResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_ResourceService_GetResourceByName_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.ResourceService/GetResourceByName", runtime.WithHTTPPathPattern("/api/v2/resources/name/{name}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ResourceService_GetResourceByName_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_GetResourceByName_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("PATCH", pattern_ResourceService_UpdateResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -318,7 +472,7 @@ func RegisterResourceServiceHandlerServer(ctx context.Context, mux *runtime.Serv }) - mux.Handle("GET", pattern_ResourceService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("DELETE", pattern_ResourceService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -428,6 +582,50 @@ func RegisterResourceServiceHandlerClient(ctx context.Context, mux *runtime.Serv }) + mux.Handle("GET", pattern_ResourceService_GetResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.ResourceService/GetResource", runtime.WithHTTPPathPattern("/api/v2/resources/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ResourceService_GetResource_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_GetResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_ResourceService_GetResourceByName_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.ResourceService/GetResourceByName", runtime.WithHTTPPathPattern("/api/v2/resources/name/{name}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ResourceService_GetResourceByName_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_GetResourceByName_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("PATCH", pattern_ResourceService_UpdateResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -450,7 +648,7 @@ func RegisterResourceServiceHandlerClient(ctx context.Context, mux *runtime.Serv }) - mux.Handle("GET", pattern_ResourceService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("DELETE", pattern_ResourceService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -480,6 +678,10 @@ var ( pattern_ResourceService_ListResources_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "resources"}, "")) + pattern_ResourceService_GetResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "resources", "id"}, "")) + + pattern_ResourceService_GetResourceByName_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "resources", "name"}, "")) + pattern_ResourceService_UpdateResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "resources", "resource.id"}, "")) pattern_ResourceService_DeleteResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "resources", "id"}, "")) @@ -490,6 +692,10 @@ var ( forward_ResourceService_ListResources_0 = runtime.ForwardResponseMessage + forward_ResourceService_GetResource_0 = runtime.ForwardResponseMessage + + forward_ResourceService_GetResourceByName_0 = runtime.ForwardResponseMessage + forward_ResourceService_UpdateResource_0 = runtime.ForwardResponseMessage forward_ResourceService_DeleteResource_0 = runtime.ForwardResponseMessage diff --git a/proto/gen/api/v2/resource_service_grpc.pb.go b/proto/gen/api/v2/resource_service_grpc.pb.go index dbaf4a0a6d799..3cb293fffbb51 100644 --- a/proto/gen/api/v2/resource_service_grpc.pb.go +++ b/proto/gen/api/v2/resource_service_grpc.pb.go @@ -19,19 +19,29 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - ResourceService_CreateResource_FullMethodName = "/memos.api.v2.ResourceService/CreateResource" - ResourceService_ListResources_FullMethodName = "/memos.api.v2.ResourceService/ListResources" - ResourceService_UpdateResource_FullMethodName = "/memos.api.v2.ResourceService/UpdateResource" - ResourceService_DeleteResource_FullMethodName = "/memos.api.v2.ResourceService/DeleteResource" + ResourceService_CreateResource_FullMethodName = "/memos.api.v2.ResourceService/CreateResource" + ResourceService_ListResources_FullMethodName = "/memos.api.v2.ResourceService/ListResources" + ResourceService_GetResource_FullMethodName = "/memos.api.v2.ResourceService/GetResource" + ResourceService_GetResourceByName_FullMethodName = "/memos.api.v2.ResourceService/GetResourceByName" + ResourceService_UpdateResource_FullMethodName = "/memos.api.v2.ResourceService/UpdateResource" + ResourceService_DeleteResource_FullMethodName = "/memos.api.v2.ResourceService/DeleteResource" ) // ResourceServiceClient is the client API for ResourceService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type ResourceServiceClient interface { + // CreateResource creates a new resource. CreateResource(ctx context.Context, in *CreateResourceRequest, opts ...grpc.CallOption) (*CreateResourceResponse, error) + // ListResources lists all resources. ListResources(ctx context.Context, in *ListResourcesRequest, opts ...grpc.CallOption) (*ListResourcesResponse, error) + // GetResource returns a resource by id. + GetResource(ctx context.Context, in *GetResourceRequest, opts ...grpc.CallOption) (*GetResourceResponse, error) + // GetResourceByName returns a resource by name. + GetResourceByName(ctx context.Context, in *GetResourceByNameRequest, opts ...grpc.CallOption) (*GetResourceByNameResponse, error) + // UpdateResource updates a resource. UpdateResource(ctx context.Context, in *UpdateResourceRequest, opts ...grpc.CallOption) (*UpdateResourceResponse, error) + // DeleteResource deletes a resource by id. DeleteResource(ctx context.Context, in *DeleteResourceRequest, opts ...grpc.CallOption) (*DeleteResourceResponse, error) } @@ -61,6 +71,24 @@ func (c *resourceServiceClient) ListResources(ctx context.Context, in *ListResou return out, nil } +func (c *resourceServiceClient) GetResource(ctx context.Context, in *GetResourceRequest, opts ...grpc.CallOption) (*GetResourceResponse, error) { + out := new(GetResourceResponse) + err := c.cc.Invoke(ctx, ResourceService_GetResource_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceServiceClient) GetResourceByName(ctx context.Context, in *GetResourceByNameRequest, opts ...grpc.CallOption) (*GetResourceByNameResponse, error) { + out := new(GetResourceByNameResponse) + err := c.cc.Invoke(ctx, ResourceService_GetResourceByName_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *resourceServiceClient) UpdateResource(ctx context.Context, in *UpdateResourceRequest, opts ...grpc.CallOption) (*UpdateResourceResponse, error) { out := new(UpdateResourceResponse) err := c.cc.Invoke(ctx, ResourceService_UpdateResource_FullMethodName, in, out, opts...) @@ -83,9 +111,17 @@ func (c *resourceServiceClient) DeleteResource(ctx context.Context, in *DeleteRe // All implementations must embed UnimplementedResourceServiceServer // for forward compatibility type ResourceServiceServer interface { + // CreateResource creates a new resource. CreateResource(context.Context, *CreateResourceRequest) (*CreateResourceResponse, error) + // ListResources lists all resources. ListResources(context.Context, *ListResourcesRequest) (*ListResourcesResponse, error) + // GetResource returns a resource by id. + GetResource(context.Context, *GetResourceRequest) (*GetResourceResponse, error) + // GetResourceByName returns a resource by name. + GetResourceByName(context.Context, *GetResourceByNameRequest) (*GetResourceByNameResponse, error) + // UpdateResource updates a resource. UpdateResource(context.Context, *UpdateResourceRequest) (*UpdateResourceResponse, error) + // DeleteResource deletes a resource by id. DeleteResource(context.Context, *DeleteResourceRequest) (*DeleteResourceResponse, error) mustEmbedUnimplementedResourceServiceServer() } @@ -100,6 +136,12 @@ func (UnimplementedResourceServiceServer) CreateResource(context.Context, *Creat func (UnimplementedResourceServiceServer) ListResources(context.Context, *ListResourcesRequest) (*ListResourcesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListResources not implemented") } +func (UnimplementedResourceServiceServer) GetResource(context.Context, *GetResourceRequest) (*GetResourceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetResource not implemented") +} +func (UnimplementedResourceServiceServer) GetResourceByName(context.Context, *GetResourceByNameRequest) (*GetResourceByNameResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetResourceByName not implemented") +} func (UnimplementedResourceServiceServer) UpdateResource(context.Context, *UpdateResourceRequest) (*UpdateResourceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateResource not implemented") } @@ -155,6 +197,42 @@ func _ResourceService_ListResources_Handler(srv interface{}, ctx context.Context return interceptor(ctx, in, info, handler) } +func _ResourceService_GetResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetResourceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceServiceServer).GetResource(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ResourceService_GetResource_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceServiceServer).GetResource(ctx, req.(*GetResourceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceService_GetResourceByName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetResourceByNameRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceServiceServer).GetResourceByName(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ResourceService_GetResourceByName_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceServiceServer).GetResourceByName(ctx, req.(*GetResourceByNameRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _ResourceService_UpdateResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(UpdateResourceRequest) if err := dec(in); err != nil { @@ -206,6 +284,14 @@ var ResourceService_ServiceDesc = grpc.ServiceDesc{ MethodName: "ListResources", Handler: _ResourceService_ListResources_Handler, }, + { + MethodName: "GetResource", + Handler: _ResourceService_GetResource_Handler, + }, + { + MethodName: "GetResourceByName", + Handler: _ResourceService_GetResourceByName_Handler, + }, { MethodName: "UpdateResource", Handler: _ResourceService_UpdateResource_Handler, diff --git a/proto/gen/api/v2/system_service.pb.go b/proto/gen/api/v2/system_service.pb.go deleted file mode 100644 index 3a9fedddefb75..0000000000000 --- a/proto/gen/api/v2/system_service.pb.go +++ /dev/null @@ -1,513 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.31.0 -// protoc (unknown) -// source: api/v2/system_service.proto - -package apiv2 - -import ( - _ "google.golang.org/genproto/googleapis/api/annotations" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type SystemInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` - Mode string `protobuf:"bytes,2,opt,name=mode,proto3" json:"mode,omitempty"` - AllowRegistration bool `protobuf:"varint,3,opt,name=allow_registration,json=allowRegistration,proto3" json:"allow_registration,omitempty"` - DisablePasswordLogin bool `protobuf:"varint,4,opt,name=disable_password_login,json=disablePasswordLogin,proto3" json:"disable_password_login,omitempty"` - AdditionalScript string `protobuf:"bytes,5,opt,name=additional_script,json=additionalScript,proto3" json:"additional_script,omitempty"` - AdditionalStyle string `protobuf:"bytes,6,opt,name=additional_style,json=additionalStyle,proto3" json:"additional_style,omitempty"` - DbSize int64 `protobuf:"varint,7,opt,name=db_size,json=dbSize,proto3" json:"db_size,omitempty"` -} - -func (x *SystemInfo) Reset() { - *x = SystemInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_system_service_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SystemInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SystemInfo) ProtoMessage() {} - -func (x *SystemInfo) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_system_service_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SystemInfo.ProtoReflect.Descriptor instead. -func (*SystemInfo) Descriptor() ([]byte, []int) { - return file_api_v2_system_service_proto_rawDescGZIP(), []int{0} -} - -func (x *SystemInfo) GetVersion() string { - if x != nil { - return x.Version - } - return "" -} - -func (x *SystemInfo) GetMode() string { - if x != nil { - return x.Mode - } - return "" -} - -func (x *SystemInfo) GetAllowRegistration() bool { - if x != nil { - return x.AllowRegistration - } - return false -} - -func (x *SystemInfo) GetDisablePasswordLogin() bool { - if x != nil { - return x.DisablePasswordLogin - } - return false -} - -func (x *SystemInfo) GetAdditionalScript() string { - if x != nil { - return x.AdditionalScript - } - return "" -} - -func (x *SystemInfo) GetAdditionalStyle() string { - if x != nil { - return x.AdditionalStyle - } - return "" -} - -func (x *SystemInfo) GetDbSize() int64 { - if x != nil { - return x.DbSize - } - return 0 -} - -type GetSystemInfoRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *GetSystemInfoRequest) Reset() { - *x = GetSystemInfoRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_system_service_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetSystemInfoRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetSystemInfoRequest) ProtoMessage() {} - -func (x *GetSystemInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_system_service_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetSystemInfoRequest.ProtoReflect.Descriptor instead. -func (*GetSystemInfoRequest) Descriptor() ([]byte, []int) { - return file_api_v2_system_service_proto_rawDescGZIP(), []int{1} -} - -type GetSystemInfoResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - SystemInfo *SystemInfo `protobuf:"bytes,1,opt,name=system_info,json=systemInfo,proto3" json:"system_info,omitempty"` -} - -func (x *GetSystemInfoResponse) Reset() { - *x = GetSystemInfoResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_system_service_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetSystemInfoResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetSystemInfoResponse) ProtoMessage() {} - -func (x *GetSystemInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_system_service_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetSystemInfoResponse.ProtoReflect.Descriptor instead. -func (*GetSystemInfoResponse) Descriptor() ([]byte, []int) { - return file_api_v2_system_service_proto_rawDescGZIP(), []int{2} -} - -func (x *GetSystemInfoResponse) GetSystemInfo() *SystemInfo { - if x != nil { - return x.SystemInfo - } - return nil -} - -type UpdateSystemInfoRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // System info is the updated data. - SystemInfo *SystemInfo `protobuf:"bytes,1,opt,name=system_info,json=systemInfo,proto3" json:"system_info,omitempty"` - UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` -} - -func (x *UpdateSystemInfoRequest) Reset() { - *x = UpdateSystemInfoRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_system_service_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateSystemInfoRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateSystemInfoRequest) ProtoMessage() {} - -func (x *UpdateSystemInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_system_service_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateSystemInfoRequest.ProtoReflect.Descriptor instead. -func (*UpdateSystemInfoRequest) Descriptor() ([]byte, []int) { - return file_api_v2_system_service_proto_rawDescGZIP(), []int{3} -} - -func (x *UpdateSystemInfoRequest) GetSystemInfo() *SystemInfo { - if x != nil { - return x.SystemInfo - } - return nil -} - -func (x *UpdateSystemInfoRequest) GetUpdateMask() *fieldmaskpb.FieldMask { - if x != nil { - return x.UpdateMask - } - return nil -} - -type UpdateSystemInfoResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - SystemInfo *SystemInfo `protobuf:"bytes,1,opt,name=system_info,json=systemInfo,proto3" json:"system_info,omitempty"` -} - -func (x *UpdateSystemInfoResponse) Reset() { - *x = UpdateSystemInfoResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_api_v2_system_service_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateSystemInfoResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateSystemInfoResponse) ProtoMessage() {} - -func (x *UpdateSystemInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_system_service_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateSystemInfoResponse.ProtoReflect.Descriptor instead. -func (*UpdateSystemInfoResponse) Descriptor() ([]byte, []int) { - return file_api_v2_system_service_proto_rawDescGZIP(), []int{4} -} - -func (x *UpdateSystemInfoResponse) GetSystemInfo() *SystemInfo { - if x != nil { - return x.SystemInfo - } - return nil -} - -var File_api_v2_system_service_proto protoreflect.FileDescriptor - -var file_api_v2_system_service_proto_rawDesc = []byte{ - 0x0a, 0x1b, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x6d, - 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x90, 0x02, 0x0a, 0x0a, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, - 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, - 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x61, - 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x34, 0x0a, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x73, 0x73, - 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x14, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x10, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, - 0x6c, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x61, - 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x12, 0x17, - 0x0a, 0x07, 0x64, 0x62, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x06, 0x64, 0x62, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x16, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x53, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0x52, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, - 0x6e, 0x66, 0x6f, 0x22, 0x91, 0x01, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x39, 0x0a, 0x0b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, - 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x55, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x6e, - 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x32, 0xae, - 0x02, 0x0a, 0x0d, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x12, 0x75, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, - 0x6f, 0x12, 0x22, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, - 0x2e, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x15, 0x12, 0x13, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0xa5, 0x01, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x25, 0x2e, 0x6d, - 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0xda, 0x41, 0x17, - 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x2c, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x3a, 0x0b, 0x73, - 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x32, 0x13, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x76, 0x32, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x42, - 0xaa, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x32, 0x42, 0x12, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, - 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, - 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, - 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, - 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_api_v2_system_service_proto_rawDescOnce sync.Once - file_api_v2_system_service_proto_rawDescData = file_api_v2_system_service_proto_rawDesc -) - -func file_api_v2_system_service_proto_rawDescGZIP() []byte { - file_api_v2_system_service_proto_rawDescOnce.Do(func() { - file_api_v2_system_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_v2_system_service_proto_rawDescData) - }) - return file_api_v2_system_service_proto_rawDescData -} - -var file_api_v2_system_service_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_api_v2_system_service_proto_goTypes = []interface{}{ - (*SystemInfo)(nil), // 0: memos.api.v2.SystemInfo - (*GetSystemInfoRequest)(nil), // 1: memos.api.v2.GetSystemInfoRequest - (*GetSystemInfoResponse)(nil), // 2: memos.api.v2.GetSystemInfoResponse - (*UpdateSystemInfoRequest)(nil), // 3: memos.api.v2.UpdateSystemInfoRequest - (*UpdateSystemInfoResponse)(nil), // 4: memos.api.v2.UpdateSystemInfoResponse - (*fieldmaskpb.FieldMask)(nil), // 5: google.protobuf.FieldMask -} -var file_api_v2_system_service_proto_depIdxs = []int32{ - 0, // 0: memos.api.v2.GetSystemInfoResponse.system_info:type_name -> memos.api.v2.SystemInfo - 0, // 1: memos.api.v2.UpdateSystemInfoRequest.system_info:type_name -> memos.api.v2.SystemInfo - 5, // 2: memos.api.v2.UpdateSystemInfoRequest.update_mask:type_name -> google.protobuf.FieldMask - 0, // 3: memos.api.v2.UpdateSystemInfoResponse.system_info:type_name -> memos.api.v2.SystemInfo - 1, // 4: memos.api.v2.SystemService.GetSystemInfo:input_type -> memos.api.v2.GetSystemInfoRequest - 3, // 5: memos.api.v2.SystemService.UpdateSystemInfo:input_type -> memos.api.v2.UpdateSystemInfoRequest - 2, // 6: memos.api.v2.SystemService.GetSystemInfo:output_type -> memos.api.v2.GetSystemInfoResponse - 4, // 7: memos.api.v2.SystemService.UpdateSystemInfo:output_type -> memos.api.v2.UpdateSystemInfoResponse - 6, // [6:8] is the sub-list for method output_type - 4, // [4:6] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name -} - -func init() { file_api_v2_system_service_proto_init() } -func file_api_v2_system_service_proto_init() { - if File_api_v2_system_service_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_api_v2_system_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SystemInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_system_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSystemInfoRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_system_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetSystemInfoResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_system_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateSystemInfoRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_api_v2_system_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateSystemInfoResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_api_v2_system_service_proto_rawDesc, - NumEnums: 0, - NumMessages: 5, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_api_v2_system_service_proto_goTypes, - DependencyIndexes: file_api_v2_system_service_proto_depIdxs, - MessageInfos: file_api_v2_system_service_proto_msgTypes, - }.Build() - File_api_v2_system_service_proto = out.File - file_api_v2_system_service_proto_rawDesc = nil - file_api_v2_system_service_proto_goTypes = nil - file_api_v2_system_service_proto_depIdxs = nil -} diff --git a/proto/gen/api/v2/system_service.pb.gw.go b/proto/gen/api/v2/system_service.pb.gw.go deleted file mode 100644 index dce748e205727..0000000000000 --- a/proto/gen/api/v2/system_service.pb.gw.go +++ /dev/null @@ -1,272 +0,0 @@ -// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: api/v2/system_service.proto - -/* -Package apiv2 is a reverse proxy. - -It translates gRPC into RESTful JSON APIs. -*/ -package apiv2 - -import ( - "context" - "io" - "net/http" - - "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" - "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" -) - -// Suppress "imported and not used" errors -var _ codes.Code -var _ io.Reader -var _ status.Status -var _ = runtime.String -var _ = utilities.NewDoubleArray -var _ = metadata.Join - -func request_SystemService_GetSystemInfo_0(ctx context.Context, marshaler runtime.Marshaler, client SystemServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq GetSystemInfoRequest - var metadata runtime.ServerMetadata - - msg, err := client.GetSystemInfo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_SystemService_GetSystemInfo_0(ctx context.Context, marshaler runtime.Marshaler, server SystemServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq GetSystemInfoRequest - var metadata runtime.ServerMetadata - - msg, err := server.GetSystemInfo(ctx, &protoReq) - return msg, metadata, err - -} - -var ( - filter_SystemService_UpdateSystemInfo_0 = &utilities.DoubleArray{Encoding: map[string]int{"system_info": 0, "systemInfo": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} -) - -func request_SystemService_UpdateSystemInfo_0(ctx context.Context, marshaler runtime.Marshaler, client SystemServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq UpdateSystemInfoRequest - var metadata runtime.ServerMetadata - - newReader, berr := utilities.IOReaderFactory(req.Body) - if berr != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) - } - if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.SystemInfo); err != nil && err != io.EOF { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 { - if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.SystemInfo); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } else { - protoReq.UpdateMask = fieldMask - } - } - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_SystemService_UpdateSystemInfo_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.UpdateSystemInfo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_SystemService_UpdateSystemInfo_0(ctx context.Context, marshaler runtime.Marshaler, server SystemServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq UpdateSystemInfoRequest - var metadata runtime.ServerMetadata - - newReader, berr := utilities.IOReaderFactory(req.Body) - if berr != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) - } - if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.SystemInfo); err != nil && err != io.EOF { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 { - if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.SystemInfo); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } else { - protoReq.UpdateMask = fieldMask - } - } - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_SystemService_UpdateSystemInfo_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := server.UpdateSystemInfo(ctx, &protoReq) - return msg, metadata, err - -} - -// RegisterSystemServiceHandlerServer registers the http handlers for service SystemService to "mux". -// UnaryRPC :call SystemServiceServer directly. -// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. -// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterSystemServiceHandlerFromEndpoint instead. -func RegisterSystemServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server SystemServiceServer) error { - - mux.Handle("GET", pattern_SystemService_GetSystemInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - var err error - var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.SystemService/GetSystemInfo", runtime.WithHTTPPathPattern("/api/v2/system/info")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_SystemService_GetSystemInfo_0(annotatedContext, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) - if err != nil { - runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) - return - } - - forward_SystemService_GetSystemInfo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("PATCH", pattern_SystemService_UpdateSystemInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - var err error - var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.SystemService/UpdateSystemInfo", runtime.WithHTTPPathPattern("/api/v2/system/info")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_SystemService_UpdateSystemInfo_0(annotatedContext, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) - if err != nil { - runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) - return - } - - forward_SystemService_UpdateSystemInfo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -// RegisterSystemServiceHandlerFromEndpoint is same as RegisterSystemServiceHandler but -// automatically dials to "endpoint" and closes the connection when "ctx" gets done. -func RegisterSystemServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.DialContext(ctx, endpoint, opts...) - if err != nil { - return err - } - defer func() { - if err != nil { - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - return - } - go func() { - <-ctx.Done() - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - }() - }() - - return RegisterSystemServiceHandler(ctx, mux, conn) -} - -// RegisterSystemServiceHandler registers the http handlers for service SystemService to "mux". -// The handlers forward requests to the grpc endpoint over "conn". -func RegisterSystemServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { - return RegisterSystemServiceHandlerClient(ctx, mux, NewSystemServiceClient(conn)) -} - -// RegisterSystemServiceHandlerClient registers the http handlers for service SystemService -// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "SystemServiceClient". -// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "SystemServiceClient" -// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "SystemServiceClient" to call the correct interceptors. -func RegisterSystemServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client SystemServiceClient) error { - - mux.Handle("GET", pattern_SystemService_GetSystemInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - var err error - var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.SystemService/GetSystemInfo", runtime.WithHTTPPathPattern("/api/v2/system/info")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_SystemService_GetSystemInfo_0(annotatedContext, inboundMarshaler, client, req, pathParams) - annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) - if err != nil { - runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) - return - } - - forward_SystemService_GetSystemInfo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("PATCH", pattern_SystemService_UpdateSystemInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - var err error - var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.SystemService/UpdateSystemInfo", runtime.WithHTTPPathPattern("/api/v2/system/info")) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_SystemService_UpdateSystemInfo_0(annotatedContext, inboundMarshaler, client, req, pathParams) - annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) - if err != nil { - runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) - return - } - - forward_SystemService_UpdateSystemInfo_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -var ( - pattern_SystemService_GetSystemInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v2", "system", "info"}, "")) - - pattern_SystemService_UpdateSystemInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v2", "system", "info"}, "")) -) - -var ( - forward_SystemService_GetSystemInfo_0 = runtime.ForwardResponseMessage - - forward_SystemService_UpdateSystemInfo_0 = runtime.ForwardResponseMessage -) diff --git a/proto/gen/api/v2/system_service_grpc.pb.go b/proto/gen/api/v2/system_service_grpc.pb.go deleted file mode 100644 index d2cee7a9b24b2..0000000000000 --- a/proto/gen/api/v2/system_service_grpc.pb.go +++ /dev/null @@ -1,146 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.3.0 -// - protoc (unknown) -// source: api/v2/system_service.proto - -package apiv2 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -const ( - SystemService_GetSystemInfo_FullMethodName = "/memos.api.v2.SystemService/GetSystemInfo" - SystemService_UpdateSystemInfo_FullMethodName = "/memos.api.v2.SystemService/UpdateSystemInfo" -) - -// SystemServiceClient is the client API for SystemService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type SystemServiceClient interface { - GetSystemInfo(ctx context.Context, in *GetSystemInfoRequest, opts ...grpc.CallOption) (*GetSystemInfoResponse, error) - UpdateSystemInfo(ctx context.Context, in *UpdateSystemInfoRequest, opts ...grpc.CallOption) (*UpdateSystemInfoResponse, error) -} - -type systemServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewSystemServiceClient(cc grpc.ClientConnInterface) SystemServiceClient { - return &systemServiceClient{cc} -} - -func (c *systemServiceClient) GetSystemInfo(ctx context.Context, in *GetSystemInfoRequest, opts ...grpc.CallOption) (*GetSystemInfoResponse, error) { - out := new(GetSystemInfoResponse) - err := c.cc.Invoke(ctx, SystemService_GetSystemInfo_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *systemServiceClient) UpdateSystemInfo(ctx context.Context, in *UpdateSystemInfoRequest, opts ...grpc.CallOption) (*UpdateSystemInfoResponse, error) { - out := new(UpdateSystemInfoResponse) - err := c.cc.Invoke(ctx, SystemService_UpdateSystemInfo_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// SystemServiceServer is the server API for SystemService service. -// All implementations must embed UnimplementedSystemServiceServer -// for forward compatibility -type SystemServiceServer interface { - GetSystemInfo(context.Context, *GetSystemInfoRequest) (*GetSystemInfoResponse, error) - UpdateSystemInfo(context.Context, *UpdateSystemInfoRequest) (*UpdateSystemInfoResponse, error) - mustEmbedUnimplementedSystemServiceServer() -} - -// UnimplementedSystemServiceServer must be embedded to have forward compatible implementations. -type UnimplementedSystemServiceServer struct { -} - -func (UnimplementedSystemServiceServer) GetSystemInfo(context.Context, *GetSystemInfoRequest) (*GetSystemInfoResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetSystemInfo not implemented") -} -func (UnimplementedSystemServiceServer) UpdateSystemInfo(context.Context, *UpdateSystemInfoRequest) (*UpdateSystemInfoResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UpdateSystemInfo not implemented") -} -func (UnimplementedSystemServiceServer) mustEmbedUnimplementedSystemServiceServer() {} - -// UnsafeSystemServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to SystemServiceServer will -// result in compilation errors. -type UnsafeSystemServiceServer interface { - mustEmbedUnimplementedSystemServiceServer() -} - -func RegisterSystemServiceServer(s grpc.ServiceRegistrar, srv SystemServiceServer) { - s.RegisterService(&SystemService_ServiceDesc, srv) -} - -func _SystemService_GetSystemInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetSystemInfoRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(SystemServiceServer).GetSystemInfo(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: SystemService_GetSystemInfo_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SystemServiceServer).GetSystemInfo(ctx, req.(*GetSystemInfoRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _SystemService_UpdateSystemInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UpdateSystemInfoRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(SystemServiceServer).UpdateSystemInfo(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: SystemService_UpdateSystemInfo_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SystemServiceServer).UpdateSystemInfo(ctx, req.(*UpdateSystemInfoRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// SystemService_ServiceDesc is the grpc.ServiceDesc for SystemService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var SystemService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "memos.api.v2.SystemService", - HandlerType: (*SystemServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "GetSystemInfo", - Handler: _SystemService_GetSystemInfo_Handler, - }, - { - MethodName: "UpdateSystemInfo", - Handler: _SystemService_UpdateSystemInfo_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "api/v2/system_service.proto", -} diff --git a/proto/gen/api/v2/tag_service.pb.go b/proto/gen/api/v2/tag_service.pb.go index cd4d9bf395eca..e71d997cc89b6 100644 --- a/proto/gen/api/v2/tag_service.pb.go +++ b/proto/gen/api/v2/tag_service.pb.go @@ -26,8 +26,10 @@ type Tag struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - CreatorId int32 `protobuf:"varint,2,opt,name=creator_id,json=creatorId,proto3" json:"creator_id,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // The creator of tags. + // Format: users/{username} + Creator string `protobuf:"bytes,2,opt,name=creator,proto3" json:"creator,omitempty"` } func (x *Tag) Reset() { @@ -69,11 +71,11 @@ func (x *Tag) GetName() string { return "" } -func (x *Tag) GetCreatorId() int32 { +func (x *Tag) GetCreator() string { if x != nil { - return x.CreatorId + return x.Creator } - return 0 + return "" } type UpsertTagRequest struct { @@ -170,18 +172,105 @@ func (x *UpsertTagResponse) GetTag() *Tag { return nil } +type BatchUpsertTagRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Requests []*UpsertTagRequest `protobuf:"bytes,1,rep,name=requests,proto3" json:"requests,omitempty"` +} + +func (x *BatchUpsertTagRequest) Reset() { + *x = BatchUpsertTagRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_tag_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchUpsertTagRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchUpsertTagRequest) ProtoMessage() {} + +func (x *BatchUpsertTagRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_tag_service_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchUpsertTagRequest.ProtoReflect.Descriptor instead. +func (*BatchUpsertTagRequest) Descriptor() ([]byte, []int) { + return file_api_v2_tag_service_proto_rawDescGZIP(), []int{3} +} + +func (x *BatchUpsertTagRequest) GetRequests() []*UpsertTagRequest { + if x != nil { + return x.Requests + } + return nil +} + +type BatchUpsertTagResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *BatchUpsertTagResponse) Reset() { + *x = BatchUpsertTagResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_tag_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchUpsertTagResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchUpsertTagResponse) ProtoMessage() {} + +func (x *BatchUpsertTagResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_tag_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchUpsertTagResponse.ProtoReflect.Descriptor instead. +func (*BatchUpsertTagResponse) Descriptor() ([]byte, []int) { + return file_api_v2_tag_service_proto_rawDescGZIP(), []int{4} +} + type ListTagsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - CreatorId int32 `protobuf:"varint,1,opt,name=creator_id,json=creatorId,proto3" json:"creator_id,omitempty"` + // The creator of tags. + // Format: users/{username} + User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` } func (x *ListTagsRequest) Reset() { *x = ListTagsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_tag_service_proto_msgTypes[3] + mi := &file_api_v2_tag_service_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -194,7 +283,7 @@ func (x *ListTagsRequest) String() string { func (*ListTagsRequest) ProtoMessage() {} func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_tag_service_proto_msgTypes[3] + mi := &file_api_v2_tag_service_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -207,14 +296,14 @@ func (x *ListTagsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsRequest.ProtoReflect.Descriptor instead. func (*ListTagsRequest) Descriptor() ([]byte, []int) { - return file_api_v2_tag_service_proto_rawDescGZIP(), []int{3} + return file_api_v2_tag_service_proto_rawDescGZIP(), []int{5} } -func (x *ListTagsRequest) GetCreatorId() int32 { +func (x *ListTagsRequest) GetUser() string { if x != nil { - return x.CreatorId + return x.User } - return 0 + return "" } type ListTagsResponse struct { @@ -228,7 +317,7 @@ type ListTagsResponse struct { func (x *ListTagsResponse) Reset() { *x = ListTagsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_tag_service_proto_msgTypes[4] + mi := &file_api_v2_tag_service_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -241,7 +330,7 @@ func (x *ListTagsResponse) String() string { func (*ListTagsResponse) ProtoMessage() {} func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_tag_service_proto_msgTypes[4] + mi := &file_api_v2_tag_service_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -254,7 +343,7 @@ func (x *ListTagsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListTagsResponse.ProtoReflect.Descriptor instead. func (*ListTagsResponse) Descriptor() ([]byte, []int) { - return file_api_v2_tag_service_proto_rawDescGZIP(), []int{4} + return file_api_v2_tag_service_proto_rawDescGZIP(), []int{6} } func (x *ListTagsResponse) GetTags() []*Tag { @@ -264,6 +353,118 @@ func (x *ListTagsResponse) GetTags() []*Tag { return nil } +type RenameTagRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The creator of tags. + // Format: users/{username} + User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` + OldName string `protobuf:"bytes,2,opt,name=old_name,json=oldName,proto3" json:"old_name,omitempty"` + NewName string `protobuf:"bytes,3,opt,name=new_name,json=newName,proto3" json:"new_name,omitempty"` +} + +func (x *RenameTagRequest) Reset() { + *x = RenameTagRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_tag_service_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RenameTagRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RenameTagRequest) ProtoMessage() {} + +func (x *RenameTagRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_tag_service_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RenameTagRequest.ProtoReflect.Descriptor instead. +func (*RenameTagRequest) Descriptor() ([]byte, []int) { + return file_api_v2_tag_service_proto_rawDescGZIP(), []int{7} +} + +func (x *RenameTagRequest) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +func (x *RenameTagRequest) GetOldName() string { + if x != nil { + return x.OldName + } + return "" +} + +func (x *RenameTagRequest) GetNewName() string { + if x != nil { + return x.NewName + } + return "" +} + +type RenameTagResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Tag *Tag `protobuf:"bytes,1,opt,name=tag,proto3" json:"tag,omitempty"` +} + +func (x *RenameTagResponse) Reset() { + *x = RenameTagResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_tag_service_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RenameTagResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RenameTagResponse) ProtoMessage() {} + +func (x *RenameTagResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_tag_service_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RenameTagResponse.ProtoReflect.Descriptor instead. +func (*RenameTagResponse) Descriptor() ([]byte, []int) { + return file_api_v2_tag_service_proto_rawDescGZIP(), []int{8} +} + +func (x *RenameTagResponse) GetTag() *Tag { + if x != nil { + return x.Tag + } + return nil +} + type DeleteTagRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -275,7 +476,7 @@ type DeleteTagRequest struct { func (x *DeleteTagRequest) Reset() { *x = DeleteTagRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_tag_service_proto_msgTypes[5] + mi := &file_api_v2_tag_service_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -288,7 +489,7 @@ func (x *DeleteTagRequest) String() string { func (*DeleteTagRequest) ProtoMessage() {} func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_tag_service_proto_msgTypes[5] + mi := &file_api_v2_tag_service_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -301,7 +502,7 @@ func (x *DeleteTagRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteTagRequest.ProtoReflect.Descriptor instead. func (*DeleteTagRequest) Descriptor() ([]byte, []int) { - return file_api_v2_tag_service_proto_rawDescGZIP(), []int{5} + return file_api_v2_tag_service_proto_rawDescGZIP(), []int{9} } func (x *DeleteTagRequest) GetTag() *Tag { @@ -320,7 +521,7 @@ type DeleteTagResponse struct { func (x *DeleteTagResponse) Reset() { *x = DeleteTagResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_tag_service_proto_msgTypes[6] + mi := &file_api_v2_tag_service_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -333,7 +534,7 @@ func (x *DeleteTagResponse) String() string { func (*DeleteTagResponse) ProtoMessage() {} func (x *DeleteTagResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_tag_service_proto_msgTypes[6] + mi := &file_api_v2_tag_service_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -346,7 +547,103 @@ func (x *DeleteTagResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteTagResponse.ProtoReflect.Descriptor instead. func (*DeleteTagResponse) Descriptor() ([]byte, []int) { - return file_api_v2_tag_service_proto_rawDescGZIP(), []int{6} + return file_api_v2_tag_service_proto_rawDescGZIP(), []int{10} +} + +type GetTagSuggestionsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The creator of tags. + // Format: users/{username} + User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` +} + +func (x *GetTagSuggestionsRequest) Reset() { + *x = GetTagSuggestionsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_tag_service_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetTagSuggestionsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTagSuggestionsRequest) ProtoMessage() {} + +func (x *GetTagSuggestionsRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_tag_service_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTagSuggestionsRequest.ProtoReflect.Descriptor instead. +func (*GetTagSuggestionsRequest) Descriptor() ([]byte, []int) { + return file_api_v2_tag_service_proto_rawDescGZIP(), []int{11} +} + +func (x *GetTagSuggestionsRequest) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +type GetTagSuggestionsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Tags []string `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty"` +} + +func (x *GetTagSuggestionsResponse) Reset() { + *x = GetTagSuggestionsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_tag_service_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetTagSuggestionsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTagSuggestionsResponse) ProtoMessage() {} + +func (x *GetTagSuggestionsResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_tag_service_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetTagSuggestionsResponse.ProtoReflect.Descriptor instead. +func (*GetTagSuggestionsResponse) Descriptor() ([]byte, []int) { + return file_api_v2_tag_service_proto_rawDescGZIP(), []int{12} +} + +func (x *GetTagSuggestionsResponse) GetTags() []string { + if x != nil { + return x.Tags + } + return nil } var File_api_v2_tag_service_proto protoreflect.FileDescriptor @@ -356,59 +653,104 @@ var file_api_v2_tag_service_proto_rawDesc = []byte{ 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x38, 0x0a, 0x03, 0x54, 0x61, 0x67, 0x12, 0x12, 0x0a, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x33, 0x0a, 0x03, 0x54, 0x61, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, - 0x22, 0x26, 0x0a, 0x10, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x38, 0x0a, 0x11, 0x55, 0x70, 0x73, 0x65, - 0x72, 0x74, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, - 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x6d, - 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x61, 0x67, 0x52, 0x03, 0x74, - 0x61, 0x67, 0x22, 0x30, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x6f, 0x72, 0x49, 0x64, 0x22, 0x39, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x61, 0x67, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x22, - 0x37, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, - 0x54, 0x61, 0x67, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0x13, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xb5, 0x02, - 0x0a, 0x0a, 0x54, 0x61, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x09, - 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x67, 0x12, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, - 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, - 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, - 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, - 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x0e, 0x22, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x74, 0x61, 0x67, 0x73, - 0x12, 0x5f, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x73, 0x12, 0x1d, 0x2e, 0x6d, - 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x65, - 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, - 0x61, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x74, 0x61, 0x67, - 0x73, 0x12, 0x62, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x67, 0x12, 0x1e, - 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, - 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x2a, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, - 0x2f, 0x74, 0x61, 0x67, 0x73, 0x42, 0xa7, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, - 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x0f, 0x54, 0x61, 0x67, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, - 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, - 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, - 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, - 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, - 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, - 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x26, 0x0a, 0x10, 0x55, + 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0x38, 0x0a, 0x11, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x67, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x61, 0x67, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0x53, 0x0a, + 0x15, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x67, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, + 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x73, 0x65, 0x72, + 0x74, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x0a, 0x0f, + 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, + 0x73, 0x65, 0x72, 0x22, 0x39, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x61, 0x67, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x22, 0x5c, + 0x0a, 0x10, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x6c, 0x64, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x6c, 0x64, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x65, 0x77, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x38, 0x0a, 0x11, + 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x23, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x61, + 0x67, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0x37, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x03, 0x74, 0x61, + 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x61, 0x67, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, + 0x13, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x53, 0x75, + 0x67, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x75, 0x73, 0x65, 0x72, 0x22, 0x2f, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x53, 0x75, + 0x67, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x04, 0x74, 0x61, 0x67, 0x73, 0x32, 0xa7, 0x05, 0x0a, 0x0a, 0x54, 0x61, 0x67, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x62, 0x0a, 0x09, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, + 0x67, 0x12, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x22, 0x0c, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x32, 0x2f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x7d, 0x0a, 0x0e, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x67, 0x12, 0x23, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, + 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x24, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x22, 0x18, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x74, 0x61, 0x67, 0x73, 0x3a, 0x62, 0x61, 0x74, 0x63, + 0x68, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x12, 0x5f, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x54, + 0x61, 0x67, 0x73, 0x12, 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x32, 0x2f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x69, 0x0a, 0x09, 0x52, 0x65, 0x6e, 0x61, + 0x6d, 0x65, 0x54, 0x61, 0x67, 0x12, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x32, 0x13, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x74, 0x61, 0x67, 0x73, 0x3a, 0x72, 0x65, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x62, 0x0a, 0x09, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x67, + 0x12, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x2a, 0x0c, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x76, 0x32, 0x2f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x54, + 0x61, 0x67, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x2e, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, + 0x54, 0x61, 0x67, 0x53, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x61, 0x67, 0x53, 0x75, 0x67, 0x67, 0x65, + 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, + 0x74, 0x61, 0x67, 0x73, 0x2f, 0x73, 0x75, 0x67, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x42, + 0xa7, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x42, 0x0f, 0x54, 0x61, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, + 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, + 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, + 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, + 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -423,31 +765,45 @@ func file_api_v2_tag_service_proto_rawDescGZIP() []byte { return file_api_v2_tag_service_proto_rawDescData } -var file_api_v2_tag_service_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_api_v2_tag_service_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_api_v2_tag_service_proto_goTypes = []interface{}{ - (*Tag)(nil), // 0: memos.api.v2.Tag - (*UpsertTagRequest)(nil), // 1: memos.api.v2.UpsertTagRequest - (*UpsertTagResponse)(nil), // 2: memos.api.v2.UpsertTagResponse - (*ListTagsRequest)(nil), // 3: memos.api.v2.ListTagsRequest - (*ListTagsResponse)(nil), // 4: memos.api.v2.ListTagsResponse - (*DeleteTagRequest)(nil), // 5: memos.api.v2.DeleteTagRequest - (*DeleteTagResponse)(nil), // 6: memos.api.v2.DeleteTagResponse + (*Tag)(nil), // 0: memos.api.v2.Tag + (*UpsertTagRequest)(nil), // 1: memos.api.v2.UpsertTagRequest + (*UpsertTagResponse)(nil), // 2: memos.api.v2.UpsertTagResponse + (*BatchUpsertTagRequest)(nil), // 3: memos.api.v2.BatchUpsertTagRequest + (*BatchUpsertTagResponse)(nil), // 4: memos.api.v2.BatchUpsertTagResponse + (*ListTagsRequest)(nil), // 5: memos.api.v2.ListTagsRequest + (*ListTagsResponse)(nil), // 6: memos.api.v2.ListTagsResponse + (*RenameTagRequest)(nil), // 7: memos.api.v2.RenameTagRequest + (*RenameTagResponse)(nil), // 8: memos.api.v2.RenameTagResponse + (*DeleteTagRequest)(nil), // 9: memos.api.v2.DeleteTagRequest + (*DeleteTagResponse)(nil), // 10: memos.api.v2.DeleteTagResponse + (*GetTagSuggestionsRequest)(nil), // 11: memos.api.v2.GetTagSuggestionsRequest + (*GetTagSuggestionsResponse)(nil), // 12: memos.api.v2.GetTagSuggestionsResponse } var file_api_v2_tag_service_proto_depIdxs = []int32{ - 0, // 0: memos.api.v2.UpsertTagResponse.tag:type_name -> memos.api.v2.Tag - 0, // 1: memos.api.v2.ListTagsResponse.tags:type_name -> memos.api.v2.Tag - 0, // 2: memos.api.v2.DeleteTagRequest.tag:type_name -> memos.api.v2.Tag - 1, // 3: memos.api.v2.TagService.UpsertTag:input_type -> memos.api.v2.UpsertTagRequest - 3, // 4: memos.api.v2.TagService.ListTags:input_type -> memos.api.v2.ListTagsRequest - 5, // 5: memos.api.v2.TagService.DeleteTag:input_type -> memos.api.v2.DeleteTagRequest - 2, // 6: memos.api.v2.TagService.UpsertTag:output_type -> memos.api.v2.UpsertTagResponse - 4, // 7: memos.api.v2.TagService.ListTags:output_type -> memos.api.v2.ListTagsResponse - 6, // 8: memos.api.v2.TagService.DeleteTag:output_type -> memos.api.v2.DeleteTagResponse - 6, // [6:9] is the sub-list for method output_type - 3, // [3:6] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 0, // 0: memos.api.v2.UpsertTagResponse.tag:type_name -> memos.api.v2.Tag + 1, // 1: memos.api.v2.BatchUpsertTagRequest.requests:type_name -> memos.api.v2.UpsertTagRequest + 0, // 2: memos.api.v2.ListTagsResponse.tags:type_name -> memos.api.v2.Tag + 0, // 3: memos.api.v2.RenameTagResponse.tag:type_name -> memos.api.v2.Tag + 0, // 4: memos.api.v2.DeleteTagRequest.tag:type_name -> memos.api.v2.Tag + 1, // 5: memos.api.v2.TagService.UpsertTag:input_type -> memos.api.v2.UpsertTagRequest + 3, // 6: memos.api.v2.TagService.BatchUpsertTag:input_type -> memos.api.v2.BatchUpsertTagRequest + 5, // 7: memos.api.v2.TagService.ListTags:input_type -> memos.api.v2.ListTagsRequest + 7, // 8: memos.api.v2.TagService.RenameTag:input_type -> memos.api.v2.RenameTagRequest + 9, // 9: memos.api.v2.TagService.DeleteTag:input_type -> memos.api.v2.DeleteTagRequest + 11, // 10: memos.api.v2.TagService.GetTagSuggestions:input_type -> memos.api.v2.GetTagSuggestionsRequest + 2, // 11: memos.api.v2.TagService.UpsertTag:output_type -> memos.api.v2.UpsertTagResponse + 4, // 12: memos.api.v2.TagService.BatchUpsertTag:output_type -> memos.api.v2.BatchUpsertTagResponse + 6, // 13: memos.api.v2.TagService.ListTags:output_type -> memos.api.v2.ListTagsResponse + 8, // 14: memos.api.v2.TagService.RenameTag:output_type -> memos.api.v2.RenameTagResponse + 10, // 15: memos.api.v2.TagService.DeleteTag:output_type -> memos.api.v2.DeleteTagResponse + 12, // 16: memos.api.v2.TagService.GetTagSuggestions:output_type -> memos.api.v2.GetTagSuggestionsResponse + 11, // [11:17] is the sub-list for method output_type + 5, // [5:11] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name } func init() { file_api_v2_tag_service_proto_init() } @@ -493,7 +849,7 @@ func file_api_v2_tag_service_proto_init() { } } file_api_v2_tag_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListTagsRequest); i { + switch v := v.(*BatchUpsertTagRequest); i { case 0: return &v.state case 1: @@ -505,7 +861,7 @@ func file_api_v2_tag_service_proto_init() { } } file_api_v2_tag_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListTagsResponse); i { + switch v := v.(*BatchUpsertTagResponse); i { case 0: return &v.state case 1: @@ -517,7 +873,7 @@ func file_api_v2_tag_service_proto_init() { } } file_api_v2_tag_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteTagRequest); i { + switch v := v.(*ListTagsRequest); i { case 0: return &v.state case 1: @@ -529,6 +885,54 @@ func file_api_v2_tag_service_proto_init() { } } file_api_v2_tag_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListTagsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_tag_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RenameTagRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_tag_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RenameTagResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_tag_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteTagRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_tag_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DeleteTagResponse); i { case 0: return &v.state @@ -540,6 +944,30 @@ func file_api_v2_tag_service_proto_init() { return nil } } + file_api_v2_tag_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTagSuggestionsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_tag_service_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetTagSuggestionsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -547,7 +975,7 @@ func file_api_v2_tag_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_v2_tag_service_proto_rawDesc, NumEnums: 0, - NumMessages: 7, + NumMessages: 13, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gen/api/v2/tag_service.pb.gw.go b/proto/gen/api/v2/tag_service.pb.gw.go index d17731c2189e4..e7ad4499f5263 100644 --- a/proto/gen/api/v2/tag_service.pb.gw.go +++ b/proto/gen/api/v2/tag_service.pb.gw.go @@ -67,6 +67,42 @@ func local_request_TagService_UpsertTag_0(ctx context.Context, marshaler runtime } +var ( + filter_TagService_BatchUpsertTag_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_TagService_BatchUpsertTag_0(ctx context.Context, marshaler runtime.Marshaler, client TagServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq BatchUpsertTagRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_TagService_BatchUpsertTag_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.BatchUpsertTag(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_TagService_BatchUpsertTag_0(ctx context.Context, marshaler runtime.Marshaler, server TagServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq BatchUpsertTagRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_TagService_BatchUpsertTag_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.BatchUpsertTag(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_TagService_ListTags_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) @@ -103,6 +139,42 @@ func local_request_TagService_ListTags_0(ctx context.Context, marshaler runtime. } +var ( + filter_TagService_RenameTag_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_TagService_RenameTag_0(ctx context.Context, marshaler runtime.Marshaler, client TagServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RenameTagRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_TagService_RenameTag_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.RenameTag(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_TagService_RenameTag_0(ctx context.Context, marshaler runtime.Marshaler, server TagServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq RenameTagRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_TagService_RenameTag_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.RenameTag(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_TagService_DeleteTag_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) @@ -139,6 +211,42 @@ func local_request_TagService_DeleteTag_0(ctx context.Context, marshaler runtime } +var ( + filter_TagService_GetTagSuggestions_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_TagService_GetTagSuggestions_0(ctx context.Context, marshaler runtime.Marshaler, client TagServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetTagSuggestionsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_TagService_GetTagSuggestions_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetTagSuggestions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_TagService_GetTagSuggestions_0(ctx context.Context, marshaler runtime.Marshaler, server TagServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetTagSuggestionsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_TagService_GetTagSuggestions_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetTagSuggestions(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterTagServiceHandlerServer registers the http handlers for service TagService to "mux". // UnaryRPC :call TagServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -170,6 +278,31 @@ func RegisterTagServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("POST", pattern_TagService_BatchUpsertTag_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.TagService/BatchUpsertTag", runtime.WithHTTPPathPattern("/api/v2/tags:batchUpsert")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_TagService_BatchUpsertTag_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TagService_BatchUpsertTag_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_TagService_ListTags_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -195,6 +328,31 @@ func RegisterTagServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("PATCH", pattern_TagService_RenameTag_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.TagService/RenameTag", runtime.WithHTTPPathPattern("/api/v2/tags:rename")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_TagService_RenameTag_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TagService_RenameTag_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("DELETE", pattern_TagService_DeleteTag_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -220,6 +378,31 @@ func RegisterTagServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("GET", pattern_TagService_GetTagSuggestions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.TagService/GetTagSuggestions", runtime.WithHTTPPathPattern("/api/v2/tags/suggestion")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_TagService_GetTagSuggestions_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TagService_GetTagSuggestions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -283,6 +466,28 @@ func RegisterTagServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("POST", pattern_TagService_BatchUpsertTag_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.TagService/BatchUpsertTag", runtime.WithHTTPPathPattern("/api/v2/tags:batchUpsert")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_TagService_BatchUpsertTag_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TagService_BatchUpsertTag_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_TagService_ListTags_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -305,6 +510,28 @@ func RegisterTagServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("PATCH", pattern_TagService_RenameTag_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.TagService/RenameTag", runtime.WithHTTPPathPattern("/api/v2/tags:rename")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_TagService_RenameTag_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TagService_RenameTag_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("DELETE", pattern_TagService_DeleteTag_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -327,21 +554,55 @@ func RegisterTagServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, }) + mux.Handle("GET", pattern_TagService_GetTagSuggestions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.TagService/GetTagSuggestions", runtime.WithHTTPPathPattern("/api/v2/tags/suggestion")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_TagService_GetTagSuggestions_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_TagService_GetTagSuggestions_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } var ( pattern_TagService_UpsertTag_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "tags"}, "")) + pattern_TagService_BatchUpsertTag_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "tags"}, "batchUpsert")) + pattern_TagService_ListTags_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "tags"}, "")) + pattern_TagService_RenameTag_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "tags"}, "rename")) + pattern_TagService_DeleteTag_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "tags"}, "")) + + pattern_TagService_GetTagSuggestions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v2", "tags", "suggestion"}, "")) ) var ( forward_TagService_UpsertTag_0 = runtime.ForwardResponseMessage + forward_TagService_BatchUpsertTag_0 = runtime.ForwardResponseMessage + forward_TagService_ListTags_0 = runtime.ForwardResponseMessage + forward_TagService_RenameTag_0 = runtime.ForwardResponseMessage + forward_TagService_DeleteTag_0 = runtime.ForwardResponseMessage + + forward_TagService_GetTagSuggestions_0 = runtime.ForwardResponseMessage ) diff --git a/proto/gen/api/v2/tag_service_grpc.pb.go b/proto/gen/api/v2/tag_service_grpc.pb.go index 871ef1d40a264..ad203d6a3844a 100644 --- a/proto/gen/api/v2/tag_service_grpc.pb.go +++ b/proto/gen/api/v2/tag_service_grpc.pb.go @@ -19,18 +19,31 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - TagService_UpsertTag_FullMethodName = "/memos.api.v2.TagService/UpsertTag" - TagService_ListTags_FullMethodName = "/memos.api.v2.TagService/ListTags" - TagService_DeleteTag_FullMethodName = "/memos.api.v2.TagService/DeleteTag" + TagService_UpsertTag_FullMethodName = "/memos.api.v2.TagService/UpsertTag" + TagService_BatchUpsertTag_FullMethodName = "/memos.api.v2.TagService/BatchUpsertTag" + TagService_ListTags_FullMethodName = "/memos.api.v2.TagService/ListTags" + TagService_RenameTag_FullMethodName = "/memos.api.v2.TagService/RenameTag" + TagService_DeleteTag_FullMethodName = "/memos.api.v2.TagService/DeleteTag" + TagService_GetTagSuggestions_FullMethodName = "/memos.api.v2.TagService/GetTagSuggestions" ) // TagServiceClient is the client API for TagService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type TagServiceClient interface { + // UpsertTag upserts a tag. UpsertTag(ctx context.Context, in *UpsertTagRequest, opts ...grpc.CallOption) (*UpsertTagResponse, error) + // BatchUpsertTag upserts multiple tags. + BatchUpsertTag(ctx context.Context, in *BatchUpsertTagRequest, opts ...grpc.CallOption) (*BatchUpsertTagResponse, error) + // ListTags lists tags. ListTags(ctx context.Context, in *ListTagsRequest, opts ...grpc.CallOption) (*ListTagsResponse, error) + // RenameTag renames a tag. + // All related memos will be updated. + RenameTag(ctx context.Context, in *RenameTagRequest, opts ...grpc.CallOption) (*RenameTagResponse, error) + // DeleteTag deletes a tag. DeleteTag(ctx context.Context, in *DeleteTagRequest, opts ...grpc.CallOption) (*DeleteTagResponse, error) + // GetTagSuggestions gets tag suggestions from the user's memos. + GetTagSuggestions(ctx context.Context, in *GetTagSuggestionsRequest, opts ...grpc.CallOption) (*GetTagSuggestionsResponse, error) } type tagServiceClient struct { @@ -50,6 +63,15 @@ func (c *tagServiceClient) UpsertTag(ctx context.Context, in *UpsertTagRequest, return out, nil } +func (c *tagServiceClient) BatchUpsertTag(ctx context.Context, in *BatchUpsertTagRequest, opts ...grpc.CallOption) (*BatchUpsertTagResponse, error) { + out := new(BatchUpsertTagResponse) + err := c.cc.Invoke(ctx, TagService_BatchUpsertTag_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *tagServiceClient) ListTags(ctx context.Context, in *ListTagsRequest, opts ...grpc.CallOption) (*ListTagsResponse, error) { out := new(ListTagsResponse) err := c.cc.Invoke(ctx, TagService_ListTags_FullMethodName, in, out, opts...) @@ -59,6 +81,15 @@ func (c *tagServiceClient) ListTags(ctx context.Context, in *ListTagsRequest, op return out, nil } +func (c *tagServiceClient) RenameTag(ctx context.Context, in *RenameTagRequest, opts ...grpc.CallOption) (*RenameTagResponse, error) { + out := new(RenameTagResponse) + err := c.cc.Invoke(ctx, TagService_RenameTag_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *tagServiceClient) DeleteTag(ctx context.Context, in *DeleteTagRequest, opts ...grpc.CallOption) (*DeleteTagResponse, error) { out := new(DeleteTagResponse) err := c.cc.Invoke(ctx, TagService_DeleteTag_FullMethodName, in, out, opts...) @@ -68,13 +99,32 @@ func (c *tagServiceClient) DeleteTag(ctx context.Context, in *DeleteTagRequest, return out, nil } +func (c *tagServiceClient) GetTagSuggestions(ctx context.Context, in *GetTagSuggestionsRequest, opts ...grpc.CallOption) (*GetTagSuggestionsResponse, error) { + out := new(GetTagSuggestionsResponse) + err := c.cc.Invoke(ctx, TagService_GetTagSuggestions_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // TagServiceServer is the server API for TagService service. // All implementations must embed UnimplementedTagServiceServer // for forward compatibility type TagServiceServer interface { + // UpsertTag upserts a tag. UpsertTag(context.Context, *UpsertTagRequest) (*UpsertTagResponse, error) + // BatchUpsertTag upserts multiple tags. + BatchUpsertTag(context.Context, *BatchUpsertTagRequest) (*BatchUpsertTagResponse, error) + // ListTags lists tags. ListTags(context.Context, *ListTagsRequest) (*ListTagsResponse, error) + // RenameTag renames a tag. + // All related memos will be updated. + RenameTag(context.Context, *RenameTagRequest) (*RenameTagResponse, error) + // DeleteTag deletes a tag. DeleteTag(context.Context, *DeleteTagRequest) (*DeleteTagResponse, error) + // GetTagSuggestions gets tag suggestions from the user's memos. + GetTagSuggestions(context.Context, *GetTagSuggestionsRequest) (*GetTagSuggestionsResponse, error) mustEmbedUnimplementedTagServiceServer() } @@ -85,12 +135,21 @@ type UnimplementedTagServiceServer struct { func (UnimplementedTagServiceServer) UpsertTag(context.Context, *UpsertTagRequest) (*UpsertTagResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpsertTag not implemented") } +func (UnimplementedTagServiceServer) BatchUpsertTag(context.Context, *BatchUpsertTagRequest) (*BatchUpsertTagResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BatchUpsertTag not implemented") +} func (UnimplementedTagServiceServer) ListTags(context.Context, *ListTagsRequest) (*ListTagsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListTags not implemented") } +func (UnimplementedTagServiceServer) RenameTag(context.Context, *RenameTagRequest) (*RenameTagResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RenameTag not implemented") +} func (UnimplementedTagServiceServer) DeleteTag(context.Context, *DeleteTagRequest) (*DeleteTagResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteTag not implemented") } +func (UnimplementedTagServiceServer) GetTagSuggestions(context.Context, *GetTagSuggestionsRequest) (*GetTagSuggestionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTagSuggestions not implemented") +} func (UnimplementedTagServiceServer) mustEmbedUnimplementedTagServiceServer() {} // UnsafeTagServiceServer may be embedded to opt out of forward compatibility for this service. @@ -122,6 +181,24 @@ func _TagService_UpsertTag_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _TagService_BatchUpsertTag_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BatchUpsertTagRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TagServiceServer).BatchUpsertTag(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: TagService_BatchUpsertTag_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TagServiceServer).BatchUpsertTag(ctx, req.(*BatchUpsertTagRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _TagService_ListTags_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListTagsRequest) if err := dec(in); err != nil { @@ -140,6 +217,24 @@ func _TagService_ListTags_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } +func _TagService_RenameTag_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RenameTagRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TagServiceServer).RenameTag(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: TagService_RenameTag_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TagServiceServer).RenameTag(ctx, req.(*RenameTagRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _TagService_DeleteTag_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(DeleteTagRequest) if err := dec(in); err != nil { @@ -158,6 +253,24 @@ func _TagService_DeleteTag_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _TagService_GetTagSuggestions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetTagSuggestionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TagServiceServer).GetTagSuggestions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: TagService_GetTagSuggestions_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TagServiceServer).GetTagSuggestions(ctx, req.(*GetTagSuggestionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + // TagService_ServiceDesc is the grpc.ServiceDesc for TagService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -169,14 +282,26 @@ var TagService_ServiceDesc = grpc.ServiceDesc{ MethodName: "UpsertTag", Handler: _TagService_UpsertTag_Handler, }, + { + MethodName: "BatchUpsertTag", + Handler: _TagService_BatchUpsertTag_Handler, + }, { MethodName: "ListTags", Handler: _TagService_ListTags_Handler, }, + { + MethodName: "RenameTag", + Handler: _TagService_RenameTag_Handler, + }, { MethodName: "DeleteTag", Handler: _TagService_DeleteTag_Handler, }, + { + MethodName: "GetTagSuggestions", + Handler: _TagService_GetTagSuggestions_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "api/v2/tag_service.proto", diff --git a/proto/gen/api/v2/user_service.pb.go b/proto/gen/api/v2/user_service.pb.go index d53fa1d7ffcd3..58e60e8556767 100644 --- a/proto/gen/api/v2/user_service.pb.go +++ b/proto/gen/api/v2/user_service.pb.go @@ -80,16 +80,19 @@ type User struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` - Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` + // The name of the user. + // Format: users/{username} + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Id int32 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty"` Role User_Role `protobuf:"varint,3,opt,name=role,proto3,enum=memos.api.v2.User_Role" json:"role,omitempty"` - Email string `protobuf:"bytes,4,opt,name=email,proto3" json:"email,omitempty"` - Nickname string `protobuf:"bytes,5,opt,name=nickname,proto3" json:"nickname,omitempty"` - AvatarUrl string `protobuf:"bytes,6,opt,name=avatar_url,json=avatarUrl,proto3" json:"avatar_url,omitempty"` - Password string `protobuf:"bytes,7,opt,name=password,proto3" json:"password,omitempty"` - RowStatus RowStatus `protobuf:"varint,8,opt,name=row_status,json=rowStatus,proto3,enum=memos.api.v2.RowStatus" json:"row_status,omitempty"` - CreateTime *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` - UpdateTime *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` + Username string `protobuf:"bytes,4,opt,name=username,proto3" json:"username,omitempty"` + Email string `protobuf:"bytes,5,opt,name=email,proto3" json:"email,omitempty"` + Nickname string `protobuf:"bytes,6,opt,name=nickname,proto3" json:"nickname,omitempty"` + AvatarUrl string `protobuf:"bytes,7,opt,name=avatar_url,json=avatarUrl,proto3" json:"avatar_url,omitempty"` + Password string `protobuf:"bytes,8,opt,name=password,proto3" json:"password,omitempty"` + RowStatus RowStatus `protobuf:"varint,9,opt,name=row_status,json=rowStatus,proto3,enum=memos.api.v2.RowStatus" json:"row_status,omitempty"` + CreateTime *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty"` + UpdateTime *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` } func (x *User) Reset() { @@ -124,18 +127,18 @@ func (*User) Descriptor() ([]byte, []int) { return file_api_v2_user_service_proto_rawDescGZIP(), []int{0} } -func (x *User) GetId() int32 { +func (x *User) GetName() string { if x != nil { - return x.Id + return x.Name } - return 0 + return "" } -func (x *User) GetUsername() string { +func (x *User) GetId() int32 { if x != nil { - return x.Username + return x.Id } - return "" + return 0 } func (x *User) GetRole() User_Role { @@ -145,6 +148,13 @@ func (x *User) GetRole() User_Role { return User_ROLE_UNSPECIFIED } +func (x *User) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + func (x *User) GetEmail() string { if x != nil { return x.Email @@ -194,18 +204,105 @@ func (x *User) GetUpdateTime() *timestamppb.Timestamp { return nil } +type ListUsersRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListUsersRequest) Reset() { + *x = ListUsersRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_user_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListUsersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListUsersRequest) ProtoMessage() {} + +func (x *ListUsersRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListUsersRequest.ProtoReflect.Descriptor instead. +func (*ListUsersRequest) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{1} +} + +type ListUsersResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Users []*User `protobuf:"bytes,1,rep,name=users,proto3" json:"users,omitempty"` +} + +func (x *ListUsersResponse) Reset() { + *x = ListUsersResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_user_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListUsersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListUsersResponse) ProtoMessage() {} + +func (x *ListUsersResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListUsersResponse.ProtoReflect.Descriptor instead. +func (*ListUsersResponse) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{2} +} + +func (x *ListUsersResponse) GetUsers() []*User { + if x != nil { + return x.Users + } + return nil +} + type GetUserRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + // The name of the user. + // Format: users/{username} + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } func (x *GetUserRequest) Reset() { *x = GetUserRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[1] + mi := &file_api_v2_user_service_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -218,7 +315,7 @@ func (x *GetUserRequest) String() string { func (*GetUserRequest) ProtoMessage() {} func (x *GetUserRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[1] + mi := &file_api_v2_user_service_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -231,12 +328,12 @@ func (x *GetUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetUserRequest.ProtoReflect.Descriptor instead. func (*GetUserRequest) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{1} + return file_api_v2_user_service_proto_rawDescGZIP(), []int{3} } -func (x *GetUserRequest) GetUsername() string { +func (x *GetUserRequest) GetName() string { if x != nil { - return x.Username + return x.Name } return "" } @@ -252,7 +349,7 @@ type GetUserResponse struct { func (x *GetUserResponse) Reset() { *x = GetUserResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[2] + mi := &file_api_v2_user_service_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -265,7 +362,7 @@ func (x *GetUserResponse) String() string { func (*GetUserResponse) ProtoMessage() {} func (x *GetUserResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[2] + mi := &file_api_v2_user_service_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -278,7 +375,7 @@ func (x *GetUserResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetUserResponse.ProtoReflect.Descriptor instead. func (*GetUserResponse) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{2} + return file_api_v2_user_service_proto_rawDescGZIP(), []int{4} } func (x *GetUserResponse) GetUser() *User { @@ -299,7 +396,7 @@ type CreateUserRequest struct { func (x *CreateUserRequest) Reset() { *x = CreateUserRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[3] + mi := &file_api_v2_user_service_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -312,7 +409,7 @@ func (x *CreateUserRequest) String() string { func (*CreateUserRequest) ProtoMessage() {} func (x *CreateUserRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[3] + mi := &file_api_v2_user_service_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -325,7 +422,7 @@ func (x *CreateUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateUserRequest.ProtoReflect.Descriptor instead. func (*CreateUserRequest) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{3} + return file_api_v2_user_service_proto_rawDescGZIP(), []int{5} } func (x *CreateUserRequest) GetUser() *User { @@ -346,7 +443,7 @@ type CreateUserResponse struct { func (x *CreateUserResponse) Reset() { *x = CreateUserResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[4] + mi := &file_api_v2_user_service_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -359,7 +456,7 @@ func (x *CreateUserResponse) String() string { func (*CreateUserResponse) ProtoMessage() {} func (x *CreateUserResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[4] + mi := &file_api_v2_user_service_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -372,7 +469,7 @@ func (x *CreateUserResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateUserResponse.ProtoReflect.Descriptor instead. func (*CreateUserResponse) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{4} + return file_api_v2_user_service_proto_rawDescGZIP(), []int{6} } func (x *CreateUserResponse) GetUser() *User { @@ -394,7 +491,7 @@ type UpdateUserRequest struct { func (x *UpdateUserRequest) Reset() { *x = UpdateUserRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[5] + mi := &file_api_v2_user_service_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -407,7 +504,7 @@ func (x *UpdateUserRequest) String() string { func (*UpdateUserRequest) ProtoMessage() {} func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[5] + mi := &file_api_v2_user_service_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -420,7 +517,7 @@ func (x *UpdateUserRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateUserRequest.ProtoReflect.Descriptor instead. func (*UpdateUserRequest) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{5} + return file_api_v2_user_service_proto_rawDescGZIP(), []int{7} } func (x *UpdateUserRequest) GetUser() *User { @@ -448,7 +545,7 @@ type UpdateUserResponse struct { func (x *UpdateUserResponse) Reset() { *x = UpdateUserResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[6] + mi := &file_api_v2_user_service_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -461,7 +558,7 @@ func (x *UpdateUserResponse) String() string { func (*UpdateUserResponse) ProtoMessage() {} func (x *UpdateUserResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[6] + mi := &file_api_v2_user_service_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -474,7 +571,7 @@ func (x *UpdateUserResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateUserResponse.ProtoReflect.Descriptor instead. func (*UpdateUserResponse) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{6} + return file_api_v2_user_service_proto_rawDescGZIP(), []int{8} } func (x *UpdateUserResponse) GetUser() *User { @@ -484,31 +581,33 @@ func (x *UpdateUserResponse) GetUser() *User { return nil } -type ListUserAccessTokensRequest struct { +type DeleteUserRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` + // The name of the user. + // Format: users/{username} + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } -func (x *ListUserAccessTokensRequest) Reset() { - *x = ListUserAccessTokensRequest{} +func (x *DeleteUserRequest) Reset() { + *x = DeleteUserRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[7] + mi := &file_api_v2_user_service_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ListUserAccessTokensRequest) String() string { +func (x *DeleteUserRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListUserAccessTokensRequest) ProtoMessage() {} +func (*DeleteUserRequest) ProtoMessage() {} -func (x *ListUserAccessTokensRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[7] +func (x *DeleteUserRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -519,43 +618,41 @@ func (x *ListUserAccessTokensRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListUserAccessTokensRequest.ProtoReflect.Descriptor instead. -func (*ListUserAccessTokensRequest) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{7} +// Deprecated: Use DeleteUserRequest.ProtoReflect.Descriptor instead. +func (*DeleteUserRequest) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{9} } -func (x *ListUserAccessTokensRequest) GetUsername() string { +func (x *DeleteUserRequest) GetName() string { if x != nil { - return x.Username + return x.Name } return "" } -type ListUserAccessTokensResponse struct { +type DeleteUserResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - AccessTokens []*UserAccessToken `protobuf:"bytes,1,rep,name=access_tokens,json=accessTokens,proto3" json:"access_tokens,omitempty"` } -func (x *ListUserAccessTokensResponse) Reset() { - *x = ListUserAccessTokensResponse{} +func (x *DeleteUserResponse) Reset() { + *x = DeleteUserResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[8] + mi := &file_api_v2_user_service_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *ListUserAccessTokensResponse) String() string { +func (x *DeleteUserResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListUserAccessTokensResponse) ProtoMessage() {} +func (*DeleteUserResponse) ProtoMessage() {} -func (x *ListUserAccessTokensResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[8] +func (x *DeleteUserResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -566,45 +663,46 @@ func (x *ListUserAccessTokensResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListUserAccessTokensResponse.ProtoReflect.Descriptor instead. -func (*ListUserAccessTokensResponse) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{8} -} - -func (x *ListUserAccessTokensResponse) GetAccessTokens() []*UserAccessToken { - if x != nil { - return x.AccessTokens - } - return nil +// Deprecated: Use DeleteUserResponse.ProtoReflect.Descriptor instead. +func (*DeleteUserResponse) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{10} } -type CreateUserAccessTokenRequest struct { +type UserSetting struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=expires_at,json=expiresAt,proto3,oneof" json:"expires_at,omitempty"` -} - -func (x *CreateUserAccessTokenRequest) Reset() { - *x = CreateUserAccessTokenRequest{} + // The name of the user. + // Format: users/{username} + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // The preferred locale of the user. + Locale string `protobuf:"bytes,2,opt,name=locale,proto3" json:"locale,omitempty"` + // The preferred appearance of the user. + Appearance string `protobuf:"bytes,3,opt,name=appearance,proto3" json:"appearance,omitempty"` + // The default visibility of the memo. + MemoVisibility string `protobuf:"bytes,4,opt,name=memo_visibility,json=memoVisibility,proto3" json:"memo_visibility,omitempty"` + // The telegram user id of the user. + TelegramUserId string `protobuf:"bytes,5,opt,name=telegram_user_id,json=telegramUserId,proto3" json:"telegram_user_id,omitempty"` +} + +func (x *UserSetting) Reset() { + *x = UserSetting{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[9] + mi := &file_api_v2_user_service_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *CreateUserAccessTokenRequest) String() string { +func (x *UserSetting) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CreateUserAccessTokenRequest) ProtoMessage() {} +func (*UserSetting) ProtoMessage() {} -func (x *CreateUserAccessTokenRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[9] +func (x *UserSetting) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -615,57 +713,73 @@ func (x *CreateUserAccessTokenRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CreateUserAccessTokenRequest.ProtoReflect.Descriptor instead. -func (*CreateUserAccessTokenRequest) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{9} +// Deprecated: Use UserSetting.ProtoReflect.Descriptor instead. +func (*UserSetting) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{11} } -func (x *CreateUserAccessTokenRequest) GetUsername() string { +func (x *UserSetting) GetName() string { if x != nil { - return x.Username + return x.Name } return "" } -func (x *CreateUserAccessTokenRequest) GetDescription() string { +func (x *UserSetting) GetLocale() string { if x != nil { - return x.Description + return x.Locale } return "" } -func (x *CreateUserAccessTokenRequest) GetExpiresAt() *timestamppb.Timestamp { +func (x *UserSetting) GetAppearance() string { if x != nil { - return x.ExpiresAt + return x.Appearance } - return nil + return "" } -type CreateUserAccessTokenResponse struct { +func (x *UserSetting) GetMemoVisibility() string { + if x != nil { + return x.MemoVisibility + } + return "" +} + +func (x *UserSetting) GetTelegramUserId() string { + if x != nil { + return x.TelegramUserId + } + return "" +} + +type GetUserSettingRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - AccessToken *UserAccessToken `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` + // The name of the user. + // Format: users/{username} + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } -func (x *CreateUserAccessTokenResponse) Reset() { - *x = CreateUserAccessTokenResponse{} +func (x *GetUserSettingRequest) Reset() { + *x = GetUserSettingRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[10] + mi := &file_api_v2_user_service_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *CreateUserAccessTokenResponse) String() string { +func (x *GetUserSettingRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CreateUserAccessTokenResponse) ProtoMessage() {} +func (*GetUserSettingRequest) ProtoMessage() {} -func (x *CreateUserAccessTokenResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[10] +func (x *GetUserSettingRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -676,45 +790,43 @@ func (x *CreateUserAccessTokenResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CreateUserAccessTokenResponse.ProtoReflect.Descriptor instead. -func (*CreateUserAccessTokenResponse) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{10} +// Deprecated: Use GetUserSettingRequest.ProtoReflect.Descriptor instead. +func (*GetUserSettingRequest) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{12} } -func (x *CreateUserAccessTokenResponse) GetAccessToken() *UserAccessToken { +func (x *GetUserSettingRequest) GetName() string { if x != nil { - return x.AccessToken + return x.Name } - return nil + return "" } -type DeleteUserAccessTokenRequest struct { +type GetUserSettingResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` - // access_token is the access token to delete. - AccessToken string `protobuf:"bytes,2,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` + Setting *UserSetting `protobuf:"bytes,1,opt,name=setting,proto3" json:"setting,omitempty"` } -func (x *DeleteUserAccessTokenRequest) Reset() { - *x = DeleteUserAccessTokenRequest{} +func (x *GetUserSettingResponse) Reset() { + *x = GetUserSettingResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[11] + mi := &file_api_v2_user_service_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *DeleteUserAccessTokenRequest) String() string { +func (x *GetUserSettingResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*DeleteUserAccessTokenRequest) ProtoMessage() {} +func (*GetUserSettingResponse) ProtoMessage() {} -func (x *DeleteUserAccessTokenRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[11] +func (x *GetUserSettingResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -725,48 +837,44 @@ func (x *DeleteUserAccessTokenRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use DeleteUserAccessTokenRequest.ProtoReflect.Descriptor instead. -func (*DeleteUserAccessTokenRequest) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{11} -} - -func (x *DeleteUserAccessTokenRequest) GetUsername() string { - if x != nil { - return x.Username - } - return "" +// Deprecated: Use GetUserSettingResponse.ProtoReflect.Descriptor instead. +func (*GetUserSettingResponse) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{13} } -func (x *DeleteUserAccessTokenRequest) GetAccessToken() string { +func (x *GetUserSettingResponse) GetSetting() *UserSetting { if x != nil { - return x.AccessToken + return x.Setting } - return "" + return nil } -type DeleteUserAccessTokenResponse struct { +type UpdateUserSettingRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + Setting *UserSetting `protobuf:"bytes,1,opt,name=setting,proto3" json:"setting,omitempty"` + UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` } -func (x *DeleteUserAccessTokenResponse) Reset() { - *x = DeleteUserAccessTokenResponse{} +func (x *UpdateUserSettingRequest) Reset() { + *x = UpdateUserSettingRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[12] + mi := &file_api_v2_user_service_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *DeleteUserAccessTokenResponse) String() string { +func (x *UpdateUserSettingRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*DeleteUserAccessTokenResponse) ProtoMessage() {} +func (*UpdateUserSettingRequest) ProtoMessage() {} -func (x *DeleteUserAccessTokenResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[12] +func (x *UpdateUserSettingRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -777,16 +885,77 @@ func (x *DeleteUserAccessTokenResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use DeleteUserAccessTokenResponse.ProtoReflect.Descriptor instead. -func (*DeleteUserAccessTokenResponse) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{12} +// Deprecated: Use UpdateUserSettingRequest.ProtoReflect.Descriptor instead. +func (*UpdateUserSettingRequest) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{14} } -type UserAccessToken struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - +func (x *UpdateUserSettingRequest) GetSetting() *UserSetting { + if x != nil { + return x.Setting + } + return nil +} + +func (x *UpdateUserSettingRequest) GetUpdateMask() *fieldmaskpb.FieldMask { + if x != nil { + return x.UpdateMask + } + return nil +} + +type UpdateUserSettingResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Setting *UserSetting `protobuf:"bytes,1,opt,name=setting,proto3" json:"setting,omitempty"` +} + +func (x *UpdateUserSettingResponse) Reset() { + *x = UpdateUserSettingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_user_service_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateUserSettingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateUserSettingResponse) ProtoMessage() {} + +func (x *UpdateUserSettingResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateUserSettingResponse.ProtoReflect.Descriptor instead. +func (*UpdateUserSettingResponse) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{15} +} + +func (x *UpdateUserSettingResponse) GetSetting() *UserSetting { + if x != nil { + return x.Setting + } + return nil +} + +type UserAccessToken struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + AccessToken string `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` IssuedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=issued_at,json=issuedAt,proto3" json:"issued_at,omitempty"` @@ -796,7 +965,7 @@ type UserAccessToken struct { func (x *UserAccessToken) Reset() { *x = UserAccessToken{} if protoimpl.UnsafeEnabled { - mi := &file_api_v2_user_service_proto_msgTypes[13] + mi := &file_api_v2_user_service_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -809,7 +978,7 @@ func (x *UserAccessToken) String() string { func (*UserAccessToken) ProtoMessage() {} func (x *UserAccessToken) ProtoReflect() protoreflect.Message { - mi := &file_api_v2_user_service_proto_msgTypes[13] + mi := &file_api_v2_user_service_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -822,7 +991,7 @@ func (x *UserAccessToken) ProtoReflect() protoreflect.Message { // Deprecated: Use UserAccessToken.ProtoReflect.Descriptor instead. func (*UserAccessToken) Descriptor() ([]byte, []int) { - return file_api_v2_user_service_proto_rawDescGZIP(), []int{13} + return file_api_v2_user_service_proto_rawDescGZIP(), []int{16} } func (x *UserAccessToken) GetAccessToken() string { @@ -853,6 +1022,310 @@ func (x *UserAccessToken) GetExpiresAt() *timestamppb.Timestamp { return nil } +type ListUserAccessTokensRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the user. + // Format: users/{username} + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *ListUserAccessTokensRequest) Reset() { + *x = ListUserAccessTokensRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_user_service_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListUserAccessTokensRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListUserAccessTokensRequest) ProtoMessage() {} + +func (x *ListUserAccessTokensRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListUserAccessTokensRequest.ProtoReflect.Descriptor instead. +func (*ListUserAccessTokensRequest) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{17} +} + +func (x *ListUserAccessTokensRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type ListUserAccessTokensResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AccessTokens []*UserAccessToken `protobuf:"bytes,1,rep,name=access_tokens,json=accessTokens,proto3" json:"access_tokens,omitempty"` +} + +func (x *ListUserAccessTokensResponse) Reset() { + *x = ListUserAccessTokensResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_user_service_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListUserAccessTokensResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListUserAccessTokensResponse) ProtoMessage() {} + +func (x *ListUserAccessTokensResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListUserAccessTokensResponse.ProtoReflect.Descriptor instead. +func (*ListUserAccessTokensResponse) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{18} +} + +func (x *ListUserAccessTokensResponse) GetAccessTokens() []*UserAccessToken { + if x != nil { + return x.AccessTokens + } + return nil +} + +type CreateUserAccessTokenRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the user. + // Format: users/{username} + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=expires_at,json=expiresAt,proto3,oneof" json:"expires_at,omitempty"` +} + +func (x *CreateUserAccessTokenRequest) Reset() { + *x = CreateUserAccessTokenRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_user_service_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateUserAccessTokenRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateUserAccessTokenRequest) ProtoMessage() {} + +func (x *CreateUserAccessTokenRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateUserAccessTokenRequest.ProtoReflect.Descriptor instead. +func (*CreateUserAccessTokenRequest) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{19} +} + +func (x *CreateUserAccessTokenRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateUserAccessTokenRequest) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *CreateUserAccessTokenRequest) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +type CreateUserAccessTokenResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AccessToken *UserAccessToken `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` +} + +func (x *CreateUserAccessTokenResponse) Reset() { + *x = CreateUserAccessTokenResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_user_service_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateUserAccessTokenResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateUserAccessTokenResponse) ProtoMessage() {} + +func (x *CreateUserAccessTokenResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateUserAccessTokenResponse.ProtoReflect.Descriptor instead. +func (*CreateUserAccessTokenResponse) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{20} +} + +func (x *CreateUserAccessTokenResponse) GetAccessToken() *UserAccessToken { + if x != nil { + return x.AccessToken + } + return nil +} + +type DeleteUserAccessTokenRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of the user. + // Format: users/{username} + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // access_token is the access token to delete. + AccessToken string `protobuf:"bytes,2,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` +} + +func (x *DeleteUserAccessTokenRequest) Reset() { + *x = DeleteUserAccessTokenRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_user_service_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteUserAccessTokenRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteUserAccessTokenRequest) ProtoMessage() {} + +func (x *DeleteUserAccessTokenRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteUserAccessTokenRequest.ProtoReflect.Descriptor instead. +func (*DeleteUserAccessTokenRequest) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{21} +} + +func (x *DeleteUserAccessTokenRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DeleteUserAccessTokenRequest) GetAccessToken() string { + if x != nil { + return x.AccessToken + } + return "" +} + +type DeleteUserAccessTokenResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteUserAccessTokenResponse) Reset() { + *x = DeleteUserAccessTokenResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_user_service_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteUserAccessTokenResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteUserAccessTokenResponse) ProtoMessage() {} + +func (x *DeleteUserAccessTokenResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_user_service_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteUserAccessTokenResponse.ProtoReflect.Descriptor instead. +func (*DeleteUserAccessTokenResponse) Descriptor() ([]byte, []int) { + return file_api_v2_user_service_proto_rawDescGZIP(), []int{22} +} + var File_api_v2_user_service_proto protoreflect.FileDescriptor var file_api_v2_user_service_proto_rawDesc = []byte{ @@ -869,179 +1342,253 @@ var file_api_v2_user_service_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc0, 0x03, 0x0a, 0x04, 0x55, 0x73, - 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2b, - 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6d, - 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, - 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, - 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, - 0x0a, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a, 0x08, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, - 0xe0, 0x41, 0x04, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x36, 0x0a, - 0x0a, 0x72, 0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, - 0x2e, 0x52, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x72, 0x6f, 0x77, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, - 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, - 0x3b, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x4f, 0x4c, 0x45, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, - 0x04, 0x48, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x44, 0x4d, 0x49, 0x4e, - 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10, 0x03, 0x22, 0x2c, 0x0a, 0x0e, - 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, - 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x39, 0x0a, 0x0f, 0x47, 0x65, - 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, - 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, - 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, - 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x3b, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, - 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, - 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, - 0x65, 0x72, 0x22, 0x3c, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, - 0x22, 0x7d, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x75, 0x73, - 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, - 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, - 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, - 0x3c, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x39, 0x0a, - 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x62, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, - 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0d, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0c, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0xab, 0x01, 0x0a, - 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0a, 0x65, - 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x09, 0x65, - 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, - 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x22, 0x61, 0x0a, 0x1d, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x5d, 0x0a, - 0x1c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x1f, 0x0a, 0x1d, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xca, 0x01, - 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, - 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x09, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, - 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x41, 0x74, 0x12, - 0x39, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x32, 0xab, 0x07, 0x0a, 0x0b, 0x55, - 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x73, 0x0a, 0x07, 0x47, 0x65, - 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x2b, 0xda, 0x41, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, - 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, - 0x6f, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1f, 0x2e, - 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, - 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x1e, 0xda, 0x41, 0x04, 0x75, 0x73, 0x65, 0x72, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x3a, - 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x09, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, - 0x12, 0x8f, 0x01, 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, - 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x3e, 0xda, 0x41, 0x10, 0x75, 0x73, 0x65, 0x72, 0x2c, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x3a, 0x04, 0x75, - 0x73, 0x65, 0x72, 0x32, 0x1d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, - 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, - 0x65, 0x7d, 0x12, 0xa8, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x6d, 0x65, - 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, - 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x39, 0xda, 0x41, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, - 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0xae, 0x01, - 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, - 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x3c, 0xda, 0x41, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x2b, 0x3a, 0x01, 0x2a, 0x22, 0x26, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, - 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x7d, - 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0xc7, - 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, - 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, + 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd4, 0x03, 0x0a, 0x04, 0x55, 0x73, + 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, + 0x6f, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, + 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x04, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x12, 0x36, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, + 0x72, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, + 0x69, 0x6d, 0x65, 0x22, 0x3b, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x52, + 0x4f, 0x4c, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x4f, 0x53, 0x54, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x41, + 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x55, 0x53, 0x45, 0x52, 0x10, 0x03, + 0x22, 0x12, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x3d, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x75, 0x73, 0x65, + 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x05, 0x75, 0x73, + 0x65, 0x72, 0x73, 0x22, 0x24, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x39, 0x0a, 0x0f, 0x47, 0x65, 0x74, + 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, + 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, + 0x75, 0x73, 0x65, 0x72, 0x22, 0x3b, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, + 0x72, 0x22, 0x3c, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, + 0x7d, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, 0x04, 0x75, 0x73, 0x65, + 0x72, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, + 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x3c, + 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x27, 0x0a, 0x11, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xac, 0x01, 0x0a, 0x0b, + 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x65, 0x61, + 0x72, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x70, + 0x65, 0x61, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, + 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0e, 0x6d, 0x65, 0x6d, 0x6f, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x12, 0x28, 0x0a, 0x10, 0x74, 0x65, 0x6c, 0x65, 0x67, 0x72, 0x61, 0x6d, 0x5f, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x65, 0x6c, 0x65, + 0x67, 0x72, 0x61, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x2b, 0x0a, 0x15, 0x47, 0x65, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x4d, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x33, 0x0a, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x73, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x22, 0x91, 0x01, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x42, + 0x03, 0xe0, 0x41, 0x02, 0x52, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x3b, 0x0a, + 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x50, 0x0a, 0x19, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, + 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x52, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x22, 0xca, 0x01, 0x0a, + 0x0f, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x09, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x5f, + 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, + 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x41, 0x74, 0x22, 0x31, 0x0a, 0x1b, 0x4c, 0x69, 0x73, + 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x62, 0x0a, 0x1c, + 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0d, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, + 0x22, 0xa3, 0x01, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x65, 0x73, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x48, 0x00, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x65, 0x73, 0x41, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x65, 0x78, 0x70, 0x69, + 0x72, 0x65, 0x73, 0x5f, 0x61, 0x74, 0x22, 0x61, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x73, 0x65, + 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0b, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x55, 0x0a, 0x1c, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x22, 0x1f, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x55, 0xda, 0x41, 0x15, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x37, 0x2a, 0x35, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, - 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x2f, 0x7b, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x7d, 0x42, 0xa8, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, - 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x10, 0x55, - 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, - 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, - 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, - 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, - 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, - 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, - 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x32, 0xb5, 0x0b, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x63, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1e, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, + 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0x6d, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, + 0x72, 0x12, 0x1c, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, + 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, + 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x75, 0x73, 0x65, + 0x72, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0x73, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0xda, 0x41, 0x04, 0x75, 0x73, 0x65, 0x72, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x0d, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0x8d, 0x01, 0x0a, 0x0a, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3c, 0xda, 0x41, + 0x10, 0x75, 0x73, 0x65, 0x72, 0x2c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, + 0x6b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, 0x3a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x32, 0x1b, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0x76, 0x0a, 0x0a, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, + 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0xda, 0x41, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x2a, 0x16, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, + 0x2a, 0x7d, 0x12, 0x8a, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, + 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x2d, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, + 0x1e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x75, + 0x73, 0x65, 0x72, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, + 0xb3, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x26, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4d, 0xda, 0x41, 0x13, 0x73, 0x65, 0x74, 0x74, 0x69, + 0x6e, 0x67, 0x2c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x31, 0x3a, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x32, 0x26, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x2a, 0x2f, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x7d, 0x12, 0xa2, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x29, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, + 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0xa8, 0x01, 0x0a, 0x15, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2b, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0xda, + 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, + 0x24, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x75, + 0x73, 0x65, 0x72, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0xc1, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, + 0x2a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4f, 0xda, 0x41, 0x11, 0x6e, 0x61, 0x6d, + 0x65, 0x2c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x35, 0x2a, 0x33, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x7b, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x2a, 0x7d, 0x2f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x2f, 0x7b, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x7d, 0x42, 0xa8, 0x01, 0x0a, 0x10, 0x63, 0x6f, + 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x10, + 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, + 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, + 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, + 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, + 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, + 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1057,60 +1604,82 @@ func file_api_v2_user_service_proto_rawDescGZIP() []byte { } var file_api_v2_user_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_api_v2_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_api_v2_user_service_proto_msgTypes = make([]protoimpl.MessageInfo, 23) var file_api_v2_user_service_proto_goTypes = []interface{}{ (User_Role)(0), // 0: memos.api.v2.User.Role (*User)(nil), // 1: memos.api.v2.User - (*GetUserRequest)(nil), // 2: memos.api.v2.GetUserRequest - (*GetUserResponse)(nil), // 3: memos.api.v2.GetUserResponse - (*CreateUserRequest)(nil), // 4: memos.api.v2.CreateUserRequest - (*CreateUserResponse)(nil), // 5: memos.api.v2.CreateUserResponse - (*UpdateUserRequest)(nil), // 6: memos.api.v2.UpdateUserRequest - (*UpdateUserResponse)(nil), // 7: memos.api.v2.UpdateUserResponse - (*ListUserAccessTokensRequest)(nil), // 8: memos.api.v2.ListUserAccessTokensRequest - (*ListUserAccessTokensResponse)(nil), // 9: memos.api.v2.ListUserAccessTokensResponse - (*CreateUserAccessTokenRequest)(nil), // 10: memos.api.v2.CreateUserAccessTokenRequest - (*CreateUserAccessTokenResponse)(nil), // 11: memos.api.v2.CreateUserAccessTokenResponse - (*DeleteUserAccessTokenRequest)(nil), // 12: memos.api.v2.DeleteUserAccessTokenRequest - (*DeleteUserAccessTokenResponse)(nil), // 13: memos.api.v2.DeleteUserAccessTokenResponse - (*UserAccessToken)(nil), // 14: memos.api.v2.UserAccessToken - (RowStatus)(0), // 15: memos.api.v2.RowStatus - (*timestamppb.Timestamp)(nil), // 16: google.protobuf.Timestamp - (*fieldmaskpb.FieldMask)(nil), // 17: google.protobuf.FieldMask + (*ListUsersRequest)(nil), // 2: memos.api.v2.ListUsersRequest + (*ListUsersResponse)(nil), // 3: memos.api.v2.ListUsersResponse + (*GetUserRequest)(nil), // 4: memos.api.v2.GetUserRequest + (*GetUserResponse)(nil), // 5: memos.api.v2.GetUserResponse + (*CreateUserRequest)(nil), // 6: memos.api.v2.CreateUserRequest + (*CreateUserResponse)(nil), // 7: memos.api.v2.CreateUserResponse + (*UpdateUserRequest)(nil), // 8: memos.api.v2.UpdateUserRequest + (*UpdateUserResponse)(nil), // 9: memos.api.v2.UpdateUserResponse + (*DeleteUserRequest)(nil), // 10: memos.api.v2.DeleteUserRequest + (*DeleteUserResponse)(nil), // 11: memos.api.v2.DeleteUserResponse + (*UserSetting)(nil), // 12: memos.api.v2.UserSetting + (*GetUserSettingRequest)(nil), // 13: memos.api.v2.GetUserSettingRequest + (*GetUserSettingResponse)(nil), // 14: memos.api.v2.GetUserSettingResponse + (*UpdateUserSettingRequest)(nil), // 15: memos.api.v2.UpdateUserSettingRequest + (*UpdateUserSettingResponse)(nil), // 16: memos.api.v2.UpdateUserSettingResponse + (*UserAccessToken)(nil), // 17: memos.api.v2.UserAccessToken + (*ListUserAccessTokensRequest)(nil), // 18: memos.api.v2.ListUserAccessTokensRequest + (*ListUserAccessTokensResponse)(nil), // 19: memos.api.v2.ListUserAccessTokensResponse + (*CreateUserAccessTokenRequest)(nil), // 20: memos.api.v2.CreateUserAccessTokenRequest + (*CreateUserAccessTokenResponse)(nil), // 21: memos.api.v2.CreateUserAccessTokenResponse + (*DeleteUserAccessTokenRequest)(nil), // 22: memos.api.v2.DeleteUserAccessTokenRequest + (*DeleteUserAccessTokenResponse)(nil), // 23: memos.api.v2.DeleteUserAccessTokenResponse + (RowStatus)(0), // 24: memos.api.v2.RowStatus + (*timestamppb.Timestamp)(nil), // 25: google.protobuf.Timestamp + (*fieldmaskpb.FieldMask)(nil), // 26: google.protobuf.FieldMask } var file_api_v2_user_service_proto_depIdxs = []int32{ 0, // 0: memos.api.v2.User.role:type_name -> memos.api.v2.User.Role - 15, // 1: memos.api.v2.User.row_status:type_name -> memos.api.v2.RowStatus - 16, // 2: memos.api.v2.User.create_time:type_name -> google.protobuf.Timestamp - 16, // 3: memos.api.v2.User.update_time:type_name -> google.protobuf.Timestamp - 1, // 4: memos.api.v2.GetUserResponse.user:type_name -> memos.api.v2.User - 1, // 5: memos.api.v2.CreateUserRequest.user:type_name -> memos.api.v2.User - 1, // 6: memos.api.v2.CreateUserResponse.user:type_name -> memos.api.v2.User - 1, // 7: memos.api.v2.UpdateUserRequest.user:type_name -> memos.api.v2.User - 17, // 8: memos.api.v2.UpdateUserRequest.update_mask:type_name -> google.protobuf.FieldMask - 1, // 9: memos.api.v2.UpdateUserResponse.user:type_name -> memos.api.v2.User - 14, // 10: memos.api.v2.ListUserAccessTokensResponse.access_tokens:type_name -> memos.api.v2.UserAccessToken - 16, // 11: memos.api.v2.CreateUserAccessTokenRequest.expires_at:type_name -> google.protobuf.Timestamp - 14, // 12: memos.api.v2.CreateUserAccessTokenResponse.access_token:type_name -> memos.api.v2.UserAccessToken - 16, // 13: memos.api.v2.UserAccessToken.issued_at:type_name -> google.protobuf.Timestamp - 16, // 14: memos.api.v2.UserAccessToken.expires_at:type_name -> google.protobuf.Timestamp - 2, // 15: memos.api.v2.UserService.GetUser:input_type -> memos.api.v2.GetUserRequest - 4, // 16: memos.api.v2.UserService.CreateUser:input_type -> memos.api.v2.CreateUserRequest - 6, // 17: memos.api.v2.UserService.UpdateUser:input_type -> memos.api.v2.UpdateUserRequest - 8, // 18: memos.api.v2.UserService.ListUserAccessTokens:input_type -> memos.api.v2.ListUserAccessTokensRequest - 10, // 19: memos.api.v2.UserService.CreateUserAccessToken:input_type -> memos.api.v2.CreateUserAccessTokenRequest - 12, // 20: memos.api.v2.UserService.DeleteUserAccessToken:input_type -> memos.api.v2.DeleteUserAccessTokenRequest - 3, // 21: memos.api.v2.UserService.GetUser:output_type -> memos.api.v2.GetUserResponse - 5, // 22: memos.api.v2.UserService.CreateUser:output_type -> memos.api.v2.CreateUserResponse - 7, // 23: memos.api.v2.UserService.UpdateUser:output_type -> memos.api.v2.UpdateUserResponse - 9, // 24: memos.api.v2.UserService.ListUserAccessTokens:output_type -> memos.api.v2.ListUserAccessTokensResponse - 11, // 25: memos.api.v2.UserService.CreateUserAccessToken:output_type -> memos.api.v2.CreateUserAccessTokenResponse - 13, // 26: memos.api.v2.UserService.DeleteUserAccessToken:output_type -> memos.api.v2.DeleteUserAccessTokenResponse - 21, // [21:27] is the sub-list for method output_type - 15, // [15:21] is the sub-list for method input_type - 15, // [15:15] is the sub-list for extension type_name - 15, // [15:15] is the sub-list for extension extendee - 0, // [0:15] is the sub-list for field type_name + 24, // 1: memos.api.v2.User.row_status:type_name -> memos.api.v2.RowStatus + 25, // 2: memos.api.v2.User.create_time:type_name -> google.protobuf.Timestamp + 25, // 3: memos.api.v2.User.update_time:type_name -> google.protobuf.Timestamp + 1, // 4: memos.api.v2.ListUsersResponse.users:type_name -> memos.api.v2.User + 1, // 5: memos.api.v2.GetUserResponse.user:type_name -> memos.api.v2.User + 1, // 6: memos.api.v2.CreateUserRequest.user:type_name -> memos.api.v2.User + 1, // 7: memos.api.v2.CreateUserResponse.user:type_name -> memos.api.v2.User + 1, // 8: memos.api.v2.UpdateUserRequest.user:type_name -> memos.api.v2.User + 26, // 9: memos.api.v2.UpdateUserRequest.update_mask:type_name -> google.protobuf.FieldMask + 1, // 10: memos.api.v2.UpdateUserResponse.user:type_name -> memos.api.v2.User + 12, // 11: memos.api.v2.GetUserSettingResponse.setting:type_name -> memos.api.v2.UserSetting + 12, // 12: memos.api.v2.UpdateUserSettingRequest.setting:type_name -> memos.api.v2.UserSetting + 26, // 13: memos.api.v2.UpdateUserSettingRequest.update_mask:type_name -> google.protobuf.FieldMask + 12, // 14: memos.api.v2.UpdateUserSettingResponse.setting:type_name -> memos.api.v2.UserSetting + 25, // 15: memos.api.v2.UserAccessToken.issued_at:type_name -> google.protobuf.Timestamp + 25, // 16: memos.api.v2.UserAccessToken.expires_at:type_name -> google.protobuf.Timestamp + 17, // 17: memos.api.v2.ListUserAccessTokensResponse.access_tokens:type_name -> memos.api.v2.UserAccessToken + 25, // 18: memos.api.v2.CreateUserAccessTokenRequest.expires_at:type_name -> google.protobuf.Timestamp + 17, // 19: memos.api.v2.CreateUserAccessTokenResponse.access_token:type_name -> memos.api.v2.UserAccessToken + 2, // 20: memos.api.v2.UserService.ListUsers:input_type -> memos.api.v2.ListUsersRequest + 4, // 21: memos.api.v2.UserService.GetUser:input_type -> memos.api.v2.GetUserRequest + 6, // 22: memos.api.v2.UserService.CreateUser:input_type -> memos.api.v2.CreateUserRequest + 8, // 23: memos.api.v2.UserService.UpdateUser:input_type -> memos.api.v2.UpdateUserRequest + 10, // 24: memos.api.v2.UserService.DeleteUser:input_type -> memos.api.v2.DeleteUserRequest + 13, // 25: memos.api.v2.UserService.GetUserSetting:input_type -> memos.api.v2.GetUserSettingRequest + 15, // 26: memos.api.v2.UserService.UpdateUserSetting:input_type -> memos.api.v2.UpdateUserSettingRequest + 18, // 27: memos.api.v2.UserService.ListUserAccessTokens:input_type -> memos.api.v2.ListUserAccessTokensRequest + 20, // 28: memos.api.v2.UserService.CreateUserAccessToken:input_type -> memos.api.v2.CreateUserAccessTokenRequest + 22, // 29: memos.api.v2.UserService.DeleteUserAccessToken:input_type -> memos.api.v2.DeleteUserAccessTokenRequest + 3, // 30: memos.api.v2.UserService.ListUsers:output_type -> memos.api.v2.ListUsersResponse + 5, // 31: memos.api.v2.UserService.GetUser:output_type -> memos.api.v2.GetUserResponse + 7, // 32: memos.api.v2.UserService.CreateUser:output_type -> memos.api.v2.CreateUserResponse + 9, // 33: memos.api.v2.UserService.UpdateUser:output_type -> memos.api.v2.UpdateUserResponse + 11, // 34: memos.api.v2.UserService.DeleteUser:output_type -> memos.api.v2.DeleteUserResponse + 14, // 35: memos.api.v2.UserService.GetUserSetting:output_type -> memos.api.v2.GetUserSettingResponse + 16, // 36: memos.api.v2.UserService.UpdateUserSetting:output_type -> memos.api.v2.UpdateUserSettingResponse + 19, // 37: memos.api.v2.UserService.ListUserAccessTokens:output_type -> memos.api.v2.ListUserAccessTokensResponse + 21, // 38: memos.api.v2.UserService.CreateUserAccessToken:output_type -> memos.api.v2.CreateUserAccessTokenResponse + 23, // 39: memos.api.v2.UserService.DeleteUserAccessToken:output_type -> memos.api.v2.DeleteUserAccessTokenResponse + 30, // [30:40] is the sub-list for method output_type + 20, // [20:30] is the sub-list for method input_type + 20, // [20:20] is the sub-list for extension type_name + 20, // [20:20] is the sub-list for extension extendee + 0, // [0:20] is the sub-list for field type_name } func init() { file_api_v2_user_service_proto_init() } @@ -1133,7 +1702,7 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetUserRequest); i { + switch v := v.(*ListUsersRequest); i { case 0: return &v.state case 1: @@ -1145,7 +1714,7 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetUserResponse); i { + switch v := v.(*ListUsersResponse); i { case 0: return &v.state case 1: @@ -1157,7 +1726,7 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateUserRequest); i { + switch v := v.(*GetUserRequest); i { case 0: return &v.state case 1: @@ -1169,7 +1738,7 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateUserResponse); i { + switch v := v.(*GetUserResponse); i { case 0: return &v.state case 1: @@ -1181,7 +1750,7 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateUserRequest); i { + switch v := v.(*CreateUserRequest); i { case 0: return &v.state case 1: @@ -1193,7 +1762,7 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateUserResponse); i { + switch v := v.(*CreateUserResponse); i { case 0: return &v.state case 1: @@ -1205,7 +1774,7 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListUserAccessTokensRequest); i { + switch v := v.(*UpdateUserRequest); i { case 0: return &v.state case 1: @@ -1217,7 +1786,7 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListUserAccessTokensResponse); i { + switch v := v.(*UpdateUserResponse); i { case 0: return &v.state case 1: @@ -1229,7 +1798,7 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateUserAccessTokenRequest); i { + switch v := v.(*DeleteUserRequest); i { case 0: return &v.state case 1: @@ -1241,7 +1810,7 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateUserAccessTokenResponse); i { + switch v := v.(*DeleteUserResponse); i { case 0: return &v.state case 1: @@ -1253,7 +1822,7 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteUserAccessTokenRequest); i { + switch v := v.(*UserSetting); i { case 0: return &v.state case 1: @@ -1265,7 +1834,7 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteUserAccessTokenResponse); i { + switch v := v.(*GetUserSettingRequest); i { case 0: return &v.state case 1: @@ -1277,6 +1846,42 @@ func file_api_v2_user_service_proto_init() { } } file_api_v2_user_service_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetUserSettingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_user_service_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateUserSettingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_user_service_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateUserSettingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_user_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*UserAccessToken); i { case 0: return &v.state @@ -1288,15 +1893,87 @@ func file_api_v2_user_service_proto_init() { return nil } } + file_api_v2_user_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListUserAccessTokensRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_user_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListUserAccessTokensResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_user_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateUserAccessTokenRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_user_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateUserAccessTokenResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_user_service_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteUserAccessTokenRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_user_service_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteUserAccessTokenResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } - file_api_v2_user_service_proto_msgTypes[9].OneofWrappers = []interface{}{} + file_api_v2_user_service_proto_msgTypes[19].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_v2_user_service_proto_rawDesc, NumEnums: 1, - NumMessages: 14, + NumMessages: 23, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gen/api/v2/user_service.pb.gw.go b/proto/gen/api/v2/user_service.pb.gw.go index 8076647ba9d88..5efaa1aabc9e6 100644 --- a/proto/gen/api/v2/user_service.pb.gw.go +++ b/proto/gen/api/v2/user_service.pb.gw.go @@ -31,6 +31,24 @@ var _ = runtime.String var _ = utilities.NewDoubleArray var _ = metadata.Join +func request_UserService_ListUsers_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListUsersRequest + var metadata runtime.ServerMetadata + + msg, err := client.ListUsers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_UserService_ListUsers_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListUsersRequest + var metadata runtime.ServerMetadata + + msg, err := server.ListUsers(ctx, &protoReq) + return msg, metadata, err + +} + func request_UserService_GetUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq GetUserRequest var metadata runtime.ServerMetadata @@ -42,14 +60,14 @@ func request_UserService_GetUser_0(ctx context.Context, marshaler runtime.Marsha _ = err ) - val, ok = pathParams["username"] + val, ok = pathParams["name"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } - protoReq.Username, err = runtime.String(val) + protoReq.Name, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } msg, err := client.GetUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -68,14 +86,14 @@ func local_request_UserService_GetUser_0(ctx context.Context, marshaler runtime. _ = err ) - val, ok = pathParams["username"] + val, ok = pathParams["name"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } - protoReq.Username, err = runtime.String(val) + protoReq.Name, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } msg, err := server.GetUser(ctx, &protoReq) @@ -118,7 +136,7 @@ func local_request_UserService_CreateUser_0(ctx context.Context, marshaler runti } var ( - filter_UserService_UpdateUser_0 = &utilities.DoubleArray{Encoding: map[string]int{"user": 0, "username": 1}, Base: []int{1, 4, 5, 2, 0, 0, 0, 0}, Check: []int{0, 1, 1, 2, 4, 2, 2, 3}} + filter_UserService_UpdateUser_0 = &utilities.DoubleArray{Encoding: map[string]int{"user": 0, "name": 1}, Base: []int{1, 4, 5, 2, 0, 0, 0, 0}, Check: []int{0, 1, 1, 2, 4, 2, 2, 3}} ) func request_UserService_UpdateUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -147,14 +165,14 @@ func request_UserService_UpdateUser_0(ctx context.Context, marshaler runtime.Mar _ = err ) - val, ok = pathParams["user.username"] + val, ok = pathParams["user.name"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "user.username") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "user.name") } - err = runtime.PopulateFieldFromPath(&protoReq, "user.username", val) + err = runtime.PopulateFieldFromPath(&protoReq, "user.name", val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "user.username", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "user.name", err) } if err := req.ParseForm(); err != nil { @@ -195,14 +213,14 @@ func local_request_UserService_UpdateUser_0(ctx context.Context, marshaler runti _ = err ) - val, ok = pathParams["user.username"] + val, ok = pathParams["user.name"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "user.username") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "user.name") } - err = runtime.PopulateFieldFromPath(&protoReq, "user.username", val) + err = runtime.PopulateFieldFromPath(&protoReq, "user.name", val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "user.username", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "user.name", err) } if err := req.ParseForm(); err != nil { @@ -217,6 +235,210 @@ func local_request_UserService_UpdateUser_0(ctx context.Context, marshaler runti } +func request_UserService_DeleteUser_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteUserRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := client.DeleteUser(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_UserService_DeleteUser_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteUserRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := server.DeleteUser(ctx, &protoReq) + return msg, metadata, err + +} + +func request_UserService_GetUserSetting_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetUserSettingRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := client.GetUserSetting(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_UserService_GetUserSetting_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetUserSettingRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := server.GetUserSetting(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_UserService_UpdateUserSetting_0 = &utilities.DoubleArray{Encoding: map[string]int{"setting": 0, "name": 1}, Base: []int{1, 4, 5, 2, 0, 0, 0, 0}, Check: []int{0, 1, 1, 2, 4, 2, 2, 3}} +) + +func request_UserService_UpdateUserSetting_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateUserSettingRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Setting); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 { + if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Setting); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } else { + protoReq.UpdateMask = fieldMask + } + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["setting.name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "setting.name") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "setting.name", val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "setting.name", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_UpdateUserSetting_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.UpdateUserSetting(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_UserService_UpdateUserSetting_0(ctx context.Context, marshaler runtime.Marshaler, server UserServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateUserSettingRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Setting); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 { + if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Setting); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } else { + protoReq.UpdateMask = fieldMask + } + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["setting.name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "setting.name") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "setting.name", val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "setting.name", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_UserService_UpdateUserSetting_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.UpdateUserSetting(ctx, &protoReq) + return msg, metadata, err + +} + func request_UserService_ListUserAccessTokens_0(ctx context.Context, marshaler runtime.Marshaler, client UserServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq ListUserAccessTokensRequest var metadata runtime.ServerMetadata @@ -228,14 +450,14 @@ func request_UserService_ListUserAccessTokens_0(ctx context.Context, marshaler r _ = err ) - val, ok = pathParams["username"] + val, ok = pathParams["name"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } - protoReq.Username, err = runtime.String(val) + protoReq.Name, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } msg, err := client.ListUserAccessTokens(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -254,14 +476,14 @@ func local_request_UserService_ListUserAccessTokens_0(ctx context.Context, marsh _ = err ) - val, ok = pathParams["username"] + val, ok = pathParams["name"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } - protoReq.Username, err = runtime.String(val) + protoReq.Name, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } msg, err := server.ListUserAccessTokens(ctx, &protoReq) @@ -288,14 +510,14 @@ func request_UserService_CreateUserAccessToken_0(ctx context.Context, marshaler _ = err ) - val, ok = pathParams["username"] + val, ok = pathParams["name"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } - protoReq.Username, err = runtime.String(val) + protoReq.Name, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } msg, err := client.CreateUserAccessToken(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) @@ -322,14 +544,14 @@ func local_request_UserService_CreateUserAccessToken_0(ctx context.Context, mars _ = err ) - val, ok = pathParams["username"] + val, ok = pathParams["name"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } - protoReq.Username, err = runtime.String(val) + protoReq.Name, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } msg, err := server.CreateUserAccessToken(ctx, &protoReq) @@ -348,14 +570,14 @@ func request_UserService_DeleteUserAccessToken_0(ctx context.Context, marshaler _ = err ) - val, ok = pathParams["username"] + val, ok = pathParams["name"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } - protoReq.Username, err = runtime.String(val) + protoReq.Name, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } val, ok = pathParams["access_token"] @@ -384,14 +606,14 @@ func local_request_UserService_DeleteUserAccessToken_0(ctx context.Context, mars _ = err ) - val, ok = pathParams["username"] + val, ok = pathParams["name"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "username") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") } - protoReq.Username, err = runtime.String(val) + protoReq.Name, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "username", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) } val, ok = pathParams["access_token"] @@ -415,6 +637,31 @@ func local_request_UserService_DeleteUserAccessToken_0(ctx context.Context, mars // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterUserServiceHandlerFromEndpoint instead. func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server UserServiceServer) error { + mux.Handle("GET", pattern_UserService_ListUsers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/ListUsers", runtime.WithHTTPPathPattern("/api/v2/users")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_UserService_ListUsers_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_UserService_ListUsers_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_UserService_GetUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -423,7 +670,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/GetUser", runtime.WithHTTPPathPattern("/api/v2/users/{username}")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/GetUser", runtime.WithHTTPPathPattern("/api/v2/{name=users/*}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -448,7 +695,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/CreateUser", runtime.WithHTTPPathPattern("/v1/users")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/CreateUser", runtime.WithHTTPPathPattern("/api/v2/users")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -473,7 +720,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/UpdateUser", runtime.WithHTTPPathPattern("/api/v2/users/{user.username}")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/UpdateUser", runtime.WithHTTPPathPattern("/api/v2/{user.name=users/*}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -490,6 +737,81 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("DELETE", pattern_UserService_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/DeleteUser", runtime.WithHTTPPathPattern("/api/v2/{name=users/*}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_UserService_DeleteUser_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_UserService_DeleteUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_UserService_GetUserSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/GetUserSetting", runtime.WithHTTPPathPattern("/api/v2/{name=users/*}/setting")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_UserService_GetUserSetting_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_UserService_GetUserSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_UserService_UpdateUserSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/UpdateUserSetting", runtime.WithHTTPPathPattern("/api/v2/{setting.name=users/*/setting}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_UserService_UpdateUserSetting_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_UserService_UpdateUserSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_UserService_ListUserAccessTokens_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -498,7 +820,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/ListUserAccessTokens", runtime.WithHTTPPathPattern("/api/v2/users/{username}/access_tokens")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/ListUserAccessTokens", runtime.WithHTTPPathPattern("/api/v2/{name=users/*}/access_tokens")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -523,7 +845,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/CreateUserAccessToken", runtime.WithHTTPPathPattern("/api/v2/users/{username}/access_tokens")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/CreateUserAccessToken", runtime.WithHTTPPathPattern("/api/v2/{name=users/*}/access_tokens")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -548,7 +870,7 @@ func RegisterUserServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/DeleteUserAccessToken", runtime.WithHTTPPathPattern("/api/v2/users/{username}/access_tokens/{access_token}")) + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.UserService/DeleteUserAccessToken", runtime.WithHTTPPathPattern("/api/v2/{name=users/*}/access_tokens/{access_token}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -606,13 +928,35 @@ func RegisterUserServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn // "UserServiceClient" to call the correct interceptors. func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client UserServiceClient) error { + mux.Handle("GET", pattern_UserService_ListUsers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/ListUsers", runtime.WithHTTPPathPattern("/api/v2/users")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_UserService_ListUsers_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_UserService_ListUsers_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_UserService_GetUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/GetUser", runtime.WithHTTPPathPattern("/api/v2/users/{username}")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/GetUser", runtime.WithHTTPPathPattern("/api/v2/{name=users/*}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -634,7 +978,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/CreateUser", runtime.WithHTTPPathPattern("/v1/users")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/CreateUser", runtime.WithHTTPPathPattern("/api/v2/users")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -656,7 +1000,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/UpdateUser", runtime.WithHTTPPathPattern("/api/v2/users/{user.username}")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/UpdateUser", runtime.WithHTTPPathPattern("/api/v2/{user.name=users/*}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -672,13 +1016,79 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux }) + mux.Handle("DELETE", pattern_UserService_DeleteUser_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/DeleteUser", runtime.WithHTTPPathPattern("/api/v2/{name=users/*}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_UserService_DeleteUser_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_UserService_DeleteUser_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_UserService_GetUserSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/GetUserSetting", runtime.WithHTTPPathPattern("/api/v2/{name=users/*}/setting")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_UserService_GetUserSetting_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_UserService_GetUserSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_UserService_UpdateUserSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/UpdateUserSetting", runtime.WithHTTPPathPattern("/api/v2/{setting.name=users/*/setting}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_UserService_UpdateUserSetting_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_UserService_UpdateUserSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_UserService_ListUserAccessTokens_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/ListUserAccessTokens", runtime.WithHTTPPathPattern("/api/v2/users/{username}/access_tokens")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/ListUserAccessTokens", runtime.WithHTTPPathPattern("/api/v2/{name=users/*}/access_tokens")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -700,7 +1110,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/CreateUserAccessToken", runtime.WithHTTPPathPattern("/api/v2/users/{username}/access_tokens")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/CreateUserAccessToken", runtime.WithHTTPPathPattern("/api/v2/{name=users/*}/access_tokens")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -722,7 +1132,7 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) var err error var annotatedContext context.Context - annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/DeleteUserAccessToken", runtime.WithHTTPPathPattern("/api/v2/users/{username}/access_tokens/{access_token}")) + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.UserService/DeleteUserAccessToken", runtime.WithHTTPPathPattern("/api/v2/{name=users/*}/access_tokens/{access_token}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return @@ -742,26 +1152,42 @@ func RegisterUserServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux } var ( - pattern_UserService_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "users", "username"}, "")) + pattern_UserService_ListUsers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "users"}, "")) + + pattern_UserService_GetUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v2", "users", "name"}, "")) + + pattern_UserService_CreateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "users"}, "")) + + pattern_UserService_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v2", "users", "user.name"}, "")) - pattern_UserService_CreateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "users"}, "")) + pattern_UserService_DeleteUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3}, []string{"api", "v2", "users", "name"}, "")) - pattern_UserService_UpdateUser_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "users", "user.username"}, "")) + pattern_UserService_GetUserSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v2", "users", "name", "setting"}, "")) - pattern_UserService_ListUserAccessTokens_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "users", "username", "access_tokens"}, "")) + pattern_UserService_UpdateUserSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 2, 3, 4, 3, 5, 4}, []string{"api", "v2", "users", "setting", "setting.name"}, "")) - pattern_UserService_CreateUserAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"api", "v2", "users", "username", "access_tokens"}, "")) + pattern_UserService_ListUserAccessTokens_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v2", "users", "name", "access_tokens"}, "")) - pattern_UserService_DeleteUserAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"api", "v2", "users", "username", "access_tokens", "access_token"}, "")) + pattern_UserService_CreateUserAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4}, []string{"api", "v2", "users", "name", "access_tokens"}, "")) + + pattern_UserService_DeleteUserAccessToken_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 2, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"api", "v2", "users", "name", "access_tokens", "access_token"}, "")) ) var ( + forward_UserService_ListUsers_0 = runtime.ForwardResponseMessage + forward_UserService_GetUser_0 = runtime.ForwardResponseMessage forward_UserService_CreateUser_0 = runtime.ForwardResponseMessage forward_UserService_UpdateUser_0 = runtime.ForwardResponseMessage + forward_UserService_DeleteUser_0 = runtime.ForwardResponseMessage + + forward_UserService_GetUserSetting_0 = runtime.ForwardResponseMessage + + forward_UserService_UpdateUserSetting_0 = runtime.ForwardResponseMessage + forward_UserService_ListUserAccessTokens_0 = runtime.ForwardResponseMessage forward_UserService_CreateUserAccessToken_0 = runtime.ForwardResponseMessage diff --git a/proto/gen/api/v2/user_service_grpc.pb.go b/proto/gen/api/v2/user_service_grpc.pb.go index 340a308f6e30e..d8345427ad095 100644 --- a/proto/gen/api/v2/user_service_grpc.pb.go +++ b/proto/gen/api/v2/user_service_grpc.pb.go @@ -19,9 +19,13 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( + UserService_ListUsers_FullMethodName = "/memos.api.v2.UserService/ListUsers" UserService_GetUser_FullMethodName = "/memos.api.v2.UserService/GetUser" UserService_CreateUser_FullMethodName = "/memos.api.v2.UserService/CreateUser" UserService_UpdateUser_FullMethodName = "/memos.api.v2.UserService/UpdateUser" + UserService_DeleteUser_FullMethodName = "/memos.api.v2.UserService/DeleteUser" + UserService_GetUserSetting_FullMethodName = "/memos.api.v2.UserService/GetUserSetting" + UserService_UpdateUserSetting_FullMethodName = "/memos.api.v2.UserService/UpdateUserSetting" UserService_ListUserAccessTokens_FullMethodName = "/memos.api.v2.UserService/ListUserAccessTokens" UserService_CreateUserAccessToken_FullMethodName = "/memos.api.v2.UserService/CreateUserAccessToken" UserService_DeleteUserAccessToken_FullMethodName = "/memos.api.v2.UserService/DeleteUserAccessToken" @@ -31,9 +35,20 @@ const ( // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type UserServiceClient interface { + // ListUsers returns a list of users. + ListUsers(ctx context.Context, in *ListUsersRequest, opts ...grpc.CallOption) (*ListUsersResponse, error) + // GetUser gets a user by name. GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error) + // CreateUser creates a new user. CreateUser(ctx context.Context, in *CreateUserRequest, opts ...grpc.CallOption) (*CreateUserResponse, error) + // UpdateUser updates a user. UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...grpc.CallOption) (*UpdateUserResponse, error) + // DeleteUser deletes a user. + DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*DeleteUserResponse, error) + // GetUserSetting gets the setting of a user. + GetUserSetting(ctx context.Context, in *GetUserSettingRequest, opts ...grpc.CallOption) (*GetUserSettingResponse, error) + // UpdateUserSetting updates the setting of a user. + UpdateUserSetting(ctx context.Context, in *UpdateUserSettingRequest, opts ...grpc.CallOption) (*UpdateUserSettingResponse, error) // ListUserAccessTokens returns a list of access tokens for a user. ListUserAccessTokens(ctx context.Context, in *ListUserAccessTokensRequest, opts ...grpc.CallOption) (*ListUserAccessTokensResponse, error) // CreateUserAccessToken creates a new access token for a user. @@ -50,6 +65,15 @@ func NewUserServiceClient(cc grpc.ClientConnInterface) UserServiceClient { return &userServiceClient{cc} } +func (c *userServiceClient) ListUsers(ctx context.Context, in *ListUsersRequest, opts ...grpc.CallOption) (*ListUsersResponse, error) { + out := new(ListUsersResponse) + err := c.cc.Invoke(ctx, UserService_ListUsers_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *userServiceClient) GetUser(ctx context.Context, in *GetUserRequest, opts ...grpc.CallOption) (*GetUserResponse, error) { out := new(GetUserResponse) err := c.cc.Invoke(ctx, UserService_GetUser_FullMethodName, in, out, opts...) @@ -77,6 +101,33 @@ func (c *userServiceClient) UpdateUser(ctx context.Context, in *UpdateUserReques return out, nil } +func (c *userServiceClient) DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...grpc.CallOption) (*DeleteUserResponse, error) { + out := new(DeleteUserResponse) + err := c.cc.Invoke(ctx, UserService_DeleteUser_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) GetUserSetting(ctx context.Context, in *GetUserSettingRequest, opts ...grpc.CallOption) (*GetUserSettingResponse, error) { + out := new(GetUserSettingResponse) + err := c.cc.Invoke(ctx, UserService_GetUserSetting_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *userServiceClient) UpdateUserSetting(ctx context.Context, in *UpdateUserSettingRequest, opts ...grpc.CallOption) (*UpdateUserSettingResponse, error) { + out := new(UpdateUserSettingResponse) + err := c.cc.Invoke(ctx, UserService_UpdateUserSetting_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *userServiceClient) ListUserAccessTokens(ctx context.Context, in *ListUserAccessTokensRequest, opts ...grpc.CallOption) (*ListUserAccessTokensResponse, error) { out := new(ListUserAccessTokensResponse) err := c.cc.Invoke(ctx, UserService_ListUserAccessTokens_FullMethodName, in, out, opts...) @@ -108,9 +159,20 @@ func (c *userServiceClient) DeleteUserAccessToken(ctx context.Context, in *Delet // All implementations must embed UnimplementedUserServiceServer // for forward compatibility type UserServiceServer interface { + // ListUsers returns a list of users. + ListUsers(context.Context, *ListUsersRequest) (*ListUsersResponse, error) + // GetUser gets a user by name. GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error) + // CreateUser creates a new user. CreateUser(context.Context, *CreateUserRequest) (*CreateUserResponse, error) + // UpdateUser updates a user. UpdateUser(context.Context, *UpdateUserRequest) (*UpdateUserResponse, error) + // DeleteUser deletes a user. + DeleteUser(context.Context, *DeleteUserRequest) (*DeleteUserResponse, error) + // GetUserSetting gets the setting of a user. + GetUserSetting(context.Context, *GetUserSettingRequest) (*GetUserSettingResponse, error) + // UpdateUserSetting updates the setting of a user. + UpdateUserSetting(context.Context, *UpdateUserSettingRequest) (*UpdateUserSettingResponse, error) // ListUserAccessTokens returns a list of access tokens for a user. ListUserAccessTokens(context.Context, *ListUserAccessTokensRequest) (*ListUserAccessTokensResponse, error) // CreateUserAccessToken creates a new access token for a user. @@ -124,6 +186,9 @@ type UserServiceServer interface { type UnimplementedUserServiceServer struct { } +func (UnimplementedUserServiceServer) ListUsers(context.Context, *ListUsersRequest) (*ListUsersResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListUsers not implemented") +} func (UnimplementedUserServiceServer) GetUser(context.Context, *GetUserRequest) (*GetUserResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetUser not implemented") } @@ -133,6 +198,15 @@ func (UnimplementedUserServiceServer) CreateUser(context.Context, *CreateUserReq func (UnimplementedUserServiceServer) UpdateUser(context.Context, *UpdateUserRequest) (*UpdateUserResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateUser not implemented") } +func (UnimplementedUserServiceServer) DeleteUser(context.Context, *DeleteUserRequest) (*DeleteUserResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteUser not implemented") +} +func (UnimplementedUserServiceServer) GetUserSetting(context.Context, *GetUserSettingRequest) (*GetUserSettingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetUserSetting not implemented") +} +func (UnimplementedUserServiceServer) UpdateUserSetting(context.Context, *UpdateUserSettingRequest) (*UpdateUserSettingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateUserSetting not implemented") +} func (UnimplementedUserServiceServer) ListUserAccessTokens(context.Context, *ListUserAccessTokensRequest) (*ListUserAccessTokensResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListUserAccessTokens not implemented") } @@ -155,6 +229,24 @@ func RegisterUserServiceServer(s grpc.ServiceRegistrar, srv UserServiceServer) { s.RegisterService(&UserService_ServiceDesc, srv) } +func _UserService_ListUsers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListUsersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).ListUsers(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_ListUsers_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).ListUsers(ctx, req.(*ListUsersRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _UserService_GetUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetUserRequest) if err := dec(in); err != nil { @@ -209,6 +301,60 @@ func _UserService_UpdateUser_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _UserService_DeleteUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteUserRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).DeleteUser(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_DeleteUser_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).DeleteUser(ctx, req.(*DeleteUserRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_GetUserSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetUserSettingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).GetUserSetting(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_GetUserSetting_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).GetUserSetting(ctx, req.(*GetUserSettingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _UserService_UpdateUserSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateUserSettingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(UserServiceServer).UpdateUserSetting(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: UserService_UpdateUserSetting_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(UserServiceServer).UpdateUserSetting(ctx, req.(*UpdateUserSettingRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _UserService_ListUserAccessTokens_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(ListUserAccessTokensRequest) if err := dec(in); err != nil { @@ -270,6 +416,10 @@ var UserService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "memos.api.v2.UserService", HandlerType: (*UserServiceServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "ListUsers", + Handler: _UserService_ListUsers_Handler, + }, { MethodName: "GetUser", Handler: _UserService_GetUser_Handler, @@ -282,6 +432,18 @@ var UserService_ServiceDesc = grpc.ServiceDesc{ MethodName: "UpdateUser", Handler: _UserService_UpdateUser_Handler, }, + { + MethodName: "DeleteUser", + Handler: _UserService_DeleteUser_Handler, + }, + { + MethodName: "GetUserSetting", + Handler: _UserService_GetUserSetting_Handler, + }, + { + MethodName: "UpdateUserSetting", + Handler: _UserService_UpdateUserSetting_Handler, + }, { MethodName: "ListUserAccessTokens", Handler: _UserService_ListUserAccessTokens_Handler, diff --git a/proto/gen/api/v2/webhook_service.pb.go b/proto/gen/api/v2/webhook_service.pb.go new file mode 100644 index 0000000000000..43f33561da910 --- /dev/null +++ b/proto/gen/api/v2/webhook_service.pb.go @@ -0,0 +1,939 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: api/v2/webhook_service.proto + +package apiv2 + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Webhook struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + CreatorId int32 `protobuf:"varint,2,opt,name=creator_id,json=creatorId,proto3" json:"creator_id,omitempty"` + CreatedTime *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_time,json=createdTime,proto3" json:"created_time,omitempty"` + UpdatedTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=updated_time,json=updatedTime,proto3" json:"updated_time,omitempty"` + RowStatus RowStatus `protobuf:"varint,5,opt,name=row_status,json=rowStatus,proto3,enum=memos.api.v2.RowStatus" json:"row_status,omitempty"` + Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` + Url string `protobuf:"bytes,7,opt,name=url,proto3" json:"url,omitempty"` +} + +func (x *Webhook) Reset() { + *x = Webhook{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_webhook_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Webhook) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Webhook) ProtoMessage() {} + +func (x *Webhook) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_webhook_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Webhook.ProtoReflect.Descriptor instead. +func (*Webhook) Descriptor() ([]byte, []int) { + return file_api_v2_webhook_service_proto_rawDescGZIP(), []int{0} +} + +func (x *Webhook) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Webhook) GetCreatorId() int32 { + if x != nil { + return x.CreatorId + } + return 0 +} + +func (x *Webhook) GetCreatedTime() *timestamppb.Timestamp { + if x != nil { + return x.CreatedTime + } + return nil +} + +func (x *Webhook) GetUpdatedTime() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedTime + } + return nil +} + +func (x *Webhook) GetRowStatus() RowStatus { + if x != nil { + return x.RowStatus + } + return RowStatus_ROW_STATUS_UNSPECIFIED +} + +func (x *Webhook) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Webhook) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +type CreateWebhookRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"` +} + +func (x *CreateWebhookRequest) Reset() { + *x = CreateWebhookRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_webhook_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateWebhookRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateWebhookRequest) ProtoMessage() {} + +func (x *CreateWebhookRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_webhook_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateWebhookRequest.ProtoReflect.Descriptor instead. +func (*CreateWebhookRequest) Descriptor() ([]byte, []int) { + return file_api_v2_webhook_service_proto_rawDescGZIP(), []int{1} +} + +func (x *CreateWebhookRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateWebhookRequest) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +type CreateWebhookResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Webhook *Webhook `protobuf:"bytes,1,opt,name=webhook,proto3" json:"webhook,omitempty"` +} + +func (x *CreateWebhookResponse) Reset() { + *x = CreateWebhookResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_webhook_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateWebhookResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateWebhookResponse) ProtoMessage() {} + +func (x *CreateWebhookResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_webhook_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateWebhookResponse.ProtoReflect.Descriptor instead. +func (*CreateWebhookResponse) Descriptor() ([]byte, []int) { + return file_api_v2_webhook_service_proto_rawDescGZIP(), []int{2} +} + +func (x *CreateWebhookResponse) GetWebhook() *Webhook { + if x != nil { + return x.Webhook + } + return nil +} + +type GetWebhookRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *GetWebhookRequest) Reset() { + *x = GetWebhookRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_webhook_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetWebhookRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetWebhookRequest) ProtoMessage() {} + +func (x *GetWebhookRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_webhook_service_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetWebhookRequest.ProtoReflect.Descriptor instead. +func (*GetWebhookRequest) Descriptor() ([]byte, []int) { + return file_api_v2_webhook_service_proto_rawDescGZIP(), []int{3} +} + +func (x *GetWebhookRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +type GetWebhookResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Webhook *Webhook `protobuf:"bytes,1,opt,name=webhook,proto3" json:"webhook,omitempty"` +} + +func (x *GetWebhookResponse) Reset() { + *x = GetWebhookResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_webhook_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetWebhookResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetWebhookResponse) ProtoMessage() {} + +func (x *GetWebhookResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_webhook_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetWebhookResponse.ProtoReflect.Descriptor instead. +func (*GetWebhookResponse) Descriptor() ([]byte, []int) { + return file_api_v2_webhook_service_proto_rawDescGZIP(), []int{4} +} + +func (x *GetWebhookResponse) GetWebhook() *Webhook { + if x != nil { + return x.Webhook + } + return nil +} + +type ListWebhooksRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CreatorId int32 `protobuf:"varint,1,opt,name=creator_id,json=creatorId,proto3" json:"creator_id,omitempty"` +} + +func (x *ListWebhooksRequest) Reset() { + *x = ListWebhooksRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_webhook_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListWebhooksRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListWebhooksRequest) ProtoMessage() {} + +func (x *ListWebhooksRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_webhook_service_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListWebhooksRequest.ProtoReflect.Descriptor instead. +func (*ListWebhooksRequest) Descriptor() ([]byte, []int) { + return file_api_v2_webhook_service_proto_rawDescGZIP(), []int{5} +} + +func (x *ListWebhooksRequest) GetCreatorId() int32 { + if x != nil { + return x.CreatorId + } + return 0 +} + +type ListWebhooksResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Webhooks []*Webhook `protobuf:"bytes,1,rep,name=webhooks,proto3" json:"webhooks,omitempty"` +} + +func (x *ListWebhooksResponse) Reset() { + *x = ListWebhooksResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_webhook_service_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListWebhooksResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListWebhooksResponse) ProtoMessage() {} + +func (x *ListWebhooksResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_webhook_service_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListWebhooksResponse.ProtoReflect.Descriptor instead. +func (*ListWebhooksResponse) Descriptor() ([]byte, []int) { + return file_api_v2_webhook_service_proto_rawDescGZIP(), []int{6} +} + +func (x *ListWebhooksResponse) GetWebhooks() []*Webhook { + if x != nil { + return x.Webhooks + } + return nil +} + +type UpdateWebhookRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Webhook *Webhook `protobuf:"bytes,1,opt,name=webhook,proto3" json:"webhook,omitempty"` + UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` +} + +func (x *UpdateWebhookRequest) Reset() { + *x = UpdateWebhookRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_webhook_service_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateWebhookRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateWebhookRequest) ProtoMessage() {} + +func (x *UpdateWebhookRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_webhook_service_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateWebhookRequest.ProtoReflect.Descriptor instead. +func (*UpdateWebhookRequest) Descriptor() ([]byte, []int) { + return file_api_v2_webhook_service_proto_rawDescGZIP(), []int{7} +} + +func (x *UpdateWebhookRequest) GetWebhook() *Webhook { + if x != nil { + return x.Webhook + } + return nil +} + +func (x *UpdateWebhookRequest) GetUpdateMask() *fieldmaskpb.FieldMask { + if x != nil { + return x.UpdateMask + } + return nil +} + +type UpdateWebhookResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Webhook *Webhook `protobuf:"bytes,1,opt,name=webhook,proto3" json:"webhook,omitempty"` +} + +func (x *UpdateWebhookResponse) Reset() { + *x = UpdateWebhookResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_webhook_service_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateWebhookResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateWebhookResponse) ProtoMessage() {} + +func (x *UpdateWebhookResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_webhook_service_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateWebhookResponse.ProtoReflect.Descriptor instead. +func (*UpdateWebhookResponse) Descriptor() ([]byte, []int) { + return file_api_v2_webhook_service_proto_rawDescGZIP(), []int{8} +} + +func (x *UpdateWebhookResponse) GetWebhook() *Webhook { + if x != nil { + return x.Webhook + } + return nil +} + +type DeleteWebhookRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *DeleteWebhookRequest) Reset() { + *x = DeleteWebhookRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_webhook_service_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteWebhookRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteWebhookRequest) ProtoMessage() {} + +func (x *DeleteWebhookRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_webhook_service_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteWebhookRequest.ProtoReflect.Descriptor instead. +func (*DeleteWebhookRequest) Descriptor() ([]byte, []int) { + return file_api_v2_webhook_service_proto_rawDescGZIP(), []int{9} +} + +func (x *DeleteWebhookRequest) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +type DeleteWebhookResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *DeleteWebhookResponse) Reset() { + *x = DeleteWebhookResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_webhook_service_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteWebhookResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteWebhookResponse) ProtoMessage() {} + +func (x *DeleteWebhookResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_webhook_service_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteWebhookResponse.ProtoReflect.Descriptor instead. +func (*DeleteWebhookResponse) Descriptor() ([]byte, []int) { + return file_api_v2_webhook_service_proto_rawDescGZIP(), []int{10} +} + +var File_api_v2_webhook_service_proto protoreflect.FileDescriptor + +var file_api_v2_webhook_service_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x13, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, + 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x94, 0x02, 0x0a, 0x07, + 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x3d, 0x0a, 0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x09, 0x72, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, + 0x72, 0x6c, 0x22, 0x3c, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, + 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, + 0x22, 0x48, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, + 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x77, 0x65, 0x62, + 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, + 0x6b, 0x52, 0x07, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x22, 0x23, 0x0a, 0x11, 0x47, 0x65, + 0x74, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x22, + 0x45, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x07, 0x77, + 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x22, 0x34, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x65, + 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x22, 0x49, 0x0a, 0x14, + 0x4c, 0x69, 0x73, 0x74, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x08, 0x77, + 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x22, 0x84, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x2f, 0x0a, 0x07, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x07, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, + 0x6b, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, + 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x48, + 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x77, 0x65, 0x62, 0x68, 0x6f, + 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, + 0x07, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x22, 0x26, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, + 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, + 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8c, 0x05, 0x0a, 0x0e, 0x57, 0x65, + 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x75, 0x0a, 0x0d, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x22, 0x2e, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, + 0x2a, 0x22, 0x10, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x77, 0x65, 0x62, 0x68, 0x6f, + 0x6f, 0x6b, 0x73, 0x12, 0x73, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, + 0x6b, 0x12, 0x1f, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x47, 0x65, 0x74, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x32, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x17, 0x12, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x77, 0x65, 0x62, 0x68, 0x6f, + 0x6f, 0x6b, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x6f, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, + 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0x21, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x65, 0x62, 0x68, + 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x57, + 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, + 0x2f, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0x9e, 0x01, 0x0a, 0x0d, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x22, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44, 0xda, 0x41, 0x13, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, + 0x2c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x28, 0x3a, 0x07, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x32, 0x1d, 0x2f, 0x61, 0x70, + 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x2f, 0x7b, 0x77, + 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, 0x69, 0x64, 0x7d, 0x12, 0x7c, 0x0a, 0x0d, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x22, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x23, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0xda, 0x41, 0x02, 0x69, 0x64, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x17, 0x2a, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x77, 0x65, 0x62, 0x68, 0x6f, + 0x6f, 0x6b, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x42, 0xab, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x42, 0x13, 0x57, + 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, + 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, + 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, + 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, + 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, + 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_v2_webhook_service_proto_rawDescOnce sync.Once + file_api_v2_webhook_service_proto_rawDescData = file_api_v2_webhook_service_proto_rawDesc +) + +func file_api_v2_webhook_service_proto_rawDescGZIP() []byte { + file_api_v2_webhook_service_proto_rawDescOnce.Do(func() { + file_api_v2_webhook_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_v2_webhook_service_proto_rawDescData) + }) + return file_api_v2_webhook_service_proto_rawDescData +} + +var file_api_v2_webhook_service_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_api_v2_webhook_service_proto_goTypes = []interface{}{ + (*Webhook)(nil), // 0: memos.api.v2.Webhook + (*CreateWebhookRequest)(nil), // 1: memos.api.v2.CreateWebhookRequest + (*CreateWebhookResponse)(nil), // 2: memos.api.v2.CreateWebhookResponse + (*GetWebhookRequest)(nil), // 3: memos.api.v2.GetWebhookRequest + (*GetWebhookResponse)(nil), // 4: memos.api.v2.GetWebhookResponse + (*ListWebhooksRequest)(nil), // 5: memos.api.v2.ListWebhooksRequest + (*ListWebhooksResponse)(nil), // 6: memos.api.v2.ListWebhooksResponse + (*UpdateWebhookRequest)(nil), // 7: memos.api.v2.UpdateWebhookRequest + (*UpdateWebhookResponse)(nil), // 8: memos.api.v2.UpdateWebhookResponse + (*DeleteWebhookRequest)(nil), // 9: memos.api.v2.DeleteWebhookRequest + (*DeleteWebhookResponse)(nil), // 10: memos.api.v2.DeleteWebhookResponse + (*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp + (RowStatus)(0), // 12: memos.api.v2.RowStatus + (*fieldmaskpb.FieldMask)(nil), // 13: google.protobuf.FieldMask +} +var file_api_v2_webhook_service_proto_depIdxs = []int32{ + 11, // 0: memos.api.v2.Webhook.created_time:type_name -> google.protobuf.Timestamp + 11, // 1: memos.api.v2.Webhook.updated_time:type_name -> google.protobuf.Timestamp + 12, // 2: memos.api.v2.Webhook.row_status:type_name -> memos.api.v2.RowStatus + 0, // 3: memos.api.v2.CreateWebhookResponse.webhook:type_name -> memos.api.v2.Webhook + 0, // 4: memos.api.v2.GetWebhookResponse.webhook:type_name -> memos.api.v2.Webhook + 0, // 5: memos.api.v2.ListWebhooksResponse.webhooks:type_name -> memos.api.v2.Webhook + 0, // 6: memos.api.v2.UpdateWebhookRequest.webhook:type_name -> memos.api.v2.Webhook + 13, // 7: memos.api.v2.UpdateWebhookRequest.update_mask:type_name -> google.protobuf.FieldMask + 0, // 8: memos.api.v2.UpdateWebhookResponse.webhook:type_name -> memos.api.v2.Webhook + 1, // 9: memos.api.v2.WebhookService.CreateWebhook:input_type -> memos.api.v2.CreateWebhookRequest + 3, // 10: memos.api.v2.WebhookService.GetWebhook:input_type -> memos.api.v2.GetWebhookRequest + 5, // 11: memos.api.v2.WebhookService.ListWebhooks:input_type -> memos.api.v2.ListWebhooksRequest + 7, // 12: memos.api.v2.WebhookService.UpdateWebhook:input_type -> memos.api.v2.UpdateWebhookRequest + 9, // 13: memos.api.v2.WebhookService.DeleteWebhook:input_type -> memos.api.v2.DeleteWebhookRequest + 2, // 14: memos.api.v2.WebhookService.CreateWebhook:output_type -> memos.api.v2.CreateWebhookResponse + 4, // 15: memos.api.v2.WebhookService.GetWebhook:output_type -> memos.api.v2.GetWebhookResponse + 6, // 16: memos.api.v2.WebhookService.ListWebhooks:output_type -> memos.api.v2.ListWebhooksResponse + 8, // 17: memos.api.v2.WebhookService.UpdateWebhook:output_type -> memos.api.v2.UpdateWebhookResponse + 10, // 18: memos.api.v2.WebhookService.DeleteWebhook:output_type -> memos.api.v2.DeleteWebhookResponse + 14, // [14:19] is the sub-list for method output_type + 9, // [9:14] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name +} + +func init() { file_api_v2_webhook_service_proto_init() } +func file_api_v2_webhook_service_proto_init() { + if File_api_v2_webhook_service_proto != nil { + return + } + file_api_v2_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_api_v2_webhook_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Webhook); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_webhook_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateWebhookRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_webhook_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateWebhookResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_webhook_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetWebhookRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_webhook_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetWebhookResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_webhook_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListWebhooksRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_webhook_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListWebhooksResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_webhook_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateWebhookRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_webhook_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateWebhookResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_webhook_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteWebhookRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_webhook_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteWebhookResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_v2_webhook_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 11, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_api_v2_webhook_service_proto_goTypes, + DependencyIndexes: file_api_v2_webhook_service_proto_depIdxs, + MessageInfos: file_api_v2_webhook_service_proto_msgTypes, + }.Build() + File_api_v2_webhook_service_proto = out.File + file_api_v2_webhook_service_proto_rawDesc = nil + file_api_v2_webhook_service_proto_goTypes = nil + file_api_v2_webhook_service_proto_depIdxs = nil +} diff --git a/proto/gen/api/v2/webhook_service.pb.gw.go b/proto/gen/api/v2/webhook_service.pb.gw.go new file mode 100644 index 0000000000000..40c5a07484a8f --- /dev/null +++ b/proto/gen/api/v2/webhook_service.pb.gw.go @@ -0,0 +1,615 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: api/v2/webhook_service.proto + +/* +Package apiv2 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package apiv2 + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +func request_WebhookService_CreateWebhook_0(ctx context.Context, marshaler runtime.Marshaler, client WebhookServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateWebhookRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.CreateWebhook(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_WebhookService_CreateWebhook_0(ctx context.Context, marshaler runtime.Marshaler, server WebhookServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq CreateWebhookRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.CreateWebhook(ctx, &protoReq) + return msg, metadata, err + +} + +func request_WebhookService_GetWebhook_0(ctx context.Context, marshaler runtime.Marshaler, client WebhookServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetWebhookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.GetWebhook(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_WebhookService_GetWebhook_0(ctx context.Context, marshaler runtime.Marshaler, server WebhookServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetWebhookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.GetWebhook(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_WebhookService_ListWebhooks_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_WebhookService_ListWebhooks_0(ctx context.Context, marshaler runtime.Marshaler, client WebhookServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListWebhooksRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WebhookService_ListWebhooks_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListWebhooks(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_WebhookService_ListWebhooks_0(ctx context.Context, marshaler runtime.Marshaler, server WebhookServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListWebhooksRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WebhookService_ListWebhooks_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListWebhooks(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_WebhookService_UpdateWebhook_0 = &utilities.DoubleArray{Encoding: map[string]int{"webhook": 0, "id": 1}, Base: []int{1, 4, 5, 2, 0, 0, 0, 0}, Check: []int{0, 1, 1, 2, 4, 2, 2, 3}} +) + +func request_WebhookService_UpdateWebhook_0(ctx context.Context, marshaler runtime.Marshaler, client WebhookServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateWebhookRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Webhook); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 { + if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Webhook); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } else { + protoReq.UpdateMask = fieldMask + } + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["webhook.id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "webhook.id") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "webhook.id", val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "webhook.id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WebhookService_UpdateWebhook_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.UpdateWebhook(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_WebhookService_UpdateWebhook_0(ctx context.Context, marshaler runtime.Marshaler, server WebhookServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpdateWebhookRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Webhook); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if protoReq.UpdateMask == nil || len(protoReq.UpdateMask.GetPaths()) == 0 { + if fieldMask, err := runtime.FieldMaskFromRequestBody(newReader(), protoReq.Webhook); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } else { + protoReq.UpdateMask = fieldMask + } + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["webhook.id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "webhook.id") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "webhook.id", val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "webhook.id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_WebhookService_UpdateWebhook_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.UpdateWebhook(ctx, &protoReq) + return msg, metadata, err + +} + +func request_WebhookService_DeleteWebhook_0(ctx context.Context, marshaler runtime.Marshaler, client WebhookServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteWebhookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.DeleteWebhook(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_WebhookService_DeleteWebhook_0(ctx context.Context, marshaler runtime.Marshaler, server WebhookServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteWebhookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Int32(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.DeleteWebhook(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterWebhookServiceHandlerServer registers the http handlers for service WebhookService to "mux". +// UnaryRPC :call WebhookServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterWebhookServiceHandlerFromEndpoint instead. +func RegisterWebhookServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server WebhookServiceServer) error { + + mux.Handle("POST", pattern_WebhookService_CreateWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.WebhookService/CreateWebhook", runtime.WithHTTPPathPattern("/api/v2/webhooks")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_WebhookService_CreateWebhook_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WebhookService_CreateWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_WebhookService_GetWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.WebhookService/GetWebhook", runtime.WithHTTPPathPattern("/api/v2/webhooks/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_WebhookService_GetWebhook_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WebhookService_GetWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_WebhookService_ListWebhooks_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.WebhookService/ListWebhooks", runtime.WithHTTPPathPattern("/api/v2/webhooks")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_WebhookService_ListWebhooks_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WebhookService_ListWebhooks_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_WebhookService_UpdateWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.WebhookService/UpdateWebhook", runtime.WithHTTPPathPattern("/api/v2/webhooks/{webhook.id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_WebhookService_UpdateWebhook_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WebhookService_UpdateWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_WebhookService_DeleteWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.WebhookService/DeleteWebhook", runtime.WithHTTPPathPattern("/api/v2/webhooks/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_WebhookService_DeleteWebhook_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WebhookService_DeleteWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterWebhookServiceHandlerFromEndpoint is same as RegisterWebhookServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterWebhookServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.DialContext(ctx, endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterWebhookServiceHandler(ctx, mux, conn) +} + +// RegisterWebhookServiceHandler registers the http handlers for service WebhookService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterWebhookServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterWebhookServiceHandlerClient(ctx, mux, NewWebhookServiceClient(conn)) +} + +// RegisterWebhookServiceHandlerClient registers the http handlers for service WebhookService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "WebhookServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "WebhookServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "WebhookServiceClient" to call the correct interceptors. +func RegisterWebhookServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client WebhookServiceClient) error { + + mux.Handle("POST", pattern_WebhookService_CreateWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.WebhookService/CreateWebhook", runtime.WithHTTPPathPattern("/api/v2/webhooks")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_WebhookService_CreateWebhook_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WebhookService_CreateWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_WebhookService_GetWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.WebhookService/GetWebhook", runtime.WithHTTPPathPattern("/api/v2/webhooks/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_WebhookService_GetWebhook_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WebhookService_GetWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_WebhookService_ListWebhooks_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.WebhookService/ListWebhooks", runtime.WithHTTPPathPattern("/api/v2/webhooks")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_WebhookService_ListWebhooks_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WebhookService_ListWebhooks_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_WebhookService_UpdateWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.WebhookService/UpdateWebhook", runtime.WithHTTPPathPattern("/api/v2/webhooks/{webhook.id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_WebhookService_UpdateWebhook_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WebhookService_UpdateWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_WebhookService_DeleteWebhook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.WebhookService/DeleteWebhook", runtime.WithHTTPPathPattern("/api/v2/webhooks/{id}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_WebhookService_DeleteWebhook_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WebhookService_DeleteWebhook_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_WebhookService_CreateWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "webhooks"}, "")) + + pattern_WebhookService_GetWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "webhooks", "id"}, "")) + + pattern_WebhookService_ListWebhooks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v2", "webhooks"}, "")) + + pattern_WebhookService_UpdateWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "webhooks", "webhook.id"}, "")) + + pattern_WebhookService_DeleteWebhook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v2", "webhooks", "id"}, "")) +) + +var ( + forward_WebhookService_CreateWebhook_0 = runtime.ForwardResponseMessage + + forward_WebhookService_GetWebhook_0 = runtime.ForwardResponseMessage + + forward_WebhookService_ListWebhooks_0 = runtime.ForwardResponseMessage + + forward_WebhookService_UpdateWebhook_0 = runtime.ForwardResponseMessage + + forward_WebhookService_DeleteWebhook_0 = runtime.ForwardResponseMessage +) diff --git a/proto/gen/api/v2/webhook_service_grpc.pb.go b/proto/gen/api/v2/webhook_service_grpc.pb.go new file mode 100644 index 0000000000000..83c33ed028c3b --- /dev/null +++ b/proto/gen/api/v2/webhook_service_grpc.pb.go @@ -0,0 +1,267 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: api/v2/webhook_service.proto + +package apiv2 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + WebhookService_CreateWebhook_FullMethodName = "/memos.api.v2.WebhookService/CreateWebhook" + WebhookService_GetWebhook_FullMethodName = "/memos.api.v2.WebhookService/GetWebhook" + WebhookService_ListWebhooks_FullMethodName = "/memos.api.v2.WebhookService/ListWebhooks" + WebhookService_UpdateWebhook_FullMethodName = "/memos.api.v2.WebhookService/UpdateWebhook" + WebhookService_DeleteWebhook_FullMethodName = "/memos.api.v2.WebhookService/DeleteWebhook" +) + +// WebhookServiceClient is the client API for WebhookService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type WebhookServiceClient interface { + // CreateWebhook creates a new webhook. + CreateWebhook(ctx context.Context, in *CreateWebhookRequest, opts ...grpc.CallOption) (*CreateWebhookResponse, error) + // GetWebhook returns a webhook by id. + GetWebhook(ctx context.Context, in *GetWebhookRequest, opts ...grpc.CallOption) (*GetWebhookResponse, error) + // ListWebhooks returns a list of webhooks. + ListWebhooks(ctx context.Context, in *ListWebhooksRequest, opts ...grpc.CallOption) (*ListWebhooksResponse, error) + // UpdateWebhook updates a webhook. + UpdateWebhook(ctx context.Context, in *UpdateWebhookRequest, opts ...grpc.CallOption) (*UpdateWebhookResponse, error) + // DeleteWebhook deletes a webhook by id. + DeleteWebhook(ctx context.Context, in *DeleteWebhookRequest, opts ...grpc.CallOption) (*DeleteWebhookResponse, error) +} + +type webhookServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewWebhookServiceClient(cc grpc.ClientConnInterface) WebhookServiceClient { + return &webhookServiceClient{cc} +} + +func (c *webhookServiceClient) CreateWebhook(ctx context.Context, in *CreateWebhookRequest, opts ...grpc.CallOption) (*CreateWebhookResponse, error) { + out := new(CreateWebhookResponse) + err := c.cc.Invoke(ctx, WebhookService_CreateWebhook_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *webhookServiceClient) GetWebhook(ctx context.Context, in *GetWebhookRequest, opts ...grpc.CallOption) (*GetWebhookResponse, error) { + out := new(GetWebhookResponse) + err := c.cc.Invoke(ctx, WebhookService_GetWebhook_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *webhookServiceClient) ListWebhooks(ctx context.Context, in *ListWebhooksRequest, opts ...grpc.CallOption) (*ListWebhooksResponse, error) { + out := new(ListWebhooksResponse) + err := c.cc.Invoke(ctx, WebhookService_ListWebhooks_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *webhookServiceClient) UpdateWebhook(ctx context.Context, in *UpdateWebhookRequest, opts ...grpc.CallOption) (*UpdateWebhookResponse, error) { + out := new(UpdateWebhookResponse) + err := c.cc.Invoke(ctx, WebhookService_UpdateWebhook_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *webhookServiceClient) DeleteWebhook(ctx context.Context, in *DeleteWebhookRequest, opts ...grpc.CallOption) (*DeleteWebhookResponse, error) { + out := new(DeleteWebhookResponse) + err := c.cc.Invoke(ctx, WebhookService_DeleteWebhook_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// WebhookServiceServer is the server API for WebhookService service. +// All implementations must embed UnimplementedWebhookServiceServer +// for forward compatibility +type WebhookServiceServer interface { + // CreateWebhook creates a new webhook. + CreateWebhook(context.Context, *CreateWebhookRequest) (*CreateWebhookResponse, error) + // GetWebhook returns a webhook by id. + GetWebhook(context.Context, *GetWebhookRequest) (*GetWebhookResponse, error) + // ListWebhooks returns a list of webhooks. + ListWebhooks(context.Context, *ListWebhooksRequest) (*ListWebhooksResponse, error) + // UpdateWebhook updates a webhook. + UpdateWebhook(context.Context, *UpdateWebhookRequest) (*UpdateWebhookResponse, error) + // DeleteWebhook deletes a webhook by id. + DeleteWebhook(context.Context, *DeleteWebhookRequest) (*DeleteWebhookResponse, error) + mustEmbedUnimplementedWebhookServiceServer() +} + +// UnimplementedWebhookServiceServer must be embedded to have forward compatible implementations. +type UnimplementedWebhookServiceServer struct { +} + +func (UnimplementedWebhookServiceServer) CreateWebhook(context.Context, *CreateWebhookRequest) (*CreateWebhookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateWebhook not implemented") +} +func (UnimplementedWebhookServiceServer) GetWebhook(context.Context, *GetWebhookRequest) (*GetWebhookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetWebhook not implemented") +} +func (UnimplementedWebhookServiceServer) ListWebhooks(context.Context, *ListWebhooksRequest) (*ListWebhooksResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListWebhooks not implemented") +} +func (UnimplementedWebhookServiceServer) UpdateWebhook(context.Context, *UpdateWebhookRequest) (*UpdateWebhookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateWebhook not implemented") +} +func (UnimplementedWebhookServiceServer) DeleteWebhook(context.Context, *DeleteWebhookRequest) (*DeleteWebhookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteWebhook not implemented") +} +func (UnimplementedWebhookServiceServer) mustEmbedUnimplementedWebhookServiceServer() {} + +// UnsafeWebhookServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to WebhookServiceServer will +// result in compilation errors. +type UnsafeWebhookServiceServer interface { + mustEmbedUnimplementedWebhookServiceServer() +} + +func RegisterWebhookServiceServer(s grpc.ServiceRegistrar, srv WebhookServiceServer) { + s.RegisterService(&WebhookService_ServiceDesc, srv) +} + +func _WebhookService_CreateWebhook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateWebhookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WebhookServiceServer).CreateWebhook(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WebhookService_CreateWebhook_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WebhookServiceServer).CreateWebhook(ctx, req.(*CreateWebhookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WebhookService_GetWebhook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetWebhookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WebhookServiceServer).GetWebhook(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WebhookService_GetWebhook_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WebhookServiceServer).GetWebhook(ctx, req.(*GetWebhookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WebhookService_ListWebhooks_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListWebhooksRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WebhookServiceServer).ListWebhooks(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WebhookService_ListWebhooks_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WebhookServiceServer).ListWebhooks(ctx, req.(*ListWebhooksRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WebhookService_UpdateWebhook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateWebhookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WebhookServiceServer).UpdateWebhook(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WebhookService_UpdateWebhook_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WebhookServiceServer).UpdateWebhook(ctx, req.(*UpdateWebhookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WebhookService_DeleteWebhook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteWebhookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WebhookServiceServer).DeleteWebhook(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WebhookService_DeleteWebhook_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WebhookServiceServer).DeleteWebhook(ctx, req.(*DeleteWebhookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// WebhookService_ServiceDesc is the grpc.ServiceDesc for WebhookService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var WebhookService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "memos.api.v2.WebhookService", + HandlerType: (*WebhookServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateWebhook", + Handler: _WebhookService_CreateWebhook_Handler, + }, + { + MethodName: "GetWebhook", + Handler: _WebhookService_GetWebhook_Handler, + }, + { + MethodName: "ListWebhooks", + Handler: _WebhookService_ListWebhooks_Handler, + }, + { + MethodName: "UpdateWebhook", + Handler: _WebhookService_UpdateWebhook_Handler, + }, + { + MethodName: "DeleteWebhook", + Handler: _WebhookService_DeleteWebhook_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api/v2/webhook_service.proto", +} diff --git a/proto/gen/api/v2/workspace_service.pb.go b/proto/gen/api/v2/workspace_service.pb.go new file mode 100644 index 0000000000000..89f88fdc3b778 --- /dev/null +++ b/proto/gen/api/v2/workspace_service.pb.go @@ -0,0 +1,349 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: api/v2/workspace_service.proto + +package apiv2 + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type WorkspaceProfile struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // version is the current version of instance + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + // mode is the instance mode (e.g. "prod", "dev" or "demo"). + Mode string `protobuf:"bytes,2,opt,name=mode,proto3" json:"mode,omitempty"` + // allow_registration is whether the registration is allowed. + AllowRegistration bool `protobuf:"varint,3,opt,name=allow_registration,json=allowRegistration,proto3" json:"allow_registration,omitempty"` + // allow_password_login is whether the password login is allowed. + DisablePasswordLogin bool `protobuf:"varint,4,opt,name=disable_password_login,json=disablePasswordLogin,proto3" json:"disable_password_login,omitempty"` + // additional_script is the additional script. + AdditionalScript string `protobuf:"bytes,5,opt,name=additional_script,json=additionalScript,proto3" json:"additional_script,omitempty"` + // additional_style is the additional style. + AdditionalStyle string `protobuf:"bytes,6,opt,name=additional_style,json=additionalStyle,proto3" json:"additional_style,omitempty"` +} + +func (x *WorkspaceProfile) Reset() { + *x = WorkspaceProfile{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_workspace_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WorkspaceProfile) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkspaceProfile) ProtoMessage() {} + +func (x *WorkspaceProfile) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_workspace_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkspaceProfile.ProtoReflect.Descriptor instead. +func (*WorkspaceProfile) Descriptor() ([]byte, []int) { + return file_api_v2_workspace_service_proto_rawDescGZIP(), []int{0} +} + +func (x *WorkspaceProfile) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *WorkspaceProfile) GetMode() string { + if x != nil { + return x.Mode + } + return "" +} + +func (x *WorkspaceProfile) GetAllowRegistration() bool { + if x != nil { + return x.AllowRegistration + } + return false +} + +func (x *WorkspaceProfile) GetDisablePasswordLogin() bool { + if x != nil { + return x.DisablePasswordLogin + } + return false +} + +func (x *WorkspaceProfile) GetAdditionalScript() string { + if x != nil { + return x.AdditionalScript + } + return "" +} + +func (x *WorkspaceProfile) GetAdditionalStyle() string { + if x != nil { + return x.AdditionalStyle + } + return "" +} + +type GetWorkspaceProfileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetWorkspaceProfileRequest) Reset() { + *x = GetWorkspaceProfileRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_workspace_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetWorkspaceProfileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetWorkspaceProfileRequest) ProtoMessage() {} + +func (x *GetWorkspaceProfileRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_workspace_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetWorkspaceProfileRequest.ProtoReflect.Descriptor instead. +func (*GetWorkspaceProfileRequest) Descriptor() ([]byte, []int) { + return file_api_v2_workspace_service_proto_rawDescGZIP(), []int{1} +} + +type GetWorkspaceProfileResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + WorkspaceProfile *WorkspaceProfile `protobuf:"bytes,1,opt,name=workspace_profile,json=workspaceProfile,proto3" json:"workspace_profile,omitempty"` +} + +func (x *GetWorkspaceProfileResponse) Reset() { + *x = GetWorkspaceProfileResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_workspace_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetWorkspaceProfileResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetWorkspaceProfileResponse) ProtoMessage() {} + +func (x *GetWorkspaceProfileResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_workspace_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetWorkspaceProfileResponse.ProtoReflect.Descriptor instead. +func (*GetWorkspaceProfileResponse) Descriptor() ([]byte, []int) { + return file_api_v2_workspace_service_proto_rawDescGZIP(), []int{2} +} + +func (x *GetWorkspaceProfileResponse) GetWorkspaceProfile() *WorkspaceProfile { + if x != nil { + return x.WorkspaceProfile + } + return nil +} + +var File_api_v2_workspace_service_proto protoreflect.FileDescriptor + +var file_api_v2_workspace_service_proto_rawDesc = []byte{ + 0x0a, 0x1e, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x1c, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfd, 0x01, 0x0a, + 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6d, + 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, + 0x2d, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x61, 0x6c, 0x6c, + 0x6f, 0x77, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, + 0x0a, 0x16, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x4c, + 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x12, 0x29, 0x0a, 0x10, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x64, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x22, 0x1c, 0x0a, 0x1a, + 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6a, 0x0a, 0x1b, 0x47, 0x65, + 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x11, 0x77, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x32, 0xa2, 0x01, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x8d, 0x01, 0x0a, 0x13, + 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x12, 0x28, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, + 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, + 0x12, 0x19, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x42, 0xad, 0x01, 0x0a, 0x10, + 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x42, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, + 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, + 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, + 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, + 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, + 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_api_v2_workspace_service_proto_rawDescOnce sync.Once + file_api_v2_workspace_service_proto_rawDescData = file_api_v2_workspace_service_proto_rawDesc +) + +func file_api_v2_workspace_service_proto_rawDescGZIP() []byte { + file_api_v2_workspace_service_proto_rawDescOnce.Do(func() { + file_api_v2_workspace_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_v2_workspace_service_proto_rawDescData) + }) + return file_api_v2_workspace_service_proto_rawDescData +} + +var file_api_v2_workspace_service_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_api_v2_workspace_service_proto_goTypes = []interface{}{ + (*WorkspaceProfile)(nil), // 0: memos.api.v2.WorkspaceProfile + (*GetWorkspaceProfileRequest)(nil), // 1: memos.api.v2.GetWorkspaceProfileRequest + (*GetWorkspaceProfileResponse)(nil), // 2: memos.api.v2.GetWorkspaceProfileResponse +} +var file_api_v2_workspace_service_proto_depIdxs = []int32{ + 0, // 0: memos.api.v2.GetWorkspaceProfileResponse.workspace_profile:type_name -> memos.api.v2.WorkspaceProfile + 1, // 1: memos.api.v2.WorkspaceService.GetWorkspaceProfile:input_type -> memos.api.v2.GetWorkspaceProfileRequest + 2, // 2: memos.api.v2.WorkspaceService.GetWorkspaceProfile:output_type -> memos.api.v2.GetWorkspaceProfileResponse + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_api_v2_workspace_service_proto_init() } +func file_api_v2_workspace_service_proto_init() { + if File_api_v2_workspace_service_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_v2_workspace_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WorkspaceProfile); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_workspace_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetWorkspaceProfileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_workspace_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetWorkspaceProfileResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_v2_workspace_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_api_v2_workspace_service_proto_goTypes, + DependencyIndexes: file_api_v2_workspace_service_proto_depIdxs, + MessageInfos: file_api_v2_workspace_service_proto_msgTypes, + }.Build() + File_api_v2_workspace_service_proto = out.File + file_api_v2_workspace_service_proto_rawDesc = nil + file_api_v2_workspace_service_proto_goTypes = nil + file_api_v2_workspace_service_proto_depIdxs = nil +} diff --git a/proto/gen/api/v2/workspace_service.pb.gw.go b/proto/gen/api/v2/workspace_service.pb.gw.go new file mode 100644 index 0000000000000..6a71ab6991c03 --- /dev/null +++ b/proto/gen/api/v2/workspace_service.pb.gw.go @@ -0,0 +1,155 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: api/v2/workspace_service.proto + +/* +Package apiv2 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package apiv2 + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +func request_WorkspaceService_GetWorkspaceProfile_0(ctx context.Context, marshaler runtime.Marshaler, client WorkspaceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetWorkspaceProfileRequest + var metadata runtime.ServerMetadata + + msg, err := client.GetWorkspaceProfile(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_WorkspaceService_GetWorkspaceProfile_0(ctx context.Context, marshaler runtime.Marshaler, server WorkspaceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetWorkspaceProfileRequest + var metadata runtime.ServerMetadata + + msg, err := server.GetWorkspaceProfile(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterWorkspaceServiceHandlerServer registers the http handlers for service WorkspaceService to "mux". +// UnaryRPC :call WorkspaceServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterWorkspaceServiceHandlerFromEndpoint instead. +func RegisterWorkspaceServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server WorkspaceServiceServer) error { + + mux.Handle("GET", pattern_WorkspaceService_GetWorkspaceProfile_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.WorkspaceService/GetWorkspaceProfile", runtime.WithHTTPPathPattern("/api/v2/workspace/profile")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_WorkspaceService_GetWorkspaceProfile_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WorkspaceService_GetWorkspaceProfile_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterWorkspaceServiceHandlerFromEndpoint is same as RegisterWorkspaceServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterWorkspaceServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.DialContext(ctx, endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterWorkspaceServiceHandler(ctx, mux, conn) +} + +// RegisterWorkspaceServiceHandler registers the http handlers for service WorkspaceService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterWorkspaceServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterWorkspaceServiceHandlerClient(ctx, mux, NewWorkspaceServiceClient(conn)) +} + +// RegisterWorkspaceServiceHandlerClient registers the http handlers for service WorkspaceService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "WorkspaceServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "WorkspaceServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "WorkspaceServiceClient" to call the correct interceptors. +func RegisterWorkspaceServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client WorkspaceServiceClient) error { + + mux.Handle("GET", pattern_WorkspaceService_GetWorkspaceProfile_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.WorkspaceService/GetWorkspaceProfile", runtime.WithHTTPPathPattern("/api/v2/workspace/profile")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_WorkspaceService_GetWorkspaceProfile_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WorkspaceService_GetWorkspaceProfile_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_WorkspaceService_GetWorkspaceProfile_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v2", "workspace", "profile"}, "")) +) + +var ( + forward_WorkspaceService_GetWorkspaceProfile_0 = runtime.ForwardResponseMessage +) diff --git a/proto/gen/api/v2/workspace_service_grpc.pb.go b/proto/gen/api/v2/workspace_service_grpc.pb.go new file mode 100644 index 0000000000000..09ccf19aa8af5 --- /dev/null +++ b/proto/gen/api/v2/workspace_service_grpc.pb.go @@ -0,0 +1,111 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: api/v2/workspace_service.proto + +package apiv2 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + WorkspaceService_GetWorkspaceProfile_FullMethodName = "/memos.api.v2.WorkspaceService/GetWorkspaceProfile" +) + +// WorkspaceServiceClient is the client API for WorkspaceService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type WorkspaceServiceClient interface { + // GetWorkspaceProfile returns the workspace profile. + GetWorkspaceProfile(ctx context.Context, in *GetWorkspaceProfileRequest, opts ...grpc.CallOption) (*GetWorkspaceProfileResponse, error) +} + +type workspaceServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewWorkspaceServiceClient(cc grpc.ClientConnInterface) WorkspaceServiceClient { + return &workspaceServiceClient{cc} +} + +func (c *workspaceServiceClient) GetWorkspaceProfile(ctx context.Context, in *GetWorkspaceProfileRequest, opts ...grpc.CallOption) (*GetWorkspaceProfileResponse, error) { + out := new(GetWorkspaceProfileResponse) + err := c.cc.Invoke(ctx, WorkspaceService_GetWorkspaceProfile_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// WorkspaceServiceServer is the server API for WorkspaceService service. +// All implementations must embed UnimplementedWorkspaceServiceServer +// for forward compatibility +type WorkspaceServiceServer interface { + // GetWorkspaceProfile returns the workspace profile. + GetWorkspaceProfile(context.Context, *GetWorkspaceProfileRequest) (*GetWorkspaceProfileResponse, error) + mustEmbedUnimplementedWorkspaceServiceServer() +} + +// UnimplementedWorkspaceServiceServer must be embedded to have forward compatible implementations. +type UnimplementedWorkspaceServiceServer struct { +} + +func (UnimplementedWorkspaceServiceServer) GetWorkspaceProfile(context.Context, *GetWorkspaceProfileRequest) (*GetWorkspaceProfileResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetWorkspaceProfile not implemented") +} +func (UnimplementedWorkspaceServiceServer) mustEmbedUnimplementedWorkspaceServiceServer() {} + +// UnsafeWorkspaceServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to WorkspaceServiceServer will +// result in compilation errors. +type UnsafeWorkspaceServiceServer interface { + mustEmbedUnimplementedWorkspaceServiceServer() +} + +func RegisterWorkspaceServiceServer(s grpc.ServiceRegistrar, srv WorkspaceServiceServer) { + s.RegisterService(&WorkspaceService_ServiceDesc, srv) +} + +func _WorkspaceService_GetWorkspaceProfile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetWorkspaceProfileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WorkspaceServiceServer).GetWorkspaceProfile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WorkspaceService_GetWorkspaceProfile_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WorkspaceServiceServer).GetWorkspaceProfile(ctx, req.(*GetWorkspaceProfileRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// WorkspaceService_ServiceDesc is the grpc.ServiceDesc for WorkspaceService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var WorkspaceService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "memos.api.v2.WorkspaceService", + HandlerType: (*WorkspaceServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetWorkspaceProfile", + Handler: _WorkspaceService_GetWorkspaceProfile_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api/v2/workspace_service.proto", +} diff --git a/proto/gen/api/v2/workspace_setting_service.pb.go b/proto/gen/api/v2/workspace_setting_service.pb.go new file mode 100644 index 0000000000000..1431cfbeea19f --- /dev/null +++ b/proto/gen/api/v2/workspace_setting_service.pb.go @@ -0,0 +1,607 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: api/v2/workspace_setting_service.proto + +package apiv2 + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type GetWorkspaceSettingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The resource name of the workspace setting. + // Format: settings/{setting} + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *GetWorkspaceSettingRequest) Reset() { + *x = GetWorkspaceSettingRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_workspace_setting_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetWorkspaceSettingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetWorkspaceSettingRequest) ProtoMessage() {} + +func (x *GetWorkspaceSettingRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_workspace_setting_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetWorkspaceSettingRequest.ProtoReflect.Descriptor instead. +func (*GetWorkspaceSettingRequest) Descriptor() ([]byte, []int) { + return file_api_v2_workspace_setting_service_proto_rawDescGZIP(), []int{0} +} + +func (x *GetWorkspaceSettingRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type GetWorkspaceSettingResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Setting *WorkspaceSetting `protobuf:"bytes,1,opt,name=setting,proto3" json:"setting,omitempty"` +} + +func (x *GetWorkspaceSettingResponse) Reset() { + *x = GetWorkspaceSettingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_workspace_setting_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetWorkspaceSettingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetWorkspaceSettingResponse) ProtoMessage() {} + +func (x *GetWorkspaceSettingResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_workspace_setting_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetWorkspaceSettingResponse.ProtoReflect.Descriptor instead. +func (*GetWorkspaceSettingResponse) Descriptor() ([]byte, []int) { + return file_api_v2_workspace_setting_service_proto_rawDescGZIP(), []int{1} +} + +func (x *GetWorkspaceSettingResponse) GetSetting() *WorkspaceSetting { + if x != nil { + return x.Setting + } + return nil +} + +type SetWorkspaceSettingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // setting is the setting to update. + Setting *WorkspaceSetting `protobuf:"bytes,1,opt,name=setting,proto3" json:"setting,omitempty"` +} + +func (x *SetWorkspaceSettingRequest) Reset() { + *x = SetWorkspaceSettingRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_workspace_setting_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetWorkspaceSettingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetWorkspaceSettingRequest) ProtoMessage() {} + +func (x *SetWorkspaceSettingRequest) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_workspace_setting_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetWorkspaceSettingRequest.ProtoReflect.Descriptor instead. +func (*SetWorkspaceSettingRequest) Descriptor() ([]byte, []int) { + return file_api_v2_workspace_setting_service_proto_rawDescGZIP(), []int{2} +} + +func (x *SetWorkspaceSettingRequest) GetSetting() *WorkspaceSetting { + if x != nil { + return x.Setting + } + return nil +} + +type SetWorkspaceSettingResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Setting *WorkspaceSetting `protobuf:"bytes,1,opt,name=setting,proto3" json:"setting,omitempty"` +} + +func (x *SetWorkspaceSettingResponse) Reset() { + *x = SetWorkspaceSettingResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_workspace_setting_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SetWorkspaceSettingResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetWorkspaceSettingResponse) ProtoMessage() {} + +func (x *SetWorkspaceSettingResponse) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_workspace_setting_service_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetWorkspaceSettingResponse.ProtoReflect.Descriptor instead. +func (*SetWorkspaceSettingResponse) Descriptor() ([]byte, []int) { + return file_api_v2_workspace_setting_service_proto_rawDescGZIP(), []int{3} +} + +func (x *SetWorkspaceSettingResponse) GetSetting() *WorkspaceSetting { + if x != nil { + return x.Setting + } + return nil +} + +type WorkspaceSetting struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // name is the name of the setting. + // Format: settings/{setting} + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Types that are assignable to Value: + // + // *WorkspaceSetting_GeneralSetting + Value isWorkspaceSetting_Value `protobuf_oneof:"value"` +} + +func (x *WorkspaceSetting) Reset() { + *x = WorkspaceSetting{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_workspace_setting_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WorkspaceSetting) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkspaceSetting) ProtoMessage() {} + +func (x *WorkspaceSetting) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_workspace_setting_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkspaceSetting.ProtoReflect.Descriptor instead. +func (*WorkspaceSetting) Descriptor() ([]byte, []int) { + return file_api_v2_workspace_setting_service_proto_rawDescGZIP(), []int{4} +} + +func (x *WorkspaceSetting) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (m *WorkspaceSetting) GetValue() isWorkspaceSetting_Value { + if m != nil { + return m.Value + } + return nil +} + +func (x *WorkspaceSetting) GetGeneralSetting() *WorkspaceGeneralSetting { + if x, ok := x.GetValue().(*WorkspaceSetting_GeneralSetting); ok { + return x.GeneralSetting + } + return nil +} + +type isWorkspaceSetting_Value interface { + isWorkspaceSetting_Value() +} + +type WorkspaceSetting_GeneralSetting struct { + // general_setting is the general setting of workspace. + GeneralSetting *WorkspaceGeneralSetting `protobuf:"bytes,2,opt,name=general_setting,json=generalSetting,proto3,oneof"` +} + +func (*WorkspaceSetting_GeneralSetting) isWorkspaceSetting_Value() {} + +type WorkspaceGeneralSetting struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // instance_url is the instance URL. + InstanceUrl string `protobuf:"bytes,1,opt,name=instance_url,json=instanceUrl,proto3" json:"instance_url,omitempty"` + // disallow_signup is the flag to disallow signup. + DisallowSignup bool `protobuf:"varint,2,opt,name=disallow_signup,json=disallowSignup,proto3" json:"disallow_signup,omitempty"` + // disallow_password_login is the flag to disallow password login. + DisallowPasswordLogin bool `protobuf:"varint,3,opt,name=disallow_password_login,json=disallowPasswordLogin,proto3" json:"disallow_password_login,omitempty"` + // additional_script is the additional script. + AdditionalScript string `protobuf:"bytes,5,opt,name=additional_script,json=additionalScript,proto3" json:"additional_script,omitempty"` + // additional_style is the additional style. + AdditionalStyle string `protobuf:"bytes,6,opt,name=additional_style,json=additionalStyle,proto3" json:"additional_style,omitempty"` +} + +func (x *WorkspaceGeneralSetting) Reset() { + *x = WorkspaceGeneralSetting{} + if protoimpl.UnsafeEnabled { + mi := &file_api_v2_workspace_setting_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WorkspaceGeneralSetting) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkspaceGeneralSetting) ProtoMessage() {} + +func (x *WorkspaceGeneralSetting) ProtoReflect() protoreflect.Message { + mi := &file_api_v2_workspace_setting_service_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkspaceGeneralSetting.ProtoReflect.Descriptor instead. +func (*WorkspaceGeneralSetting) Descriptor() ([]byte, []int) { + return file_api_v2_workspace_setting_service_proto_rawDescGZIP(), []int{5} +} + +func (x *WorkspaceGeneralSetting) GetInstanceUrl() string { + if x != nil { + return x.InstanceUrl + } + return "" +} + +func (x *WorkspaceGeneralSetting) GetDisallowSignup() bool { + if x != nil { + return x.DisallowSignup + } + return false +} + +func (x *WorkspaceGeneralSetting) GetDisallowPasswordLogin() bool { + if x != nil { + return x.DisallowPasswordLogin + } + return false +} + +func (x *WorkspaceGeneralSetting) GetAdditionalScript() string { + if x != nil { + return x.AdditionalScript + } + return "" +} + +func (x *WorkspaceGeneralSetting) GetAdditionalStyle() string { + if x != nil { + return x.AdditionalStyle + } + return "" +} + +var File_api_v2_workspace_setting_service_proto protoreflect.FileDescriptor + +var file_api_v2_workspace_setting_service_proto_rawDesc = []byte{ + 0x0a, 0x26, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, + 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, + 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x03, 0xe0, 0x41, 0x02, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x57, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x22, 0x56, + 0x0a, 0x1a, 0x53, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x07, + 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x73, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x22, 0x57, 0x0a, 0x1b, 0x53, 0x65, 0x74, 0x57, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x22, + 0x81, 0x01, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x6c, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, + 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x0e, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x22, 0xf5, 0x01, 0x0a, 0x17, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, + 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x55, + 0x72, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x73, + 0x69, 0x67, 0x6e, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x69, 0x73, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x12, 0x36, 0x0a, 0x17, 0x64, + 0x69, 0x73, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x64, 0x69, + 0x73, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x4c, 0x6f, + 0x67, 0x69, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, + 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x12, 0x29, 0x0a, 0x10, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x64, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x32, 0xef, 0x02, 0x0a, 0x17, + 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x9e, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x57, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, + 0x28, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, + 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, + 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0xda, 0x41, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x25, 0x12, 0x23, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x77, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x2a, 0x7d, 0x12, 0xb2, 0x01, 0x0a, 0x13, 0x53, 0x65, 0x74, + 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x12, 0x28, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, + 0x53, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x74, 0x57, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0xda, 0x41, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x36, 0x3a, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x32, 0x2b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x2f, 0x7b, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x3d, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2f, 0x2a, 0x7d, 0x42, 0xb4, 0x01, + 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x42, 0x1c, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, + 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x3b, 0x61, + 0x70, 0x69, 0x76, 0x32, 0xa2, 0x02, 0x03, 0x4d, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x4d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, + 0x73, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x4d, 0x65, 0x6d, 0x6f, 0x73, + 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x69, + 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_api_v2_workspace_setting_service_proto_rawDescOnce sync.Once + file_api_v2_workspace_setting_service_proto_rawDescData = file_api_v2_workspace_setting_service_proto_rawDesc +) + +func file_api_v2_workspace_setting_service_proto_rawDescGZIP() []byte { + file_api_v2_workspace_setting_service_proto_rawDescOnce.Do(func() { + file_api_v2_workspace_setting_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_v2_workspace_setting_service_proto_rawDescData) + }) + return file_api_v2_workspace_setting_service_proto_rawDescData +} + +var file_api_v2_workspace_setting_service_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_api_v2_workspace_setting_service_proto_goTypes = []interface{}{ + (*GetWorkspaceSettingRequest)(nil), // 0: memos.api.v2.GetWorkspaceSettingRequest + (*GetWorkspaceSettingResponse)(nil), // 1: memos.api.v2.GetWorkspaceSettingResponse + (*SetWorkspaceSettingRequest)(nil), // 2: memos.api.v2.SetWorkspaceSettingRequest + (*SetWorkspaceSettingResponse)(nil), // 3: memos.api.v2.SetWorkspaceSettingResponse + (*WorkspaceSetting)(nil), // 4: memos.api.v2.WorkspaceSetting + (*WorkspaceGeneralSetting)(nil), // 5: memos.api.v2.WorkspaceGeneralSetting +} +var file_api_v2_workspace_setting_service_proto_depIdxs = []int32{ + 4, // 0: memos.api.v2.GetWorkspaceSettingResponse.setting:type_name -> memos.api.v2.WorkspaceSetting + 4, // 1: memos.api.v2.SetWorkspaceSettingRequest.setting:type_name -> memos.api.v2.WorkspaceSetting + 4, // 2: memos.api.v2.SetWorkspaceSettingResponse.setting:type_name -> memos.api.v2.WorkspaceSetting + 5, // 3: memos.api.v2.WorkspaceSetting.general_setting:type_name -> memos.api.v2.WorkspaceGeneralSetting + 0, // 4: memos.api.v2.WorkspaceSettingService.GetWorkspaceSetting:input_type -> memos.api.v2.GetWorkspaceSettingRequest + 2, // 5: memos.api.v2.WorkspaceSettingService.SetWorkspaceSetting:input_type -> memos.api.v2.SetWorkspaceSettingRequest + 1, // 6: memos.api.v2.WorkspaceSettingService.GetWorkspaceSetting:output_type -> memos.api.v2.GetWorkspaceSettingResponse + 3, // 7: memos.api.v2.WorkspaceSettingService.SetWorkspaceSetting:output_type -> memos.api.v2.SetWorkspaceSettingResponse + 6, // [6:8] is the sub-list for method output_type + 4, // [4:6] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_api_v2_workspace_setting_service_proto_init() } +func file_api_v2_workspace_setting_service_proto_init() { + if File_api_v2_workspace_setting_service_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_api_v2_workspace_setting_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetWorkspaceSettingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_workspace_setting_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetWorkspaceSettingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_workspace_setting_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetWorkspaceSettingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_workspace_setting_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SetWorkspaceSettingResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_workspace_setting_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WorkspaceSetting); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_v2_workspace_setting_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WorkspaceGeneralSetting); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_api_v2_workspace_setting_service_proto_msgTypes[4].OneofWrappers = []interface{}{ + (*WorkspaceSetting_GeneralSetting)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_api_v2_workspace_setting_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_api_v2_workspace_setting_service_proto_goTypes, + DependencyIndexes: file_api_v2_workspace_setting_service_proto_depIdxs, + MessageInfos: file_api_v2_workspace_setting_service_proto_msgTypes, + }.Build() + File_api_v2_workspace_setting_service_proto = out.File + file_api_v2_workspace_setting_service_proto_rawDesc = nil + file_api_v2_workspace_setting_service_proto_goTypes = nil + file_api_v2_workspace_setting_service_proto_depIdxs = nil +} diff --git a/proto/gen/api/v2/workspace_setting_service.pb.gw.go b/proto/gen/api/v2/workspace_setting_service.pb.gw.go new file mode 100644 index 0000000000000..e0a685e5f30e6 --- /dev/null +++ b/proto/gen/api/v2/workspace_setting_service.pb.gw.go @@ -0,0 +1,308 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: api/v2/workspace_setting_service.proto + +/* +Package apiv2 is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package apiv2 + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +func request_WorkspaceSettingService_GetWorkspaceSetting_0(ctx context.Context, marshaler runtime.Marshaler, client WorkspaceSettingServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetWorkspaceSettingRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := client.GetWorkspaceSetting(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_WorkspaceSettingService_GetWorkspaceSetting_0(ctx context.Context, marshaler runtime.Marshaler, server WorkspaceSettingServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GetWorkspaceSettingRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := server.GetWorkspaceSetting(ctx, &protoReq) + return msg, metadata, err + +} + +func request_WorkspaceSettingService_SetWorkspaceSetting_0(ctx context.Context, marshaler runtime.Marshaler, client WorkspaceSettingServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SetWorkspaceSettingRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Setting); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["setting.name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "setting.name") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "setting.name", val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "setting.name", err) + } + + msg, err := client.SetWorkspaceSetting(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_WorkspaceSettingService_SetWorkspaceSetting_0(ctx context.Context, marshaler runtime.Marshaler, server WorkspaceSettingServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SetWorkspaceSettingRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Setting); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["setting.name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "setting.name") + } + + err = runtime.PopulateFieldFromPath(&protoReq, "setting.name", val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "setting.name", err) + } + + msg, err := server.SetWorkspaceSetting(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterWorkspaceSettingServiceHandlerServer registers the http handlers for service WorkspaceSettingService to "mux". +// UnaryRPC :call WorkspaceSettingServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterWorkspaceSettingServiceHandlerFromEndpoint instead. +func RegisterWorkspaceSettingServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server WorkspaceSettingServiceServer) error { + + mux.Handle("GET", pattern_WorkspaceSettingService_GetWorkspaceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.WorkspaceSettingService/GetWorkspaceSetting", runtime.WithHTTPPathPattern("/api/v2/workspace/{name=settings/*}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_WorkspaceSettingService_GetWorkspaceSetting_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WorkspaceSettingService_GetWorkspaceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_WorkspaceSettingService_SetWorkspaceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/memos.api.v2.WorkspaceSettingService/SetWorkspaceSetting", runtime.WithHTTPPathPattern("/api/v2/workspace/{setting.name=settings/*}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_WorkspaceSettingService_SetWorkspaceSetting_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WorkspaceSettingService_SetWorkspaceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterWorkspaceSettingServiceHandlerFromEndpoint is same as RegisterWorkspaceSettingServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterWorkspaceSettingServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.DialContext(ctx, endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterWorkspaceSettingServiceHandler(ctx, mux, conn) +} + +// RegisterWorkspaceSettingServiceHandler registers the http handlers for service WorkspaceSettingService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterWorkspaceSettingServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterWorkspaceSettingServiceHandlerClient(ctx, mux, NewWorkspaceSettingServiceClient(conn)) +} + +// RegisterWorkspaceSettingServiceHandlerClient registers the http handlers for service WorkspaceSettingService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "WorkspaceSettingServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "WorkspaceSettingServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "WorkspaceSettingServiceClient" to call the correct interceptors. +func RegisterWorkspaceSettingServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client WorkspaceSettingServiceClient) error { + + mux.Handle("GET", pattern_WorkspaceSettingService_GetWorkspaceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.WorkspaceSettingService/GetWorkspaceSetting", runtime.WithHTTPPathPattern("/api/v2/workspace/{name=settings/*}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_WorkspaceSettingService_GetWorkspaceSetting_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WorkspaceSettingService_GetWorkspaceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PATCH", pattern_WorkspaceSettingService_SetWorkspaceSetting_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/memos.api.v2.WorkspaceSettingService/SetWorkspaceSetting", runtime.WithHTTPPathPattern("/api/v2/workspace/{setting.name=settings/*}")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_WorkspaceSettingService_SetWorkspaceSetting_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_WorkspaceSettingService_SetWorkspaceSetting_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_WorkspaceSettingService_GetWorkspaceSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 2, 5, 4}, []string{"api", "v2", "workspace", "settings", "name"}, "")) + + pattern_WorkspaceSettingService_SetWorkspaceSetting_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 2, 5, 4}, []string{"api", "v2", "workspace", "settings", "setting.name"}, "")) +) + +var ( + forward_WorkspaceSettingService_GetWorkspaceSetting_0 = runtime.ForwardResponseMessage + + forward_WorkspaceSettingService_SetWorkspaceSetting_0 = runtime.ForwardResponseMessage +) diff --git a/proto/gen/api/v2/workspace_setting_service_grpc.pb.go b/proto/gen/api/v2/workspace_setting_service_grpc.pb.go new file mode 100644 index 0000000000000..c747d13030774 --- /dev/null +++ b/proto/gen/api/v2/workspace_setting_service_grpc.pb.go @@ -0,0 +1,151 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: api/v2/workspace_setting_service.proto + +package apiv2 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + WorkspaceSettingService_GetWorkspaceSetting_FullMethodName = "/memos.api.v2.WorkspaceSettingService/GetWorkspaceSetting" + WorkspaceSettingService_SetWorkspaceSetting_FullMethodName = "/memos.api.v2.WorkspaceSettingService/SetWorkspaceSetting" +) + +// WorkspaceSettingServiceClient is the client API for WorkspaceSettingService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type WorkspaceSettingServiceClient interface { + // GetWorkspaceSetting returns the setting by name. + GetWorkspaceSetting(ctx context.Context, in *GetWorkspaceSettingRequest, opts ...grpc.CallOption) (*GetWorkspaceSettingResponse, error) + // SetWorkspaceSetting updates the setting. + SetWorkspaceSetting(ctx context.Context, in *SetWorkspaceSettingRequest, opts ...grpc.CallOption) (*SetWorkspaceSettingResponse, error) +} + +type workspaceSettingServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewWorkspaceSettingServiceClient(cc grpc.ClientConnInterface) WorkspaceSettingServiceClient { + return &workspaceSettingServiceClient{cc} +} + +func (c *workspaceSettingServiceClient) GetWorkspaceSetting(ctx context.Context, in *GetWorkspaceSettingRequest, opts ...grpc.CallOption) (*GetWorkspaceSettingResponse, error) { + out := new(GetWorkspaceSettingResponse) + err := c.cc.Invoke(ctx, WorkspaceSettingService_GetWorkspaceSetting_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *workspaceSettingServiceClient) SetWorkspaceSetting(ctx context.Context, in *SetWorkspaceSettingRequest, opts ...grpc.CallOption) (*SetWorkspaceSettingResponse, error) { + out := new(SetWorkspaceSettingResponse) + err := c.cc.Invoke(ctx, WorkspaceSettingService_SetWorkspaceSetting_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// WorkspaceSettingServiceServer is the server API for WorkspaceSettingService service. +// All implementations must embed UnimplementedWorkspaceSettingServiceServer +// for forward compatibility +type WorkspaceSettingServiceServer interface { + // GetWorkspaceSetting returns the setting by name. + GetWorkspaceSetting(context.Context, *GetWorkspaceSettingRequest) (*GetWorkspaceSettingResponse, error) + // SetWorkspaceSetting updates the setting. + SetWorkspaceSetting(context.Context, *SetWorkspaceSettingRequest) (*SetWorkspaceSettingResponse, error) + mustEmbedUnimplementedWorkspaceSettingServiceServer() +} + +// UnimplementedWorkspaceSettingServiceServer must be embedded to have forward compatible implementations. +type UnimplementedWorkspaceSettingServiceServer struct { +} + +func (UnimplementedWorkspaceSettingServiceServer) GetWorkspaceSetting(context.Context, *GetWorkspaceSettingRequest) (*GetWorkspaceSettingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetWorkspaceSetting not implemented") +} +func (UnimplementedWorkspaceSettingServiceServer) SetWorkspaceSetting(context.Context, *SetWorkspaceSettingRequest) (*SetWorkspaceSettingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetWorkspaceSetting not implemented") +} +func (UnimplementedWorkspaceSettingServiceServer) mustEmbedUnimplementedWorkspaceSettingServiceServer() { +} + +// UnsafeWorkspaceSettingServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to WorkspaceSettingServiceServer will +// result in compilation errors. +type UnsafeWorkspaceSettingServiceServer interface { + mustEmbedUnimplementedWorkspaceSettingServiceServer() +} + +func RegisterWorkspaceSettingServiceServer(s grpc.ServiceRegistrar, srv WorkspaceSettingServiceServer) { + s.RegisterService(&WorkspaceSettingService_ServiceDesc, srv) +} + +func _WorkspaceSettingService_GetWorkspaceSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetWorkspaceSettingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WorkspaceSettingServiceServer).GetWorkspaceSetting(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WorkspaceSettingService_GetWorkspaceSetting_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WorkspaceSettingServiceServer).GetWorkspaceSetting(ctx, req.(*GetWorkspaceSettingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _WorkspaceSettingService_SetWorkspaceSetting_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetWorkspaceSettingRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(WorkspaceSettingServiceServer).SetWorkspaceSetting(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: WorkspaceSettingService_SetWorkspaceSetting_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(WorkspaceSettingServiceServer).SetWorkspaceSetting(ctx, req.(*SetWorkspaceSettingRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// WorkspaceSettingService_ServiceDesc is the grpc.ServiceDesc for WorkspaceSettingService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var WorkspaceSettingService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "memos.api.v2.WorkspaceSettingService", + HandlerType: (*WorkspaceSettingServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetWorkspaceSetting", + Handler: _WorkspaceSettingService_GetWorkspaceSetting_Handler, + }, + { + MethodName: "SetWorkspaceSetting", + Handler: _WorkspaceSettingService_SetWorkspaceSetting_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "api/v2/workspace_setting_service.proto", +} diff --git a/proto/gen/store/README.md b/proto/gen/store/README.md index 08e5dc1dfd0e3..5164aa2fb41db 100644 --- a/proto/gen/store/README.md +++ b/proto/gen/store/README.md @@ -6,17 +6,20 @@ - [store/activity.proto](#store_activity-proto) - [ActivityMemoCommentPayload](#memos-store-ActivityMemoCommentPayload) - [ActivityPayload](#memos-store-ActivityPayload) + - [ActivityVersionUpdatePayload](#memos-store-ActivityVersionUpdatePayload) - [store/common.proto](#store_common-proto) + - [RowStatus](#memos-store-RowStatus) + - [store/inbox.proto](#store_inbox-proto) - [InboxMessage](#memos-store-InboxMessage) - [InboxMessage.Type](#memos-store-InboxMessage-Type) -- [store/system_setting.proto](#store_system_setting-proto) - - [BackupConfig](#memos-store-BackupConfig) +- [store/reaction.proto](#store_reaction-proto) + - [Reaction](#memos-store-Reaction) - - [SystemSettingKey](#memos-store-SystemSettingKey) + - [Reaction.Type](#memos-store-Reaction-Type) - [store/user_setting.proto](#store_user_setting-proto) - [AccessTokensUserSetting](#memos-store-AccessTokensUserSetting) @@ -25,6 +28,15 @@ - [UserSettingKey](#memos-store-UserSettingKey) +- [store/webhook.proto](#store_webhook-proto) + - [Webhook](#memos-store-Webhook) + +- [store/workspace_setting.proto](#store_workspace_setting-proto) + - [WorkspaceGeneralSetting](#memos-store-WorkspaceGeneralSetting) + - [WorkspaceSetting](#memos-store-WorkspaceSetting) + + - [WorkspaceSettingKey](#memos-store-WorkspaceSettingKey) + - [Scalar Value Types](#scalar-value-types) @@ -61,6 +73,22 @@ | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | memo_comment | [ActivityMemoCommentPayload](#memos-store-ActivityMemoCommentPayload) | | | +| version_update | [ActivityVersionUpdatePayload](#memos-store-ActivityVersionUpdatePayload) | | | + + + + + + + + +### ActivityVersionUpdatePayload + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| version | [string](#string) | | | @@ -84,6 +112,19 @@ + + + +### RowStatus + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| ROW_STATUS_UNSPECIFIED | 0 | | +| NORMAL | 1 | | +| ARCHIVED | 2 | | + + @@ -126,6 +167,7 @@ | ---- | ------ | ----------- | | TYPE_UNSPECIFIED | 0 | | | TYPE_MEMO_COMMENT | 1 | | +| TYPE_VERSION_UPDATE | 2 | | @@ -136,24 +178,26 @@ - +

Top

-## store/system_setting.proto +## store/reaction.proto - + -### BackupConfig +### Reaction | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| enabled | [bool](#bool) | | enabled indicates whether backup is enabled. | -| cron | [string](#string) | | cron is the cron expression for backup. See https://godoc.org/github.com/robfig/cron#hdr-CRON_Expression_Format | -| max_keep | [int32](#int32) | | max_keep is the maximum number of backups to keep. | +| id | [int32](#int32) | | | +| created_ts | [int64](#int64) | | | +| creator_id | [int32](#int32) | | | +| content_id | [string](#string) | | content_id is the id of the content that the reaction is for. This can be a memo. e.g. memos/101 | +| reaction_type | [Reaction.Type](#memos-store-Reaction-Type) | | | @@ -162,15 +206,26 @@ - + -### SystemSettingKey +### Reaction.Type | Name | Number | Description | | ---- | ------ | ----------- | -| SYSTEM_SETTING_KEY_UNSPECIFIED | 0 | | -| BACKUP_CONFIG | 1 | BackupConfig is the key for auto-backup configuration. | +| TYPE_UNSPECIFIED | 0 | | +| THUMBS_UP | 1 | | +| THUMBS_DOWN | 2 | | +| HEART | 3 | | +| FIRE | 4 | | +| CLAPPING_HANDS | 5 | | +| LAUGH | 6 | | +| OK_HAND | 7 | | +| ROCKET | 8 | | +| EYES | 9 | | +| THINKING_FACE | 10 | | +| CLOWN_FACE | 11 | | +| QUESTION_MARK | 12 | | @@ -230,6 +285,10 @@ | user_id | [int32](#int32) | | | | key | [UserSettingKey](#memos-store-UserSettingKey) | | | | access_tokens | [AccessTokensUserSetting](#memos-store-AccessTokensUserSetting) | | | +| locale | [string](#string) | | | +| appearance | [string](#string) | | | +| memo_visibility | [string](#string) | | | +| telegram_user_id | [string](#string) | | | @@ -247,6 +306,110 @@ | ---- | ------ | ----------- | | USER_SETTING_KEY_UNSPECIFIED | 0 | | | USER_SETTING_ACCESS_TOKENS | 1 | Access tokens for the user. | +| USER_SETTING_LOCALE | 2 | The locale of the user. | +| USER_SETTING_APPEARANCE | 3 | The appearance of the user. | +| USER_SETTING_MEMO_VISIBILITY | 4 | The visibility of the memo. | +| USER_SETTING_TELEGRAM_USER_ID | 5 | The telegram user id of the user. | + + + + + + + + + + + +

Top

+ +## store/webhook.proto + + + + + +### Webhook + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| id | [int32](#int32) | | | +| created_ts | [int64](#int64) | | | +| updated_ts | [int64](#int64) | | | +| creator_id | [int32](#int32) | | | +| row_status | [RowStatus](#memos-store-RowStatus) | | | +| name | [string](#string) | | | +| url | [string](#string) | | | + + + + + + + + + + + + + + + + +

Top

+ +## store/workspace_setting.proto + + + + + +### WorkspaceGeneralSetting + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| instance_url | [string](#string) | | instance_url is the instance URL. | +| disallow_signup | [bool](#bool) | | disallow_signup is the flag to disallow signup. | +| disallow_password_login | [bool](#bool) | | disallow_password_login is the flag to disallow password login. | +| additional_script | [string](#string) | | additional_script is the additional script. | +| additional_style | [string](#string) | | additional_style is the additional style. | + + + + + + + + +### WorkspaceSetting + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| key | [WorkspaceSettingKey](#memos-store-WorkspaceSettingKey) | | | +| general | [WorkspaceGeneralSetting](#memos-store-WorkspaceGeneralSetting) | | | + + + + + + + + + + +### WorkspaceSettingKey + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| WORKSPACE_SETTING_KEY_UNSPECIFIED | 0 | | +| WORKSPACE_SETTING_GENERAL | 1 | WORKSPACE_SETTING_GENERAL is the key for general settings. | diff --git a/proto/gen/store/activity.pb.go b/proto/gen/store/activity.pb.go index dbf9eb1b9a43c..76b2aea202e2e 100644 --- a/proto/gen/store/activity.pb.go +++ b/proto/gen/store/activity.pb.go @@ -75,18 +75,66 @@ func (x *ActivityMemoCommentPayload) GetRelatedMemoId() int32 { return 0 } +type ActivityVersionUpdatePayload struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` +} + +func (x *ActivityVersionUpdatePayload) Reset() { + *x = ActivityVersionUpdatePayload{} + if protoimpl.UnsafeEnabled { + mi := &file_store_activity_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ActivityVersionUpdatePayload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ActivityVersionUpdatePayload) ProtoMessage() {} + +func (x *ActivityVersionUpdatePayload) ProtoReflect() protoreflect.Message { + mi := &file_store_activity_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ActivityVersionUpdatePayload.ProtoReflect.Descriptor instead. +func (*ActivityVersionUpdatePayload) Descriptor() ([]byte, []int) { + return file_store_activity_proto_rawDescGZIP(), []int{1} +} + +func (x *ActivityVersionUpdatePayload) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + type ActivityPayload struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MemoComment *ActivityMemoCommentPayload `protobuf:"bytes,1,opt,name=memo_comment,json=memoComment,proto3" json:"memo_comment,omitempty"` + MemoComment *ActivityMemoCommentPayload `protobuf:"bytes,1,opt,name=memo_comment,json=memoComment,proto3" json:"memo_comment,omitempty"` + VersionUpdate *ActivityVersionUpdatePayload `protobuf:"bytes,2,opt,name=version_update,json=versionUpdate,proto3" json:"version_update,omitempty"` } func (x *ActivityPayload) Reset() { *x = ActivityPayload{} if protoimpl.UnsafeEnabled { - mi := &file_store_activity_proto_msgTypes[1] + mi := &file_store_activity_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -99,7 +147,7 @@ func (x *ActivityPayload) String() string { func (*ActivityPayload) ProtoMessage() {} func (x *ActivityPayload) ProtoReflect() protoreflect.Message { - mi := &file_store_activity_proto_msgTypes[1] + mi := &file_store_activity_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -112,7 +160,7 @@ func (x *ActivityPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use ActivityPayload.ProtoReflect.Descriptor instead. func (*ActivityPayload) Descriptor() ([]byte, []int) { - return file_store_activity_proto_rawDescGZIP(), []int{1} + return file_store_activity_proto_rawDescGZIP(), []int{2} } func (x *ActivityPayload) GetMemoComment() *ActivityMemoCommentPayload { @@ -122,6 +170,13 @@ func (x *ActivityPayload) GetMemoComment() *ActivityMemoCommentPayload { return nil } +func (x *ActivityPayload) GetVersionUpdate() *ActivityVersionUpdatePayload { + if x != nil { + return x.VersionUpdate + } + return nil +} + var File_store_activity_proto protoreflect.FileDescriptor var file_store_activity_proto_rawDesc = []byte{ @@ -133,23 +188,32 @@ var file_store_activity_proto_rawDesc = []byte{ 0x28, 0x05, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, - 0x49, 0x64, 0x22, 0x5d, 0x0a, 0x0f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x50, 0x61, - 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x4a, 0x0a, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x63, 0x6f, - 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6d, 0x65, - 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, - 0x74, 0x79, 0x4d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x79, - 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, - 0x74, 0x42, 0x98, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x0d, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, - 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0xa2, 0x02, 0x03, 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, - 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, - 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, - 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x49, 0x64, 0x22, 0x38, 0x0a, 0x1c, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xaf, 0x01, 0x0a, + 0x0f, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x12, 0x4a, 0x0a, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x4d, 0x65, 0x6d, + 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, + 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x50, 0x0a, 0x0e, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x52, + 0x0d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x98, + 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x42, 0x0d, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, + 0x03, 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x6f, + 0x72, 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, + 0xe2, 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x4d, 0x65, 0x6d, + 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -164,18 +228,20 @@ func file_store_activity_proto_rawDescGZIP() []byte { return file_store_activity_proto_rawDescData } -var file_store_activity_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_store_activity_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_store_activity_proto_goTypes = []interface{}{ - (*ActivityMemoCommentPayload)(nil), // 0: memos.store.ActivityMemoCommentPayload - (*ActivityPayload)(nil), // 1: memos.store.ActivityPayload + (*ActivityMemoCommentPayload)(nil), // 0: memos.store.ActivityMemoCommentPayload + (*ActivityVersionUpdatePayload)(nil), // 1: memos.store.ActivityVersionUpdatePayload + (*ActivityPayload)(nil), // 2: memos.store.ActivityPayload } var file_store_activity_proto_depIdxs = []int32{ 0, // 0: memos.store.ActivityPayload.memo_comment:type_name -> memos.store.ActivityMemoCommentPayload - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 1, // 1: memos.store.ActivityPayload.version_update:type_name -> memos.store.ActivityVersionUpdatePayload + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_store_activity_proto_init() } @@ -197,6 +263,18 @@ func file_store_activity_proto_init() { } } file_store_activity_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ActivityVersionUpdatePayload); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_store_activity_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ActivityPayload); i { case 0: return &v.state @@ -215,7 +293,7 @@ func file_store_activity_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_store_activity_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/gen/store/common.pb.go b/proto/gen/store/common.pb.go index 0ee5f9d42ffde..ecf2b6618e3ec 100644 --- a/proto/gen/store/common.pb.go +++ b/proto/gen/store/common.pb.go @@ -10,6 +10,7 @@ import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" + sync "sync" ) const ( @@ -19,25 +20,93 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type RowStatus int32 + +const ( + RowStatus_ROW_STATUS_UNSPECIFIED RowStatus = 0 + RowStatus_NORMAL RowStatus = 1 + RowStatus_ARCHIVED RowStatus = 2 +) + +// Enum value maps for RowStatus. +var ( + RowStatus_name = map[int32]string{ + 0: "ROW_STATUS_UNSPECIFIED", + 1: "NORMAL", + 2: "ARCHIVED", + } + RowStatus_value = map[string]int32{ + "ROW_STATUS_UNSPECIFIED": 0, + "NORMAL": 1, + "ARCHIVED": 2, + } +) + +func (x RowStatus) Enum() *RowStatus { + p := new(RowStatus) + *p = x + return p +} + +func (x RowStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (RowStatus) Descriptor() protoreflect.EnumDescriptor { + return file_store_common_proto_enumTypes[0].Descriptor() +} + +func (RowStatus) Type() protoreflect.EnumType { + return &file_store_common_proto_enumTypes[0] +} + +func (x RowStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use RowStatus.Descriptor instead. +func (RowStatus) EnumDescriptor() ([]byte, []int) { + return file_store_common_proto_rawDescGZIP(), []int{0} +} + var File_store_common_proto protoreflect.FileDescriptor var file_store_common_proto_rawDesc = []byte{ 0x0a, 0x12, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x42, 0x96, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, - 0x02, 0x03, 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, - 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, - 0x65, 0xe2, 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x4d, 0x65, - 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x65, 0x2a, 0x41, 0x0a, 0x09, 0x52, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, + 0x0a, 0x16, 0x52, 0x4f, 0x57, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, + 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x52, 0x43, 0x48, 0x49, 0x56, + 0x45, 0x44, 0x10, 0x02, 0x42, 0x96, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0xa2, 0x02, 0x03, 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, + 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_store_common_proto_rawDescOnce sync.Once + file_store_common_proto_rawDescData = file_store_common_proto_rawDesc +) + +func file_store_common_proto_rawDescGZIP() []byte { + file_store_common_proto_rawDescOnce.Do(func() { + file_store_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_store_common_proto_rawDescData) + }) + return file_store_common_proto_rawDescData } -var file_store_common_proto_goTypes = []interface{}{} +var file_store_common_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_store_common_proto_goTypes = []interface{}{ + (RowStatus)(0), // 0: memos.store.RowStatus +} var file_store_common_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type 0, // [0:0] is the sub-list for method input_type @@ -56,13 +125,14 @@ func file_store_common_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_store_common_proto_rawDesc, - NumEnums: 0, + NumEnums: 1, NumMessages: 0, NumExtensions: 0, NumServices: 0, }, GoTypes: file_store_common_proto_goTypes, DependencyIndexes: file_store_common_proto_depIdxs, + EnumInfos: file_store_common_proto_enumTypes, }.Build() File_store_common_proto = out.File file_store_common_proto_rawDesc = nil diff --git a/proto/gen/store/inbox.pb.go b/proto/gen/store/inbox.pb.go index 50ec5a16106b6..3c33542baf20a 100644 --- a/proto/gen/store/inbox.pb.go +++ b/proto/gen/store/inbox.pb.go @@ -23,8 +23,9 @@ const ( type InboxMessage_Type int32 const ( - InboxMessage_TYPE_UNSPECIFIED InboxMessage_Type = 0 - InboxMessage_TYPE_MEMO_COMMENT InboxMessage_Type = 1 + InboxMessage_TYPE_UNSPECIFIED InboxMessage_Type = 0 + InboxMessage_TYPE_MEMO_COMMENT InboxMessage_Type = 1 + InboxMessage_TYPE_VERSION_UPDATE InboxMessage_Type = 2 ) // Enum value maps for InboxMessage_Type. @@ -32,10 +33,12 @@ var ( InboxMessage_Type_name = map[int32]string{ 0: "TYPE_UNSPECIFIED", 1: "TYPE_MEMO_COMMENT", + 2: "TYPE_VERSION_UPDATE", } InboxMessage_Type_value = map[string]int32{ - "TYPE_UNSPECIFIED": 0, - "TYPE_MEMO_COMMENT": 1, + "TYPE_UNSPECIFIED": 0, + "TYPE_MEMO_COMMENT": 1, + "TYPE_VERSION_UPDATE": 2, } ) @@ -126,27 +129,29 @@ var File_store_inbox_proto protoreflect.FileDescriptor var file_store_inbox_proto_rawDesc = []byte{ 0x0a, 0x11, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x22, 0xad, 0x01, 0x0a, 0x0c, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x22, 0xc6, 0x01, 0x0a, 0x0c, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x63, - 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x49, 0x64, 0x88, 0x01, 0x01, 0x22, 0x33, 0x0a, 0x04, 0x54, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x49, 0x64, 0x88, 0x01, 0x01, 0x22, 0x4c, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x01, - 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, - 0x42, 0x95, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x42, 0x0a, 0x49, 0x6e, 0x62, 0x6f, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, - 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, - 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x6f, 0x72, - 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, - 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, - 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x17, 0x0a, 0x13, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, + 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x02, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x42, 0x95, 0x01, 0x0a, 0x0f, 0x63, 0x6f, + 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x0a, 0x49, + 0x6e, 0x62, 0x6f, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, + 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, + 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, + 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, + 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, + 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/gen/store/reaction.pb.go b/proto/gen/store/reaction.pb.go new file mode 100644 index 0000000000000..af85af464a22d --- /dev/null +++ b/proto/gen/store/reaction.pb.go @@ -0,0 +1,290 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: store/reaction.proto + +package store + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Reaction_Type int32 + +const ( + Reaction_TYPE_UNSPECIFIED Reaction_Type = 0 + Reaction_THUMBS_UP Reaction_Type = 1 + Reaction_THUMBS_DOWN Reaction_Type = 2 + Reaction_HEART Reaction_Type = 3 + Reaction_FIRE Reaction_Type = 4 + Reaction_CLAPPING_HANDS Reaction_Type = 5 + Reaction_LAUGH Reaction_Type = 6 + Reaction_OK_HAND Reaction_Type = 7 + Reaction_ROCKET Reaction_Type = 8 + Reaction_EYES Reaction_Type = 9 + Reaction_THINKING_FACE Reaction_Type = 10 + Reaction_CLOWN_FACE Reaction_Type = 11 + Reaction_QUESTION_MARK Reaction_Type = 12 +) + +// Enum value maps for Reaction_Type. +var ( + Reaction_Type_name = map[int32]string{ + 0: "TYPE_UNSPECIFIED", + 1: "THUMBS_UP", + 2: "THUMBS_DOWN", + 3: "HEART", + 4: "FIRE", + 5: "CLAPPING_HANDS", + 6: "LAUGH", + 7: "OK_HAND", + 8: "ROCKET", + 9: "EYES", + 10: "THINKING_FACE", + 11: "CLOWN_FACE", + 12: "QUESTION_MARK", + } + Reaction_Type_value = map[string]int32{ + "TYPE_UNSPECIFIED": 0, + "THUMBS_UP": 1, + "THUMBS_DOWN": 2, + "HEART": 3, + "FIRE": 4, + "CLAPPING_HANDS": 5, + "LAUGH": 6, + "OK_HAND": 7, + "ROCKET": 8, + "EYES": 9, + "THINKING_FACE": 10, + "CLOWN_FACE": 11, + "QUESTION_MARK": 12, + } +) + +func (x Reaction_Type) Enum() *Reaction_Type { + p := new(Reaction_Type) + *p = x + return p +} + +func (x Reaction_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Reaction_Type) Descriptor() protoreflect.EnumDescriptor { + return file_store_reaction_proto_enumTypes[0].Descriptor() +} + +func (Reaction_Type) Type() protoreflect.EnumType { + return &file_store_reaction_proto_enumTypes[0] +} + +func (x Reaction_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Reaction_Type.Descriptor instead. +func (Reaction_Type) EnumDescriptor() ([]byte, []int) { + return file_store_reaction_proto_rawDescGZIP(), []int{0, 0} +} + +type Reaction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + CreatedTs int64 `protobuf:"varint,2,opt,name=created_ts,json=createdTs,proto3" json:"created_ts,omitempty"` + CreatorId int32 `protobuf:"varint,3,opt,name=creator_id,json=creatorId,proto3" json:"creator_id,omitempty"` + // content_id is the id of the content that the reaction is for. + // This can be a memo. e.g. memos/101 + ContentId string `protobuf:"bytes,4,opt,name=content_id,json=contentId,proto3" json:"content_id,omitempty"` + ReactionType Reaction_Type `protobuf:"varint,5,opt,name=reaction_type,json=reactionType,proto3,enum=memos.store.Reaction_Type" json:"reaction_type,omitempty"` +} + +func (x *Reaction) Reset() { + *x = Reaction{} + if protoimpl.UnsafeEnabled { + mi := &file_store_reaction_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Reaction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Reaction) ProtoMessage() {} + +func (x *Reaction) ProtoReflect() protoreflect.Message { + mi := &file_store_reaction_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Reaction.ProtoReflect.Descriptor instead. +func (*Reaction) Descriptor() ([]byte, []int) { + return file_store_reaction_proto_rawDescGZIP(), []int{0} +} + +func (x *Reaction) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Reaction) GetCreatedTs() int64 { + if x != nil { + return x.CreatedTs + } + return 0 +} + +func (x *Reaction) GetCreatorId() int32 { + if x != nil { + return x.CreatorId + } + return 0 +} + +func (x *Reaction) GetContentId() string { + if x != nil { + return x.ContentId + } + return "" +} + +func (x *Reaction) GetReactionType() Reaction_Type { + if x != nil { + return x.ReactionType + } + return Reaction_TYPE_UNSPECIFIED +} + +var File_store_reaction_proto protoreflect.FileDescriptor + +var file_store_reaction_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x22, 0x84, 0x03, 0x0a, 0x08, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x54, 0x73, 0x12, + 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x3f, 0x0a, + 0x0d, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x2e, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x0c, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, 0xc9, + 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, + 0x09, 0x54, 0x48, 0x55, 0x4d, 0x42, 0x53, 0x5f, 0x55, 0x50, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, + 0x54, 0x48, 0x55, 0x4d, 0x42, 0x53, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x02, 0x12, 0x09, 0x0a, + 0x05, 0x48, 0x45, 0x41, 0x52, 0x54, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x46, 0x49, 0x52, 0x45, + 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4c, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x48, + 0x41, 0x4e, 0x44, 0x53, 0x10, 0x05, 0x12, 0x09, 0x0a, 0x05, 0x4c, 0x41, 0x55, 0x47, 0x48, 0x10, + 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x4b, 0x5f, 0x48, 0x41, 0x4e, 0x44, 0x10, 0x07, 0x12, 0x0a, + 0x0a, 0x06, 0x52, 0x4f, 0x43, 0x4b, 0x45, 0x54, 0x10, 0x08, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x59, + 0x45, 0x53, 0x10, 0x09, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x48, 0x49, 0x4e, 0x4b, 0x49, 0x4e, 0x47, + 0x5f, 0x46, 0x41, 0x43, 0x45, 0x10, 0x0a, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x4c, 0x4f, 0x57, 0x4e, + 0x5f, 0x46, 0x41, 0x43, 0x45, 0x10, 0x0b, 0x12, 0x11, 0x0a, 0x0d, 0x51, 0x55, 0x45, 0x53, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x41, 0x52, 0x4b, 0x10, 0x0c, 0x42, 0x98, 0x01, 0x0a, 0x0f, 0x63, + 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x0d, + 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, + 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x4d, 0x53, 0x58, + 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, + 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x4d, + 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, + 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_store_reaction_proto_rawDescOnce sync.Once + file_store_reaction_proto_rawDescData = file_store_reaction_proto_rawDesc +) + +func file_store_reaction_proto_rawDescGZIP() []byte { + file_store_reaction_proto_rawDescOnce.Do(func() { + file_store_reaction_proto_rawDescData = protoimpl.X.CompressGZIP(file_store_reaction_proto_rawDescData) + }) + return file_store_reaction_proto_rawDescData +} + +var file_store_reaction_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_store_reaction_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_store_reaction_proto_goTypes = []interface{}{ + (Reaction_Type)(0), // 0: memos.store.Reaction.Type + (*Reaction)(nil), // 1: memos.store.Reaction +} +var file_store_reaction_proto_depIdxs = []int32{ + 0, // 0: memos.store.Reaction.reaction_type:type_name -> memos.store.Reaction.Type + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_store_reaction_proto_init() } +func file_store_reaction_proto_init() { + if File_store_reaction_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_store_reaction_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Reaction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_store_reaction_proto_rawDesc, + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_store_reaction_proto_goTypes, + DependencyIndexes: file_store_reaction_proto_depIdxs, + EnumInfos: file_store_reaction_proto_enumTypes, + MessageInfos: file_store_reaction_proto_msgTypes, + }.Build() + File_store_reaction_proto = out.File + file_store_reaction_proto_rawDesc = nil + file_store_reaction_proto_goTypes = nil + file_store_reaction_proto_depIdxs = nil +} diff --git a/proto/gen/store/system_setting.pb.go b/proto/gen/store/system_setting.pb.go deleted file mode 100644 index 0b7b65d5a5c34..0000000000000 --- a/proto/gen/store/system_setting.pb.go +++ /dev/null @@ -1,229 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.31.0 -// protoc (unknown) -// source: store/system_setting.proto - -package store - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type SystemSettingKey int32 - -const ( - SystemSettingKey_SYSTEM_SETTING_KEY_UNSPECIFIED SystemSettingKey = 0 - // BackupConfig is the key for auto-backup configuration. - SystemSettingKey_BACKUP_CONFIG SystemSettingKey = 1 -) - -// Enum value maps for SystemSettingKey. -var ( - SystemSettingKey_name = map[int32]string{ - 0: "SYSTEM_SETTING_KEY_UNSPECIFIED", - 1: "BACKUP_CONFIG", - } - SystemSettingKey_value = map[string]int32{ - "SYSTEM_SETTING_KEY_UNSPECIFIED": 0, - "BACKUP_CONFIG": 1, - } -) - -func (x SystemSettingKey) Enum() *SystemSettingKey { - p := new(SystemSettingKey) - *p = x - return p -} - -func (x SystemSettingKey) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (SystemSettingKey) Descriptor() protoreflect.EnumDescriptor { - return file_store_system_setting_proto_enumTypes[0].Descriptor() -} - -func (SystemSettingKey) Type() protoreflect.EnumType { - return &file_store_system_setting_proto_enumTypes[0] -} - -func (x SystemSettingKey) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use SystemSettingKey.Descriptor instead. -func (SystemSettingKey) EnumDescriptor() ([]byte, []int) { - return file_store_system_setting_proto_rawDescGZIP(), []int{0} -} - -type BackupConfig struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // enabled indicates whether backup is enabled. - Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` - // cron is the cron expression for backup. See https://godoc.org/github.com/robfig/cron#hdr-CRON_Expression_Format - Cron string `protobuf:"bytes,2,opt,name=cron,proto3" json:"cron,omitempty"` - // max_keep is the maximum number of backups to keep. - MaxKeep int32 `protobuf:"varint,3,opt,name=max_keep,json=maxKeep,proto3" json:"max_keep,omitempty"` -} - -func (x *BackupConfig) Reset() { - *x = BackupConfig{} - if protoimpl.UnsafeEnabled { - mi := &file_store_system_setting_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *BackupConfig) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*BackupConfig) ProtoMessage() {} - -func (x *BackupConfig) ProtoReflect() protoreflect.Message { - mi := &file_store_system_setting_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use BackupConfig.ProtoReflect.Descriptor instead. -func (*BackupConfig) Descriptor() ([]byte, []int) { - return file_store_system_setting_proto_rawDescGZIP(), []int{0} -} - -func (x *BackupConfig) GetEnabled() bool { - if x != nil { - return x.Enabled - } - return false -} - -func (x *BackupConfig) GetCron() string { - if x != nil { - return x.Cron - } - return "" -} - -func (x *BackupConfig) GetMaxKeep() int32 { - if x != nil { - return x.MaxKeep - } - return 0 -} - -var File_store_system_setting_proto protoreflect.FileDescriptor - -var file_store_system_setting_proto_rawDesc = []byte{ - 0x0a, 0x1a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x73, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x6d, 0x65, - 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x57, 0x0a, 0x0c, 0x42, 0x61, 0x63, - 0x6b, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x6b, - 0x65, 0x65, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x4b, 0x65, - 0x65, 0x70, 0x2a, 0x49, 0x0a, 0x10, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x1e, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, - 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x42, 0x41, - 0x43, 0x4b, 0x55, 0x50, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, 0x01, 0x42, 0x9d, 0x01, - 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x42, 0x12, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, - 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0xa2, 0x02, 0x03, 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, - 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, - 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_store_system_setting_proto_rawDescOnce sync.Once - file_store_system_setting_proto_rawDescData = file_store_system_setting_proto_rawDesc -) - -func file_store_system_setting_proto_rawDescGZIP() []byte { - file_store_system_setting_proto_rawDescOnce.Do(func() { - file_store_system_setting_proto_rawDescData = protoimpl.X.CompressGZIP(file_store_system_setting_proto_rawDescData) - }) - return file_store_system_setting_proto_rawDescData -} - -var file_store_system_setting_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_store_system_setting_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_store_system_setting_proto_goTypes = []interface{}{ - (SystemSettingKey)(0), // 0: memos.store.SystemSettingKey - (*BackupConfig)(nil), // 1: memos.store.BackupConfig -} -var file_store_system_setting_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_store_system_setting_proto_init() } -func file_store_system_setting_proto_init() { - if File_store_system_setting_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_store_system_setting_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BackupConfig); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_store_system_setting_proto_rawDesc, - NumEnums: 1, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_store_system_setting_proto_goTypes, - DependencyIndexes: file_store_system_setting_proto_depIdxs, - EnumInfos: file_store_system_setting_proto_enumTypes, - MessageInfos: file_store_system_setting_proto_msgTypes, - }.Build() - File_store_system_setting_proto = out.File - file_store_system_setting_proto_rawDesc = nil - file_store_system_setting_proto_goTypes = nil - file_store_system_setting_proto_depIdxs = nil -} diff --git a/proto/gen/store/user_setting.pb.go b/proto/gen/store/user_setting.pb.go index c2e6419ee5b26..4046368b73235 100644 --- a/proto/gen/store/user_setting.pb.go +++ b/proto/gen/store/user_setting.pb.go @@ -26,6 +26,14 @@ const ( UserSettingKey_USER_SETTING_KEY_UNSPECIFIED UserSettingKey = 0 // Access tokens for the user. UserSettingKey_USER_SETTING_ACCESS_TOKENS UserSettingKey = 1 + // The locale of the user. + UserSettingKey_USER_SETTING_LOCALE UserSettingKey = 2 + // The appearance of the user. + UserSettingKey_USER_SETTING_APPEARANCE UserSettingKey = 3 + // The visibility of the memo. + UserSettingKey_USER_SETTING_MEMO_VISIBILITY UserSettingKey = 4 + // The telegram user id of the user. + UserSettingKey_USER_SETTING_TELEGRAM_USER_ID UserSettingKey = 5 ) // Enum value maps for UserSettingKey. @@ -33,10 +41,18 @@ var ( UserSettingKey_name = map[int32]string{ 0: "USER_SETTING_KEY_UNSPECIFIED", 1: "USER_SETTING_ACCESS_TOKENS", + 2: "USER_SETTING_LOCALE", + 3: "USER_SETTING_APPEARANCE", + 4: "USER_SETTING_MEMO_VISIBILITY", + 5: "USER_SETTING_TELEGRAM_USER_ID", } UserSettingKey_value = map[string]int32{ - "USER_SETTING_KEY_UNSPECIFIED": 0, - "USER_SETTING_ACCESS_TOKENS": 1, + "USER_SETTING_KEY_UNSPECIFIED": 0, + "USER_SETTING_ACCESS_TOKENS": 1, + "USER_SETTING_LOCALE": 2, + "USER_SETTING_APPEARANCE": 3, + "USER_SETTING_MEMO_VISIBILITY": 4, + "USER_SETTING_TELEGRAM_USER_ID": 5, } ) @@ -77,6 +93,10 @@ type UserSetting struct { // Types that are assignable to Value: // // *UserSetting_AccessTokens + // *UserSetting_Locale + // *UserSetting_Appearance + // *UserSetting_MemoVisibility + // *UserSetting_TelegramUserId Value isUserSetting_Value `protobuf_oneof:"value"` } @@ -140,6 +160,34 @@ func (x *UserSetting) GetAccessTokens() *AccessTokensUserSetting { return nil } +func (x *UserSetting) GetLocale() string { + if x, ok := x.GetValue().(*UserSetting_Locale); ok { + return x.Locale + } + return "" +} + +func (x *UserSetting) GetAppearance() string { + if x, ok := x.GetValue().(*UserSetting_Appearance); ok { + return x.Appearance + } + return "" +} + +func (x *UserSetting) GetMemoVisibility() string { + if x, ok := x.GetValue().(*UserSetting_MemoVisibility); ok { + return x.MemoVisibility + } + return "" +} + +func (x *UserSetting) GetTelegramUserId() string { + if x, ok := x.GetValue().(*UserSetting_TelegramUserId); ok { + return x.TelegramUserId + } + return "" +} + type isUserSetting_Value interface { isUserSetting_Value() } @@ -148,8 +196,32 @@ type UserSetting_AccessTokens struct { AccessTokens *AccessTokensUserSetting `protobuf:"bytes,3,opt,name=access_tokens,json=accessTokens,proto3,oneof"` } +type UserSetting_Locale struct { + Locale string `protobuf:"bytes,4,opt,name=locale,proto3,oneof"` +} + +type UserSetting_Appearance struct { + Appearance string `protobuf:"bytes,5,opt,name=appearance,proto3,oneof"` +} + +type UserSetting_MemoVisibility struct { + MemoVisibility string `protobuf:"bytes,6,opt,name=memo_visibility,json=memoVisibility,proto3,oneof"` +} + +type UserSetting_TelegramUserId struct { + TelegramUserId string `protobuf:"bytes,7,opt,name=telegram_user_id,json=telegramUserId,proto3,oneof"` +} + func (*UserSetting_AccessTokens) isUserSetting_Value() {} +func (*UserSetting_Locale) isUserSetting_Value() {} + +func (*UserSetting_Appearance) isUserSetting_Value() {} + +func (*UserSetting_MemoVisibility) isUserSetting_Value() {} + +func (*UserSetting_TelegramUserId) isUserSetting_Value() {} + type AccessTokensUserSetting struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -260,7 +332,7 @@ var File_store_user_setting_proto protoreflect.FileDescriptor var file_store_user_setting_proto_rawDesc = []byte{ 0x0a, 0x18, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, - 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0xab, 0x01, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, + 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0xbe, 0x02, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, @@ -270,36 +342,53 @@ var file_store_user_setting_proto_rawDesc = []byte{ 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x0c, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x42, 0x07, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xc4, 0x01, 0x0a, 0x17, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x06, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, + 0x61, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x70, + 0x70, 0x65, 0x61, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x0f, 0x6d, 0x65, 0x6d, 0x6f, + 0x5f, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x00, 0x52, 0x0e, 0x6d, 0x65, 0x6d, 0x6f, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x10, 0x74, 0x65, 0x6c, 0x65, 0x67, 0x72, 0x61, 0x6d, 0x5f, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x0e, 0x74, 0x65, 0x6c, 0x65, 0x67, 0x72, 0x61, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x42, + 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xc4, 0x01, 0x0a, 0x17, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x12, 0x55, 0x0a, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, - 0x67, 0x12, 0x55, 0x0a, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, - 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x73, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x1a, 0x52, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x52, 0x0a, 0x0e, - 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x12, 0x20, - 0x0a, 0x1c, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x4b, - 0x45, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x1e, 0x0a, 0x1a, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, - 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x4f, 0x4b, 0x45, 0x4e, 0x53, 0x10, 0x01, - 0x42, 0x9b, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x42, 0x10, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, - 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, - 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, - 0x73, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, - 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, - 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x67, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0c, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x1a, 0x52, 0x0a, 0x0b, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x20, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, + 0xcd, 0x01, 0x0a, 0x0e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x4b, + 0x65, 0x79, 0x12, 0x20, 0x0a, 0x1c, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, + 0x4e, 0x47, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, + 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x54, 0x4f, 0x4b, 0x45, + 0x4e, 0x53, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, + 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x45, 0x10, 0x02, 0x12, 0x1b, 0x0a, + 0x17, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x50, + 0x50, 0x45, 0x41, 0x52, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x03, 0x12, 0x20, 0x0a, 0x1c, 0x55, 0x53, + 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, 0x5f, + 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x10, 0x04, 0x12, 0x21, 0x0a, 0x1d, + 0x55, 0x53, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x54, 0x45, 0x4c, + 0x45, 0x47, 0x52, 0x41, 0x4d, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x49, 0x44, 0x10, 0x05, 0x42, + 0x9b, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x42, 0x10, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, + 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0xa2, 0x02, 0x03, 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, + 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, + 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -378,6 +467,10 @@ func file_store_user_setting_proto_init() { } file_store_user_setting_proto_msgTypes[0].OneofWrappers = []interface{}{ (*UserSetting_AccessTokens)(nil), + (*UserSetting_Locale)(nil), + (*UserSetting_Appearance)(nil), + (*UserSetting_MemoVisibility)(nil), + (*UserSetting_TelegramUserId)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/proto/gen/store/webhook.pb.go b/proto/gen/store/webhook.pb.go new file mode 100644 index 0000000000000..d85d40253552e --- /dev/null +++ b/proto/gen/store/webhook.pb.go @@ -0,0 +1,214 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: store/webhook.proto + +package store + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Webhook struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + CreatedTs int64 `protobuf:"varint,2,opt,name=created_ts,json=createdTs,proto3" json:"created_ts,omitempty"` + UpdatedTs int64 `protobuf:"varint,3,opt,name=updated_ts,json=updatedTs,proto3" json:"updated_ts,omitempty"` + CreatorId int32 `protobuf:"varint,4,opt,name=creator_id,json=creatorId,proto3" json:"creator_id,omitempty"` + RowStatus RowStatus `protobuf:"varint,5,opt,name=row_status,json=rowStatus,proto3,enum=memos.store.RowStatus" json:"row_status,omitempty"` + Name string `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"` + Url string `protobuf:"bytes,7,opt,name=url,proto3" json:"url,omitempty"` +} + +func (x *Webhook) Reset() { + *x = Webhook{} + if protoimpl.UnsafeEnabled { + mi := &file_store_webhook_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Webhook) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Webhook) ProtoMessage() {} + +func (x *Webhook) ProtoReflect() protoreflect.Message { + mi := &file_store_webhook_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Webhook.ProtoReflect.Descriptor instead. +func (*Webhook) Descriptor() ([]byte, []int) { + return file_store_webhook_proto_rawDescGZIP(), []int{0} +} + +func (x *Webhook) GetId() int32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Webhook) GetCreatedTs() int64 { + if x != nil { + return x.CreatedTs + } + return 0 +} + +func (x *Webhook) GetUpdatedTs() int64 { + if x != nil { + return x.UpdatedTs + } + return 0 +} + +func (x *Webhook) GetCreatorId() int32 { + if x != nil { + return x.CreatorId + } + return 0 +} + +func (x *Webhook) GetRowStatus() RowStatus { + if x != nil { + return x.RowStatus + } + return RowStatus_ROW_STATUS_UNSPECIFIED +} + +func (x *Webhook) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Webhook) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +var File_store_webhook_proto protoreflect.FileDescriptor + +var file_store_webhook_proto_rawDesc = []byte{ + 0x0a, 0x13, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x1a, 0x12, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd3, 0x01, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, 0x6f, + 0x6f, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x54, + 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x54, 0x73, + 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, + 0x35, 0x0a, 0x0a, 0x72, 0x6f, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x2e, 0x52, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, 0x72, 0x6f, 0x77, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, + 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x42, 0x97, 0x01, 0x0a, + 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x42, 0x0c, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x73, 0x65, + 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x4d, 0x53, + 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, + 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, + 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x3a, + 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_store_webhook_proto_rawDescOnce sync.Once + file_store_webhook_proto_rawDescData = file_store_webhook_proto_rawDesc +) + +func file_store_webhook_proto_rawDescGZIP() []byte { + file_store_webhook_proto_rawDescOnce.Do(func() { + file_store_webhook_proto_rawDescData = protoimpl.X.CompressGZIP(file_store_webhook_proto_rawDescData) + }) + return file_store_webhook_proto_rawDescData +} + +var file_store_webhook_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_store_webhook_proto_goTypes = []interface{}{ + (*Webhook)(nil), // 0: memos.store.Webhook + (RowStatus)(0), // 1: memos.store.RowStatus +} +var file_store_webhook_proto_depIdxs = []int32{ + 1, // 0: memos.store.Webhook.row_status:type_name -> memos.store.RowStatus + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_store_webhook_proto_init() } +func file_store_webhook_proto_init() { + if File_store_webhook_proto != nil { + return + } + file_store_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_store_webhook_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Webhook); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_store_webhook_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_store_webhook_proto_goTypes, + DependencyIndexes: file_store_webhook_proto_depIdxs, + MessageInfos: file_store_webhook_proto_msgTypes, + }.Build() + File_store_webhook_proto = out.File + file_store_webhook_proto_rawDesc = nil + file_store_webhook_proto_goTypes = nil + file_store_webhook_proto_depIdxs = nil +} diff --git a/proto/gen/store/workspace_setting.pb.go b/proto/gen/store/workspace_setting.pb.go new file mode 100644 index 0000000000000..be1c79c3001b9 --- /dev/null +++ b/proto/gen/store/workspace_setting.pb.go @@ -0,0 +1,360 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: store/workspace_setting.proto + +package store + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type WorkspaceSettingKey int32 + +const ( + WorkspaceSettingKey_WORKSPACE_SETTING_KEY_UNSPECIFIED WorkspaceSettingKey = 0 + // WORKSPACE_SETTING_GENERAL is the key for general settings. + WorkspaceSettingKey_WORKSPACE_SETTING_GENERAL WorkspaceSettingKey = 1 +) + +// Enum value maps for WorkspaceSettingKey. +var ( + WorkspaceSettingKey_name = map[int32]string{ + 0: "WORKSPACE_SETTING_KEY_UNSPECIFIED", + 1: "WORKSPACE_SETTING_GENERAL", + } + WorkspaceSettingKey_value = map[string]int32{ + "WORKSPACE_SETTING_KEY_UNSPECIFIED": 0, + "WORKSPACE_SETTING_GENERAL": 1, + } +) + +func (x WorkspaceSettingKey) Enum() *WorkspaceSettingKey { + p := new(WorkspaceSettingKey) + *p = x + return p +} + +func (x WorkspaceSettingKey) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (WorkspaceSettingKey) Descriptor() protoreflect.EnumDescriptor { + return file_store_workspace_setting_proto_enumTypes[0].Descriptor() +} + +func (WorkspaceSettingKey) Type() protoreflect.EnumType { + return &file_store_workspace_setting_proto_enumTypes[0] +} + +func (x WorkspaceSettingKey) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use WorkspaceSettingKey.Descriptor instead. +func (WorkspaceSettingKey) EnumDescriptor() ([]byte, []int) { + return file_store_workspace_setting_proto_rawDescGZIP(), []int{0} +} + +type WorkspaceSetting struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key WorkspaceSettingKey `protobuf:"varint,1,opt,name=key,proto3,enum=memos.store.WorkspaceSettingKey" json:"key,omitempty"` + // Types that are assignable to Value: + // + // *WorkspaceSetting_General + Value isWorkspaceSetting_Value `protobuf_oneof:"value"` +} + +func (x *WorkspaceSetting) Reset() { + *x = WorkspaceSetting{} + if protoimpl.UnsafeEnabled { + mi := &file_store_workspace_setting_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WorkspaceSetting) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkspaceSetting) ProtoMessage() {} + +func (x *WorkspaceSetting) ProtoReflect() protoreflect.Message { + mi := &file_store_workspace_setting_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkspaceSetting.ProtoReflect.Descriptor instead. +func (*WorkspaceSetting) Descriptor() ([]byte, []int) { + return file_store_workspace_setting_proto_rawDescGZIP(), []int{0} +} + +func (x *WorkspaceSetting) GetKey() WorkspaceSettingKey { + if x != nil { + return x.Key + } + return WorkspaceSettingKey_WORKSPACE_SETTING_KEY_UNSPECIFIED +} + +func (m *WorkspaceSetting) GetValue() isWorkspaceSetting_Value { + if m != nil { + return m.Value + } + return nil +} + +func (x *WorkspaceSetting) GetGeneral() *WorkspaceGeneralSetting { + if x, ok := x.GetValue().(*WorkspaceSetting_General); ok { + return x.General + } + return nil +} + +type isWorkspaceSetting_Value interface { + isWorkspaceSetting_Value() +} + +type WorkspaceSetting_General struct { + General *WorkspaceGeneralSetting `protobuf:"bytes,2,opt,name=general,proto3,oneof"` +} + +func (*WorkspaceSetting_General) isWorkspaceSetting_Value() {} + +type WorkspaceGeneralSetting struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // instance_url is the instance URL. + InstanceUrl string `protobuf:"bytes,1,opt,name=instance_url,json=instanceUrl,proto3" json:"instance_url,omitempty"` + // disallow_signup is the flag to disallow signup. + DisallowSignup bool `protobuf:"varint,2,opt,name=disallow_signup,json=disallowSignup,proto3" json:"disallow_signup,omitempty"` + // disallow_password_login is the flag to disallow password login. + DisallowPasswordLogin bool `protobuf:"varint,3,opt,name=disallow_password_login,json=disallowPasswordLogin,proto3" json:"disallow_password_login,omitempty"` + // additional_script is the additional script. + AdditionalScript string `protobuf:"bytes,5,opt,name=additional_script,json=additionalScript,proto3" json:"additional_script,omitempty"` + // additional_style is the additional style. + AdditionalStyle string `protobuf:"bytes,6,opt,name=additional_style,json=additionalStyle,proto3" json:"additional_style,omitempty"` +} + +func (x *WorkspaceGeneralSetting) Reset() { + *x = WorkspaceGeneralSetting{} + if protoimpl.UnsafeEnabled { + mi := &file_store_workspace_setting_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WorkspaceGeneralSetting) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WorkspaceGeneralSetting) ProtoMessage() {} + +func (x *WorkspaceGeneralSetting) ProtoReflect() protoreflect.Message { + mi := &file_store_workspace_setting_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WorkspaceGeneralSetting.ProtoReflect.Descriptor instead. +func (*WorkspaceGeneralSetting) Descriptor() ([]byte, []int) { + return file_store_workspace_setting_proto_rawDescGZIP(), []int{1} +} + +func (x *WorkspaceGeneralSetting) GetInstanceUrl() string { + if x != nil { + return x.InstanceUrl + } + return "" +} + +func (x *WorkspaceGeneralSetting) GetDisallowSignup() bool { + if x != nil { + return x.DisallowSignup + } + return false +} + +func (x *WorkspaceGeneralSetting) GetDisallowPasswordLogin() bool { + if x != nil { + return x.DisallowPasswordLogin + } + return false +} + +func (x *WorkspaceGeneralSetting) GetAdditionalScript() string { + if x != nil { + return x.AdditionalScript + } + return "" +} + +func (x *WorkspaceGeneralSetting) GetAdditionalStyle() string { + if x != nil { + return x.AdditionalStyle + } + return "" +} + +var File_store_workspace_setting_proto protoreflect.FileDescriptor + +var file_store_workspace_setting_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x91, 0x01, 0x0a, + 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x12, 0x32, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, + 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x57, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x40, 0x0a, 0x07, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x07, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x22, 0xf5, 0x01, 0x0a, 0x17, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x21, 0x0a, 0x0c, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x55, 0x72, 0x6c, 0x12, + 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x73, 0x69, 0x67, 0x6e, + 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x69, 0x73, 0x61, 0x6c, 0x6c, + 0x6f, 0x77, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x12, 0x36, 0x0a, 0x17, 0x64, 0x69, 0x73, 0x61, + 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x6c, 0x6f, + 0x67, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x64, 0x69, 0x73, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x4c, 0x6f, 0x67, 0x69, 0x6e, + 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x61, 0x64, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x29, 0x0a, + 0x10, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x2a, 0x5b, 0x0a, 0x13, 0x57, 0x6f, 0x72, 0x6b, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x4b, 0x65, 0x79, 0x12, + 0x25, 0x0a, 0x21, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, + 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, + 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x47, 0x45, 0x4e, 0x45, + 0x52, 0x41, 0x4c, 0x10, 0x01, 0x42, 0xa0, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x6d, 0x65, + 0x6d, 0x6f, 0x73, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x42, 0x15, 0x57, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, + 0x73, 0x65, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x65, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, + 0x4d, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x2e, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0xca, 0x02, 0x0b, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, + 0x02, 0x17, 0x4d, 0x65, 0x6d, 0x6f, 0x73, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x4d, 0x65, 0x6d, 0x6f, + 0x73, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_store_workspace_setting_proto_rawDescOnce sync.Once + file_store_workspace_setting_proto_rawDescData = file_store_workspace_setting_proto_rawDesc +) + +func file_store_workspace_setting_proto_rawDescGZIP() []byte { + file_store_workspace_setting_proto_rawDescOnce.Do(func() { + file_store_workspace_setting_proto_rawDescData = protoimpl.X.CompressGZIP(file_store_workspace_setting_proto_rawDescData) + }) + return file_store_workspace_setting_proto_rawDescData +} + +var file_store_workspace_setting_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_store_workspace_setting_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_store_workspace_setting_proto_goTypes = []interface{}{ + (WorkspaceSettingKey)(0), // 0: memos.store.WorkspaceSettingKey + (*WorkspaceSetting)(nil), // 1: memos.store.WorkspaceSetting + (*WorkspaceGeneralSetting)(nil), // 2: memos.store.WorkspaceGeneralSetting +} +var file_store_workspace_setting_proto_depIdxs = []int32{ + 0, // 0: memos.store.WorkspaceSetting.key:type_name -> memos.store.WorkspaceSettingKey + 2, // 1: memos.store.WorkspaceSetting.general:type_name -> memos.store.WorkspaceGeneralSetting + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_store_workspace_setting_proto_init() } +func file_store_workspace_setting_proto_init() { + if File_store_workspace_setting_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_store_workspace_setting_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WorkspaceSetting); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_store_workspace_setting_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WorkspaceGeneralSetting); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_store_workspace_setting_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*WorkspaceSetting_General)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_store_workspace_setting_proto_rawDesc, + NumEnums: 1, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_store_workspace_setting_proto_goTypes, + DependencyIndexes: file_store_workspace_setting_proto_depIdxs, + EnumInfos: file_store_workspace_setting_proto_enumTypes, + MessageInfos: file_store_workspace_setting_proto_msgTypes, + }.Build() + File_store_workspace_setting_proto = out.File + file_store_workspace_setting_proto_rawDesc = nil + file_store_workspace_setting_proto_goTypes = nil + file_store_workspace_setting_proto_depIdxs = nil +} diff --git a/proto/store/activity.proto b/proto/store/activity.proto index d6613bd9eab22..d5c7bdf163158 100644 --- a/proto/store/activity.proto +++ b/proto/store/activity.proto @@ -9,6 +9,11 @@ message ActivityMemoCommentPayload { int32 related_memo_id = 2; } +message ActivityVersionUpdatePayload { + string version = 1; +} + message ActivityPayload { ActivityMemoCommentPayload memo_comment = 1; + ActivityVersionUpdatePayload version_update = 2; } diff --git a/proto/store/common.proto b/proto/store/common.proto index 5990f042cde97..147cfd3199e57 100644 --- a/proto/store/common.proto +++ b/proto/store/common.proto @@ -3,3 +3,11 @@ syntax = "proto3"; package memos.store; option go_package = "gen/store"; + +enum RowStatus { + ROW_STATUS_UNSPECIFIED = 0; + + NORMAL = 1; + + ARCHIVED = 2; +} diff --git a/proto/store/inbox.proto b/proto/store/inbox.proto index f4bd4cf07b831..6349105ac61dd 100644 --- a/proto/store/inbox.proto +++ b/proto/store/inbox.proto @@ -8,6 +8,7 @@ message InboxMessage { enum Type { TYPE_UNSPECIFIED = 0; TYPE_MEMO_COMMENT = 1; + TYPE_VERSION_UPDATE = 2; } Type type = 1; optional int32 activity_id = 2; diff --git a/proto/store/reaction.proto b/proto/store/reaction.proto new file mode 100644 index 0000000000000..00cec419a291e --- /dev/null +++ b/proto/store/reaction.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; + +package memos.store; + +option go_package = "gen/store"; + +message Reaction { + int32 id = 1; + + int64 created_ts = 2; + + int32 creator_id = 3; + + // content_id is the id of the content that the reaction is for. + // This can be a memo. e.g. memos/101 + string content_id = 4; + + enum Type { + TYPE_UNSPECIFIED = 0; + THUMBS_UP = 1; + THUMBS_DOWN = 2; + HEART = 3; + FIRE = 4; + CLAPPING_HANDS = 5; + LAUGH = 6; + OK_HAND = 7; + ROCKET = 8; + EYES = 9; + THINKING_FACE = 10; + CLOWN_FACE = 11; + QUESTION_MARK = 12; + } + Type reaction_type = 5; +} diff --git a/proto/store/system_setting.proto b/proto/store/system_setting.proto deleted file mode 100644 index 0663d9853c451..0000000000000 --- a/proto/store/system_setting.proto +++ /dev/null @@ -1,21 +0,0 @@ -syntax = "proto3"; - -package memos.store; - -option go_package = "gen/store"; - -enum SystemSettingKey { - SYSTEM_SETTING_KEY_UNSPECIFIED = 0; - - // BackupConfig is the key for auto-backup configuration. - BACKUP_CONFIG = 1; -} - -message BackupConfig { - // enabled indicates whether backup is enabled. - bool enabled = 1; - // cron is the cron expression for backup. See https://godoc.org/github.com/robfig/cron#hdr-CRON_Expression_Format - string cron = 2; - // max_keep is the maximum number of backups to keep. - int32 max_keep = 3; -} diff --git a/proto/store/user_setting.proto b/proto/store/user_setting.proto index 6d46fc9867b5e..085bdb2912687 100644 --- a/proto/store/user_setting.proto +++ b/proto/store/user_setting.proto @@ -4,23 +4,32 @@ package memos.store; option go_package = "gen/store"; +enum UserSettingKey { + USER_SETTING_KEY_UNSPECIFIED = 0; + // Access tokens for the user. + USER_SETTING_ACCESS_TOKENS = 1; + // The locale of the user. + USER_SETTING_LOCALE = 2; + // The appearance of the user. + USER_SETTING_APPEARANCE = 3; + // The visibility of the memo. + USER_SETTING_MEMO_VISIBILITY = 4; + // The telegram user id of the user. + USER_SETTING_TELEGRAM_USER_ID = 5; +} + message UserSetting { int32 user_id = 1; - UserSettingKey key = 2; - oneof value { AccessTokensUserSetting access_tokens = 3; + string locale = 4; + string appearance = 5; + string memo_visibility = 6; + string telegram_user_id = 7; } } -enum UserSettingKey { - USER_SETTING_KEY_UNSPECIFIED = 0; - - // Access tokens for the user. - USER_SETTING_ACCESS_TOKENS = 1; -} - message AccessTokensUserSetting { message AccessToken { // The access token is a JWT token. diff --git a/proto/store/webhook.proto b/proto/store/webhook.proto new file mode 100644 index 0000000000000..04627d7ece761 --- /dev/null +++ b/proto/store/webhook.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +package memos.store; + +import "store/common.proto"; + +option go_package = "gen/store"; + +message Webhook { + int32 id = 1; + + int64 created_ts = 2; + + int64 updated_ts = 3; + + int32 creator_id = 4; + + RowStatus row_status = 5; + + string name = 6; + + string url = 7; +} diff --git a/proto/store/workspace_setting.proto b/proto/store/workspace_setting.proto new file mode 100644 index 0000000000000..8d93d9a57cb8e --- /dev/null +++ b/proto/store/workspace_setting.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +package memos.store; + +option go_package = "gen/store"; + +enum WorkspaceSettingKey { + WORKSPACE_SETTING_KEY_UNSPECIFIED = 0; + // WORKSPACE_SETTING_GENERAL is the key for general settings. + WORKSPACE_SETTING_GENERAL = 1; +} + +message WorkspaceSetting { + WorkspaceSettingKey key = 1; + oneof value { + WorkspaceGeneralSetting general = 2; + } +} + +message WorkspaceGeneralSetting { + // instance_url is the instance URL. + string instance_url = 1; + // disallow_signup is the flag to disallow signup. + bool disallow_signup = 2; + // disallow_password_login is the flag to disallow password login. + bool disallow_password_login = 3; + // additional_script is the additional script. + string additional_script = 5; + // additional_style is the additional style. + string additional_style = 6; +} diff --git a/scripts/.air-windows.toml b/scripts/.air-windows.toml index dcdd77994c529..300ed4ba55a16 100644 --- a/scripts/.air-windows.toml +++ b/scripts/.air-windows.toml @@ -3,7 +3,7 @@ tmp_dir = ".air" [build] bin = "./.air/memos.exe --mode dev" -cmd = "go build -o ./.air/memos.exe ./main.go" +cmd = "go build -o ./.air/memos.exe ./bin/memos/main.go" delay = 1000 exclude_dir = [".air", "web", "build"] include_ext = ["go", "mod", "sum"] diff --git a/scripts/.air.toml b/scripts/.air.toml index 9a39fb39021a5..110e099aee1f3 100644 --- a/scripts/.air.toml +++ b/scripts/.air.toml @@ -3,7 +3,7 @@ tmp_dir = ".air" [build] bin = "./.air/memos --mode dev" -cmd = "go build -o ./.air/memos ./main.go" +cmd = "go build -o ./.air/memos ./bin/memos/main.go" delay = 1000 exclude_dir = [".air", "web", "build"] include_ext = ["go", "mod", "sum"] diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 59991c5504cd1..052b5c52efbaa 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -43,6 +43,7 @@ if ([string]::IsNullOrWhiteSpace($repoRoot)) { Write-Host "Repository root: " -NoNewline Write-Host $repoRoot -f Blue +Push-Location Set-Location "$repoRoot/web" if (-not (Get-Command pnpm -ErrorAction SilentlyContinue)) { @@ -50,6 +51,7 @@ if (-not (Get-Command pnpm -ErrorAction SilentlyContinue)) { npm install -g pnpm if (!$?) { Write-Host -BackgroundColor red -ForegroundColor white "Could not install pnpm. See above." + Pop-Location Exit 1 } } @@ -58,43 +60,37 @@ Write-Host "`nInstalling frontend dependencies..." -f DarkYellow pnpm i --frozen-lockfile if (!$?) { Write-Host -BackgroundColor red -ForegroundColor white "Could not install frontend dependencies. See above." + Pop-Location Exit 1 } Write-Host "Frontend dependencies installed!" -f green -Write-Host "`nBuilding frontend..." -f DarkYellow -$frontendTime = Measure-Command { - &pnpm build | Out-Host -} +Write-Host "`nRemoving previous frontend build from ./build/dist ..." -f Magenta +Remove-Item "$repoRoot/build/dist" -Recurse -Force -ErrorAction SilentlyContinue if (!$?) { - Write-Host -BackgroundColor red -ForegroundColor white "Could not build frontend. See above." + Write-Host -BackgroundColor red -ForegroundColor white "Could not remove frontend from ./build/dist. See above." + Pop-Location Exit 1 -} else { - Write-Host "Frontend built!" -f green } -Write-Host "`nGenerating buf types..." -f DarkYellow +Write-Host "`nBuilding frontend..." -f DarkYellow $frontendTime = Measure-Command { - &pnpm type-gen | Out-Host + &pnpm build | Out-Host } if (!$?) { - Write-Host -BackgroundColor red -ForegroundColor white "Could not generate buf types. See above." + Write-Host -BackgroundColor red -ForegroundColor white "Could not build frontend. See above." + Pop-Location Exit 1 -} else { - Write-Host "buf types generated!" -f green } - -Write-Host "`nBacking up frontend placeholder..." -f Magenta -Move-Item "$repoRoot/server/dist" "$repoRoot/server/dist.bak" -Force -ErrorAction Stop -if (!$?) { - Write-Host -BackgroundColor red -ForegroundColor white "Could not backup frontend placeholder. See above." - Exit 1 +else { + Write-Host "Frontend built!" -f green } -Write-Host "Moving frontend build to ./server/dist..." -f Magenta -Move-Item "$repoRoot/web/dist" "$repoRoot/server/" -Force -ErrorAction Stop +Write-Host "Moving frontend build to ./build/dist..." -f Magenta +Move-Item "$repoRoot/web/dist" "$repoRoot/build/" -Force -ErrorAction Stop if (!$?) { - Write-Host -BackgroundColor red -ForegroundColor white "Could not move frontend build to /server/dist. See above." + Write-Host -BackgroundColor red -ForegroundColor white "Could not move frontend build to ./build/dist. See above." + Pop-Location Exit 1 } @@ -114,7 +110,7 @@ $backendTime = Measure-Command { } Write-Host "Building $os/$arch to $output..." -f Blue - &go build -trimpath -o $output -ldflags="$($ldFlags -join " ")" ./main.go | Out-Host + &go build -trimpath -o $output -ldflags="$($ldFlags -join " ")" ./bin/memos/main.go | Out-Host if (!$?) { Write-Host -BackgroundColor red -ForegroundColor white "'go build' failed for $build ($outputBinary)!. See above." continue @@ -126,20 +122,6 @@ Write-Host "Backend built!" -f green Write-Host "`nFrontend build took $($frontendTime.TotalSeconds) seconds." -f Cyan Write-Host "Backend builds took $($backendTime.TotalSeconds) seconds." -f Cyan -Write-Host "`nRemoving frontend from ./server/dist ..." -f Magenta -Remove-Item "$repoRoot/server/dist" -Recurse -Force -ErrorAction SilentlyContinue -if (!$?) { - Write-Host -BackgroundColor red -ForegroundColor white "Could not remove frontend from /server/dist. See above." - Exit 1 -} - -Write-Host "Restoring frontend placeholder..." -f Magenta -Move-Item "$repoRoot/server/dist.bak" "$repoRoot/server/dist" -Force -ErrorAction Stop -if (!$?) { - Write-Host -BackgroundColor red -ForegroundColor white "Could not restore frontend placeholder. See above." - Exit 1 -} - Write-Host "`nBuilds:" -f White foreach ($build in $goBuilds) { $output = [IO.Path]::Combine($repoRoot, "build", "memos-$os-$arch") diff --git a/scripts/build.sh b/scripts/build.sh index 91c768435d356..f030894641a15 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -11,7 +11,7 @@ # * node.js # * npm -# Usage: +# Usage: # chmod +x ./scripts/build.sh # ./scripts/build.sh # @@ -53,15 +53,15 @@ else echo -e "Repository root: \033[0;34m$repo_root\033[0m" fi - +pushd $repo_root cd "$repo_root/web" -if ! command -v pnpm &> /dev/null -then +if ! command -v pnpm &>/dev/null; then echo -e "\n\033[35mInstalling pnpm...\033[0m" npm install -g pnpm if [ $? -ne 0 ]; then echo -e "\033[0;31mFailed to install pnpm! Exiting.\033[0m" + popd exit 1 fi fi @@ -70,39 +70,35 @@ echo -e "\n\033[33mInstalling frontend dependencies...\033[0m" pnpm i --frozen-lockfile if [ $? -ne 0 ]; then echo -e "\033[0;31mFrontend dependencies failed to install! Exiting.\033[0m" + popd exit 1 fi echo -e "\033[32mFrontend dependencies installed!\033[0m" -echo -e "\n\033[33mGenerating buf types...\033[0m" -pnpm type-gen +echo -e "\n\033[35mRemoving previous frontend build from ./build/dist...\033[0m" +rm -rf $repo_root/build/dist if [ $? -ne 0 ]; then - echo -e "\033[0;31mCould not generate buf types! Exiting.\033[0m" + echo -e "\033[93mCould not remove frontend from ./build/dist.\033[0m" + popd exit 1 fi -echo -e "\033[32mbuf types generated!\033[0m" echo -e "\n\033[33mBuilding frontend...\033[0m" pnpm build if [ $? -ne 0 ]; then echo -e "\033[0;31mFrontend build failed! Exiting.\033[0m" + popd exit 1 fi echo -e "\033[32mFrontend built!\033[0m" cd $repo_root -echo -e "\n\033[35mBacking up frontend placeholder...\033[0m" -mv -f "$repo_root/server/dist" "$repo_root/server/dist.bak" -if [ $? -ne 0 ]; then - echo -e "\033[0;31mFailed to backup frontend placeholder! Exiting.\033[0m" - exit 1 -fi - -echo -e "\033[35mMoving frontend build to ./server/dist...\033[0m" -mv -f "$repo_root/web/dist" "$repo_root/server/" +echo -e "\033[35mMoving frontend build to ./build/dist...\033[0m" +mv -f "$repo_root/web/dist" "$repo_root/build/" if [ $? -ne 0 ]; then echo -e "\033[0;31mFailed to move frontend build! Exiting.\033[0m" + popd exit 1 fi @@ -117,11 +113,11 @@ for build in "${goBuilds[@]}"; do if [ "$os" = "windows" ]; then output="$output.exe" fi - - CGO_ENABLED=0 GOOS=$os GOARCH=$arch go build -trimpath -ldflags="${ldFlags[*]}" -o "$output" ./main.go + + CGO_ENABLED=0 GOOS=$os GOARCH=$arch go build -trimpath -ldflags="${ldFlags[*]}" -o "$output" ./bin/memos/main.go echo -e "\033[34mBuilding $os/$arch to $output...\033[0m" - GOOS=$os GOARCH=$arch go build -ldflags="${ldFlags[*]}" -o "./build/memos-$os-$arch" ./main.go + GOOS=$os GOARCH=$arch go build -ldflags="${ldFlags[*]}" -o "./build/memos-$os-$arch" ./bin/memos/main.go if [ $? -ne 0 ]; then echo -e "\033[0;31mgo build failed for $os/$arch($output)! See above.\033[0m" fi @@ -129,22 +125,6 @@ done echo -e "\033[32mBackend built!\033[0m" -echo -e "\n\033[35mRemoving frontend from ./server/dist...\033[0m" -rm -rf $repo_root/server/dist -if [ $? -ne 0 ] -then - echo -e "\033[93mCould not remove frontend from /server/dist.\033[0m" - exit 1 -fi - -echo -e "\033[35mRestoring frontend placeholder...\033[0m" -mv $repo_root/server/dist.bak $repo_root/server/dist -if [ $? -ne 0 ] -then - echo -e "\033[93mCould not restore frontend placeholder.\033e[0m" - exit 1 -fi - echo -e "\n\033[37mBuilds:\033[0m" for build in "${goBuilds[@]}"; do os=$(echo $build | cut -d'/' -f1) diff --git a/scripts/docker-compose.dev.yaml b/scripts/docker-compose.dev.yaml new file mode 100644 index 0000000000000..05abbf9cc7f63 --- /dev/null +++ b/scripts/docker-compose.dev.yaml @@ -0,0 +1,340 @@ +# > Memos development environment < +# +# Available profiles: sqlite, mysql, postgres. +# Use `docker compose --profile PROFILE_NAME up` to launch only services within the profile. +# +# Services in the `tools` profile are used for running one-off tasks like linting, generating code, etc. +# +# Services started in all database profiles: +# Front-end: http://localhost:3001 +# API: http://localhost:8081 +# Adminer: http://localhost:8091 +# +# On Windows, run this before using docker-compose on a new terminal: +# $Env:HOME=$Env:USERPROFILE +# +# > Start Memos in development mode: +# docker compose -f ./scripts/docker-compose.dev.yaml --profile [sqlite|mysql|postgres] up --detach +# +# > Stop all services: +# docker compose -f ./scripts/docker-compose.dev.yaml --profile sqlite --profile postgres --profile mysql down +# +# > Remove related volumes: (all other files are mapped to ./air/docker/ directory) +# docker volume rm memos-dev_pnpm-store memos-dev_node-modules +# +# One-off tasks: +# > pnpm: +# docker compose -f ./scripts/docker-compose.dev.yaml run --rm pnpm [add|remove|update] [PACKAGE_NAME] [--save-dev] +# +# > buf: (run this after modifying .proto files) +# docker compose -f ./scripts/docker-compose.dev.yaml run --rm buf generate +# +# > go: +# docker compose -f ./scripts/docker-compose.dev.yaml run --rm go mod tidy -go=1.22 +# +# > golangci-lint: (run this before submitting Pull Requests affecting Go code) +# docker compose -f ./scripts/docker-compose.dev.yaml run --rm golangci-lint run +# +# > goimports: (run this if golangci-lint shows "File is not `goimports`-ed" +# docker compose -f ./scripts/docker-compose.dev.yaml run --rm goimports -local https://github.com/usememos/memos -w [FILE|.] +# +version: "3.0" +name: memos-dev +volumes: + # pnpm uses hard links and node_modules uses symlinks. + # Using volumes make things work properly on any host OS. + node-modules: + pnpm-store: +services: + web: + profiles: ["sqlite", "mysql", "postgres"] + image: node:20-alpine + ports: [3001:3001] + environment: + DEV_PROXY_SERVER: http://api:8081/ + NPM_CONFIG_UPDATE_NOTIFIER: false + working_dir: &web-working-dir /work/web + entrypoint: ["/bin/sh", "-c"] + command: ["corepack enable && pnpm i --frozen-lockfile && pnpm dev"] + tmpfs: &web-tmpfs /work/node_modules/:exec # avoid ERR_PNPM_LINKING_FAILED + volumes: &web-volumes + - node-modules:/work/web/node_modules + - pnpm-store:/work/web/.pnpm-store + - ../proto:/work/proto + - ../web:/work/web + - ../web/node_modules:/work/web/node_modules + healthcheck: + test: ["CMD", "wget", "-qO", "-", "http://localhost:3001"] + interval: 10s + timeout: 5s + + api: + profiles: ["sqlite"] + image: &api-image golang:1.22-alpine + ports: &api-ports [8081:8081] + environment: + MEMOS_DRIVER: sqlite + MEMOS_DATA: /var/opt/memos + working_dir: &api-working-dir /work + volumes: &api-volumes + - $HOME/go/pkg/:/go/pkg/ # Share go mod cache with host + - ../.air/docker/go-build:/root/.cache/go-build + - ../.air/docker/go/bin:/go/bin + - ../.air/docker/memosdata:/var/opt/memos + - ..:/work/ + configs: &api-configs + - source: air-entrypoint.sh + target: /usr/local/bin/entrypoint.sh + entrypoint: &api-entrypoint ["/bin/sh", "/usr/local/bin/entrypoint.sh"] + command: &api-command ["-c", "./scripts/.air.toml"] + healthcheck: &api-healthcheck + test: ["CMD", "wget", "-qO", "-", "http://localhost:8081/api/v1/ping"] + interval: 10s + timeout: 5s + + api-mysql: + profiles: ["mysql"] + depends_on: { mysql: { condition: service_healthy } } + hostname: api + environment: + { MEMOS_DRIVER: mysql, MEMOS_DSN: memos:memos@tcp(mysql)/memos } + image: *api-image + ports: *api-ports + working_dir: *api-working-dir + volumes: *api-volumes + configs: *api-configs + entrypoint: *api-entrypoint + command: *api-command + healthcheck: *api-healthcheck + + api-postgres: + profiles: ["postgres"] + depends_on: { postgres: { condition: service_healthy } } + hostname: api + environment: + MEMOS_DSN: "postgresql://memos:memos@postgres:5432/memos?sslmode=disable" + MEMOS_DRIVER: postgres + image: *api-image + ports: *api-ports + working_dir: *api-working-dir + volumes: *api-volumes + configs: *api-configs + entrypoint: *api-entrypoint + command: *api-command + healthcheck: *api-healthcheck + + mysql: + profiles: ["mysql"] + image: mysql + environment: + MYSQL_USER: memos + MYSQL_PASSWORD: memos + MYSQL_DATABASE: memos + MYSQL_ALLOW_EMPTY_PASSWORD: "yes" + volumes: [../.air/docker/mysql:/var/lib/mysql] + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] + interval: 10s + timeout: 5s + + postgres: + profiles: ["postgres"] + image: postgres:alpine + hostname: postgres + volumes: [../.air/docker/postgres:/var/lib/postgresql/data] + environment: + { POSTGRES_DB: memos, POSTGRES_USER: memos, POSTGRES_PASSWORD: memos } + healthcheck: + test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + interval: 10s + timeout: 5s + + pnpm: + profiles: ["tools"] + image: node:20-alpine + environment: { NPM_CONFIG_UPDATE_NOTIFIER: false } + working_dir: *web-working-dir + volumes: *web-volumes + tmpfs: *web-tmpfs + configs: + - source: pnpm-entrypoint.sh + target: /usr/local/bin/entrypoint.sh + entrypoint: ["sh", "/usr/local/bin/entrypoint.sh"] + + buf: + profiles: ["tools"] + image: bufbuild/buf + working_dir: /work/proto + command: generate + volumes: + - ../proto:/work/proto + - ../web/src/types/:/work/web/src/types/ + + go: + profiles: ["tools"] + image: *api-image + working_dir: *api-working-dir + volumes: *api-volumes + entrypoint: ["go"] + + goimports: + profiles: ["tools"] + image: *api-image + working_dir: *api-working-dir + volumes: *api-volumes + configs: + - source: goimports-entrypoint.sh + target: /usr/local/bin/entrypoint.sh + entrypoint: ["/bin/sh", "/usr/local/bin/entrypoint.sh"] + + golangci-lint: + profiles: ["tools"] + image: *api-image + working_dir: *api-working-dir + volumes: *api-volumes + configs: + - source: golangci-lint-entrypoint.sh + target: /usr/local/bin/entrypoint.sh + entrypoint: ["/bin/sh", "/usr/local/bin/entrypoint.sh"] + + adminer-mysql: + profiles: ["mysql"] + depends_on: { mysql: { condition: service_healthy } } + image: adminer + environment: &adminer-environment + ADMINER_DEFAULT_DRIVER: server # "server" is mysql + ADMINER_DEFAULT_SERVER: mysql + ADMINER_DEFAULT_USERNAME: memos + ADMINER_DEFAULT_PASSWORD: memos + ADMINER_DEFAULT_DB: memos + ADMINER_DESIGN: dracula # light: pepa-linha | https://www.adminer.org/#extras + ADMINER_PLUGINS: tables-filter table-structure edit-textarea dump-json # https://www.adminer.org/en/plugins/ + ports: &adminer-ports [127.0.0.1:8091:8080] + healthcheck: &adminer-healthcheck + test: 'php -r "exit(strpos(file_get_contents(\"http://localhost:8080/\"), \"Adminer\") !== false ? 0 : 1);"' + interval: 10s + timeout: 5s + configs: &adminer-configs + - source: adminer-index.php + target: /var/www/html/index.php + + adminer-postgres: + profiles: ["postgres"] + depends_on: { postgres: { condition: service_healthy } } + image: adminer + ports: *adminer-ports + healthcheck: *adminer-healthcheck + configs: *adminer-configs + environment: + <<: *adminer-environment + ADMINER_DEFAULT_DRIVER: pgsql + ADMINER_DEFAULT_SERVER: postgres + + adminer-sqlite: + profiles: ["sqlite"] + image: adminer + ports: *adminer-ports + healthcheck: *adminer-healthcheck + configs: *adminer-configs + environment: + <<: *adminer-environment + ADMINER_DEFAULT_PASSWORD: "" + ADMINER_DEFAULT_DRIVER: sqlite + ADMINER_DEFAULT_DB: /data/memos_dev.db + volumes: [../.air/docker/memosdata:/data] + +configs: + # Patched version of adminer index.php to fill the login form with default values + # and allow passwordless login whenever ADMINER_DEFAULT_DRIVER is sqlite. + adminer-index.php: + content: | + MaxContentLength { + return nil, status.Errorf(codes.InvalidArgument, "content too long") + } + + create := &store.Memo{ + ResourceName: shortuuid.New(), + CreatorID: user.ID, + Content: request.Content, + Visibility: convertVisibilityToStore(request.Visibility), + } + // Find disable public memos system setting. + disablePublicMemosSystem, err := s.getDisablePublicMemosSystemSettingValue(ctx) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get system setting") + } + if disablePublicMemosSystem && create.Visibility == store.Public { + return nil, status.Errorf(codes.PermissionDenied, "disable public memos system setting is enabled") + } + + memo, err := s.Store.CreateMemo(ctx, create) + if err != nil { + return nil, err + } + + memoMessage, err := s.convertMemoFromStore(ctx, memo) + if err != nil { + return nil, errors.Wrap(err, "failed to convert memo") + } + // Try to dispatch webhook when memo is created. + if err := s.DispatchMemoCreatedWebhook(ctx, memoMessage); err != nil { + slog.Warn("Failed to dispatch memo created webhook", err) + } + + response := &apiv2pb.CreateMemoResponse{ + Memo: memoMessage, + } + return response, nil +} + +func (s *APIV2Service) ListMemos(ctx context.Context, request *apiv2pb.ListMemosRequest) (*apiv2pb.ListMemosResponse, error) { + memoFind := &store.FindMemo{ + // Exclude comments by default. + ExcludeComments: true, + } + if err := s.buildMemoFindWithFilter(ctx, memoFind, request.Filter); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "failed to build find memos with filter") + } + + var limit, offset int + if request.PageToken != "" { + var pageToken apiv2pb.PageToken + if err := unmarshalPageToken(request.PageToken, &pageToken); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid page token: %v", err) + } + limit = int(pageToken.Limit) + offset = int(pageToken.Offset) + } else { + limit = int(request.PageSize) + } + if limit <= 0 { + limit = DefaultPageSize + } + limitPlusOne := limit + 1 + memoFind.Limit = &limitPlusOne + memoFind.Offset = &offset + memos, err := s.Store.ListMemos(ctx, memoFind) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to list memos") + } + + memoMessages := []*apiv2pb.Memo{} + nextPageToken := "" + if len(memos) == limitPlusOne { + memos = memos[:limit] + nextPageToken, err = getPageToken(limit, offset+limit) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get next page token, error: %v", err) + } + } + for _, memo := range memos { + memoMessage, err := s.convertMemoFromStore(ctx, memo) + if err != nil { + return nil, errors.Wrap(err, "failed to convert memo") + } + memoMessages = append(memoMessages, memoMessage) + } + + response := &apiv2pb.ListMemosResponse{ + Memos: memoMessages, + NextPageToken: nextPageToken, + } + return response, nil +} + +func (s *APIV2Service) GetMemo(ctx context.Context, request *apiv2pb.GetMemoRequest) (*apiv2pb.GetMemoResponse, error) { + memo, err := s.Store.GetMemo(ctx, &store.FindMemo{ + ID: &request.Id, + }) + if err != nil { + return nil, err + } + if memo == nil { + return nil, status.Errorf(codes.NotFound, "memo not found") + } + if memo.Visibility != store.Public { + user, err := getCurrentUser(ctx, s.Store) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user") + } + if user == nil { + return nil, status.Errorf(codes.PermissionDenied, "permission denied") + } + if memo.Visibility == store.Private && memo.CreatorID != user.ID { + return nil, status.Errorf(codes.PermissionDenied, "permission denied") + } + } + + memoMessage, err := s.convertMemoFromStore(ctx, memo) + if err != nil { + return nil, errors.Wrap(err, "failed to convert memo") + } + response := &apiv2pb.GetMemoResponse{ + Memo: memoMessage, + } + return response, nil +} + +func (s *APIV2Service) GetMemoByName(ctx context.Context, request *apiv2pb.GetMemoByNameRequest) (*apiv2pb.GetMemoByNameResponse, error) { + memo, err := s.Store.GetMemo(ctx, &store.FindMemo{ + ResourceName: &request.Name, + }) + if err != nil { + return nil, err + } + if memo == nil { + return nil, status.Errorf(codes.NotFound, "memo not found") + } + if memo.Visibility != store.Public { + user, err := getCurrentUser(ctx, s.Store) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user") + } + if user == nil { + return nil, status.Errorf(codes.PermissionDenied, "permission denied") + } + if memo.Visibility == store.Private && memo.CreatorID != user.ID { + return nil, status.Errorf(codes.PermissionDenied, "permission denied") + } + } + + memoMessage, err := s.convertMemoFromStore(ctx, memo) + if err != nil { + return nil, errors.Wrap(err, "failed to convert memo") + } + response := &apiv2pb.GetMemoByNameResponse{ + Memo: memoMessage, + } + return response, nil +} + +func (s *APIV2Service) UpdateMemo(ctx context.Context, request *apiv2pb.UpdateMemoRequest) (*apiv2pb.UpdateMemoResponse, error) { + if request.UpdateMask == nil || len(request.UpdateMask.Paths) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "update mask is required") + } + + memo, err := s.Store.GetMemo(ctx, &store.FindMemo{ + ID: &request.Memo.Id, + }) + if err != nil { + return nil, err + } + if memo == nil { + return nil, status.Errorf(codes.NotFound, "memo not found") + } + + user, _ := getCurrentUser(ctx, s.Store) + if memo.CreatorID != user.ID { + return nil, status.Errorf(codes.PermissionDenied, "permission denied") + } + + currentTs := time.Now().Unix() + update := &store.UpdateMemo{ + ID: request.Memo.Id, + UpdatedTs: ¤tTs, + } + for _, path := range request.UpdateMask.Paths { + if path == "content" { + update.Content = &request.Memo.Content + } else if path == "resource_name" { + update.ResourceName = &request.Memo.Name + if !util.ResourceNameMatcher.MatchString(*update.ResourceName) { + return nil, status.Errorf(codes.InvalidArgument, "invalid resource name") + } + } else if path == "visibility" { + visibility := convertVisibilityToStore(request.Memo.Visibility) + // Find disable public memos system setting. + disablePublicMemosSystem, err := s.getDisablePublicMemosSystemSettingValue(ctx) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get system setting") + } + if disablePublicMemosSystem && visibility == store.Public { + return nil, status.Errorf(codes.PermissionDenied, "disable public memos system setting is enabled") + } + update.Visibility = &visibility + } else if path == "row_status" { + rowStatus := convertRowStatusToStore(request.Memo.RowStatus) + update.RowStatus = &rowStatus + } else if path == "created_ts" { + createdTs := request.Memo.CreateTime.AsTime().Unix() + update.CreatedTs = &createdTs + } else if path == "pinned" { + if _, err := s.Store.UpsertMemoOrganizer(ctx, &store.MemoOrganizer{ + MemoID: request.Memo.Id, + UserID: user.ID, + Pinned: request.Memo.Pinned, + }); err != nil { + return nil, status.Errorf(codes.Internal, "failed to upsert memo organizer") + } + } + } + if update.Content != nil && len(*update.Content) > MaxContentLength { + return nil, status.Errorf(codes.InvalidArgument, "content too long") + } + + if err = s.Store.UpdateMemo(ctx, update); err != nil { + return nil, status.Errorf(codes.Internal, "failed to update memo") + } + + memo, err = s.Store.GetMemo(ctx, &store.FindMemo{ + ID: &request.Memo.Id, + }) + if err != nil { + return nil, errors.Wrap(err, "failed to get memo") + } + memoMessage, err := s.convertMemoFromStore(ctx, memo) + if err != nil { + return nil, errors.Wrap(err, "failed to convert memo") + } + // Try to dispatch webhook when memo is updated. + if err := s.DispatchMemoUpdatedWebhook(ctx, memoMessage); err != nil { + slog.Warn("Failed to dispatch memo updated webhook", err) + } + + return &apiv2pb.UpdateMemoResponse{ + Memo: memoMessage, + }, nil +} + +func (s *APIV2Service) DeleteMemo(ctx context.Context, request *apiv2pb.DeleteMemoRequest) (*apiv2pb.DeleteMemoResponse, error) { + memo, err := s.Store.GetMemo(ctx, &store.FindMemo{ + ID: &request.Id, + }) + if err != nil { + return nil, err + } + if memo == nil { + return nil, status.Errorf(codes.NotFound, "memo not found") + } + + user, _ := getCurrentUser(ctx, s.Store) + if memo.CreatorID != user.ID { + return nil, status.Errorf(codes.PermissionDenied, "permission denied") + } + + if memoMessage, err := s.convertMemoFromStore(ctx, memo); err == nil { + // Try to dispatch webhook when memo is deleted. + if err := s.DispatchMemoDeletedWebhook(ctx, memoMessage); err != nil { + slog.Warn("Failed to dispatch memo deleted webhook", err) + } + } + + if err = s.Store.DeleteMemo(ctx, &store.DeleteMemo{ + ID: request.Id, + }); err != nil { + return nil, status.Errorf(codes.Internal, "failed to delete memo") + } + + return &apiv2pb.DeleteMemoResponse{}, nil +} + +func (s *APIV2Service) CreateMemoComment(ctx context.Context, request *apiv2pb.CreateMemoCommentRequest) (*apiv2pb.CreateMemoCommentResponse, error) { + relatedMemo, err := s.Store.GetMemo(ctx, &store.FindMemo{ID: &request.Id}) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get memo") + } + + // Create the comment memo first. + createMemoResponse, err := s.CreateMemo(ctx, request.Create) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to create memo") + } + + // Build the relation between the comment memo and the original memo. + memo := createMemoResponse.Memo + _, err = s.Store.UpsertMemoRelation(ctx, &store.MemoRelation{ + MemoID: memo.Id, + RelatedMemoID: request.Id, + Type: store.MemoRelationComment, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to create memo relation") + } + if memo.Visibility != apiv2pb.Visibility_PRIVATE && memo.CreatorId != relatedMemo.CreatorID { + activity, err := s.Store.CreateActivity(ctx, &store.Activity{ + CreatorID: memo.CreatorId, + Type: store.ActivityTypeMemoComment, + Level: store.ActivityLevelInfo, + Payload: &storepb.ActivityPayload{ + MemoComment: &storepb.ActivityMemoCommentPayload{ + MemoId: memo.Id, + RelatedMemoId: request.Id, + }, + }, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to create activity") + } + if _, err := s.Store.CreateInbox(ctx, &store.Inbox{ + SenderID: memo.CreatorId, + ReceiverID: relatedMemo.CreatorID, + Status: store.UNREAD, + Message: &storepb.InboxMessage{ + Type: storepb.InboxMessage_TYPE_MEMO_COMMENT, + ActivityId: &activity.ID, + }, + }); err != nil { + return nil, status.Errorf(codes.Internal, "failed to create inbox") + } + } + + response := &apiv2pb.CreateMemoCommentResponse{ + Memo: memo, + } + return response, nil +} + +func (s *APIV2Service) ListMemoComments(ctx context.Context, request *apiv2pb.ListMemoCommentsRequest) (*apiv2pb.ListMemoCommentsResponse, error) { + memoRelationComment := store.MemoRelationComment + memoRelations, err := s.Store.ListMemoRelations(ctx, &store.FindMemoRelation{ + RelatedMemoID: &request.Id, + Type: &memoRelationComment, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to list memo relations") + } + + var memos []*apiv2pb.Memo + for _, memoRelation := range memoRelations { + memo, err := s.Store.GetMemo(ctx, &store.FindMemo{ + ID: &memoRelation.MemoID, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get memo") + } + if memo != nil { + memoMessage, err := s.convertMemoFromStore(ctx, memo) + if err != nil { + return nil, errors.Wrap(err, "failed to convert memo") + } + memos = append(memos, memoMessage) + } + } + + response := &apiv2pb.ListMemoCommentsResponse{ + Memos: memos, + } + return response, nil +} + +func (s *APIV2Service) GetUserMemosStats(ctx context.Context, request *apiv2pb.GetUserMemosStatsRequest) (*apiv2pb.GetUserMemosStatsResponse, error) { + username, err := ExtractUsernameFromName(request.Name) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid username") + } + user, err := s.Store.GetUser(ctx, &store.FindUser{ + Username: &username, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user") + } + if user == nil { + return nil, status.Errorf(codes.NotFound, "user not found") + } + + normalRowStatus := store.Normal + memoFind := &store.FindMemo{ + CreatorID: &user.ID, + RowStatus: &normalRowStatus, + ExcludeComments: true, + ExcludeContent: true, + } + if err := s.buildMemoFindWithFilter(ctx, memoFind, request.Filter); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "failed to build find memos with filter") + } + + memos, err := s.Store.ListMemos(ctx, memoFind) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to list memos") + } + + location, err := time.LoadLocation(request.Timezone) + if err != nil { + return nil, status.Errorf(codes.Internal, "invalid timezone location") + } + + displayWithUpdatedTs, err := s.getMemoDisplayWithUpdatedTsSettingValue(ctx) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get memo display with updated ts setting value") + } + stats := make(map[string]int32) + for _, memo := range memos { + displayTs := memo.CreatedTs + if displayWithUpdatedTs { + displayTs = memo.UpdatedTs + } + stats[time.Unix(displayTs, 0).In(location).Format("2006-01-02")]++ + } + + response := &apiv2pb.GetUserMemosStatsResponse{ + Stats: stats, + } + return response, nil +} + +func (s *APIV2Service) ExportMemos(ctx context.Context, request *apiv2pb.ExportMemosRequest) (*apiv2pb.ExportMemosResponse, error) { + normalRowStatus := store.Normal + memoFind := &store.FindMemo{ + RowStatus: &normalRowStatus, + // Exclude comments by default. + ExcludeComments: true, + } + if err := s.buildMemoFindWithFilter(ctx, memoFind, request.Filter); err != nil { + return nil, status.Errorf(codes.Internal, "failed to build find memos with filter") + } + + memos, err := s.Store.ListMemos(ctx, memoFind) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to list memos") + } + + buf := new(bytes.Buffer) + writer := zip.NewWriter(buf) + for _, memo := range memos { + memoMessage, err := s.convertMemoFromStore(ctx, memo) + if err != nil { + return nil, errors.Wrap(err, "failed to convert memo") + } + file, err := writer.Create(time.Unix(memo.CreatedTs, 0).Format(time.RFC3339) + ".md") + if err != nil { + return nil, status.Errorf(codes.Internal, "Failed to create memo file") + } + _, err = file.Write([]byte(memoMessage.Content)) + if err != nil { + return nil, status.Errorf(codes.Internal, "Failed to write to memo file") + } + } + if err := writer.Close(); err != nil { + return nil, status.Errorf(codes.Internal, "Failed to close zip file writer") + } + + return &apiv2pb.ExportMemosResponse{ + Content: buf.Bytes(), + }, nil +} + +func (s *APIV2Service) convertMemoFromStore(ctx context.Context, memo *store.Memo) (*apiv2pb.Memo, error) { + displayTs := memo.CreatedTs + if displayWithUpdatedTs, err := s.getMemoDisplayWithUpdatedTsSettingValue(ctx); err == nil && displayWithUpdatedTs { + displayTs = memo.UpdatedTs + } + + creator, err := s.Store.GetUser(ctx, &store.FindUser{ID: &memo.CreatorID}) + if err != nil { + return nil, errors.Wrap(err, "failed to get creator") + } + + listMemoRelationsResponse, err := s.ListMemoRelations(ctx, &apiv2pb.ListMemoRelationsRequest{Id: memo.ID}) + if err != nil { + return nil, errors.Wrap(err, "failed to list memo relations") + } + + listMemoResourcesResponse, err := s.ListMemoResources(ctx, &apiv2pb.ListMemoResourcesRequest{Id: memo.ID}) + if err != nil { + return nil, errors.Wrap(err, "failed to list memo resources") + } + + listMemoReactionsResponse, err := s.ListMemoReactions(ctx, &apiv2pb.ListMemoReactionsRequest{Id: memo.ID}) + if err != nil { + return nil, errors.Wrap(err, "failed to list memo reactions") + } + + return &apiv2pb.Memo{ + Id: int32(memo.ID), + Name: memo.ResourceName, + RowStatus: convertRowStatusFromStore(memo.RowStatus), + Creator: fmt.Sprintf("%s%s", UserNamePrefix, creator.Username), + CreatorId: int32(memo.CreatorID), + CreateTime: timestamppb.New(time.Unix(memo.CreatedTs, 0)), + UpdateTime: timestamppb.New(time.Unix(memo.UpdatedTs, 0)), + DisplayTime: timestamppb.New(time.Unix(displayTs, 0)), + Content: memo.Content, + Visibility: convertVisibilityFromStore(memo.Visibility), + Pinned: memo.Pinned, + ParentId: memo.ParentID, + Relations: listMemoRelationsResponse.Relations, + Resources: listMemoResourcesResponse.Resources, + Reactions: listMemoReactionsResponse.Reactions, + }, nil +} + +func (s *APIV2Service) getMemoDisplayWithUpdatedTsSettingValue(ctx context.Context) (bool, error) { + memoDisplayWithUpdatedTsSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{ + Name: apiv1.SystemSettingMemoDisplayWithUpdatedTsName.String(), + }) + if err != nil { + return false, errors.Wrap(err, "failed to find system setting") + } + if memoDisplayWithUpdatedTsSetting == nil { + return false, nil + } + + memoDisplayWithUpdatedTs := false + if err := json.Unmarshal([]byte(memoDisplayWithUpdatedTsSetting.Value), &memoDisplayWithUpdatedTs); err != nil { + return false, errors.Wrap(err, "failed to unmarshal system setting value") + } + return memoDisplayWithUpdatedTs, nil +} + +func (s *APIV2Service) getDisablePublicMemosSystemSettingValue(ctx context.Context) (bool, error) { + disablePublicMemosSystemSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{ + Name: apiv1.SystemSettingDisablePublicMemosName.String(), + }) + if err != nil { + return false, errors.Wrap(err, "failed to find system setting") + } + if disablePublicMemosSystemSetting == nil { + return false, nil + } + + disablePublicMemos := false + if err := json.Unmarshal([]byte(disablePublicMemosSystemSetting.Value), &disablePublicMemos); err != nil { + return false, errors.Wrap(err, "failed to unmarshal system setting value") + } + return disablePublicMemos, nil +} + +func convertVisibilityFromStore(visibility store.Visibility) apiv2pb.Visibility { + switch visibility { + case store.Private: + return apiv2pb.Visibility_PRIVATE + case store.Protected: + return apiv2pb.Visibility_PROTECTED + case store.Public: + return apiv2pb.Visibility_PUBLIC + default: + return apiv2pb.Visibility_VISIBILITY_UNSPECIFIED + } +} + +func convertVisibilityToStore(visibility apiv2pb.Visibility) store.Visibility { + switch visibility { + case apiv2pb.Visibility_PRIVATE: + return store.Private + case apiv2pb.Visibility_PROTECTED: + return store.Protected + case apiv2pb.Visibility_PUBLIC: + return store.Public + default: + return store.Private + } +} + +func (s *APIV2Service) buildMemoFindWithFilter(ctx context.Context, find *store.FindMemo, filter string) error { + user, _ := getCurrentUser(ctx, s.Store) + if find == nil { + find = &store.FindMemo{} + } + if filter != "" { + filter, err := parseListMemosFilter(filter) + if err != nil { + return status.Errorf(codes.InvalidArgument, "invalid filter: %v", err) + } + if len(filter.ContentSearch) > 0 { + find.ContentSearch = filter.ContentSearch + } + if len(filter.Visibilities) > 0 { + find.VisibilityList = filter.Visibilities + } + if filter.OrderByPinned { + find.OrderByPinned = filter.OrderByPinned + } + if filter.DisplayTimeAfter != nil { + displayWithUpdatedTs, err := s.getMemoDisplayWithUpdatedTsSettingValue(ctx) + if err != nil { + return status.Errorf(codes.Internal, "failed to get memo display with updated ts setting value") + } + if displayWithUpdatedTs { + find.UpdatedTsAfter = filter.DisplayTimeAfter + } else { + find.CreatedTsAfter = filter.DisplayTimeAfter + } + } + if filter.DisplayTimeBefore != nil { + displayWithUpdatedTs, err := s.getMemoDisplayWithUpdatedTsSettingValue(ctx) + if err != nil { + return status.Errorf(codes.Internal, "failed to get memo display with updated ts setting value") + } + if displayWithUpdatedTs { + find.UpdatedTsBefore = filter.DisplayTimeBefore + } else { + find.CreatedTsBefore = filter.DisplayTimeBefore + } + } + if filter.Creator != nil { + username, err := ExtractUsernameFromName(*filter.Creator) + if err != nil { + return status.Errorf(codes.InvalidArgument, "invalid creator name") + } + user, err := s.Store.GetUser(ctx, &store.FindUser{ + Username: &username, + }) + if err != nil { + return status.Errorf(codes.Internal, "failed to get user") + } + if user == nil { + return status.Errorf(codes.NotFound, "user not found") + } + find.CreatorID = &user.ID + } + if filter.RowStatus != nil { + find.RowStatus = filter.RowStatus + } + } + + // If the user is not authenticated, only public memos are visible. + if user == nil { + if filter == "" { + // If no filter is provided, return an error. + return status.Errorf(codes.InvalidArgument, "filter is required") + } + + find.VisibilityList = []store.Visibility{store.Public} + } else if find.CreatorID != nil && *find.CreatorID != user.ID { + find.VisibilityList = []store.Visibility{store.Public, store.Protected} + } + + displayWithUpdatedTs, err := s.getMemoDisplayWithUpdatedTsSettingValue(ctx) + if err != nil { + return status.Errorf(codes.Internal, "failed to get memo display with updated ts setting value") + } + if displayWithUpdatedTs { + find.OrderByUpdatedTs = true + } + return nil +} + +// ListMemosFilterCELAttributes are the CEL attributes for ListMemosFilter. +var ListMemosFilterCELAttributes = []cel.EnvOption{ + cel.Variable("content_search", cel.ListType(cel.StringType)), + cel.Variable("visibilities", cel.ListType(cel.StringType)), + cel.Variable("order_by_pinned", cel.BoolType), + cel.Variable("display_time_before", cel.IntType), + cel.Variable("display_time_after", cel.IntType), + cel.Variable("creator", cel.StringType), + cel.Variable("row_status", cel.StringType), +} + +type ListMemosFilter struct { + ContentSearch []string + Visibilities []store.Visibility + OrderByPinned bool + DisplayTimeBefore *int64 + DisplayTimeAfter *int64 + Creator *string + RowStatus *store.RowStatus +} + +func parseListMemosFilter(expression string) (*ListMemosFilter, error) { + e, err := cel.NewEnv(ListMemosFilterCELAttributes...) + if err != nil { + return nil, err + } + ast, issues := e.Compile(expression) + if issues != nil { + return nil, errors.Errorf("found issue %v", issues) + } + filter := &ListMemosFilter{} + expr, err := cel.AstToParsedExpr(ast) + if err != nil { + return nil, err + } + callExpr := expr.GetExpr().GetCallExpr() + findField(callExpr, filter) + return filter, nil +} + +func findField(callExpr *expr.Expr_Call, filter *ListMemosFilter) { + if len(callExpr.Args) == 2 { + idExpr := callExpr.Args[0].GetIdentExpr() + if idExpr != nil { + if idExpr.Name == "content_search" { + contentSearch := []string{} + for _, expr := range callExpr.Args[1].GetListExpr().GetElements() { + value := expr.GetConstExpr().GetStringValue() + contentSearch = append(contentSearch, value) + } + filter.ContentSearch = contentSearch + } else if idExpr.Name == "visibilities" { + visibilities := []store.Visibility{} + for _, expr := range callExpr.Args[1].GetListExpr().GetElements() { + value := expr.GetConstExpr().GetStringValue() + visibilities = append(visibilities, store.Visibility(value)) + } + filter.Visibilities = visibilities + } else if idExpr.Name == "order_by_pinned" { + value := callExpr.Args[1].GetConstExpr().GetBoolValue() + filter.OrderByPinned = value + } else if idExpr.Name == "display_time_before" { + displayTimeBefore := callExpr.Args[1].GetConstExpr().GetInt64Value() + filter.DisplayTimeBefore = &displayTimeBefore + } else if idExpr.Name == "display_time_after" { + displayTimeAfter := callExpr.Args[1].GetConstExpr().GetInt64Value() + filter.DisplayTimeAfter = &displayTimeAfter + } else if idExpr.Name == "creator" { + creator := callExpr.Args[1].GetConstExpr().GetStringValue() + filter.Creator = &creator + } else if idExpr.Name == "row_status" { + rowStatus := store.RowStatus(callExpr.Args[1].GetConstExpr().GetStringValue()) + filter.RowStatus = &rowStatus + } + return + } + } + for _, arg := range callExpr.Args { + callExpr := arg.GetCallExpr() + if callExpr != nil { + findField(callExpr, filter) + } + } +} + +// DispatchMemoCreatedWebhook dispatches webhook when memo is created. +func (s *APIV2Service) DispatchMemoCreatedWebhook(ctx context.Context, memo *apiv2pb.Memo) error { + return s.dispatchMemoRelatedWebhook(ctx, memo, "memos.memo.created") +} + +// DispatchMemoUpdatedWebhook dispatches webhook when memo is updated. +func (s *APIV2Service) DispatchMemoUpdatedWebhook(ctx context.Context, memo *apiv2pb.Memo) error { + return s.dispatchMemoRelatedWebhook(ctx, memo, "memos.memo.updated") +} + +// DispatchMemoDeletedWebhook dispatches webhook when memo is deleted. +func (s *APIV2Service) DispatchMemoDeletedWebhook(ctx context.Context, memo *apiv2pb.Memo) error { + return s.dispatchMemoRelatedWebhook(ctx, memo, "memos.memo.deleted") +} + +func (s *APIV2Service) dispatchMemoRelatedWebhook(ctx context.Context, memo *apiv2pb.Memo, activityType string) error { + webhooks, err := s.Store.ListWebhooks(ctx, &store.FindWebhook{ + CreatorID: &memo.CreatorId, + }) + if err != nil { + return err + } + for _, hook := range webhooks { + payload := convertMemoToWebhookPayload(memo) + payload.ActivityType = activityType + payload.URL = hook.Url + err := webhook.Post(*payload) + if err != nil { + return errors.Wrap(err, "failed to post webhook") + } + } + return nil +} + +func convertMemoToWebhookPayload(memo *apiv2pb.Memo) *webhook.WebhookPayload { + return &webhook.WebhookPayload{ + CreatorID: memo.CreatorId, + CreatedTs: time.Now().Unix(), + Memo: &webhook.Memo{ + ID: memo.Id, + CreatorID: memo.CreatorId, + CreatedTs: memo.CreateTime.Seconds, + UpdatedTs: memo.UpdateTime.Seconds, + Content: memo.Content, + Visibility: memo.Visibility.String(), + Pinned: memo.Pinned, + ResourceList: func() []*webhook.Resource { + resources := []*webhook.Resource{} + for _, resource := range memo.Resources { + resources = append(resources, &webhook.Resource{ + ID: resource.Id, + Filename: resource.Filename, + ExternalLink: resource.ExternalLink, + Type: resource.Type, + Size: resource.Size, + }) + } + return resources + }(), + RelationList: func() []*webhook.MemoRelation { + relations := []*webhook.MemoRelation{} + for _, relation := range memo.Relations { + relations = append(relations, &webhook.MemoRelation{ + MemoID: relation.MemoId, + RelatedMemoID: relation.RelatedMemoId, + Type: relation.Type.String(), + }) + } + return relations + }(), + }, + } +} diff --git a/server/route/api/v2/reaction_service.go b/server/route/api/v2/reaction_service.go new file mode 100644 index 0000000000000..8a507bc2d2d84 --- /dev/null +++ b/server/route/api/v2/reaction_service.go @@ -0,0 +1,83 @@ +package v2 + +import ( + "context" + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + apiv2pb "github.com/usememos/memos/proto/gen/api/v2" + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (s *APIV2Service) ListMemoReactions(ctx context.Context, request *apiv2pb.ListMemoReactionsRequest) (*apiv2pb.ListMemoReactionsResponse, error) { + contentID := fmt.Sprintf("memos/%d", request.Id) + reactions, err := s.Store.ListReactions(ctx, &store.FindReaction{ + ContentID: &contentID, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to list reactions") + } + + response := &apiv2pb.ListMemoReactionsResponse{ + Reactions: []*apiv2pb.Reaction{}, + } + for _, reaction := range reactions { + reactionMessage, err := s.convertReactionFromStore(ctx, reaction) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to convert reaction") + } + response.Reactions = append(response.Reactions, reactionMessage) + } + return response, nil +} + +func (s *APIV2Service) UpsertMemoReaction(ctx context.Context, request *apiv2pb.UpsertMemoReactionRequest) (*apiv2pb.UpsertMemoReactionResponse, error) { + user, err := getCurrentUser(ctx, s.Store) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get current user") + } + reaction, err := s.Store.UpsertReaction(ctx, &storepb.Reaction{ + CreatorId: user.ID, + ContentId: request.Reaction.ContentId, + ReactionType: storepb.Reaction_Type(request.Reaction.ReactionType), + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to upsert reaction") + } + + reactionMessage, err := s.convertReactionFromStore(ctx, reaction) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to convert reaction") + } + return &apiv2pb.UpsertMemoReactionResponse{ + Reaction: reactionMessage, + }, nil +} + +func (s *APIV2Service) DeleteMemoReaction(ctx context.Context, request *apiv2pb.DeleteMemoReactionRequest) (*apiv2pb.DeleteMemoReactionResponse, error) { + if err := s.Store.DeleteReaction(ctx, &store.DeleteReaction{ + ID: request.Id, + }); err != nil { + return nil, status.Errorf(codes.Internal, "failed to delete reaction") + } + + return &apiv2pb.DeleteMemoReactionResponse{}, nil +} + +func (s *APIV2Service) convertReactionFromStore(ctx context.Context, reaction *storepb.Reaction) (*apiv2pb.Reaction, error) { + creator, err := s.Store.GetUser(ctx, &store.FindUser{ + ID: &reaction.CreatorId, + }) + if err != nil { + return nil, err + } + return &apiv2pb.Reaction{ + Id: reaction.Id, + Creator: fmt.Sprintf("%s%s", UserNamePrefix, creator.Username), + ContentId: reaction.ContentId, + ReactionType: apiv2pb.Reaction_Type(reaction.ReactionType), + }, nil +} diff --git a/api/v2/resource_name.go b/server/route/api/v2/resource_name.go similarity index 59% rename from api/v2/resource_name.go rename to server/route/api/v2/resource_name.go index a12231f58bb7d..a2987dfbd3bbb 100644 --- a/api/v2/resource_name.go +++ b/server/route/api/v2/resource_name.go @@ -10,7 +10,9 @@ import ( ) const ( - InboxNamePrefix = "inboxes/" + WorkspaceSettingNamePrefix = "settings/" + UserNamePrefix = "users/" + InboxNamePrefix = "inboxes/" ) // GetNameParentTokens returns the tokens from a resource name. @@ -33,8 +35,25 @@ func GetNameParentTokens(name string, tokenPrefixes ...string) ([]string, error) return tokens, nil } -// GetInboxID returns the inbox ID from a resource name. -func GetInboxID(name string) (int32, error) { +func ExtractWorkspaceSettingKeyFromName(name string) (string, error) { + tokens, err := GetNameParentTokens(name, WorkspaceSettingNamePrefix) + if err != nil { + return "", err + } + return tokens[0], nil +} + +// ExtractUsernameFromName returns the username from a resource name. +func ExtractUsernameFromName(name string) (string, error) { + tokens, err := GetNameParentTokens(name, UserNamePrefix) + if err != nil { + return "", err + } + return tokens[0], nil +} + +// ExtractInboxIDFromName returns the inbox ID from a resource name. +func ExtractInboxIDFromName(name string) (int32, error) { tokens, err := GetNameParentTokens(name, InboxNamePrefix) if err != nil { return 0, err diff --git a/api/v2/resource_service.go b/server/route/api/v2/resource_service.go similarity index 56% rename from api/v2/resource_service.go rename to server/route/api/v2/resource_service.go index 2ad7ad0e522d6..88c25690f59db 100644 --- a/api/v2/resource_service.go +++ b/server/route/api/v2/resource_service.go @@ -2,8 +2,10 @@ package v2 import ( "context" + "net/url" "time" + "github.com/lithammer/shortuuid/v4" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" @@ -12,6 +14,42 @@ import ( "github.com/usememos/memos/store" ) +func (s *APIV2Service) CreateResource(ctx context.Context, request *apiv2pb.CreateResourceRequest) (*apiv2pb.CreateResourceResponse, error) { + user, err := getCurrentUser(ctx, s.Store) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err) + } + if request.ExternalLink != "" { + // Only allow those external links scheme with http/https + linkURL, err := url.Parse(request.ExternalLink) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid external link: %v", err) + } + if linkURL.Scheme != "http" && linkURL.Scheme != "https" { + return nil, status.Errorf(codes.InvalidArgument, "invalid external link scheme: %v", linkURL.Scheme) + } + } + + create := &store.Resource{ + ResourceName: shortuuid.New(), + CreatorID: user.ID, + Filename: request.Filename, + ExternalLink: request.ExternalLink, + Type: request.Type, + } + if request.MemoId != nil { + create.MemoID = request.MemoId + } + resource, err := s.Store.CreateResource(ctx, create) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to create resource: %v", err) + } + + return &apiv2pb.CreateResourceResponse{ + Resource: s.convertResourceFromStore(ctx, resource), + }, nil +} + func (s *APIV2Service) ListResources(ctx context.Context, _ *apiv2pb.ListResourcesRequest) (*apiv2pb.ListResourcesResponse, error) { user, err := getCurrentUser(ctx, s.Store) if err != nil { @@ -31,6 +69,38 @@ func (s *APIV2Service) ListResources(ctx context.Context, _ *apiv2pb.ListResourc return response, nil } +func (s *APIV2Service) GetResource(ctx context.Context, request *apiv2pb.GetResourceRequest) (*apiv2pb.GetResourceResponse, error) { + resource, err := s.Store.GetResource(ctx, &store.FindResource{ + ID: &request.Id, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get resource: %v", err) + } + if resource == nil { + return nil, status.Errorf(codes.NotFound, "resource not found") + } + + return &apiv2pb.GetResourceResponse{ + Resource: s.convertResourceFromStore(ctx, resource), + }, nil +} + +func (s *APIV2Service) GetResourceByName(ctx context.Context, request *apiv2pb.GetResourceByNameRequest) (*apiv2pb.GetResourceByNameResponse, error) { + resource, err := s.Store.GetResource(ctx, &store.FindResource{ + ResourceName: &request.Name, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get resource: %v", err) + } + if resource == nil { + return nil, status.Errorf(codes.NotFound, "resource not found") + } + + return &apiv2pb.GetResourceByNameResponse{ + Resource: s.convertResourceFromStore(ctx, resource), + }, nil +} + func (s *APIV2Service) UpdateResource(ctx context.Context, request *apiv2pb.UpdateResourceRequest) (*apiv2pb.UpdateResourceResponse, error) { if request.UpdateMask == nil || len(request.UpdateMask.Paths) == 0 { return nil, status.Errorf(codes.InvalidArgument, "update mask is required") @@ -95,7 +165,8 @@ func (s *APIV2Service) convertResourceFromStore(ctx context.Context, resource *s return &apiv2pb.Resource{ Id: resource.ID, - CreatedTs: timestamppb.New(time.Unix(resource.CreatedTs, 0)), + Name: resource.ResourceName, + CreateTime: timestamppb.New(time.Unix(resource.CreatedTs, 0)), Filename: resource.Filename, ExternalLink: resource.ExternalLink, Type: resource.Type, diff --git a/server/route/api/v2/tag_service.go b/server/route/api/v2/tag_service.go new file mode 100644 index 0000000000000..3e888a86a74c0 --- /dev/null +++ b/server/route/api/v2/tag_service.go @@ -0,0 +1,271 @@ +package v2 + +import ( + "context" + "fmt" + "slices" + "sort" + + "github.com/pkg/errors" + "github.com/yourselfhosted/gomark/ast" + "github.com/yourselfhosted/gomark/parser" + "github.com/yourselfhosted/gomark/parser/tokenizer" + "github.com/yourselfhosted/gomark/restore" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + apiv2pb "github.com/usememos/memos/proto/gen/api/v2" + "github.com/usememos/memos/store" +) + +func (s *APIV2Service) UpsertTag(ctx context.Context, request *apiv2pb.UpsertTagRequest) (*apiv2pb.UpsertTagResponse, error) { + user, err := getCurrentUser(ctx, s.Store) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user") + } + + tag, err := s.Store.UpsertTag(ctx, &store.Tag{ + Name: request.Name, + CreatorID: user.ID, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to upsert tag: %v", err) + } + + t, err := s.convertTagFromStore(ctx, tag) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to convert tag: %v", err) + } + return &apiv2pb.UpsertTagResponse{ + Tag: t, + }, nil +} + +func (s *APIV2Service) BatchUpsertTag(ctx context.Context, request *apiv2pb.BatchUpsertTagRequest) (*apiv2pb.BatchUpsertTagResponse, error) { + for _, r := range request.Requests { + if _, err := s.UpsertTag(ctx, r); err != nil { + return nil, status.Errorf(codes.Internal, "failed to batch upsert tags: %v", err) + } + } + return &apiv2pb.BatchUpsertTagResponse{}, nil +} + +func (s *APIV2Service) ListTags(ctx context.Context, request *apiv2pb.ListTagsRequest) (*apiv2pb.ListTagsResponse, error) { + username, err := ExtractUsernameFromName(request.User) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid username: %v", err) + } + user, err := s.Store.GetUser(ctx, &store.FindUser{ + Username: &username, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) + } + if user == nil { + return nil, status.Errorf(codes.NotFound, "user not found") + } + tags, err := s.Store.ListTags(ctx, &store.FindTag{ + CreatorID: user.ID, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to list tags: %v", err) + } + + response := &apiv2pb.ListTagsResponse{} + for _, tag := range tags { + t, err := s.convertTagFromStore(ctx, tag) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to convert tag: %v", err) + } + response.Tags = append(response.Tags, t) + } + return response, nil +} + +func (s *APIV2Service) RenameTag(ctx context.Context, request *apiv2pb.RenameTagRequest) (*apiv2pb.RenameTagResponse, error) { + username, err := ExtractUsernameFromName(request.User) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid username: %v", err) + } + user, err := s.Store.GetUser(ctx, &store.FindUser{ + Username: &username, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) + } + if user == nil { + return nil, status.Errorf(codes.NotFound, "user not found") + } + + // Find all related memos. + memos, err := s.Store.ListMemos(ctx, &store.FindMemo{ + CreatorID: &user.ID, + ContentSearch: []string{fmt.Sprintf("#%s", request.OldName)}, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to list memos: %v", err) + } + // Replace tag name in memo content. + for _, memo := range memos { + nodes, err := parser.Parse(tokenizer.Tokenize(memo.Content)) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to parse memo: %v", err) + } + TraverseASTNodes(nodes, func(node ast.Node) { + if tag, ok := node.(*ast.Tag); ok && tag.Content == request.OldName { + tag.Content = request.NewName + } + }) + content := restore.Restore(nodes) + if err := s.Store.UpdateMemo(ctx, &store.UpdateMemo{ + ID: memo.ID, + Content: &content, + }); err != nil { + return nil, status.Errorf(codes.Internal, "failed to update memo: %v", err) + } + } + + // Delete old tag and create new tag. + if err := s.Store.DeleteTag(ctx, &store.DeleteTag{ + CreatorID: user.ID, + Name: request.OldName, + }); err != nil { + return nil, status.Errorf(codes.Internal, "failed to delete tag: %v", err) + } + tag, err := s.Store.UpsertTag(ctx, &store.Tag{ + CreatorID: user.ID, + Name: request.NewName, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to upsert tag: %v", err) + } + + tagMessage, err := s.convertTagFromStore(ctx, tag) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to convert tag: %v", err) + } + return &apiv2pb.RenameTagResponse{Tag: tagMessage}, nil +} + +func (s *APIV2Service) DeleteTag(ctx context.Context, request *apiv2pb.DeleteTagRequest) (*apiv2pb.DeleteTagResponse, error) { + username, err := ExtractUsernameFromName(request.Tag.Creator) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid username: %v", err) + } + user, err := s.Store.GetUser(ctx, &store.FindUser{ + Username: &username, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) + } + if user == nil { + return nil, status.Errorf(codes.NotFound, "user not found") + } + if err := s.Store.DeleteTag(ctx, &store.DeleteTag{ + Name: request.Tag.Name, + CreatorID: user.ID, + }); err != nil { + return nil, status.Errorf(codes.Internal, "failed to delete tag: %v", err) + } + + return &apiv2pb.DeleteTagResponse{}, nil +} + +func (s *APIV2Service) GetTagSuggestions(ctx context.Context, request *apiv2pb.GetTagSuggestionsRequest) (*apiv2pb.GetTagSuggestionsResponse, error) { + username, err := ExtractUsernameFromName(request.User) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid username: %v", err) + } + user, err := s.Store.GetUser(ctx, &store.FindUser{ + Username: &username, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) + } + if user == nil { + return nil, status.Errorf(codes.NotFound, "user not found") + } + normalRowStatus := store.Normal + memoFind := &store.FindMemo{ + CreatorID: &user.ID, + ContentSearch: []string{"#"}, + RowStatus: &normalRowStatus, + } + memos, err := s.Store.ListMemos(ctx, memoFind) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to list memos: %v", err) + } + + tagList, err := s.Store.ListTags(ctx, &store.FindTag{ + CreatorID: user.ID, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to list tags: %v", err) + } + + tagNameList := []string{} + for _, tag := range tagList { + tagNameList = append(tagNameList, tag.Name) + } + tagMapSet := make(map[string]bool) + for _, memo := range memos { + nodes, err := parser.Parse(tokenizer.Tokenize(memo.Content)) + if err != nil { + return nil, errors.Wrap(err, "failed to parse memo content") + } + + // Dynamically upsert tags from memo content. + TraverseASTNodes(nodes, func(node ast.Node) { + if tagNode, ok := node.(*ast.Tag); ok { + tag := tagNode.Content + if !slices.Contains(tagNameList, tag) { + tagMapSet[tag] = true + } + } + }) + } + suggestions := []string{} + for tag := range tagMapSet { + suggestions = append(suggestions, tag) + } + sort.Strings(suggestions) + + return &apiv2pb.GetTagSuggestionsResponse{ + Tags: suggestions, + }, nil +} + +func (s *APIV2Service) convertTagFromStore(ctx context.Context, tag *store.Tag) (*apiv2pb.Tag, error) { + user, err := s.Store.GetUser(ctx, &store.FindUser{ + ID: &tag.CreatorID, + }) + if err != nil { + return nil, errors.Wrap(err, "failed to get user") + } + return &apiv2pb.Tag{ + Name: tag.Name, + Creator: fmt.Sprintf("%s%s", UserNamePrefix, user.Username), + }, nil +} + +func TraverseASTNodes(nodes []ast.Node, fn func(ast.Node)) { + for _, node := range nodes { + fn(node) + switch n := node.(type) { + case *ast.Paragraph: + TraverseASTNodes(n.Children, fn) + case *ast.Heading: + TraverseASTNodes(n.Children, fn) + case *ast.Blockquote: + TraverseASTNodes(n.Children, fn) + case *ast.OrderedList: + TraverseASTNodes(n.Children, fn) + case *ast.UnorderedList: + TraverseASTNodes(n.Children, fn) + case *ast.TaskList: + TraverseASTNodes(n.Children, fn) + case *ast.Bold: + TraverseASTNodes(n.Children, fn) + } + } +} diff --git a/api/v2/user_service.go b/server/route/api/v2/user_service.go similarity index 58% rename from api/v2/user_service.go rename to server/route/api/v2/user_service.go index 7ec9ff26c4420..f9bc6a565107c 100644 --- a/api/v2/user_service.go +++ b/server/route/api/v2/user_service.go @@ -2,12 +2,12 @@ package v2 import ( "context" + "fmt" "net/http" - "regexp" "strings" "time" - "github.com/golang-jwt/jwt/v4" + "github.com/golang-jwt/jwt/v5" "github.com/labstack/echo/v4" "github.com/pkg/errors" "golang.org/x/crypto/bcrypt" @@ -16,19 +16,43 @@ import ( "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" - "github.com/usememos/memos/api/auth" + "github.com/usememos/memos/internal/util" apiv2pb "github.com/usememos/memos/proto/gen/api/v2" storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/server/route/api/auth" "github.com/usememos/memos/store" ) -var ( - usernameMatcher = regexp.MustCompile("^[a-z0-9]([a-z0-9-]{1,30}[a-z0-9])$") -) +func (s *APIV2Service) ListUsers(ctx context.Context, _ *apiv2pb.ListUsersRequest) (*apiv2pb.ListUsersResponse, error) { + currentUser, err := getCurrentUser(ctx, s.Store) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) + } + if currentUser.Role != store.RoleHost && currentUser.Role != store.RoleAdmin { + return nil, status.Errorf(codes.PermissionDenied, "permission denied") + } + + users, err := s.Store.ListUsers(ctx, &store.FindUser{}) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to list users: %v", err) + } + + response := &apiv2pb.ListUsersResponse{ + Users: []*apiv2pb.User{}, + } + for _, user := range users { + response.Users = append(response.Users, convertUserFromStore(user)) + } + return response, nil +} func (s *APIV2Service) GetUser(ctx context.Context, request *apiv2pb.GetUserRequest) (*apiv2pb.GetUserResponse, error) { + username, err := ExtractUsernameFromName(request.Name) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "name is required") + } user, err := s.Store.GetUser(ctx, &store.FindUser{ - Username: &request.Username, + Username: &username, }) if err != nil { return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) @@ -53,8 +77,12 @@ func (s *APIV2Service) CreateUser(ctx context.Context, request *apiv2pb.CreateUs return nil, status.Errorf(codes.PermissionDenied, "permission denied") } - if !usernameMatcher.MatchString(strings.ToLower(request.User.Username)) { - return nil, status.Errorf(codes.InvalidArgument, "invalid username: %s", request.User.Username) + username, err := ExtractUsernameFromName(request.User.Name) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "name is required") + } + if !util.ResourceNameMatcher.MatchString(strings.ToLower(username)) { + return nil, status.Errorf(codes.InvalidArgument, "invalid username: %s", username) } passwordHash, err := bcrypt.GenerateFromPassword([]byte(request.User.Password), bcrypt.DefaultCost) if err != nil { @@ -62,7 +90,7 @@ func (s *APIV2Service) CreateUser(ctx context.Context, request *apiv2pb.CreateUs } user, err := s.Store.CreateUser(ctx, &store.User{ - Username: request.User.Username, + Username: username, Role: convertUserRoleToStore(request.User.Role), Email: request.User.Email, Nickname: request.User.Nickname, @@ -79,25 +107,41 @@ func (s *APIV2Service) CreateUser(ctx context.Context, request *apiv2pb.CreateUs } func (s *APIV2Service) UpdateUser(ctx context.Context, request *apiv2pb.UpdateUserRequest) (*apiv2pb.UpdateUserResponse, error) { + username, err := ExtractUsernameFromName(request.User.Name) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "name is required") + } currentUser, err := getCurrentUser(ctx, s.Store) if err != nil { return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) } - if currentUser.Username != request.User.Username && currentUser.Role != store.RoleAdmin { + if currentUser.Username != username && currentUser.Role != store.RoleAdmin && currentUser.Role != store.RoleHost { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } if request.UpdateMask == nil || len(request.UpdateMask.Paths) == 0 { return nil, status.Errorf(codes.InvalidArgument, "update mask is empty") } + user, err := s.Store.GetUser(ctx, &store.FindUser{Username: &username}) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) + } + if user == nil { + return nil, status.Errorf(codes.NotFound, "user not found") + } + + if s.Profile.Mode == "demo" && user.Username == "memos-demo" { + return nil, status.Errorf(codes.PermissionDenied, "unauthorized to update user in demo mode") + } + currentTs := time.Now().Unix() update := &store.UpdateUser{ - ID: currentUser.ID, + ID: user.ID, UpdatedTs: ¤tTs, } for _, field := range request.UpdateMask.Paths { if field == "username" { - if !usernameMatcher.MatchString(strings.ToLower(request.User.Username)) { + if !util.ResourceNameMatcher.MatchString(strings.ToLower(request.User.Username)) { return nil, status.Errorf(codes.InvalidArgument, "invalid username: %s", request.User.Username) } update.Username = &request.User.Username @@ -125,17 +169,153 @@ func (s *APIV2Service) UpdateUser(ctx context.Context, request *apiv2pb.UpdateUs } } - user, err := s.Store.UpdateUser(ctx, update) + updatedUser, err := s.Store.UpdateUser(ctx, update) if err != nil { return nil, status.Errorf(codes.Internal, "failed to update user: %v", err) } response := &apiv2pb.UpdateUserResponse{ - User: convertUserFromStore(user), + User: convertUserFromStore(updatedUser), } return response, nil } +func (s *APIV2Service) DeleteUser(ctx context.Context, request *apiv2pb.DeleteUserRequest) (*apiv2pb.DeleteUserResponse, error) { + username, err := ExtractUsernameFromName(request.Name) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "name is required") + } + currentUser, err := getCurrentUser(ctx, s.Store) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) + } + if currentUser.Username != username && currentUser.Role != store.RoleAdmin && currentUser.Role != store.RoleHost { + return nil, status.Errorf(codes.PermissionDenied, "permission denied") + } + + user, err := s.Store.GetUser(ctx, &store.FindUser{Username: &username}) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) + } + if user == nil { + return nil, status.Errorf(codes.NotFound, "user not found") + } + + if s.Profile.Mode == "demo" && user.Username == "memos-demo" { + return nil, status.Errorf(codes.PermissionDenied, "unauthorized to delete this user in demo mode") + } + + if err := s.Store.DeleteUser(ctx, &store.DeleteUser{ + ID: user.ID, + }); err != nil { + return nil, status.Errorf(codes.Internal, "failed to delete user: %v", err) + } + + return &apiv2pb.DeleteUserResponse{}, nil +} + +func getDefaultUserSetting() *apiv2pb.UserSetting { + return &apiv2pb.UserSetting{ + Locale: "en", + Appearance: "system", + MemoVisibility: "PRIVATE", + } +} + +func (s *APIV2Service) GetUserSetting(ctx context.Context, _ *apiv2pb.GetUserSettingRequest) (*apiv2pb.GetUserSettingResponse, error) { + user, err := getCurrentUser(ctx, s.Store) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err) + } + + userSettings, err := s.Store.ListUserSettings(ctx, &store.FindUserSetting{ + UserID: &user.ID, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to list user settings: %v", err) + } + userSettingMessage := getDefaultUserSetting() + for _, setting := range userSettings { + if setting.Key == storepb.UserSettingKey_USER_SETTING_LOCALE { + userSettingMessage.Locale = setting.GetLocale() + } else if setting.Key == storepb.UserSettingKey_USER_SETTING_APPEARANCE { + userSettingMessage.Appearance = setting.GetAppearance() + } else if setting.Key == storepb.UserSettingKey_USER_SETTING_MEMO_VISIBILITY { + userSettingMessage.MemoVisibility = setting.GetMemoVisibility() + } else if setting.Key == storepb.UserSettingKey_USER_SETTING_TELEGRAM_USER_ID { + userSettingMessage.TelegramUserId = setting.GetTelegramUserId() + } + } + return &apiv2pb.GetUserSettingResponse{ + Setting: userSettingMessage, + }, nil +} + +func (s *APIV2Service) UpdateUserSetting(ctx context.Context, request *apiv2pb.UpdateUserSettingRequest) (*apiv2pb.UpdateUserSettingResponse, error) { + user, err := getCurrentUser(ctx, s.Store) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err) + } + + if request.UpdateMask == nil || len(request.UpdateMask.Paths) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "update mask is empty") + } + + for _, field := range request.UpdateMask.Paths { + if field == "locale" { + if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{ + UserId: user.ID, + Key: storepb.UserSettingKey_USER_SETTING_LOCALE, + Value: &storepb.UserSetting_Locale{ + Locale: request.Setting.Locale, + }, + }); err != nil { + return nil, status.Errorf(codes.Internal, "failed to upsert user setting: %v", err) + } + } else if field == "appearance" { + if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{ + UserId: user.ID, + Key: storepb.UserSettingKey_USER_SETTING_APPEARANCE, + Value: &storepb.UserSetting_Appearance{ + Appearance: request.Setting.Appearance, + }, + }); err != nil { + return nil, status.Errorf(codes.Internal, "failed to upsert user setting: %v", err) + } + } else if field == "memo_visibility" { + if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{ + UserId: user.ID, + Key: storepb.UserSettingKey_USER_SETTING_MEMO_VISIBILITY, + Value: &storepb.UserSetting_MemoVisibility{ + MemoVisibility: request.Setting.MemoVisibility, + }, + }); err != nil { + return nil, status.Errorf(codes.Internal, "failed to upsert user setting: %v", err) + } + } else if field == "telegram_user_id" { + if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{ + UserId: user.ID, + Key: storepb.UserSettingKey_USER_SETTING_TELEGRAM_USER_ID, + Value: &storepb.UserSetting_TelegramUserId{ + TelegramUserId: request.Setting.TelegramUserId, + }, + }); err != nil { + return nil, status.Errorf(codes.Internal, "failed to upsert user setting: %v", err) + } + } else { + return nil, status.Errorf(codes.InvalidArgument, "invalid update path: %s", field) + } + } + + userSettingResponse, err := s.GetUserSetting(ctx, &apiv2pb.GetUserSettingRequest{}) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user setting: %v", err) + } + return &apiv2pb.UpdateUserSettingResponse{ + Setting: userSettingResponse.Setting, + }, nil +} + func (s *APIV2Service) ListUserAccessTokens(ctx context.Context, request *apiv2pb.ListUserAccessTokensRequest) (*apiv2pb.ListUserAccessTokensResponse, error) { user, err := getCurrentUser(ctx, s.Store) if err != nil { @@ -146,17 +326,21 @@ func (s *APIV2Service) ListUserAccessTokens(ctx context.Context, request *apiv2p } userID := user.ID + username, err := ExtractUsernameFromName(request.Name) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "name is required") + } // List access token for other users need to be verified. - if user.Username != request.Username { + if user.Username != username { // Normal users can only list their access tokens. if user.Role == store.RoleUser { return nil, status.Errorf(codes.PermissionDenied, "permission denied") } // The request user must be exist. - requestUser, err := s.Store.GetUser(ctx, &store.FindUser{Username: &request.Username}) + requestUser, err := s.Store.GetUser(ctx, &store.FindUser{Username: &username}) if requestUser == nil || err != nil { - return nil, status.Errorf(codes.NotFound, "fail to find user %s", request.Username) + return nil, status.Errorf(codes.NotFound, "fail to find user %s", username) } userID = requestUser.ID } @@ -217,21 +401,7 @@ func (s *APIV2Service) CreateUserAccessToken(ctx context.Context, request *apiv2 expiresAt = request.ExpiresAt.AsTime() } - // Create access token for other users need to be verified. - if user.Username != request.Username { - // Normal users can only create access tokens for others. - if user.Role == store.RoleUser { - return nil, status.Errorf(codes.PermissionDenied, "permission denied") - } - - // The request user must be exist. - requestUser, err := s.Store.GetUser(ctx, &store.FindUser{Username: &request.Username}) - if requestUser == nil || err != nil { - return nil, status.Errorf(codes.NotFound, "fail to find user %s", request.Username) - } - } - - accessToken, err := auth.GenerateAccessToken(request.Username, user.ID, expiresAt, []byte(s.Secret)) + accessToken, err := auth.GenerateAccessToken(user.Username, user.ID, expiresAt, []byte(s.Secret)) if err != nil { return nil, status.Errorf(codes.Internal, "failed to generate access token: %v", err) } @@ -288,7 +458,7 @@ func (s *APIV2Service) DeleteUserAccessToken(ctx context.Context, request *apiv2 } updatedUserAccessTokens = append(updatedUserAccessTokens, userAccessToken) } - if _, err := s.Store.UpsertUserSettingV1(ctx, &storepb.UserSetting{ + if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{ UserId: user.ID, Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS, Value: &storepb.UserSetting_AccessTokens{ @@ -313,7 +483,7 @@ func (s *APIV2Service) UpsertAccessTokenToStore(ctx context.Context, user *store Description: description, } userAccessTokens = append(userAccessTokens, &userAccessToken) - if _, err := s.Store.UpsertUserSettingV1(ctx, &storepb.UserSetting{ + if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{ UserId: user.ID, Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS, Value: &storepb.UserSetting_AccessTokens{ @@ -329,12 +499,13 @@ func (s *APIV2Service) UpsertAccessTokenToStore(ctx context.Context, user *store func convertUserFromStore(user *store.User) *apiv2pb.User { return &apiv2pb.User{ - Id: int32(user.ID), + Name: fmt.Sprintf("%s%s", UserNamePrefix, user.Username), + Id: user.ID, RowStatus: convertRowStatusFromStore(user.RowStatus), CreateTime: timestamppb.New(time.Unix(user.CreatedTs, 0)), UpdateTime: timestamppb.New(time.Unix(user.UpdatedTs, 0)), - Username: user.Username, Role: convertUserRoleFromStore(user.Role), + Username: user.Username, Email: user.Email, Nickname: user.Nickname, AvatarUrl: user.AvatarURL, diff --git a/api/v2/v2.go b/server/route/api/v2/v2.go similarity index 68% rename from api/v2/v2.go rename to server/route/api/v2/v2.go index 5becfb2087045..ced8b2f2494b6 100644 --- a/api/v2/v2.go +++ b/server/route/api/v2/v2.go @@ -3,10 +3,13 @@ package v2 import ( "context" "fmt" + "log/slog" + "net" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/improbable-eng/grpc-web/go/grpcweb" "github.com/labstack/echo/v4" + "github.com/pkg/errors" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/reflection" @@ -17,13 +20,17 @@ import ( ) type APIV2Service struct { - apiv2pb.UnimplementedSystemServiceServer + apiv2pb.UnimplementedWorkspaceServiceServer + apiv2pb.UnimplementedWorkspaceSettingServiceServer + apiv2pb.UnimplementedAuthServiceServer apiv2pb.UnimplementedUserServiceServer apiv2pb.UnimplementedMemoServiceServer apiv2pb.UnimplementedResourceServiceServer apiv2pb.UnimplementedTagServiceServer apiv2pb.UnimplementedInboxServiceServer apiv2pb.UnimplementedActivityServiceServer + apiv2pb.UnimplementedWebhookServiceServer + apiv2pb.UnimplementedLinkServiceServer Secret string Profile *profile.Profile @@ -38,6 +45,7 @@ func NewAPIV2Service(secret string, profile *profile.Profile, store *store.Store authProvider := NewGRPCAuthInterceptor(store, secret) grpcServer := grpc.NewServer( grpc.ChainUnaryInterceptor( + NewLoggerInterceptor().LoggerInterceptor, authProvider.AuthenticationInterceptor, ), ) @@ -49,13 +57,17 @@ func NewAPIV2Service(secret string, profile *profile.Profile, store *store.Store grpcServerPort: grpcServerPort, } - apiv2pb.RegisterSystemServiceServer(grpcServer, apiv2Service) + apiv2pb.RegisterWorkspaceServiceServer(grpcServer, apiv2Service) + apiv2pb.RegisterWorkspaceSettingServiceServer(grpcServer, apiv2Service) + apiv2pb.RegisterAuthServiceServer(grpcServer, apiv2Service) apiv2pb.RegisterUserServiceServer(grpcServer, apiv2Service) apiv2pb.RegisterMemoServiceServer(grpcServer, apiv2Service) apiv2pb.RegisterTagServiceServer(grpcServer, apiv2Service) apiv2pb.RegisterResourceServiceServer(grpcServer, apiv2Service) apiv2pb.RegisterInboxServiceServer(grpcServer, apiv2Service) apiv2pb.RegisterActivityServiceServer(grpcServer, apiv2Service) + apiv2pb.RegisterWebhookServiceServer(grpcServer, apiv2Service) + apiv2pb.RegisterLinkServiceServer(grpcServer, apiv2Service) reflection.Register(grpcServer) return apiv2Service @@ -79,7 +91,13 @@ func (s *APIV2Service) RegisterGateway(ctx context.Context, e *echo.Echo) error } gwMux := runtime.NewServeMux() - if err := apiv2pb.RegisterSystemServiceHandler(context.Background(), gwMux, conn); err != nil { + if err := apiv2pb.RegisterWorkspaceServiceHandler(context.Background(), gwMux, conn); err != nil { + return err + } + if err := apiv2pb.RegisterWorkspaceSettingServiceHandler(context.Background(), gwMux, conn); err != nil { + return err + } + if err := apiv2pb.RegisterAuthServiceHandler(context.Background(), gwMux, conn); err != nil { return err } if err := apiv2pb.RegisterUserServiceHandler(context.Background(), gwMux, conn); err != nil { @@ -100,6 +118,12 @@ func (s *APIV2Service) RegisterGateway(ctx context.Context, e *echo.Echo) error if err := apiv2pb.RegisterActivityServiceHandler(context.Background(), gwMux, conn); err != nil { return err } + if err := apiv2pb.RegisterWebhookServiceHandler(context.Background(), gwMux, conn); err != nil { + return err + } + if err := apiv2pb.RegisterLinkServiceHandler(context.Background(), gwMux, conn); err != nil { + return err + } e.Any("/api/v2/*", echo.WrapHandler(gwMux)) // GRPC web proxy. @@ -112,5 +136,16 @@ func (s *APIV2Service) RegisterGateway(ctx context.Context, e *echo.Echo) error wrappedGrpc := grpcweb.WrapServer(s.grpcServer, options...) e.Any("/memos.api.v2.*", echo.WrapHandler(wrappedGrpc)) + // Start gRPC server. + listen, err := net.Listen("tcp", fmt.Sprintf("%s:%d", s.Profile.Addr, s.grpcServerPort)) + if err != nil { + return errors.Wrap(err, "failed to start gRPC server") + } + go func() { + if err := s.grpcServer.Serve(listen); err != nil { + slog.Error("failed to start gRPC server", err) + } + }() + return nil } diff --git a/server/route/api/v2/webhook_service.go b/server/route/api/v2/webhook_service.go new file mode 100644 index 0000000000000..3beb84068271b --- /dev/null +++ b/server/route/api/v2/webhook_service.go @@ -0,0 +1,120 @@ +package v2 + +import ( + "context" + "time" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/timestamppb" + + apiv2pb "github.com/usememos/memos/proto/gen/api/v2" + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (s *APIV2Service) CreateWebhook(ctx context.Context, request *apiv2pb.CreateWebhookRequest) (*apiv2pb.CreateWebhookResponse, error) { + currentUser, err := getCurrentUser(ctx, s.Store) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) + } + + webhook, err := s.Store.CreateWebhook(ctx, &storepb.Webhook{ + CreatorId: currentUser.ID, + Name: request.Name, + Url: request.Url, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to create webhook, error: %+v", err) + } + return &apiv2pb.CreateWebhookResponse{ + Webhook: convertWebhookFromStore(webhook), + }, nil +} + +func (s *APIV2Service) ListWebhooks(ctx context.Context, request *apiv2pb.ListWebhooksRequest) (*apiv2pb.ListWebhooksResponse, error) { + webhooks, err := s.Store.ListWebhooks(ctx, &store.FindWebhook{ + CreatorID: &request.CreatorId, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to list webhooks, error: %+v", err) + } + + response := &apiv2pb.ListWebhooksResponse{ + Webhooks: []*apiv2pb.Webhook{}, + } + for _, webhook := range webhooks { + response.Webhooks = append(response.Webhooks, convertWebhookFromStore(webhook)) + } + return response, nil +} + +func (s *APIV2Service) GetWebhook(ctx context.Context, request *apiv2pb.GetWebhookRequest) (*apiv2pb.GetWebhookResponse, error) { + currentUser, err := getCurrentUser(ctx, s.Store) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get user: %v", err) + } + + webhook, err := s.Store.GetWebhooks(ctx, &store.FindWebhook{ + ID: &request.Id, + CreatorID: ¤tUser.ID, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get webhook, error: %+v", err) + } + if webhook == nil { + return nil, status.Errorf(codes.NotFound, "webhook not found") + } + return &apiv2pb.GetWebhookResponse{ + Webhook: convertWebhookFromStore(webhook), + }, nil +} + +func (s *APIV2Service) UpdateWebhook(ctx context.Context, request *apiv2pb.UpdateWebhookRequest) (*apiv2pb.UpdateWebhookResponse, error) { + if request.UpdateMask == nil || len(request.UpdateMask.Paths) == 0 { + return nil, status.Errorf(codes.InvalidArgument, "update_mask is required") + } + + update := &store.UpdateWebhook{} + for _, field := range request.UpdateMask.Paths { + switch field { + case "row_status": + rowStatus := storepb.RowStatus(storepb.RowStatus_value[request.Webhook.RowStatus.String()]) + update.RowStatus = &rowStatus + case "name": + update.Name = &request.Webhook.Name + case "url": + update.URL = &request.Webhook.Url + } + } + + webhook, err := s.Store.UpdateWebhook(ctx, update) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to update webhook, error: %+v", err) + } + return &apiv2pb.UpdateWebhookResponse{ + Webhook: convertWebhookFromStore(webhook), + }, nil +} + +func (s *APIV2Service) DeleteWebhook(ctx context.Context, request *apiv2pb.DeleteWebhookRequest) (*apiv2pb.DeleteWebhookResponse, error) { + err := s.Store.DeleteWebhook(ctx, &store.DeleteWebhook{ + ID: request.Id, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to delete webhook, error: %+v", err) + } + return &apiv2pb.DeleteWebhookResponse{}, nil +} + +func convertWebhookFromStore(webhook *storepb.Webhook) *apiv2pb.Webhook { + return &apiv2pb.Webhook{ + Id: webhook.Id, + CreatedTime: timestamppb.New(time.Unix(webhook.CreatedTs, 0)), + UpdatedTime: timestamppb.New(time.Unix(webhook.UpdatedTs, 0)), + RowStatus: apiv2pb.RowStatus(webhook.RowStatus), + CreatorId: webhook.CreatorId, + Name: webhook.Name, + Url: webhook.Url, + } +} diff --git a/server/route/api/v2/workspace_service.go b/server/route/api/v2/workspace_service.go new file mode 100644 index 0000000000000..78b31a7e2689b --- /dev/null +++ b/server/route/api/v2/workspace_service.go @@ -0,0 +1,17 @@ +package v2 + +import ( + "context" + + apiv2pb "github.com/usememos/memos/proto/gen/api/v2" +) + +func (s *APIV2Service) GetWorkspaceProfile(_ context.Context, _ *apiv2pb.GetWorkspaceProfileRequest) (*apiv2pb.GetWorkspaceProfileResponse, error) { + workspaceProfile := &apiv2pb.WorkspaceProfile{ + Version: s.Profile.Version, + Mode: s.Profile.Mode, + } + return &apiv2pb.GetWorkspaceProfileResponse{ + WorkspaceProfile: workspaceProfile, + }, nil +} diff --git a/server/route/api/v2/workspace_setting_service.go b/server/route/api/v2/workspace_setting_service.go new file mode 100644 index 0000000000000..8b3941997d332 --- /dev/null +++ b/server/route/api/v2/workspace_setting_service.go @@ -0,0 +1,95 @@ +package v2 + +import ( + "context" + "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + apiv2pb "github.com/usememos/memos/proto/gen/api/v2" + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (s *APIV2Service) GetWorkspaceSetting(ctx context.Context, request *apiv2pb.GetWorkspaceSettingRequest) (*apiv2pb.GetWorkspaceSettingResponse, error) { + settingKeyString, err := ExtractWorkspaceSettingKeyFromName(request.Name) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid workspace setting name: %v", err) + } + settingKey := storepb.WorkspaceSettingKey(storepb.WorkspaceSettingKey_value[settingKeyString]) + workspaceSetting, err := s.Store.GetWorkspaceSettingV1(ctx, &store.FindWorkspaceSettingV1{ + Key: settingKey, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get workspace setting: %v", err) + } + if workspaceSetting == nil { + return nil, status.Errorf(codes.NotFound, "workspace setting not found") + } + + return &apiv2pb.GetWorkspaceSettingResponse{ + Setting: convertWorkspaceSettingFromStore(workspaceSetting), + }, nil +} + +func (s *APIV2Service) SetWorkspaceSetting(ctx context.Context, request *apiv2pb.SetWorkspaceSettingRequest) (*apiv2pb.SetWorkspaceSettingResponse, error) { + user, err := getCurrentUser(ctx, s.Store) + if err != nil { + return nil, status.Errorf(codes.Internal, "failed to get current user: %v", err) + } + if user.Role != store.RoleHost { + return nil, status.Errorf(codes.PermissionDenied, "permission denied") + } + + if _, err := s.Store.UpsertWorkspaceSettingV1(ctx, convertWorkspaceSettingToStore(request.Setting)); err != nil { + return nil, status.Errorf(codes.Internal, "failed to upsert workspace setting: %v", err) + } + + return &apiv2pb.SetWorkspaceSettingResponse{}, nil +} + +func convertWorkspaceSettingFromStore(setting *storepb.WorkspaceSetting) *apiv2pb.WorkspaceSetting { + return &apiv2pb.WorkspaceSetting{ + Name: fmt.Sprintf("%s%s", WorkspaceSettingNamePrefix, setting.Key.String()), + Value: &apiv2pb.WorkspaceSetting_GeneralSetting{ + GeneralSetting: convertWorkspaceGeneralSettingFromStore(setting.GetGeneral()), + }, + } +} + +func convertWorkspaceSettingToStore(setting *apiv2pb.WorkspaceSetting) *storepb.WorkspaceSetting { + settingKeyString, _ := ExtractWorkspaceSettingKeyFromName(setting.Name) + return &storepb.WorkspaceSetting{ + Key: storepb.WorkspaceSettingKey(storepb.WorkspaceSettingKey_value[settingKeyString]), + Value: &storepb.WorkspaceSetting_General{ + General: convertWorkspaceGeneralSettingToStore(setting.GetGeneralSetting()), + }, + } +} + +func convertWorkspaceGeneralSettingFromStore(setting *storepb.WorkspaceGeneralSetting) *apiv2pb.WorkspaceGeneralSetting { + if setting == nil { + return nil + } + return &apiv2pb.WorkspaceGeneralSetting{ + InstanceUrl: setting.InstanceUrl, + DisallowSignup: setting.DisallowSignup, + DisallowPasswordLogin: setting.DisallowPasswordLogin, + AdditionalScript: setting.AdditionalScript, + AdditionalStyle: setting.AdditionalStyle, + } +} + +func convertWorkspaceGeneralSettingToStore(setting *apiv2pb.WorkspaceGeneralSetting) *storepb.WorkspaceGeneralSetting { + if setting == nil { + return nil + } + return &storepb.WorkspaceGeneralSetting{ + InstanceUrl: setting.InstanceUrl, + DisallowSignup: setting.DisallowSignup, + DisallowPasswordLogin: setting.DisallowPasswordLogin, + AdditionalScript: setting.AdditionalScript, + AdditionalStyle: setting.AdditionalStyle, + } +} diff --git a/server/route/frontend/frontend.go b/server/route/frontend/frontend.go new file mode 100644 index 0000000000000..02c56860d504c --- /dev/null +++ b/server/route/frontend/frontend.go @@ -0,0 +1,171 @@ +package frontend + +import ( + "context" + "fmt" + "net/http" + "os" + "strings" + + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" + "github.com/yourselfhosted/gomark/parser" + "github.com/yourselfhosted/gomark/parser/tokenizer" + "github.com/yourselfhosted/gomark/renderer" + + "github.com/usememos/memos/internal/util" + "github.com/usememos/memos/server/profile" + "github.com/usememos/memos/store" +) + +const ( + // maxMetadataDescriptionLength is the maximum length of metadata description. + maxMetadataDescriptionLength = 256 +) + +type FrontendService struct { + Profile *profile.Profile + Store *store.Store +} + +func NewFrontendService(profile *profile.Profile, store *store.Store) *FrontendService { + return &FrontendService{ + Profile: profile, + Store: store, + } +} + +func (s *FrontendService) Serve(ctx context.Context, e *echo.Echo) { + // Use echo static middleware to serve the built dist folder. + // refer: https://github.com/labstack/echo/blob/master/middleware/static.go + e.Use(middleware.StaticWithConfig(middleware.StaticConfig{ + Root: "dist", + HTML5: true, + Skipper: func(c echo.Context) bool { + return util.HasPrefixes(c.Path(), "/api", "/memos.api.v2", "/robots.txt", "/sitemap.xml", "/m/:name") + }, + })) + + s.registerRoutes(e) + s.registerFileRoutes(ctx, e) +} + +func (s *FrontendService) registerRoutes(e *echo.Echo) { + rawIndexHTML := getRawIndexHTML() + + e.GET("/m/:name", func(c echo.Context) error { + ctx := c.Request().Context() + resourceName := c.Param("name") + memo, err := s.Store.GetMemo(ctx, &store.FindMemo{ + ResourceName: &resourceName, + }) + if err != nil { + return c.HTML(http.StatusOK, rawIndexHTML) + } + if memo == nil { + return c.HTML(http.StatusOK, rawIndexHTML) + } + creator, err := s.Store.GetUser(ctx, &store.FindUser{ + ID: &memo.CreatorID, + }) + if err != nil { + return c.HTML(http.StatusOK, rawIndexHTML) + } + + // Inject memo metadata into `index.html`. + indexHTML := strings.ReplaceAll(rawIndexHTML, "", generateMemoMetadata(memo, creator).String()) + indexHTML = strings.ReplaceAll(indexHTML, "", fmt.Sprintf("", memo.ID)) + return c.HTML(http.StatusOK, indexHTML) + }) +} + +func (s *FrontendService) registerFileRoutes(ctx context.Context, e *echo.Echo) { + workspaceGeneralSetting, err := s.Store.GetWorkspaceGeneralSetting(ctx) + if err != nil { + return + } + instanceURL := workspaceGeneralSetting.GetInstanceUrl() + if instanceURL == "" { + return + } + + e.GET("/robots.txt", func(c echo.Context) error { + robotsTxt := fmt.Sprintf(`User-agent: * +Allow: / +Host: %s +Sitemap: %s/sitemap.xml`, instanceURL, instanceURL) + return c.String(http.StatusOK, robotsTxt) + }) + + e.GET("/sitemap.xml", func(c echo.Context) error { + ctx := c.Request().Context() + urlsets := []string{} + // Append memo list. + memoList, err := s.Store.ListMemos(ctx, &store.FindMemo{ + VisibilityList: []store.Visibility{store.Public}, + }) + if err != nil { + return err + } + for _, memo := range memoList { + urlsets = append(urlsets, fmt.Sprintf(`%s`, fmt.Sprintf("%s/m/%s", instanceURL, memo.ResourceName))) + } + sitemap := fmt.Sprintf(`%s`, strings.Join(urlsets, "\n")) + return c.XMLBlob(http.StatusOK, []byte(sitemap)) + }) +} + +func generateMemoMetadata(memo *store.Memo, creator *store.User) *Metadata { + metadata := getDefaultMetadata() + metadata.Title = fmt.Sprintf("%s(@%s) on Memos", creator.Nickname, creator.Username) + if memo.Visibility == store.Public { + tokens := tokenizer.Tokenize(memo.Content) + nodes, _ := parser.Parse(tokens) + description := renderer.NewStringRenderer().Render(nodes) + if len(description) == 0 { + description = memo.Content + } + if len(description) > maxMetadataDescriptionLength { + description = description[:maxMetadataDescriptionLength] + "..." + } + metadata.Description = description + } + + return metadata +} + +func getRawIndexHTML() string { + bytes, _ := os.ReadFile("dist/index.html") + return string(bytes) +} + +type Metadata struct { + Title string + Description string + ImageURL string +} + +func getDefaultMetadata() *Metadata { + return &Metadata{ + Title: "Memos", + Description: "A privacy-first, lightweight note-taking service. Easily capture and share your great thoughts.", + ImageURL: "/logo.webp", + } +} + +func (m *Metadata) String() string { + metadataList := []string{ + fmt.Sprintf(``, m.Description), + fmt.Sprintf(``, m.Title), + fmt.Sprintf(``, m.Description), + fmt.Sprintf(``, m.ImageURL), + ``, + // Twitter related fields. + fmt.Sprintf(``, m.Title), + fmt.Sprintf(``, m.Description), + fmt.Sprintf(``, m.ImageURL), + ``, + ``, + } + return strings.Join(metadataList, "\n") +} diff --git a/api/resource/resource.go b/server/route/resource/resource.go similarity index 81% rename from api/resource/resource.go rename to server/route/resource/resource.go index 892ea7a7183f0..7e977f904f660 100644 --- a/api/resource/resource.go +++ b/server/route/resource/resource.go @@ -4,9 +4,9 @@ import ( "bytes" "fmt" "io" + "log/slog" "net/http" "os" - "path" "path/filepath" "strings" "sync/atomic" @@ -15,9 +15,7 @@ import ( "github.com/disintegration/imaging" "github.com/labstack/echo/v4" "github.com/pkg/errors" - "go.uber.org/zap" - "github.com/usememos/memos/internal/log" "github.com/usememos/memos/internal/util" "github.com/usememos/memos/server/profile" "github.com/usememos/memos/store" @@ -31,39 +29,35 @@ const ( thumbnailImagePath = ".thumbnail_cache" ) -type Service struct { +type ResourceService struct { Profile *profile.Profile Store *store.Store } -func NewService(profile *profile.Profile, store *store.Store) *Service { - return &Service{ +func NewResourceService(profile *profile.Profile, store *store.Store) *ResourceService { + return &ResourceService{ Profile: profile, Store: store, } } -func (s *Service) RegisterResourcePublicRoutes(g *echo.Group) { - g.GET("/r/:resourceId", s.streamResource) - g.GET("/r/:resourceId/*", s.streamResource) +func (s *ResourceService) RegisterRoutes(g *echo.Group) { + g.GET("/r/:resourceName", s.streamResource) + g.GET("/r/:resourceName/*", s.streamResource) } -func (s *Service) streamResource(c echo.Context) error { +func (s *ResourceService) streamResource(c echo.Context) error { ctx := c.Request().Context() - resourceID, err := util.ConvertStringToInt32(c.Param("resourceId")) - if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("resourceId"))).SetInternal(err) - } - + resourceName := c.Param("resourceName") resource, err := s.Store.GetResource(ctx, &store.FindResource{ - ID: &resourceID, - GetBlob: true, + ResourceName: &resourceName, + GetBlob: true, }) if err != nil { - return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("Failed to find resource by ID: %v", resourceID)).SetInternal(err) + return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("Failed to find resource by id: %s", resourceName)).SetInternal(err) } if resource == nil { - return echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("Resource not found: %d", resourceID)) + return echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("Resource not found: %s", resourceName)) } // Check the related memo visibility. if resource.MemoID != nil { @@ -83,7 +77,11 @@ func (s *Service) streamResource(c echo.Context) error { blob := resource.Blob if resource.InternalPath != "" { - resourcePath := resource.InternalPath + resourcePath := filepath.FromSlash(resource.InternalPath) + if !filepath.IsAbs(resourcePath) { + resourcePath = filepath.Join(s.Profile.Data, resourcePath) + } + src, err := os.Open(resourcePath) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("Failed to open the local resource: %s", resourcePath)).SetInternal(err) @@ -100,14 +98,15 @@ func (s *Service) streamResource(c echo.Context) error { thumbnailPath := filepath.Join(s.Profile.Data, thumbnailImagePath, fmt.Sprintf("%d%s", resource.ID, ext)) thumbnailBlob, err := getOrGenerateThumbnailImage(blob, thumbnailPath) if err != nil { - log.Warn(fmt.Sprintf("failed to get or generate local thumbnail with path %s", thumbnailPath), zap.Error(err)) + slog.Warn("failed to get or generate thumbnail image", err) } else { blob = thumbnailBlob } } - c.Response().Writer.Header().Set(echo.HeaderCacheControl, "max-age=31536000, immutable") - c.Response().Writer.Header().Set(echo.HeaderContentSecurityPolicy, "default-src 'self'") + c.Response().Writer.Header().Set(echo.HeaderCacheControl, "max-age=3600") + c.Response().Writer.Header().Set(echo.HeaderContentSecurityPolicy, "default-src 'none'; script-src 'none'; img-src 'self'; media-src 'self'; sandbox;") + c.Response().Writer.Header().Set("Content-Disposition", fmt.Sprintf(`filename="%s"`, resource.Filename)) resourceType := strings.ToLower(resource.Type) if strings.HasPrefix(resourceType, "text") { resourceType = echo.MIMETextPlainCharsetUTF8 @@ -115,7 +114,6 @@ func (s *Service) streamResource(c echo.Context) error { http.ServeContent(c.Response(), c.Request(), resource.Filename, time.Unix(resource.UpdatedTs, 0), bytes.NewReader(blob)) return nil } - c.Response().Writer.Header().Set("Content-Disposition", fmt.Sprintf(`filename="%s"`, resource.Filename)) return c.Stream(http.StatusOK, resourceType, bytes.NewReader(blob)) } @@ -142,7 +140,7 @@ func getOrGenerateThumbnailImage(srcBlob []byte, dstPath string) ([]byte, error) } thumbnailImage := imaging.Resize(src, 512, 0, imaging.Lanczos) - dstDir := path.Dir(dstPath) + dstDir := filepath.Dir(dstPath) if err := os.MkdirAll(dstDir, os.ModePerm); err != nil { return nil, errors.Wrap(err, "failed to create thumbnail dir") } diff --git a/server/route/rss/rss.go b/server/route/rss/rss.go new file mode 100644 index 0000000000000..9b1745ee35b4b --- /dev/null +++ b/server/route/rss/rss.go @@ -0,0 +1,169 @@ +package rss + +import ( + "context" + "net/http" + "strconv" + "strings" + "time" + + "github.com/gorilla/feeds" + "github.com/labstack/echo/v4" + "github.com/yourselfhosted/gomark" + "github.com/yourselfhosted/gomark/ast" + "github.com/yourselfhosted/gomark/renderer" + + "github.com/usememos/memos/internal/util" + "github.com/usememos/memos/server/profile" + "github.com/usememos/memos/store" +) + +const ( + maxRSSItemCount = 100 + maxRSSItemTitleLength = 128 +) + +type RSSService struct { + Profile *profile.Profile + Store *store.Store +} + +func NewRSSService(profile *profile.Profile, store *store.Store) *RSSService { + return &RSSService{ + Profile: profile, + Store: store, + } +} + +func (s *RSSService) RegisterRoutes(g *echo.Group) { + g.GET("/explore/rss.xml", s.GetExploreRSS) + g.GET("/u/:username/rss.xml", s.GetUserRSS) +} + +func (s *RSSService) GetExploreRSS(c echo.Context) error { + ctx := c.Request().Context() + normalStatus := store.Normal + memoFind := store.FindMemo{ + RowStatus: &normalStatus, + VisibilityList: []store.Visibility{store.Public}, + } + memoList, err := s.Store.ListMemos(ctx, &memoFind) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find memo list").SetInternal(err) + } + + baseURL := c.Scheme() + "://" + c.Request().Host + rss, err := s.generateRSSFromMemoList(ctx, memoList, baseURL) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, "Failed to generate rss").SetInternal(err) + } + c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationXMLCharsetUTF8) + return c.String(http.StatusOK, rss) +} + +func (s *RSSService) GetUserRSS(c echo.Context) error { + ctx := c.Request().Context() + username := c.Param("username") + user, err := s.Store.GetUser(ctx, &store.FindUser{ + Username: &username, + }) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err) + } + if user == nil { + return echo.NewHTTPError(http.StatusNotFound, "User not found") + } + + normalStatus := store.Normal + memoFind := store.FindMemo{ + CreatorID: &user.ID, + RowStatus: &normalStatus, + VisibilityList: []store.Visibility{store.Public}, + } + memoList, err := s.Store.ListMemos(ctx, &memoFind) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find memo list").SetInternal(err) + } + + baseURL := c.Scheme() + "://" + c.Request().Host + rss, err := s.generateRSSFromMemoList(ctx, memoList, baseURL) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, "Failed to generate rss").SetInternal(err) + } + c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationXMLCharsetUTF8) + return c.String(http.StatusOK, rss) +} + +func (s *RSSService) generateRSSFromMemoList(ctx context.Context, memoList []*store.Memo, baseURL string) (string, error) { + feed := &feeds.Feed{ + Title: "Memos", + Link: &feeds.Link{Href: baseURL}, + Description: "An open source, lightweight note-taking service. Easily capture and share your great thoughts.", + Created: time.Now(), + } + + var itemCountLimit = util.Min(len(memoList), maxRSSItemCount) + feed.Items = make([]*feeds.Item, itemCountLimit) + for i := 0; i < itemCountLimit; i++ { + memo := memoList[i] + description, err := getRSSItemDescription(memo.Content) + if err != nil { + return "", err + } + feed.Items[i] = &feeds.Item{ + Title: getRSSItemTitle(memo.Content), + Link: &feeds.Link{Href: baseURL + "/m/" + memo.ResourceName}, + Description: description, + Created: time.Unix(memo.CreatedTs, 0), + } + resources, err := s.Store.ListResources(ctx, &store.FindResource{ + MemoID: &memo.ID, + }) + if err != nil { + return "", err + } + if len(resources) > 0 { + resource := resources[0] + enclosure := feeds.Enclosure{} + if resource.ExternalLink != "" { + enclosure.Url = resource.ExternalLink + } else { + enclosure.Url = baseURL + "/o/r/" + resource.ResourceName + } + enclosure.Length = strconv.Itoa(int(resource.Size)) + enclosure.Type = resource.Type + feed.Items[i].Enclosure = &enclosure + } + } + + rss, err := feed.ToRss() + if err != nil { + return "", err + } + return rss, nil +} + +func getRSSItemTitle(content string) string { + nodes, _ := gomark.Parse(content) + if len(nodes) > 0 { + firstNode := nodes[0] + title := renderer.NewStringRenderer().Render([]ast.Node{firstNode}) + return title + } + + title := strings.Split(content, "\n")[0] + var titleLengthLimit = util.Min(len(title), maxRSSItemTitleLength) + if titleLengthLimit < len(title) { + title = title[:titleLengthLimit] + "..." + } + return title +} + +func getRSSItemDescription(content string) (string, error) { + nodes, err := gomark.Parse(content) + if err != nil { + return "", err + } + result := renderer.NewHTMLRenderer().Render(nodes) + return result, nil +} diff --git a/server/server.go b/server/server.go index e17cb99c5804b..94c1af42c009d 100644 --- a/server/server.go +++ b/server/server.go @@ -11,20 +11,18 @@ import ( "github.com/go-zoox/logger" "github.com/google/uuid" "github.com/labstack/echo/v4" - "github.com/labstack/echo/v4/middleware" "github.com/pkg/errors" - echoSwagger "github.com/swaggo/echo-swagger" "github.com/go-zoox/connect-middleware-for-echo" "github.com/go-zoox/random" - "github.com/usememos/memos/api/auth" - apiv1 "github.com/usememos/memos/api/v1" - apiv2 "github.com/usememos/memos/api/v2" "github.com/usememos/memos/plugin/telegram" "github.com/usememos/memos/server/integration" "github.com/usememos/memos/server/profile" - "github.com/usememos/memos/server/service/backup" - "github.com/usememos/memos/server/service/metric" + "github.com/usememos/memos/server/route/api/auth" + apiv1 "github.com/usememos/memos/server/route/api/v1" + apiv2 "github.com/usememos/memos/server/route/api/v2" + "github.com/usememos/memos/server/route/frontend" + versionchecker "github.com/usememos/memos/server/service/version_checker" "github.com/usememos/memos/store" storeX "github.com/usememos/memos/store" ) @@ -37,13 +35,8 @@ type Server struct { Profile *profile.Profile Store *store.Store - // API services. - apiV1Service *apiv1.APIV1Service - apiV2Service *apiv2.APIV2Service - // Asynchronous runners. - backupRunner *backup.BackupRunner - telegramBot *telegram.Bot + telegramBot *telegram.Bot } func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store) (*Server, error) { @@ -58,28 +51,34 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store Profile: profile, // Asynchronous runners. - backupRunner: backup.NewBackupRunner(store), - telegramBot: telegram.NewBotWithHandler(integration.NewTelegramHandler(store)), + telegramBot: telegram.NewBotWithHandler(integration.NewTelegramHandler(store)), } - e.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ - Format: `{"time":"${time_rfc3339}","latency":"${latency_human}",` + - `"method":"${method}","uri":"${uri}",` + - `"status":${status},"error":"${error}"}` + "\n", - })) + // Register CORS middleware. + e.Use(CORSMiddleware()) - e.Use(middleware.Gzip()) + serverID, err := s.getSystemServerID(ctx) + if err != nil { + return nil, errors.Wrap(err, "failed to retrieve system server ID") + } + s.ID = serverID - e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ - Skipper: grpcRequestSkipper, - AllowOrigins: []string{"*"}, - AllowMethods: []string{http.MethodGet, http.MethodHead, http.MethodPut, http.MethodPatch, http.MethodPost, http.MethodDelete}, - })) + secret := "usememos" + if profile.Mode == "prod" { + secret, err = s.getSystemSecretSessionName(ctx) + if err != nil { + return nil, errors.Wrap(err, "failed to retrieve system secret session name") + } + } + + s.Secret = secret + apiV1Service := apiv1.NewAPIV1Service(s.Secret, profile, store, s.telegramBot) + apiV2Service := apiv2.NewAPIV2Service(s.Secret, profile, store, s.Profile.Port+1) - e.Use(middleware.TimeoutWithConfig(middleware.TimeoutConfig{ - Skipper: grpcRequestSkipper, - Timeout: 30 * time.Second, - })) + // Register healthz endpoint. + e.GET("/healthz", func(c echo.Context) error { + return c.String(http.StatusOK, "Service ready.") + }) // ######## CONNECT START e.Use(connect.Create(os.Getenv("SECRET_KEY"))) @@ -123,7 +122,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to generate tokens, err: %s", err)).SetInternal(err) } - if err := s.apiV1Service.UpsertAccessTokenToStore(ctx, user, accessToken); err != nil { + if err := apiV1Service.UpsertAccessTokenToStore(ctx, user, accessToken); err != nil { return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to upsert access token, err: %s", err)).SetInternal(err) } cookieExp := time.Now().Add(auth.CookieExpDuration) @@ -152,38 +151,18 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store }) // ######## CONNECT END - serverID, err := s.getSystemServerID(ctx) - if err != nil { - return nil, errors.Wrap(err, "failed to retrieve system server ID") - } - s.ID = serverID - - // Serve frontend. - embedFrontend(e) - - // Serve swagger in dev/demo mode. - if profile.Mode == "dev" || profile.Mode == "demo" { - e.GET("/api/*", echoSwagger.WrapHandler) + // Only serve frontend when it's enabled. + if profile.Frontend { + frontendService := frontend.NewFrontendService(profile, store) + frontendService.Serve(ctx, e) } - secret := "usememos" - if profile.Mode == "prod" { - secret, err = s.getSystemSecretSessionName(ctx) - if err != nil { - return nil, errors.Wrap(err, "failed to retrieve system secret session name") - } - } - s.Secret = secret - + // Register API v1 endpoints. rootGroup := e.Group("") - apiV1Service := apiv1.NewAPIV1Service(s.Secret, profile, store, s.telegramBot) apiV1Service.Register(rootGroup) - s.apiV1Service = apiV1Service - - s.apiV2Service = apiv2.NewAPIV2Service(s.Secret, profile, store, s.Profile.Port+1) // Register gRPC gateway as api v2. - if err := s.apiV2Service.RegisterGateway(ctx, e); err != nil { + if err := apiV2Service.RegisterGateway(ctx, e); err != nil { return nil, errors.Wrap(err, "failed to register gRPC gateway") } @@ -191,10 +170,8 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store } func (s *Server) Start(ctx context.Context) error { + go versionchecker.NewVersionChecker(s.Store, s.Profile).Start(ctx) go s.telegramBot.Start(ctx) - go s.backupRunner.Run(ctx) - - metric.Enqueue("server start") return s.e.Start(fmt.Sprintf("%s:%d", s.Profile.Addr, s.Profile.Port)) } @@ -220,14 +197,14 @@ func (s *Server) GetEcho() *echo.Echo { } func (s *Server) getSystemServerID(ctx context.Context) (string, error) { - serverIDSetting, err := s.Store.GetSystemSetting(ctx, &store.FindSystemSetting{ + serverIDSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{ Name: apiv1.SystemSettingServerIDName.String(), }) if err != nil { return "", err } if serverIDSetting == nil || serverIDSetting.Value == "" { - serverIDSetting, err = s.Store.UpsertSystemSetting(ctx, &store.SystemSetting{ + serverIDSetting, err = s.Store.UpsertWorkspaceSetting(ctx, &store.WorkspaceSetting{ Name: apiv1.SystemSettingServerIDName.String(), Value: uuid.NewString(), }) @@ -239,14 +216,14 @@ func (s *Server) getSystemServerID(ctx context.Context) (string, error) { } func (s *Server) getSystemSecretSessionName(ctx context.Context) (string, error) { - secretSessionNameValue, err := s.Store.GetSystemSetting(ctx, &store.FindSystemSetting{ + secretSessionNameValue, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{ Name: apiv1.SystemSettingSecretSessionName.String(), }) if err != nil { return "", err } if secretSessionNameValue == nil || secretSessionNameValue.Value == "" { - secretSessionNameValue, err = s.Store.UpsertSystemSetting(ctx, &store.SystemSetting{ + secretSessionNameValue, err = s.Store.UpsertWorkspaceSetting(ctx, &store.WorkspaceSetting{ Name: apiv1.SystemSettingSecretSessionName.String(), Value: uuid.NewString(), }) @@ -260,3 +237,28 @@ func (s *Server) getSystemSecretSessionName(ctx context.Context) (string, error) func grpcRequestSkipper(c echo.Context) bool { return strings.HasPrefix(c.Request().URL.Path, "/memos.api.v2.") } + +func CORSMiddleware() echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + if grpcRequestSkipper(c) { + return next(c) + } + + r := c.Request() + w := c.Response().Writer + + w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) + w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") + w.Header().Set("Access-Control-Allow-Credentials", "true") + + // If it's preflight request, return immediately. + if r.Method == "OPTIONS" { + w.WriteHeader(http.StatusOK) + return nil + } + return next(c) + } + } +} diff --git a/server/service/backup/backup.go b/server/service/backup/backup.go deleted file mode 100644 index 399d586dd79f3..0000000000000 --- a/server/service/backup/backup.go +++ /dev/null @@ -1,65 +0,0 @@ -package backup - -import ( - "context" - "fmt" - "strconv" - "time" - - "go.uber.org/zap" - - apiv1 "github.com/usememos/memos/api/v1" - "github.com/usememos/memos/internal/log" - "github.com/usememos/memos/store" -) - -// nolint -type BackupRunner struct { - Store *store.Store -} - -func NewBackupRunner(store *store.Store) *BackupRunner { - return &BackupRunner{ - Store: store, - } -} - -func (r *BackupRunner) Run(ctx context.Context) { - intervalStr := r.Store.GetSystemSettingValueWithDefault(ctx, apiv1.SystemSettingAutoBackupIntervalName.String(), "") - if intervalStr == "" { - log.Debug("no SystemSettingAutoBackupIntervalName setting, disable auto backup") - return - } - - interval, err := strconv.Atoi(intervalStr) - if err != nil || interval < 0 { - log.Error(fmt.Sprintf("invalid SystemSettingAutoBackupIntervalName value %s, disable auto backup", intervalStr), zap.Error(err)) - return - } - - if interval == 0 { - println("AutoBackupIntervalName value is 0, disable auto backup") - return - } - - log.Info("enable auto backup every " + intervalStr + " seconds") - ticker := time.NewTicker(time.Duration(interval) * time.Second) - defer ticker.Stop() - - var t time.Time - for { - select { - case <-ctx.Done(): - log.Info("stop auto backup graceful.") - return - case t = <-ticker.C: - } - - filename := r.Store.Profile.DSN + t.Format("-20060102-150405.bak") - log.Info(fmt.Sprintf("create backup to %s", filename)) - err := r.Store.BackupTo(ctx, filename) - if err != nil { - log.Error("fail to create backup", zap.Error(err)) - } - } -} diff --git a/server/service/metric/metric.go b/server/service/metric/metric.go deleted file mode 100644 index 504dc1e377377..0000000000000 --- a/server/service/metric/metric.go +++ /dev/null @@ -1,52 +0,0 @@ -package metric - -import ( - "github.com/posthog/posthog-go" - - "github.com/usememos/memos/server/profile" -) - -const ( - PostHogAPIKey = "phc_YFEi1aqUBW9sX2KDzdvMtK43DNu0mkeoKMKc0EQum2t" -) - -var ( - client *MetricClient -) - -// nolint -type MetricClient struct { - workspaceID string - profile *profile.Profile - phClient *posthog.Client -} - -func NewMetricClient(workspaceID string, profile profile.Profile) (*MetricClient, error) { - phClient, err := posthog.NewWithConfig(PostHogAPIKey, posthog.Config{ - Endpoint: "https://app.posthog.com", - }) - if err != nil { - return nil, err - } - client = &MetricClient{ - workspaceID: workspaceID, - profile: &profile, - phClient: &phClient, - } - return client, nil -} - -func Enqueue(event string) { - if client == nil { - return - } - if client.profile.Mode != "prod" { - return - } - - // nolint - (*client.phClient).Enqueue(posthog.Capture{ - DistinctId: `memos-` + client.workspaceID, - Event: event, - }) -} diff --git a/server/service/version_checker/version_checker.go b/server/service/version_checker/version_checker.go new file mode 100644 index 0000000000000..0c3459a2ca045 --- /dev/null +++ b/server/service/version_checker/version_checker.go @@ -0,0 +1,137 @@ +package versionchecker + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + "time" + + "github.com/pkg/errors" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/server/profile" + "github.com/usememos/memos/server/version" + "github.com/usememos/memos/store" +) + +// nolint +type VersionChecker struct { + Store *store.Store + Profile *profile.Profile +} + +func NewVersionChecker(store *store.Store, profile *profile.Profile) *VersionChecker { + return &VersionChecker{ + Store: store, + Profile: profile, + } +} + +func (*VersionChecker) GetLatestVersion() (string, error) { + response, err := http.Get("https://www.usememos.com/api/version") + if err != nil { + return "", errors.Wrap(err, "failed to make http request") + } + defer response.Body.Close() + + buf := &bytes.Buffer{} + _, err = buf.ReadFrom(response.Body) + if err != nil { + return "", errors.Wrap(err, "fail to read response body") + } + + version := "" + if err = json.Unmarshal(buf.Bytes(), &version); err != nil { + return "", errors.Wrap(err, "fail to unmarshal get version response") + } + return version, nil +} + +func (c *VersionChecker) Check(ctx context.Context) { + latestVersion, err := c.GetLatestVersion() + if err != nil { + return + } + if !version.IsVersionGreaterThan(latestVersion, version.GetCurrentVersion(c.Profile.Mode)) { + return + } + + versionUpdateActivityType := store.ActivityTypeVersionUpdate + list, err := c.Store.ListActivities(ctx, &store.FindActivity{ + Type: &versionUpdateActivityType, + }) + if err != nil { + return + } + + shouldNotify := true + if len(list) > 0 { + latestVersionUpdateActivity := list[0] + if latestVersionUpdateActivity.Payload != nil && version.IsVersionGreaterOrEqualThan(latestVersionUpdateActivity.Payload.VersionUpdate.Version, latestVersion) { + shouldNotify = false + } + } + + if !shouldNotify { + return + } + + // Create version update activity and inbox message. + activity := &store.Activity{ + CreatorID: store.SystemBotID, + Type: store.ActivityTypeVersionUpdate, + Level: store.ActivityLevelInfo, + Payload: &storepb.ActivityPayload{ + VersionUpdate: &storepb.ActivityVersionUpdatePayload{ + Version: latestVersion, + }, + }, + } + if _, err := c.Store.CreateActivity(ctx, activity); err != nil { + return + } + + hostUserRole := store.RoleHost + users, err := c.Store.ListUsers(ctx, &store.FindUser{ + Role: &hostUserRole, + }) + if err != nil { + return + } + if len(users) == 0 { + return + } + + hostUser := users[0] + if _, err := c.Store.CreateInbox(ctx, &store.Inbox{ + SenderID: store.SystemBotID, + ReceiverID: hostUser.ID, + Status: store.UNREAD, + Message: &storepb.InboxMessage{ + Type: storepb.InboxMessage_TYPE_VERSION_UPDATE, + ActivityId: &activity.ID, + }, + }); err != nil { + fmt.Printf("failed to create inbox: %s\n", err) + } +} + +func (c *VersionChecker) Start(ctx context.Context) { + c.Check(ctx) + + // Schedule checker every 8 hours. + ticker := time.NewTicker(8 * time.Hour) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + } + + c.Check(ctx) + } +} diff --git a/server/service/version_checker/version_checker_test.go b/server/service/version_checker/version_checker_test.go new file mode 100644 index 0000000000000..19a7dc35b5b43 --- /dev/null +++ b/server/service/version_checker/version_checker_test.go @@ -0,0 +1,12 @@ +package versionchecker + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestGetLatestVersion(t *testing.T) { + _, err := NewVersionChecker(nil, nil).GetLatestVersion() + require.NoError(t, err) +} diff --git a/server/version/version.go b/server/version/version.go index 92a9c0b873821..a5a30df4d97b1 100644 --- a/server/version/version.go +++ b/server/version/version.go @@ -9,10 +9,10 @@ import ( // Version is the service current released version. // Semantic versioning: https://semver.org/ -var Version = "0.17.0" +var Version = "0.20.1" // DevVersion is the service current development version. -var DevVersion = "0.17.0" +var DevVersion = "0.20.1" func GetCurrentVersion(mode string) string { if mode == "dev" || mode == "demo" { diff --git a/store/activity.go b/store/activity.go index 3da43db5f081d..59078e213a455 100644 --- a/store/activity.go +++ b/store/activity.go @@ -9,7 +9,8 @@ import ( type ActivityType string const ( - ActivityTypeMemoComment ActivityType = "MEMO_COMMENT" + ActivityTypeMemoComment ActivityType = "MEMO_COMMENT" + ActivityTypeVersionUpdate ActivityType = "VERSION_UPDATE" ) func (t ActivityType) String() string { @@ -40,7 +41,8 @@ type Activity struct { } type FindActivity struct { - ID *int32 + ID *int32 + Type *ActivityType } func (s *Store) CreateActivity(ctx context.Context, create *Activity) (*Activity, error) { diff --git a/store/cache.go b/store/cache.go index 671a6a613d3a8..34c9c9d8d730e 100644 --- a/store/cache.go +++ b/store/cache.go @@ -4,10 +4,6 @@ import ( "fmt" ) -func getUserSettingCacheKey(userID int32, key string) string { - return fmt.Sprintf("%d-%s", userID, key) -} - func getUserSettingV1CacheKey(userID int32, key string) string { return fmt.Sprintf("%d-%s-v1", userID, key) } diff --git a/store/db/db.go b/store/db/db.go index 23386050c126f..47a369385e542 100644 --- a/store/db/db.go +++ b/store/db/db.go @@ -6,6 +6,7 @@ import ( "github.com/usememos/memos/server/profile" "github.com/usememos/memos/store" "github.com/usememos/memos/store/db/mysql" + "github.com/usememos/memos/store/db/postgres" "github.com/usememos/memos/store/db/sqlite" ) @@ -19,6 +20,8 @@ func NewDBDriver(profile *profile.Profile) (store.Driver, error) { driver, err = sqlite.NewDB(profile) case "mysql": driver, err = mysql.NewDB(profile) + case "postgres": + driver, err = postgres.NewDB(profile) default: return nil, errors.New("unknown db driver") } diff --git a/store/db/mysql/activity.go b/store/db/mysql/activity.go index 075aed0f7aa0a..fd36be4e414e4 100644 --- a/store/db/mysql/activity.go +++ b/store/db/mysql/activity.go @@ -24,19 +24,7 @@ func (d *DB) CreateActivity(ctx context.Context, create *store.Activity) (*store placeholder := []string{"?", "?", "?", "?"} args := []any{create.CreatorID, create.Type.String(), create.Level.String(), payloadString} - if create.ID != 0 { - fields = append(fields, "`id`") - placeholder = append(placeholder, "?") - args = append(args, create.ID) - } - - if create.CreatedTs != 0 { - fields = append(fields, "`created_ts`") - placeholder = append(placeholder, "FROM_UNIXTIME(?)") - args = append(args, create.CreatedTs) - } - - stmt := "INSERT INTO activity (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ")" + stmt := "INSERT INTO `activity` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ")" result, err := d.db.ExecContext(ctx, stmt, args...) if err != nil { return nil, errors.Wrap(err, "failed to execute statement") @@ -63,8 +51,11 @@ func (d *DB) ListActivities(ctx context.Context, find *store.FindActivity) ([]*s if find.ID != nil { where, args = append(where, "`id` = ?"), append(args, *find.ID) } + if find.Type != nil { + where, args = append(where, "`type` = ?"), append(args, find.Type.String()) + } - query := "SELECT `id`, `creator_id`, `type`, `level`, `payload`, UNIX_TIMESTAMP(`created_ts`) FROM `activity` WHERE " + strings.Join(where, " AND ") + query := "SELECT `id`, `creator_id`, `type`, `level`, `payload`, UNIX_TIMESTAMP(`created_ts`) FROM `activity` WHERE " + strings.Join(where, " AND ") + " ORDER BY `created_ts` DESC" rows, err := d.db.QueryContext(ctx, query, args...) if err != nil { return nil, err diff --git a/store/db/mysql/idp.go b/store/db/mysql/idp.go index c5fcc7f307810..fd3aad3978975 100644 --- a/store/db/mysql/idp.go +++ b/store/db/mysql/idp.go @@ -26,10 +26,6 @@ func (d *DB) CreateIdentityProvider(ctx context.Context, create *store.IdentityP fields := []string{"`name`", "`type`", "`identifier_filter`", "`config`"} args := []any{create.Name, create.Type, create.IdentifierFilter, string(configBytes)} - if create.ID != 0 { - fields, placeholders, args = append(fields, "`id`"), append(placeholders, "?"), append(args, create.ID) - } - stmt := "INSERT INTO `idp` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholders, ", ") + ")" result, err := d.db.ExecContext(ctx, stmt, args...) if err != nil { diff --git a/store/db/mysql/inbox.go b/store/db/mysql/inbox.go index ad80e0a8a062a..db8df0d5c084c 100644 --- a/store/db/mysql/inbox.go +++ b/store/db/mysql/inbox.go @@ -2,6 +2,7 @@ package mysql import ( "context" + "database/sql" "strings" "github.com/pkg/errors" @@ -132,3 +133,13 @@ func (d *DB) DeleteInbox(ctx context.Context, delete *store.DeleteInbox) error { } return nil } + +func vacuumInbox(ctx context.Context, tx *sql.Tx) error { + stmt := "DELETE FROM `inbox` WHERE `sender_id` NOT IN (SELECT `id` FROM `user`)" + _, err := tx.ExecContext(ctx, stmt) + if err != nil { + return err + } + + return nil +} diff --git a/store/db/mysql/memo.go b/store/db/mysql/memo.go index 0aeb208548f0c..5b2e053554277 100644 --- a/store/db/mysql/memo.go +++ b/store/db/mysql/memo.go @@ -8,40 +8,15 @@ import ( "github.com/pkg/errors" - "github.com/usememos/memos/internal/util" "github.com/usememos/memos/store" ) func (d *DB) CreateMemo(ctx context.Context, create *store.Memo) (*store.Memo, error) { - fields := []string{"`creator_id`", "`content`", "`visibility`"} - placeholder := []string{"?", "?", "?"} - args := []any{create.CreatorID, create.Content, create.Visibility} + fields := []string{"`resource_name`", "`creator_id`", "`content`", "`visibility`"} + placeholder := []string{"?", "?", "?", "?"} + args := []any{create.ResourceName, create.CreatorID, create.Content, create.Visibility} - if create.ID != 0 { - fields = append(fields, "`id`") - placeholder = append(placeholder, "?") - args = append(args, create.ID) - } - - if create.CreatedTs != 0 { - fields = append(fields, "`created_ts`") - placeholder = append(placeholder, "FROM_UNIXTIME(?)") - args = append(args, create.CreatedTs) - } - - if create.UpdatedTs != 0 { - fields = append(fields, "`updated_ts`") - placeholder = append(placeholder, "FROM_UNIXTIME(?)") - args = append(args, create.UpdatedTs) - } - - if create.RowStatus != "" { - fields = append(fields, "`row_status`") - placeholder = append(placeholder, "?") - args = append(args, create.RowStatus) - } - - stmt := "INSERT INTO memo (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ")" + stmt := "INSERT INTO `memo` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ")" result, err := d.db.ExecContext(ctx, stmt, args...) if err != nil { return nil, err @@ -63,11 +38,14 @@ func (d *DB) CreateMemo(ctx context.Context, create *store.Memo) (*store.Memo, e } func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo, error) { - where, args := []string{"1 = 1"}, []any{} + where, having, args := []string{"1 = 1"}, []string{"1 = 1"}, []any{} if v := find.ID; v != nil { where, args = append(where, "`memo`.`id` = ?"), append(args, *v) } + if v := find.ResourceName; v != nil { + where, args = append(where, "`memo`.`resource_name` = ?"), append(args, *v) + } if v := find.CreatorID; v != nil { where, args = append(where, "`memo`.`creator_id` = ?"), append(args, *v) } @@ -80,8 +58,11 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo if v := find.CreatedTsAfter; v != nil { where, args = append(where, "UNIX_TIMESTAMP(`memo`.`created_ts`) > ?"), append(args, *v) } - if v := find.Pinned; v != nil { - where = append(where, "`memo_organizer`.`pinned` = 1") + if v := find.UpdatedTsBefore; v != nil { + where, args = append(where, "UNIX_TIMESTAMP(`memo`.`updated_ts`) < ?"), append(args, *v) + } + if v := find.UpdatedTsAfter; v != nil { + where, args = append(where, "UNIX_TIMESTAMP(`memo`.`updated_ts`) > ?"), append(args, *v) } if v := find.ContentSearch; len(v) != 0 { for _, s := range v { @@ -89,14 +70,21 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo } } if v := find.VisibilityList; len(v) != 0 { - list := []string{} + placeholder := []string{} for _, visibility := range v { - list = append(list, "?") - args = append(args, visibility) + placeholder = append(placeholder, "?") + args = append(args, visibility.String()) } - where = append(where, fmt.Sprintf("`memo`.`visibility` in (%s)", strings.Join(list, ","))) + where = append(where, fmt.Sprintf("`memo`.`visibility` in (%s)", strings.Join(placeholder, ","))) + } + if find.ExcludeComments { + having = append(having, "`parent_id` IS NULL") + } + + orders := []string{} + if find.OrderByPinned { + orders = append(orders, "`pinned` DESC") } - orders := []string{"`pinned` DESC"} if find.OrderByUpdatedTs { orders = append(orders, "`updated_ts` DESC") } else { @@ -104,7 +92,22 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo } orders = append(orders, "`id` DESC") - query := "SELECT `memo`.`id` AS `id`, `memo`.`creator_id` AS `creator_id`, UNIX_TIMESTAMP(`memo`.`created_ts`) AS `created_ts`, UNIX_TIMESTAMP(`memo`.`updated_ts`) AS `updated_ts`, `memo`.`row_status` AS `row_status`, `memo`.`content` AS `content`, `memo`.`visibility` AS `visibility`, MAX(CASE WHEN `memo_organizer`.`pinned` = 1 THEN 1 ELSE 0 END) AS `pinned`, GROUP_CONCAT(`resource`.`id`) AS `resource_id_list`, (SELECT GROUP_CONCAT(`memo_id`,':',`related_memo_id`,':',`type`) FROM `memo_relation` WHERE `memo_relation`.`memo_id` = `memo`.`id` OR `memo_relation`.`related_memo_id` = `memo`.`id` ) AS `relation_list` FROM `memo` LEFT JOIN `memo_organizer` ON `memo`.`id` = `memo_organizer`.`memo_id` LEFT JOIN `resource` ON `memo`.`id` = `resource`.`memo_id` WHERE " + strings.Join(where, " AND ") + " GROUP BY `memo`.`id` ORDER BY " + strings.Join(orders, ", ") + fields := []string{ + "`memo`.`id` AS `id`", + "`memo`.`resource_name` AS `resource_name`", + "`memo`.`creator_id` AS `creator_id`", + "UNIX_TIMESTAMP(`memo`.`created_ts`) AS `created_ts`", + "UNIX_TIMESTAMP(`memo`.`updated_ts`) AS `updated_ts`", + "`memo`.`row_status` AS `row_status`", + "`memo`.`visibility` AS `visibility`", + "IFNULL(`memo_organizer`.`pinned`, 0) AS `pinned`", + "`memo_relation`.`related_memo_id` AS `parent_id`", + } + if !find.ExcludeContent { + fields = append(fields, "`memo`.`content` AS `content`") + } + + query := "SELECT " + strings.Join(fields, ", ") + " FROM `memo` LEFT JOIN `memo_organizer` ON `memo`.`id` = `memo_organizer`.`memo_id` AND `memo`.`creator_id` = `memo_organizer`.`user_id` LEFT JOIN `memo_relation` ON `memo`.`id` = `memo_relation`.`memo_id` AND `memo_relation`.`type` = \"COMMENT\" WHERE " + strings.Join(where, " AND ") + " HAVING " + strings.Join(having, " AND ") + " ORDER BY " + strings.Join(orders, ", ") if find.Limit != nil { query = fmt.Sprintf("%s LIMIT %d", query, *find.Limit) if find.Offset != nil { @@ -121,61 +124,22 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo list := make([]*store.Memo, 0) for rows.Next() { var memo store.Memo - var memoResourceIDList sql.NullString - var memoRelationList sql.NullString - if err := rows.Scan( + dests := []any{ &memo.ID, + &memo.ResourceName, &memo.CreatorID, &memo.CreatedTs, &memo.UpdatedTs, &memo.RowStatus, - &memo.Content, &memo.Visibility, &memo.Pinned, - &memoResourceIDList, - &memoRelationList, - ); err != nil { - return nil, err + &memo.ParentID, } - - if memoResourceIDList.Valid { - idStringList := strings.Split(memoResourceIDList.String, ",") - memo.ResourceIDList = make([]int32, 0, len(idStringList)) - for _, idString := range idStringList { - id, err := util.ConvertStringToInt32(idString) - if err != nil { - return nil, err - } - memo.ResourceIDList = append(memo.ResourceIDList, id) - } + if !find.ExcludeContent { + dests = append(dests, &memo.Content) } - if memoRelationList.Valid { - memo.RelationList = make([]*store.MemoRelation, 0) - relatedMemoTypeList := strings.Split(memoRelationList.String, ",") - for _, relatedMemoType := range relatedMemoTypeList { - relatedMemoTypeList := strings.Split(relatedMemoType, ":") - if len(relatedMemoTypeList) != 3 { - return nil, errors.Errorf("invalid relation format") - } - memoID, err := util.ConvertStringToInt32(relatedMemoTypeList[0]) - if err != nil { - return nil, err - } - relatedMemoID, err := util.ConvertStringToInt32(relatedMemoTypeList[1]) - if err != nil { - return nil, err - } - relationType := store.MemoRelationType(relatedMemoTypeList[2]) - memo.RelationList = append(memo.RelationList, &store.MemoRelation{ - MemoID: memoID, - RelatedMemoID: relatedMemoID, - Type: relationType, - }) - // Set the first parent ID if relation type is comment. - if memo.ParentID == nil && memoID == memo.ID && relationType == store.MemoRelationComment { - memo.ParentID = &relatedMemoID - } - } + if err := rows.Scan(dests...); err != nil { + return nil, err } list = append(list, &memo) } @@ -202,6 +166,9 @@ func (d *DB) GetMemo(ctx context.Context, find *store.FindMemo) (*store.Memo, er func (d *DB) UpdateMemo(ctx context.Context, update *store.UpdateMemo) error { set, args := []string{}, []any{} + if v := update.ResourceName; v != nil { + set, args = append(set, "`resource_name` = ?"), append(args, *v) + } if v := update.CreatedTs; v != nil { set, args = append(set, "`created_ts` = FROM_UNIXTIME(?)"), append(args, *v) } @@ -244,38 +211,6 @@ func (d *DB) DeleteMemo(ctx context.Context, delete *store.DeleteMemo) error { return nil } -func (d *DB) FindMemosVisibilityList(ctx context.Context, memoIDs []int32) ([]store.Visibility, error) { - args := make([]any, 0, len(memoIDs)) - list := make([]string, 0, len(memoIDs)) - for _, memoID := range memoIDs { - args = append(args, memoID) - list = append(list, "?") - } - - where := fmt.Sprintf("`id` in (%s)", strings.Join(list, ",")) - query := "SELECT DISTINCT(`visibility`) FROM `memo` WHERE " + where - rows, err := d.db.QueryContext(ctx, query, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - visibilityList := make([]store.Visibility, 0) - for rows.Next() { - var visibility store.Visibility - if err := rows.Scan(&visibility); err != nil { - return nil, err - } - visibilityList = append(visibilityList, visibility) - } - - if err := rows.Err(); err != nil { - return nil, err - } - - return visibilityList, nil -} - func vacuumMemo(ctx context.Context, tx *sql.Tx) error { stmt := "DELETE FROM `memo` WHERE `creator_id` NOT IN (SELECT `id` FROM `user`)" _, err := tx.ExecContext(ctx, stmt) diff --git a/store/db/mysql/migration/dev/LATEST__SCHEMA.sql b/store/db/mysql/migration/dev/LATEST__SCHEMA.sql index e9f9551a2fc08..f69bbe308b8a7 100644 --- a/store/db/mysql/migration/dev/LATEST__SCHEMA.sql +++ b/store/db/mysql/migration/dev/LATEST__SCHEMA.sql @@ -1,27 +1,12 @@ --- drop all tables first -DROP TABLE IF EXISTS `migration_history`; -DROP TABLE IF EXISTS `system_setting`; -DROP TABLE IF EXISTS `user`; -DROP TABLE IF EXISTS `user_setting`; -DROP TABLE IF EXISTS `memo`; -DROP TABLE IF EXISTS `memo_organizer`; -DROP TABLE IF EXISTS `memo_relation`; -DROP TABLE IF EXISTS `resource`; -DROP TABLE IF EXISTS `tag`; -DROP TABLE IF EXISTS `activity`; -DROP TABLE IF EXISTS `storage`; -DROP TABLE IF EXISTS `idp`; -DROP TABLE IF EXISTS `inbox`; - -- migration_history CREATE TABLE `migration_history` ( - `version` VARCHAR(255) NOT NULL PRIMARY KEY, + `version` VARCHAR(256) NOT NULL PRIMARY KEY, `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); -- system_setting CREATE TABLE `system_setting` ( - `name` VARCHAR(255) NOT NULL PRIMARY KEY, + `name` VARCHAR(256) NOT NULL PRIMARY KEY, `value` LONGTEXT NOT NULL, `description` TEXT NOT NULL ); @@ -31,19 +16,19 @@ CREATE TABLE `user` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - `row_status` VARCHAR(255) NOT NULL DEFAULT 'NORMAL', - `username` VARCHAR(255) NOT NULL UNIQUE, - `role` VARCHAR(255) NOT NULL DEFAULT 'USER', - `email` VARCHAR(255) NOT NULL DEFAULT '', - `nickname` VARCHAR(255) NOT NULL DEFAULT '', - `password_hash` VARCHAR(255) NOT NULL, + `row_status` VARCHAR(256) NOT NULL DEFAULT 'NORMAL', + `username` VARCHAR(256) NOT NULL UNIQUE, + `role` VARCHAR(256) NOT NULL DEFAULT 'USER', + `email` VARCHAR(256) NOT NULL DEFAULT '', + `nickname` VARCHAR(256) NOT NULL DEFAULT '', + `password_hash` VARCHAR(256) NOT NULL, `avatar_url` LONGTEXT NOT NULL ); -- user_setting CREATE TABLE `user_setting` ( `user_id` INT NOT NULL, - `key` VARCHAR(255) NOT NULL, + `key` VARCHAR(256) NOT NULL, `value` LONGTEXT NOT NULL, UNIQUE(`user_id`,`key`) ); @@ -51,12 +36,13 @@ CREATE TABLE `user_setting` ( -- memo CREATE TABLE `memo` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + `resource_name` VARCHAR(256) NOT NULL UNIQUE, `creator_id` INT NOT NULL, `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - `row_status` VARCHAR(255) NOT NULL DEFAULT 'NORMAL', + `row_status` VARCHAR(256) NOT NULL DEFAULT 'NORMAL', `content` TEXT NOT NULL, - `visibility` VARCHAR(255) NOT NULL DEFAULT 'PRIVATE' + `visibility` VARCHAR(256) NOT NULL DEFAULT 'PRIVATE' ); -- memo_organizer @@ -78,21 +64,22 @@ CREATE TABLE `memo_relation` ( -- resource CREATE TABLE `resource` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + `resource_name` VARCHAR(256) NOT NULL UNIQUE, `creator_id` INT NOT NULL, `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `filename` TEXT NOT NULL, `blob` MEDIUMBLOB, `external_link` TEXT NOT NULL, - `type` VARCHAR(255) NOT NULL DEFAULT '', + `type` VARCHAR(256) NOT NULL DEFAULT '', `size` INT NOT NULL DEFAULT '0', - `internal_path` VARCHAR(255) NOT NULL DEFAULT '', + `internal_path` VARCHAR(256) NOT NULL DEFAULT '', `memo_id` INT DEFAULT NULL ); -- tag CREATE TABLE `tag` ( - `name` VARCHAR(255) NOT NULL, + `name` VARCHAR(256) NOT NULL, `creator_id` INT NOT NULL, UNIQUE(`name`,`creator_id`) ); @@ -102,8 +89,8 @@ CREATE TABLE `activity` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `creator_id` INT NOT NULL, `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - `type` VARCHAR(255) NOT NULL DEFAULT '', - `level` VARCHAR(255) NOT NULL DEFAULT 'INFO', + `type` VARCHAR(256) NOT NULL DEFAULT '', + `level` VARCHAR(256) NOT NULL DEFAULT 'INFO', `payload` TEXT NOT NULL ); @@ -131,5 +118,26 @@ CREATE TABLE `inbox` ( `sender_id` INT NOT NULL, `receiver_id` INT NOT NULL, `status` TEXT NOT NULL, - `message` TEXT NOT NULL DEFAULT '{}' + `message` TEXT NOT NULL +); + +-- webhook +CREATE TABLE `webhook` ( + `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `row_status` VARCHAR(256) NOT NULL DEFAULT 'NORMAL', + `creator_id` INT NOT NULL, + `name` TEXT NOT NULL, + `url` TEXT NOT NULL +); + +-- reaction +CREATE TABLE `reaction` ( + `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `creator_id` INT NOT NULL, + `content_id` VARCHAR(256) NOT NULL, + `reaction_type` VARCHAR(256) NOT NULL, + UNIQUE(`creator_id`,`content_id`,`reaction_type`) ); diff --git a/store/db/mysql/migration/prod/0.18/01__webhook.sql b/store/db/mysql/migration/prod/0.18/01__webhook.sql new file mode 100644 index 0000000000000..937f333e03cf4 --- /dev/null +++ b/store/db/mysql/migration/prod/0.18/01__webhook.sql @@ -0,0 +1,10 @@ +-- webhook +CREATE TABLE `webhook` ( + `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `row_status` VARCHAR(256) NOT NULL DEFAULT 'NORMAL', + `creator_id` INT NOT NULL, + `name` TEXT NOT NULL, + `url` TEXT NOT NULL +); diff --git a/store/db/mysql/migration/prod/0.18/02__user_setting.sql b/store/db/mysql/migration/prod/0.18/02__user_setting.sql new file mode 100644 index 0000000000000..99709e43e5c50 --- /dev/null +++ b/store/db/mysql/migration/prod/0.18/02__user_setting.sql @@ -0,0 +1,4 @@ +UPDATE `user_setting` SET `key` = 'USER_SETTING_LOCALE', `value` = REPLACE(`value`, '"', '') WHERE `key` = 'locale'; +UPDATE `user_setting` SET `key` = 'USER_SETTING_APPEARANCE', `value` = REPLACE(`value`, '"', '') WHERE `key` = 'appearance'; +UPDATE `user_setting` SET `key` = 'USER_SETTING_MEMO_VISIBILITY', `value` = REPLACE(`value`, '"', '') WHERE `key` = 'memo-visibility'; +UPDATE `user_setting` SET `key` = 'USER_SETTING_TELEGRAM_USER_ID', `value` = REPLACE(`value`, '"', '') WHERE `key` = 'telegram-user-id'; diff --git a/store/db/mysql/migration/prod/0.19/00__add_resource_name.sql b/store/db/mysql/migration/prod/0.19/00__add_resource_name.sql new file mode 100644 index 0000000000000..4625691433e08 --- /dev/null +++ b/store/db/mysql/migration/prod/0.19/00__add_resource_name.sql @@ -0,0 +1,15 @@ +ALTER TABLE `memo` ADD COLUMN `resource_name` VARCHAR(256) AFTER `id`; + +UPDATE `memo` SET `resource_name` = uuid(); + +ALTER TABLE `memo` MODIFY COLUMN `resource_name` VARCHAR(256) NOT NULL; + +CREATE UNIQUE INDEX idx_memo_resource_name ON `memo` (`resource_name`); + +ALTER TABLE `resource` ADD COLUMN `resource_name` VARCHAR(256) AFTER `id`; + +UPDATE `resource` SET `resource_name` = uuid(); + +ALTER TABLE `resource` MODIFY COLUMN `resource_name` VARCHAR(256) NOT NULL; + +CREATE UNIQUE INDEX idx_resource_resource_name ON `resource` (`resource_name`); diff --git a/store/db/mysql/migration/prod/0.20/00__reaction.sql b/store/db/mysql/migration/prod/0.20/00__reaction.sql new file mode 100644 index 0000000000000..a25a1bafd4937 --- /dev/null +++ b/store/db/mysql/migration/prod/0.20/00__reaction.sql @@ -0,0 +1,9 @@ +-- reaction +CREATE TABLE `reaction` ( + `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `creator_id` INT NOT NULL, + `content_id` VARCHAR(256) NOT NULL, + `reaction_type` VARCHAR(256) NOT NULL, + UNIQUE(`creator_id`,`content_id`,`reaction_type`) +); diff --git a/store/db/mysql/migration/prod/LATEST__SCHEMA.sql b/store/db/mysql/migration/prod/LATEST__SCHEMA.sql index 005595bcece0c..f69bbe308b8a7 100644 --- a/store/db/mysql/migration/prod/LATEST__SCHEMA.sql +++ b/store/db/mysql/migration/prod/LATEST__SCHEMA.sql @@ -1,27 +1,12 @@ --- drop all tables first -DROP TABLE IF EXISTS `migration_history`; -DROP TABLE IF EXISTS `system_setting`; -DROP TABLE IF EXISTS `user`; -DROP TABLE IF EXISTS `user_setting`; -DROP TABLE IF EXISTS `memo`; -DROP TABLE IF EXISTS `memo_organizer`; -DROP TABLE IF EXISTS `memo_relation`; -DROP TABLE IF EXISTS `resource`; -DROP TABLE IF EXISTS `tag`; -DROP TABLE IF EXISTS `activity`; -DROP TABLE IF EXISTS `storage`; -DROP TABLE IF EXISTS `idp`; -DROP TABLE IF EXISTS `inbox`; - -- migration_history CREATE TABLE `migration_history` ( - `version` VARCHAR(255) NOT NULL PRIMARY KEY, + `version` VARCHAR(256) NOT NULL PRIMARY KEY, `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); -- system_setting CREATE TABLE `system_setting` ( - `name` VARCHAR(255) NOT NULL PRIMARY KEY, + `name` VARCHAR(256) NOT NULL PRIMARY KEY, `value` LONGTEXT NOT NULL, `description` TEXT NOT NULL ); @@ -31,19 +16,19 @@ CREATE TABLE `user` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - `row_status` VARCHAR(255) NOT NULL DEFAULT 'NORMAL', - `username` VARCHAR(255) NOT NULL UNIQUE, - `role` VARCHAR(255) NOT NULL DEFAULT 'USER', - `email` VARCHAR(255) NOT NULL DEFAULT '', - `nickname` VARCHAR(255) NOT NULL DEFAULT '', - `password_hash` VARCHAR(255) NOT NULL, + `row_status` VARCHAR(256) NOT NULL DEFAULT 'NORMAL', + `username` VARCHAR(256) NOT NULL UNIQUE, + `role` VARCHAR(256) NOT NULL DEFAULT 'USER', + `email` VARCHAR(256) NOT NULL DEFAULT '', + `nickname` VARCHAR(256) NOT NULL DEFAULT '', + `password_hash` VARCHAR(256) NOT NULL, `avatar_url` LONGTEXT NOT NULL ); -- user_setting CREATE TABLE `user_setting` ( `user_id` INT NOT NULL, - `key` VARCHAR(255) NOT NULL, + `key` VARCHAR(256) NOT NULL, `value` LONGTEXT NOT NULL, UNIQUE(`user_id`,`key`) ); @@ -51,12 +36,13 @@ CREATE TABLE `user_setting` ( -- memo CREATE TABLE `memo` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + `resource_name` VARCHAR(256) NOT NULL UNIQUE, `creator_id` INT NOT NULL, `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - `row_status` VARCHAR(255) NOT NULL DEFAULT 'NORMAL', + `row_status` VARCHAR(256) NOT NULL DEFAULT 'NORMAL', `content` TEXT NOT NULL, - `visibility` VARCHAR(255) NOT NULL DEFAULT 'PRIVATE' + `visibility` VARCHAR(256) NOT NULL DEFAULT 'PRIVATE' ); -- memo_organizer @@ -78,21 +64,22 @@ CREATE TABLE `memo_relation` ( -- resource CREATE TABLE `resource` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + `resource_name` VARCHAR(256) NOT NULL UNIQUE, `creator_id` INT NOT NULL, `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `filename` TEXT NOT NULL, `blob` MEDIUMBLOB, `external_link` TEXT NOT NULL, - `type` VARCHAR(255) NOT NULL DEFAULT '', + `type` VARCHAR(256) NOT NULL DEFAULT '', `size` INT NOT NULL DEFAULT '0', - `internal_path` VARCHAR(255) NOT NULL DEFAULT '', + `internal_path` VARCHAR(256) NOT NULL DEFAULT '', `memo_id` INT DEFAULT NULL ); -- tag CREATE TABLE `tag` ( - `name` VARCHAR(255) NOT NULL, + `name` VARCHAR(256) NOT NULL, `creator_id` INT NOT NULL, UNIQUE(`name`,`creator_id`) ); @@ -102,8 +89,8 @@ CREATE TABLE `activity` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `creator_id` INT NOT NULL, `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - `type` VARCHAR(255) NOT NULL DEFAULT '', - `level` VARCHAR(255) NOT NULL DEFAULT 'INFO', + `type` VARCHAR(256) NOT NULL DEFAULT '', + `level` VARCHAR(256) NOT NULL DEFAULT 'INFO', `payload` TEXT NOT NULL ); @@ -133,3 +120,24 @@ CREATE TABLE `inbox` ( `status` TEXT NOT NULL, `message` TEXT NOT NULL ); + +-- webhook +CREATE TABLE `webhook` ( + `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `row_status` VARCHAR(256) NOT NULL DEFAULT 'NORMAL', + `creator_id` INT NOT NULL, + `name` TEXT NOT NULL, + `url` TEXT NOT NULL +); + +-- reaction +CREATE TABLE `reaction` ( + `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + `created_ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `creator_id` INT NOT NULL, + `content_id` VARCHAR(256) NOT NULL, + `reaction_type` VARCHAR(256) NOT NULL, + UNIQUE(`creator_id`,`content_id`,`reaction_type`) +); diff --git a/store/db/mysql/migration_history.go b/store/db/mysql/migration_history.go index 8eca1768d60d3..bc6c89fc4d849 100644 --- a/store/db/mysql/migration_history.go +++ b/store/db/mysql/migration_history.go @@ -2,39 +2,21 @@ package mysql import ( "context" - "strings" -) - -type MigrationHistory struct { - Version string - CreatedTs int64 -} -type MigrationHistoryUpsert struct { - Version string -} - -type MigrationHistoryFind struct { - Version *string -} - -func (d *DB) FindMigrationHistoryList(ctx context.Context, find *MigrationHistoryFind) ([]*MigrationHistory, error) { - where, args := []string{"1 = 1"}, []any{} - - if v := find.Version; v != nil { - where, args = append(where, "`version` = ?"), append(args, *v) - } + "github.com/usememos/memos/store" +) - query := "SELECT `version`, UNIX_TIMESTAMP(`created_ts`) FROM `migration_history` WHERE " + strings.Join(where, " AND ") + " ORDER BY `created_ts` DESC" - rows, err := d.db.QueryContext(ctx, query, args...) +func (d *DB) FindMigrationHistoryList(ctx context.Context, _ *store.FindMigrationHistory) ([]*store.MigrationHistory, error) { + query := "SELECT `version`, UNIX_TIMESTAMP(`created_ts`) FROM `migration_history` ORDER BY `created_ts` DESC" + rows, err := d.db.QueryContext(ctx, query) if err != nil { return nil, err } defer rows.Close() - list := make([]*MigrationHistory, 0) + list := make([]*store.MigrationHistory, 0) for rows.Next() { - var migrationHistory MigrationHistory + var migrationHistory store.MigrationHistory if err := rows.Scan( &migrationHistory.Version, &migrationHistory.CreatedTs, @@ -52,14 +34,14 @@ func (d *DB) FindMigrationHistoryList(ctx context.Context, find *MigrationHistor return list, nil } -func (d *DB) UpsertMigrationHistory(ctx context.Context, upsert *MigrationHistoryUpsert) (*MigrationHistory, error) { +func (d *DB) UpsertMigrationHistory(ctx context.Context, upsert *store.UpsertMigrationHistory) (*store.MigrationHistory, error) { stmt := "INSERT INTO `migration_history` (`version`) VALUES (?) ON DUPLICATE KEY UPDATE `version` = ?" _, err := d.db.ExecContext(ctx, stmt, upsert.Version, upsert.Version) if err != nil { return nil, err } - var migrationHistory MigrationHistory + var migrationHistory store.MigrationHistory stmt = "SELECT `version`, UNIX_TIMESTAMP(`created_ts`) FROM `migration_history` WHERE `version` = ?" if err := d.db.QueryRowContext(ctx, stmt, upsert.Version).Scan( &migrationHistory.Version, @@ -67,6 +49,5 @@ func (d *DB) UpsertMigrationHistory(ctx context.Context, upsert *MigrationHistor ); err != nil { return nil, err } - return &migrationHistory, nil } diff --git a/store/db/mysql/migrator.go b/store/db/mysql/migrator.go index 6b5c049b624c8..0c54e4abd85da 100644 --- a/store/db/mysql/migrator.go +++ b/store/db/mysql/migrator.go @@ -12,15 +12,16 @@ import ( "github.com/pkg/errors" "github.com/usememos/memos/server/version" + "github.com/usememos/memos/store" ) +//go:embed migration +var migrationFS embed.FS + const ( latestSchemaFileName = "LATEST__SCHEMA.sql" ) -//go:embed migration -var migrationFS embed.FS - func (d *DB) Migrate(ctx context.Context) error { if d.profile.IsDev() { return d.nonProdMigrate(ctx) @@ -53,8 +54,6 @@ func (d *DB) nonProdMigrate(ctx context.Context) error { return nil } - println("no tables in the database. start migration") - buf, err := migrationFS.ReadFile("migration/dev/" + latestSchemaFileName) if err != nil { return errors.Errorf("failed to read latest schema file: %s", err) @@ -64,31 +63,22 @@ func (d *DB) nonProdMigrate(ctx context.Context) error { if _, err := d.db.ExecContext(ctx, stmt); err != nil { return errors.Errorf("failed to exec SQL %s: %s", stmt, err) } - - // In demo mode, we should seed the database. - if d.profile.Mode == "demo" { - if err := d.seed(ctx); err != nil { - return errors.Wrap(err, "failed to seed") - } - } return nil } func (d *DB) prodMigrate(ctx context.Context) error { currentVersion := version.GetCurrentVersion(d.profile.Mode) - migrationHistoryList, err := d.FindMigrationHistoryList(ctx, &MigrationHistoryFind{}) + migrationHistoryList, err := d.FindMigrationHistoryList(ctx, &store.FindMigrationHistory{}) // If there is no migration history, we should apply the latest schema. if err != nil || len(migrationHistoryList) == 0 { buf, err := migrationFS.ReadFile("migration/prod/" + latestSchemaFileName) if err != nil { return errors.Errorf("failed to read latest schema file: %s", err) } - - stmt := string(buf) - if _, err := d.db.ExecContext(ctx, stmt); err != nil { - return errors.Errorf("failed to exec SQL %s: %s", stmt, err) + if _, err := d.db.ExecContext(ctx, string(buf)); err != nil { + return errors.Errorf("failed to exec latest schema: %s", err) } - if _, err := d.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{ + if _, err := d.UpsertMigrationHistory(ctx, &store.UpsertMigrationHistory{ Version: currentVersion, }); err != nil { return errors.Wrap(err, "failed to upsert migration history") @@ -106,17 +96,17 @@ func (d *DB) prodMigrate(ctx context.Context) error { return nil } - println("start migrate") + fmt.Println("start to migrate database schema") for _, minorVersion := range getMinorVersionList() { normalizedVersion := minorVersion + ".0" if version.IsVersionGreaterThan(normalizedVersion, latestMigrationHistoryVersion) && version.IsVersionGreaterOrEqualThan(currentVersion, normalizedVersion) { - println("applying migration for", normalizedVersion) + fmt.Println("applying migration of", normalizedVersion) if err := d.applyMigrationForMinorVersion(ctx, minorVersion); err != nil { return errors.Wrap(err, "failed to apply minor version migration") } } } - println("end migrate") + fmt.Println("end migrate") return nil } @@ -145,42 +135,13 @@ func (d *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion str // Upsert the newest version to migration_history. version := minorVersion + ".0" - if _, err = d.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{Version: version}); err != nil { + if _, err = d.UpsertMigrationHistory(ctx, &store.UpsertMigrationHistory{Version: version}); err != nil { return errors.Wrapf(err, "failed to upsert migration history with version: %s", version) } return nil } -//go:embed seed -var seedFS embed.FS - -func (d *DB) seed(ctx context.Context) error { - filenames, err := fs.Glob(seedFS, "seed/*.sql") - if err != nil { - return errors.Wrap(err, "failed to read seed files") - } - - sort.Strings(filenames) - // Loop over all seed files and execute them in order. - for _, filename := range filenames { - buf, err := seedFS.ReadFile(filename) - if err != nil { - return errors.Wrapf(err, "failed to read seed file, filename=%s", filename) - } - - for _, stmt := range strings.Split(string(buf), ";") { - if strings.TrimSpace(stmt) == "" { - continue - } - if _, err := d.db.ExecContext(ctx, stmt); err != nil { - return errors.Wrapf(err, "seed error: %s", stmt) - } - } - } - return nil -} - // minorDirRegexp is a regular expression for minor version directory. var minorDirRegexp = regexp.MustCompile(`^migration/prod/[0-9]+\.[0-9]+$`) diff --git a/store/db/mysql/mysql.go b/store/db/mysql/mysql.go index fa9c069154c33..3dee829bbd640 100644 --- a/store/db/mysql/mysql.go +++ b/store/db/mysql/mysql.go @@ -3,12 +3,11 @@ package mysql import ( "context" "database/sql" - "fmt" + "log/slog" "github.com/go-sql-driver/mysql" "github.com/pkg/errors" - "github.com/usememos/memos/internal/log" "github.com/usememos/memos/server/profile" "github.com/usememos/memos/store" ) @@ -23,13 +22,14 @@ func NewDB(profile *profile.Profile) (store.Driver, error) { // Open MySQL connection with parameter. // multiStatements=true is required for migration. // See more in: https://github.com/go-sql-driver/mysql#multistatements - dsn := fmt.Sprintf("%s?multiStatements=true", profile.DSN) + dsn, err := mergeDSN(profile.DSN) + if err != nil { + return nil, err + } - var err error driver := DB{profile: profile} driver.config, err = mysql.ParseDSN(dsn) if err != nil { - log.Error(fmt.Sprintf("DSN parse error: %s", dsn)) return nil, errors.New("Parse DSN eroor") } @@ -67,6 +67,9 @@ func (d *DB) Vacuum(ctx context.Context) error { if err := vacuumMemoRelations(ctx, tx); err != nil { return err } + if err := vacuumInbox(ctx, tx); err != nil { + return err + } if err := vacuumTag(ctx, tx); err != nil { // Prevent revive warning. return err @@ -75,10 +78,6 @@ func (d *DB) Vacuum(ctx context.Context) error { return tx.Commit() } -func (*DB) BackupTo(context.Context, string) error { - return errors.New("Please use mysqldump to backup") -} - func (d *DB) GetCurrentDBSize(ctx context.Context) (int64, error) { query := "SELECT SUM(`data_length` + `index_length`) AS `size` " + " FROM information_schema.TABLES" + @@ -86,7 +85,7 @@ func (d *DB) GetCurrentDBSize(ctx context.Context) (int64, error) { " GROUP BY `table_schema`" rows, err := d.db.QueryContext(ctx, query, d.config.DBName) if err != nil { - log.Error("Query db size error, make sure you have enough privilege") + slog.Error("Query db size error, make sure you have enough privilege", err) return 0, err } defer rows.Close() @@ -108,3 +107,13 @@ func (d *DB) GetCurrentDBSize(ctx context.Context) (int64, error) { func (d *DB) Close() error { return d.db.Close() } + +func mergeDSN(baseDSN string) (string, error) { + config, err := mysql.ParseDSN(baseDSN) + if err != nil { + return "", errors.Wrapf(err, "failed to parse DSN: %s", baseDSN) + } + + config.MultiStatements = true + return config.FormatDSN(), nil +} diff --git a/store/db/mysql/reaction.go b/store/db/mysql/reaction.go new file mode 100644 index 0000000000000..511b10fc9120f --- /dev/null +++ b/store/db/mysql/reaction.go @@ -0,0 +1,107 @@ +package mysql + +import ( + "context" + "strings" + + "github.com/pkg/errors" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (d *DB) UpsertReaction(ctx context.Context, upsert *storepb.Reaction) (*storepb.Reaction, error) { + fields := []string{"`creator_id`", "`content_id`", "`reaction_type`"} + placeholder := []string{"?", "?", "?"} + args := []interface{}{upsert.CreatorId, upsert.ContentId, upsert.ReactionType.String()} + stmt := "INSERT INTO `reaction` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ")" + result, err := d.db.ExecContext(ctx, stmt, args...) + if err != nil { + return nil, err + } + + rawID, err := result.LastInsertId() + if err != nil { + return nil, err + } + id := int32(rawID) + reaction, err := d.GetReaction(ctx, &store.FindReaction{ID: &id}) + if err != nil { + return nil, err + } + if reaction == nil { + return nil, errors.Errorf("failed to create reaction") + } + return reaction, nil +} + +func (d *DB) ListReactions(ctx context.Context, find *store.FindReaction) ([]*storepb.Reaction, error) { + where, args := []string{"1 = 1"}, []interface{}{} + if find.ID != nil { + where, args = append(where, "`id` = ?"), append(args, *find.ID) + } + if find.CreatorID != nil { + where, args = append(where, "`creator_id` = ?"), append(args, *find.CreatorID) + } + if find.ContentID != nil { + where, args = append(where, "`content_id` = ?"), append(args, *find.ContentID) + } + + rows, err := d.db.QueryContext(ctx, ` + SELECT + id, + UNIX_TIMESTAMP(created_ts) AS created_ts, + creator_id, + content_id, + reaction_type + FROM reaction + WHERE `+strings.Join(where, " AND ")+` + ORDER BY id ASC`, + args..., + ) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*storepb.Reaction{} + for rows.Next() { + reaction := &storepb.Reaction{} + var reactionType string + if err := rows.Scan( + &reaction.Id, + &reaction.CreatedTs, + &reaction.CreatorId, + &reaction.ContentId, + &reactionType, + ); err != nil { + return nil, err + } + reaction.ReactionType = storepb.Reaction_Type(storepb.Reaction_Type_value[reactionType]) + list = append(list, reaction) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) GetReaction(ctx context.Context, find *store.FindReaction) (*storepb.Reaction, error) { + list, err := d.ListReactions(ctx, find) + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + + reaction := list[0] + return reaction, nil +} + +func (d *DB) DeleteReaction(ctx context.Context, delete *store.DeleteReaction) error { + _, err := d.db.ExecContext(ctx, "DELETE FROM `reaction` WHERE `id` = ?", delete.ID) + return err +} diff --git a/store/db/mysql/resource.go b/store/db/mysql/resource.go index 501a0f39fb4fc..e2c570eae03d2 100644 --- a/store/db/mysql/resource.go +++ b/store/db/mysql/resource.go @@ -6,39 +6,13 @@ import ( "fmt" "strings" - "github.com/pkg/errors" - "github.com/usememos/memos/store" ) func (d *DB) CreateResource(ctx context.Context, create *store.Resource) (*store.Resource, error) { - fields := []string{"`filename`", "`blob`", "`external_link`", "`type`", "`size`", "`creator_id`", "`internal_path`"} - placeholder := []string{"?", "?", "?", "?", "?", "?", "?"} - args := []any{create.Filename, create.Blob, create.ExternalLink, create.Type, create.Size, create.CreatorID, create.InternalPath} - - if create.ID != 0 { - fields = append(fields, "`id`") - placeholder = append(placeholder, "?") - args = append(args, create.ID) - } - - if create.CreatedTs != 0 { - fields = append(fields, "`created_ts`") - placeholder = append(placeholder, "FROM_UNIXTIME(?)") - args = append(args, create.CreatedTs) - } - - if create.UpdatedTs != 0 { - fields = append(fields, "`updated_ts`") - placeholder = append(placeholder, "FROM_UNIXTIME(?)") - args = append(args, create.UpdatedTs) - } - - if create.MemoID != nil { - fields = append(fields, "`memo_id`") - placeholder = append(placeholder, "?") - args = append(args, *create.MemoID) - } + fields := []string{"`resource_name`", "`filename`", "`blob`", "`external_link`", "`type`", "`size`", "`creator_id`", "`internal_path`", "`memo_id`"} + placeholder := []string{"?", "?", "?", "?", "?", "?", "?", "?", "?"} + args := []any{create.ResourceName, create.Filename, create.Blob, create.ExternalLink, create.Type, create.Size, create.CreatorID, create.InternalPath, create.MemoID} stmt := "INSERT INTO `resource` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ")" result, err := d.db.ExecContext(ctx, stmt, args...) @@ -52,15 +26,7 @@ func (d *DB) CreateResource(ctx context.Context, create *store.Resource) (*store } id32 := int32(id) - list, err := d.ListResources(ctx, &store.FindResource{ID: &id32}) - if err != nil { - return nil, err - } - if len(list) != 1 { - return nil, errors.Wrapf(nil, "unexpected resource count: %d", len(list)) - } - - return list[0], nil + return d.GetResource(ctx, &store.FindResource{ID: &id32}) } func (d *DB) ListResources(ctx context.Context, find *store.FindResource) ([]*store.Resource, error) { @@ -69,6 +35,9 @@ func (d *DB) ListResources(ctx context.Context, find *store.FindResource) ([]*st if v := find.ID; v != nil { where, args = append(where, "`id` = ?"), append(args, *v) } + if v := find.ResourceName; v != nil { + where, args = append(where, "`resource_name` = ?"), append(args, *v) + } if v := find.CreatorID; v != nil { where, args = append(where, "`creator_id` = ?"), append(args, *v) } @@ -82,12 +51,12 @@ func (d *DB) ListResources(ctx context.Context, find *store.FindResource) ([]*st where = append(where, "`memo_id` IS NOT NULL") } - fields := []string{"`id`", "`filename`", "`external_link`", "`type`", "`size`", "`creator_id`", "UNIX_TIMESTAMP(`created_ts`)", "UNIX_TIMESTAMP(`updated_ts`)", "`internal_path`", "`memo_id`"} + fields := []string{"`id`", "`resource_name`", "`filename`", "`external_link`", "`type`", "`size`", "`creator_id`", "UNIX_TIMESTAMP(`created_ts`)", "UNIX_TIMESTAMP(`updated_ts`)", "`internal_path`", "`memo_id`"} if find.GetBlob { fields = append(fields, "`blob`") } - query := fmt.Sprintf("SELECT %s FROM `resource` WHERE %s GROUP BY `id` ORDER BY `created_ts` DESC", strings.Join(fields, ", "), strings.Join(where, " AND ")) + query := fmt.Sprintf("SELECT %s FROM `resource` WHERE %s ORDER BY `updated_ts` DESC, `created_ts` DESC", strings.Join(fields, ", "), strings.Join(where, " AND ")) if find.Limit != nil { query = fmt.Sprintf("%s LIMIT %d", query, *find.Limit) if find.Offset != nil { @@ -107,6 +76,7 @@ func (d *DB) ListResources(ctx context.Context, find *store.FindResource) ([]*st var memoID sql.NullInt32 dests := []any{ &resource.ID, + &resource.ResourceName, &resource.Filename, &resource.ExternalLink, &resource.Type, @@ -136,11 +106,26 @@ func (d *DB) ListResources(ctx context.Context, find *store.FindResource) ([]*st return list, nil } +func (d *DB) GetResource(ctx context.Context, find *store.FindResource) (*store.Resource, error) { + list, err := d.ListResources(ctx, find) + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + + return list[0], nil +} + func (d *DB) UpdateResource(ctx context.Context, update *store.UpdateResource) (*store.Resource, error) { set, args := []string{}, []any{} + if v := update.ResourceName; v != nil { + set, args = append(set, "`resource_name` = ?"), append(args, *v) + } if v := update.UpdatedTs; v != nil { - set, args = append(set, "`updated_ts` = ?"), append(args, *v) + set, args = append(set, "`updated_ts` = FROM_UNIXTIME(?)"), append(args, *v) } if v := update.Filename; v != nil { set, args = append(set, "`filename` = ?"), append(args, *v) @@ -148,6 +133,9 @@ func (d *DB) UpdateResource(ctx context.Context, update *store.UpdateResource) ( if v := update.InternalPath; v != nil { set, args = append(set, "`internal_path` = ?"), append(args, *v) } + if v := update.ExternalLink; v != nil { + set, args = append(set, "`external_link` = ?"), append(args, *v) + } if v := update.MemoID; v != nil { set, args = append(set, "`memo_id` = ?"), append(args, *v) } @@ -161,15 +149,7 @@ func (d *DB) UpdateResource(ctx context.Context, update *store.UpdateResource) ( return nil, err } - list, err := d.ListResources(ctx, &store.FindResource{ID: &update.ID}) - if err != nil { - return nil, err - } - if len(list) != 1 { - return nil, errors.Wrapf(nil, "unexpected resource count: %d", len(list)) - } - - return list[0], nil + return d.GetResource(ctx, &store.FindResource{ID: &update.ID}) } func (d *DB) DeleteResource(ctx context.Context, delete *store.DeleteResource) error { diff --git a/store/db/mysql/seed/10000__reset.sql b/store/db/mysql/seed/10000__reset.sql deleted file mode 100644 index de4e97c984ce6..0000000000000 --- a/store/db/mysql/seed/10000__reset.sql +++ /dev/null @@ -1,4 +0,0 @@ -TRUNCATE TABLE memo_organizer; -TRUNCATE TABLE resource; -TRUNCATE TABLE memo; -TRUNCATE TABLE user; diff --git a/store/db/mysql/seed/10001__user.sql b/store/db/mysql/seed/10001__user.sql deleted file mode 100644 index 4bd60e841af79..0000000000000 --- a/store/db/mysql/seed/10001__user.sql +++ /dev/null @@ -1,45 +0,0 @@ -INSERT INTO - user ( - `id`, - `username`, - `role`, - `email`, - `nickname`, - `row_status`, - `avatar_url`, - `password_hash` - ) -VALUES - ( - 101, - 'memos-demo', - 'HOST', - 'demo@usememos.com', - 'Derobot', - 'NORMAL', - '', - -- raw password: secret - '$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK' - ), - ( - 102, - 'jack', - 'USER', - 'jack@usememos.com', - 'Jack', - 'NORMAL', - '', - -- raw password: secret - '$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK' - ), - ( - 103, - 'bob', - 'USER', - 'bob@usememos.com', - 'Bob', - 'ARCHIVED', - '', - -- raw password: secret - '$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK' - ); diff --git a/store/db/mysql/seed/10002__memo.sql b/store/db/mysql/seed/10002__memo.sql deleted file mode 100644 index 31e3d1da03949..0000000000000 --- a/store/db/mysql/seed/10002__memo.sql +++ /dev/null @@ -1,54 +0,0 @@ -INSERT INTO - memo (`id`, `content`, `creator_id`) -VALUES - ( - 1, - "#Hello 👋 Welcome to memos.", - 101 - ); - -INSERT INTO - memo ( - `id`, - `content`, - `creator_id`, - `visibility` - ) -VALUES - ( - 2, - '#TODO -- [x] Take more photos about **🌄 sunset** -- [x] Clean the room -- [ ] Read *📖 The Little Prince* -(👆 click to toggle status)', - 101, - 'PROTECTED' - ), - ( - 3, - "**[Slash](https://github.com/boojack/slash)**: A bookmarking and url shortener, save and share your links very easily. -![](https://github.com/boojack/slash/raw/main/resources/demo.gif) - -**[SQL Chat](https://www.sqlchat.ai)**: Chat-based SQL Client -![](https://www.sqlchat.ai/chat-logo-and-text.webp)", - 101, - 'PUBLIC' - ), - ( - 4, - '#TODO -- [x] Take more photos about **🌄 sunset** -- [ ] Clean the classroom -- [ ] Watch *👦 The Boys* -(👆 click to toggle status) -', - 102, - 'PROTECTED' - ), - ( - 5, - '三人行,必有我师焉!👨‍🏫', - 102, - 'PUBLIC' - ); diff --git a/store/db/mysql/seed/10003__memo_organizer.sql b/store/db/mysql/seed/10003__memo_organizer.sql deleted file mode 100644 index e1a2c4061b0f9..0000000000000 --- a/store/db/mysql/seed/10003__memo_organizer.sql +++ /dev/null @@ -1,5 +0,0 @@ -INSERT INTO - memo_organizer (`memo_id`, `user_id`, `pinned`) -VALUES - (1, 101, 1), - (3, 101, 1); diff --git a/store/db/mysql/seed/10004__tag.sql b/store/db/mysql/seed/10004__tag.sql deleted file mode 100644 index 40a7c774837df..0000000000000 --- a/store/db/mysql/seed/10004__tag.sql +++ /dev/null @@ -1,6 +0,0 @@ -INSERT INTO - tag (`name`, `creator_id`) -VALUES - ('Hello', 101), - ('TODO', 101), - ('TODO', 102); diff --git a/store/db/mysql/storage.go b/store/db/mysql/storage.go index 36507ee6598e4..6b667af784af1 100644 --- a/store/db/mysql/storage.go +++ b/store/db/mysql/storage.go @@ -12,12 +12,6 @@ func (d *DB) CreateStorage(ctx context.Context, create *store.Storage) (*store.S placeholder := []string{"?", "?", "?"} args := []any{create.Name, create.Type, create.Config} - if create.ID != 0 { - fields = append(fields, "`id`") - placeholder = append(placeholder, "?") - args = append(args, create.ID) - } - stmt := "INSERT INTO `storage` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ")" result, err := d.db.ExecContext(ctx, stmt, args...) if err != nil { @@ -68,18 +62,6 @@ func (d *DB) ListStorages(ctx context.Context, find *store.FindStorage) ([]*stor return list, nil } -func (d *DB) GetStorage(ctx context.Context, find *store.FindStorage) (*store.Storage, error) { - list, err := d.ListStorages(ctx, find) - if err != nil { - return nil, err - } - if len(list) == 0 { - return nil, nil - } - - return list[0], nil -} - func (d *DB) UpdateStorage(ctx context.Context, update *store.UpdateStorage) (*store.Storage, error) { set, args := []string{}, []any{} if update.Name != nil { diff --git a/store/db/mysql/system_setting.go b/store/db/mysql/system_setting.go deleted file mode 100644 index 08285bffc191e..0000000000000 --- a/store/db/mysql/system_setting.go +++ /dev/null @@ -1,59 +0,0 @@ -package mysql - -import ( - "context" - "strings" - - "github.com/usememos/memos/store" -) - -func (d *DB) UpsertSystemSetting(ctx context.Context, upsert *store.SystemSetting) (*store.SystemSetting, error) { - stmt := "INSERT INTO `system_setting` (`name`, `value`, `description`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `value` = ?, `description` = ?" - _, err := d.db.ExecContext( - ctx, - stmt, - upsert.Name, - upsert.Value, - upsert.Description, - upsert.Value, - upsert.Description, - ) - if err != nil { - return nil, err - } - - return upsert, nil -} - -func (d *DB) ListSystemSettings(ctx context.Context, find *store.FindSystemSetting) ([]*store.SystemSetting, error) { - where, args := []string{"1 = 1"}, []any{} - if find.Name != "" { - where, args = append(where, "`name` = ?"), append(args, find.Name) - } - - query := "SELECT `name`, `value`, `description` FROM `system_setting` WHERE " + strings.Join(where, " AND ") - rows, err := d.db.QueryContext(ctx, query, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - list := []*store.SystemSetting{} - for rows.Next() { - systemSettingMessage := &store.SystemSetting{} - if err := rows.Scan( - &systemSettingMessage.Name, - &systemSettingMessage.Value, - &systemSettingMessage.Description, - ); err != nil { - return nil, err - } - list = append(list, systemSettingMessage) - } - - if err := rows.Err(); err != nil { - return nil, err - } - - return list, nil -} diff --git a/store/db/mysql/user.go b/store/db/mysql/user.go index 882a0db4bdfb5..1926213548bcc 100644 --- a/store/db/mysql/user.go +++ b/store/db/mysql/user.go @@ -14,30 +14,6 @@ func (d *DB) CreateUser(ctx context.Context, create *store.User) (*store.User, e placeholder := []string{"?", "?", "?", "?", "?", "?"} args := []any{create.Username, create.Role, create.Email, create.Nickname, create.PasswordHash, create.AvatarURL} - if create.RowStatus != "" { - fields = append(fields, "`row_status`") - placeholder = append(placeholder, "?") - args = append(args, create.RowStatus) - } - - if create.CreatedTs != 0 { - fields = append(fields, "`created_ts`") - placeholder = append(placeholder, "FROM_UNIXTIME(?)") - args = append(args, create.CreatedTs) - } - - if create.UpdatedTs != 0 { - fields = append(fields, "`updated_ts`") - placeholder = append(placeholder, "FROM_UNIXTIME(?)") - args = append(args, create.UpdatedTs) - } - - if create.ID != 0 { - fields = append(fields, "`id`") - placeholder = append(placeholder, "?") - args = append(args, create.ID) - } - stmt := "INSERT INTO user (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ")" result, err := d.db.ExecContext(ctx, stmt, args...) if err != nil { diff --git a/store/db/mysql/user_setting.go b/store/db/mysql/user_setting.go index aa9ffba97bde4..8a2114de844fb 100644 --- a/store/db/mysql/user_setting.go +++ b/store/db/mysql/user_setting.go @@ -12,53 +12,7 @@ import ( "github.com/usememos/memos/store" ) -func (d *DB) UpsertUserSetting(ctx context.Context, upsert *store.UserSetting) (*store.UserSetting, error) { - stmt := "INSERT INTO `user_setting` (`user_id`, `key`, `value`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `value` = ?" - if _, err := d.db.ExecContext(ctx, stmt, upsert.UserID, upsert.Key, upsert.Value, upsert.Value); err != nil { - return nil, err - } - - return upsert, nil -} - -func (d *DB) ListUserSettings(ctx context.Context, find *store.FindUserSetting) ([]*store.UserSetting, error) { - where, args := []string{"1 = 1"}, []any{} - - if v := find.Key; v != "" { - where, args = append(where, "`key` = ?"), append(args, v) - } - if v := find.UserID; v != nil { - where, args = append(where, "`user_id` = ?"), append(args, *find.UserID) - } - - query := "SELECT `user_id`, `key`, `value` FROM `user_setting` WHERE " + strings.Join(where, " AND ") - rows, err := d.db.QueryContext(ctx, query, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - userSettingList := make([]*store.UserSetting, 0) - for rows.Next() { - var userSetting store.UserSetting - if err := rows.Scan( - &userSetting.UserID, - &userSetting.Key, - &userSetting.Value, - ); err != nil { - return nil, err - } - userSettingList = append(userSettingList, &userSetting) - } - - if err := rows.Err(); err != nil { - return nil, err - } - - return userSettingList, nil -} - -func (d *DB) UpsertUserSettingV1(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) { +func (d *DB) UpsertUserSetting(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) { stmt := "INSERT INTO `user_setting` (`user_id`, `key`, `value`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `value` = ?" var valueString string if upsert.Key == storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS { @@ -67,8 +21,16 @@ func (d *DB) UpsertUserSettingV1(ctx context.Context, upsert *storepb.UserSettin return nil, err } valueString = string(valueBytes) + } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_LOCALE { + valueString = upsert.GetLocale() + } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_APPEARANCE { + valueString = upsert.GetAppearance() + } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_MEMO_VISIBILITY { + valueString = upsert.GetMemoVisibility() + } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_TELEGRAM_USER_ID { + valueString = upsert.GetTelegramUserId() } else { - return nil, errors.New("invalid user setting key") + return nil, errors.Errorf("unknown user setting key: %s", upsert.Key.String()) } if _, err := d.db.ExecContext(ctx, stmt, upsert.UserId, upsert.Key.String(), valueString, valueString); err != nil { @@ -78,7 +40,7 @@ func (d *DB) UpsertUserSettingV1(ctx context.Context, upsert *storepb.UserSettin return upsert, nil } -func (d *DB) ListUserSettingsV1(ctx context.Context, find *store.FindUserSettingV1) ([]*storepb.UserSetting, error) { +func (d *DB) ListUserSettings(ctx context.Context, find *store.FindUserSetting) ([]*storepb.UserSetting, error) { where, args := []string{"1 = 1"}, []any{} if v := find.Key; v != storepb.UserSettingKey_USER_SETTING_KEY_UNSPECIFIED { @@ -115,8 +77,24 @@ func (d *DB) ListUserSettingsV1(ctx context.Context, find *store.FindUserSetting userSetting.Value = &storepb.UserSetting_AccessTokens{ AccessTokens: accessTokensUserSetting, } + } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_LOCALE { + userSetting.Value = &storepb.UserSetting_Locale{ + Locale: valueString, + } + } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_APPEARANCE { + userSetting.Value = &storepb.UserSetting_Appearance{ + Appearance: valueString, + } + } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_MEMO_VISIBILITY { + userSetting.Value = &storepb.UserSetting_MemoVisibility{ + MemoVisibility: valueString, + } + } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_TELEGRAM_USER_ID { + userSetting.Value = &storepb.UserSetting_TelegramUserId{ + TelegramUserId: valueString, + } } else { - // Skip unknown user setting v1 key. + // Skip unknown user setting key. continue } userSettingList = append(userSettingList, userSetting) diff --git a/store/db/mysql/webhook.go b/store/db/mysql/webhook.go new file mode 100644 index 0000000000000..37082df298847 --- /dev/null +++ b/store/db/mysql/webhook.go @@ -0,0 +1,115 @@ +package mysql + +import ( + "context" + "strings" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (d *DB) CreateWebhook(ctx context.Context, create *storepb.Webhook) (*storepb.Webhook, error) { + fields := []string{"`name`", "`url`", "`creator_id`"} + placeholder := []string{"?", "?", "?"} + args := []any{create.Name, create.Url, create.CreatorId} + + stmt := "INSERT INTO `webhook` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ")" + result, err := d.db.ExecContext(ctx, stmt, args...) + if err != nil { + return nil, err + } + + id, err := result.LastInsertId() + if err != nil { + return nil, err + } + + create.Id = int32(id) + return d.GetWebhook(ctx, &store.FindWebhook{ID: &create.Id}) +} + +func (d *DB) ListWebhooks(ctx context.Context, find *store.FindWebhook) ([]*storepb.Webhook, error) { + where, args := []string{"1 = 1"}, []any{} + if find.ID != nil { + where, args = append(where, "`id` = ?"), append(args, *find.ID) + } + if find.CreatorID != nil { + where, args = append(where, "`creator_id` = ?"), append(args, *find.CreatorID) + } + + rows, err := d.db.QueryContext(ctx, "SELECT `id`, UNIX_TIMESTAMP(`created_ts`), UNIX_TIMESTAMP(`updated_ts`), `row_status`, `creator_id`, `name`, `url` FROM `webhook` WHERE "+strings.Join(where, " AND ")+" ORDER BY `id` DESC", + args..., + ) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*storepb.Webhook{} + for rows.Next() { + webhook := &storepb.Webhook{} + var rowStatus string + if err := rows.Scan( + &webhook.Id, + &webhook.CreatedTs, + &webhook.UpdatedTs, + &rowStatus, + &webhook.CreatorId, + &webhook.Name, + &webhook.Url, + ); err != nil { + return nil, err + } + webhook.RowStatus = storepb.RowStatus(storepb.RowStatus_value[rowStatus]) + list = append(list, webhook) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) GetWebhook(ctx context.Context, find *store.FindWebhook) (*storepb.Webhook, error) { + list, err := d.ListWebhooks(ctx, find) + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + return list[0], nil +} + +func (d *DB) UpdateWebhook(ctx context.Context, update *store.UpdateWebhook) (*storepb.Webhook, error) { + set, args := []string{}, []any{} + if update.RowStatus != nil { + set, args = append(set, "`row_status` = ?"), append(args, update.RowStatus.String()) + } + if update.Name != nil { + set, args = append(set, "`name` = ?"), append(args, *update.Name) + } + if update.URL != nil { + set, args = append(set, "`url` = ?"), append(args, *update.URL) + } + args = append(args, update.ID) + + stmt := "UPDATE `webhook` SET " + strings.Join(set, ", ") + " WHERE `id` = ?" + _, err := d.db.ExecContext(ctx, stmt, args...) + if err != nil { + return nil, err + } + + webhook, err := d.GetWebhook(ctx, &store.FindWebhook{ID: &update.ID}) + if err != nil { + return nil, err + } + + return webhook, nil +} + +func (d *DB) DeleteWebhook(ctx context.Context, delete *store.DeleteWebhook) error { + _, err := d.db.ExecContext(ctx, "DELETE FROM `webhook` WHERE `id` = ?", delete.ID) + return err +} diff --git a/store/db/mysql/workspace_setting.go b/store/db/mysql/workspace_setting.go new file mode 100644 index 0000000000000..bcac51e2ba704 --- /dev/null +++ b/store/db/mysql/workspace_setting.go @@ -0,0 +1,131 @@ +package mysql + +import ( + "context" + "strings" + + "google.golang.org/protobuf/encoding/protojson" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (d *DB) UpsertWorkspaceSetting(ctx context.Context, upsert *store.WorkspaceSetting) (*store.WorkspaceSetting, error) { + stmt := "INSERT INTO `system_setting` (`name`, `value`, `description`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `value` = ?, `description` = ?" + _, err := d.db.ExecContext( + ctx, + stmt, + upsert.Name, + upsert.Value, + upsert.Description, + upsert.Value, + upsert.Description, + ) + if err != nil { + return nil, err + } + + return upsert, nil +} + +func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspaceSetting) ([]*store.WorkspaceSetting, error) { + where, args := []string{"1 = 1"}, []any{} + if find.Name != "" { + where, args = append(where, "`name` = ?"), append(args, find.Name) + } + + query := "SELECT `name`, `value`, `description` FROM `system_setting` WHERE " + strings.Join(where, " AND ") + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*store.WorkspaceSetting{} + for rows.Next() { + systemSettingMessage := &store.WorkspaceSetting{} + if err := rows.Scan( + &systemSettingMessage.Name, + &systemSettingMessage.Value, + &systemSettingMessage.Description, + ); err != nil { + return nil, err + } + list = append(list, systemSettingMessage) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) DeleteWorkspaceSetting(ctx context.Context, delete *store.DeleteWorkspaceSetting) error { + stmt := "DELETE FROM `system_setting` WHERE `name` = ?" + _, err := d.db.ExecContext(ctx, stmt, delete.Name) + return err +} + +func (d *DB) UpsertWorkspaceSettingV1(ctx context.Context, upsert *storepb.WorkspaceSetting) (*storepb.WorkspaceSetting, error) { + stmt := ` + INSERT INTO system_setting (name, value, description) + VALUES (?, ?, '') + ON DUPLICATE KEY UPDATE value = ?` + var valueString string + if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_GENERAL { + valueBytes, err := protojson.Marshal(upsert.GetGeneral()) + if err != nil { + return nil, err + } + valueString = string(valueBytes) + } + if _, err := d.db.ExecContext(ctx, stmt, upsert.Key.String(), valueString, valueString); err != nil { + return nil, err + } + return upsert, nil +} + +func (d *DB) ListWorkspaceSettingsV1(ctx context.Context, find *store.FindWorkspaceSettingV1) ([]*storepb.WorkspaceSetting, error) { + where, args := []string{"1 = 1"}, []any{} + if find.Key != storepb.WorkspaceSettingKey_WORKSPACE_SETTING_KEY_UNSPECIFIED { + where, args = append(where, "name = ?"), append(args, find.Key.String()) + } + + query := `SELECT name, value FROM system_setting WHERE ` + strings.Join(where, " AND ") + + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*storepb.WorkspaceSetting{} + for rows.Next() { + workspaceSetting := &storepb.WorkspaceSetting{} + var keyString, valueString string + if err := rows.Scan( + &keyString, + &valueString, + ); err != nil { + return nil, err + } + workspaceSetting.Key = storepb.WorkspaceSettingKey(storepb.WorkspaceSettingKey_value[keyString]) + if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_GENERAL { + generalSetting := &storepb.WorkspaceGeneralSetting{} + if err := protojson.Unmarshal([]byte(valueString), generalSetting); err != nil { + return nil, err + } + workspaceSetting.Value = &storepb.WorkspaceSetting_General{General: generalSetting} + } else { + // Skip unknown workspace setting key. + continue + } + list = append(list, workspaceSetting) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} diff --git a/store/db/postgres/activity.go b/store/db/postgres/activity.go new file mode 100644 index 0000000000000..84e1532831411 --- /dev/null +++ b/store/db/postgres/activity.go @@ -0,0 +1,81 @@ +package postgres + +import ( + "context" + "strings" + + "github.com/pkg/errors" + "google.golang.org/protobuf/encoding/protojson" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (d *DB) CreateActivity(ctx context.Context, create *store.Activity) (*store.Activity, error) { + payloadString := "{}" + if create.Payload != nil { + bytes, err := protojson.Marshal(create.Payload) + if err != nil { + return nil, errors.Wrap(err, "failed to marshal activity payload") + } + payloadString = string(bytes) + } + + fields := []string{"creator_id", "type", "level", "payload"} + args := []any{create.CreatorID, create.Type.String(), create.Level.String(), payloadString} + stmt := "INSERT INTO activity (" + strings.Join(fields, ", ") + ") VALUES (" + placeholders(len(args)) + ") RETURNING id, created_ts" + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( + &create.ID, + &create.CreatedTs, + ); err != nil { + return nil, err + } + + return create, nil +} + +func (d *DB) ListActivities(ctx context.Context, find *store.FindActivity) ([]*store.Activity, error) { + where, args := []string{"1 = 1"}, []any{} + if find.ID != nil { + where, args = append(where, "id = "+placeholder(len(args)+1)), append(args, *find.ID) + } + if find.Type != nil { + where, args = append(where, "type = "+placeholder(len(args)+1)), append(args, find.Type.String()) + } + + query := "SELECT id, creator_id, type, level, payload, created_ts FROM activity WHERE " + strings.Join(where, " AND ") + " ORDER BY created_ts DESC" + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*store.Activity{} + for rows.Next() { + activity := &store.Activity{} + var payloadBytes []byte + if err := rows.Scan( + &activity.ID, + &activity.CreatorID, + &activity.Type, + &activity.Level, + &payloadBytes, + &activity.CreatedTs, + ); err != nil { + return nil, err + } + + payload := &storepb.ActivityPayload{} + if err := protojsonUnmarshaler.Unmarshal(payloadBytes, payload); err != nil { + return nil, err + } + activity.Payload = payload + list = append(list, activity) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} diff --git a/store/db/postgres/common.go b/store/db/postgres/common.go new file mode 100644 index 0000000000000..b4f074d629338 --- /dev/null +++ b/store/db/postgres/common.go @@ -0,0 +1,26 @@ +package postgres + +import ( + "fmt" + "strings" + + "google.golang.org/protobuf/encoding/protojson" +) + +var ( + protojsonUnmarshaler = protojson.UnmarshalOptions{ + DiscardUnknown: true, + } +) + +func placeholder(n int) string { + return "$" + fmt.Sprint(n) +} + +func placeholders(n int) string { + list := []string{} + for i := 0; i < n; i++ { + list = append(list, placeholder(i+1)) + } + return strings.Join(list, ", ") +} diff --git a/store/db/postgres/idp.go b/store/db/postgres/idp.go new file mode 100644 index 0000000000000..2257df513a49d --- /dev/null +++ b/store/db/postgres/idp.go @@ -0,0 +1,173 @@ +package postgres + +import ( + "context" + "encoding/json" + "strings" + + "github.com/pkg/errors" + + "github.com/usememos/memos/store" +) + +func (d *DB) CreateIdentityProvider(ctx context.Context, create *store.IdentityProvider) (*store.IdentityProvider, error) { + var configBytes []byte + if create.Type == store.IdentityProviderOAuth2Type { + bytes, err := json.Marshal(create.Config.OAuth2Config) + if err != nil { + return nil, err + } + configBytes = bytes + } else { + return nil, errors.Errorf("unsupported idp type %s", string(create.Type)) + } + + fields := []string{"name", "type", "identifier_filter", "config"} + args := []any{create.Name, create.Type, create.IdentifierFilter, string(configBytes)} + stmt := "INSERT INTO idp (" + strings.Join(fields, ", ") + ") VALUES (" + placeholders(len(args)) + ") RETURNING id" + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan(&create.ID); err != nil { + return nil, err + } + + identityProvider := create + return identityProvider, nil +} + +func (d *DB) ListIdentityProviders(ctx context.Context, find *store.FindIdentityProvider) ([]*store.IdentityProvider, error) { + where, args := []string{"1 = 1"}, []any{} + if v := find.ID; v != nil { + where, args = append(where, "id = "+placeholder(len(args)+1)), append(args, *v) + } + + rows, err := d.db.QueryContext(ctx, ` + SELECT + id, + name, + type, + identifier_filter, + config + FROM idp + WHERE `+strings.Join(where, " AND ")+` ORDER BY id ASC`, + args..., + ) + if err != nil { + return nil, err + } + defer rows.Close() + + var identityProviders []*store.IdentityProvider + for rows.Next() { + var identityProvider store.IdentityProvider + var identityProviderConfig string + if err := rows.Scan( + &identityProvider.ID, + &identityProvider.Name, + &identityProvider.Type, + &identityProvider.IdentifierFilter, + &identityProviderConfig, + ); err != nil { + return nil, err + } + + if identityProvider.Type == store.IdentityProviderOAuth2Type { + oauth2Config := &store.IdentityProviderOAuth2Config{} + if err := json.Unmarshal([]byte(identityProviderConfig), oauth2Config); err != nil { + return nil, err + } + identityProvider.Config = &store.IdentityProviderConfig{ + OAuth2Config: oauth2Config, + } + } else { + return nil, errors.Errorf("unsupported idp type %s", string(identityProvider.Type)) + } + identityProviders = append(identityProviders, &identityProvider) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return identityProviders, nil +} + +func (d *DB) GetIdentityProvider(ctx context.Context, find *store.FindIdentityProvider) (*store.IdentityProvider, error) { + list, err := d.ListIdentityProviders(ctx, find) + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + + return list[0], nil +} + +func (d *DB) UpdateIdentityProvider(ctx context.Context, update *store.UpdateIdentityProvider) (*store.IdentityProvider, error) { + set, args := []string{}, []any{} + if v := update.Name; v != nil { + set, args = append(set, "name = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.IdentifierFilter; v != nil { + set, args = append(set, "identifier_filter = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.Config; v != nil { + var configBytes []byte + if update.Type == store.IdentityProviderOAuth2Type { + bytes, err := json.Marshal(update.Config.OAuth2Config) + if err != nil { + return nil, err + } + configBytes = bytes + } else { + return nil, errors.Errorf("unsupported idp type %s", string(update.Type)) + } + set, args = append(set, "config = "+placeholder(len(args)+1)), append(args, string(configBytes)) + } + + stmt := ` + UPDATE idp + SET ` + strings.Join(set, ", ") + ` + WHERE id = ` + placeholder(len(args)+1) + ` + RETURNING id, name, type, identifier_filter, config + ` + args = append(args, update.ID) + + var identityProvider store.IdentityProvider + var identityProviderConfig string + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( + &identityProvider.ID, + &identityProvider.Name, + &identityProvider.Type, + &identityProvider.IdentifierFilter, + &identityProviderConfig, + ); err != nil { + return nil, err + } + + if identityProvider.Type == store.IdentityProviderOAuth2Type { + oauth2Config := &store.IdentityProviderOAuth2Config{} + if err := json.Unmarshal([]byte(identityProviderConfig), oauth2Config); err != nil { + return nil, err + } + identityProvider.Config = &store.IdentityProviderConfig{ + OAuth2Config: oauth2Config, + } + } else { + return nil, errors.Errorf("unsupported idp type %s", string(identityProvider.Type)) + } + + return &identityProvider, nil +} + +func (d *DB) DeleteIdentityProvider(ctx context.Context, delete *store.DeleteIdentityProvider) error { + where, args := []string{"id = $1"}, []any{delete.ID} + stmt := `DELETE FROM idp WHERE ` + strings.Join(where, " AND ") + result, err := d.db.ExecContext(ctx, stmt, args...) + if err != nil { + return err + } + if _, err = result.RowsAffected(); err != nil { + return err + } + return nil +} diff --git a/store/db/postgres/inbox.go b/store/db/postgres/inbox.go new file mode 100644 index 0000000000000..66460d341d7aa --- /dev/null +++ b/store/db/postgres/inbox.go @@ -0,0 +1,145 @@ +package postgres + +import ( + "context" + "database/sql" + "strings" + + "github.com/pkg/errors" + "google.golang.org/protobuf/encoding/protojson" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (d *DB) CreateInbox(ctx context.Context, create *store.Inbox) (*store.Inbox, error) { + messageString := "{}" + if create.Message != nil { + bytes, err := protojson.Marshal(create.Message) + if err != nil { + return nil, errors.Wrap(err, "failed to marshal inbox message") + } + messageString = string(bytes) + } + + fields := []string{"sender_id", "receiver_id", "status", "message"} + args := []any{create.SenderID, create.ReceiverID, create.Status, messageString} + stmt := "INSERT INTO inbox (" + strings.Join(fields, ", ") + ") VALUES (" + placeholders(len(args)) + ") RETURNING id, created_ts" + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( + &create.ID, + &create.CreatedTs, + ); err != nil { + return nil, err + } + + return create, nil +} + +func (d *DB) ListInboxes(ctx context.Context, find *store.FindInbox) ([]*store.Inbox, error) { + where, args := []string{"1 = 1"}, []any{} + + if find.ID != nil { + where, args = append(where, "id = "+placeholder(len(args)+1)), append(args, *find.ID) + } + if find.SenderID != nil { + where, args = append(where, "sender_id = "+placeholder(len(args)+1)), append(args, *find.SenderID) + } + if find.ReceiverID != nil { + where, args = append(where, "receiver_id = "+placeholder(len(args)+1)), append(args, *find.ReceiverID) + } + if find.Status != nil { + where, args = append(where, "status = "+placeholder(len(args)+1)), append(args, *find.Status) + } + + query := "SELECT id, created_ts, sender_id, receiver_id, status, message FROM inbox WHERE " + strings.Join(where, " AND ") + " ORDER BY created_ts DESC" + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*store.Inbox{} + for rows.Next() { + inbox := &store.Inbox{} + var messageBytes []byte + if err := rows.Scan( + &inbox.ID, + &inbox.CreatedTs, + &inbox.SenderID, + &inbox.ReceiverID, + &inbox.Status, + &messageBytes, + ); err != nil { + return nil, err + } + + message := &storepb.InboxMessage{} + if err := protojsonUnmarshaler.Unmarshal(messageBytes, message); err != nil { + return nil, err + } + inbox.Message = message + list = append(list, inbox) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) GetInbox(ctx context.Context, find *store.FindInbox) (*store.Inbox, error) { + list, err := d.ListInboxes(ctx, find) + if err != nil { + return nil, errors.Wrap(err, "failed to get inbox") + } + if len(list) != 1 { + return nil, errors.Wrapf(nil, "unexpected inbox count: %d", len(list)) + } + return list[0], nil +} + +func (d *DB) UpdateInbox(ctx context.Context, update *store.UpdateInbox) (*store.Inbox, error) { + set, args := []string{"status = $1"}, []any{update.Status.String()} + args = append(args, update.ID) + query := "UPDATE inbox SET " + strings.Join(set, ", ") + " WHERE id = $2 RETURNING id, created_ts, sender_id, receiver_id, status, message" + inbox := &store.Inbox{} + var messageBytes []byte + if err := d.db.QueryRowContext(ctx, query, args...).Scan( + &inbox.ID, + &inbox.CreatedTs, + &inbox.SenderID, + &inbox.ReceiverID, + &inbox.Status, + &messageBytes, + ); err != nil { + return nil, err + } + message := &storepb.InboxMessage{} + if err := protojsonUnmarshaler.Unmarshal(messageBytes, message); err != nil { + return nil, err + } + inbox.Message = message + return inbox, nil +} + +func (d *DB) DeleteInbox(ctx context.Context, delete *store.DeleteInbox) error { + result, err := d.db.ExecContext(ctx, "DELETE FROM inbox WHERE id = $1", delete.ID) + if err != nil { + return err + } + if _, err := result.RowsAffected(); err != nil { + return err + } + return nil +} + +func vacuumInbox(ctx context.Context, tx *sql.Tx) error { + stmt := `DELETE FROM inbox WHERE sender_id NOT IN (SELECT id FROM "user")` + _, err := tx.ExecContext(ctx, stmt) + if err != nil { + return err + } + + return nil +} diff --git a/store/db/postgres/memo.go b/store/db/postgres/memo.go new file mode 100644 index 0000000000000..7721912268936 --- /dev/null +++ b/store/db/postgres/memo.go @@ -0,0 +1,208 @@ +package postgres + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/pkg/errors" + + "github.com/usememos/memos/store" +) + +func (d *DB) CreateMemo(ctx context.Context, create *store.Memo) (*store.Memo, error) { + fields := []string{"resource_name", "creator_id", "content", "visibility"} + args := []any{create.ResourceName, create.CreatorID, create.Content, create.Visibility} + + stmt := "INSERT INTO memo (" + strings.Join(fields, ", ") + ") VALUES (" + placeholders(len(args)) + ") RETURNING id, created_ts, updated_ts, row_status" + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( + &create.ID, + &create.CreatedTs, + &create.UpdatedTs, + &create.RowStatus, + ); err != nil { + return nil, err + } + + return create, nil +} + +func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo, error) { + where, args := []string{"1 = 1"}, []any{} + + if v := find.ID; v != nil { + where, args = append(where, "memo.id = "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.ResourceName; v != nil { + where, args = append(where, "memo.resource_name = "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.CreatorID; v != nil { + where, args = append(where, "memo.creator_id = "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.RowStatus; v != nil { + where, args = append(where, "memo.row_status = "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.CreatedTsBefore; v != nil { + where, args = append(where, "memo.created_ts < "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.CreatedTsAfter; v != nil { + where, args = append(where, "memo.created_ts > "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.UpdatedTsBefore; v != nil { + where, args = append(where, "memo.updated_ts < "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.UpdatedTsAfter; v != nil { + where, args = append(where, "memo.updated_ts > "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.ContentSearch; len(v) != 0 { + for _, s := range v { + where, args = append(where, "memo.content LIKE "+placeholder(len(args)+1)), append(args, fmt.Sprintf("%%%s%%", s)) + } + } + if v := find.VisibilityList; len(v) != 0 { + holders := []string{} + for _, visibility := range v { + holders = append(holders, placeholder(len(args)+1)) + args = append(args, visibility.String()) + } + where = append(where, fmt.Sprintf("memo.visibility in (%s)", strings.Join(holders, ", "))) + } + if find.ExcludeComments { + where = append(where, "memo_relation.related_memo_id IS NULL") + } + + orders := []string{} + if find.OrderByPinned { + orders = append(orders, "pinned DESC") + } + if find.OrderByUpdatedTs { + orders = append(orders, "updated_ts DESC") + } else { + orders = append(orders, "created_ts DESC") + } + orders = append(orders, "id DESC") + + fields := []string{ + `memo.id AS id`, + `memo.resource_name AS resource_name`, + `memo.creator_id AS creator_id`, + `memo.created_ts AS created_ts`, + `memo.updated_ts AS updated_ts`, + `memo.row_status AS row_status`, + `memo.visibility AS visibility`, + `COALESCE(memo_organizer.pinned, 0) AS pinned`, + `memo_relation.related_memo_id AS parent_id`, + } + if !find.ExcludeContent { + fields = append(fields, `memo.content AS content`) + } + + query := `SELECT ` + strings.Join(fields, ", ") + ` + FROM memo + LEFT JOIN memo_organizer ON memo.id = memo_organizer.memo_id AND memo.creator_id = memo_organizer.user_id + LEFT JOIN memo_relation ON memo.id = memo_relation.memo_id AND memo_relation.type = 'COMMENT' + WHERE ` + strings.Join(where, " AND ") + ` + ORDER BY ` + strings.Join(orders, ", ") + if find.Limit != nil { + query = fmt.Sprintf("%s LIMIT %d", query, *find.Limit) + if find.Offset != nil { + query = fmt.Sprintf("%s OFFSET %d", query, *find.Offset) + } + } + + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := make([]*store.Memo, 0) + for rows.Next() { + var memo store.Memo + dests := []any{ + &memo.ID, + &memo.ResourceName, + &memo.CreatorID, + &memo.CreatedTs, + &memo.UpdatedTs, + &memo.RowStatus, + &memo.Visibility, + &memo.Pinned, + &memo.ParentID, + } + if !find.ExcludeContent { + dests = append(dests, &memo.Content) + } + if err := rows.Scan(dests...); err != nil { + return nil, err + } + list = append(list, &memo) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) GetMemo(ctx context.Context, find *store.FindMemo) (*store.Memo, error) { + list, err := d.ListMemos(ctx, find) + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + + memo := list[0] + return memo, nil +} + +func (d *DB) UpdateMemo(ctx context.Context, update *store.UpdateMemo) error { + set, args := []string{}, []any{} + if v := update.ResourceName; v != nil { + set, args = append(set, "resource_name = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.CreatedTs; v != nil { + set, args = append(set, "created_ts = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.UpdatedTs; v != nil { + set, args = append(set, "updated_ts = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.RowStatus; v != nil { + set, args = append(set, "row_status = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.Content; v != nil { + set, args = append(set, "content = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.Visibility; v != nil { + set, args = append(set, "visibility = "+placeholder(len(args)+1)), append(args, *v) + } + stmt := `UPDATE memo SET ` + strings.Join(set, ", ") + ` WHERE id = ` + placeholder(len(args)+1) + args = append(args, update.ID) + if _, err := d.db.ExecContext(ctx, stmt, args...); err != nil { + return err + } + return nil +} + +func (d *DB) DeleteMemo(ctx context.Context, delete *store.DeleteMemo) error { + where, args := []string{"id = " + placeholder(1)}, []any{delete.ID} + stmt := `DELETE FROM memo WHERE ` + strings.Join(where, " AND ") + result, err := d.db.ExecContext(ctx, stmt, args...) + if err != nil { + return errors.Wrap(err, "failed to delete memo") + } + if _, err := result.RowsAffected(); err != nil { + return err + } + return nil +} + +func vacuumMemo(ctx context.Context, tx *sql.Tx) error { + stmt := `DELETE FROM memo WHERE creator_id NOT IN (SELECT id FROM "user")` + _, err := tx.ExecContext(ctx, stmt) + return err +} diff --git a/store/db/postgres/memo_organizer.go b/store/db/postgres/memo_organizer.go new file mode 100644 index 0000000000000..00b5807b9b2bd --- /dev/null +++ b/store/db/postgres/memo_organizer.go @@ -0,0 +1,107 @@ +package postgres + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/usememos/memos/store" +) + +func (d *DB) UpsertMemoOrganizer(ctx context.Context, upsert *store.MemoOrganizer) (*store.MemoOrganizer, error) { + pinned := 0 + if upsert.Pinned { + pinned = 1 + } + stmt := ` + INSERT INTO memo_organizer ( + memo_id, + user_id, + pinned + ) + VALUES (` + placeholders(3) + `) + ON CONFLICT(memo_id, user_id) DO UPDATE + SET pinned = EXCLUDED.pinned` + if _, err := d.db.ExecContext(ctx, stmt, upsert.MemoID, upsert.UserID, pinned); err != nil { + return nil, err + } + + return upsert, nil +} + +func (d *DB) ListMemoOrganizer(ctx context.Context, find *store.FindMemoOrganizer) ([]*store.MemoOrganizer, error) { + where, args := []string{"1 = 1"}, []any{} + if find.MemoID != 0 { + where, args = append(where, "memo_id = "+placeholder(len(args)+1)), append(args, find.MemoID) + } + if find.UserID != 0 { + where, args = append(where, "user_id = "+placeholder(len(args)+1)), append(args, find.UserID) + } + + query := fmt.Sprintf(` + SELECT + memo_id, + user_id, + pinned + FROM memo_organizer + WHERE %s + `, strings.Join(where, " AND ")) + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*store.MemoOrganizer{} + for rows.Next() { + memoOrganizer := &store.MemoOrganizer{} + pinned := 0 + if err := rows.Scan( + &memoOrganizer.MemoID, + &memoOrganizer.UserID, + &pinned, + ); err != nil { + return nil, err + } + + memoOrganizer.Pinned = pinned == 1 + list = append(list, memoOrganizer) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) DeleteMemoOrganizer(ctx context.Context, delete *store.DeleteMemoOrganizer) error { + where, args := []string{}, []any{} + if v := delete.MemoID; v != nil { + where, args = append(where, "memo_id = "+placeholder(len(args)+1)), append(args, *v) + } + if v := delete.UserID; v != nil { + where, args = append(where, "user_id = "+placeholder(len(args)+1)), append(args, *v) + } + stmt := `DELETE FROM memo_organizer WHERE ` + strings.Join(where, " AND ") + if _, err := d.db.ExecContext(ctx, stmt, args...); err != nil { + return err + } + return nil +} + +func vacuumMemoOrganizer(ctx context.Context, tx *sql.Tx) error { + stmt := ` + DELETE FROM + memo_organizer + WHERE + memo_id NOT IN (SELECT id FROM memo) + OR user_id NOT IN (SELECT id FROM "user")` + _, err := tx.ExecContext(ctx, stmt) + if err != nil { + return err + } + + return nil +} diff --git a/store/db/postgres/memo_relation.go b/store/db/postgres/memo_relation.go new file mode 100644 index 0000000000000..39bc10cb054ec --- /dev/null +++ b/store/db/postgres/memo_relation.go @@ -0,0 +1,113 @@ +package postgres + +import ( + "context" + "database/sql" + "strings" + + "github.com/usememos/memos/store" +) + +func (d *DB) UpsertMemoRelation(ctx context.Context, create *store.MemoRelation) (*store.MemoRelation, error) { + stmt := ` + INSERT INTO memo_relation ( + memo_id, + related_memo_id, + type + ) + VALUES (` + placeholders(3) + `) + RETURNING memo_id, related_memo_id, type + ` + memoRelation := &store.MemoRelation{} + if err := d.db.QueryRowContext( + ctx, + stmt, + create.MemoID, + create.RelatedMemoID, + create.Type, + ).Scan( + &memoRelation.MemoID, + &memoRelation.RelatedMemoID, + &memoRelation.Type, + ); err != nil { + return nil, err + } + + return memoRelation, nil +} + +func (d *DB) ListMemoRelations(ctx context.Context, find *store.FindMemoRelation) ([]*store.MemoRelation, error) { + where, args := []string{"1 = 1"}, []any{} + if find.MemoID != nil { + where, args = append(where, "memo_id = "+placeholder(len(args)+1)), append(args, find.MemoID) + } + if find.RelatedMemoID != nil { + where, args = append(where, "related_memo_id = "+placeholder(len(args)+1)), append(args, find.RelatedMemoID) + } + if find.Type != nil { + where, args = append(where, "type = "+placeholder(len(args)+1)), append(args, find.Type) + } + + rows, err := d.db.QueryContext(ctx, ` + SELECT + memo_id, + related_memo_id, + type + FROM memo_relation + WHERE `+strings.Join(where, " AND "), args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*store.MemoRelation{} + for rows.Next() { + memoRelation := &store.MemoRelation{} + if err := rows.Scan( + &memoRelation.MemoID, + &memoRelation.RelatedMemoID, + &memoRelation.Type, + ); err != nil { + return nil, err + } + list = append(list, memoRelation) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) DeleteMemoRelation(ctx context.Context, delete *store.DeleteMemoRelation) error { + where, args := []string{"1 = 1"}, []any{} + if delete.MemoID != nil { + where, args = append(where, "memo_id = "+placeholder(len(args)+1)), append(args, delete.MemoID) + } + if delete.RelatedMemoID != nil { + where, args = append(where, "related_memo_id = "+placeholder(len(args)+1)), append(args, delete.RelatedMemoID) + } + if delete.Type != nil { + where, args = append(where, "type = "+placeholder(len(args)+1)), append(args, delete.Type) + } + stmt := `DELETE FROM memo_relation WHERE ` + strings.Join(where, " AND ") + result, err := d.db.ExecContext(ctx, stmt, args...) + if err != nil { + return err + } + if _, err = result.RowsAffected(); err != nil { + return err + } + return nil +} + +func vacuumMemoRelations(ctx context.Context, tx *sql.Tx) error { + if _, err := tx.ExecContext(ctx, ` + DELETE FROM memo_relation + WHERE memo_id NOT IN (SELECT id FROM memo) OR related_memo_id NOT IN (SELECT id FROM memo) + `); err != nil { + return err + } + return nil +} diff --git a/store/db/postgres/migration/dev/LATEST__SCHEMA.sql b/store/db/postgres/migration/dev/LATEST__SCHEMA.sql new file mode 100644 index 0000000000000..1ab5f95e4458a --- /dev/null +++ b/store/db/postgres/migration/dev/LATEST__SCHEMA.sql @@ -0,0 +1,143 @@ +-- migration_history +CREATE TABLE migration_history ( + version TEXT NOT NULL PRIMARY KEY, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()) +); + +-- system_setting +CREATE TABLE system_setting ( + name TEXT NOT NULL PRIMARY KEY, + value TEXT NOT NULL, + description TEXT NOT NULL +); + +-- user +CREATE TABLE "user" ( + id SERIAL PRIMARY KEY, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + updated_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + row_status TEXT NOT NULL DEFAULT 'NORMAL', + username TEXT NOT NULL UNIQUE, + role TEXT NOT NULL DEFAULT 'USER', + email TEXT NOT NULL DEFAULT '', + nickname TEXT NOT NULL DEFAULT '', + password_hash TEXT NOT NULL, + avatar_url TEXT NOT NULL +); + +-- user_setting +CREATE TABLE user_setting ( + user_id INTEGER NOT NULL, + key TEXT NOT NULL, + value TEXT NOT NULL, + UNIQUE(user_id, key) +); + +-- memo +CREATE TABLE memo ( + id SERIAL PRIMARY KEY, + resource_name TEXT NOT NULL UNIQUE, + creator_id INTEGER NOT NULL, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + updated_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + row_status TEXT NOT NULL DEFAULT 'NORMAL', + content TEXT NOT NULL, + visibility TEXT NOT NULL DEFAULT 'PRIVATE' +); + +-- memo_organizer +CREATE TABLE memo_organizer ( + memo_id INTEGER NOT NULL, + user_id INTEGER NOT NULL, + pinned INTEGER NOT NULL DEFAULT 0, + UNIQUE(memo_id, user_id) +); + +-- memo_relation +CREATE TABLE memo_relation ( + memo_id INTEGER NOT NULL, + related_memo_id INTEGER NOT NULL, + type TEXT NOT NULL, + UNIQUE(memo_id, related_memo_id, type) +); + +-- resource +CREATE TABLE resource ( + id SERIAL PRIMARY KEY, + resource_name TEXT NOT NULL UNIQUE, + creator_id INTEGER NOT NULL, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + updated_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + filename TEXT NOT NULL, + blob BYTEA, + external_link TEXT NOT NULL, + type TEXT NOT NULL DEFAULT '', + size INTEGER NOT NULL DEFAULT 0, + internal_path TEXT NOT NULL DEFAULT '', + memo_id INTEGER DEFAULT NULL +); + +-- tag +CREATE TABLE tag ( + name TEXT NOT NULL, + creator_id INTEGER NOT NULL, + UNIQUE(name, creator_id) +); + +-- activity +CREATE TABLE activity ( + id SERIAL PRIMARY KEY, + creator_id INTEGER NOT NULL, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + type TEXT NOT NULL DEFAULT '', + level TEXT NOT NULL DEFAULT 'INFO', + payload JSONB NOT NULL DEFAULT '{}' +); + +-- storage +CREATE TABLE storage ( + id SERIAL PRIMARY KEY, + name TEXT NOT NULL, + type TEXT NOT NULL, + config JSONB NOT NULL DEFAULT '{}' +); + +-- idp +CREATE TABLE idp ( + id SERIAL PRIMARY KEY, + name TEXT NOT NULL, + type TEXT NOT NULL, + identifier_filter TEXT NOT NULL DEFAULT '', + config JSONB NOT NULL DEFAULT '{}' +); + +-- inbox +CREATE TABLE inbox ( + id SERIAL PRIMARY KEY, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + sender_id INTEGER NOT NULL, + receiver_id INTEGER NOT NULL, + status TEXT NOT NULL, + message TEXT NOT NULL +); + +-- webhook +CREATE TABLE webhook ( + id SERIAL PRIMARY KEY, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + updated_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + row_status TEXT NOT NULL DEFAULT 'NORMAL', + creator_id INTEGER NOT NULL, + name TEXT NOT NULL, + url TEXT NOT NULL +); + +-- reaction +CREATE TABLE reaction ( + id SERIAL PRIMARY KEY, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + creator_id INTEGER NOT NULL, + content_id TEXT NOT NULL, + reaction_type TEXT NOT NULL, + UNIQUE(creator_id, content_id, reaction_type) +); diff --git a/store/db/postgres/migration/prod/0.19/00__add_resource_name.sql b/store/db/postgres/migration/prod/0.19/00__add_resource_name.sql new file mode 100644 index 0000000000000..aa5b560f060cd --- /dev/null +++ b/store/db/postgres/migration/prod/0.19/00__add_resource_name.sql @@ -0,0 +1,15 @@ +ALTER TABLE memo ADD COLUMN resource_name TEXT; + +UPDATE memo SET resource_name = uuid_in(md5(random()::text || random()::text)::cstring); + +ALTER TABLE memo ALTER COLUMN resource_name SET NOT NULL; + +CREATE UNIQUE INDEX idx_memo_resource_name ON memo (resource_name); + +ALTER TABLE resource ADD COLUMN resource_name TEXT; + +UPDATE resource SET resource_name = uuid_in(md5(random()::text || random()::text)::cstring); + +ALTER TABLE resource ALTER COLUMN resource_name SET NOT NULL; + +CREATE UNIQUE INDEX idx_resource_resource_name ON resource (resource_name); diff --git a/store/db/postgres/migration/prod/0.20/00_reaction.sql b/store/db/postgres/migration/prod/0.20/00_reaction.sql new file mode 100644 index 0000000000000..f9866ee946fab --- /dev/null +++ b/store/db/postgres/migration/prod/0.20/00_reaction.sql @@ -0,0 +1,9 @@ +-- reaction +CREATE TABLE reaction ( + id SERIAL PRIMARY KEY, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + creator_id INTEGER NOT NULL, + content_id TEXT NOT NULL, + reaction_type TEXT NOT NULL, + UNIQUE(creator_id, content_id, reaction_type) +); diff --git a/store/db/postgres/migration/prod/LATEST__SCHEMA.sql b/store/db/postgres/migration/prod/LATEST__SCHEMA.sql new file mode 100644 index 0000000000000..1ab5f95e4458a --- /dev/null +++ b/store/db/postgres/migration/prod/LATEST__SCHEMA.sql @@ -0,0 +1,143 @@ +-- migration_history +CREATE TABLE migration_history ( + version TEXT NOT NULL PRIMARY KEY, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()) +); + +-- system_setting +CREATE TABLE system_setting ( + name TEXT NOT NULL PRIMARY KEY, + value TEXT NOT NULL, + description TEXT NOT NULL +); + +-- user +CREATE TABLE "user" ( + id SERIAL PRIMARY KEY, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + updated_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + row_status TEXT NOT NULL DEFAULT 'NORMAL', + username TEXT NOT NULL UNIQUE, + role TEXT NOT NULL DEFAULT 'USER', + email TEXT NOT NULL DEFAULT '', + nickname TEXT NOT NULL DEFAULT '', + password_hash TEXT NOT NULL, + avatar_url TEXT NOT NULL +); + +-- user_setting +CREATE TABLE user_setting ( + user_id INTEGER NOT NULL, + key TEXT NOT NULL, + value TEXT NOT NULL, + UNIQUE(user_id, key) +); + +-- memo +CREATE TABLE memo ( + id SERIAL PRIMARY KEY, + resource_name TEXT NOT NULL UNIQUE, + creator_id INTEGER NOT NULL, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + updated_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + row_status TEXT NOT NULL DEFAULT 'NORMAL', + content TEXT NOT NULL, + visibility TEXT NOT NULL DEFAULT 'PRIVATE' +); + +-- memo_organizer +CREATE TABLE memo_organizer ( + memo_id INTEGER NOT NULL, + user_id INTEGER NOT NULL, + pinned INTEGER NOT NULL DEFAULT 0, + UNIQUE(memo_id, user_id) +); + +-- memo_relation +CREATE TABLE memo_relation ( + memo_id INTEGER NOT NULL, + related_memo_id INTEGER NOT NULL, + type TEXT NOT NULL, + UNIQUE(memo_id, related_memo_id, type) +); + +-- resource +CREATE TABLE resource ( + id SERIAL PRIMARY KEY, + resource_name TEXT NOT NULL UNIQUE, + creator_id INTEGER NOT NULL, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + updated_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + filename TEXT NOT NULL, + blob BYTEA, + external_link TEXT NOT NULL, + type TEXT NOT NULL DEFAULT '', + size INTEGER NOT NULL DEFAULT 0, + internal_path TEXT NOT NULL DEFAULT '', + memo_id INTEGER DEFAULT NULL +); + +-- tag +CREATE TABLE tag ( + name TEXT NOT NULL, + creator_id INTEGER NOT NULL, + UNIQUE(name, creator_id) +); + +-- activity +CREATE TABLE activity ( + id SERIAL PRIMARY KEY, + creator_id INTEGER NOT NULL, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + type TEXT NOT NULL DEFAULT '', + level TEXT NOT NULL DEFAULT 'INFO', + payload JSONB NOT NULL DEFAULT '{}' +); + +-- storage +CREATE TABLE storage ( + id SERIAL PRIMARY KEY, + name TEXT NOT NULL, + type TEXT NOT NULL, + config JSONB NOT NULL DEFAULT '{}' +); + +-- idp +CREATE TABLE idp ( + id SERIAL PRIMARY KEY, + name TEXT NOT NULL, + type TEXT NOT NULL, + identifier_filter TEXT NOT NULL DEFAULT '', + config JSONB NOT NULL DEFAULT '{}' +); + +-- inbox +CREATE TABLE inbox ( + id SERIAL PRIMARY KEY, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + sender_id INTEGER NOT NULL, + receiver_id INTEGER NOT NULL, + status TEXT NOT NULL, + message TEXT NOT NULL +); + +-- webhook +CREATE TABLE webhook ( + id SERIAL PRIMARY KEY, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + updated_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + row_status TEXT NOT NULL DEFAULT 'NORMAL', + creator_id INTEGER NOT NULL, + name TEXT NOT NULL, + url TEXT NOT NULL +); + +-- reaction +CREATE TABLE reaction ( + id SERIAL PRIMARY KEY, + created_ts BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()), + creator_id INTEGER NOT NULL, + content_id TEXT NOT NULL, + reaction_type TEXT NOT NULL, + UNIQUE(creator_id, content_id, reaction_type) +); diff --git a/store/db/postgres/migration_history.go b/store/db/postgres/migration_history.go new file mode 100644 index 0000000000000..385b898b47b4a --- /dev/null +++ b/store/db/postgres/migration_history.go @@ -0,0 +1,57 @@ +package postgres + +import ( + "context" + + "github.com/usememos/memos/store" +) + +func (d *DB) FindMigrationHistoryList(ctx context.Context, _ *store.FindMigrationHistory) ([]*store.MigrationHistory, error) { + query := "SELECT version, created_ts FROM migration_history ORDER BY created_ts DESC" + rows, err := d.db.QueryContext(ctx, query) + if err != nil { + return nil, err + } + defer rows.Close() + + list := make([]*store.MigrationHistory, 0) + for rows.Next() { + var migrationHistory store.MigrationHistory + if err := rows.Scan( + &migrationHistory.Version, + &migrationHistory.CreatedTs, + ); err != nil { + return nil, err + } + + list = append(list, &migrationHistory) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) UpsertMigrationHistory(ctx context.Context, upsert *store.UpsertMigrationHistory) (*store.MigrationHistory, error) { + stmt := ` + INSERT INTO migration_history ( + version + ) + VALUES ($1) + ON CONFLICT(version) DO UPDATE + SET + version=EXCLUDED.version + RETURNING version, created_ts + ` + var migrationHistory store.MigrationHistory + if err := d.db.QueryRowContext(ctx, stmt, upsert.Version).Scan( + &migrationHistory.Version, + &migrationHistory.CreatedTs, + ); err != nil { + return nil, err + } + + return &migrationHistory, nil +} diff --git a/store/db/postgres/migrator.go b/store/db/postgres/migrator.go new file mode 100644 index 0000000000000..21eeddb1d01a9 --- /dev/null +++ b/store/db/postgres/migrator.go @@ -0,0 +1,170 @@ +package postgres + +import ( + "context" + "embed" + "fmt" + "io/fs" + "regexp" + "sort" + "strings" + + "github.com/pkg/errors" + + "github.com/usememos/memos/server/version" + "github.com/usememos/memos/store" +) + +//go:embed migration +var migrationFS embed.FS + +const ( + latestSchemaFileName = "LATEST__SCHEMA.sql" +) + +func (d *DB) Migrate(ctx context.Context) error { + if d.profile.IsDev() { + return d.nonProdMigrate(ctx) + } + + return d.prodMigrate(ctx) +} + +func (d *DB) nonProdMigrate(ctx context.Context) error { + rows, err := d.db.QueryContext(ctx, "SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema';") + if err != nil { + return errors.Errorf("failed to query database tables: %s", err) + } + if rows.Err() != nil { + return errors.Errorf("failed to query database tables: %s", err) + } + defer rows.Close() + + var tables []string + for rows.Next() { + var table string + err := rows.Scan(&table) + if err != nil { + return errors.Errorf("failed to scan table name: %s", err) + } + tables = append(tables, table) + } + + if len(tables) != 0 { + return nil + } + + buf, err := migrationFS.ReadFile("migration/dev/" + latestSchemaFileName) + if err != nil { + return errors.Errorf("failed to read latest schema file: %s", err) + } + + stmt := string(buf) + if _, err := d.db.ExecContext(ctx, stmt); err != nil { + return errors.Errorf("failed to exec SQL %s: %s", stmt, err) + } + + return nil +} + +func (d *DB) prodMigrate(ctx context.Context) error { + currentVersion := version.GetCurrentVersion(d.profile.Mode) + migrationHistoryList, err := d.FindMigrationHistoryList(ctx, &store.FindMigrationHistory{}) + // If there is no migration history, we should apply the latest schema. + if err != nil || len(migrationHistoryList) == 0 { + buf, err := migrationFS.ReadFile("migration/prod/" + latestSchemaFileName) + if err != nil { + return errors.Errorf("failed to read latest schema file: %s", err) + } + + stmt := string(buf) + if _, err := d.db.ExecContext(ctx, stmt); err != nil { + return errors.Errorf("failed to exec SQL %s: %s", stmt, err) + } + if _, err := d.UpsertMigrationHistory(ctx, &store.UpsertMigrationHistory{ + Version: currentVersion, + }); err != nil { + return errors.Wrap(err, "failed to upsert migration history") + } + return nil + } + + migrationHistoryVersionList := []string{} + for _, migrationHistory := range migrationHistoryList { + migrationHistoryVersionList = append(migrationHistoryVersionList, migrationHistory.Version) + } + sort.Sort(version.SortVersion(migrationHistoryVersionList)) + latestMigrationHistoryVersion := migrationHistoryVersionList[len(migrationHistoryVersionList)-1] + if !version.IsVersionGreaterThan(version.GetSchemaVersion(currentVersion), latestMigrationHistoryVersion) { + return nil + } + + fmt.Println("start migrate") + for _, minorVersion := range getMinorVersionList() { + normalizedVersion := minorVersion + ".0" + if version.IsVersionGreaterThan(normalizedVersion, latestMigrationHistoryVersion) && version.IsVersionGreaterOrEqualThan(currentVersion, normalizedVersion) { + fmt.Println("applying migration for", normalizedVersion) + if err := d.applyMigrationForMinorVersion(ctx, minorVersion); err != nil { + return errors.Wrap(err, "failed to apply minor version migration") + } + } + } + fmt.Println("end migrate") + return nil +} + +func (d *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion string) error { + filenames, err := fs.Glob(migrationFS, fmt.Sprintf("migration/prod/%s/*.sql", minorVersion)) + if err != nil { + return errors.Wrap(err, "failed to read ddl files") + } + + sort.Strings(filenames) + // Loop over all migration files and execute them in order. + for _, filename := range filenames { + buf, err := migrationFS.ReadFile(filename) + if err != nil { + return errors.Wrapf(err, "failed to read minor version migration file, filename=%s", filename) + } + for _, stmt := range strings.Split(string(buf), ";") { + if strings.TrimSpace(stmt) == "" { + continue + } + if _, err := d.db.ExecContext(ctx, stmt); err != nil { + return errors.Wrapf(err, "migrate error: %s", stmt) + } + } + } + + // Upsert the newest version to migration_history. + version := minorVersion + ".0" + if _, err = d.UpsertMigrationHistory(ctx, &store.UpsertMigrationHistory{Version: version}); err != nil { + return errors.Wrapf(err, "failed to upsert migration history with version: %s", version) + } + + return nil +} + +// minorDirRegexp is a regular expression for minor version directory. +var minorDirRegexp = regexp.MustCompile(`^migration/prod/[0-9]+\.[0-9]+$`) + +func getMinorVersionList() []string { + minorVersionList := []string{} + + if err := fs.WalkDir(migrationFS, "migration", func(path string, file fs.DirEntry, err error) error { + if err != nil { + return err + } + if file.IsDir() && minorDirRegexp.MatchString(path) { + minorVersionList = append(minorVersionList, file.Name()) + } + + return nil + }); err != nil { + panic(err) + } + + sort.Sort(version.SortVersion(minorVersionList)) + + return minorVersionList +} diff --git a/store/db/postgres/postgres.go b/store/db/postgres/postgres.go new file mode 100644 index 0000000000000..57951e0c01872 --- /dev/null +++ b/store/db/postgres/postgres.go @@ -0,0 +1,86 @@ +package postgres + +import ( + "context" + "database/sql" + "log" + + // Import the PostgreSQL driver. + _ "github.com/lib/pq" + "github.com/pkg/errors" + + "github.com/usememos/memos/server/profile" + "github.com/usememos/memos/store" +) + +type DB struct { + db *sql.DB + profile *profile.Profile + // Add any other fields as needed +} + +func NewDB(profile *profile.Profile) (store.Driver, error) { + if profile == nil { + return nil, errors.New("profile is nil") + } + + // Open the PostgreSQL connection + db, err := sql.Open("postgres", profile.DSN) + if err != nil { + log.Printf("Failed to open database: %s", err) + return nil, errors.Wrapf(err, "failed to open database: %s", profile.DSN) + } + + var driver store.Driver = &DB{ + db: db, + profile: profile, + } + + // Return the DB struct + return driver, nil +} + +func (d *DB) GetDB() *sql.DB { + return d.db +} + +func (d *DB) Vacuum(ctx context.Context) error { + tx, err := d.db.BeginTx(ctx, nil) + if err != nil { + return err + } + defer tx.Rollback() + + if err := vacuumMemo(ctx, tx); err != nil { + return err + } + if err := vacuumResource(ctx, tx); err != nil { + return err + } + if err := vacuumUserSetting(ctx, tx); err != nil { + return err + } + if err := vacuumMemoOrganizer(ctx, tx); err != nil { + return err + } + if err := vacuumMemoRelations(ctx, tx); err != nil { + return err + } + if err := vacuumInbox(ctx, tx); err != nil { + return err + } + if err := vacuumTag(ctx, tx); err != nil { + // Prevent revive warning. + return err + } + + return tx.Commit() +} + +func (*DB) GetCurrentDBSize(context.Context) (int64, error) { + return 0, errors.New("unimplemented") +} + +func (d *DB) Close() error { + return d.db.Close() +} diff --git a/store/db/postgres/reaction.go b/store/db/postgres/reaction.go new file mode 100644 index 0000000000000..83a3c8f605d30 --- /dev/null +++ b/store/db/postgres/reaction.go @@ -0,0 +1,82 @@ +package postgres + +import ( + "context" + "strings" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (d *DB) UpsertReaction(ctx context.Context, upsert *storepb.Reaction) (*storepb.Reaction, error) { + fields := []string{"creator_id", "content_id", "reaction_type"} + args := []interface{}{upsert.CreatorId, upsert.ContentId, upsert.ReactionType.String()} + stmt := "INSERT INTO reaction (" + strings.Join(fields, ", ") + ") VALUES (" + placeholders(len(args)) + ") RETURNING id, created_ts" + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( + &upsert.Id, + &upsert.CreatedTs, + ); err != nil { + return nil, err + } + + reaction := upsert + return reaction, nil +} + +func (d *DB) ListReactions(ctx context.Context, find *store.FindReaction) ([]*storepb.Reaction, error) { + where, args := []string{"1 = 1"}, []interface{}{} + if find.ID != nil { + where, args = append(where, "id = "+placeholder(len(args)+1)), append(args, *find.ID) + } + if find.CreatorID != nil { + where, args = append(where, "creator_id = "+placeholder(len(args)+1)), append(args, *find.CreatorID) + } + if find.ContentID != nil { + where, args = append(where, "content_id = "+placeholder(len(args)+1)), append(args, *find.ContentID) + } + + rows, err := d.db.QueryContext(ctx, ` + SELECT + id, + created_ts, + creator_id, + content_id, + reaction_type + FROM reaction + WHERE `+strings.Join(where, " AND ")+` + ORDER BY id ASC`, + args..., + ) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*storepb.Reaction{} + for rows.Next() { + reaction := &storepb.Reaction{} + var reactionType string + if err := rows.Scan( + &reaction.Id, + &reaction.CreatedTs, + &reaction.CreatorId, + &reaction.ContentId, + &reactionType, + ); err != nil { + return nil, err + } + reaction.ReactionType = storepb.Reaction_Type(storepb.Reaction_Type_value[reactionType]) + list = append(list, reaction) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) DeleteReaction(ctx context.Context, delete *store.DeleteReaction) error { + _, err := d.db.ExecContext(ctx, "DELETE FROM reaction WHERE id = $1", delete.ID) + return err +} diff --git a/store/db/postgres/resource.go b/store/db/postgres/resource.go new file mode 100644 index 0000000000000..3ced746156bcc --- /dev/null +++ b/store/db/postgres/resource.go @@ -0,0 +1,174 @@ +package postgres + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "github.com/usememos/memos/store" +) + +func (d *DB) CreateResource(ctx context.Context, create *store.Resource) (*store.Resource, error) { + fields := []string{"resource_name", "filename", "blob", "external_link", "type", "size", "creator_id", "internal_path", "memo_id"} + args := []any{create.ResourceName, create.Filename, create.Blob, create.ExternalLink, create.Type, create.Size, create.CreatorID, create.InternalPath, create.MemoID} + + stmt := "INSERT INTO resource (" + strings.Join(fields, ", ") + ") VALUES (" + placeholders(len(args)) + ") RETURNING id, created_ts, updated_ts" + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan(&create.ID, &create.CreatedTs, &create.UpdatedTs); err != nil { + return nil, err + } + return create, nil +} + +func (d *DB) ListResources(ctx context.Context, find *store.FindResource) ([]*store.Resource, error) { + where, args := []string{"1 = 1"}, []any{} + + if v := find.ID; v != nil { + where, args = append(where, "id = "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.ResourceName; v != nil { + where, args = append(where, "resource_name = "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.CreatorID; v != nil { + where, args = append(where, "creator_id = "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.Filename; v != nil { + where, args = append(where, "filename = "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.MemoID; v != nil { + where, args = append(where, "memo_id = "+placeholder(len(args)+1)), append(args, *v) + } + if find.HasRelatedMemo { + where = append(where, "memo_id IS NOT NULL") + } + + fields := []string{"id", "resource_name", "filename", "external_link", "type", "size", "creator_id", "created_ts", "updated_ts", "internal_path", "memo_id"} + if find.GetBlob { + fields = append(fields, "blob") + } + + query := fmt.Sprintf(` + SELECT + %s + FROM resource + WHERE %s + ORDER BY updated_ts DESC, created_ts DESC + `, strings.Join(fields, ", "), strings.Join(where, " AND ")) + if find.Limit != nil { + query = fmt.Sprintf("%s LIMIT %d", query, *find.Limit) + if find.Offset != nil { + query = fmt.Sprintf("%s OFFSET %d", query, *find.Offset) + } + } + + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := make([]*store.Resource, 0) + for rows.Next() { + resource := store.Resource{} + var memoID sql.NullInt32 + dests := []any{ + &resource.ID, + &resource.ResourceName, + &resource.Filename, + &resource.ExternalLink, + &resource.Type, + &resource.Size, + &resource.CreatorID, + &resource.CreatedTs, + &resource.UpdatedTs, + &resource.InternalPath, + &memoID, + } + if find.GetBlob { + dests = append(dests, &resource.Blob) + } + if err := rows.Scan(dests...); err != nil { + return nil, err + } + if memoID.Valid { + resource.MemoID = &memoID.Int32 + } + list = append(list, &resource) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) UpdateResource(ctx context.Context, update *store.UpdateResource) (*store.Resource, error) { + set, args := []string{}, []any{} + + if v := update.ResourceName; v != nil { + set, args = append(set, "resource_name = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.UpdatedTs; v != nil { + set, args = append(set, "updated_ts = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.Filename; v != nil { + set, args = append(set, "filename = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.InternalPath; v != nil { + set, args = append(set, "internal_path = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.ExternalLink; v != nil { + set, args = append(set, "external_link = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.MemoID; v != nil { + set, args = append(set, "memo_id = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.Blob; v != nil { + set, args = append(set, "blob = "+placeholder(len(args)+1)), append(args, v) + } + + fields := []string{"id", "resource_name", "filename", "external_link", "type", "size", "creator_id", "created_ts", "updated_ts", "internal_path"} + stmt := `UPDATE resource SET ` + strings.Join(set, ", ") + ` WHERE id = ` + placeholder(len(args)+1) + ` RETURNING ` + strings.Join(fields, ", ") + args = append(args, update.ID) + resource := store.Resource{} + dests := []any{ + &resource.ID, + &resource.ResourceName, + &resource.Filename, + &resource.ExternalLink, + &resource.Type, + &resource.Size, + &resource.CreatorID, + &resource.CreatedTs, + &resource.UpdatedTs, + &resource.InternalPath, + } + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan(dests...); err != nil { + return nil, err + } + + return &resource, nil +} + +func (d *DB) DeleteResource(ctx context.Context, delete *store.DeleteResource) error { + stmt := `DELETE FROM resource WHERE id = $1` + result, err := d.db.ExecContext(ctx, stmt, delete.ID) + if err != nil { + return err + } + if _, err := result.RowsAffected(); err != nil { + return err + } + return nil +} + +func vacuumResource(ctx context.Context, tx *sql.Tx) error { + stmt := `DELETE FROM resource WHERE creator_id NOT IN (SELECT id FROM "user")` + _, err := tx.ExecContext(ctx, stmt) + if err != nil { + return err + } + + return nil +} diff --git a/store/db/postgres/storage.go b/store/db/postgres/storage.go new file mode 100644 index 0000000000000..e3610d17aa08f --- /dev/null +++ b/store/db/postgres/storage.go @@ -0,0 +1,102 @@ +package postgres + +import ( + "context" + "strings" + + "github.com/usememos/memos/store" +) + +func (d *DB) CreateStorage(ctx context.Context, create *store.Storage) (*store.Storage, error) { + fields := []string{"name", "type", "config"} + args := []any{create.Name, create.Type, create.Config} + + stmt := "INSERT INTO storage (" + strings.Join(fields, ", ") + ") VALUES (" + placeholders(len(args)) + ") RETURNING id" + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( + &create.ID, + ); err != nil { + return nil, err + } + + storage := create + return storage, nil +} + +func (d *DB) ListStorages(ctx context.Context, find *store.FindStorage) ([]*store.Storage, error) { + where, args := []string{"1 = 1"}, []any{} + if find.ID != nil { + where, args = append(where, "id = "+placeholder(len(args)+1)), append(args, *find.ID) + } + + rows, err := d.db.QueryContext(ctx, ` + SELECT + id, + name, + type, + config + FROM storage + WHERE `+strings.Join(where, " AND ")+` + ORDER BY id DESC`, + args..., + ) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*store.Storage{} + for rows.Next() { + storage := &store.Storage{} + if err := rows.Scan( + &storage.ID, + &storage.Name, + &storage.Type, + &storage.Config, + ); err != nil { + return nil, err + } + list = append(list, storage) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) UpdateStorage(ctx context.Context, update *store.UpdateStorage) (*store.Storage, error) { + set, args := []string{}, []any{} + if update.Name != nil { + set, args = append(set, "name = "+placeholder(len(args)+1)), append(args, *update.Name) + } + if update.Config != nil { + set, args = append(set, "config = "+placeholder(len(args)+1)), append(args, *update.Config) + } + + stmt := `UPDATE storage SET ` + strings.Join(set, ", ") + ` WHERE id = ` + placeholder(len(args)+1) + ` RETURNING id, name, type, config` + args = append(args, update.ID) + storage := &store.Storage{} + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( + &storage.ID, + &storage.Name, + &storage.Type, + &storage.Config, + ); err != nil { + return nil, err + } + + return storage, nil +} + +func (d *DB) DeleteStorage(ctx context.Context, delete *store.DeleteStorage) error { + stmt := `DELETE FROM storage WHERE id = $1` + result, err := d.db.ExecContext(ctx, stmt, delete.ID) + if err != nil { + return err + } + if _, err := result.RowsAffected(); err != nil { + return err + } + return nil +} diff --git a/store/db/postgres/tag.go b/store/db/postgres/tag.go new file mode 100644 index 0000000000000..d23118ebf9a03 --- /dev/null +++ b/store/db/postgres/tag.go @@ -0,0 +1,81 @@ +package postgres + +import ( + "context" + "database/sql" + "strings" + + "github.com/usememos/memos/store" +) + +func (d *DB) UpsertTag(ctx context.Context, upsert *store.Tag) (*store.Tag, error) { + stmt := "INSERT INTO tag (name, creator_id) VALUES ($1, $2) ON CONFLICT (name, creator_id) DO UPDATE SET name = $3" + if _, err := d.db.ExecContext(ctx, stmt, upsert.Name, upsert.CreatorID, upsert.Name); err != nil { + return nil, err + } + return upsert, nil +} + +func (d *DB) ListTags(ctx context.Context, find *store.FindTag) ([]*store.Tag, error) { + where, args := []string{"1 = 1"}, []any{} + + if find.CreatorID != 0 { + where, args = append(where, "creator_id = "+placeholder(len(args)+1)), append(args, find.CreatorID) + } + + query := ` + SELECT + name, + creator_id + FROM tag + WHERE ` + strings.Join(where, " AND ") + ` + ORDER BY name ASC + ` + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*store.Tag{} + for rows.Next() { + tag := &store.Tag{} + if err := rows.Scan( + &tag.Name, + &tag.CreatorID, + ); err != nil { + return nil, err + } + + list = append(list, tag) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) DeleteTag(ctx context.Context, delete *store.DeleteTag) error { + where, args := []string{"name = $1", "creator_id = $2"}, []any{delete.Name, delete.CreatorID} + stmt := `DELETE FROM tag WHERE ` + strings.Join(where, " AND ") + result, err := d.db.ExecContext(ctx, stmt, args...) + if err != nil { + return err + } + if _, err = result.RowsAffected(); err != nil { + return err + } + return nil +} + +func vacuumTag(ctx context.Context, tx *sql.Tx) error { + stmt := `DELETE FROM tag WHERE creator_id NOT IN (SELECT id FROM "user")` + _, err := tx.ExecContext(ctx, stmt) + if err != nil { + return err + } + + return nil +} diff --git a/store/db/postgres/user.go b/store/db/postgres/user.go new file mode 100644 index 0000000000000..588bbac376630 --- /dev/null +++ b/store/db/postgres/user.go @@ -0,0 +1,162 @@ +package postgres + +import ( + "context" + "strings" + + "github.com/usememos/memos/store" +) + +func (d *DB) CreateUser(ctx context.Context, create *store.User) (*store.User, error) { + fields := []string{"username", "role", "email", "nickname", "password_hash", "avatar_url"} + args := []any{create.Username, create.Role, create.Email, create.Nickname, create.PasswordHash, create.AvatarURL} + stmt := "INSERT INTO \"user\" (" + strings.Join(fields, ", ") + ") VALUES (" + placeholders(len(args)) + ") RETURNING id, avatar_url, created_ts, updated_ts, row_status" + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( + &create.ID, + &create.AvatarURL, + &create.CreatedTs, + &create.UpdatedTs, + &create.RowStatus, + ); err != nil { + return nil, err + } + + return create, nil +} + +func (d *DB) UpdateUser(ctx context.Context, update *store.UpdateUser) (*store.User, error) { + set, args := []string{}, []any{} + if v := update.UpdatedTs; v != nil { + set, args = append(set, "updated_ts = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.RowStatus; v != nil { + set, args = append(set, "row_status = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.Username; v != nil { + set, args = append(set, "username = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.Email; v != nil { + set, args = append(set, "email = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.Nickname; v != nil { + set, args = append(set, "nickname = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.AvatarURL; v != nil { + set, args = append(set, "avatar_url = "+placeholder(len(args)+1)), append(args, *v) + } + if v := update.PasswordHash; v != nil { + set, args = append(set, "password_hash = "+placeholder(len(args)+1)), append(args, *v) + } + + query := ` + UPDATE "user" + SET ` + strings.Join(set, ", ") + ` + WHERE id = ` + placeholder(len(args)+1) + ` + RETURNING id, username, role, email, nickname, password_hash, avatar_url, created_ts, updated_ts, row_status + ` + args = append(args, update.ID) + user := &store.User{} + if err := d.db.QueryRowContext(ctx, query, args...).Scan( + &user.ID, + &user.Username, + &user.Role, + &user.Email, + &user.Nickname, + &user.PasswordHash, + &user.AvatarURL, + &user.CreatedTs, + &user.UpdatedTs, + &user.RowStatus, + ); err != nil { + return nil, err + } + + return user, nil +} + +func (d *DB) ListUsers(ctx context.Context, find *store.FindUser) ([]*store.User, error) { + where, args := []string{"1 = 1"}, []any{} + + if v := find.ID; v != nil { + where, args = append(where, "id = "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.Username; v != nil { + where, args = append(where, "username = "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.Role; v != nil { + where, args = append(where, "role = "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.Email; v != nil { + where, args = append(where, "email = "+placeholder(len(args)+1)), append(args, *v) + } + if v := find.Nickname; v != nil { + where, args = append(where, "nickname = "+placeholder(len(args)+1)), append(args, *v) + } + + query := ` + SELECT + id, + username, + role, + email, + nickname, + password_hash, + avatar_url, + created_ts, + updated_ts, + row_status + FROM "user" + WHERE ` + strings.Join(where, " AND ") + ` + ORDER BY created_ts DESC, row_status DESC + ` + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := make([]*store.User, 0) + for rows.Next() { + var user store.User + if err := rows.Scan( + &user.ID, + &user.Username, + &user.Role, + &user.Email, + &user.Nickname, + &user.PasswordHash, + &user.AvatarURL, + &user.CreatedTs, + &user.UpdatedTs, + &user.RowStatus, + ); err != nil { + return nil, err + } + list = append(list, &user) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) DeleteUser(ctx context.Context, delete *store.DeleteUser) error { + result, err := d.db.ExecContext(ctx, ` + DELETE FROM "user" WHERE id = $1 + `, delete.ID) + if err != nil { + return err + } + if _, err := result.RowsAffected(); err != nil { + return err + } + + if err := d.Vacuum(ctx); err != nil { + // Prevent linter warning. + return err + } + + return nil +} diff --git a/store/db/postgres/user_setting.go b/store/db/postgres/user_setting.go new file mode 100644 index 0000000000000..71c5fd3fa702b --- /dev/null +++ b/store/db/postgres/user_setting.go @@ -0,0 +1,131 @@ +package postgres + +import ( + "context" + "database/sql" + "strings" + + "github.com/pkg/errors" + "google.golang.org/protobuf/encoding/protojson" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (d *DB) UpsertUserSetting(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) { + stmt := ` + INSERT INTO user_setting ( + user_id, key, value + ) + VALUES ($1, $2, $3) + ON CONFLICT(user_id, key) DO UPDATE + SET value = EXCLUDED.value + ` + var valueString string + if upsert.Key == storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS { + valueBytes, err := protojson.Marshal(upsert.GetAccessTokens()) + if err != nil { + return nil, err + } + valueString = string(valueBytes) + } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_LOCALE { + valueString = upsert.GetLocale() + } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_APPEARANCE { + valueString = upsert.GetAppearance() + } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_MEMO_VISIBILITY { + valueString = upsert.GetMemoVisibility() + } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_TELEGRAM_USER_ID { + valueString = upsert.GetTelegramUserId() + } else { + return nil, errors.Errorf("unknown user setting key: %s", upsert.Key.String()) + } + + if _, err := d.db.ExecContext(ctx, stmt, upsert.UserId, upsert.Key.String(), valueString); err != nil { + return nil, err + } + + return upsert, nil +} + +func (d *DB) ListUserSettings(ctx context.Context, find *store.FindUserSetting) ([]*storepb.UserSetting, error) { + where, args := []string{"1 = 1"}, []any{} + + if v := find.Key; v != storepb.UserSettingKey_USER_SETTING_KEY_UNSPECIFIED { + where, args = append(where, "key = "+placeholder(len(args)+1)), append(args, v.String()) + } + if v := find.UserID; v != nil { + where, args = append(where, "user_id = "+placeholder(len(args)+1)), append(args, *find.UserID) + } + + query := ` + SELECT + user_id, + key, + value + FROM user_setting + WHERE ` + strings.Join(where, " AND ") + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + userSettingList := make([]*storepb.UserSetting, 0) + for rows.Next() { + userSetting := &storepb.UserSetting{} + var keyString, valueString string + if err := rows.Scan( + &userSetting.UserId, + &keyString, + &valueString, + ); err != nil { + return nil, err + } + userSetting.Key = storepb.UserSettingKey(storepb.UserSettingKey_value[keyString]) + if userSetting.Key == storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS { + accessTokensUserSetting := &storepb.AccessTokensUserSetting{} + if err := protojson.Unmarshal([]byte(valueString), accessTokensUserSetting); err != nil { + return nil, err + } + userSetting.Value = &storepb.UserSetting_AccessTokens{ + AccessTokens: accessTokensUserSetting, + } + } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_LOCALE { + userSetting.Value = &storepb.UserSetting_Locale{ + Locale: valueString, + } + } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_APPEARANCE { + userSetting.Value = &storepb.UserSetting_Appearance{ + Appearance: valueString, + } + } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_MEMO_VISIBILITY { + userSetting.Value = &storepb.UserSetting_MemoVisibility{ + MemoVisibility: valueString, + } + } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_TELEGRAM_USER_ID { + userSetting.Value = &storepb.UserSetting_TelegramUserId{ + TelegramUserId: valueString, + } + } else { + // Skip unknown user setting key. + continue + } + userSettingList = append(userSettingList, userSetting) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return userSettingList, nil +} + +func vacuumUserSetting(ctx context.Context, tx *sql.Tx) error { + stmt := `DELETE FROM user_setting WHERE user_id NOT IN (SELECT id FROM "user")` + _, err := tx.ExecContext(ctx, stmt) + if err != nil { + return err + } + + return nil +} diff --git a/store/db/postgres/webhook.go b/store/db/postgres/webhook.go new file mode 100644 index 0000000000000..d0baf0f296da8 --- /dev/null +++ b/store/db/postgres/webhook.go @@ -0,0 +1,118 @@ +package postgres + +import ( + "context" + "strings" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (d *DB) CreateWebhook(ctx context.Context, create *storepb.Webhook) (*storepb.Webhook, error) { + fields := []string{"name", "url", "creator_id"} + args := []any{create.Name, create.Url, create.CreatorId} + stmt := "INSERT INTO webhook (" + strings.Join(fields, ", ") + ") VALUES (" + placeholders(len(args)) + ") RETURNING id, created_ts, updated_ts, row_status" + var rowStatus string + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( + &create.Id, + &create.CreatedTs, + &create.UpdatedTs, + &rowStatus, + ); err != nil { + return nil, err + } + + create.RowStatus = storepb.RowStatus(storepb.RowStatus_value[rowStatus]) + webhook := create + return webhook, nil +} + +func (d *DB) ListWebhooks(ctx context.Context, find *store.FindWebhook) ([]*storepb.Webhook, error) { + where, args := []string{"1 = 1"}, []any{} + if find.ID != nil { + where, args = append(where, "id = "+placeholder(len(args)+1)), append(args, *find.ID) + } + if find.CreatorID != nil { + where, args = append(where, "creator_id = "+placeholder(len(args)+1)), append(args, *find.CreatorID) + } + + rows, err := d.db.QueryContext(ctx, ` + SELECT + id, + created_ts, + updated_ts, + row_status, + creator_id, + name, + url + FROM webhook + WHERE `+strings.Join(where, " AND ")+` + ORDER BY id DESC`, + args..., + ) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*storepb.Webhook{} + for rows.Next() { + webhook := &storepb.Webhook{} + var rowStatus string + if err := rows.Scan( + &webhook.Id, + &webhook.CreatedTs, + &webhook.UpdatedTs, + &rowStatus, + &webhook.CreatorId, + &webhook.Name, + &webhook.Url, + ); err != nil { + return nil, err + } + webhook.RowStatus = storepb.RowStatus(storepb.RowStatus_value[rowStatus]) + list = append(list, webhook) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) UpdateWebhook(ctx context.Context, update *store.UpdateWebhook) (*storepb.Webhook, error) { + set, args := []string{}, []any{} + if update.RowStatus != nil { + set, args = append(set, "row_status = "+placeholder(len(args)+1)), append(args, update.RowStatus.String()) + } + if update.Name != nil { + set, args = append(set, "name = "+placeholder(len(args)+1)), append(args, *update.Name) + } + if update.URL != nil { + set, args = append(set, "url = "+placeholder(len(args)+1)), append(args, *update.URL) + } + + stmt := "UPDATE webhook SET " + strings.Join(set, ", ") + " WHERE id = " + placeholder(len(args)+1) + " RETURNING id, created_ts, updated_ts, row_status, creator_id, name, url" + args = append(args, update.ID) + webhook := &storepb.Webhook{} + var rowStatus string + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( + &webhook.Id, + &webhook.CreatedTs, + &webhook.UpdatedTs, + &rowStatus, + &webhook.CreatorId, + &webhook.Name, + &webhook.Url, + ); err != nil { + return nil, err + } + webhook.RowStatus = storepb.RowStatus(storepb.RowStatus_value[rowStatus]) + return webhook, nil +} + +func (d *DB) DeleteWebhook(ctx context.Context, delete *store.DeleteWebhook) error { + _, err := d.db.ExecContext(ctx, "DELETE FROM webhook WHERE id = $1", delete.ID) + return err +} diff --git a/store/db/postgres/workspace_setting.go b/store/db/postgres/workspace_setting.go new file mode 100644 index 0000000000000..c38778d86aa38 --- /dev/null +++ b/store/db/postgres/workspace_setting.go @@ -0,0 +1,141 @@ +package postgres + +import ( + "context" + "strings" + + "google.golang.org/protobuf/encoding/protojson" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (d *DB) UpsertWorkspaceSetting(ctx context.Context, upsert *store.WorkspaceSetting) (*store.WorkspaceSetting, error) { + stmt := ` + INSERT INTO system_setting ( + name, value, description + ) + VALUES ($1, $2, $3) + ON CONFLICT(name) DO UPDATE + SET + value = EXCLUDED.value, + description = EXCLUDED.description + ` + if _, err := d.db.ExecContext(ctx, stmt, upsert.Name, upsert.Value, upsert.Description); err != nil { + return nil, err + } + + return upsert, nil +} + +func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspaceSetting) ([]*store.WorkspaceSetting, error) { + where, args := []string{"1 = 1"}, []any{} + if find.Name != "" { + where, args = append(where, "name = "+placeholder(len(args)+1)), append(args, find.Name) + } + + query := ` + SELECT + name, + value, + description + FROM system_setting + WHERE ` + strings.Join(where, " AND ") + + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*store.WorkspaceSetting{} + for rows.Next() { + systemSettingMessage := &store.WorkspaceSetting{} + if err := rows.Scan( + &systemSettingMessage.Name, + &systemSettingMessage.Value, + &systemSettingMessage.Description, + ); err != nil { + return nil, err + } + list = append(list, systemSettingMessage) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) DeleteWorkspaceSetting(ctx context.Context, delete *store.DeleteWorkspaceSetting) error { + stmt := `DELETE FROM system_setting WHERE name = $1` + _, err := d.db.ExecContext(ctx, stmt, delete.Name) + return err +} + +func (d *DB) UpsertWorkspaceSettingV1(ctx context.Context, upsert *storepb.WorkspaceSetting) (*storepb.WorkspaceSetting, error) { + stmt := ` + INSERT INTO system_setting ( + name, value, description + ) + VALUES ($1, $2, '') + ON CONFLICT(name) DO UPDATE + SET value = EXCLUDED.value` + var valueString string + if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_GENERAL { + valueBytes, err := protojson.Marshal(upsert.GetGeneral()) + if err != nil { + return nil, err + } + valueString = string(valueBytes) + } + if _, err := d.db.ExecContext(ctx, stmt, upsert.Key.String(), valueString); err != nil { + return nil, err + } + return upsert, nil +} + +func (d *DB) ListWorkspaceSettingsV1(ctx context.Context, find *store.FindWorkspaceSettingV1) ([]*storepb.WorkspaceSetting, error) { + where, args := []string{"1 = 1"}, []any{} + if find.Key != storepb.WorkspaceSettingKey_WORKSPACE_SETTING_KEY_UNSPECIFIED { + where, args = append(where, "name = "+placeholder(len(args)+1)), append(args, find.Key.String()) + } + + query := `SELECT name, value FROM system_setting WHERE ` + strings.Join(where, " AND ") + + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*storepb.WorkspaceSetting{} + for rows.Next() { + workspaceSetting := &storepb.WorkspaceSetting{} + var keyString, valueString string + if err := rows.Scan( + &keyString, + &valueString, + ); err != nil { + return nil, err + } + workspaceSetting.Key = storepb.WorkspaceSettingKey(storepb.WorkspaceSettingKey_value[keyString]) + if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_GENERAL { + generalSetting := &storepb.WorkspaceGeneralSetting{} + if err := protojson.Unmarshal([]byte(valueString), generalSetting); err != nil { + return nil, err + } + workspaceSetting.Value = &storepb.WorkspaceSetting_General{General: generalSetting} + } else { + // Skip unknown workspace setting key. + continue + } + list = append(list, workspaceSetting) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} diff --git a/store/db/sqlite/activity.go b/store/db/sqlite/activity.go index 1853df1ea1d5d..8bbe331ce3efc 100644 --- a/store/db/sqlite/activity.go +++ b/store/db/sqlite/activity.go @@ -25,18 +25,6 @@ func (d *DB) CreateActivity(ctx context.Context, create *store.Activity) (*store placeholder := []string{"?", "?", "?", "?"} args := []any{create.CreatorID, create.Type.String(), create.Level.String(), payloadString} - if create.ID != 0 { - fields = append(fields, "`id`") - placeholder = append(placeholder, "?") - args = append(args, create.ID) - } - - if create.CreatedTs != 0 { - fields = append(fields, "`created_ts`") - placeholder = append(placeholder, "?") - args = append(args, create.CreatedTs) - } - stmt := "INSERT INTO activity (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ") RETURNING `id`, `created_ts`" if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( &create.ID, @@ -50,12 +38,14 @@ func (d *DB) CreateActivity(ctx context.Context, create *store.Activity) (*store func (d *DB) ListActivities(ctx context.Context, find *store.FindActivity) ([]*store.Activity, error) { where, args := []string{"1 = 1"}, []any{} - if find.ID != nil { where, args = append(where, "`id` = ?"), append(args, *find.ID) } + if find.Type != nil { + where, args = append(where, "`type` = ?"), append(args, find.Type.String()) + } - query := "SELECT `id`, `creator_id`, `type`, `level`, `payload`, `created_ts` FROM `activity` WHERE " + strings.Join(where, " AND ") + query := "SELECT `id`, `creator_id`, `type`, `level`, `payload`, `created_ts` FROM `activity` WHERE " + strings.Join(where, " AND ") + " ORDER BY `created_ts` DESC" rows, err := d.db.QueryContext(ctx, query, args...) if err != nil { return nil, err diff --git a/store/db/sqlite/idp.go b/store/db/sqlite/idp.go index 27b864b7a8abc..484d8d8de3fd7 100644 --- a/store/db/sqlite/idp.go +++ b/store/db/sqlite/idp.go @@ -27,10 +27,6 @@ func (d *DB) CreateIdentityProvider(ctx context.Context, create *store.IdentityP fields := []string{"`name`", "`type`", "`identifier_filter`", "`config`"} args := []any{create.Name, create.Type, create.IdentifierFilter, string(configBytes)} - if create.ID != 0 { - fields, placeholders, args = append(fields, "`id`"), append(placeholders, "?"), append(args, create.ID) - } - stmt := "INSERT INTO `idp` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholders, ", ") + ") RETURNING `id`" if err := d.db.QueryRowContext(ctx, stmt, args...).Scan(&create.ID); err != nil { return nil, err @@ -97,19 +93,6 @@ func (d *DB) ListIdentityProviders(ctx context.Context, find *store.FindIdentity return identityProviders, nil } -func (d *DB) GetIdentityProvider(ctx context.Context, find *store.FindIdentityProvider) (*store.IdentityProvider, error) { - list, err := d.ListIdentityProviders(ctx, find) - if err != nil { - return nil, err - } - if len(list) == 0 { - return nil, nil - } - - identityProvider := list[0] - return identityProvider, nil -} - func (d *DB) UpdateIdentityProvider(ctx context.Context, update *store.UpdateIdentityProvider) (*store.IdentityProvider, error) { set, args := []string{}, []any{} if v := update.Name; v != nil { diff --git a/store/db/sqlite/inbox.go b/store/db/sqlite/inbox.go index 97331c5ddc62e..72865b8f20b9c 100644 --- a/store/db/sqlite/inbox.go +++ b/store/db/sqlite/inbox.go @@ -2,6 +2,7 @@ package sqlite import ( "context" + "database/sql" "strings" "github.com/pkg/errors" @@ -123,3 +124,22 @@ func (d *DB) DeleteInbox(ctx context.Context, delete *store.DeleteInbox) error { } return nil } + +func vacuumInbox(ctx context.Context, tx *sql.Tx) error { + stmt := ` + DELETE FROM + inbox + WHERE + sender_id NOT IN ( + SELECT + id + FROM + user + )` + _, err := tx.ExecContext(ctx, stmt) + if err != nil { + return err + } + + return nil +} diff --git a/store/db/sqlite/memo.go b/store/db/sqlite/memo.go index 9a729e5f9fb98..2257a0e583b8d 100644 --- a/store/db/sqlite/memo.go +++ b/store/db/sqlite/memo.go @@ -6,42 +6,15 @@ import ( "fmt" "strings" - "github.com/pkg/errors" - - "github.com/usememos/memos/internal/util" "github.com/usememos/memos/store" ) func (d *DB) CreateMemo(ctx context.Context, create *store.Memo) (*store.Memo, error) { - fields := []string{"`creator_id`", "`content`", "`visibility`"} - placeholder := []string{"?", "?", "?"} - args := []any{create.CreatorID, create.Content, create.Visibility} - - if create.ID != 0 { - fields = append(fields, "`id`") - placeholder = append(placeholder, "?") - args = append(args, create.ID) - } - - if create.CreatedTs != 0 { - fields = append(fields, "`created_ts`") - placeholder = append(placeholder, "?") - args = append(args, create.CreatedTs) - } + fields := []string{"`resource_name`", "`creator_id`", "`content`", "`visibility`"} + placeholder := []string{"?", "?", "?", "?"} + args := []any{create.ResourceName, create.CreatorID, create.Content, create.Visibility} - if create.UpdatedTs != 0 { - fields = append(fields, "`updated_ts`") - placeholder = append(placeholder, "?") - args = append(args, create.UpdatedTs) - } - - if create.RowStatus != "" { - fields = append(fields, "`row_status`") - placeholder = append(placeholder, "?") - args = append(args, create.RowStatus) - } - - stmt := "INSERT INTO memo (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ") RETURNING `id`, `created_ts`, `updated_ts`, `row_status`" + stmt := "INSERT INTO `memo` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ") RETURNING `id`, `created_ts`, `updated_ts`, `row_status`" if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( &create.ID, &create.CreatedTs, @@ -58,95 +31,77 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo where, args := []string{"1 = 1"}, []any{} if v := find.ID; v != nil { - where, args = append(where, "memo.id = ?"), append(args, *v) + where, args = append(where, "`memo`.`id` = ?"), append(args, *v) + } + if v := find.ResourceName; v != nil { + where, args = append(where, "`memo`.`resource_name` = ?"), append(args, *v) } if v := find.CreatorID; v != nil { - where, args = append(where, "memo.creator_id = ?"), append(args, *v) + where, args = append(where, "`memo`.`creator_id` = ?"), append(args, *v) } if v := find.RowStatus; v != nil { - where, args = append(where, "memo.row_status = ?"), append(args, *v) + where, args = append(where, "`memo`.`row_status` = ?"), append(args, *v) } if v := find.CreatedTsBefore; v != nil { - where, args = append(where, "memo.created_ts < ?"), append(args, *v) + where, args = append(where, "`memo`.`created_ts` < ?"), append(args, *v) } if v := find.CreatedTsAfter; v != nil { - where, args = append(where, "memo.created_ts > ?"), append(args, *v) + where, args = append(where, "`memo`.`created_ts` > ?"), append(args, *v) + } + if v := find.UpdatedTsBefore; v != nil { + where, args = append(where, "`memo`.`updated_ts` < ?"), append(args, *v) + } + if v := find.UpdatedTsAfter; v != nil { + where, args = append(where, "`memo`.`updated_ts` > ?"), append(args, *v) } if v := find.ContentSearch; len(v) != 0 { for _, s := range v { - where, args = append(where, "memo.content LIKE ?"), append(args, "%"+s+"%") + where, args = append(where, "`memo`.`content` LIKE ?"), append(args, fmt.Sprintf("%%%s%%", s)) } } if v := find.VisibilityList; len(v) != 0 { - list := []string{} + placeholder := []string{} for _, visibility := range v { - list = append(list, fmt.Sprintf("$%d", len(args)+1)) - args = append(args, visibility) + placeholder = append(placeholder, "?") + args = append(args, visibility.String()) } - where = append(where, fmt.Sprintf("memo.visibility in (%s)", strings.Join(list, ","))) + where = append(where, fmt.Sprintf("`memo`.`visibility` IN (%s)", strings.Join(placeholder, ","))) } - if v := find.Pinned; v != nil { - where = append(where, "memo_organizer.pinned = 1") - } - if v := find.HasParent; v != nil { - if *v { - where = append(where, "parent_id IS NOT NULL") - } else { - where = append(where, "parent_id IS NULL") - } + if find.ExcludeComments { + where = append(where, "`parent_id` IS NULL") } - orders := []string{"pinned DESC"} + orders := []string{} + if find.OrderByPinned { + orders = append(orders, "`pinned` DESC") + } if find.OrderByUpdatedTs { - orders = append(orders, "updated_ts DESC") + orders = append(orders, "`updated_ts` DESC") } else { - orders = append(orders, "created_ts DESC") + orders = append(orders, "`created_ts` DESC") } - orders = append(orders, "id DESC") + orders = append(orders, "`id` DESC") fields := []string{ - `memo.id AS id,`, - `memo.creator_id AS creator_id,`, - `memo.created_ts AS created_ts,`, - `memo.updated_ts AS updated_ts,`, - `memo.row_status AS row_status,`, - `memo.visibility AS visibility,`, + "`memo`.`id` AS `id`", + "`memo`.`resource_name` AS `resource_name`", + "`memo`.`creator_id` AS `creator_id`", + "`memo`.`created_ts` AS `created_ts`", + "`memo`.`updated_ts` AS `updated_ts`", + "`memo`.`row_status` AS `row_status`", + "`memo`.`visibility` AS `visibility`", + "IFNULL(`memo_organizer`.`pinned`, 0) AS `pinned`", + "`memo_relation`.`related_memo_id` AS `parent_id`", } if !find.ExcludeContent { - fields = append(fields, `memo.content AS content,`) + fields = append(fields, "`memo`.`content` AS `content`") } - query := ` - SELECT - ` + strings.Join(fields, "\n") + ` - CASE WHEN mo.pinned = 1 THEN 1 ELSE 0 END AS pinned, - ( - SELECT - related_memo_id - FROM - memo_relation - WHERE - memo_relation.memo_id = memo.id AND memo_relation.type = 'COMMENT' - LIMIT 1 - ) AS parent_id, - GROUP_CONCAT(resource.id) AS resource_id_list, - ( - SELECT - GROUP_CONCAT(memo_relation.memo_id || ':' || memo_relation.related_memo_id || ':' || memo_relation.type) - FROM - memo_relation - WHERE - memo_relation.memo_id = memo.id OR memo_relation.related_memo_id = memo.id - ) AS relation_list - FROM - memo - LEFT JOIN - memo_organizer mo ON memo.id = mo.memo_id - LEFT JOIN - resource ON memo.id = resource.memo_id - WHERE ` + strings.Join(where, " AND ") + ` - GROUP BY memo.id - ORDER BY ` + strings.Join(orders, ", ") + query := "SELECT " + strings.Join(fields, ", ") + "FROM `memo` " + + "LEFT JOIN `memo_organizer` ON `memo`.`id` = `memo_organizer`.`memo_id` AND `memo`.`creator_id` = `memo_organizer`.`user_id` " + + "LEFT JOIN `memo_relation` ON `memo`.`id` = `memo_relation`.`memo_id` AND `memo_relation`.`type` = \"COMMENT\" " + + "WHERE " + strings.Join(where, " AND ") + " " + + "ORDER BY " + strings.Join(orders, ", ") if find.Limit != nil { query = fmt.Sprintf("%s LIMIT %d", query, *find.Limit) if find.Offset != nil { @@ -163,59 +118,23 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo list := make([]*store.Memo, 0) for rows.Next() { var memo store.Memo - var memoResourceIDList sql.NullString - var memoRelationList sql.NullString dests := []any{ &memo.ID, + &memo.ResourceName, &memo.CreatorID, &memo.CreatedTs, &memo.UpdatedTs, &memo.RowStatus, &memo.Visibility, + &memo.Pinned, + &memo.ParentID, } if !find.ExcludeContent { dests = append(dests, &memo.Content) } - dests = append(dests, &memo.Pinned, &memo.ParentID, &memoResourceIDList, &memoRelationList) if err := rows.Scan(dests...); err != nil { return nil, err } - - if memoResourceIDList.Valid { - idStringList := strings.Split(memoResourceIDList.String, ",") - memo.ResourceIDList = make([]int32, 0, len(idStringList)) - for _, idString := range idStringList { - id, err := util.ConvertStringToInt32(idString) - if err != nil { - return nil, err - } - memo.ResourceIDList = append(memo.ResourceIDList, id) - } - } - if memoRelationList.Valid { - memo.RelationList = make([]*store.MemoRelation, 0) - relatedMemoTypeList := strings.Split(memoRelationList.String, ",") - for _, relatedMemoType := range relatedMemoTypeList { - relatedMemoTypeList := strings.Split(relatedMemoType, ":") - if len(relatedMemoTypeList) != 3 { - return nil, errors.New("invalid relation format") - } - memoID, err := util.ConvertStringToInt32(relatedMemoTypeList[0]) - if err != nil { - return nil, err - } - relatedMemoID, err := util.ConvertStringToInt32(relatedMemoTypeList[1]) - if err != nil { - return nil, err - } - relationType := store.MemoRelationType(relatedMemoTypeList[2]) - memo.RelationList = append(memo.RelationList, &store.MemoRelation{ - MemoID: memoID, - RelatedMemoID: relatedMemoID, - Type: relationType, - }) - } - } list = append(list, &memo) } @@ -228,28 +147,27 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo func (d *DB) UpdateMemo(ctx context.Context, update *store.UpdateMemo) error { set, args := []string{}, []any{} + if v := update.ResourceName; v != nil { + set, args = append(set, "`resource_name` = ?"), append(args, *v) + } if v := update.CreatedTs; v != nil { - set, args = append(set, "created_ts = ?"), append(args, *v) + set, args = append(set, "`created_ts` = ?"), append(args, *v) } if v := update.UpdatedTs; v != nil { - set, args = append(set, "updated_ts = ?"), append(args, *v) + set, args = append(set, "`updated_ts` = ?"), append(args, *v) } if v := update.RowStatus; v != nil { - set, args = append(set, "row_status = ?"), append(args, *v) + set, args = append(set, "`row_status` = ?"), append(args, *v) } if v := update.Content; v != nil { - set, args = append(set, "content = ?"), append(args, *v) + set, args = append(set, "`content` = ?"), append(args, *v) } if v := update.Visibility; v != nil { - set, args = append(set, "visibility = ?"), append(args, *v) + set, args = append(set, "`visibility` = ?"), append(args, *v) } args = append(args, update.ID) - stmt := ` - UPDATE memo - SET ` + strings.Join(set, ", ") + ` - WHERE id = ? - ` + stmt := "UPDATE `memo` SET " + strings.Join(set, ", ") + " WHERE `id` = ?" if _, err := d.db.ExecContext(ctx, stmt, args...); err != nil { return err } @@ -257,8 +175,8 @@ func (d *DB) UpdateMemo(ctx context.Context, update *store.UpdateMemo) error { } func (d *DB) DeleteMemo(ctx context.Context, delete *store.DeleteMemo) error { - where, args := []string{"id = ?"}, []any{delete.ID} - stmt := `DELETE FROM memo WHERE ` + strings.Join(where, " AND ") + where, args := []string{"`id` = ?"}, []any{delete.ID} + stmt := "DELETE FROM `memo` WHERE " + strings.Join(where, " AND ") result, err := d.db.ExecContext(ctx, stmt, args...) if err != nil { return err @@ -274,49 +192,8 @@ func (d *DB) DeleteMemo(ctx context.Context, delete *store.DeleteMemo) error { return nil } -func (d *DB) FindMemosVisibilityList(ctx context.Context, memoIDs []int32) ([]store.Visibility, error) { - args := make([]any, 0, len(memoIDs)) - list := make([]string, 0, len(memoIDs)) - for _, memoID := range memoIDs { - args = append(args, memoID) - list = append(list, "?") - } - - where := fmt.Sprintf("id in (%s)", strings.Join(list, ",")) - query := `SELECT DISTINCT(visibility) FROM memo WHERE ` + where - rows, err := d.db.QueryContext(ctx, query, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - visibilityList := make([]store.Visibility, 0) - for rows.Next() { - var visibility store.Visibility - if err := rows.Scan(&visibility); err != nil { - return nil, err - } - visibilityList = append(visibilityList, visibility) - } - - if err := rows.Err(); err != nil { - return nil, err - } - - return visibilityList, nil -} - func vacuumMemo(ctx context.Context, tx *sql.Tx) error { - stmt := ` - DELETE FROM - memo - WHERE - creator_id NOT IN ( - SELECT - id - FROM - user - )` + stmt := "DELETE FROM `memo` WHERE `creator_id` NOT IN (SELECT `id` FROM `user`)" _, err := tx.ExecContext(ctx, stmt) if err != nil { return err diff --git a/store/db/sqlite/migration/dev/LATEST__SCHEMA.sql b/store/db/sqlite/migration/dev/LATEST__SCHEMA.sql index 597d631727dd4..b2408ddccc78e 100644 --- a/store/db/sqlite/migration/dev/LATEST__SCHEMA.sql +++ b/store/db/sqlite/migration/dev/LATEST__SCHEMA.sql @@ -1,18 +1,3 @@ --- drop all tables first -DROP TABLE IF EXISTS migration_history; -DROP TABLE IF EXISTS system_setting; -DROP TABLE IF EXISTS user; -DROP TABLE IF EXISTS user_setting; -DROP TABLE IF EXISTS memo; -DROP TABLE IF EXISTS memo_organizer; -DROP TABLE IF EXISTS memo_relation; -DROP TABLE IF EXISTS resource; -DROP TABLE IF EXISTS tag; -DROP TABLE IF EXISTS activity; -DROP TABLE IF EXISTS storage; -DROP TABLE IF EXISTS idp; -DROP TABLE IF EXISTS inbox; - -- migration_history CREATE TABLE migration_history ( version TEXT NOT NULL PRIMARY KEY, @@ -54,6 +39,7 @@ CREATE TABLE user_setting ( -- memo CREATE TABLE memo ( id INTEGER PRIMARY KEY AUTOINCREMENT, + resource_name TEXT NOT NULL UNIQUE, creator_id INTEGER NOT NULL, created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), @@ -85,6 +71,7 @@ CREATE TABLE memo_relation ( -- resource CREATE TABLE resource ( id INTEGER PRIMARY KEY AUTOINCREMENT, + resource_name TEXT NOT NULL UNIQUE, creator_id INTEGER NOT NULL, created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), @@ -144,3 +131,26 @@ CREATE TABLE inbox ( status TEXT NOT NULL, message TEXT NOT NULL DEFAULT '{}' ); + +-- webhook +CREATE TABLE webhook ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), + updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), + row_status TEXT NOT NULL CHECK (row_status IN ('NORMAL', 'ARCHIVED')) DEFAULT 'NORMAL', + creator_id INTEGER NOT NULL, + name TEXT NOT NULL, + url TEXT NOT NULL +); + +CREATE INDEX idx_webhook_creator_id ON webhook (creator_id); + +-- reaction +CREATE TABLE reaction ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), + creator_id INTEGER NOT NULL, + content_id TEXT NOT NULL, + reaction_type TEXT NOT NULL, + UNIQUE(creator_id, content_id, reaction_type) +); diff --git a/store/db/sqlite/migration/prod/0.18/00__webhook.sql b/store/db/sqlite/migration/prod/0.18/00__webhook.sql new file mode 100644 index 0000000000000..426ce9c2ad072 --- /dev/null +++ b/store/db/sqlite/migration/prod/0.18/00__webhook.sql @@ -0,0 +1,12 @@ +-- webhook +CREATE TABLE webhook ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), + updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), + row_status TEXT NOT NULL CHECK (row_status IN ('NORMAL', 'ARCHIVED')) DEFAULT 'NORMAL', + creator_id INTEGER NOT NULL, + name TEXT NOT NULL, + url TEXT NOT NULL +); + +CREATE INDEX idx_webhook_creator_id ON webhook (creator_id); diff --git a/store/db/sqlite/migration/prod/0.18/01__user_setting.sql b/store/db/sqlite/migration/prod/0.18/01__user_setting.sql new file mode 100644 index 0000000000000..fe79a8f16f261 --- /dev/null +++ b/store/db/sqlite/migration/prod/0.18/01__user_setting.sql @@ -0,0 +1,4 @@ +UPDATE user_setting SET key = 'USER_SETTING_LOCALE', value = REPLACE(value, '"', '') WHERE key = 'locale'; +UPDATE user_setting SET key = 'USER_SETTING_APPEARANCE', value = REPLACE(value, '"', '') WHERE key = 'appearance'; +UPDATE user_setting SET key = 'USER_SETTING_MEMO_VISIBILITY', value = REPLACE(value, '"', '') WHERE key = 'memo-visibility'; +UPDATE user_setting SET key = 'USER_SETTING_TELEGRAM_USER_ID', value = REPLACE(value, '"', '') WHERE key = 'telegram-user-id'; diff --git a/store/db/sqlite/migration/prod/0.19/00__add_resource_name.sql b/store/db/sqlite/migration/prod/0.19/00__add_resource_name.sql new file mode 100644 index 0000000000000..33add15ecdc7b --- /dev/null +++ b/store/db/sqlite/migration/prod/0.19/00__add_resource_name.sql @@ -0,0 +1,11 @@ +ALTER TABLE memo ADD COLUMN resource_name TEXT NOT NULL DEFAULT ""; + +UPDATE memo SET resource_name = lower(hex(randomblob(8))); + +CREATE UNIQUE INDEX idx_memo_resource_name ON memo (resource_name); + +ALTER TABLE resource ADD COLUMN resource_name TEXT NOT NULL DEFAULT ""; + +UPDATE resource SET resource_name = lower(hex(randomblob(8))); + +CREATE UNIQUE INDEX idx_resource_resource_name ON resource (resource_name); diff --git a/store/db/sqlite/migration/prod/0.20/00__reaction.sql b/store/db/sqlite/migration/prod/0.20/00__reaction.sql new file mode 100644 index 0000000000000..b4e8bd62cb3cf --- /dev/null +++ b/store/db/sqlite/migration/prod/0.20/00__reaction.sql @@ -0,0 +1,9 @@ +-- reaction +CREATE TABLE reaction ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), + creator_id INTEGER NOT NULL, + content_id TEXT NOT NULL, + reaction_type TEXT NOT NULL, + UNIQUE(creator_id, content_id, reaction_type) +); diff --git a/store/db/sqlite/migration/prod/LATEST__SCHEMA.sql b/store/db/sqlite/migration/prod/LATEST__SCHEMA.sql index 597d631727dd4..b2408ddccc78e 100644 --- a/store/db/sqlite/migration/prod/LATEST__SCHEMA.sql +++ b/store/db/sqlite/migration/prod/LATEST__SCHEMA.sql @@ -1,18 +1,3 @@ --- drop all tables first -DROP TABLE IF EXISTS migration_history; -DROP TABLE IF EXISTS system_setting; -DROP TABLE IF EXISTS user; -DROP TABLE IF EXISTS user_setting; -DROP TABLE IF EXISTS memo; -DROP TABLE IF EXISTS memo_organizer; -DROP TABLE IF EXISTS memo_relation; -DROP TABLE IF EXISTS resource; -DROP TABLE IF EXISTS tag; -DROP TABLE IF EXISTS activity; -DROP TABLE IF EXISTS storage; -DROP TABLE IF EXISTS idp; -DROP TABLE IF EXISTS inbox; - -- migration_history CREATE TABLE migration_history ( version TEXT NOT NULL PRIMARY KEY, @@ -54,6 +39,7 @@ CREATE TABLE user_setting ( -- memo CREATE TABLE memo ( id INTEGER PRIMARY KEY AUTOINCREMENT, + resource_name TEXT NOT NULL UNIQUE, creator_id INTEGER NOT NULL, created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), @@ -85,6 +71,7 @@ CREATE TABLE memo_relation ( -- resource CREATE TABLE resource ( id INTEGER PRIMARY KEY AUTOINCREMENT, + resource_name TEXT NOT NULL UNIQUE, creator_id INTEGER NOT NULL, created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), @@ -144,3 +131,26 @@ CREATE TABLE inbox ( status TEXT NOT NULL, message TEXT NOT NULL DEFAULT '{}' ); + +-- webhook +CREATE TABLE webhook ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), + updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), + row_status TEXT NOT NULL CHECK (row_status IN ('NORMAL', 'ARCHIVED')) DEFAULT 'NORMAL', + creator_id INTEGER NOT NULL, + name TEXT NOT NULL, + url TEXT NOT NULL +); + +CREATE INDEX idx_webhook_creator_id ON webhook (creator_id); + +-- reaction +CREATE TABLE reaction ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), + creator_id INTEGER NOT NULL, + content_id TEXT NOT NULL, + reaction_type TEXT NOT NULL, + UNIQUE(creator_id, content_id, reaction_type) +); diff --git a/store/db/sqlite/migration_history.go b/store/db/sqlite/migration_history.go index 0c5224e7b4fcf..b7ec01b24af9b 100644 --- a/store/db/sqlite/migration_history.go +++ b/store/db/sqlite/migration_history.go @@ -2,47 +2,21 @@ package sqlite import ( "context" - "strings" -) - -type MigrationHistory struct { - Version string - CreatedTs int64 -} -type MigrationHistoryUpsert struct { - Version string -} - -type MigrationHistoryFind struct { - Version *string -} - -func (d *DB) FindMigrationHistoryList(ctx context.Context, find *MigrationHistoryFind) ([]*MigrationHistory, error) { - where, args := []string{"1 = 1"}, []any{} - - if v := find.Version; v != nil { - where, args = append(where, "version = ?"), append(args, *v) - } + "github.com/usememos/memos/store" +) - query := ` - SELECT - version, - created_ts - FROM - migration_history - WHERE ` + strings.Join(where, " AND ") + ` - ORDER BY created_ts DESC - ` - rows, err := d.db.QueryContext(ctx, query, args...) +func (d *DB) FindMigrationHistoryList(ctx context.Context, _ *store.FindMigrationHistory) ([]*store.MigrationHistory, error) { + query := "SELECT `version`, `created_ts` FROM `migration_history` ORDER BY `created_ts` DESC" + rows, err := d.db.QueryContext(ctx, query) if err != nil { return nil, err } defer rows.Close() - list := make([]*MigrationHistory, 0) + list := make([]*store.MigrationHistory, 0) for rows.Next() { - var migrationHistory MigrationHistory + var migrationHistory store.MigrationHistory if err := rows.Scan( &migrationHistory.Version, &migrationHistory.CreatedTs, @@ -60,7 +34,7 @@ func (d *DB) FindMigrationHistoryList(ctx context.Context, find *MigrationHistor return list, nil } -func (d *DB) UpsertMigrationHistory(ctx context.Context, upsert *MigrationHistoryUpsert) (*MigrationHistory, error) { +func (d *DB) UpsertMigrationHistory(ctx context.Context, upsert *store.UpsertMigrationHistory) (*store.MigrationHistory, error) { stmt := ` INSERT INTO migration_history ( version @@ -71,7 +45,7 @@ func (d *DB) UpsertMigrationHistory(ctx context.Context, upsert *MigrationHistor version=EXCLUDED.version RETURNING version, created_ts ` - var migrationHistory MigrationHistory + var migrationHistory store.MigrationHistory if err := d.db.QueryRowContext(ctx, stmt, upsert.Version).Scan( &migrationHistory.Version, &migrationHistory.CreatedTs, diff --git a/store/db/sqlite/migrator.go b/store/db/sqlite/migrator.go index 7aeb4aaacddf1..f174819d7610b 100644 --- a/store/db/sqlite/migrator.go +++ b/store/db/sqlite/migrator.go @@ -13,6 +13,7 @@ import ( "github.com/pkg/errors" "github.com/usememos/memos/server/version" + "github.com/usememos/memos/store" ) //go:embed migration @@ -33,7 +34,7 @@ func (d *DB) Migrate(ctx context.Context) error { return errors.Wrap(err, "failed to apply latest schema") } // Upsert the newest version to migration_history. - if _, err := d.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{ + if _, err := d.UpsertMigrationHistory(ctx, &store.UpsertMigrationHistory{ Version: currentVersion, }); err != nil { return errors.Wrap(err, "failed to upsert migration history") @@ -43,7 +44,7 @@ func (d *DB) Migrate(ctx context.Context) error { } } else { // If db file exists, we should check if we need to migrate the database. - migrationHistoryList, err := d.FindMigrationHistoryList(ctx, &MigrationHistoryFind{}) + migrationHistoryList, err := d.FindMigrationHistoryList(ctx, &store.FindMigrationHistory{}) if err != nil { return errors.Wrap(err, "failed to find migration history") } @@ -53,7 +54,7 @@ func (d *DB) Migrate(ctx context.Context) error { if err := d.applyMigrationForMinorVersion(ctx, minorVersion); err != nil { return errors.Wrapf(err, "failed to apply version %s migration", minorVersion) } - _, err := d.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{ + _, err := d.UpsertMigrationHistory(ctx, &store.UpsertMigrationHistory{ Version: currentVersion, }) if err != nil { @@ -71,7 +72,7 @@ func (d *DB) Migrate(ctx context.Context) error { if version.IsVersionGreaterThan(version.GetSchemaVersion(currentVersion), latestMigrationHistoryVersion) { minorVersionList := getMinorVersionList() - // backup the raw database file before migration + // Backup the raw database file before migration. rawBytes, err := os.ReadFile(d.profile.DSN) if err != nil { return errors.Wrap(err, "failed to read raw database file") @@ -80,22 +81,22 @@ func (d *DB) Migrate(ctx context.Context) error { if err := os.WriteFile(backupDBFilePath, rawBytes, 0644); err != nil { return errors.Wrap(err, "failed to write raw database file") } - println("succeed to copy a backup database file") - println("start migrate") + fmt.Println("succeed to copy a backup database file") + fmt.Println("start migrate") for _, minorVersion := range minorVersionList { normalizedVersion := minorVersion + ".0" if version.IsVersionGreaterThan(normalizedVersion, latestMigrationHistoryVersion) && version.IsVersionGreaterOrEqualThan(currentVersion, normalizedVersion) { - println("applying migration for", normalizedVersion) + fmt.Println("applying migration for", normalizedVersion) if err := d.applyMigrationForMinorVersion(ctx, minorVersion); err != nil { return errors.Wrap(err, "failed to apply minor version migration") } } } - println("end migrate") + fmt.Println("end migrate") - // remove the created backup db file after migrate succeed + // Remove the created backup db file after migrate succeed. if err := os.Remove(backupDBFilePath); err != nil { - println(fmt.Sprintf("Failed to remove temp database file, err %v", err)) + fmt.Printf("Failed to remove temp database file, err %v", err) } } } @@ -162,7 +163,7 @@ func (d *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion str // Upsert the newest version to migration_history. version := minorVersion + ".0" - if _, err = d.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{ + if _, err = d.UpsertMigrationHistory(ctx, &store.UpsertMigrationHistory{ Version: version, }); err != nil { return errors.Wrapf(err, "failed to upsert migration history with version: %s", version) diff --git a/store/db/sqlite/reaction.go b/store/db/sqlite/reaction.go new file mode 100644 index 0000000000000..a56b5c0988c93 --- /dev/null +++ b/store/db/sqlite/reaction.go @@ -0,0 +1,83 @@ +package sqlite + +import ( + "context" + "strings" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (d *DB) UpsertReaction(ctx context.Context, upsert *storepb.Reaction) (*storepb.Reaction, error) { + fields := []string{"`creator_id`", "`content_id`", "`reaction_type`"} + placeholder := []string{"?", "?", "?"} + args := []interface{}{upsert.CreatorId, upsert.ContentId, upsert.ReactionType.String()} + stmt := "INSERT INTO `reaction` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ") RETURNING `id`, `created_ts`" + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( + &upsert.Id, + &upsert.CreatedTs, + ); err != nil { + return nil, err + } + + reaction := upsert + return reaction, nil +} + +func (d *DB) ListReactions(ctx context.Context, find *store.FindReaction) ([]*storepb.Reaction, error) { + where, args := []string{"1 = 1"}, []interface{}{} + if find.ID != nil { + where, args = append(where, "id = ?"), append(args, *find.ID) + } + if find.CreatorID != nil { + where, args = append(where, "creator_id = ?"), append(args, *find.CreatorID) + } + if find.ContentID != nil { + where, args = append(where, "content_id = ?"), append(args, *find.ContentID) + } + + rows, err := d.db.QueryContext(ctx, ` + SELECT + id, + created_ts, + creator_id, + content_id, + reaction_type + FROM reaction + WHERE `+strings.Join(where, " AND ")+` + ORDER BY id ASC`, + args..., + ) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*storepb.Reaction{} + for rows.Next() { + reaction := &storepb.Reaction{} + var reactionType string + if err := rows.Scan( + &reaction.Id, + &reaction.CreatedTs, + &reaction.CreatorId, + &reaction.ContentId, + &reactionType, + ); err != nil { + return nil, err + } + reaction.ReactionType = storepb.Reaction_Type(storepb.Reaction_Type_value[reactionType]) + list = append(list, reaction) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) DeleteReaction(ctx context.Context, delete *store.DeleteReaction) error { + _, err := d.db.ExecContext(ctx, "DELETE FROM `reaction` WHERE `id` = ?", delete.ID) + return err +} diff --git a/store/db/sqlite/resource.go b/store/db/sqlite/resource.go index 945de31ecd4e6..bb0d6ee78d16a 100644 --- a/store/db/sqlite/resource.go +++ b/store/db/sqlite/resource.go @@ -10,33 +10,9 @@ import ( ) func (d *DB) CreateResource(ctx context.Context, create *store.Resource) (*store.Resource, error) { - fields := []string{"`filename`", "`blob`", "`external_link`", "`type`", "`size`", "`creator_id`", "`internal_path`"} - placeholder := []string{"?", "?", "?", "?", "?", "?", "?"} - args := []any{create.Filename, create.Blob, create.ExternalLink, create.Type, create.Size, create.CreatorID, create.InternalPath} - - if create.ID != 0 { - fields = append(fields, "`id`") - placeholder = append(placeholder, "?") - args = append(args, create.ID) - } - - if create.CreatedTs != 0 { - fields = append(fields, "`created_ts`") - placeholder = append(placeholder, "?") - args = append(args, create.CreatedTs) - } - - if create.UpdatedTs != 0 { - fields = append(fields, "`updated_ts`") - placeholder = append(placeholder, "?") - args = append(args, create.UpdatedTs) - } - - if create.MemoID != nil { - fields = append(fields, "`memo_id`") - placeholder = append(placeholder, "?") - args = append(args, *create.MemoID) - } + fields := []string{"`resource_name`", "`filename`", "`blob`", "`external_link`", "`type`", "`size`", "`creator_id`", "`internal_path`", "`memo_id`"} + placeholder := []string{"?", "?", "?", "?", "?", "?", "?", "?", "?"} + args := []any{create.ResourceName, create.Filename, create.Blob, create.ExternalLink, create.Type, create.Size, create.CreatorID, create.InternalPath, create.MemoID} stmt := "INSERT INTO `resource` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ") RETURNING `id`, `created_ts`, `updated_ts`" if err := d.db.QueryRowContext(ctx, stmt, args...).Scan(&create.ID, &create.CreatedTs, &create.UpdatedTs); err != nil { @@ -50,34 +26,30 @@ func (d *DB) ListResources(ctx context.Context, find *store.FindResource) ([]*st where, args := []string{"1 = 1"}, []any{} if v := find.ID; v != nil { - where, args = append(where, "id = ?"), append(args, *v) + where, args = append(where, "`id` = ?"), append(args, *v) + } + if v := find.ResourceName; v != nil { + where, args = append(where, "`resource_name` = ?"), append(args, *v) } if v := find.CreatorID; v != nil { - where, args = append(where, "creator_id = ?"), append(args, *v) + where, args = append(where, "`creator_id` = ?"), append(args, *v) } if v := find.Filename; v != nil { - where, args = append(where, "filename = ?"), append(args, *v) + where, args = append(where, "`filename` = ?"), append(args, *v) } if v := find.MemoID; v != nil { - where, args = append(where, "memo_id = ?"), append(args, *v) + where, args = append(where, "`memo_id` = ?"), append(args, *v) } if find.HasRelatedMemo { - where = append(where, "memo_id IS NOT NULL") + where = append(where, "`memo_id` IS NOT NULL") } - fields := []string{"id", "filename", "external_link", "type", "size", "creator_id", "created_ts", "updated_ts", "internal_path", "memo_id"} + fields := []string{"`id`", "`resource_name`", "`filename`", "`external_link`", "`type`", "`size`", "`creator_id`", "`created_ts`", "`updated_ts`", "`internal_path`", "`memo_id`"} if find.GetBlob { - fields = append(fields, "blob") + fields = append(fields, "`blob`") } - query := fmt.Sprintf(` - SELECT - %s - FROM resource - WHERE %s - GROUP BY id - ORDER BY created_ts DESC - `, strings.Join(fields, ", "), strings.Join(where, " AND ")) + query := fmt.Sprintf("SELECT %s FROM `resource` WHERE %s ORDER BY `updated_ts` DESC, `created_ts` DESC", strings.Join(fields, ", "), strings.Join(where, " AND ")) if find.Limit != nil { query = fmt.Sprintf("%s LIMIT %d", query, *find.Limit) if find.Offset != nil { @@ -97,6 +69,7 @@ func (d *DB) ListResources(ctx context.Context, find *store.FindResource) ([]*st var memoID sql.NullInt32 dests := []any{ &resource.ID, + &resource.ResourceName, &resource.Filename, &resource.ExternalLink, &resource.Type, @@ -129,32 +102,35 @@ func (d *DB) ListResources(ctx context.Context, find *store.FindResource) ([]*st func (d *DB) UpdateResource(ctx context.Context, update *store.UpdateResource) (*store.Resource, error) { set, args := []string{}, []any{} + if v := update.ResourceName; v != nil { + set, args = append(set, "`resource_name` = ?"), append(args, *v) + } if v := update.UpdatedTs; v != nil { - set, args = append(set, "updated_ts = ?"), append(args, *v) + set, args = append(set, "`updated_ts` = ?"), append(args, *v) } if v := update.Filename; v != nil { - set, args = append(set, "filename = ?"), append(args, *v) + set, args = append(set, "`filename` = ?"), append(args, *v) } if v := update.InternalPath; v != nil { - set, args = append(set, "internal_path = ?"), append(args, *v) + set, args = append(set, "`internal_path` = ?"), append(args, *v) + } + if v := update.ExternalLink; v != nil { + set, args = append(set, "`external_link` = ?"), append(args, *v) } if v := update.MemoID; v != nil { - set, args = append(set, "memo_id = ?"), append(args, *v) + set, args = append(set, "`memo_id` = ?"), append(args, *v) } if v := update.Blob; v != nil { - set, args = append(set, "blob = ?"), append(args, v) + set, args = append(set, "`blob` = ?"), append(args, v) } args = append(args, update.ID) - fields := []string{"id", "filename", "external_link", "type", "size", "creator_id", "created_ts", "updated_ts", "internal_path"} - stmt := ` - UPDATE resource - SET ` + strings.Join(set, ", ") + ` - WHERE id = ? - RETURNING ` + strings.Join(fields, ", ") + fields := []string{"`id`", "`resource_name`", "`filename`", "`external_link`", "`type`", "`size`", "`creator_id`", "`created_ts`", "`updated_ts`", "`internal_path`"} + stmt := "UPDATE `resource` SET " + strings.Join(set, ", ") + " WHERE `id` = ? RETURNING " + strings.Join(fields, ", ") resource := store.Resource{} dests := []any{ &resource.ID, + &resource.ResourceName, &resource.Filename, &resource.ExternalLink, &resource.Type, @@ -172,10 +148,7 @@ func (d *DB) UpdateResource(ctx context.Context, update *store.UpdateResource) ( } func (d *DB) DeleteResource(ctx context.Context, delete *store.DeleteResource) error { - stmt := ` - DELETE FROM resource - WHERE id = ? - ` + stmt := "DELETE FROM `resource` WHERE `id` = ?" result, err := d.db.ExecContext(ctx, stmt, delete.ID) if err != nil { return err @@ -193,16 +166,7 @@ func (d *DB) DeleteResource(ctx context.Context, delete *store.DeleteResource) e } func vacuumResource(ctx context.Context, tx *sql.Tx) error { - stmt := ` - DELETE FROM - resource - WHERE - creator_id NOT IN ( - SELECT - id - FROM - user - )` + stmt := "DELETE FROM `resource` WHERE `creator_id` NOT IN (SELECT `id` FROM `user`)" _, err := tx.ExecContext(ctx, stmt) if err != nil { return err diff --git a/store/db/sqlite/seed/10002__memo.sql b/store/db/sqlite/seed/10002__memo.sql index d1baa8cc35adb..f905eed4cbe02 100644 --- a/store/db/sqlite/seed/10002__memo.sql +++ b/store/db/sqlite/seed/10002__memo.sql @@ -1,8 +1,14 @@ INSERT INTO - memo (`id`, `content`, `creator_id`) + memo ( + `id`, + `resource_name`, + `content`, + `creator_id` + ) VALUES ( 1, + "FqaZcg5H6EdGB9ke8kYUcy", "#Hello 👋 Welcome to memos.", 101 ); @@ -10,6 +16,7 @@ VALUES INSERT INTO memo ( `id`, + `resource_name`, `content`, `creator_id`, `visibility` @@ -17,11 +24,11 @@ INSERT INTO VALUES ( 2, + "DCo8442yRnXYPPcKSUAaEb", '#TODO - [x] Take more photos about **🌄 sunset**; - [x] Clean the room; -- [ ] Read *📖 The Little Prince*; -(👆 click to toggle status)', +- [ ] Read *📖 The Little Prince*;', 101, 'PROTECTED' ); @@ -29,6 +36,7 @@ VALUES INSERT INTO memo ( `id`, + `resource_name`, `content`, `creator_id`, `visibility` @@ -36,11 +44,9 @@ INSERT INTO VALUES ( 3, - "**[Slash](https://github.com/boojack/slash)**: A bookmarking and url shortener, save and share your links very easily. -![](https://github.com/boojack/slash/raw/main/resources/demo.gif) - -**[TechStack](https://github.com/Get-Tech-Stack/TechStack)**: A browser extension that will display the technology stack of the GitHub repository. -![](https://github.com/Get-Tech-Stack/TechStack/blob/main/img/1.png?raw=true)", + "ZvH7a6VWMuX5aArtECTj4N", + '**[Memos](https://github.com/usememos/memos)**: A lightweight, self-hosted memo hub. Open Source and Free forever. +**[Slash](https://github.com/yourselfhosted/slash)**: An open source, self-hosted bookmarks and link sharing platform. Save and share your links very easily.', 101, 'PUBLIC' ); @@ -48,6 +54,7 @@ VALUES INSERT INTO memo ( `id`, + `resource_name`, `content`, `creator_id`, `visibility` @@ -55,12 +62,11 @@ INSERT INTO VALUES ( 4, + "2ad3WzUF4C6pTYXdm2nQC6", '#TODO - [x] Take more photos about **🌄 sunset**; - [ ] Clean the classroom; -- [ ] Watch *👦 The Boys*; -(👆 click to toggle status) -', +- [ ] Watch *👦 The Boys*;', 102, 'PROTECTED' ); @@ -68,6 +74,7 @@ VALUES INSERT INTO memo ( `id`, + `resource_name`, `content`, `creator_id`, `visibility` @@ -75,6 +82,7 @@ INSERT INTO VALUES ( 5, + "Pw2awZvxxLK4sPRtHmYuS7", '三人行,必有我师焉!👨‍🏫', 102, 'PUBLIC' diff --git a/store/db/sqlite/seed/10005__workspace_setting.sql b/store/db/sqlite/seed/10005__workspace_setting.sql new file mode 100644 index 0000000000000..f35b4f82d087c --- /dev/null +++ b/store/db/sqlite/seed/10005__workspace_setting.sql @@ -0,0 +1,4 @@ +INSERT INTO + system_setting (`name`, `value`) +VALUES + ('WORKSPACE_SETTING_GENERAL', '{"instanceUrl":"https://demo.usememos.com"}'); diff --git a/store/db/sqlite/seed/10006__resource.sql b/store/db/sqlite/seed/10006__resource.sql new file mode 100644 index 0000000000000..a810b75ffc531 --- /dev/null +++ b/store/db/sqlite/seed/10006__resource.sql @@ -0,0 +1,4 @@ +INSERT INTO + resource (`resource_name`, `creator_id`, `filename`, `external_link`, `type`, `memo_id`) +VALUES + ("Pw2awZvxxLK4sPRtHmYuS7", 101, 'slash-demo.png', 'https://github.com/yourselfhosted/slash/blob/main/docs/assets/demo.png?raw=true', 'image/png', 3); diff --git a/store/db/sqlite/sqlite.go b/store/db/sqlite/sqlite.go index e766343ea3766..981a02c8e4c72 100644 --- a/store/db/sqlite/sqlite.go +++ b/store/db/sqlite/sqlite.go @@ -8,7 +8,9 @@ import ( "github.com/pkg/errors" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "modernc.org/sqlite" + + // Import the SQLite driver. + _ "modernc.org/sqlite" "github.com/usememos/memos/server/profile" "github.com/usememos/memos/store" @@ -95,6 +97,9 @@ func vacuumImpl(ctx context.Context, tx *sql.Tx) error { if err := vacuumMemoRelations(ctx, tx); err != nil { return err } + if err := vacuumInbox(ctx, tx); err != nil { + return err + } if err := vacuumTag(ctx, tx); err != nil { // Prevent revive warning. return err @@ -103,43 +108,6 @@ func vacuumImpl(ctx context.Context, tx *sql.Tx) error { return nil } -func (d *DB) BackupTo(ctx context.Context, filename string) error { - conn, err := d.db.Conn(ctx) - if err != nil { - return errors.Wrap(err, "fail to open new connection") - } - defer conn.Close() - - err = conn.Raw(func(driverConn any) error { - type backuper interface { - NewBackup(string) (*sqlite.Backup, error) - } - backupConn, ok := driverConn.(backuper) - if !ok { - return errors.New("db connection is not a sqlite backuper") - } - - bck, err := backupConn.NewBackup(filename) - if err != nil { - return errors.Wrap(err, "fail to create sqlite backup") - } - - for more := true; more; { - more, err = bck.Step(-1) - if err != nil { - return errors.Wrap(err, "fail to execute sqlite backup") - } - } - - return bck.Finish() - }) - if err != nil { - return errors.Wrap(err, "fail to backup") - } - - return nil -} - func (d *DB) GetCurrentDBSize(context.Context) (int64, error) { fi, err := os.Stat(d.profile.DSN) if err != nil { diff --git a/store/db/sqlite/storage.go b/store/db/sqlite/storage.go index 5d4d009af44a1..c0b1d35b7ecef 100644 --- a/store/db/sqlite/storage.go +++ b/store/db/sqlite/storage.go @@ -12,12 +12,6 @@ func (d *DB) CreateStorage(ctx context.Context, create *store.Storage) (*store.S placeholder := []string{"?", "?", "?"} args := []any{create.Name, create.Type, create.Config} - if create.ID != 0 { - fields = append(fields, "`id`") - placeholder = append(placeholder, "?") - args = append(args, create.ID) - } - stmt := "INSERT INTO `storage` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ") RETURNING `id`" if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( &create.ID, @@ -72,18 +66,6 @@ func (d *DB) ListStorages(ctx context.Context, find *store.FindStorage) ([]*stor return list, nil } -func (d *DB) GetStorage(ctx context.Context, find *store.FindStorage) (*store.Storage, error) { - list, err := d.ListStorages(ctx, find) - if err != nil { - return nil, err - } - if len(list) == 0 { - return nil, nil - } - - return list[0], nil -} - func (d *DB) UpdateStorage(ctx context.Context, update *store.UpdateStorage) (*store.Storage, error) { set, args := []string{}, []any{} if update.Name != nil { diff --git a/store/db/sqlite/system_setting.go b/store/db/sqlite/system_setting.go deleted file mode 100644 index 95474fa0da545..0000000000000 --- a/store/db/sqlite/system_setting.go +++ /dev/null @@ -1,66 +0,0 @@ -package sqlite - -import ( - "context" - "strings" - - "github.com/usememos/memos/store" -) - -func (d *DB) UpsertSystemSetting(ctx context.Context, upsert *store.SystemSetting) (*store.SystemSetting, error) { - stmt := ` - INSERT INTO system_setting ( - name, value, description - ) - VALUES (?, ?, ?) - ON CONFLICT(name) DO UPDATE - SET - value = EXCLUDED.value, - description = EXCLUDED.description - ` - if _, err := d.db.ExecContext(ctx, stmt, upsert.Name, upsert.Value, upsert.Description); err != nil { - return nil, err - } - - return upsert, nil -} - -func (d *DB) ListSystemSettings(ctx context.Context, find *store.FindSystemSetting) ([]*store.SystemSetting, error) { - where, args := []string{"1 = 1"}, []any{} - if find.Name != "" { - where, args = append(where, "name = ?"), append(args, find.Name) - } - - query := ` - SELECT - name, - value, - description - FROM system_setting - WHERE ` + strings.Join(where, " AND ") - - rows, err := d.db.QueryContext(ctx, query, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - list := []*store.SystemSetting{} - for rows.Next() { - systemSettingMessage := &store.SystemSetting{} - if err := rows.Scan( - &systemSettingMessage.Name, - &systemSettingMessage.Value, - &systemSettingMessage.Description, - ); err != nil { - return nil, err - } - list = append(list, systemSettingMessage) - } - - if err := rows.Err(); err != nil { - return nil, err - } - - return list, nil -} diff --git a/store/db/sqlite/user.go b/store/db/sqlite/user.go index 0a7e0be68cfef..216d1170c0821 100644 --- a/store/db/sqlite/user.go +++ b/store/db/sqlite/user.go @@ -11,37 +11,6 @@ func (d *DB) CreateUser(ctx context.Context, create *store.User) (*store.User, e fields := []string{"`username`", "`role`", "`email`", "`nickname`", "`password_hash`"} placeholder := []string{"?", "?", "?", "?", "?"} args := []any{create.Username, create.Role, create.Email, create.Nickname, create.PasswordHash} - - if create.AvatarURL != "" { - fields = append(fields, "`avatar_url`") - placeholder = append(placeholder, "?") - args = append(args, create.AvatarURL) - } - - if create.RowStatus != "" { - fields = append(fields, "`row_status`") - placeholder = append(placeholder, "?") - args = append(args, create.RowStatus) - } - - if create.CreatedTs != 0 { - fields = append(fields, "`created_ts`") - placeholder = append(placeholder, "?") - args = append(args, create.CreatedTs) - } - - if create.UpdatedTs != 0 { - fields = append(fields, "`updated_ts`") - placeholder = append(placeholder, "?") - args = append(args, create.UpdatedTs) - } - - if create.ID != 0 { - fields = append(fields, "`id`") - placeholder = append(placeholder, "?") - args = append(args, create.ID) - } - stmt := "INSERT INTO user (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ") RETURNING id, avatar_url, created_ts, updated_ts, row_status" if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( &create.ID, diff --git a/store/db/sqlite/user_setting.go b/store/db/sqlite/user_setting.go index 96d086a5e77d6..95e065e89832b 100644 --- a/store/db/sqlite/user_setting.go +++ b/store/db/sqlite/user_setting.go @@ -3,75 +3,16 @@ package sqlite import ( "context" "database/sql" - "errors" "strings" + "github.com/pkg/errors" "google.golang.org/protobuf/encoding/protojson" storepb "github.com/usememos/memos/proto/gen/store" "github.com/usememos/memos/store" ) -func (d *DB) UpsertUserSetting(ctx context.Context, upsert *store.UserSetting) (*store.UserSetting, error) { - stmt := ` - INSERT INTO user_setting ( - user_id, key, value - ) - VALUES (?, ?, ?) - ON CONFLICT(user_id, key) DO UPDATE - SET value = EXCLUDED.value - ` - if _, err := d.db.ExecContext(ctx, stmt, upsert.UserID, upsert.Key, upsert.Value); err != nil { - return nil, err - } - - return upsert, nil -} - -func (d *DB) ListUserSettings(ctx context.Context, find *store.FindUserSetting) ([]*store.UserSetting, error) { - where, args := []string{"1 = 1"}, []any{} - - if v := find.Key; v != "" { - where, args = append(where, "key = ?"), append(args, v) - } - if v := find.UserID; v != nil { - where, args = append(where, "user_id = ?"), append(args, *find.UserID) - } - - query := ` - SELECT - user_id, - key, - value - FROM user_setting - WHERE ` + strings.Join(where, " AND ") - rows, err := d.db.QueryContext(ctx, query, args...) - if err != nil { - return nil, err - } - defer rows.Close() - - userSettingList := make([]*store.UserSetting, 0) - for rows.Next() { - var userSetting store.UserSetting - if err := rows.Scan( - &userSetting.UserID, - &userSetting.Key, - &userSetting.Value, - ); err != nil { - return nil, err - } - userSettingList = append(userSettingList, &userSetting) - } - - if err := rows.Err(); err != nil { - return nil, err - } - - return userSettingList, nil -} - -func (d *DB) UpsertUserSettingV1(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) { +func (d *DB) UpsertUserSetting(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) { stmt := ` INSERT INTO user_setting ( user_id, key, value @@ -87,8 +28,16 @@ func (d *DB) UpsertUserSettingV1(ctx context.Context, upsert *storepb.UserSettin return nil, err } valueString = string(valueBytes) + } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_LOCALE { + valueString = upsert.GetLocale() + } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_APPEARANCE { + valueString = upsert.GetAppearance() + } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_MEMO_VISIBILITY { + valueString = upsert.GetMemoVisibility() + } else if upsert.Key == storepb.UserSettingKey_USER_SETTING_TELEGRAM_USER_ID { + valueString = upsert.GetTelegramUserId() } else { - return nil, errors.New("invalid user setting key") + return nil, errors.Errorf("unknown user setting key: %s", upsert.Key.String()) } if _, err := d.db.ExecContext(ctx, stmt, upsert.UserId, upsert.Key.String(), valueString); err != nil { @@ -98,7 +47,7 @@ func (d *DB) UpsertUserSettingV1(ctx context.Context, upsert *storepb.UserSettin return upsert, nil } -func (d *DB) ListUserSettingsV1(ctx context.Context, find *store.FindUserSettingV1) ([]*storepb.UserSetting, error) { +func (d *DB) ListUserSettings(ctx context.Context, find *store.FindUserSetting) ([]*storepb.UserSetting, error) { where, args := []string{"1 = 1"}, []any{} if v := find.Key; v != storepb.UserSettingKey_USER_SETTING_KEY_UNSPECIFIED { @@ -141,13 +90,28 @@ func (d *DB) ListUserSettingsV1(ctx context.Context, find *store.FindUserSetting userSetting.Value = &storepb.UserSetting_AccessTokens{ AccessTokens: accessTokensUserSetting, } + } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_LOCALE { + userSetting.Value = &storepb.UserSetting_Locale{ + Locale: valueString, + } + } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_APPEARANCE { + userSetting.Value = &storepb.UserSetting_Appearance{ + Appearance: valueString, + } + } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_MEMO_VISIBILITY { + userSetting.Value = &storepb.UserSetting_MemoVisibility{ + MemoVisibility: valueString, + } + } else if userSetting.Key == storepb.UserSettingKey_USER_SETTING_TELEGRAM_USER_ID { + userSetting.Value = &storepb.UserSetting_TelegramUserId{ + TelegramUserId: valueString, + } } else { - // Skip unknown user setting v1 key. + // Skip unknown user setting key. continue } userSettingList = append(userSettingList, userSetting) } - if err := rows.Err(); err != nil { return nil, err } diff --git a/store/db/sqlite/webhook.go b/store/db/sqlite/webhook.go new file mode 100644 index 0000000000000..21df940ddbbbf --- /dev/null +++ b/store/db/sqlite/webhook.go @@ -0,0 +1,119 @@ +package sqlite + +import ( + "context" + "strings" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (d *DB) CreateWebhook(ctx context.Context, create *storepb.Webhook) (*storepb.Webhook, error) { + fields := []string{"`name`", "`url`", "`creator_id`"} + placeholder := []string{"?", "?", "?"} + args := []any{create.Name, create.Url, create.CreatorId} + stmt := "INSERT INTO `webhook` (" + strings.Join(fields, ", ") + ") VALUES (" + strings.Join(placeholder, ", ") + ") RETURNING `id`, `created_ts`, `updated_ts`, `row_status`" + var rowStatus string + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( + &create.Id, + &create.CreatedTs, + &create.UpdatedTs, + &rowStatus, + ); err != nil { + return nil, err + } + + create.RowStatus = storepb.RowStatus(storepb.RowStatus_value[rowStatus]) + webhook := create + return webhook, nil +} + +func (d *DB) ListWebhooks(ctx context.Context, find *store.FindWebhook) ([]*storepb.Webhook, error) { + where, args := []string{"1 = 1"}, []any{} + if find.ID != nil { + where, args = append(where, "`id` = ?"), append(args, *find.ID) + } + if find.CreatorID != nil { + where, args = append(where, "`creator_id` = ?"), append(args, *find.CreatorID) + } + + rows, err := d.db.QueryContext(ctx, ` + SELECT + id, + created_ts, + updated_ts, + row_status, + creator_id, + name, + url + FROM webhook + WHERE `+strings.Join(where, " AND ")+` + ORDER BY id DESC`, + args..., + ) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*storepb.Webhook{} + for rows.Next() { + webhook := &storepb.Webhook{} + var rowStatus string + if err := rows.Scan( + &webhook.Id, + &webhook.CreatedTs, + &webhook.UpdatedTs, + &rowStatus, + &webhook.CreatorId, + &webhook.Name, + &webhook.Url, + ); err != nil { + return nil, err + } + webhook.RowStatus = storepb.RowStatus(storepb.RowStatus_value[rowStatus]) + list = append(list, webhook) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) UpdateWebhook(ctx context.Context, update *store.UpdateWebhook) (*storepb.Webhook, error) { + set, args := []string{}, []any{} + if update.RowStatus != nil { + set, args = append(set, "row_status = ?"), append(args, update.RowStatus.String()) + } + if update.Name != nil { + set, args = append(set, "name = ?"), append(args, *update.Name) + } + if update.URL != nil { + set, args = append(set, "url = ?"), append(args, *update.URL) + } + args = append(args, update.ID) + + stmt := "UPDATE `webhook` SET " + strings.Join(set, ", ") + " WHERE `id` = ? RETURNING `id`, `created_ts`, `updated_ts`, `row_status`, `creator_id`, `name`, `url`" + webhook := &storepb.Webhook{} + var rowStatus string + if err := d.db.QueryRowContext(ctx, stmt, args...).Scan( + &webhook.Id, + &webhook.CreatedTs, + &webhook.UpdatedTs, + &rowStatus, + &webhook.CreatorId, + &webhook.Name, + &webhook.Url, + ); err != nil { + return nil, err + } + webhook.RowStatus = storepb.RowStatus(storepb.RowStatus_value[rowStatus]) + return webhook, nil +} + +func (d *DB) DeleteWebhook(ctx context.Context, delete *store.DeleteWebhook) error { + _, err := d.db.ExecContext(ctx, "DELETE FROM `webhook` WHERE `id` = ?", delete.ID) + return err +} diff --git a/store/db/sqlite/workspace_setting.go b/store/db/sqlite/workspace_setting.go new file mode 100644 index 0000000000000..a55eb014f5105 --- /dev/null +++ b/store/db/sqlite/workspace_setting.go @@ -0,0 +1,140 @@ +package sqlite + +import ( + "context" + "strings" + + "google.golang.org/protobuf/encoding/protojson" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func (d *DB) UpsertWorkspaceSetting(ctx context.Context, upsert *store.WorkspaceSetting) (*store.WorkspaceSetting, error) { + stmt := ` + INSERT INTO system_setting ( + name, value, description + ) + VALUES (?, ?, ?) + ON CONFLICT(name) DO UPDATE + SET + value = EXCLUDED.value, + description = EXCLUDED.description + ` + if _, err := d.db.ExecContext(ctx, stmt, upsert.Name, upsert.Value, upsert.Description); err != nil { + return nil, err + } + + return upsert, nil +} + +func (d *DB) ListWorkspaceSettings(ctx context.Context, find *store.FindWorkspaceSetting) ([]*store.WorkspaceSetting, error) { + where, args := []string{"1 = 1"}, []any{} + if find.Name != "" { + where, args = append(where, "name = ?"), append(args, find.Name) + } + + query := ` + SELECT + name, + value, + description + FROM system_setting + WHERE ` + strings.Join(where, " AND ") + + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*store.WorkspaceSetting{} + for rows.Next() { + systemSettingMessage := &store.WorkspaceSetting{} + if err := rows.Scan( + &systemSettingMessage.Name, + &systemSettingMessage.Value, + &systemSettingMessage.Description, + ); err != nil { + return nil, err + } + list = append(list, systemSettingMessage) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} + +func (d *DB) DeleteWorkspaceSetting(ctx context.Context, delete *store.DeleteWorkspaceSetting) error { + stmt := "DELETE FROM system_setting WHERE name = ?" + _, err := d.db.ExecContext(ctx, stmt, delete.Name) + return err +} + +func (d *DB) UpsertWorkspaceSettingV1(ctx context.Context, upsert *storepb.WorkspaceSetting) (*storepb.WorkspaceSetting, error) { + stmt := ` + INSERT INTO system_setting ( + name, value + ) + VALUES (?, ?) + ON CONFLICT(name) DO UPDATE + SET value = EXCLUDED.value` + var valueString string + if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_GENERAL { + valueBytes, err := protojson.Marshal(upsert.GetGeneral()) + if err != nil { + return nil, err + } + valueString = string(valueBytes) + } + if _, err := d.db.ExecContext(ctx, stmt, upsert.Key.String(), valueString); err != nil { + return nil, err + } + return upsert, nil +} + +func (d *DB) ListWorkspaceSettingsV1(ctx context.Context, find *store.FindWorkspaceSettingV1) ([]*storepb.WorkspaceSetting, error) { + where, args := []string{"1 = 1"}, []any{} + if find.Key != storepb.WorkspaceSettingKey_WORKSPACE_SETTING_KEY_UNSPECIFIED { + where, args = append(where, "name = ?"), append(args, find.Key.String()) + } + + query := `SELECT name, value FROM system_setting WHERE ` + strings.Join(where, " AND ") + rows, err := d.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + list := []*storepb.WorkspaceSetting{} + for rows.Next() { + workspaceSetting := &storepb.WorkspaceSetting{} + var keyString, valueString string + if err := rows.Scan( + &keyString, + &valueString, + ); err != nil { + return nil, err + } + workspaceSetting.Key = storepb.WorkspaceSettingKey(storepb.WorkspaceSettingKey_value[keyString]) + if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_GENERAL { + generalSetting := &storepb.WorkspaceGeneralSetting{} + if err := protojson.Unmarshal([]byte(valueString), generalSetting); err != nil { + return nil, err + } + workspaceSetting.Value = &storepb.WorkspaceSetting_General{General: generalSetting} + } else { + // Skip unknown workspace setting key. + continue + } + list = append(list, workspaceSetting) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return list, nil +} diff --git a/store/driver.go b/store/driver.go index f434fecb7c051..86a95b2f42e8f 100644 --- a/store/driver.go +++ b/store/driver.go @@ -15,11 +15,14 @@ type Driver interface { Migrate(ctx context.Context) error Vacuum(ctx context.Context) error - BackupTo(ctx context.Context, filename string) error // current file is driver GetCurrentDBSize(ctx context.Context) (int64, error) + // MigrationHistory model related methods. + FindMigrationHistoryList(ctx context.Context, find *FindMigrationHistory) ([]*MigrationHistory, error) + UpsertMigrationHistory(ctx context.Context, upsert *UpsertMigrationHistory) (*MigrationHistory, error) + // Activity model related methods. CreateActivity(ctx context.Context, create *Activity) (*Activity, error) ListActivities(ctx context.Context, find *FindActivity) ([]*Activity, error) @@ -35,7 +38,6 @@ type Driver interface { ListMemos(ctx context.Context, find *FindMemo) ([]*Memo, error) UpdateMemo(ctx context.Context, update *UpdateMemo) error DeleteMemo(ctx context.Context, delete *DeleteMemo) error - FindMemosVisibilityList(ctx context.Context, memoIDs []int32) ([]Visibility, error) // MemoRelation model related methods. UpsertMemoRelation(ctx context.Context, create *MemoRelation) (*MemoRelation, error) @@ -47,9 +49,12 @@ type Driver interface { ListMemoOrganizer(ctx context.Context, find *FindMemoOrganizer) ([]*MemoOrganizer, error) DeleteMemoOrganizer(ctx context.Context, delete *DeleteMemoOrganizer) error - // SystemSetting model related methods. - UpsertSystemSetting(ctx context.Context, upsert *SystemSetting) (*SystemSetting, error) - ListSystemSettings(ctx context.Context, find *FindSystemSetting) ([]*SystemSetting, error) + // WorkspaceSetting model related methods. + UpsertWorkspaceSetting(ctx context.Context, upsert *WorkspaceSetting) (*WorkspaceSetting, error) + ListWorkspaceSettings(ctx context.Context, find *FindWorkspaceSetting) ([]*WorkspaceSetting, error) + DeleteWorkspaceSetting(ctx context.Context, delete *DeleteWorkspaceSetting) error + UpsertWorkspaceSettingV1(ctx context.Context, upsert *storepb.WorkspaceSetting) (*storepb.WorkspaceSetting, error) + ListWorkspaceSettingsV1(ctx context.Context, find *FindWorkspaceSettingV1) ([]*storepb.WorkspaceSetting, error) // User model related methods. CreateUser(ctx context.Context, create *User) (*User, error) @@ -58,15 +63,12 @@ type Driver interface { DeleteUser(ctx context.Context, delete *DeleteUser) error // UserSetting model related methods. - UpsertUserSetting(ctx context.Context, upsert *UserSetting) (*UserSetting, error) - ListUserSettings(ctx context.Context, find *FindUserSetting) ([]*UserSetting, error) - UpsertUserSettingV1(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) - ListUserSettingsV1(ctx context.Context, find *FindUserSettingV1) ([]*storepb.UserSetting, error) + UpsertUserSetting(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) + ListUserSettings(ctx context.Context, find *FindUserSetting) ([]*storepb.UserSetting, error) // IdentityProvider model related methods. CreateIdentityProvider(ctx context.Context, create *IdentityProvider) (*IdentityProvider, error) ListIdentityProviders(ctx context.Context, find *FindIdentityProvider) ([]*IdentityProvider, error) - GetIdentityProvider(ctx context.Context, find *FindIdentityProvider) (*IdentityProvider, error) UpdateIdentityProvider(ctx context.Context, update *UpdateIdentityProvider) (*IdentityProvider, error) DeleteIdentityProvider(ctx context.Context, delete *DeleteIdentityProvider) error @@ -78,7 +80,6 @@ type Driver interface { // Storage model related methods. CreateStorage(ctx context.Context, create *Storage) (*Storage, error) ListStorages(ctx context.Context, find *FindStorage) ([]*Storage, error) - GetStorage(ctx context.Context, find *FindStorage) (*Storage, error) UpdateStorage(ctx context.Context, update *UpdateStorage) (*Storage, error) DeleteStorage(ctx context.Context, delete *DeleteStorage) error @@ -87,4 +88,15 @@ type Driver interface { ListInboxes(ctx context.Context, find *FindInbox) ([]*Inbox, error) UpdateInbox(ctx context.Context, update *UpdateInbox) (*Inbox, error) DeleteInbox(ctx context.Context, delete *DeleteInbox) error + + // Webhook model related methods. + CreateWebhook(ctx context.Context, create *storepb.Webhook) (*storepb.Webhook, error) + ListWebhooks(ctx context.Context, find *FindWebhook) ([]*storepb.Webhook, error) + UpdateWebhook(ctx context.Context, update *UpdateWebhook) (*storepb.Webhook, error) + DeleteWebhook(ctx context.Context, delete *DeleteWebhook) error + + // Reaction model related methods. + UpsertReaction(ctx context.Context, create *storepb.Reaction) (*storepb.Reaction, error) + ListReactions(ctx context.Context, find *FindReaction) ([]*storepb.Reaction, error) + DeleteReaction(ctx context.Context, delete *DeleteReaction) error } diff --git a/store/memo.go b/store/memo.go index 35a6031becf20..4d0953ab588ff 100644 --- a/store/memo.go +++ b/store/memo.go @@ -2,6 +2,9 @@ package store import ( "context" + "errors" + + "github.com/usememos/memos/internal/util" ) // Visibility is the type of a visibility. @@ -29,7 +32,8 @@ func (v Visibility) String() string { } type Memo struct { - ID int32 + ID int32 + ResourceName string // Standard fields RowStatus RowStatus @@ -42,43 +46,43 @@ type Memo struct { Visibility Visibility // Composed fields - // For those comment memos, the parent ID is the memo ID of the memo being commented. - // If the parent ID is nil, then this memo is not a comment. - ParentID *int32 - Pinned bool - ResourceIDList []int32 - RelationList []*MemoRelation + Pinned bool + ParentID *int32 } type FindMemo struct { - ID *int32 + ID *int32 + ResourceName *string // Standard fields RowStatus *RowStatus CreatorID *int32 CreatedTsAfter *int64 CreatedTsBefore *int64 + UpdatedTsAfter *int64 + UpdatedTsBefore *int64 // Domain specific fields - ContentSearch []string - VisibilityList []Visibility - Pinned *bool - HasParent *bool - ExcludeContent bool + ContentSearch []string + VisibilityList []Visibility + ExcludeContent bool + ExcludeComments bool // Pagination Limit *int Offset *int OrderByUpdatedTs bool + OrderByPinned bool } type UpdateMemo struct { - ID int32 - CreatedTs *int64 - UpdatedTs *int64 - RowStatus *RowStatus - Content *string - Visibility *Visibility + ID int32 + ResourceName *string + CreatedTs *int64 + UpdatedTs *int64 + RowStatus *RowStatus + Content *string + Visibility *Visibility } type DeleteMemo struct { @@ -86,6 +90,9 @@ type DeleteMemo struct { } func (s *Store) CreateMemo(ctx context.Context, create *Memo) (*Memo, error) { + if !util.ResourceNameMatcher.MatchString(create.ResourceName) { + return nil, errors.New("resource name is invalid") + } return s.driver.CreateMemo(ctx, create) } @@ -107,13 +114,12 @@ func (s *Store) GetMemo(ctx context.Context, find *FindMemo) (*Memo, error) { } func (s *Store) UpdateMemo(ctx context.Context, update *UpdateMemo) error { + if update.ResourceName != nil && !util.ResourceNameMatcher.MatchString(*update.ResourceName) { + return errors.New("resource name is invalid") + } return s.driver.UpdateMemo(ctx, update) } func (s *Store) DeleteMemo(ctx context.Context, delete *DeleteMemo) error { return s.driver.DeleteMemo(ctx, delete) } - -func (s *Store) FindMemosVisibilityList(ctx context.Context, memoIDs []int32) ([]Visibility, error) { - return s.driver.FindMemosVisibilityList(ctx, memoIDs) -} diff --git a/store/memo_relation.go b/store/memo_relation.go index 68e62cf8551b0..3d68049dfd960 100644 --- a/store/memo_relation.go +++ b/store/memo_relation.go @@ -39,19 +39,6 @@ func (s *Store) ListMemoRelations(ctx context.Context, find *FindMemoRelation) ( return s.driver.ListMemoRelations(ctx, find) } -func (s *Store) GetMemoRelation(ctx context.Context, find *FindMemoRelation) (*MemoRelation, error) { - list, err := s.ListMemoRelations(ctx, find) - if err != nil { - return nil, err - } - - if len(list) == 0 { - return nil, nil - } - - return list[0], nil -} - func (s *Store) DeleteMemoRelation(ctx context.Context, delete *DeleteMemoRelation) error { return s.driver.DeleteMemoRelation(ctx, delete) } diff --git a/store/migration_history.go b/store/migration_history.go new file mode 100644 index 0000000000000..693663befb0f4 --- /dev/null +++ b/store/migration_history.go @@ -0,0 +1,13 @@ +package store + +type MigrationHistory struct { + Version string + CreatedTs int64 +} + +type UpsertMigrationHistory struct { + Version string +} + +type FindMigrationHistory struct { +} diff --git a/store/migrator.go b/store/migrator.go new file mode 100644 index 0000000000000..fca734f3b12b5 --- /dev/null +++ b/store/migrator.go @@ -0,0 +1,61 @@ +package store + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/pkg/errors" + + storepb "github.com/usememos/memos/proto/gen/store" +) + +// MigrateWorkspaceSetting migrates workspace setting from v1 to v2. +func (s *Store) MigrateWorkspaceSetting(ctx context.Context) error { + workspaceSettings, err := s.ListWorkspaceSettings(ctx, &FindWorkspaceSetting{}) + if err != nil { + return errors.Wrap(err, "failed to list workspace settings") + } + + workspaceGeneralSetting, err := s.GetWorkspaceGeneralSetting(ctx) + if err != nil { + return errors.Wrap(err, "failed to get workspace general setting") + } + + for _, workspaceSetting := range workspaceSettings { + matched := true + var baseValue any + // nolint + json.Unmarshal([]byte(workspaceSetting.Value), &baseValue) + if workspaceSetting.Name == "allow-signup" { + workspaceGeneralSetting.DisallowSignup = !baseValue.(bool) + } else if workspaceSetting.Name == "disable-password-login" { + workspaceGeneralSetting.DisallowPasswordLogin = baseValue.(bool) + } else if workspaceSetting.Name == "additional-style" { + workspaceGeneralSetting.AdditionalStyle = baseValue.(string) + } else if workspaceSetting.Name == "additional-script" { + workspaceGeneralSetting.AdditionalScript = baseValue.(string) + } else if workspaceSetting.Name == "instance-url" { + workspaceGeneralSetting.InstanceUrl = workspaceSetting.Value + } else { + matched = false + } + + if matched { + if err := s.DeleteWorkspaceSetting(ctx, &DeleteWorkspaceSetting{ + Name: workspaceSetting.Name, + }); err != nil { + return errors.Wrap(err, fmt.Sprintf("failed to delete workspace setting: %s", workspaceSetting.Name)) + } + } + } + + if _, err := s.UpsertWorkspaceSettingV1(ctx, &storepb.WorkspaceSetting{ + Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_GENERAL, + Value: &storepb.WorkspaceSetting_General{General: workspaceGeneralSetting}, + }); err != nil { + return errors.Wrap(err, "failed to upsert workspace general setting") + } + + return nil +} diff --git a/store/reaction.go b/store/reaction.go new file mode 100644 index 0000000000000..67d4906a2daa3 --- /dev/null +++ b/store/reaction.go @@ -0,0 +1,29 @@ +package store + +import ( + "context" + + storepb "github.com/usememos/memos/proto/gen/store" +) + +type FindReaction struct { + ID *int32 + CreatorID *int32 + ContentID *string +} + +type DeleteReaction struct { + ID int32 +} + +func (s *Store) UpsertReaction(ctx context.Context, upsert *storepb.Reaction) (*storepb.Reaction, error) { + return s.driver.UpsertReaction(ctx, upsert) +} + +func (s *Store) ListReactions(ctx context.Context, find *FindReaction) ([]*storepb.Reaction, error) { + return s.driver.ListReactions(ctx, find) +} + +func (s *Store) DeleteReaction(ctx context.Context, delete *DeleteReaction) error { + return s.driver.DeleteReaction(ctx, delete) +} diff --git a/store/resource.go b/store/resource.go index 4d9979455b3f6..fae1cd1b5b970 100644 --- a/store/resource.go +++ b/store/resource.go @@ -17,7 +17,8 @@ const ( ) type Resource struct { - ID int32 + ID int32 + ResourceName string // Standard fields CreatorID int32 @@ -37,6 +38,7 @@ type Resource struct { type FindResource struct { GetBlob bool ID *int32 + ResourceName *string CreatorID *int32 Filename *string MemoID *int32 @@ -47,9 +49,11 @@ type FindResource struct { type UpdateResource struct { ID int32 + ResourceName *string UpdatedTs *int64 Filename *string InternalPath *string + ExternalLink *string MemoID *int32 Blob []byte } @@ -60,6 +64,9 @@ type DeleteResource struct { } func (s *Store) CreateResource(ctx context.Context, create *Resource) (*Resource, error) { + if !util.ResourceNameMatcher.MatchString(create.ResourceName) { + return nil, errors.New("invalid resource name") + } return s.driver.CreateResource(ctx, create) } @@ -81,6 +88,9 @@ func (s *Store) GetResource(ctx context.Context, find *FindResource) (*Resource, } func (s *Store) UpdateResource(ctx context.Context, update *UpdateResource) (*Resource, error) { + if update.ResourceName != nil && !util.ResourceNameMatcher.MatchString(*update.ResourceName) { + return nil, errors.New("invalid resource name") + } return s.driver.UpdateResource(ctx, update) } @@ -95,8 +105,13 @@ func (s *Store) DeleteResource(ctx context.Context, delete *DeleteResource) erro // Delete the local file. if resource.InternalPath != "" { - _ = os.Remove(resource.InternalPath) + resourcePath := filepath.FromSlash(resource.InternalPath) + if !filepath.IsAbs(resourcePath) { + resourcePath = filepath.Join(s.Profile.Data, resourcePath) + } + _ = os.Remove(resourcePath) } + // Delete the thumbnail. if util.HasPrefixes(resource.Type, "image/png", "image/jpeg") { ext := filepath.Ext(resource.Filename) diff --git a/store/store.go b/store/store.go index a2c8e06861b13..5ee65604b6875 100644 --- a/store/store.go +++ b/store/store.go @@ -9,24 +9,28 @@ import ( // Store provides database access to all raw objects. type Store struct { - Profile *profile.Profile - driver Driver - systemSettingCache sync.Map // map[string]*SystemSetting - userCache sync.Map // map[int]*User - userSettingCache sync.Map // map[string]*UserSetting - idpCache sync.Map // map[int]*IdentityProvider + Profile *profile.Profile + driver Driver + workspaceSettingCache sync.Map // map[string]*WorkspaceSetting + workspaceSettingV1Cache sync.Map // map[string]*storepb.WorkspaceSetting + userCache sync.Map // map[int]*User + userSettingCache sync.Map // map[string]*UserSetting + idpCache sync.Map // map[int]*IdentityProvider } // New creates a new instance of Store. func New(driver Driver, profile *profile.Profile) *Store { return &Store{ - Profile: profile, driver: driver, + Profile: profile, } } -func (s *Store) BackupTo(ctx context.Context, filename string) error { - return s.driver.BackupTo(ctx, filename) +func (s *Store) MigrateManually(ctx context.Context) error { + if err := s.MigrateWorkspaceSetting(ctx); err != nil { + return err + } + return nil } func (s *Store) Vacuum(ctx context.Context) error { diff --git a/store/system_setting.go b/store/system_setting.go deleted file mode 100644 index 9ae3232c97bd3..0000000000000 --- a/store/system_setting.go +++ /dev/null @@ -1,61 +0,0 @@ -package store - -import ( - "context" -) - -type SystemSetting struct { - Name string - Value string - Description string -} - -type FindSystemSetting struct { - Name string -} - -func (s *Store) UpsertSystemSetting(ctx context.Context, upsert *SystemSetting) (*SystemSetting, error) { - return s.driver.UpsertSystemSetting(ctx, upsert) -} - -func (s *Store) ListSystemSettings(ctx context.Context, find *FindSystemSetting) ([]*SystemSetting, error) { - list, err := s.driver.ListSystemSettings(ctx, find) - if err != nil { - return nil, err - } - - for _, systemSettingMessage := range list { - s.systemSettingCache.Store(systemSettingMessage.Name, systemSettingMessage) - } - return list, nil -} - -func (s *Store) GetSystemSetting(ctx context.Context, find *FindSystemSetting) (*SystemSetting, error) { - if find.Name != "" { - if cache, ok := s.systemSettingCache.Load(find.Name); ok { - return cache.(*SystemSetting), nil - } - } - - list, err := s.ListSystemSettings(ctx, find) - if err != nil { - return nil, err - } - - if len(list) == 0 { - return nil, nil - } - - systemSettingMessage := list[0] - s.systemSettingCache.Store(systemSettingMessage.Name, systemSettingMessage) - return systemSettingMessage, nil -} - -func (s *Store) GetSystemSettingValueWithDefault(ctx context.Context, settingName string, defaultValue string) string { - if setting, err := s.GetSystemSetting(ctx, &FindSystemSetting{ - Name: settingName, - }); err == nil && setting != nil { - return setting.Value - } - return defaultValue -} diff --git a/store/user.go b/store/user.go index 6afd9dfb9df0b..4dcda4f6540ac 100644 --- a/store/user.go +++ b/store/user.go @@ -28,6 +28,20 @@ func (e Role) String() string { return "USER" } +const ( + SystemBotID int32 = 0 +) + +var ( + SystemBot = &User{ + ID: SystemBotID, + Username: "system_bot", + Role: RoleAdmin, + Email: "", + Nickname: "Bot", + } +) + type User struct { ID int32 @@ -106,6 +120,10 @@ func (s *Store) ListUsers(ctx context.Context, find *FindUser) ([]*User, error) func (s *Store) GetUser(ctx context.Context, find *FindUser) (*User, error) { if find.ID != nil { + if *find.ID == SystemBotID { + return SystemBot, nil + } + if cache, ok := s.userCache.Load(*find.ID); ok { return cache.(*User), nil } diff --git a/store/user_setting.go b/store/user_setting.go index bac59b72664df..d8e85bf50d2ae 100644 --- a/store/user_setting.go +++ b/store/user_setting.go @@ -6,66 +6,13 @@ import ( storepb "github.com/usememos/memos/proto/gen/store" ) -type UserSetting struct { - UserID int32 - Key string - Value string -} - type FindUserSetting struct { - UserID *int32 - Key string -} - -func (s *Store) UpsertUserSetting(ctx context.Context, upsert *UserSetting) (*UserSetting, error) { - userSetting, err := s.driver.UpsertUserSetting(ctx, upsert) - if err != nil { - return nil, err - } - - s.userSettingCache.Store(getUserSettingCacheKey(userSetting.UserID, userSetting.Key), userSetting) - return userSetting, nil -} - -func (s *Store) ListUserSettings(ctx context.Context, find *FindUserSetting) ([]*UserSetting, error) { - userSettingList, err := s.driver.ListUserSettings(ctx, find) - if err != nil { - return nil, err - } - - for _, userSetting := range userSettingList { - s.userSettingCache.Store(getUserSettingCacheKey(userSetting.UserID, userSetting.Key), userSetting) - } - return userSettingList, nil -} - -func (s *Store) GetUserSetting(ctx context.Context, find *FindUserSetting) (*UserSetting, error) { - if find.UserID != nil { - if cache, ok := s.userSettingCache.Load(getUserSettingCacheKey(*find.UserID, find.Key)); ok { - return cache.(*UserSetting), nil - } - } - - list, err := s.ListUserSettings(ctx, find) - if err != nil { - return nil, err - } - - if len(list) == 0 { - return nil, nil - } - - userSetting := list[0] - return userSetting, nil -} - -type FindUserSettingV1 struct { UserID *int32 Key storepb.UserSettingKey } -func (s *Store) UpsertUserSettingV1(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) { - userSettingMessage, err := s.driver.UpsertUserSettingV1(ctx, upsert) +func (s *Store) UpsertUserSetting(ctx context.Context, upsert *storepb.UserSetting) (*storepb.UserSetting, error) { + userSettingMessage, err := s.driver.UpsertUserSetting(ctx, upsert) if err != nil { return nil, err } @@ -74,8 +21,8 @@ func (s *Store) UpsertUserSettingV1(ctx context.Context, upsert *storepb.UserSet return userSettingMessage, nil } -func (s *Store) ListUserSettingsV1(ctx context.Context, find *FindUserSettingV1) ([]*storepb.UserSetting, error) { - userSettingList, err := s.driver.ListUserSettingsV1(ctx, find) +func (s *Store) ListUserSettings(ctx context.Context, find *FindUserSetting) ([]*storepb.UserSetting, error) { + userSettingList, err := s.driver.ListUserSettings(ctx, find) if err != nil { return nil, err } @@ -86,14 +33,14 @@ func (s *Store) ListUserSettingsV1(ctx context.Context, find *FindUserSettingV1) return userSettingList, nil } -func (s *Store) GetUserSettingV1(ctx context.Context, find *FindUserSettingV1) (*storepb.UserSetting, error) { +func (s *Store) GetUserSetting(ctx context.Context, find *FindUserSetting) (*storepb.UserSetting, error) { if find.UserID != nil { if cache, ok := s.userSettingCache.Load(getUserSettingV1CacheKey(*find.UserID, find.Key.String())); ok { return cache.(*storepb.UserSetting), nil } } - list, err := s.ListUserSettingsV1(ctx, find) + list, err := s.ListUserSettings(ctx, find) if err != nil { return nil, err } @@ -109,7 +56,7 @@ func (s *Store) GetUserSettingV1(ctx context.Context, find *FindUserSettingV1) ( // GetUserAccessTokens returns the access tokens of the user. func (s *Store) GetUserAccessTokens(ctx context.Context, userID int32) ([]*storepb.AccessTokensUserSetting_AccessToken, error) { - userSetting, err := s.GetUserSettingV1(ctx, &FindUserSettingV1{ + userSetting, err := s.GetUserSetting(ctx, &FindUserSetting{ UserID: &userID, Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS, }) @@ -123,3 +70,30 @@ func (s *Store) GetUserAccessTokens(ctx context.Context, userID int32) ([]*store accessTokensUserSetting := userSetting.GetAccessTokens() return accessTokensUserSetting.AccessTokens, nil } + +// RemoveUserAccessToken remove the access token of the user. +func (s *Store) RemoveUserAccessToken(ctx context.Context, userID int32, token string) error { + oldAccessTokens, err := s.GetUserAccessTokens(ctx, userID) + if err != nil { + return err + } + + newAccessTokens := make([]*storepb.AccessTokensUserSetting_AccessToken, 0, len(oldAccessTokens)) + for _, t := range oldAccessTokens { + if token != t.AccessToken { + newAccessTokens = append(newAccessTokens, t) + } + } + + _, err = s.UpsertUserSetting(ctx, &storepb.UserSetting{ + UserId: userID, + Key: storepb.UserSettingKey_USER_SETTING_ACCESS_TOKENS, + Value: &storepb.UserSetting_AccessTokens{ + AccessTokens: &storepb.AccessTokensUserSetting{ + AccessTokens: newAccessTokens, + }, + }, + }) + + return err +} diff --git a/store/webhook.go b/store/webhook.go new file mode 100644 index 0000000000000..2adf3236b8158 --- /dev/null +++ b/store/webhook.go @@ -0,0 +1,50 @@ +package store + +import ( + "context" + + storepb "github.com/usememos/memos/proto/gen/store" +) + +type FindWebhook struct { + ID *int32 + CreatorID *int32 +} + +type UpdateWebhook struct { + ID int32 + RowStatus *storepb.RowStatus + Name *string + URL *string +} + +type DeleteWebhook struct { + ID int32 +} + +func (s *Store) CreateWebhook(ctx context.Context, create *storepb.Webhook) (*storepb.Webhook, error) { + return s.driver.CreateWebhook(ctx, create) +} + +func (s *Store) ListWebhooks(ctx context.Context, find *FindWebhook) ([]*storepb.Webhook, error) { + return s.driver.ListWebhooks(ctx, find) +} + +func (s *Store) GetWebhooks(ctx context.Context, find *FindWebhook) (*storepb.Webhook, error) { + list, err := s.ListWebhooks(ctx, find) + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + return list[0], nil +} + +func (s *Store) UpdateWebhook(ctx context.Context, update *UpdateWebhook) (*storepb.Webhook, error) { + return s.driver.UpdateWebhook(ctx, update) +} + +func (s *Store) DeleteWebhook(ctx context.Context, delete *DeleteWebhook) error { + return s.driver.DeleteWebhook(ctx, delete) +} diff --git a/store/workspace_setting.go b/store/workspace_setting.go new file mode 100644 index 0000000000000..5747875edde20 --- /dev/null +++ b/store/workspace_setting.go @@ -0,0 +1,129 @@ +package store + +import ( + "context" + + "github.com/pkg/errors" + + storepb "github.com/usememos/memos/proto/gen/store" +) + +type WorkspaceSetting struct { + Name string + Value string + Description string +} + +type FindWorkspaceSetting struct { + Name string +} + +type DeleteWorkspaceSetting struct { + Name string +} + +func (s *Store) UpsertWorkspaceSetting(ctx context.Context, upsert *WorkspaceSetting) (*WorkspaceSetting, error) { + return s.driver.UpsertWorkspaceSetting(ctx, upsert) +} + +func (s *Store) ListWorkspaceSettings(ctx context.Context, find *FindWorkspaceSetting) ([]*WorkspaceSetting, error) { + list, err := s.driver.ListWorkspaceSettings(ctx, find) + if err != nil { + return nil, err + } + + for _, systemSettingMessage := range list { + s.workspaceSettingCache.Store(systemSettingMessage.Name, systemSettingMessage) + } + return list, nil +} + +func (s *Store) GetWorkspaceSetting(ctx context.Context, find *FindWorkspaceSetting) (*WorkspaceSetting, error) { + if find.Name != "" { + if cache, ok := s.workspaceSettingCache.Load(find.Name); ok { + return cache.(*WorkspaceSetting), nil + } + } + + list, err := s.ListWorkspaceSettings(ctx, find) + if err != nil { + return nil, err + } + + if len(list) == 0 { + return nil, nil + } + + systemSettingMessage := list[0] + s.workspaceSettingCache.Store(systemSettingMessage.Name, systemSettingMessage) + return systemSettingMessage, nil +} + +func (s *Store) DeleteWorkspaceSetting(ctx context.Context, delete *DeleteWorkspaceSetting) error { + err := s.driver.DeleteWorkspaceSetting(ctx, delete) + if err != nil { + return errors.Wrap(err, "Failed to delete workspace setting") + } + s.workspaceSettingCache.Delete(delete.Name) + return nil +} + +type FindWorkspaceSettingV1 struct { + Key storepb.WorkspaceSettingKey +} + +func (s *Store) UpsertWorkspaceSettingV1(ctx context.Context, upsert *storepb.WorkspaceSetting) (*storepb.WorkspaceSetting, error) { + workspaceSetting, err := s.driver.UpsertWorkspaceSettingV1(ctx, upsert) + if err != nil { + return nil, errors.Wrap(err, "Failed to upsert workspace setting") + } + s.workspaceSettingV1Cache.Store(workspaceSetting.Key.String(), workspaceSetting) + return workspaceSetting, nil +} + +func (s *Store) ListWorkspaceSettingsV1(ctx context.Context, find *FindWorkspaceSettingV1) ([]*storepb.WorkspaceSetting, error) { + list, err := s.driver.ListWorkspaceSettingsV1(ctx, find) + if err != nil { + return nil, err + } + + for _, workspaceSetting := range list { + s.workspaceSettingV1Cache.Store(workspaceSetting.Key.String(), workspaceSetting) + } + return list, nil +} + +func (s *Store) GetWorkspaceSettingV1(ctx context.Context, find *FindWorkspaceSettingV1) (*storepb.WorkspaceSetting, error) { + if find.Key != storepb.WorkspaceSettingKey_WORKSPACE_SETTING_KEY_UNSPECIFIED { + if cache, ok := s.workspaceSettingV1Cache.Load(find.Key.String()); ok { + return cache.(*storepb.WorkspaceSetting), nil + } + } + + list, err := s.ListWorkspaceSettingsV1(ctx, find) + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + + workspaceSetting := list[0] + s.workspaceSettingV1Cache.Store(workspaceSetting.Key.String(), workspaceSetting) + return workspaceSetting, nil +} + +func (s *Store) GetWorkspaceGeneralSetting(ctx context.Context) (*storepb.WorkspaceGeneralSetting, error) { + workspaceSetting, err := s.GetWorkspaceSettingV1(ctx, &FindWorkspaceSettingV1{ + Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_GENERAL, + }) + if err != nil { + return nil, errors.Wrap(err, "failed to get workspace setting") + } + + workspaceGeneralSetting := &storepb.WorkspaceGeneralSetting{} + if workspaceSetting != nil { + workspaceGeneralSetting = workspaceSetting.GetGeneral() + } + return workspaceGeneralSetting, nil +} diff --git a/test/server/auth_test.go b/test/server/auth_test.go deleted file mode 100644 index 372a420747ced..0000000000000 --- a/test/server/auth_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package testserver - -import ( - "bytes" - "context" - "encoding/json" - "testing" - - "github.com/pkg/errors" - "github.com/stretchr/testify/require" - - apiv1 "github.com/usememos/memos/api/v1" -) - -func TestAuthServer(t *testing.T) { - ctx := context.Background() - s, err := NewTestingServer(ctx, t) - require.NoError(t, err) - defer s.Shutdown(ctx) - - signup := &apiv1.SignUp{ - Username: "testuser", - Password: "testpassword", - } - user, err := s.postAuthSignUp(signup) - require.NoError(t, err) - require.Equal(t, signup.Username, user.Username) - - signin := &apiv1.SignIn{ - Username: "testuser", - Password: "testpassword", - } - user, err = s.postAuthSignIn(signin) - require.NoError(t, err) - require.Equal(t, signup.Username, user.Username) - err = s.postSignOut() - require.NoError(t, err) - _, err = s.getCurrentUser() - require.Error(t, err) -} - -func (s *TestingServer) postAuthSignUp(signup *apiv1.SignUp) (*apiv1.User, error) { - rawData, err := json.Marshal(&signup) - if err != nil { - return nil, errors.Wrap(err, "failed to marshal signup") - } - reader := bytes.NewReader(rawData) - body, err := s.post("/api/v1/auth/signup", reader, nil) - if err != nil { - return nil, errors.Wrap(err, "fail to post request") - } - - buf := &bytes.Buffer{} - _, err = buf.ReadFrom(body) - if err != nil { - return nil, errors.Wrap(err, "fail to read response body") - } - - user := &apiv1.User{} - if err = json.Unmarshal(buf.Bytes(), user); err != nil { - return nil, errors.Wrap(err, "fail to unmarshal post signup response") - } - return user, nil -} - -func (s *TestingServer) postAuthSignIn(signip *apiv1.SignIn) (*apiv1.User, error) { - rawData, err := json.Marshal(&signip) - if err != nil { - return nil, errors.Wrap(err, "failed to marshal signin") - } - reader := bytes.NewReader(rawData) - body, err := s.post("/api/v1/auth/signin", reader, nil) - if err != nil { - return nil, errors.Wrap(err, "fail to post request") - } - - buf := &bytes.Buffer{} - _, err = buf.ReadFrom(body) - if err != nil { - return nil, errors.Wrap(err, "fail to read response body") - } - - user := &apiv1.User{} - if err = json.Unmarshal(buf.Bytes(), user); err != nil { - return nil, errors.Wrap(err, "fail to unmarshal post signin response") - } - return user, nil -} - -func (s *TestingServer) postSignOut() error { - _, err := s.post("/api/v1/auth/signout", nil, nil) - if err != nil { - return errors.Wrap(err, "fail to post request") - } - return nil -} diff --git a/test/server/memo_relation_test.go b/test/server/memo_relation_test.go deleted file mode 100644 index 53179934351d6..0000000000000 --- a/test/server/memo_relation_test.go +++ /dev/null @@ -1,92 +0,0 @@ -package testserver - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "testing" - - "github.com/pkg/errors" - "github.com/stretchr/testify/require" - - apiv1 "github.com/usememos/memos/api/v1" -) - -func TestMemoRelationServer(t *testing.T) { - ctx := context.Background() - s, err := NewTestingServer(ctx, t) - require.NoError(t, err) - defer s.Shutdown(ctx) - - signup := &apiv1.SignUp{ - Username: "testuser", - Password: "testpassword", - } - user, err := s.postAuthSignUp(signup) - require.NoError(t, err) - require.Equal(t, signup.Username, user.Username) - memo, err := s.postMemoCreate(&apiv1.CreateMemoRequest{ - Content: "test memo", - }) - require.NoError(t, err) - require.Equal(t, "test memo", memo.Content) - memo2, err := s.postMemoCreate(&apiv1.CreateMemoRequest{ - Content: "test memo2", - RelationList: []*apiv1.UpsertMemoRelationRequest{ - { - RelatedMemoID: memo.ID, - Type: apiv1.MemoRelationReference, - }, - }, - }) - require.NoError(t, err) - require.Equal(t, "test memo2", memo2.Content) - memoList, err := s.getMemoList() - require.NoError(t, err) - require.Len(t, memoList, 2) - require.Len(t, memo2.RelationList, 1) - err = s.deleteMemoRelation(memo2.ID, memo.ID, apiv1.MemoRelationReference) - require.NoError(t, err) - memo2, err = s.getMemo(memo2.ID) - require.NoError(t, err) - require.Len(t, memo2.RelationList, 0) - memoRelation, err := s.postMemoRelationUpsert(memo2.ID, &apiv1.UpsertMemoRelationRequest{ - RelatedMemoID: memo.ID, - Type: apiv1.MemoRelationReference, - }) - require.NoError(t, err) - require.Equal(t, memo.ID, memoRelation.RelatedMemoID) - memo2, err = s.getMemo(memo2.ID) - require.NoError(t, err) - require.Len(t, memo2.RelationList, 1) -} - -func (s *TestingServer) postMemoRelationUpsert(memoID int32, memoRelationUpsert *apiv1.UpsertMemoRelationRequest) (*apiv1.MemoRelation, error) { - rawData, err := json.Marshal(&memoRelationUpsert) - if err != nil { - return nil, errors.Wrap(err, "failed to marshal memo relation upsert") - } - reader := bytes.NewReader(rawData) - body, err := s.post(fmt.Sprintf("/api/v1/memo/%d/relation", memoID), reader, nil) - if err != nil { - return nil, err - } - - buf := &bytes.Buffer{} - _, err = buf.ReadFrom(body) - if err != nil { - return nil, errors.Wrap(err, "fail to read response body") - } - - memoRelation := &apiv1.MemoRelation{} - if err = json.Unmarshal(buf.Bytes(), memoRelation); err != nil { - return nil, errors.Wrap(err, "fail to unmarshal post memo relation upsert response") - } - return memoRelation, nil -} - -func (s *TestingServer) deleteMemoRelation(memoID int32, relatedMemoID int32, relationType apiv1.MemoRelationType) error { - _, err := s.delete(fmt.Sprintf("/api/v1/memo/%d/relation/%d/type/%s", memoID, relatedMemoID, relationType), nil) - return err -} diff --git a/test/server/memo_test.go b/test/server/memo_test.go deleted file mode 100644 index 0c0fb37ca7644..0000000000000 --- a/test/server/memo_test.go +++ /dev/null @@ -1,176 +0,0 @@ -package testserver - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "testing" - - "github.com/pkg/errors" - "github.com/stretchr/testify/require" - - apiv1 "github.com/usememos/memos/api/v1" -) - -func TestMemoServer(t *testing.T) { - ctx := context.Background() - s, err := NewTestingServer(ctx, t) - require.NoError(t, err) - defer s.Shutdown(ctx) - - signup := &apiv1.SignUp{ - Username: "testuser", - Password: "testpassword", - } - user, err := s.postAuthSignUp(signup) - require.NoError(t, err) - require.Equal(t, signup.Username, user.Username) - memo, err := s.postMemoCreate(&apiv1.CreateMemoRequest{ - Content: "test memo", - }) - require.NoError(t, err) - require.Equal(t, "test memo", memo.Content) - memoList, err := s.getMemoList() - require.NoError(t, err) - require.Len(t, memoList, 1) - updatedContent := "updated memo" - memo, err = s.patchMemo(&apiv1.PatchMemoRequest{ - ID: memo.ID, - Content: &updatedContent, - }) - require.NoError(t, err) - require.Equal(t, updatedContent, memo.Content) - require.Equal(t, false, memo.Pinned) - _, err = s.postMemoOrganizer(memo.ID, &apiv1.UpsertMemoOrganizerRequest{ - Pinned: true, - }) - require.NoError(t, err) - memo, err = s.patchMemo(&apiv1.PatchMemoRequest{ - ID: memo.ID, - Content: &updatedContent, - }) - require.NoError(t, err) - require.Equal(t, updatedContent, memo.Content) - require.Equal(t, true, memo.Pinned) - err = s.deleteMemo(memo.ID) - require.NoError(t, err) - memoList, err = s.getMemoList() - require.NoError(t, err) - require.Len(t, memoList, 0) -} - -func (s *TestingServer) getMemo(memoID int32) (*apiv1.Memo, error) { - body, err := s.get(fmt.Sprintf("/api/v1/memo/%d", memoID), nil) - if err != nil { - return nil, err - } - - buf := &bytes.Buffer{} - _, err = buf.ReadFrom(body) - if err != nil { - return nil, errors.Wrap(err, "fail to read response body") - } - - memo := &apiv1.Memo{} - if err = json.Unmarshal(buf.Bytes(), memo); err != nil { - return nil, errors.Wrap(err, "fail to unmarshal get memo response") - } - return memo, nil -} - -func (s *TestingServer) getMemoList() ([]*apiv1.Memo, error) { - body, err := s.get("/api/v1/memo", nil) - if err != nil { - return nil, err - } - - buf := &bytes.Buffer{} - _, err = buf.ReadFrom(body) - if err != nil { - return nil, errors.Wrap(err, "fail to read response body") - } - - memoList := []*apiv1.Memo{} - if err = json.Unmarshal(buf.Bytes(), &memoList); err != nil { - return nil, errors.Wrap(err, "fail to unmarshal get memo list response") - } - return memoList, nil -} - -func (s *TestingServer) postMemoCreate(memoCreate *apiv1.CreateMemoRequest) (*apiv1.Memo, error) { - rawData, err := json.Marshal(&memoCreate) - if err != nil { - return nil, errors.Wrap(err, "failed to marshal memo create") - } - reader := bytes.NewReader(rawData) - body, err := s.post("/api/v1/memo", reader, nil) - if err != nil { - return nil, err - } - - buf := &bytes.Buffer{} - _, err = buf.ReadFrom(body) - if err != nil { - return nil, errors.Wrap(err, "fail to read response body") - } - - memo := &apiv1.Memo{} - if err = json.Unmarshal(buf.Bytes(), memo); err != nil { - return nil, errors.Wrap(err, "fail to unmarshal post memo create response") - } - return memo, nil -} - -func (s *TestingServer) patchMemo(memoPatch *apiv1.PatchMemoRequest) (*apiv1.Memo, error) { - rawData, err := json.Marshal(&memoPatch) - if err != nil { - return nil, errors.Wrap(err, "failed to marshal memo patch") - } - reader := bytes.NewReader(rawData) - body, err := s.patch(fmt.Sprintf("/api/v1/memo/%d", memoPatch.ID), reader, nil) - if err != nil { - return nil, err - } - - buf := &bytes.Buffer{} - _, err = buf.ReadFrom(body) - if err != nil { - return nil, errors.Wrap(err, "fail to read response body") - } - - memo := &apiv1.Memo{} - if err = json.Unmarshal(buf.Bytes(), memo); err != nil { - return nil, errors.Wrap(err, "fail to unmarshal patch memo response") - } - return memo, nil -} - -func (s *TestingServer) deleteMemo(memoID int32) error { - _, err := s.delete(fmt.Sprintf("/api/v1/memo/%d", memoID), nil) - return err -} - -func (s *TestingServer) postMemoOrganizer(memoID int32, memosOrganizer *apiv1.UpsertMemoOrganizerRequest) (*apiv1.Memo, error) { - rawData, err := json.Marshal(&memosOrganizer) - if err != nil { - return nil, errors.Wrap(err, "failed to marshal memos organizer") - } - reader := bytes.NewReader(rawData) - body, err := s.post(fmt.Sprintf("/api/v1/memo/%d/organizer", memoID), reader, nil) - if err != nil { - return nil, err - } - - buf := &bytes.Buffer{} - _, err = buf.ReadFrom(body) - if err != nil { - return nil, errors.Wrap(err, "fail to read response body") - } - - memo := &apiv1.Memo{} - if err = json.Unmarshal(buf.Bytes(), memo); err != nil { - return nil, errors.Wrap(err, "fail to unmarshal organizer memo create response") - } - return memo, err -} diff --git a/test/server/server.go b/test/server/server.go deleted file mode 100644 index 99524edb91870..0000000000000 --- a/test/server/server.go +++ /dev/null @@ -1,181 +0,0 @@ -package testserver - -import ( - "context" - "fmt" - "io" - "net/http" - "net/url" - "strings" - "testing" - "time" - - "github.com/pkg/errors" - // sqlite driver. - _ "modernc.org/sqlite" - - "github.com/usememos/memos/api/auth" - "github.com/usememos/memos/server" - "github.com/usememos/memos/server/profile" - "github.com/usememos/memos/store" - "github.com/usememos/memos/store/db" - "github.com/usememos/memos/test" -) - -type TestingServer struct { - server *server.Server - client *http.Client - profile *profile.Profile - cookie string -} - -func NewTestingServer(ctx context.Context, t *testing.T) (*TestingServer, error) { - profile := test.GetTestingProfile(t) - dbDriver, err := db.NewDBDriver(profile) - if err != nil { - return nil, errors.Wrap(err, "failed to create db driver") - } - if err := dbDriver.Migrate(ctx); err != nil { - return nil, errors.Wrap(err, "failed to migrate db") - } - - store := store.New(dbDriver, profile) - server, err := server.NewServer(ctx, profile, store) - if err != nil { - return nil, errors.Wrap(err, "failed to create server") - } - - s := &TestingServer{ - server: server, - client: &http.Client{}, - profile: profile, - cookie: "", - } - errChan := make(chan error, 1) - - go func() { - if err := s.server.Start(ctx); err != nil { - if err != http.ErrServerClosed { - errChan <- errors.Wrap(err, "failed to run main server") - } - } - }() - - if err := s.waitForServerStart(errChan); err != nil { - return nil, errors.Wrap(err, "failed to start server") - } - - return s, nil -} - -func (s *TestingServer) Shutdown(ctx context.Context) { - s.server.Shutdown(ctx) -} - -func (s *TestingServer) waitForServerStart(errChan <-chan error) error { - ticker := time.NewTicker(100 * time.Millisecond) - defer ticker.Stop() - - for { - select { - case <-ticker.C: - if s == nil { - continue - } - e := s.server.GetEcho() - if e == nil { - continue - } - addr := e.ListenerAddr() - if addr != nil && strings.Contains(addr.String(), ":") { - return nil // was started - } - case err := <-errChan: - if err == http.ErrServerClosed { - return nil - } - return err - } - } -} - -func (s *TestingServer) request(method, uri string, body io.Reader, params, header map[string]string) (io.ReadCloser, error) { - fullURL := fmt.Sprintf("http://localhost:%d%s", s.profile.Port, uri) - req, err := http.NewRequest(method, fullURL, body) - if err != nil { - return nil, errors.Wrapf(err, "fail to create a new %s request(%q)", method, fullURL) - } - - for k, v := range header { - req.Header.Set(k, v) - } - - q := url.Values{} - for k, v := range params { - q.Add(k, v) - } - if len(q) > 0 { - req.URL.RawQuery = q.Encode() - } - - resp, err := s.client.Do(req) - if err != nil { - return nil, errors.Wrapf(err, "fail to send a %s request(%q)", method, fullURL) - } - if resp.StatusCode != http.StatusOK { - body, err := io.ReadAll(resp.Body) - if err != nil { - return nil, errors.Wrap(err, "failed to read http response body") - } - return nil, errors.Errorf("http response error code %v body %q", resp.StatusCode, string(body)) - } - - if method == "POST" { - if strings.Contains(uri, "/api/v1/auth/login") || strings.Contains(uri, "/api/v1/auth/signup") { - cookie := "" - h := resp.Header.Get("Set-Cookie") - parts := strings.Split(h, "; ") - for _, p := range parts { - if strings.HasPrefix(p, fmt.Sprintf("%s=", auth.AccessTokenCookieName)) { - cookie = p - break - } - } - if cookie == "" { - return nil, errors.New("unable to find access token in the login response headers") - } - s.cookie = cookie - } else if strings.Contains(uri, "/api/v1/auth/signout") { - s.cookie = "" - } - } - return resp.Body, nil -} - -// get sends a GET client request. -func (s *TestingServer) get(url string, params map[string]string) (io.ReadCloser, error) { - return s.request("GET", url, nil, params, map[string]string{ - "Cookie": s.cookie, - }) -} - -// post sends a POST client request. -func (s *TestingServer) post(url string, body io.Reader, params map[string]string) (io.ReadCloser, error) { - return s.request("POST", url, body, params, map[string]string{ - "Cookie": s.cookie, - }) -} - -// patch sends a PATCH client request. -func (s *TestingServer) patch(url string, body io.Reader, params map[string]string) (io.ReadCloser, error) { - return s.request("PATCH", url, body, params, map[string]string{ - "Cookie": s.cookie, - }) -} - -// delete sends a DELETE client request. -func (s *TestingServer) delete(url string, params map[string]string) (io.ReadCloser, error) { - return s.request("DELETE", url, nil, params, map[string]string{ - "Cookie": s.cookie, - }) -} diff --git a/test/server/system_test.go b/test/server/system_test.go deleted file mode 100644 index 03ac3ebd456e3..0000000000000 --- a/test/server/system_test.go +++ /dev/null @@ -1,64 +0,0 @@ -package testserver - -import ( - "bytes" - "context" - "encoding/json" - "testing" - - "github.com/pkg/errors" - "github.com/stretchr/testify/require" - - apiv1 "github.com/usememos/memos/api/v1" -) - -func TestSystemServer(t *testing.T) { - ctx := context.Background() - s, err := NewTestingServer(ctx, t) - require.NoError(t, err) - defer s.Shutdown(ctx) - - status, err := s.getSystemStatus() - require.NoError(t, err) - require.Equal(t, (*apiv1.User)(nil), status.Host) - - signup := &apiv1.SignUp{ - Username: "testuser", - Password: "testpassword", - } - user, err := s.postAuthSignUp(signup) - require.NoError(t, err) - require.Equal(t, signup.Username, user.Username) - err = s.pingSystem() - require.NoError(t, err) - status, err = s.getSystemStatus() - require.NoError(t, err) - require.Equal(t, user.ID, status.Host.ID) -} - -func (s *TestingServer) pingSystem() error { - _, err := s.get("/api/v1/ping", nil) - if err != nil { - return err - } - return nil -} - -func (s *TestingServer) getSystemStatus() (*apiv1.SystemStatus, error) { - body, err := s.get("/api/v1/status", nil) - if err != nil { - return nil, err - } - - buf := &bytes.Buffer{} - _, err = buf.ReadFrom(body) - if err != nil { - return nil, errors.Wrap(err, "fail to read response body") - } - - systemStatus := &apiv1.SystemStatus{} - if err = json.Unmarshal(buf.Bytes(), systemStatus); err != nil { - return nil, errors.Wrap(err, "fail to unmarshal get system status response") - } - return systemStatus, nil -} diff --git a/test/server/user_test.go b/test/server/user_test.go deleted file mode 100644 index da9c6301840b3..0000000000000 --- a/test/server/user_test.go +++ /dev/null @@ -1,104 +0,0 @@ -package testserver - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "testing" - - "github.com/pkg/errors" - "github.com/stretchr/testify/require" - - apiv1 "github.com/usememos/memos/api/v1" -) - -func TestUserServer(t *testing.T) { - ctx := context.Background() - s, err := NewTestingServer(ctx, t) - require.NoError(t, err) - defer s.Shutdown(ctx) - - signup := &apiv1.SignUp{ - Username: "testuser", - Password: "testpassword", - } - user, err := s.postAuthSignUp(signup) - require.NoError(t, err) - require.Equal(t, signup.Username, user.Username) - user, err = s.getCurrentUser() - require.NoError(t, err) - require.Equal(t, signup.Username, user.Username) - user, err = s.getUserByID(user.ID) - require.NoError(t, err) - require.Equal(t, signup.Username, user.Username) - newEmail := "test@usermemos.com" - userPatch := &apiv1.UpdateUserRequest{ - Email: &newEmail, - } - user, err = s.patchUser(user.ID, userPatch) - require.NoError(t, err) - require.Equal(t, newEmail, user.Email) -} - -func (s *TestingServer) getCurrentUser() (*apiv1.User, error) { - body, err := s.get("/api/v1/user/me", nil) - if err != nil { - return nil, err - } - - buf := &bytes.Buffer{} - _, err = buf.ReadFrom(body) - if err != nil { - return nil, errors.Wrap(err, "fail to read response body") - } - - user := &apiv1.User{} - if err = json.Unmarshal(buf.Bytes(), &user); err != nil { - return nil, errors.Wrap(err, "fail to unmarshal get user response") - } - return user, nil -} - -func (s *TestingServer) getUserByID(userID int32) (*apiv1.User, error) { - body, err := s.get(fmt.Sprintf("/api/v1/user/%d", userID), nil) - if err != nil { - return nil, err - } - - buf := &bytes.Buffer{} - _, err = buf.ReadFrom(body) - if err != nil { - return nil, errors.Wrap(err, "fail to read response body") - } - - user := &apiv1.User{} - if err = json.Unmarshal(buf.Bytes(), &user); err != nil { - return nil, errors.Wrap(err, "fail to unmarshal get user response") - } - return user, nil -} - -func (s *TestingServer) patchUser(userID int32, request *apiv1.UpdateUserRequest) (*apiv1.User, error) { - rawData, err := json.Marshal(&request) - if err != nil { - return nil, errors.Wrap(err, "failed to marshal request") - } - reader := bytes.NewReader(rawData) - body, err := s.patch(fmt.Sprintf("/api/v1/user/%d", userID), reader, nil) - if err != nil { - return nil, err - } - - buf := &bytes.Buffer{} - _, err = buf.ReadFrom(body) - if err != nil { - return nil, errors.Wrap(err, "fail to read response body") - } - - user := &apiv1.User{} - if err = json.Unmarshal(buf.Bytes(), user); err != nil { - return nil, errors.Wrap(err, "fail to unmarshal patch user response") - } - return user, nil -} diff --git a/test/store/activity_test.go b/test/store/activity_test.go index d5b996d272f8c..3ac3d8c197798 100644 --- a/test/store/activity_test.go +++ b/test/store/activity_test.go @@ -30,4 +30,5 @@ func TestActivityStore(t *testing.T) { require.NoError(t, err) require.Equal(t, 1, len(activities)) require.Equal(t, activity, activities[0]) + ts.Close() } diff --git a/test/store/idp_test.go b/test/store/idp_test.go index 847db471102f5..b29b1deea2450 100644 --- a/test/store/idp_test.go +++ b/test/store/idp_test.go @@ -53,4 +53,5 @@ func TestIdentityProviderStore(t *testing.T) { idpList, err := ts.ListIdentityProviders(ctx, &store.FindIdentityProvider{}) require.NoError(t, err) require.Equal(t, 0, len(idpList)) + ts.Close() } diff --git a/test/store/inbox_test.go b/test/store/inbox_test.go index 0bef75647f0f8..63791ad8e1221 100644 --- a/test/store/inbox_test.go +++ b/test/store/inbox_test.go @@ -50,4 +50,5 @@ func TestInboxStore(t *testing.T) { }) require.NoError(t, err) require.Equal(t, 0, len(inboxes)) + ts.Close() } diff --git a/test/store/memo_organizer_test.go b/test/store/memo_organizer_test.go new file mode 100644 index 0000000000000..4243a01a55d2b --- /dev/null +++ b/test/store/memo_organizer_test.go @@ -0,0 +1,64 @@ +package teststore + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/usememos/memos/store" +) + +func TestMemoOrganizerStore(t *testing.T) { + ctx := context.Background() + ts := NewTestingStore(ctx, t) + user, err := createTestingHostUser(ctx, ts) + require.NoError(t, err) + memoCreate := &store.Memo{ + ResourceName: "main-memo", + CreatorID: user.ID, + Content: "main memo content", + Visibility: store.Public, + } + memo, err := ts.CreateMemo(ctx, memoCreate) + require.NoError(t, err) + require.Equal(t, memoCreate.Content, memo.Content) + + memoOrganizer, err := ts.UpsertMemoOrganizer(ctx, &store.MemoOrganizer{ + MemoID: memo.ID, + UserID: user.ID, + Pinned: true, + }) + require.NoError(t, err) + require.NotNil(t, memoOrganizer) + require.Equal(t, memo.ID, memoOrganizer.MemoID) + require.Equal(t, user.ID, memoOrganizer.UserID) + require.Equal(t, true, memoOrganizer.Pinned) + + memoOrganizerTemp, err := ts.GetMemoOrganizer(ctx, &store.FindMemoOrganizer{ + MemoID: memo.ID, + }) + require.NoError(t, err) + require.Equal(t, memoOrganizer, memoOrganizerTemp) + memoOrganizerTemp, err = ts.UpsertMemoOrganizer(ctx, &store.MemoOrganizer{ + MemoID: memo.ID, + UserID: user.ID, + Pinned: false, + }) + require.NoError(t, err) + require.NotNil(t, memoOrganizerTemp) + require.Equal(t, memo.ID, memoOrganizerTemp.MemoID) + require.Equal(t, user.ID, memoOrganizerTemp.UserID) + require.Equal(t, false, memoOrganizerTemp.Pinned) + err = ts.DeleteMemoOrganizer(ctx, &store.DeleteMemoOrganizer{ + MemoID: &memo.ID, + UserID: &user.ID, + }) + require.NoError(t, err) + memoOrganizers, err := ts.ListMemoOrganizer(ctx, &store.FindMemoOrganizer{ + UserID: user.ID, + }) + require.NoError(t, err) + require.Equal(t, 0, len(memoOrganizers)) + ts.Close() +} diff --git a/test/store/memo_relation_test.go b/test/store/memo_relation_test.go index 55b189dcfd616..bf825608bf96f 100644 --- a/test/store/memo_relation_test.go +++ b/test/store/memo_relation_test.go @@ -15,25 +15,28 @@ func TestMemoRelationStore(t *testing.T) { user, err := createTestingHostUser(ctx, ts) require.NoError(t, err) memoCreate := &store.Memo{ - CreatorID: user.ID, - Content: "main memo content", - Visibility: store.Public, + ResourceName: "main-memo", + CreatorID: user.ID, + Content: "main memo content", + Visibility: store.Public, } memo, err := ts.CreateMemo(ctx, memoCreate) require.NoError(t, err) require.Equal(t, memoCreate.Content, memo.Content) relatedMemoCreate := &store.Memo{ - CreatorID: user.ID, - Content: "related memo content", - Visibility: store.Public, + ResourceName: "related-memo", + CreatorID: user.ID, + Content: "related memo content", + Visibility: store.Public, } relatedMemo, err := ts.CreateMemo(ctx, relatedMemoCreate) require.NoError(t, err) require.Equal(t, relatedMemoCreate.Content, relatedMemo.Content) commentMemoCreate := &store.Memo{ - CreatorID: user.ID, - Content: "comment memo content", - Visibility: store.Public, + ResourceName: "comment-memo", + CreatorID: user.ID, + Content: "comment memo content", + Visibility: store.Public, } commentMemo, err := ts.CreateMemo(ctx, commentMemoCreate) require.NoError(t, err) @@ -55,37 +58,5 @@ func TestMemoRelationStore(t *testing.T) { } _, err = ts.UpsertMemoRelation(ctx, commentRelation) require.NoError(t, err) - - memo, err = ts.GetMemo(ctx, &store.FindMemo{ - ID: &memo.ID, - }) - require.NoError(t, err) - require.Equal(t, 2, len(memo.RelationList)) - require.Equal(t, referenceRelation, memo.RelationList[0]) - require.Equal(t, commentRelation, memo.RelationList[1]) - relatedMemo, err = ts.GetMemo(ctx, &store.FindMemo{ - ID: &relatedMemo.ID, - }) - require.NoError(t, err) - require.Equal(t, 1, len(relatedMemo.RelationList)) - require.Equal(t, referenceRelation, relatedMemo.RelationList[0]) - commentMemo, err = ts.GetMemo(ctx, &store.FindMemo{ - ID: &commentMemo.ID, - }) - require.NoError(t, err) - require.Equal(t, 1, len(commentMemo.RelationList)) - require.Equal(t, commentRelation, commentMemo.RelationList[0]) - err = ts.DeleteMemo(ctx, &store.DeleteMemo{ - ID: relatedMemo.ID, - }) - require.NoError(t, err) - err = ts.DeleteMemo(ctx, &store.DeleteMemo{ - ID: commentMemo.ID, - }) - require.NoError(t, err) - memoRelation, err := ts.ListMemoRelations(ctx, &store.FindMemoRelation{ - MemoID: &memo.ID, - }) - require.NoError(t, err) - require.Equal(t, 0, len(memoRelation)) + ts.Close() } diff --git a/test/store/memo_test.go b/test/store/memo_test.go index 95931b639df26..c9a929ba66ec6 100644 --- a/test/store/memo_test.go +++ b/test/store/memo_test.go @@ -15,9 +15,10 @@ func TestMemoStore(t *testing.T) { user, err := createTestingHostUser(ctx, ts) require.NoError(t, err) memoCreate := &store.Memo{ - CreatorID: user.ID, - Content: "test_content", - Visibility: store.Public, + ResourceName: "test-resource-name", + CreatorID: user.ID, + Content: "test_content", + Visibility: store.Public, } memo, err := ts.CreateMemo(ctx, memoCreate) require.NoError(t, err) @@ -49,4 +50,35 @@ func TestMemoStore(t *testing.T) { }) require.NoError(t, err) require.Equal(t, 0, len(memoList)) + + memoList, err = ts.ListMemos(ctx, &store.FindMemo{ + CreatorID: &user.ID, + VisibilityList: []store.Visibility{ + store.Public, + }, + }) + require.NoError(t, err) + require.Equal(t, 0, len(memoList)) + ts.Close() +} + +func TestDeleteMemoStore(t *testing.T) { + ctx := context.Background() + ts := NewTestingStore(ctx, t) + user, err := createTestingHostUser(ctx, ts) + require.NoError(t, err) + memoCreate := &store.Memo{ + ResourceName: "test-resource-name", + CreatorID: user.ID, + Content: "test_content", + Visibility: store.Public, + } + memo, err := ts.CreateMemo(ctx, memoCreate) + require.NoError(t, err) + require.Equal(t, memoCreate.Content, memo.Content) + err = ts.DeleteMemo(ctx, &store.DeleteMemo{ + ID: memo.ID, + }) + require.NoError(t, err) + ts.Close() } diff --git a/test/store/reaction_test.go b/test/store/reaction_test.go new file mode 100644 index 0000000000000..3e3b1e2f59586 --- /dev/null +++ b/test/store/reaction_test.go @@ -0,0 +1,49 @@ +package teststore + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func TestReactionStore(t *testing.T) { + ctx := context.Background() + ts := NewTestingStore(ctx, t) + + user, err := createTestingHostUser(ctx, ts) + require.NoError(t, err) + + contentID := "test_content_id" + reaction, err := ts.UpsertReaction(ctx, &storepb.Reaction{ + CreatorId: user.ID, + ContentId: contentID, + ReactionType: storepb.Reaction_HEART, + }) + require.NoError(t, err) + require.NotNil(t, reaction) + require.NotEmpty(t, reaction.Id) + + reactions, err := ts.ListReactions(ctx, &store.FindReaction{ + ContentID: &contentID, + }) + require.NoError(t, err) + require.Len(t, reactions, 1) + require.Equal(t, reaction, reactions[0]) + + err = ts.DeleteReaction(ctx, &store.DeleteReaction{ + ID: reaction.Id, + }) + require.NoError(t, err) + + reactions, err = ts.ListReactions(ctx, &store.FindReaction{ + ContentID: &contentID, + }) + require.NoError(t, err) + require.Len(t, reactions, 0) + + ts.Close() +} diff --git a/test/store/resource_test.go b/test/store/resource_test.go index 11f12903b274a..90d66490a5c6e 100644 --- a/test/store/resource_test.go +++ b/test/store/resource_test.go @@ -4,6 +4,7 @@ import ( "context" "testing" + "github.com/lithammer/shortuuid/v4" "github.com/stretchr/testify/require" "github.com/usememos/memos/store" @@ -13,6 +14,7 @@ func TestResourceStore(t *testing.T) { ctx := context.Background() ts := NewTestingStore(ctx, t) _, err := ts.CreateResource(ctx, &store.Resource{ + ResourceName: shortuuid.New(), CreatorID: 101, Filename: "test.epub", Blob: []byte("test"), @@ -59,4 +61,5 @@ func TestResourceStore(t *testing.T) { ID: 2, }) require.NoError(t, err) + ts.Close() } diff --git a/test/store/storage_test.go b/test/store/storage_test.go index bb7901c55d006..0f75d6244b71d 100644 --- a/test/store/storage_test.go +++ b/test/store/storage_test.go @@ -36,4 +36,5 @@ func TestStorageStore(t *testing.T) { storageList, err = ts.ListStorages(ctx, &store.FindStorage{}) require.NoError(t, err) require.Equal(t, 0, len(storageList)) + ts.Close() } diff --git a/test/store/store.go b/test/store/store.go index 46ecaebd1a48f..ab642574f4a19 100644 --- a/test/store/store.go +++ b/test/store/store.go @@ -5,11 +5,10 @@ import ( "fmt" "testing" - // mysql driver. - _ "github.com/go-sql-driver/mysql" // sqlite driver. _ "modernc.org/sqlite" + "github.com/usememos/memos/server/profile" "github.com/usememos/memos/store" "github.com/usememos/memos/store/db" "github.com/usememos/memos/test" @@ -21,6 +20,7 @@ func NewTestingStore(ctx context.Context, t *testing.T) *store.Store { if err != nil { fmt.Printf("failed to create db driver, error: %+v\n", err) } + resetTestingDB(ctx, profile, dbDriver) if err := dbDriver.Migrate(ctx); err != nil { fmt.Printf("failed to migrate db, error: %+v\n", err) } @@ -28,3 +28,49 @@ func NewTestingStore(ctx context.Context, t *testing.T) *store.Store { store := store.New(dbDriver, profile) return store } + +func resetTestingDB(ctx context.Context, profile *profile.Profile, dbDriver store.Driver) { + if profile.Driver == "mysql" { + _, err := dbDriver.GetDB().ExecContext(ctx, ` + DROP TABLE IF EXISTS migration_history; + DROP TABLE IF EXISTS system_setting; + DROP TABLE IF EXISTS user; + DROP TABLE IF EXISTS user_setting; + DROP TABLE IF EXISTS memo; + DROP TABLE IF EXISTS memo_organizer; + DROP TABLE IF EXISTS memo_relation; + DROP TABLE IF EXISTS resource; + DROP TABLE IF EXISTS tag; + DROP TABLE IF EXISTS activity; + DROP TABLE IF EXISTS storage; + DROP TABLE IF EXISTS idp; + DROP TABLE IF EXISTS inbox; + DROP TABLE IF EXISTS webhook; + DROP TABLE IF EXISTS reaction;`) + if err != nil { + fmt.Printf("failed to reset testing db, error: %+v\n", err) + panic(err) + } + } else if profile.Driver == "postgres" { + _, err := dbDriver.GetDB().ExecContext(ctx, ` + DROP TABLE IF EXISTS migration_history CASCADE; + DROP TABLE IF EXISTS system_setting CASCADE; + DROP TABLE IF EXISTS "user" CASCADE; + DROP TABLE IF EXISTS user_setting CASCADE; + DROP TABLE IF EXISTS memo CASCADE; + DROP TABLE IF EXISTS memo_organizer CASCADE; + DROP TABLE IF EXISTS memo_relation CASCADE; + DROP TABLE IF EXISTS resource CASCADE; + DROP TABLE IF EXISTS tag CASCADE; + DROP TABLE IF EXISTS activity CASCADE; + DROP TABLE IF EXISTS storage CASCADE; + DROP TABLE IF EXISTS idp CASCADE; + DROP TABLE IF EXISTS inbox CASCADE; + DROP TABLE IF EXISTS webhook CASCADE; + DROP TABLE IF EXISTS reaction CASCADE;`) + if err != nil { + fmt.Printf("failed to reset testing db, error: %+v\n", err) + panic(err) + } + } +} diff --git a/test/store/store_test.go b/test/store/store_test.go deleted file mode 100644 index 47e99ce6949cc..0000000000000 --- a/test/store/store_test.go +++ /dev/null @@ -1 +0,0 @@ -package teststore diff --git a/test/store/system_setting_test.go b/test/store/system_setting_test.go deleted file mode 100644 index def01fa048826..0000000000000 --- a/test/store/system_setting_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package teststore - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - - apiv1 "github.com/usememos/memos/api/v1" - "github.com/usememos/memos/store" -) - -func TestSystemSettingStore(t *testing.T) { - ctx := context.Background() - ts := NewTestingStore(ctx, t) - _, err := ts.UpsertSystemSetting(ctx, &store.SystemSetting{ - Name: apiv1.SystemSettingServerIDName.String(), - Value: "test_server_id", - }) - require.NoError(t, err) - _, err = ts.UpsertSystemSetting(ctx, &store.SystemSetting{ - Name: apiv1.SystemSettingSecretSessionName.String(), - Value: "test_secret_session_name", - }) - require.NoError(t, err) - _, err = ts.UpsertSystemSetting(ctx, &store.SystemSetting{ - Name: apiv1.SystemSettingAllowSignUpName.String(), - Value: "true", - }) - require.NoError(t, err) - _, err = ts.UpsertSystemSetting(ctx, &store.SystemSetting{ - Name: apiv1.SystemSettingLocalStoragePathName.String(), - Value: "/tmp/memos", - }) - require.NoError(t, err) - list, err := ts.ListSystemSettings(ctx, &store.FindSystemSetting{}) - require.NoError(t, err) - require.Equal(t, 4, len(list)) -} diff --git a/test/store/tag_test.go b/test/store/tag_test.go index 0b0624cd08dff..c5eac5c584cd1 100644 --- a/test/store/tag_test.go +++ b/test/store/tag_test.go @@ -35,4 +35,5 @@ func TestTagStore(t *testing.T) { tags, err = ts.ListTags(ctx, &store.FindTag{}) require.NoError(t, err) require.Equal(t, 0, len(tags)) + ts.Close() } diff --git a/test/store/user_setting_test.go b/test/store/user_setting_test.go index c9341def832da..ce7c012e1c39d 100644 --- a/test/store/user_setting_test.go +++ b/test/store/user_setting_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/require" + storepb "github.com/usememos/memos/proto/gen/store" "github.com/usememos/memos/store" ) @@ -14,19 +15,14 @@ func TestUserSettingStore(t *testing.T) { ts := NewTestingStore(ctx, t) user, err := createTestingHostUser(ctx, ts) require.NoError(t, err) - _, err = ts.UpsertUserSetting(ctx, &store.UserSetting{ - UserID: user.ID, - Key: "test_key", - Value: "test_value", - }) - require.NoError(t, err) - _, err = ts.UpsertUserSetting(ctx, &store.UserSetting{ - UserID: user.ID, - Key: "locale", - Value: "zh", + _, err = ts.UpsertUserSetting(ctx, &storepb.UserSetting{ + UserId: user.ID, + Key: storepb.UserSettingKey_USER_SETTING_LOCALE, + Value: &storepb.UserSetting_Locale{Locale: "en"}, }) require.NoError(t, err) list, err := ts.ListUserSettings(ctx, &store.FindUserSetting{}) require.NoError(t, err) - require.Equal(t, 2, len(list)) + require.Equal(t, 1, len(list)) + ts.Close() } diff --git a/test/store/user_test.go b/test/store/user_test.go index 560eea2fd039a..dde7d156dd445 100644 --- a/test/store/user_test.go +++ b/test/store/user_test.go @@ -35,6 +35,7 @@ func TestUserStore(t *testing.T) { users, err = ts.ListUsers(ctx, &store.FindUser{}) require.NoError(t, err) require.Equal(t, 0, len(users)) + ts.Close() } func createTestingHostUser(ctx context.Context, ts *store.Store) (*store.User, error) { diff --git a/test/store/webhook_test.go b/test/store/webhook_test.go new file mode 100644 index 0000000000000..2c9ae5469a8a2 --- /dev/null +++ b/test/store/webhook_test.go @@ -0,0 +1,51 @@ +package teststore + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func TestWebhookStore(t *testing.T) { + ctx := context.Background() + ts := NewTestingStore(ctx, t) + user, err := createTestingHostUser(ctx, ts) + require.NoError(t, err) + webhook, err := ts.CreateWebhook(ctx, &storepb.Webhook{ + CreatorId: user.ID, + Name: "test_webhook", + Url: "https://example.com", + RowStatus: storepb.RowStatus_NORMAL, + }) + require.NoError(t, err) + require.Equal(t, "test_webhook", webhook.Name) + require.Equal(t, user.ID, webhook.CreatorId) + webhooks, err := ts.ListWebhooks(ctx, &store.FindWebhook{ + CreatorID: &user.ID, + }) + require.NoError(t, err) + require.Equal(t, 1, len(webhooks)) + require.Equal(t, webhook, webhooks[0]) + newName := "test_webhook_new" + updatedWebhook, err := ts.UpdateWebhook(ctx, &store.UpdateWebhook{ + ID: webhook.Id, + Name: &newName, + }) + require.NoError(t, err) + require.Equal(t, newName, updatedWebhook.Name) + require.Equal(t, webhook.CreatorId, updatedWebhook.CreatorId) + err = ts.DeleteWebhook(ctx, &store.DeleteWebhook{ + ID: webhook.Id, + }) + require.NoError(t, err) + webhooks, err = ts.ListWebhooks(ctx, &store.FindWebhook{ + CreatorID: &user.ID, + }) + require.NoError(t, err) + require.Equal(t, 0, len(webhooks)) + ts.Close() +} diff --git a/test/store/workspace_setting_test.go b/test/store/workspace_setting_test.go new file mode 100644 index 0000000000000..d791c61d0f12d --- /dev/null +++ b/test/store/workspace_setting_test.go @@ -0,0 +1,30 @@ +package teststore + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" +) + +func TestWorkspaceSettingV1Store(t *testing.T) { + ctx := context.Background() + ts := NewTestingStore(ctx, t) + workspaceSetting, err := ts.UpsertWorkspaceSettingV1(ctx, &storepb.WorkspaceSetting{ + Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_GENERAL, + Value: &storepb.WorkspaceSetting_General{ + General: &storepb.WorkspaceGeneralSetting{ + DisallowSignup: true, + }, + }, + }) + require.NoError(t, err) + list, err := ts.ListWorkspaceSettingsV1(ctx, &store.FindWorkspaceSettingV1{}) + require.NoError(t, err) + require.Equal(t, 1, len(list)) + require.Equal(t, workspaceSetting, list[0]) + ts.Close() +} diff --git a/test/test.go b/test/test.go index 10c37e9ebeb9d..9862fd23b01ce 100644 --- a/test/test.go +++ b/test/test.go @@ -6,6 +6,8 @@ import ( "os" "testing" + "github.com/joho/godotenv" + "github.com/usememos/memos/server/profile" "github.com/usememos/memos/server/version" ) @@ -24,6 +26,10 @@ func getUnusedPort() int { } func GetTestingProfile(t *testing.T) *profile.Profile { + if err := godotenv.Load(".env"); err != nil { + t.Log("failed to load .env file, but it's ok") + } + // Get a temporary directory for the test data. dir := t.TempDir() mode := "dev" @@ -33,7 +39,6 @@ func GetTestingProfile(t *testing.T) *profile.Profile { if driver == "sqlite" { dsn = fmt.Sprintf("%s/memos_%s.db", dir, mode) } - println("dsn", dsn, driver) return &profile.Profile{ Mode: mode, Port: port, diff --git a/web/.env.example b/web/.env.example new file mode 100644 index 0000000000000..0f4e8826df06f --- /dev/null +++ b/web/.env.example @@ -0,0 +1 @@ +VITE_API_BASE_URL=http://localhost:8081 diff --git a/web/.eslintrc.json b/web/.eslintrc.json index 209b39ad0faaf..1e30948d7a47b 100644 --- a/web/.eslintrc.json +++ b/web/.eslintrc.json @@ -13,7 +13,7 @@ "sourceType": "module" }, "plugins": ["react", "@typescript-eslint", "prettier"], - "ignorePatterns": ["node_modules", "dist", "public"], + "ignorePatterns": ["node_modules", "dist", "public", "src/assets"], "rules": { "prettier/prettier": [ "error", diff --git a/web/.gitignore b/web/.gitignore index f4e178b9b5bd0..77f1076b8dbec 100644 --- a/web/.gitignore +++ b/web/.gitignore @@ -1,4 +1,5 @@ node_modules +.pnpm-store .DS_Store dist dist-ssr diff --git a/web/.vscode/extensions.json b/web/.vscode/extensions.json deleted file mode 100644 index 809e8c8fac15d..0000000000000 --- a/web/.vscode/extensions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "recommendations": [ - "lokalise.i18n-ally", - "bradlc.vscode-tailwindcss", - "dbaeumer.vscode-eslint", - "csstools.postcss" - ] -} diff --git a/web/.vscode/settings.json b/web/.vscode/settings.json deleted file mode 100644 index cba5eb29a6299..0000000000000 --- a/web/.vscode/settings.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"], - "editor.codeActionsOnSave": { - "source.fixAll.eslint": true - }, - "i18n-ally.localesPaths": [ - "src/locales" - ], - "files.associations": { - "*.less": "postcss" - }, - "i18n-ally.keystyle": "nested" -} diff --git a/web/README.md b/web/README.md index 89ddc3ee97fad..bb1b934aad79b 100644 --- a/web/README.md +++ b/web/README.md @@ -1 +1 @@ -# memos web +# The frontend of Memos diff --git a/web/index.html b/web/index.html index 234ef154c2f22..2bbab70e75ebd 100644 --- a/web/index.html +++ b/web/index.html @@ -1,24 +1,26 @@ - + - + + + - + - - memos + + Memos +
- + diff --git a/web/package.json b/web/package.json index 7efa7d023a5cb..c67f5e77dd3ad 100644 --- a/web/package.json +++ b/web/package.json @@ -4,68 +4,69 @@ "dev": "vite", "build": "tsc && vite build", "lint": "eslint --ext .js,.ts,.tsx, src", - "lint-fix": "eslint --ext .js,.ts,.tsx, src --fix", - "type-gen": "cd ../proto && buf generate", - "type-check": "tsc" + "type-check": "tsc", + "postinstall": "cd ../proto && buf generate" }, "packageManager": "pnpm@8.7.0", "dependencies": { - "@emotion/react": "^11.11.1", + "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.0", "@matejmazur/react-katex": "^3.1.3", - "@mui/joy": "5.0.0-beta.12", + "@mui/joy": "5.0.0-beta.30", "@reduxjs/toolkit": "^1.9.7", - "@tailwindcss/container-queries": "^0.1.1", - "axios": "^0.27.2", - "classnames": "^2.3.2", + "axios": "^1.6.7", + "classnames": "^2.5.1", "copy-to-clipboard": "^3.3.3", + "fuse.js": "^7.0.0", "highlight.js": "^11.9.0", "i18next": "^21.10.0", - "i18next-browser-languagedetector": "^7.1.0", "katex": "^0.16.9", "lodash-es": "^4.17.21", - "long": "^5.2.3", - "lucide-react": "^0.263.1", - "nice-grpc-web": "^3.3.2", - "protobufjs": "^7.2.5", + "lucide-react": "^0.309.0", + "mermaid": "^10.9.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-hot-toast": "^2.4.1", "react-i18next": "^11.18.6", "react-redux": "^8.1.3", - "react-router-dom": "^6.17.0", - "react-use": "^17.4.0", - "semver": "^7.5.4", - "tailwindcss": "^3.3.5", + "react-router-dom": "^6.22.2", + "react-use": "^17.5.0", + "tailwindcss": "^3.4.1", "textarea-caret": "^3.1.0", "uuid": "^9.0.1", - "zustand": "^4.4.4" + "zustand": "^4.5.2" }, "devDependencies": { - "@bufbuild/buf": "^1.27.2", - "@trivago/prettier-plugin-sort-imports": "^3.4.0", - "@types/katex": "^0.16.5", - "@types/lodash-es": "^4.17.10", - "@types/node": "^18.18.7", - "@types/qs": "^6.9.9", - "@types/react": "^18.2.33", - "@types/react-dom": "^18.2.14", - "@types/semver": "^7.5.4", - "@types/textarea-caret": "^3.0.2", - "@types/uuid": "^9.0.6", - "@typescript-eslint/eslint-plugin": "^6.9.0", - "@typescript-eslint/parser": "^6.9.0", - "@vitejs/plugin-react-swc": "^3.4.0", - "autoprefixer": "^10.4.16", - "eslint": "^8.52.0", + "@bufbuild/buf": "^1.29.0", + "@trivago/prettier-plugin-sort-imports": "^4.3.0", + "@types/d3": "^7.4.3", + "@types/dompurify": "^3.0.5", + "@types/katex": "^0.16.7", + "@types/lodash-es": "^4.17.12", + "@types/node": "^20.11.24", + "@types/qs": "^6.9.12", + "@types/react": "^18.2.63", + "@types/react-dom": "^18.2.20", + "@types/textarea-caret": "^3.0.3", + "@types/uuid": "^9.0.8", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", + "@vitejs/plugin-react": "^4.2.1", + "autoprefixer": "^10.4.18", + "eslint": "^8.57.0", "eslint-config-prettier": "^8.10.0", - "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-react": "^7.33.2", + "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-react": "^7.34.0", "less": "^4.2.0", - "postcss": "^8.4.31", - "prettier": "2.6.2", - "terser": "^5.22.0", - "typescript": "^5.2.2", - "vite": "^4.5.0" + "long": "^5.2.3", + "nice-grpc-web": "^3.3.2", + "postcss": "^8.4.35", + "prettier": "^3.2.5", + "protobufjs": "^7.2.6", + "typescript": "^5.3.3", + "vite": "^5.1.5" + }, + "resolutions": { + "csstype": "3.1.2" } } diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 7ac1394794f22..bf45dc0632ed7 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -4,61 +4,55 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + csstype: 3.1.2 + dependencies: '@emotion/react': - specifier: ^11.11.1 - version: 11.11.1(@types/react@18.2.33)(react@18.2.0) + specifier: ^11.11.4 + version: 11.11.4(@types/react@18.2.63)(react@18.2.0) '@emotion/styled': specifier: ^11.11.0 - version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react@18.2.0) + version: 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.63)(react@18.2.0) '@matejmazur/react-katex': specifier: ^3.1.3 version: 3.1.3(katex@0.16.9)(react@18.2.0) '@mui/joy': - specifier: 5.0.0-beta.12 - version: 5.0.0-beta.12(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0) + specifier: 5.0.0-beta.30 + version: 5.0.0-beta.30(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0) '@reduxjs/toolkit': specifier: ^1.9.7 version: 1.9.7(react-redux@8.1.3)(react@18.2.0) - '@tailwindcss/container-queries': - specifier: ^0.1.1 - version: 0.1.1(tailwindcss@3.3.5) axios: - specifier: ^0.27.2 - version: 0.27.2 + specifier: ^1.6.7 + version: 1.6.7 classnames: - specifier: ^2.3.2 - version: 2.3.2 + specifier: ^2.5.1 + version: 2.5.1 copy-to-clipboard: specifier: ^3.3.3 version: 3.3.3 + fuse.js: + specifier: ^7.0.0 + version: 7.0.0 highlight.js: specifier: ^11.9.0 version: 11.9.0 i18next: specifier: ^21.10.0 version: 21.10.0 - i18next-browser-languagedetector: - specifier: ^7.1.0 - version: 7.1.0 katex: specifier: ^0.16.9 version: 0.16.9 lodash-es: specifier: ^4.17.21 version: 4.17.21 - long: - specifier: ^5.2.3 - version: 5.2.3 lucide-react: - specifier: ^0.263.1 - version: 0.263.1(react@18.2.0) - nice-grpc-web: - specifier: ^3.3.2 - version: 3.3.2(ws@8.14.2) - protobufjs: - specifier: ^7.2.5 - version: 7.2.5 + specifier: ^0.309.0 + version: 0.309.0(react@18.2.0) + mermaid: + specifier: ^10.9.0 + version: 10.9.0 react: specifier: ^18.2.0 version: 18.2.0 @@ -73,19 +67,16 @@ dependencies: version: 11.18.6(i18next@21.10.0)(react-dom@18.2.0)(react@18.2.0) react-redux: specifier: ^8.1.3 - version: 8.1.3(@types/react-dom@18.2.14)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) + version: 8.1.3(@types/react-dom@18.2.20)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) react-router-dom: - specifier: ^6.17.0 - version: 6.17.0(react-dom@18.2.0)(react@18.2.0) + specifier: ^6.22.2 + version: 6.22.2(react-dom@18.2.0)(react@18.2.0) react-use: - specifier: ^17.4.0 - version: 17.4.0(react-dom@18.2.0)(react@18.2.0) - semver: - specifier: ^7.5.4 - version: 7.5.4 + specifier: ^17.5.0 + version: 17.5.0(react-dom@18.2.0)(react@18.2.0) tailwindcss: - specifier: ^3.3.5 - version: 3.3.5 + specifier: ^3.4.1 + version: 3.4.1 textarea-caret: specifier: ^3.1.0 version: 3.1.0 @@ -93,85 +84,94 @@ dependencies: specifier: ^9.0.1 version: 9.0.1 zustand: - specifier: ^4.4.4 - version: 4.4.4(@types/react@18.2.33)(react@18.2.0) + specifier: ^4.5.2 + version: 4.5.2(@types/react@18.2.63)(react@18.2.0) devDependencies: '@bufbuild/buf': - specifier: ^1.27.2 - version: 1.27.2 + specifier: ^1.29.0 + version: 1.29.0 '@trivago/prettier-plugin-sort-imports': - specifier: ^3.4.0 - version: 3.4.0(prettier@2.6.2) + specifier: ^4.3.0 + version: 4.3.0(prettier@3.2.5) + '@types/d3': + specifier: ^7.4.3 + version: 7.4.3 + '@types/dompurify': + specifier: ^3.0.5 + version: 3.0.5 '@types/katex': - specifier: ^0.16.5 - version: 0.16.5 + specifier: ^0.16.7 + version: 0.16.7 '@types/lodash-es': - specifier: ^4.17.10 - version: 4.17.10 + specifier: ^4.17.12 + version: 4.17.12 '@types/node': - specifier: ^18.18.7 - version: 18.18.7 + specifier: ^20.11.24 + version: 20.11.24 '@types/qs': - specifier: ^6.9.9 - version: 6.9.9 + specifier: ^6.9.12 + version: 6.9.12 '@types/react': - specifier: ^18.2.33 - version: 18.2.33 + specifier: ^18.2.63 + version: 18.2.63 '@types/react-dom': - specifier: ^18.2.14 - version: 18.2.14 - '@types/semver': - specifier: ^7.5.4 - version: 7.5.4 + specifier: ^18.2.20 + version: 18.2.20 '@types/textarea-caret': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.3 + version: 3.0.3 '@types/uuid': - specifier: ^9.0.6 - version: 9.0.6 + specifier: ^9.0.8 + version: 9.0.8 '@typescript-eslint/eslint-plugin': - specifier: ^6.9.0 - version: 6.9.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2) + specifier: ^6.21.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.57.0)(typescript@5.3.3) '@typescript-eslint/parser': - specifier: ^6.9.0 - version: 6.9.0(eslint@8.52.0)(typescript@5.2.2) - '@vitejs/plugin-react-swc': - specifier: ^3.4.0 - version: 3.4.0(vite@4.5.0) + specifier: ^6.21.0 + version: 6.21.0(eslint@8.57.0)(typescript@5.3.3) + '@vitejs/plugin-react': + specifier: ^4.2.1 + version: 4.2.1(vite@5.1.5) autoprefixer: - specifier: ^10.4.16 - version: 10.4.16(postcss@8.4.31) + specifier: ^10.4.18 + version: 10.4.18(postcss@8.4.35) eslint: - specifier: ^8.52.0 - version: 8.52.0 + specifier: ^8.57.0 + version: 8.57.0 eslint-config-prettier: specifier: ^8.10.0 - version: 8.10.0(eslint@8.52.0) + version: 8.10.0(eslint@8.57.0) eslint-plugin-prettier: - specifier: ^4.2.1 - version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.52.0)(prettier@2.6.2) + specifier: ^5.1.3 + version: 5.1.3(eslint-config-prettier@8.10.0)(eslint@8.57.0)(prettier@3.2.5) eslint-plugin-react: - specifier: ^7.33.2 - version: 7.33.2(eslint@8.52.0) + specifier: ^7.34.0 + version: 7.34.0(eslint@8.57.0) less: specifier: ^4.2.0 version: 4.2.0 + long: + specifier: ^5.2.3 + version: 5.2.3 + nice-grpc-web: + specifier: ^3.3.2 + version: 3.3.2(ws@8.16.0) postcss: - specifier: ^8.4.31 - version: 8.4.31 + specifier: ^8.4.35 + version: 8.4.35 prettier: - specifier: 2.6.2 - version: 2.6.2 - terser: - specifier: ^5.22.0 - version: 5.22.0 + specifier: ^3.2.5 + version: 3.2.5 + protobufjs: + specifier: ^7.2.6 + version: 7.2.6 typescript: - specifier: ^5.2.2 - version: 5.2.2 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.5.0 - version: 4.5.0(@types/node@18.18.7)(less@4.2.0)(terser@5.22.0) + specifier: ^5.1.5 + version: 5.1.5(@types/node@20.11.24)(less@4.2.0) packages: @@ -185,41 +185,41 @@ packages: engines: {node: '>=10'} dev: false - /@ampproject/remapping@2.2.1: - resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.20 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 dev: true - /@babel/code-frame@7.22.13: - resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} + /@babel/code-frame@7.23.5: + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/highlight': 7.22.20 + '@babel/highlight': 7.23.4 chalk: 2.4.2 - /@babel/compat-data@7.23.2: - resolution: {integrity: sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==} + /@babel/compat-data@7.23.5: + resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} engines: {node: '>=6.9.0'} dev: true - /@babel/core@7.17.8: - resolution: {integrity: sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ==} + /@babel/core@7.24.0: + resolution: {integrity: sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==} engines: {node: '>=6.9.0'} dependencies: - '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.22.13 - '@babel/generator': 7.17.7 - '@babel/helper-compilation-targets': 7.22.15 - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.17.8) - '@babel/helpers': 7.23.2 - '@babel/parser': 7.18.9 - '@babel/template': 7.22.15 - '@babel/traverse': 7.17.3 - '@babel/types': 7.17.0 - convert-source-map: 1.9.0 + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) + '@babel/helpers': 7.24.0 + '@babel/parser': 7.24.0 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.0 + '@babel/types': 7.24.0 + convert-source-map: 2.0.0 debug: 4.3.4 gensync: 1.0.0-beta.2 json5: 2.2.3 @@ -237,23 +237,23 @@ packages: source-map: 0.5.7 dev: true - /@babel/generator@7.23.0: - resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} + /@babel/generator@7.23.6: + resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.20 + '@babel/types': 7.24.0 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 dev: true - /@babel/helper-compilation-targets@7.22.15: - resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} + /@babel/helper-compilation-targets@7.23.6: + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/compat-data': 7.23.2 - '@babel/helper-validator-option': 7.22.15 - browserslist: 4.22.1 + '@babel/compat-data': 7.23.5 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.23.0 lru-cache: 5.1.1 semver: 6.3.1 dev: true @@ -267,30 +267,30 @@ packages: resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.22.15 - '@babel/types': 7.23.0 + '@babel/template': 7.24.0 + '@babel/types': 7.24.0 dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 dev: true /@babel/helper-module-imports@7.22.15: resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 - /@babel/helper-module-transforms@7.23.0(@babel/core@7.17.8): - resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==} + /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.0): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.17.8 + '@babel/core': 7.24.0 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-module-imports': 7.22.15 '@babel/helper-simple-access': 7.22.5 @@ -298,114 +298,131 @@ packages: '@babel/helper-validator-identifier': 7.22.20 dev: true + /@babel/helper-plugin-utils@7.24.0: + resolution: {integrity: sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-simple-access@7.22.5: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 dev: true /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 dev: true - /@babel/helper-string-parser@7.22.5: - resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + /@babel/helper-string-parser@7.23.4: + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} engines: {node: '>=6.9.0'} /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} - /@babel/helper-validator-option@7.22.15: - resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==} + /@babel/helper-validator-option@7.23.5: + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} dev: true - /@babel/helpers@7.23.2: - resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==} + /@babel/helpers@7.24.0: + resolution: {integrity: sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.22.15 - '@babel/traverse': 7.23.2 - '@babel/types': 7.23.0 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.0 + '@babel/types': 7.24.0 transitivePeerDependencies: - supports-color dev: true - /@babel/highlight@7.22.20: - resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} + /@babel/highlight@7.23.4: + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 - /@babel/parser@7.18.9: - resolution: {integrity: sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==} + /@babel/parser@7.24.0: + resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==} engines: {node: '>=6.0.0'} hasBin: true dependencies: '@babel/types': 7.17.0 dev: true - /@babel/parser@7.23.0: - resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} - engines: {node: '>=6.0.0'} - hasBin: true + /@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.24.0): + resolution: {integrity: sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - '@babel/types': 7.17.0 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/runtime@7.23.2: - resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} + /@babel/plugin-transform-react-jsx-source@7.23.3(@babel/core@7.24.0): + resolution: {integrity: sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 dependencies: - regenerator-runtime: 0.14.0 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/runtime@7.24.0: + resolution: {integrity: sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 dev: false - /@babel/template@7.22.15: - resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + /@babel/template@7.24.0: + resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.13 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/code-frame': 7.23.5 + '@babel/parser': 7.24.0 + '@babel/types': 7.24.0 dev: true - /@babel/traverse@7.17.3: - resolution: {integrity: sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==} + /@babel/traverse@7.23.2: + resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.13 - '@babel/generator': 7.17.7 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.18.9 - '@babel/types': 7.17.0 + '@babel/parser': 7.24.0 + '@babel/types': 7.24.0 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true - /@babel/traverse@7.23.2: - resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} + /@babel/traverse@7.24.0: + resolution: {integrity: sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.13 - '@babel/generator': 7.23.0 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/parser': 7.24.0 + '@babel/types': 7.24.0 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: @@ -420,16 +437,20 @@ packages: to-fast-properties: 2.0.0 dev: true - /@babel/types@7.23.0: - resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} + /@babel/types@7.24.0: + resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-string-parser': 7.22.5 + '@babel/helper-string-parser': 7.23.4 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 - /@bufbuild/buf-darwin-arm64@1.27.2: - resolution: {integrity: sha512-ob1IAhFVsAVUr5o4EAwoeQ6FOGJdiS6eYGTGQiZzJEAYSs2dX/WQ9+Xz9EPQUb93n7PMjNs38DLDfwGQ3u3dsg==} + /@braintree/sanitize-url@6.0.4: + resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==} + dev: false + + /@bufbuild/buf-darwin-arm64@1.29.0: + resolution: {integrity: sha512-5hKxsARoY2WpWq1n5ONFqqGuauHb4yILKXCy37KRYCKiRLWmIP5yI3gWvWHKoH7sUJWTQmBqdJoCvYQr6ahQnw==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -437,8 +458,8 @@ packages: dev: true optional: true - /@bufbuild/buf-darwin-x64@1.27.2: - resolution: {integrity: sha512-Kp0HBvLjeOxJtZ/j3vOulX6G3u5pa9vksVmJ5HGjhL0BZJwavh8Bd9YgrBDrTzKtTQMHxmhTSaNEgNUWkjecfw==} + /@bufbuild/buf-darwin-x64@1.29.0: + resolution: {integrity: sha512-wOAPxbPLBns4AHiComWtdO1sx1J1p6mDYTbqmloHuI+B5U2rDbMsoHoe4nBcoMF8+RHxoqjypha29wVo6yzbZg==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -446,8 +467,8 @@ packages: dev: true optional: true - /@bufbuild/buf-linux-aarch64@1.27.2: - resolution: {integrity: sha512-rq+bpT+FMR1iiUvcHno1SPS4e0Ydr+F7ArIzN5cO4DKL09sBJXcaVGa7fRRlBZvNJTt3XRVtlE8LNLGH7zjBOg==} + /@bufbuild/buf-linux-aarch64@1.29.0: + resolution: {integrity: sha512-jLk2J/wyyM7KNJ/DkLfhy3eS2/Bdb70e/56adMkapSoLJmghnpgxW+oFznMxxQUX5I9BU5hTn1UhDFxgLwhP7g==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -455,8 +476,8 @@ packages: dev: true optional: true - /@bufbuild/buf-linux-x64@1.27.2: - resolution: {integrity: sha512-t/lcJ06gELy+4hVROuoeX8Y+oXq9NrPX+UgT5WujGo21oOb8UAQETZLRefj2U4IRqYqXhTKicfOI2y8xI7CSlQ==} + /@bufbuild/buf-linux-x64@1.29.0: + resolution: {integrity: sha512-heLOywj3Oaoh69RnTx7tHsuz6rEnvz77bghLEOghsrjBR6Jcpcwc137EZR4kRTIWJNrE8Kmo3RVeXlv144qQIQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -464,8 +485,8 @@ packages: dev: true optional: true - /@bufbuild/buf-win32-arm64@1.27.2: - resolution: {integrity: sha512-rJieGmtSw4tfteW6mhjdtDDTFBbl2HBan1FnfNAOZH4ZrTwfcOO5Vn3fUMl+jPtiCpTscyzVaYHI+LvYffSdvg==} + /@bufbuild/buf-win32-arm64@1.29.0: + resolution: {integrity: sha512-Eglyvr3PLqVucuHBcQ61conyBgH9BRaoLpKWcce1gYBVlxMQM1NxjVjGOWihxQ1dXXw5qZXmYfVODf3gSwPMuQ==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -473,8 +494,8 @@ packages: dev: true optional: true - /@bufbuild/buf-win32-x64@1.27.2: - resolution: {integrity: sha512-x9IKCHgj6GmDGH2xlTo80l2feNU3hUeoEwLFLH4I5Qs2L1gfYIDMZGp+0Bhm5eK9CIWYtkJqeqGRIJkrJA6CfQ==} + /@bufbuild/buf-win32-x64@1.29.0: + resolution: {integrity: sha512-wRk6co+nqHqEq4iLolXgej0jUVlWlTtGHjKaq54lTbKZrwxrBgql6qS06abgNPRASX0++XT9m3QRZ97qEIC/HQ==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -482,28 +503,28 @@ packages: dev: true optional: true - /@bufbuild/buf@1.27.2: - resolution: {integrity: sha512-hwZYF0DCxvmTAZIAeT/q66HYtIxnSH9jn/CVElaJA/l+Clr9zhLdfKFd1yD2lMqHpNUEeXtA8T0ABXv29NVfYQ==} + /@bufbuild/buf@1.29.0: + resolution: {integrity: sha512-euksXeFtvlvAV5j94LqXb69qQcJvFfo8vN1d3cx+IzhOKoipykuQQTq7mOWVo2R0kdk6yIMBLBofOYOsh0Df8g==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@bufbuild/buf-darwin-arm64': 1.27.2 - '@bufbuild/buf-darwin-x64': 1.27.2 - '@bufbuild/buf-linux-aarch64': 1.27.2 - '@bufbuild/buf-linux-x64': 1.27.2 - '@bufbuild/buf-win32-arm64': 1.27.2 - '@bufbuild/buf-win32-x64': 1.27.2 + '@bufbuild/buf-darwin-arm64': 1.29.0 + '@bufbuild/buf-darwin-x64': 1.29.0 + '@bufbuild/buf-linux-aarch64': 1.29.0 + '@bufbuild/buf-linux-x64': 1.29.0 + '@bufbuild/buf-win32-arm64': 1.29.0 + '@bufbuild/buf-win32-x64': 1.29.0 dev: true /@emotion/babel-plugin@11.11.0: resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==} dependencies: '@babel/helper-module-imports': 7.22.15 - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 '@emotion/hash': 0.9.1 '@emotion/memoize': 0.8.1 - '@emotion/serialize': 1.1.2 + '@emotion/serialize': 1.1.3 babel-plugin-macros: 3.1.0 convert-source-map: 1.9.0 escape-string-regexp: 4.0.0 @@ -526,8 +547,8 @@ packages: resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} dev: false - /@emotion/is-prop-valid@1.2.1: - resolution: {integrity: sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==} + /@emotion/is-prop-valid@1.2.2: + resolution: {integrity: sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==} dependencies: '@emotion/memoize': 0.8.1 dev: false @@ -536,8 +557,8 @@ packages: resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} dev: false - /@emotion/react@11.11.1(@types/react@18.2.33)(react@18.2.0): - resolution: {integrity: sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==} + /@emotion/react@11.11.4(@types/react@18.2.63)(react@18.2.0): + resolution: {integrity: sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==} peerDependencies: '@types/react': '*' react: '>=16.8.0' @@ -545,20 +566,20 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 '@emotion/babel-plugin': 11.11.0 '@emotion/cache': 11.11.0 - '@emotion/serialize': 1.1.2 + '@emotion/serialize': 1.1.3 '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 '@emotion/weak-memoize': 0.3.1 - '@types/react': 18.2.33 + '@types/react': 18.2.63 hoist-non-react-statics: 3.3.2 react: 18.2.0 dev: false - /@emotion/serialize@1.1.2: - resolution: {integrity: sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==} + /@emotion/serialize@1.1.3: + resolution: {integrity: sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==} dependencies: '@emotion/hash': 0.9.1 '@emotion/memoize': 0.8.1 @@ -571,7 +592,7 @@ packages: resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} dev: false - /@emotion/styled@11.11.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react@18.2.0): + /@emotion/styled@11.11.0(@emotion/react@11.11.4)(@types/react@18.2.63)(react@18.2.0): resolution: {integrity: sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==} peerDependencies: '@emotion/react': ^11.0.0-rc.0 @@ -581,14 +602,14 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 '@emotion/babel-plugin': 11.11.0 - '@emotion/is-prop-valid': 1.2.1 - '@emotion/react': 11.11.1(@types/react@18.2.33)(react@18.2.0) - '@emotion/serialize': 1.1.2 + '@emotion/is-prop-valid': 1.2.2 + '@emotion/react': 11.11.4(@types/react@18.2.63)(react@18.2.0) + '@emotion/serialize': 1.1.3 '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 - '@types/react': 18.2.33 + '@types/react': 18.2.63 react: 18.2.0 dev: false @@ -612,8 +633,17 @@ packages: resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==} dev: false - /@esbuild/android-arm64@0.18.20: - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + /@esbuild/aix-ppc64@0.19.12: + resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.19.12: + resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -621,8 +651,8 @@ packages: dev: true optional: true - /@esbuild/android-arm@0.18.20: - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + /@esbuild/android-arm@0.19.12: + resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -630,8 +660,8 @@ packages: dev: true optional: true - /@esbuild/android-x64@0.18.20: - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + /@esbuild/android-x64@0.19.12: + resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -639,8 +669,8 @@ packages: dev: true optional: true - /@esbuild/darwin-arm64@0.18.20: - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + /@esbuild/darwin-arm64@0.19.12: + resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -648,8 +678,8 @@ packages: dev: true optional: true - /@esbuild/darwin-x64@0.18.20: - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + /@esbuild/darwin-x64@0.19.12: + resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -657,8 +687,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-arm64@0.18.20: - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + /@esbuild/freebsd-arm64@0.19.12: + resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -666,8 +696,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-x64@0.18.20: - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + /@esbuild/freebsd-x64@0.19.12: + resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -675,8 +705,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm64@0.18.20: - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + /@esbuild/linux-arm64@0.19.12: + resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -684,8 +714,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm@0.18.20: - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + /@esbuild/linux-arm@0.19.12: + resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -693,8 +723,8 @@ packages: dev: true optional: true - /@esbuild/linux-ia32@0.18.20: - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + /@esbuild/linux-ia32@0.19.12: + resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -702,8 +732,8 @@ packages: dev: true optional: true - /@esbuild/linux-loong64@0.18.20: - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + /@esbuild/linux-loong64@0.19.12: + resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -711,8 +741,8 @@ packages: dev: true optional: true - /@esbuild/linux-mips64el@0.18.20: - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + /@esbuild/linux-mips64el@0.19.12: + resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -720,8 +750,8 @@ packages: dev: true optional: true - /@esbuild/linux-ppc64@0.18.20: - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + /@esbuild/linux-ppc64@0.19.12: + resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -729,8 +759,8 @@ packages: dev: true optional: true - /@esbuild/linux-riscv64@0.18.20: - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + /@esbuild/linux-riscv64@0.19.12: + resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -738,8 +768,8 @@ packages: dev: true optional: true - /@esbuild/linux-s390x@0.18.20: - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + /@esbuild/linux-s390x@0.19.12: + resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -747,8 +777,8 @@ packages: dev: true optional: true - /@esbuild/linux-x64@0.18.20: - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + /@esbuild/linux-x64@0.19.12: + resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -756,8 +786,8 @@ packages: dev: true optional: true - /@esbuild/netbsd-x64@0.18.20: - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + /@esbuild/netbsd-x64@0.19.12: + resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -765,8 +795,8 @@ packages: dev: true optional: true - /@esbuild/openbsd-x64@0.18.20: - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + /@esbuild/openbsd-x64@0.19.12: + resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -774,8 +804,8 @@ packages: dev: true optional: true - /@esbuild/sunos-x64@0.18.20: - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + /@esbuild/sunos-x64@0.19.12: + resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -783,8 +813,8 @@ packages: dev: true optional: true - /@esbuild/win32-arm64@0.18.20: - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + /@esbuild/win32-arm64@0.19.12: + resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -792,8 +822,8 @@ packages: dev: true optional: true - /@esbuild/win32-ia32@0.18.20: - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + /@esbuild/win32-ia32@0.19.12: + resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -801,8 +831,8 @@ packages: dev: true optional: true - /@esbuild/win32-x64@0.18.20: - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + /@esbuild/win32-x64@0.19.12: + resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -810,13 +840,13 @@ packages: dev: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.52.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.52.0 + eslint: 8.57.0 eslint-visitor-keys: 3.4.3 dev: true @@ -825,15 +855,15 @@ packages: engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/eslintrc@2.1.2: - resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} + /@eslint/eslintrc@2.1.4: + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 debug: 4.3.4 espree: 9.6.1 - globals: 13.23.0 - ignore: 5.2.4 + globals: 13.24.0 + ignore: 5.3.1 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -842,44 +872,44 @@ packages: - supports-color dev: true - /@eslint/js@8.52.0: - resolution: {integrity: sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==} + /@eslint/js@8.57.0: + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@floating-ui/core@1.5.0: - resolution: {integrity: sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==} + /@floating-ui/core@1.6.0: + resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==} dependencies: - '@floating-ui/utils': 0.1.6 + '@floating-ui/utils': 0.2.1 dev: false - /@floating-ui/dom@1.5.3: - resolution: {integrity: sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==} + /@floating-ui/dom@1.6.3: + resolution: {integrity: sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==} dependencies: - '@floating-ui/core': 1.5.0 - '@floating-ui/utils': 0.1.6 + '@floating-ui/core': 1.6.0 + '@floating-ui/utils': 0.2.1 dev: false - /@floating-ui/react-dom@2.0.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==} + /@floating-ui/react-dom@2.0.8(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' dependencies: - '@floating-ui/dom': 1.5.3 + '@floating-ui/dom': 1.6.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@floating-ui/utils@0.1.6: - resolution: {integrity: sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==} + /@floating-ui/utils@0.2.1: + resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==} dev: false - /@humanwhocodes/config-array@0.11.13: - resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} + /@humanwhocodes/config-array@0.11.14: + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} dependencies: - '@humanwhocodes/object-schema': 2.0.1 + '@humanwhocodes/object-schema': 2.0.2 debug: 4.3.4 minimatch: 3.1.2 transitivePeerDependencies: @@ -891,40 +921,45 @@ packages: engines: {node: '>=12.22'} dev: true - /@humanwhocodes/object-schema@2.0.1: - resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} + /@humanwhocodes/object-schema@2.0.2: + resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} dev: true - /@jridgewell/gen-mapping@0.3.3: - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: false + + /@jridgewell/gen-mapping@0.3.5: + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} dependencies: - '@jridgewell/set-array': 1.1.2 + '@jridgewell/set-array': 1.2.1 '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.20 + '@jridgewell/trace-mapping': 0.3.25 - /@jridgewell/resolve-uri@3.1.1: - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - /@jridgewell/set-array@1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} - /@jridgewell/source-map@0.3.5: - resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} - dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.20 - dev: true - /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - /@jridgewell/trace-mapping@0.3.20: - resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} + /@jridgewell/trace-mapping@0.3.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} dependencies: - '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 /@matejmazur/react-katex@3.1.3(katex@0.16.9)(react@18.2.0): @@ -938,8 +973,8 @@ packages: react: 18.2.0 dev: false - /@mui/base@5.0.0-beta.21(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-eTKWx3WV/nwmRUK4z4K1MzlMyWCsi3WJ3RtV4DiXZeRh4qd4JCyp1Zzzi8Wv9xM4dEBmqQntFoei716PzwmFfA==} + /@mui/base@5.0.0-beta.38(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-AsjD6Y1X5A1qndxz8xCcR8LDqv31aiwlgWMPxFAX/kCKiIGKlK65yMeVZ62iQr/6LBz+9hSKLiD1i4TZdAHKcQ==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -949,24 +984,24 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 - '@floating-ui/react-dom': 2.0.2(react-dom@18.2.0)(react@18.2.0) - '@mui/types': 7.2.7(@types/react@18.2.33) - '@mui/utils': 5.14.15(@types/react@18.2.33)(react@18.2.0) + '@babel/runtime': 7.24.0 + '@floating-ui/react-dom': 2.0.8(react-dom@18.2.0)(react@18.2.0) + '@mui/types': 7.2.13(@types/react@18.2.63) + '@mui/utils': 5.15.12(@types/react@18.2.63)(react@18.2.0) '@popperjs/core': 2.11.8 - '@types/react': 18.2.33 - clsx: 2.0.0 + '@types/react': 18.2.63 + clsx: 2.1.0 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@mui/core-downloads-tracker@5.14.15: - resolution: {integrity: sha512-ZCDzBWtCKjAYAlKKM3PA/jG/3uVIDT9ZitOtVixIVmTCQyc5jSV1qhJX8+qIGz4RQZ9KLzPWO2tXd0O5hvzouQ==} + /@mui/core-downloads-tracker@5.15.12: + resolution: {integrity: sha512-brRO+tMFLpGyjEYHrX97bzqeF6jZmKpqqe1rY0LyIHAwP6xRVzh++zSecOQorDOCaZJg4XkGT9xfD+RWOWxZBA==} dev: false - /@mui/joy@5.0.0-beta.12(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-e5G9EGkxiCXWNFbSdo4V4TzqjwDqlgMbCHygzFlBwrgY1pn4jBxC5NZe4btq2CREpAi9nZlCeYgHd3ejKYBGBg==} + /@mui/joy@5.0.0-beta.30(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-m8f/sYarTohCqZOy3i1q/MYNmAshoccoRbOrWQ7+At1ReaJPz2D2LUYzYjJxxaK7sOjhDtY9etK7WfsrJhqGLA==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -982,23 +1017,23 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 - '@emotion/react': 11.11.1(@types/react@18.2.33)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react@18.2.0) - '@mui/base': 5.0.0-beta.21(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0) - '@mui/core-downloads-tracker': 5.14.15 - '@mui/system': 5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.33)(react@18.2.0) - '@mui/types': 7.2.7(@types/react@18.2.33) - '@mui/utils': 5.14.15(@types/react@18.2.33)(react@18.2.0) - '@types/react': 18.2.33 - clsx: 2.0.0 + '@babel/runtime': 7.24.0 + '@emotion/react': 11.11.4(@types/react@18.2.63)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.63)(react@18.2.0) + '@mui/base': 5.0.0-beta.38(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0) + '@mui/core-downloads-tracker': 5.15.12 + '@mui/system': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react@18.2.0) + '@mui/types': 7.2.13(@types/react@18.2.63) + '@mui/utils': 5.15.12(@types/react@18.2.63)(react@18.2.0) + '@types/react': 18.2.63 + clsx: 2.1.0 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@mui/private-theming@5.14.15(@types/react@18.2.33)(react@18.2.0): - resolution: {integrity: sha512-V2Xh+Tu6A07NoSpup0P9m29GwvNMYl5DegsGWqlOTJyAV7cuuVjmVPqxgvL8xBng4R85xqIQJRMjtYYktoPNuQ==} + /@mui/private-theming@5.15.12(@types/react@18.2.63)(react@18.2.0): + resolution: {integrity: sha512-cqoSo9sgA5HE+8vZClbLrq9EkyOnYysooepi5eKaKvJ41lReT2c5wOZAeDDM1+xknrMDos+0mT2zr3sZmUiRRA==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -1007,15 +1042,15 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 - '@mui/utils': 5.14.15(@types/react@18.2.33)(react@18.2.0) - '@types/react': 18.2.33 + '@babel/runtime': 7.24.0 + '@mui/utils': 5.15.12(@types/react@18.2.63)(react@18.2.0) + '@types/react': 18.2.63 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/styled-engine@5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0): - resolution: {integrity: sha512-mbOjRf867BysNpexe5Z/P8s3bWzDPNowmKhi7gtNDP/LPEeqAfiDSuC4WPTXmtvse1dCl30Nl755OLUYuoi7Mw==} + /@mui/styled-engine@5.15.11(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(react@18.2.0): + resolution: {integrity: sha512-So21AhAngqo07ces4S/JpX5UaMU2RHXpEA6hNzI6IQjd/1usMPxpgK8wkGgTe3JKmC2KDmH8cvoycq5H3Ii7/w==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.4.1 @@ -1027,17 +1062,17 @@ packages: '@emotion/styled': optional: true dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 '@emotion/cache': 11.11.0 - '@emotion/react': 11.11.1(@types/react@18.2.33)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react@18.2.0) + '@emotion/react': 11.11.4(@types/react@18.2.63)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.63)(react@18.2.0) csstype: 3.1.2 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/system@5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.33)(react@18.2.0): - resolution: {integrity: sha512-zr0Gdk1RgKiEk+tCMB900LaOpEC8NaGvxtkmMdL/CXgkqQZSVZOt2PQsxJWaw7kE4YVkIe4VukFVc43qcq9u3w==} + /@mui/system@5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react@18.2.0): + resolution: {integrity: sha512-/pq+GO6yN3X7r3hAwFTrzkAh7K1bTF5r8IzS79B9eyKJg7v6B/t4/zZYMR6OT9qEPtwf6rYN2Utg1e6Z7F1OgQ==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -1052,33 +1087,33 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 - '@emotion/react': 11.11.1(@types/react@18.2.33)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react@18.2.0) - '@mui/private-theming': 5.14.15(@types/react@18.2.33)(react@18.2.0) - '@mui/styled-engine': 5.14.15(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0) - '@mui/types': 7.2.7(@types/react@18.2.33) - '@mui/utils': 5.14.15(@types/react@18.2.33)(react@18.2.0) - '@types/react': 18.2.33 - clsx: 2.0.0 + '@babel/runtime': 7.24.0 + '@emotion/react': 11.11.4(@types/react@18.2.63)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.63)(react@18.2.0) + '@mui/private-theming': 5.15.12(@types/react@18.2.63)(react@18.2.0) + '@mui/styled-engine': 5.15.11(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(react@18.2.0) + '@mui/types': 7.2.13(@types/react@18.2.63) + '@mui/utils': 5.15.12(@types/react@18.2.63)(react@18.2.0) + '@types/react': 18.2.63 + clsx: 2.1.0 csstype: 3.1.2 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/types@7.2.7(@types/react@18.2.33): - resolution: {integrity: sha512-sofpWmcBqOlTzRbr1cLQuUDKaUYVZTw8ENQrtL39TECRNENEzwgnNPh6WMfqMZlMvf1Aj9DLg74XPjnLr0izUQ==} + /@mui/types@7.2.13(@types/react@18.2.63): + resolution: {integrity: sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 peerDependenciesMeta: '@types/react': optional: true dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.63 dev: false - /@mui/utils@5.14.15(@types/react@18.2.33)(react@18.2.0): - resolution: {integrity: sha512-QBfHovAvTa0J1jXuYDaXGk+Yyp7+Fm8GSqx6nK2JbezGqzCFfirNdop/+bL9Flh/OQ/64PeXcW4HGDdOge+n3A==} + /@mui/utils@5.15.12(@types/react@18.2.63)(react@18.2.0): + resolution: {integrity: sha512-8SDGCnO2DY9Yy+5bGzu00NZowSDtuyHP4H8gunhHGQoIlhlY2Z3w64wBzAOLpYw/ZhJNzksDTnS/i8qdJvxuow==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -1087,9 +1122,9 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 - '@types/prop-types': 15.7.9 - '@types/react': 18.2.33 + '@babel/runtime': 7.24.0 + '@types/prop-types': 15.7.11 + '@types/react': 18.2.63 prop-types: 15.8.1 react: 18.2.0 react-is: 18.2.0 @@ -1111,7 +1146,19 @@ packages: engines: {node: '>= 8'} dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 + fastq: 1.17.1 + + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: false + optional: true + + /@pkgr/core@0.1.1: + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + dev: true /@popperjs/core@2.11.8: resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} @@ -1119,46 +1166,46 @@ packages: /@protobufjs/aspromise@1.1.2: resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} - dev: false + dev: true /@protobufjs/base64@1.1.2: resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - dev: false + dev: true /@protobufjs/codegen@2.0.4: resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} - dev: false + dev: true /@protobufjs/eventemitter@1.1.0: resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} - dev: false + dev: true /@protobufjs/fetch@1.1.0: resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/inquire': 1.1.0 - dev: false + dev: true /@protobufjs/float@1.0.2: resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - dev: false + dev: true /@protobufjs/inquire@1.1.0: resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} - dev: false + dev: true /@protobufjs/path@1.1.2: resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} - dev: false + dev: true /@protobufjs/pool@1.1.0: resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - dev: false + dev: true /@protobufjs/utf8@1.1.0: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} - dev: false + dev: true /@reduxjs/toolkit@1.9.7(react-redux@8.1.3)(react@18.2.0): resolution: {integrity: sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==} @@ -1173,170 +1220,370 @@ packages: dependencies: immer: 9.0.21 react: 18.2.0 - react-redux: 8.1.3(@types/react-dom@18.2.14)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) + react-redux: 8.1.3(@types/react-dom@18.2.20)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) redux: 4.2.1 redux-thunk: 2.4.2(redux@4.2.1) reselect: 4.1.8 dev: false - /@remix-run/router@1.10.0: - resolution: {integrity: sha512-Lm+fYpMfZoEucJ7cMxgt4dYt8jLfbpwRCzAjm9UgSLOkmlqo9gupxt6YX3DY0Fk155NT9l17d/ydi+964uS9Lw==} + /@remix-run/router@1.15.2: + resolution: {integrity: sha512-+Rnav+CaoTE5QJc4Jcwh5toUpnVLKYbpU6Ys0zqbakqbaLQHeglLVHPfxOiQqdNmUy5C2lXz5dwC6tQNX2JW2Q==} engines: {node: '>=14.0.0'} dev: false - /@swc/core-darwin-arm64@1.3.95: - resolution: {integrity: sha512-VAuBAP3MNetO/yBIBzvorUXq7lUBwhfpJxYViSxyluMwtoQDhE/XWN598TWMwMl1ZuImb56d7eUsuFdjgY7pJw==} - engines: {node: '>=10'} + /@rollup/rollup-android-arm-eabi@4.12.1: + resolution: {integrity: sha512-iU2Sya8hNn1LhsYyf0N+L4Gf9Qc+9eBTJJJsaOGUp+7x4n2M9dxTt8UvhJl3oeftSjblSlpCfvjA/IfP3g5VjQ==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-android-arm64@4.12.1: + resolution: {integrity: sha512-wlzcWiH2Ir7rdMELxFE5vuM7D6TsOcJ2Yw0c3vaBR3VOsJFVTx9xvwnAvhgU5Ii8Gd6+I11qNHwndDscIm0HXg==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-arm64@4.12.1: + resolution: {integrity: sha512-YRXa1+aZIFN5BaImK+84B3uNK8C6+ynKLPgvn29X9s0LTVCByp54TB7tdSMHDR7GTV39bz1lOmlLDuedgTwwHg==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /@swc/core-darwin-x64@1.3.95: - resolution: {integrity: sha512-20vF2rvUsN98zGLZc+dsEdHvLoCuiYq/1B+TDeE4oolgTFDmI1jKO+m44PzWjYtKGU9QR95sZ6r/uec0QC5O4Q==} - engines: {node: '>=10'} + /@rollup/rollup-darwin-x64@4.12.1: + resolution: {integrity: sha512-opjWJ4MevxeA8FhlngQWPBOvVWYNPFkq6/25rGgG+KOy0r8clYwL1CFd+PGwRqqMFVQ4/Qd3sQu5t7ucP7C/Uw==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /@swc/core-linux-arm-gnueabihf@1.3.95: - resolution: {integrity: sha512-oEudEM8PST1MRNGs+zu0cx5i9uP8TsLE4/L9HHrS07Ck0RJ3DCj3O2fU832nmLe2QxnAGPwBpSO9FntLfOiWEQ==} - engines: {node: '>=10'} + /@rollup/rollup-linux-arm-gnueabihf@4.12.1: + resolution: {integrity: sha512-uBkwaI+gBUlIe+EfbNnY5xNyXuhZbDSx2nzzW8tRMjUmpScd6lCQYKY2V9BATHtv5Ef2OBq6SChEP8h+/cxifQ==} cpu: [arm] os: [linux] requiresBuild: true dev: true optional: true - /@swc/core-linux-arm64-gnu@1.3.95: - resolution: {integrity: sha512-pIhFI+cuC1aYg+0NAPxwT/VRb32f2ia8oGxUjQR6aJg65gLkUYQzdwuUmpMtFR2WVf7WVFYxUnjo4UyMuyh3ng==} - engines: {node: '>=10'} + /@rollup/rollup-linux-arm64-gnu@4.12.1: + resolution: {integrity: sha512-0bK9aG1kIg0Su7OcFTlexkVeNZ5IzEsnz1ept87a0TUgZ6HplSgkJAnFpEVRW7GRcikT4GlPV0pbtVedOaXHQQ==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /@swc/core-linux-arm64-musl@1.3.95: - resolution: {integrity: sha512-ZpbTr+QZDT4OPJfjPAmScqdKKaT+wGurvMU5AhxLaf85DuL8HwUwwlL0n1oLieLc47DwIJEMuKQkYhXMqmJHlg==} - engines: {node: '>=10'} + /@rollup/rollup-linux-arm64-musl@4.12.1: + resolution: {integrity: sha512-qB6AFRXuP8bdkBI4D7UPUbE7OQf7u5OL+R94JE42Z2Qjmyj74FtDdLGeriRyBDhm4rQSvqAGCGC01b8Fu2LthQ==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /@swc/core-linux-x64-gnu@1.3.95: - resolution: {integrity: sha512-n9SuHEFtdfSJ+sHdNXNRuIOVprB8nbsz+08apKfdo4lEKq6IIPBBAk5kVhPhkjmg2dFVHVo4Tr/OHXM1tzWCCw==} - engines: {node: '>=10'} + /@rollup/rollup-linux-riscv64-gnu@4.12.1: + resolution: {integrity: sha512-sHig3LaGlpNgDj5o8uPEoGs98RII8HpNIqFtAI8/pYABO8i0nb1QzT0JDoXF/pxzqO+FkxvwkHZo9k0NJYDedg==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.12.1: + resolution: {integrity: sha512-nD3YcUv6jBJbBNFvSbp0IV66+ba/1teuBcu+fBBPZ33sidxitc6ErhON3JNavaH8HlswhWMC3s5rgZpM4MtPqQ==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /@swc/core-linux-x64-musl@1.3.95: - resolution: {integrity: sha512-L1JrVlsXU3LC0WwmVnMK9HrOT2uhHahAoPNMJnZQpc18a0paO9fqifPG8M/HjNRffMUXR199G/phJsf326UvVg==} - engines: {node: '>=10'} + /@rollup/rollup-linux-x64-musl@4.12.1: + resolution: {integrity: sha512-7/XVZqgBby2qp/cO0TQ8uJK+9xnSdJ9ct6gSDdEr4MfABrjTyrW6Bau7HQ73a2a5tPB7hno49A0y1jhWGDN9OQ==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /@swc/core-win32-arm64-msvc@1.3.95: - resolution: {integrity: sha512-YaP4x/aZbUyNdqCBpC2zL8b8n58MEpOUpmOIZK6G1SxGi+2ENht7gs7+iXpWPc0sy7X3YPKmSWMAuui0h8lgAA==} - engines: {node: '>=10'} + /@rollup/rollup-win32-arm64-msvc@4.12.1: + resolution: {integrity: sha512-CYc64bnICG42UPL7TrhIwsJW4QcKkIt9gGlj21gq3VV0LL6XNb1yAdHVp1pIi9gkts9gGcT3OfUYHjGP7ETAiw==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /@swc/core-win32-ia32-msvc@1.3.95: - resolution: {integrity: sha512-w0u3HI916zT4BC/57gOd+AwAEjXeUlQbGJ9H4p/gzs1zkSHtoDQghVUNy3n/ZKp9KFod/95cA8mbVF9t1+6epQ==} - engines: {node: '>=10'} + /@rollup/rollup-win32-ia32-msvc@4.12.1: + resolution: {integrity: sha512-LN+vnlZ9g0qlHGlS920GR4zFCqAwbv2lULrR29yGaWP9u7wF5L7GqWu9Ah6/kFZPXPUkpdZwd//TNR+9XC9hvA==} cpu: [ia32] os: [win32] requiresBuild: true dev: true optional: true - /@swc/core-win32-x64-msvc@1.3.95: - resolution: {integrity: sha512-5RGnMt0S6gg4Gc6QtPUJ3Qs9Un4sKqccEzgH/tj7V/DVTJwKdnBKxFZfgQ34OR2Zpz7zGOn889xwsFVXspVWNA==} - engines: {node: '>=10'} + /@rollup/rollup-win32-x64-msvc@4.12.1: + resolution: {integrity: sha512-n+vkrSyphvmU0qkQ6QBNXCGr2mKjhP08mPRM/Xp5Ck2FV4NrHU+y6axzDeixUrCBHVUS51TZhjqrKBBsHLKb2Q==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /@swc/core@1.3.95: - resolution: {integrity: sha512-PMrNeuqIusq9DPDooV3FfNEbZuTu5jKAc04N3Hm6Uk2Fl49cqElLFQ4xvl4qDmVDz97n3n/C1RE0/f6WyGPEiA==} - engines: {node: '>=10'} - requiresBuild: true + /@trivago/prettier-plugin-sort-imports@4.3.0(prettier@3.2.5): + resolution: {integrity: sha512-r3n0onD3BTOVUNPhR4lhVK4/pABGpbA7bW3eumZnYdKaHkf1qEC+Mag6DPbGNuuh0eG8AaYj+YqmVHSiGslaTQ==} peerDependencies: - '@swc/helpers': ^0.5.0 + '@vue/compiler-sfc': 3.x + prettier: 2.x - 3.x peerDependenciesMeta: - '@swc/helpers': + '@vue/compiler-sfc': optional: true dependencies: - '@swc/counter': 0.1.2 - '@swc/types': 0.1.5 - optionalDependencies: - '@swc/core-darwin-arm64': 1.3.95 - '@swc/core-darwin-x64': 1.3.95 - '@swc/core-linux-arm-gnueabihf': 1.3.95 - '@swc/core-linux-arm64-gnu': 1.3.95 - '@swc/core-linux-arm64-musl': 1.3.95 - '@swc/core-linux-x64-gnu': 1.3.95 - '@swc/core-linux-x64-musl': 1.3.95 - '@swc/core-win32-arm64-msvc': 1.3.95 - '@swc/core-win32-ia32-msvc': 1.3.95 - '@swc/core-win32-x64-msvc': 1.3.95 + '@babel/generator': 7.17.7 + '@babel/parser': 7.24.0 + '@babel/traverse': 7.23.2 + '@babel/types': 7.17.0 + javascript-natural-sort: 0.7.1 + lodash: 4.17.21 + prettier: 3.2.5 + transitivePeerDependencies: + - supports-color dev: true - /@swc/counter@0.1.2: - resolution: {integrity: sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==} + /@types/babel__core@7.20.5: + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + dependencies: + '@babel/parser': 7.24.0 + '@babel/types': 7.24.0 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.5 dev: true - /@swc/types@0.1.5: - resolution: {integrity: sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==} + /@types/babel__generator@7.6.8: + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + dependencies: + '@babel/types': 7.24.0 dev: true - /@tailwindcss/container-queries@0.1.1(tailwindcss@3.3.5): - resolution: {integrity: sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==} - peerDependencies: - tailwindcss: '>=3.2.0' + /@types/babel__template@7.4.4: + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} dependencies: - tailwindcss: 3.3.5 + '@babel/parser': 7.24.0 + '@babel/types': 7.24.0 + dev: true + + /@types/babel__traverse@7.20.5: + resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + dependencies: + '@babel/types': 7.24.0 + dev: true + + /@types/d3-array@3.2.1: + resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} + dev: true + + /@types/d3-axis@3.0.6: + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + dependencies: + '@types/d3-selection': 3.0.10 + dev: true + + /@types/d3-brush@3.0.6: + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} + dependencies: + '@types/d3-selection': 3.0.10 + dev: true + + /@types/d3-chord@3.0.6: + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} + dev: true + + /@types/d3-color@3.1.3: + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + dev: true + + /@types/d3-contour@3.0.6: + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + dependencies: + '@types/d3-array': 3.2.1 + '@types/geojson': 7946.0.14 + dev: true + + /@types/d3-delaunay@6.0.4: + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + dev: true + + /@types/d3-dispatch@3.0.6: + resolution: {integrity: sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==} + dev: true + + /@types/d3-drag@3.0.7: + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + dependencies: + '@types/d3-selection': 3.0.10 + dev: true + + /@types/d3-dsv@3.0.7: + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + dev: true + + /@types/d3-ease@3.0.2: + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + dev: true + + /@types/d3-fetch@3.0.7: + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + dependencies: + '@types/d3-dsv': 3.0.7 + dev: true + + /@types/d3-force@3.0.9: + resolution: {integrity: sha512-IKtvyFdb4Q0LWna6ymywQsEYjK/94SGhPrMfEr1TIc5OBeziTi+1jcCvttts8e0UWZIxpasjnQk9MNk/3iS+kA==} + dev: true + + /@types/d3-format@3.0.4: + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + dev: true + + /@types/d3-geo@3.1.0: + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} + dependencies: + '@types/geojson': 7946.0.14 + dev: true + + /@types/d3-hierarchy@3.1.6: + resolution: {integrity: sha512-qlmD/8aMk5xGorUvTUWHCiumvgaUXYldYjNVOWtYoTYY/L+WwIEAmJxUmTgr9LoGNG0PPAOmqMDJVDPc7DOpPw==} + dev: true + + /@types/d3-interpolate@3.0.4: + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + dependencies: + '@types/d3-color': 3.1.3 + dev: true + + /@types/d3-path@3.1.0: + resolution: {integrity: sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==} + dev: true + + /@types/d3-polygon@3.0.2: + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} + dev: true + + /@types/d3-quadtree@3.0.6: + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} + dev: true + + /@types/d3-random@3.0.3: + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} + dev: true + + /@types/d3-scale-chromatic@3.0.3: + resolution: {integrity: sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==} + + /@types/d3-scale@4.0.8: + resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==} + dependencies: + '@types/d3-time': 3.0.3 + + /@types/d3-selection@3.0.10: + resolution: {integrity: sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==} + dev: true + + /@types/d3-shape@3.1.6: + resolution: {integrity: sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==} + dependencies: + '@types/d3-path': 3.1.0 + dev: true + + /@types/d3-time-format@4.0.3: + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} + dev: true + + /@types/d3-time@3.0.3: + resolution: {integrity: sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==} + + /@types/d3-timer@3.0.2: + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + dev: true + + /@types/d3-transition@3.0.8: + resolution: {integrity: sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==} + dependencies: + '@types/d3-selection': 3.0.10 + dev: true + + /@types/d3-zoom@3.0.8: + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.10 + dev: true + + /@types/d3@7.4.3: + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + dependencies: + '@types/d3-array': 3.2.1 + '@types/d3-axis': 3.0.6 + '@types/d3-brush': 3.0.6 + '@types/d3-chord': 3.0.6 + '@types/d3-color': 3.1.3 + '@types/d3-contour': 3.0.6 + '@types/d3-delaunay': 6.0.4 + '@types/d3-dispatch': 3.0.6 + '@types/d3-drag': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.9 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.1.0 + '@types/d3-hierarchy': 3.1.6 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.1.0 + '@types/d3-polygon': 3.0.2 + '@types/d3-quadtree': 3.0.6 + '@types/d3-random': 3.0.3 + '@types/d3-scale': 4.0.8 + '@types/d3-scale-chromatic': 3.0.3 + '@types/d3-selection': 3.0.10 + '@types/d3-shape': 3.1.6 + '@types/d3-time': 3.0.3 + '@types/d3-time-format': 4.0.3 + '@types/d3-timer': 3.0.2 + '@types/d3-transition': 3.0.8 + '@types/d3-zoom': 3.0.8 + dev: true + + /@types/debug@4.1.12: + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + dependencies: + '@types/ms': 0.7.34 dev: false - /@trivago/prettier-plugin-sort-imports@3.4.0(prettier@2.6.2): - resolution: {integrity: sha512-485Iailw8X5f7KetzRka20RF1kPBEINR5LJMNwlBZWY1gRAlVnv5dZzyNPnLxSP0Qcia8HETa9Cdd8LlX9o+pg==} - peerDependencies: - prettier: 2.x + /@types/dompurify@3.0.5: + resolution: {integrity: sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==} dependencies: - '@babel/core': 7.17.8 - '@babel/generator': 7.17.7 - '@babel/parser': 7.18.9 - '@babel/traverse': 7.17.3 - '@babel/types': 7.17.0 - '@vue/compiler-sfc': 3.3.7 - javascript-natural-sort: 0.7.1 - lodash: 4.17.21 - prettier: 2.6.2 - transitivePeerDependencies: - - supports-color + '@types/trusted-types': 2.0.7 dev: true - /@types/hoist-non-react-statics@3.3.4: - resolution: {integrity: sha512-ZchYkbieA+7tnxwX/SCBySx9WwvWR8TaP5tb2jRAzwvLb/rWchGw3v0w3pqUbUvj0GCwW2Xz/AVPSk6kUGctXQ==} + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + dev: true + + /@types/geojson@7946.0.14: + resolution: {integrity: sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==} + dev: true + + /@types/hoist-non-react-statics@3.3.5: + resolution: {integrity: sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==} dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.63 hoist-non-react-statics: 3.3.2 dev: false @@ -1344,73 +1591,92 @@ packages: resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==} dev: false - /@types/json-schema@7.0.14: - resolution: {integrity: sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==} + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true - /@types/katex@0.16.5: - resolution: {integrity: sha512-DD2Y3xMlTQvAnN6d8803xdgnOeYZ+HwMglb7/9YCf49J9RkJL53azf9qKa40MkEYhqVwxZ1GS2+VlShnz4Z1Bw==} + /@types/katex@0.16.7: + resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} dev: true - /@types/lodash-es@4.17.10: - resolution: {integrity: sha512-YJP+w/2khSBwbUSFdGsSqmDvmnN3cCKoPOL7Zjle6s30ZtemkkqhjVfFqGwPN7ASil5VyjE2GtyU/yqYY6mC0A==} + /@types/lodash-es@4.17.12: + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} dependencies: - '@types/lodash': 4.14.200 + '@types/lodash': 4.14.202 dev: true - /@types/lodash@4.14.200: - resolution: {integrity: sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q==} + /@types/lodash@4.14.202: + resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} dev: true - /@types/node@18.18.7: - resolution: {integrity: sha512-bw+lEsxis6eqJYW8Ql6+yTqkE6RuFtsQPSe5JxXbqYRFQEER5aJA9a5UH9igqDWm3X4iLHIKOHlnAXLM4mi7uQ==} + /@types/mdast@3.0.15: + resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + dependencies: + '@types/unist': 2.0.10 + dev: false + + /@types/ms@0.7.34: + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + dev: false + + /@types/node@20.11.24: + resolution: {integrity: sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==} dependencies: undici-types: 5.26.5 + dev: true - /@types/parse-json@4.0.1: - resolution: {integrity: sha512-3YmXzzPAdOTVljVMkTMBdBEvlOLg2cDQaDhnnhT3nT9uDbnJzjWhKlzb+desT12Y7tGqaN6d+AbozcKzyL36Ng==} + /@types/parse-json@4.0.2: + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} dev: false - /@types/prop-types@15.7.9: - resolution: {integrity: sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==} + /@types/prop-types@15.7.11: + resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} - /@types/qs@6.9.9: - resolution: {integrity: sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==} + /@types/qs@6.9.12: + resolution: {integrity: sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==} dev: true - /@types/react-dom@18.2.14: - resolution: {integrity: sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ==} + /@types/react-dom@18.2.20: + resolution: {integrity: sha512-HXN/biJY8nv20Cn9ZbCFq3liERd4CozVZmKbaiZ9KiKTrWqsP7eoGDO6OOGvJQwoVFuiXaiJ7nBBjiFFbRmQMQ==} dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.63 - /@types/react@18.2.33: - resolution: {integrity: sha512-v+I7S+hu3PIBoVkKGpSYYpiBT1ijqEzWpzQD62/jm4K74hPpSP7FF9BnKG6+fg2+62weJYkkBWDJlZt5JO/9hg==} + /@types/react@18.2.63: + resolution: {integrity: sha512-ppaqODhs15PYL2nGUOaOu2RSCCB4Difu4UFrP4I3NHLloXC/ESQzQMi9nvjfT1+rudd0d2L3fQPJxRSey+rGlQ==} dependencies: - '@types/prop-types': 15.7.9 - '@types/scheduler': 0.16.5 + '@types/prop-types': 15.7.11 + '@types/scheduler': 0.16.8 csstype: 3.1.2 - /@types/scheduler@0.16.5: - resolution: {integrity: sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==} + /@types/scheduler@0.16.8: + resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} + + /@types/semver@7.5.8: + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + dev: true - /@types/semver@7.5.4: - resolution: {integrity: sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==} + /@types/textarea-caret@3.0.3: + resolution: {integrity: sha512-bsA9GdXV1wQsXyDjS5+A+czz8IAR3haH5DU+KctIoXbzobRL2NOiwF/+EbB7pofAyudMytLj4ihPtbmbJT8FWw==} dev: true - /@types/textarea-caret@3.0.2: - resolution: {integrity: sha512-Bda0K7o7QLHp5KEqLYxZJaCDQZ5okxo3iGVCTOfOxHQQxo7ayYUXv1UyGhzmMPucT0UbeMeCW+DCGiAdyf8cTQ==} + /@types/trusted-types@2.0.7: + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} dev: true + /@types/unist@2.0.10: + resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} + dev: false + /@types/use-sync-external-store@0.0.3: resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==} dev: false - /@types/uuid@9.0.6: - resolution: {integrity: sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew==} + /@types/uuid@9.0.8: + resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} dev: true - /@typescript-eslint/eslint-plugin@6.9.0(@typescript-eslint/parser@6.9.0)(eslint@8.52.0)(typescript@5.2.2): - resolution: {integrity: sha512-lgX7F0azQwRPB7t7WAyeHWVfW1YJ9NIgd9mvGhfQpRY56X6AVf8mwM8Wol+0z4liE7XX3QOt8MN1rUKCfSjRIA==} + /@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.57.0)(typescript@5.3.3): + resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -1421,25 +1687,25 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 6.9.0(eslint@8.52.0)(typescript@5.2.2) - '@typescript-eslint/scope-manager': 6.9.0 - '@typescript-eslint/type-utils': 6.9.0(eslint@8.52.0)(typescript@5.2.2) - '@typescript-eslint/utils': 6.9.0(eslint@8.52.0)(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.9.0 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4 - eslint: 8.52.0 + eslint: 8.57.0 graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.1 natural-compare: 1.4.0 - semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.2.2) - typescript: 5.2.2 + semver: 7.6.0 + ts-api-utils: 1.2.1(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@6.9.0(eslint@8.52.0)(typescript@5.2.2): - resolution: {integrity: sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw==} + /@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.3.3): + resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1448,27 +1714,27 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.9.0 - '@typescript-eslint/types': 6.9.0 - '@typescript-eslint/typescript-estree': 6.9.0(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.9.0 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4 - eslint: 8.52.0 - typescript: 5.2.2 + eslint: 8.57.0 + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@6.9.0: - resolution: {integrity: sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw==} + /@typescript-eslint/scope-manager@6.21.0: + resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.9.0 - '@typescript-eslint/visitor-keys': 6.9.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 dev: true - /@typescript-eslint/type-utils@6.9.0(eslint@8.52.0)(typescript@5.2.2): - resolution: {integrity: sha512-XXeahmfbpuhVbhSOROIzJ+b13krFmgtc4GlEuu1WBT+RpyGPIA4Y/eGnXzjbDj5gZLzpAXO/sj+IF/x2GtTMjQ==} + /@typescript-eslint/type-utils@6.21.0(eslint@8.57.0)(typescript@5.3.3): + resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1477,23 +1743,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.9.0(typescript@5.2.2) - '@typescript-eslint/utils': 6.9.0(eslint@8.52.0)(typescript@5.2.2) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.3.3) debug: 4.3.4 - eslint: 8.52.0 - ts-api-utils: 1.0.3(typescript@5.2.2) - typescript: 5.2.2 + eslint: 8.57.0 + ts-api-utils: 1.2.1(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@6.9.0: - resolution: {integrity: sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw==} + /@typescript-eslint/types@6.21.0: + resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.9.0(typescript@5.2.2): - resolution: {integrity: sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ==} + /@typescript-eslint/typescript-estree@6.21.0(typescript@5.3.3): + resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -1501,42 +1767,43 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.9.0 - '@typescript-eslint/visitor-keys': 6.9.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.2.2) - typescript: 5.2.2 + minimatch: 9.0.3 + semver: 7.6.0 + ts-api-utils: 1.2.1(typescript@5.3.3) + typescript: 5.3.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@6.9.0(eslint@8.52.0)(typescript@5.2.2): - resolution: {integrity: sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ==} + /@typescript-eslint/utils@6.21.0(eslint@8.57.0)(typescript@5.3.3): + resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) - '@types/json-schema': 7.0.14 - '@types/semver': 7.5.4 - '@typescript-eslint/scope-manager': 6.9.0 - '@typescript-eslint/types': 6.9.0 - '@typescript-eslint/typescript-estree': 6.9.0(typescript@5.2.2) - eslint: 8.52.0 - semver: 7.5.4 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.3.3) + eslint: 8.57.0 + semver: 7.6.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys@6.9.0: - resolution: {integrity: sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg==} + /@typescript-eslint/visitor-keys@6.21.0: + resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.9.0 + '@typescript-eslint/types': 6.21.0 eslint-visitor-keys: 3.4.3 dev: true @@ -1544,67 +1811,20 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true - /@vitejs/plugin-react-swc@3.4.0(vite@4.5.0): - resolution: {integrity: sha512-m7UaA4Uvz82N/0EOVpZL4XsFIakRqrFKeSNxa1FBLSXGvWrWRBwmZb4qxk+ZIVAZcW3c3dn5YosomDgx62XWcQ==} + /@vitejs/plugin-react@4.2.1(vite@5.1.5): + resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} + engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^4 - dependencies: - '@swc/core': 1.3.95 - vite: 4.5.0(@types/node@18.18.7)(less@4.2.0)(terser@5.22.0) + vite: ^4.2.0 || ^5.0.0 + dependencies: + '@babel/core': 7.24.0 + '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.24.0) + '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.24.0) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.0 + vite: 5.1.5(@types/node@20.11.24)(less@4.2.0) transitivePeerDependencies: - - '@swc/helpers' - dev: true - - /@vue/compiler-core@3.3.7: - resolution: {integrity: sha512-pACdY6YnTNVLXsB86YD8OF9ihwpolzhhtdLVHhBL6do/ykr6kKXNYABRtNMGrsQXpEXXyAdwvWWkuTbs4MFtPQ==} - dependencies: - '@babel/parser': 7.23.0 - '@vue/shared': 3.3.7 - estree-walker: 2.0.2 - source-map-js: 1.0.2 - dev: true - - /@vue/compiler-dom@3.3.7: - resolution: {integrity: sha512-0LwkyJjnUPssXv/d1vNJ0PKfBlDoQs7n81CbO6Q0zdL7H1EzqYRrTVXDqdBVqro0aJjo/FOa1qBAPVI4PGSHBw==} - dependencies: - '@vue/compiler-core': 3.3.7 - '@vue/shared': 3.3.7 - dev: true - - /@vue/compiler-sfc@3.3.7: - resolution: {integrity: sha512-7pfldWy/J75U/ZyYIXRVqvLRw3vmfxDo2YLMwVtWVNew8Sm8d6wodM+OYFq4ll/UxfqVr0XKiVwti32PCrruAw==} - dependencies: - '@babel/parser': 7.23.0 - '@vue/compiler-core': 3.3.7 - '@vue/compiler-dom': 3.3.7 - '@vue/compiler-ssr': 3.3.7 - '@vue/reactivity-transform': 3.3.7 - '@vue/shared': 3.3.7 - estree-walker: 2.0.2 - magic-string: 0.30.5 - postcss: 8.4.31 - source-map-js: 1.0.2 - dev: true - - /@vue/compiler-ssr@3.3.7: - resolution: {integrity: sha512-TxOfNVVeH3zgBc82kcUv+emNHo+vKnlRrkv8YvQU5+Y5LJGJwSNzcmLUoxD/dNzv0bhQ/F0s+InlgV0NrApJZg==} - dependencies: - '@vue/compiler-dom': 3.3.7 - '@vue/shared': 3.3.7 - dev: true - - /@vue/reactivity-transform@3.3.7: - resolution: {integrity: sha512-APhRmLVbgE1VPGtoLQoWBJEaQk4V8JUsqrQihImVqKT+8U6Qi3t5ATcg4Y9wGAPb3kIhetpufyZ1RhwbZCIdDA==} - dependencies: - '@babel/parser': 7.23.0 - '@vue/compiler-core': 3.3.7 - '@vue/shared': 3.3.7 - estree-walker: 2.0.2 - magic-string: 0.30.5 - dev: true - - /@vue/shared@3.3.7: - resolution: {integrity: sha512-N/tbkINRUDExgcPTBvxNkvHGu504k8lzlNQRITVnm6YjOjwa4r0nnbd4Jb01sNpur5hAllyRJzSK5PvB9PPwRg==} + - supports-color dev: true /@xobotyi/scrollbar-width@1.9.5: @@ -1613,18 +1833,18 @@ packages: /abort-controller-x@0.4.3: resolution: {integrity: sha512-VtUwTNU8fpMwvWGn4xE93ywbogTYsuT+AUxAXOeelbXuQVIwNmC5YLeho9sH4vZ4ITW8414TTAOG1nW6uIVHCA==} - dev: false + dev: true - /acorn-jsx@5.3.2(acorn@8.11.2): + /acorn-jsx@5.3.2(acorn@8.11.3): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - acorn: 8.11.2 + acorn: 8.11.3 dev: true - /acorn@8.11.2: - resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} engines: {node: '>=0.4.0'} hasBin: true dev: true @@ -1641,7 +1861,11 @@ packages: /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - dev: true + + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: false /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} @@ -1654,7 +1878,11 @@ packages: engines: {node: '>=8'} dependencies: color-convert: 2.0.1 - dev: true + + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: false /any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -1676,21 +1904,22 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true - /array-buffer-byte-length@1.0.0: - resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + /array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - is-array-buffer: 3.0.2 + call-bind: 1.0.7 + is-array-buffer: 3.0.4 dev: true /array-includes@3.1.7: resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 + es-abstract: 1.22.5 + get-intrinsic: 1.2.4 is-string: 1.0.7 dev: true @@ -1699,13 +1928,24 @@ packages: engines: {node: '>=8'} dev: true + /array.prototype.findlast@1.2.4: + resolution: {integrity: sha512-BMtLxpV+8BD+6ZPFIWmnUBpQoy+A+ujcg4rhp2iwCRJYA7PEh2MS4NL3lz8EiDlLrJPp2hg9qWihr5pd//jcGw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + es-errors: 1.3.0 + es-shim-unscopables: 1.0.2 + dev: true + /array.prototype.flat@1.3.2: resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.22.5 es-shim-unscopables: 1.0.2 dev: true @@ -1713,33 +1953,43 @@ packages: resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + es-shim-unscopables: 1.0.2 + dev: true + + /array.prototype.toreversed@1.1.2: + resolution: {integrity: sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==} + dependencies: + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.22.5 es-shim-unscopables: 1.0.2 dev: true - /array.prototype.tosorted@1.1.2: - resolution: {integrity: sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==} + /array.prototype.tosorted@1.1.3: + resolution: {integrity: sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.22.5 + es-errors: 1.3.0 es-shim-unscopables: 1.0.2 - get-intrinsic: 1.2.2 dev: true - /arraybuffer.prototype.slice@1.0.2: - resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} + /arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} dependencies: - array-buffer-byte-length: 1.0.0 - call-bind: 1.0.5 + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 - is-array-buffer: 3.0.2 - is-shared-array-buffer: 1.0.2 + es-abstract: 1.22.5 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 dev: true /asynciterator.prototype@1.0.0: @@ -1752,32 +2002,35 @@ packages: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false - /autoprefixer@10.4.16(postcss@8.4.31): - resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==} + /autoprefixer@10.4.18(postcss@8.4.35): + resolution: {integrity: sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: - browserslist: 4.22.1 - caniuse-lite: 1.0.30001555 + browserslist: 4.23.0 + caniuse-lite: 1.0.30001594 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.31 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /available-typed-arrays@1.0.5: - resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.0.0 dev: true - /axios@0.27.2: - resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} + /axios@1.6.7: + resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} dependencies: - follow-redirects: 1.15.3 + follow-redirects: 1.15.5 form-data: 4.0.0 + proxy-from-env: 1.1.0 transitivePeerDependencies: - debug dev: false @@ -1786,7 +2039,7 @@ packages: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 cosmiconfig: 7.1.0 resolve: 1.22.8 dev: false @@ -1804,6 +2057,12 @@ packages: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} @@ -1811,27 +2070,26 @@ packages: dependencies: fill-range: 7.0.1 - /browserslist@4.22.1: - resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==} + /browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001555 - electron-to-chromium: 1.4.569 - node-releases: 2.0.13 - update-browserslist-db: 1.0.13(browserslist@4.22.1) + caniuse-lite: 1.0.30001594 + electron-to-chromium: 1.4.693 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.23.0) dev: true - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true - - /call-bind@1.0.5: - resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.2 - set-function-length: 1.1.1 + get-intrinsic: 1.2.4 + set-function-length: 1.2.1 dev: true /callsites@3.1.0: @@ -1843,8 +2101,8 @@ packages: engines: {node: '>= 6'} dev: false - /caniuse-lite@1.0.30001555: - resolution: {integrity: sha512-NzbUFKUnJ3DTcq6YyZB6+qqhfD112uR3uoEnkmfzm2wVzUNsFkU7AwBjKQ654Sp5cau0JxhFyRSn/tQZ+XfygA==} + /caniuse-lite@1.0.30001594: + resolution: {integrity: sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==} dev: true /chalk@2.4.2: @@ -1863,8 +2121,12 @@ packages: supports-color: 7.2.0 dev: true - /chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + /character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + dev: false + + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} dependencies: anymatch: 3.1.3 @@ -1878,12 +2140,12 @@ packages: fsevents: 2.3.3 dev: false - /classnames@2.3.2: - resolution: {integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==} + /classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} dev: false - /clsx@2.0.0: - resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} + /clsx@2.1.0: + resolution: {integrity: sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==} engines: {node: '>=6'} dev: false @@ -1897,14 +2159,12 @@ packages: engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 - dev: true /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true /combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} @@ -1913,15 +2173,16 @@ packages: delayed-stream: 1.0.0 dev: false - /commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: true - /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} dev: false + /commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + dev: false + /commander@8.3.0: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} @@ -1929,9 +2190,15 @@ packages: /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true /convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: false + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true /copy-anything@2.0.6: resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} @@ -1945,11 +2212,17 @@ packages: toggle-selection: 1.0.6 dev: false + /cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + dependencies: + layout-base: 1.0.2 + dev: false + /cosmiconfig@7.1.0: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} engines: {node: '>=10'} dependencies: - '@types/parse-json': 4.0.1 + '@types/parse-json': 4.0.2 import-fresh: 3.3.0 parse-json: 5.2.0 path-type: 4.0.0 @@ -1963,7 +2236,6 @@ packages: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - dev: true /css-in-js-utils@3.1.0: resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==} @@ -1988,18 +2260,304 @@ packages: /csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} - /debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - requiresBuild: true + /cytoscape-cose-bilkent@4.1.0(cytoscape@3.28.1): + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + cytoscape: ^3.2.0 dependencies: - ms: 2.1.3 - dev: true - optional: true + cose-base: 1.0.3 + cytoscape: 3.28.1 + dev: false + + /cytoscape@3.28.1: + resolution: {integrity: sha512-xyItz4O/4zp9/239wCcH8ZcFuuZooEeF8KHRmzjDfGdXsj3OG9MFSMA0pJE0uX3uCN/ygof6hHf4L7lst+JaDg==} + engines: {node: '>=0.10'} + dependencies: + heap: 0.2.7 + lodash: 4.17.21 + dev: false + + /d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + dependencies: + internmap: 1.0.1 + dev: false + + /d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + dependencies: + internmap: 2.0.3 + dev: false + + /d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + dev: false + + /d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + dev: false + + /d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + dependencies: + d3-path: 3.1.0 + dev: false + + /d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + dev: false + + /d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + dev: false + + /d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + dependencies: + delaunator: 5.0.1 + dev: false + + /d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + dev: false + + /d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + dev: false + + /d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + dev: false + + /d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + dev: false + + /d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + dependencies: + d3-dsv: 3.0.1 + dev: false + + /d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + dev: false + + /d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + dev: false + + /d3-geo@3.1.0: + resolution: {integrity: sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + dev: false + + /d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + dev: false + + /d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + dependencies: + d3-color: 3.1.0 + dev: false + + /d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + dev: false + + /d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + dev: false + + /d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + dev: false + + /d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + dev: false + + /d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + dev: false + + /d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + dev: false + + /d3-scale-chromatic@3.0.0: + resolution: {integrity: sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==} + engines: {node: '>=12'} + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + dev: false + + /d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + dev: false + + /d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + dev: false + + /d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + dependencies: + d3-path: 1.0.9 + dev: false + + /d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + dependencies: + d3-path: 3.1.0 + dev: false + + /d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + dependencies: + d3-time: 3.1.0 + dev: false + + /d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + dev: false + + /d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + dev: false + + /d3-transition@3.0.1(d3-selection@3.0.0): + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + dev: false + + /d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + dev: false + + /d3@7.8.5: + resolution: {integrity: sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.0 + d3-geo: 3.1.0 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.0.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + dev: false + + /dagre-d3-es@7.0.10: + resolution: {integrity: sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==} + dependencies: + d3: 7.8.5 + lodash-es: 4.17.21 + dev: false + + /dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dev: false /debug@4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} @@ -2011,39 +2569,60 @@ packages: optional: true dependencies: ms: 2.1.2 - dev: true + + /decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + dependencies: + character-entities: 2.0.2 + dev: false /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true - /define-data-property@1.1.1: - resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 + es-define-property: 1.0.0 + es-errors: 1.3.0 gopd: 1.0.1 - has-property-descriptors: 1.0.1 dev: true /define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 - has-property-descriptors: 1.0.1 + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 object-keys: 1.1.1 dev: true + /delaunator@5.0.1: + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + dependencies: + robust-predicates: 3.0.2 + dev: false + /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} dev: false + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: false + /didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} dev: false + /diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} + engines: {node: '>=0.3.1'} + dev: false + /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -2069,10 +2648,30 @@ packages: esutils: 2.0.3 dev: true - /electron-to-chromium@1.4.569: - resolution: {integrity: sha512-LsrJjZ0IbVy12ApW3gpYpcmHS3iRxH4bkKOW98y1/D+3cvDUWGcbzbsFinfUS8knpcZk/PG/2p/RnkMCYN7PVg==} + /dompurify@3.0.9: + resolution: {integrity: sha512-uyb4NDIvQ3hRn6NiC+SIFaP4mJ/MdXlvtunaqK9Bn6dD3RuB/1S/gasEjDHD8eiaqdSael2vBv+hOs7Y+jhYOQ==} + dev: false + + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: false + + /electron-to-chromium@1.4.693: + resolution: {integrity: sha512-/if4Ueg0GUQlhCrW2ZlXwDAm40ipuKo+OgeHInlL8sbjt+hzISxZK949fZeJaVsheamrzANXvw1zQTvbxTvSHw==} dev: true + /elkjs@0.9.2: + resolution: {integrity: sha512-2Y/RaA1pdgSHpY0YG4TYuYCD2wh97CRvu22eLG3Kz0pgQ/6KbIFTxsTnDc4MH/6hFlg2L/9qXrDMG0nMjP63iw==} + dev: false + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: false + + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: false + /errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} hasBin: true @@ -2094,83 +2693,99 @@ packages: stackframe: 1.3.4 dev: false - /es-abstract@1.22.3: - resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} + /es-abstract@1.22.5: + resolution: {integrity: sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==} engines: {node: '>= 0.4'} dependencies: - array-buffer-byte-length: 1.0.0 - arraybuffer.prototype.slice: 1.0.2 - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 - es-set-tostringtag: 2.0.2 + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 - get-intrinsic: 1.2.2 - get-symbol-description: 1.0.0 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 globalthis: 1.0.3 gopd: 1.0.1 - has-property-descriptors: 1.0.1 - has-proto: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.0 - internal-slot: 1.0.6 - is-array-buffer: 3.0.2 + hasown: 2.0.1 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 is-callable: 1.2.7 - is-negative-zero: 2.0.2 + is-negative-zero: 2.0.3 is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 + is-shared-array-buffer: 1.0.3 is-string: 1.0.7 - is-typed-array: 1.1.12 + is-typed-array: 1.1.13 is-weakref: 1.0.2 object-inspect: 1.13.1 object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.5.1 - safe-array-concat: 1.0.1 - safe-regex-test: 1.0.0 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.0 + safe-regex-test: 1.0.3 string.prototype.trim: 1.2.8 string.prototype.trimend: 1.0.7 string.prototype.trimstart: 1.0.7 - typed-array-buffer: 1.0.0 - typed-array-byte-length: 1.0.0 - typed-array-byte-offset: 1.0.0 - typed-array-length: 1.0.4 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.5 unbox-primitive: 1.0.2 - which-typed-array: 1.1.13 + which-typed-array: 1.1.14 + dev: true + + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 dev: true - /es-iterator-helpers@1.0.15: - resolution: {integrity: sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==} + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + dev: true + + /es-iterator-helpers@1.0.17: + resolution: {integrity: sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==} + engines: {node: '>= 0.4'} dependencies: asynciterator.prototype: 1.0.0 - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 - es-set-tostringtag: 2.0.2 + es-abstract: 1.22.5 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 function-bind: 1.1.2 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 globalthis: 1.0.3 - has-property-descriptors: 1.0.1 - has-proto: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 has-symbols: 1.0.3 - internal-slot: 1.0.6 + internal-slot: 1.0.7 iterator.prototype: 1.1.2 - safe-array-concat: 1.0.1 + safe-array-concat: 1.1.0 dev: true - /es-set-tostringtag@2.0.2: - resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} + /es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 - has-tostringtag: 1.0.0 - hasown: 2.0.0 + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.1 dev: true /es-shim-unscopables@1.0.2: resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} dependencies: - hasown: 2.0.0 + hasown: 2.0.1 dev: true /es-to-primitive@1.2.1: @@ -2182,38 +2797,39 @@ packages: is-symbol: 1.0.4 dev: true - /esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + /esbuild@0.19.12: + resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 - dev: true - - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + '@esbuild/aix-ppc64': 0.19.12 + '@esbuild/android-arm': 0.19.12 + '@esbuild/android-arm64': 0.19.12 + '@esbuild/android-x64': 0.19.12 + '@esbuild/darwin-arm64': 0.19.12 + '@esbuild/darwin-x64': 0.19.12 + '@esbuild/freebsd-arm64': 0.19.12 + '@esbuild/freebsd-x64': 0.19.12 + '@esbuild/linux-arm': 0.19.12 + '@esbuild/linux-arm64': 0.19.12 + '@esbuild/linux-ia32': 0.19.12 + '@esbuild/linux-loong64': 0.19.12 + '@esbuild/linux-mips64el': 0.19.12 + '@esbuild/linux-ppc64': 0.19.12 + '@esbuild/linux-riscv64': 0.19.12 + '@esbuild/linux-s390x': 0.19.12 + '@esbuild/linux-x64': 0.19.12 + '@esbuild/netbsd-x64': 0.19.12 + '@esbuild/openbsd-x64': 0.19.12 + '@esbuild/sunos-x64': 0.19.12 + '@esbuild/win32-arm64': 0.19.12 + '@esbuild/win32-ia32': 0.19.12 + '@esbuild/win32-x64': 0.19.12 + dev: true + + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} dev: true @@ -2225,44 +2841,50 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - /eslint-config-prettier@8.10.0(eslint@8.52.0): + /eslint-config-prettier@8.10.0(eslint@8.57.0): resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.52.0 + eslint: 8.57.0 dev: true - /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0)(eslint@8.52.0)(prettier@2.6.2): - resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} - engines: {node: '>=12.0.0'} + /eslint-plugin-prettier@5.1.3(eslint-config-prettier@8.10.0)(eslint@8.57.0)(prettier@3.2.5): + resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} + engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - eslint: '>=7.28.0' + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' eslint-config-prettier: '*' - prettier: '>=2.0.0' + prettier: '>=3.0.0' peerDependenciesMeta: + '@types/eslint': + optional: true eslint-config-prettier: optional: true dependencies: - eslint: 8.52.0 - eslint-config-prettier: 8.10.0(eslint@8.52.0) - prettier: 2.6.2 + eslint: 8.57.0 + eslint-config-prettier: 8.10.0(eslint@8.57.0) + prettier: 3.2.5 prettier-linter-helpers: 1.0.0 + synckit: 0.8.8 dev: true - /eslint-plugin-react@7.33.2(eslint@8.52.0): - resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} + /eslint-plugin-react@7.34.0(eslint@8.57.0): + resolution: {integrity: sha512-MeVXdReleBTdkz/bvcQMSnCXGi+c9kvy51IpinjnJgutl3YTHWsDdke7Z1ufZpGfDG8xduBDKyjtB9JH1eBKIQ==} engines: {node: '>=4'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 dependencies: array-includes: 3.1.7 + array.prototype.findlast: 1.2.4 array.prototype.flatmap: 1.3.2 - array.prototype.tosorted: 1.1.2 + array.prototype.toreversed: 1.1.2 + array.prototype.tosorted: 1.1.3 doctrine: 2.1.0 - es-iterator-helpers: 1.0.15 - eslint: 8.52.0 + es-iterator-helpers: 1.0.17 + eslint: 8.57.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.5 minimatch: 3.1.2 @@ -2289,16 +2911,16 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.52.0: - resolution: {integrity: sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==} + /eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.52.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@eslint-community/regexpp': 4.10.0 - '@eslint/eslintrc': 2.1.2 - '@eslint/js': 8.52.0 - '@humanwhocodes/config-array': 0.11.13 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 '@ungap/structured-clone': 1.2.0 @@ -2317,9 +2939,9 @@ packages: file-entry-cache: 6.0.1 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.23.0 + globals: 13.24.0 graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.1 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -2340,8 +2962,8 @@ packages: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 8.11.2 - acorn-jsx: 5.3.2(acorn@8.11.2) + acorn: 8.11.3 + acorn-jsx: 5.3.2(acorn@8.11.3) eslint-visitor-keys: 3.4.3 dev: true @@ -2364,10 +2986,6 @@ packages: engines: {node: '>=4.0'} dev: true - /estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - dev: true - /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -2380,8 +2998,8 @@ packages: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} dev: true - /fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} dependencies: '@nodelib/fs.stat': 2.0.5 @@ -2410,8 +3028,8 @@ packages: resolution: {integrity: sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==} dev: false - /fastq@1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + /fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} dependencies: reusify: 1.0.4 @@ -2419,7 +3037,7 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: - flat-cache: 3.1.1 + flat-cache: 3.2.0 dev: true /fill-range@7.0.1: @@ -2440,21 +3058,21 @@ packages: path-exists: 4.0.0 dev: true - /flat-cache@3.1.1: - resolution: {integrity: sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==} - engines: {node: '>=12.0.0'} + /flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} dependencies: - flatted: 3.2.9 + flatted: 3.3.1 keyv: 4.5.4 rimraf: 3.0.2 dev: true - /flatted@3.2.9: - resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} + /flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} dev: true - /follow-redirects@1.15.3: - resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==} + /follow-redirects@1.15.5: + resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -2469,6 +3087,14 @@ packages: is-callable: 1.2.7 dev: true + /foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + dev: false + /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -2484,6 +3110,7 @@ packages: /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true /fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} @@ -2499,9 +3126,9 @@ packages: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.22.5 functions-have-names: 1.2.3 dev: true @@ -2509,26 +3136,34 @@ packages: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} dev: true + /fuse.js@7.0.0: + resolution: {integrity: sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==} + engines: {node: '>=10'} + dev: false + /gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} dev: true - /get-intrinsic@1.2.2: - resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} dependencies: + es-errors: 1.3.0 function-bind: 1.1.2 - has-proto: 1.0.1 + has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.0 + hasown: 2.0.1 dev: true - /get-symbol-description@1.0.0: - resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + /get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 dev: true /glob-parent@5.1.2: @@ -2540,18 +3175,19 @@ packages: /glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - dependencies: - is-glob: 4.0.3 - - /glob@7.1.6: - resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 + dependencies: + is-glob: 4.0.3 + + /glob@10.3.10: + resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.3 + minipass: 7.0.4 + path-scurry: 1.10.1 dev: false /glob@7.2.3: @@ -2570,8 +3206,8 @@ packages: engines: {node: '>=4'} dev: true - /globals@13.23.0: - resolution: {integrity: sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==} + /globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} dependencies: type-fest: 0.20.2 @@ -2590,16 +3226,16 @@ packages: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.3.1 - ignore: 5.2.4 + fast-glob: 3.3.2 + ignore: 5.3.1 merge2: 1.4.1 slash: 3.0.0 dev: true - /goober@2.1.13(csstype@3.1.2): - resolution: {integrity: sha512-jFj3BQeleOoy7t93E9rZ2de+ScC4lQICLwiAQmKMg9F6roKGaLSHoCDYKkWlSafg138jejvq/mTdvmnwDQgqoQ==} + /goober@2.1.14(csstype@3.1.2): + resolution: {integrity: sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==} peerDependencies: - csstype: ^3.0.10 + csstype: 3.1.2 dependencies: csstype: 3.1.2 dev: false @@ -2607,7 +3243,7 @@ packages: /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 dev: true /graceful-fs@4.2.11: @@ -2633,14 +3269,14 @@ packages: engines: {node: '>=8'} dev: true - /has-property-descriptors@1.0.1: - resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} dependencies: - get-intrinsic: 1.2.2 + es-define-property: 1.0.0 dev: true - /has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} engines: {node: '>= 0.4'} dev: true @@ -2649,19 +3285,23 @@ packages: engines: {node: '>= 0.4'} dev: true - /has-tostringtag@1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 dev: true - /hasown@2.0.0: - resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + /hasown@2.0.1: + resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} engines: {node: '>= 0.4'} dependencies: function-bind: 1.1.2 + /heap@0.2.7: + resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} + dev: false + /highlight.js@11.9.0: resolution: {integrity: sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==} engines: {node: '>=12.0.0'} @@ -2683,16 +3323,10 @@ packages: resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==} dev: false - /i18next-browser-languagedetector@7.1.0: - resolution: {integrity: sha512-cr2k7u1XJJ4HTOjM9GyOMtbOA47RtUoWRAtt52z43r3AoMs2StYKyjS3URPhzHaf+mn10hY9dZWamga5WPQjhA==} - dependencies: - '@babel/runtime': 7.23.2 - dev: false - /i18next@21.10.0: resolution: {integrity: sha512-YeuIBmFsGjUfO3qBmMOc0rQaun4mIpGKET5WDwvu8lU7gvwpcariZLNtL0Fzj+zazcHUrlXHiptcFhBMFaxzfg==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 dev: false /iconv-lite@0.6.3: @@ -2701,11 +3335,9 @@ packages: requiresBuild: true dependencies: safer-buffer: 2.1.2 - dev: true - optional: true - /ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + /ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} dev: true @@ -2738,32 +3370,43 @@ packages: dependencies: once: 1.4.0 wrappy: 1.0.2 + dev: true /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true - /inline-style-prefixer@6.0.4: - resolution: {integrity: sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg==} + /inline-style-prefixer@7.0.0: + resolution: {integrity: sha512-I7GEdScunP1dQ6IM2mQWh6v0mOYdYmH3Bp31UecKdrcUgcURTcctSe1IECdUznSHKSmsHtjrT3CwCPI1pyxfUQ==} dependencies: css-in-js-utils: 3.1.0 fast-loops: 1.1.3 dev: false - /internal-slot@1.0.6: - resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} + /internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 - hasown: 2.0.0 - side-channel: 1.0.4 + es-errors: 1.3.0 + hasown: 2.0.1 + side-channel: 1.0.6 dev: true - /is-array-buffer@3.0.2: - resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + /internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + dev: false + + /internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + dev: false + + /is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - is-typed-array: 1.1.12 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 dev: true /is-arrayish@0.2.1: @@ -2774,7 +3417,7 @@ packages: resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /is-bigint@1.0.4: @@ -2794,8 +3437,8 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 dev: true /is-callable@1.2.7: @@ -2806,13 +3449,13 @@ packages: /is-core-module@2.13.1: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} dependencies: - hasown: 2.0.0 + hasown: 2.0.1 /is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /is-extglob@2.1.1: @@ -2822,14 +3465,19 @@ packages: /is-finalizationregistry@1.0.2: resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 dev: true + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: false + /is-generator-function@1.0.10: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /is-glob@4.0.3: @@ -2842,8 +3490,8 @@ packages: resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} dev: true - /is-negative-zero@2.0.2: - resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + /is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} dev: true @@ -2851,7 +3499,7 @@ packages: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /is-number@7.0.0: @@ -2867,25 +3515,26 @@ packages: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 dev: true /is-set@2.0.2: resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} dev: true - /is-shared-array-buffer@1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + /is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 dev: true /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /is-symbol@1.0.4: @@ -2895,11 +3544,11 @@ packages: has-symbols: 1.0.3 dev: true - /is-typed-array@1.1.12: - resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + /is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} engines: {node: '>= 0.4'} dependencies: - which-typed-array: 1.1.13 + which-typed-array: 1.1.14 dev: true /is-weakmap@2.0.1: @@ -2909,14 +3558,14 @@ packages: /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 dev: true /is-weakset@2.0.2: resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 dev: true /is-what@3.14.1: @@ -2929,38 +3578,46 @@ packages: /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true - /isomorphic-ws@5.0.0(ws@8.14.2): + /isomorphic-ws@5.0.0(ws@8.16.0): resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} peerDependencies: ws: '*' dependencies: - ws: 8.14.2 - dev: false + ws: 8.16.0 + dev: true /iterator.prototype@1.1.2: resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} dependencies: define-properties: 1.2.1 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 - reflect.getprototypeof: 1.0.4 - set-function-name: 2.0.1 + reflect.getprototypeof: 1.0.5 + set-function-name: 2.0.2 dev: true + /jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: false + /javascript-natural-sort@0.7.1: resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} dev: true - /jiti@1.20.0: - resolution: {integrity: sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==} + /jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} hasBin: true dev: false - /js-base64@3.7.5: - resolution: {integrity: sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA==} - dev: false + /js-base64@3.7.7: + resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} + dev: true /js-cookie@2.2.1: resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} @@ -3010,7 +3667,7 @@ packages: dependencies: array-includes: 3.1.7 array.prototype.flat: 1.3.2 - object.assign: 4.1.4 + object.assign: 4.1.5 object.values: 1.1.7 dev: true @@ -3027,6 +3684,19 @@ packages: json-buffer: 3.0.1 dev: true + /khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + dev: false + + /kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + dev: false + + /layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + dev: false + /less@4.2.0: resolution: {integrity: sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==} engines: {node: '>=6'} @@ -3041,10 +3711,8 @@ packages: image-size: 0.5.5 make-dir: 2.1.0 mime: 1.6.0 - needle: 3.2.0 + needle: 3.3.1 source-map: 0.6.1 - transitivePeerDependencies: - - supports-color dev: true /levn@0.4.1: @@ -3060,6 +3728,11 @@ packages: engines: {node: '>=10'} dev: false + /lilconfig@3.1.1: + resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} + engines: {node: '>=14'} + dev: false + /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: false @@ -3081,11 +3754,10 @@ packages: /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true /long@5.2.3: resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} - dev: false + dev: true /loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} @@ -3093,6 +3765,11 @@ packages: dependencies: js-tokens: 4.0.0 + /lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} + engines: {node: 14 || >=16.14} + dev: false + /lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} dependencies: @@ -3104,22 +3781,16 @@ packages: engines: {node: '>=10'} dependencies: yallist: 4.0.0 + dev: true - /lucide-react@0.263.1(react@18.2.0): - resolution: {integrity: sha512-keqxAx97PlaEN89PXZ6ki1N8nRjGWtDa4021GFYLNj0RgruM5odbpl8GHTExj0hhPq3sF6Up0gnxt6TSHu+ovw==} + /lucide-react@0.309.0(react@18.2.0): + resolution: {integrity: sha512-zNVPczuwFrCfksZH3zbd1UDE6/WYhYAdbe2k7CImVyPAkXLgIwbs6eXQ4loigqDnUFjyFYCI5jZ1y10Kqal0dg==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 dependencies: react: 18.2.0 dev: false - /magic-string@0.30.5: - resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - /make-dir@2.1.0: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} engines: {node: '>=6'} @@ -3130,6 +3801,31 @@ packages: dev: true optional: true + /mdast-util-from-markdown@1.3.1: + resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} + dependencies: + '@types/mdast': 3.0.15 + '@types/unist': 2.0.10 + decode-named-character-reference: 1.0.2 + mdast-util-to-string: 3.2.0 + micromark: 3.2.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-decode-string: 1.1.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + unist-util-stringify-position: 3.0.3 + uvu: 0.5.6 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-to-string@3.2.0: + resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==} + dependencies: + '@types/mdast': 3.0.15 + dev: false + /mdn-data@2.0.14: resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} dev: false @@ -3138,6 +3834,208 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + /mermaid@10.9.0: + resolution: {integrity: sha512-swZju0hFox/B/qoLKK0rOxxgh8Cf7rJSfAUc1u8fezVihYMvrJAS45GzAxTVf4Q+xn9uMgitBcmWk7nWGXOs/g==} + dependencies: + '@braintree/sanitize-url': 6.0.4 + '@types/d3-scale': 4.0.8 + '@types/d3-scale-chromatic': 3.0.3 + cytoscape: 3.28.1 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.28.1) + d3: 7.8.5 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.10 + dayjs: 1.11.10 + dompurify: 3.0.9 + elkjs: 0.9.2 + katex: 0.16.9 + khroma: 2.1.0 + lodash-es: 4.17.21 + mdast-util-from-markdown: 1.3.1 + non-layered-tidy-tree-layout: 2.0.2 + stylis: 4.3.1 + ts-dedent: 2.2.0 + uuid: 9.0.1 + web-worker: 1.3.0 + transitivePeerDependencies: + - supports-color + dev: false + + /micromark-core-commonmark@1.1.0: + resolution: {integrity: sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==} + dependencies: + decode-named-character-reference: 1.0.2 + micromark-factory-destination: 1.1.0 + micromark-factory-label: 1.1.0 + micromark-factory-space: 1.1.0 + micromark-factory-title: 1.1.0 + micromark-factory-whitespace: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-chunked: 1.1.0 + micromark-util-classify-character: 1.1.0 + micromark-util-html-tag-name: 1.2.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-resolve-all: 1.1.0 + micromark-util-subtokenize: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + dev: false + + /micromark-factory-destination@1.1.0: + resolution: {integrity: sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==} + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + dev: false + + /micromark-factory-label@1.1.0: + resolution: {integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==} + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + dev: false + + /micromark-factory-space@1.1.0: + resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + dependencies: + micromark-util-character: 1.2.0 + micromark-util-types: 1.1.0 + dev: false + + /micromark-factory-title@1.1.0: + resolution: {integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==} + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + dev: false + + /micromark-factory-whitespace@1.1.0: + resolution: {integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==} + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + dev: false + + /micromark-util-character@1.2.0: + resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + dependencies: + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + dev: false + + /micromark-util-chunked@1.1.0: + resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==} + dependencies: + micromark-util-symbol: 1.1.0 + dev: false + + /micromark-util-classify-character@1.1.0: + resolution: {integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==} + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + dev: false + + /micromark-util-combine-extensions@1.1.0: + resolution: {integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==} + dependencies: + micromark-util-chunked: 1.1.0 + micromark-util-types: 1.1.0 + dev: false + + /micromark-util-decode-numeric-character-reference@1.1.0: + resolution: {integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==} + dependencies: + micromark-util-symbol: 1.1.0 + dev: false + + /micromark-util-decode-string@1.1.0: + resolution: {integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==} + dependencies: + decode-named-character-reference: 1.0.2 + micromark-util-character: 1.2.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-symbol: 1.1.0 + dev: false + + /micromark-util-encode@1.1.0: + resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==} + dev: false + + /micromark-util-html-tag-name@1.2.0: + resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==} + dev: false + + /micromark-util-normalize-identifier@1.1.0: + resolution: {integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==} + dependencies: + micromark-util-symbol: 1.1.0 + dev: false + + /micromark-util-resolve-all@1.1.0: + resolution: {integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==} + dependencies: + micromark-util-types: 1.1.0 + dev: false + + /micromark-util-sanitize-uri@1.2.0: + resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==} + dependencies: + micromark-util-character: 1.2.0 + micromark-util-encode: 1.1.0 + micromark-util-symbol: 1.1.0 + dev: false + + /micromark-util-subtokenize@1.1.0: + resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==} + dependencies: + micromark-util-chunked: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + dev: false + + /micromark-util-symbol@1.1.0: + resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + dev: false + + /micromark-util-types@1.1.0: + resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + dev: false + + /micromark@3.2.0: + resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==} + dependencies: + '@types/debug': 4.1.12 + debug: 4.3.4 + decode-named-character-reference: 1.0.2 + micromark-core-commonmark: 1.1.0 + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-chunked: 1.1.0 + micromark-util-combine-extensions: 1.1.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-encode: 1.1.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-resolve-all: 1.1.0 + micromark-util-sanitize-uri: 1.2.0 + micromark-util-subtokenize: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + transitivePeerDependencies: + - supports-color + dev: false + /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -3169,16 +4067,26 @@ packages: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 + dev: true + + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + + /minipass@7.0.4: + resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} + engines: {node: '>=16 || 14 >=14.17'} + dev: false + + /mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: false /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true - - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - requiresBuild: true - dev: true - optional: true /mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -3188,26 +4096,26 @@ packages: thenify-all: 1.6.0 dev: false - /nano-css@5.3.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg==} + /nano-css@5.6.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-T2Mhc//CepkTa3X4pUhKgbEheJHYAxD0VptuqFhDbGMUWVV2m+lkNiW/Ieuj35wrfC8Zm0l7HvssQh7zcEttSw==} peerDependencies: react: '*' react-dom: '*' dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 css-tree: 1.1.3 csstype: 3.1.2 fastest-stable-stringify: 2.0.2 - inline-style-prefixer: 6.0.4 + inline-style-prefixer: 7.0.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) rtl-css-js: 1.16.1 - sourcemap-codec: 1.4.8 stacktrace-js: 2.0.2 - stylis: 4.3.0 + stylis: 4.3.1 dev: false - /nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -3215,17 +4123,14 @@ packages: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true - /needle@3.2.0: - resolution: {integrity: sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==} + /needle@3.3.1: + resolution: {integrity: sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==} engines: {node: '>= 4.4.x'} hasBin: true requiresBuild: true dependencies: - debug: 3.2.7 iconv-lite: 0.6.3 sax: 1.3.0 - transitivePeerDependencies: - - supports-color dev: true optional: true @@ -3233,23 +4138,27 @@ packages: resolution: {integrity: sha512-7RNWbls5kAL1QVUOXvBsv1uO0wPQK3lHv+cY1gwkTzirnG1Nop4cBJZubpgziNbaVc/bl9QJcyvsf/NQxa3rjQ==} dependencies: ts-error: 1.0.6 - dev: false + dev: true - /nice-grpc-web@3.3.2(ws@8.14.2): + /nice-grpc-web@3.3.2(ws@8.16.0): resolution: {integrity: sha512-qetU+H6y6jVvI5NZdtTls9UdqdCNwhr4UxqL5SfH6v8ISxucxDVPRYxnZaoZyWjMRvRgAKiQDIMu0bB0oedD0A==} dependencies: abort-controller-x: 0.4.3 - isomorphic-ws: 5.0.0(ws@8.14.2) - js-base64: 3.7.5 + isomorphic-ws: 5.0.0(ws@8.16.0) + js-base64: 3.7.7 nice-grpc-common: 2.0.2 transitivePeerDependencies: - ws - dev: false + dev: true - /node-releases@2.0.13: - resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} dev: true + /non-layered-tidy-tree-layout@2.0.2: + resolution: {integrity: sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==} + dev: false + /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -3278,11 +4187,11 @@ packages: engines: {node: '>= 0.4'} dev: true - /object.assign@4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + /object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 @@ -3292,40 +4201,41 @@ packages: resolution: {integrity: sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.22.5 dev: true /object.fromentries@2.0.7: resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.22.5 dev: true /object.hasown@1.1.3: resolution: {integrity: sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==} dependencies: define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.22.5 dev: true /object.values@1.1.7: resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.22.5 dev: true /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 + dev: true /optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} @@ -3363,7 +4273,7 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: - '@babel/code-frame': 7.22.13 + '@babel/code-frame': 7.23.5 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -3382,15 +4292,23 @@ packages: /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} + dev: true /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - dev: true /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + /path-scurry@1.10.1: + resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 10.2.0 + minipass: 7.0.4 + dev: false + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -3419,30 +4337,35 @@ packages: engines: {node: '>= 6'} dev: false - /postcss-import@15.1.0(postcss@8.4.31): + /possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + dev: true + + /postcss-import@15.1.0(postcss@8.4.35): resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} peerDependencies: postcss: ^8.0.0 dependencies: - postcss: 8.4.31 + postcss: 8.4.35 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 dev: false - /postcss-js@4.0.1(postcss@8.4.31): + /postcss-js@4.0.1(postcss@8.4.35): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 dependencies: camelcase-css: 2.0.1 - postcss: 8.4.31 + postcss: 8.4.35 dev: false - /postcss-load-config@4.0.1(postcss@8.4.31): - resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} + /postcss-load-config@4.0.2(postcss@8.4.35): + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} engines: {node: '>= 14'} peerDependencies: postcss: '>=8.0.9' @@ -3453,23 +4376,23 @@ packages: ts-node: optional: true dependencies: - lilconfig: 2.1.0 - postcss: 8.4.31 - yaml: 2.3.3 + lilconfig: 3.1.1 + postcss: 8.4.35 + yaml: 2.4.1 dev: false - /postcss-nested@6.0.1(postcss@8.4.31): + /postcss-nested@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.2.14 dependencies: - postcss: 8.4.31 - postcss-selector-parser: 6.0.13 + postcss: 8.4.35 + postcss-selector-parser: 6.0.15 dev: false - /postcss-selector-parser@6.0.13: - resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==} + /postcss-selector-parser@6.0.15: + resolution: {integrity: sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==} engines: {node: '>=4'} dependencies: cssesc: 3.0.0 @@ -3479,11 +4402,11 @@ packages: /postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - /postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + /postcss@8.4.35: + resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==} engines: {node: ^10 || ^12 || >=14} dependencies: - nanoid: 3.3.6 + nanoid: 3.3.7 picocolors: 1.0.0 source-map-js: 1.0.2 @@ -3499,9 +4422,9 @@ packages: fast-diff: 1.3.0 dev: true - /prettier@2.6.2: - resolution: {integrity: sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==} - engines: {node: '>=10.13.0'} + /prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + engines: {node: '>=14'} hasBin: true dev: true @@ -3512,8 +4435,8 @@ packages: object-assign: 4.1.1 react-is: 16.13.1 - /protobufjs@7.2.5: - resolution: {integrity: sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==} + /protobufjs@7.2.6: + resolution: {integrity: sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==} engines: {node: '>=12.0.0'} requiresBuild: true dependencies: @@ -3527,8 +4450,12 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 18.18.7 + '@types/node': 20.11.24 long: 5.2.3 + dev: true + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} dev: false /prr@1.0.1: @@ -3537,8 +4464,8 @@ packages: dev: true optional: true - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} dev: true @@ -3562,7 +4489,7 @@ packages: react: '>=16' react-dom: '>=16' dependencies: - goober: 2.1.13(csstype@3.1.2) + goober: 2.1.14(csstype@3.1.2) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) transitivePeerDependencies: @@ -3582,7 +4509,7 @@ packages: react-native: optional: true dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 html-parse-stringify: 3.0.1 i18next: 21.10.0 react: 18.2.0 @@ -3596,7 +4523,7 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: false - /react-redux@8.1.3(@types/react-dom@18.2.14)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1): + /react-redux@8.1.3(@types/react-dom@18.2.20)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1): resolution: {integrity: sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==} peerDependencies: '@types/react': ^16.8 || ^17.0 || ^18.0 @@ -3617,10 +4544,10 @@ packages: redux: optional: true dependencies: - '@babel/runtime': 7.23.2 - '@types/hoist-non-react-statics': 3.3.4 - '@types/react': 18.2.33 - '@types/react-dom': 18.2.14 + '@babel/runtime': 7.24.0 + '@types/hoist-non-react-statics': 3.3.5 + '@types/react': 18.2.63 + '@types/react-dom': 18.2.20 '@types/use-sync-external-store': 0.0.3 hoist-non-react-statics: 3.3.2 react: 18.2.0 @@ -3630,26 +4557,31 @@ packages: use-sync-external-store: 1.2.0(react@18.2.0) dev: false - /react-router-dom@6.17.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-qWHkkbXQX+6li0COUUPKAUkxjNNqPJuiBd27dVwQGDNsuFBdMbrS6UZ0CLYc4CsbdLYTckn4oB4tGDuPZpPhaQ==} + /react-refresh@0.14.0: + resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + engines: {node: '>=0.10.0'} + dev: true + + /react-router-dom@6.22.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-WgqxD2qySEIBPZ3w0sHH+PUAiamDeszls9tzqMPBDA1YYVucTBXLU7+gtRfcSnhe92A3glPnvSxK2dhNoAVOIQ==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' dependencies: - '@remix-run/router': 1.10.0 + '@remix-run/router': 1.15.2 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-router: 6.17.0(react@18.2.0) + react-router: 6.22.2(react@18.2.0) dev: false - /react-router@6.17.0(react@18.2.0): - resolution: {integrity: sha512-YJR3OTJzi3zhqeJYADHANCGPUu9J+6fT5GLv82UWRGSxu6oJYCKVmxUcaBQuGm9udpWmPsvpme/CdHumqgsoaA==} + /react-router@6.22.2(react@18.2.0): + resolution: {integrity: sha512-YD3Dzprzpcq+tBMHBS822tCjnWD3iIZbTeSXMY9LPSG541EfoBGyZ3bS25KEnaZjLcmQpw2AVLkFyfgXY8uvcw==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' dependencies: - '@remix-run/router': 1.10.0 + '@remix-run/router': 1.15.2 react: 18.2.0 dev: false @@ -3663,11 +4595,11 @@ packages: tslib: 2.6.2 dev: false - /react-use@17.4.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-TgbNTCA33Wl7xzIJegn1HndB4qTS9u03QUwyNycUnXaweZkE4Kq2SB+Yoxx8qbshkZGYBDvUXbXWRUmQDcZZ/Q==} + /react-use@17.5.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-PbfwSPMwp/hoL847rLnm/qkjg3sTRCvn6YhUZiHaUa3FA6/aNoFX79ul5Xt70O1rK+9GxSVqkY0eTwMdsR/bWg==} peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react: '*' + react-dom: '*' dependencies: '@types/js-cookie': 2.2.7 '@xobotyi/scrollbar-width': 1.9.5 @@ -3675,7 +4607,7 @@ packages: fast-deep-equal: 3.1.3 fast-shallow-equal: 1.0.0 js-cookie: 2.2.1 - nano-css: 5.3.5(react-dom@18.2.0)(react@18.2.0) + nano-css: 5.6.1(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-universal-interface: 0.6.2(react@18.2.0)(tslib@2.6.2) @@ -3718,32 +4650,34 @@ packages: /redux@4.2.1: resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 dev: false - /reflect.getprototypeof@1.0.4: - resolution: {integrity: sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==} + /reflect.getprototypeof@1.0.5: + resolution: {integrity: sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 + es-abstract: 1.22.5 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 globalthis: 1.0.3 which-builtin-type: 1.1.3 dev: true - /regenerator-runtime@0.14.0: - resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} dev: false - /regexp.prototype.flags@1.5.1: - resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} + /regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - set-function-name: 2.0.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 dev: true /reselect@4.1.8: @@ -3787,18 +4721,37 @@ packages: glob: 7.2.3 dev: true - /rollup@3.29.4: - resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} + /robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + dev: false + + /rollup@4.12.1: + resolution: {integrity: sha512-ggqQKvx/PsB0FaWXhIvVkSWh7a/PCLQAsMjBc+nA2M8Rv2/HG0X6zvixAB7KyZBRtifBUhy5k8voQX/mRnABPg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + dependencies: + '@types/estree': 1.0.5 optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.12.1 + '@rollup/rollup-android-arm64': 4.12.1 + '@rollup/rollup-darwin-arm64': 4.12.1 + '@rollup/rollup-darwin-x64': 4.12.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.12.1 + '@rollup/rollup-linux-arm64-gnu': 4.12.1 + '@rollup/rollup-linux-arm64-musl': 4.12.1 + '@rollup/rollup-linux-riscv64-gnu': 4.12.1 + '@rollup/rollup-linux-x64-gnu': 4.12.1 + '@rollup/rollup-linux-x64-musl': 4.12.1 + '@rollup/rollup-win32-arm64-msvc': 4.12.1 + '@rollup/rollup-win32-ia32-msvc': 4.12.1 + '@rollup/rollup-win32-x64-msvc': 4.12.1 fsevents: 2.3.3 dev: true /rtl-css-js@1.16.1: resolution: {integrity: sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.24.0 dev: false /run-parallel@1.2.0: @@ -3806,29 +4759,39 @@ packages: dependencies: queue-microtask: 1.2.3 - /safe-array-concat@1.0.1: - resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} + /rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + dev: false + + /sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + dependencies: + mri: 1.2.0 + dev: false + + /safe-array-concat@1.1.0: + resolution: {integrity: sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==} engines: {node: '>=0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 isarray: 2.0.5 dev: true - /safe-regex-test@1.0.0: - resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + /safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + es-errors: 1.3.0 is-regex: 1.1.4 dev: true /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} requiresBuild: true - dev: true - optional: true /sax@1.3.0: resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==} @@ -3859,30 +4822,34 @@ packages: hasBin: true dev: true - /semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + /semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} engines: {node: '>=10'} hasBin: true dependencies: lru-cache: 6.0.0 + dev: true - /set-function-length@1.1.1: - resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + /set-function-length@1.2.1: + resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 - get-intrinsic: 1.2.2 + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 gopd: 1.0.1 - has-property-descriptors: 1.0.1 + has-property-descriptors: 1.0.2 dev: true - /set-function-name@2.0.1: - resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} + /set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 + define-data-property: 1.1.4 + es-errors: 1.3.0 functions-have-names: 1.2.3 - has-property-descriptors: 1.0.1 + has-property-descriptors: 1.0.2 dev: true /set-harmonic-interval@1.0.1: @@ -3895,21 +4862,26 @@ packages: engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 - dev: true /shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - dev: true - /side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + /side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 object-inspect: 1.13.1 dev: true + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: false + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -3919,13 +4891,6 @@ packages: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} - /source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: true - /source-map@0.5.6: resolution: {integrity: sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==} engines: {node: '>=0.10.0'} @@ -3939,11 +4904,6 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - /sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - dev: false - /stack-generator@2.0.10: resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==} dependencies: @@ -3969,43 +4929,61 @@ packages: stacktrace-gps: 3.1.2 dev: false + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: false + + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + dev: false + /string.prototype.matchall@4.0.10: resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 - get-intrinsic: 1.2.2 + es-abstract: 1.22.5 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 - internal-slot: 1.0.6 - regexp.prototype.flags: 1.5.1 - set-function-name: 2.0.1 - side-channel: 1.0.4 + internal-slot: 1.0.7 + regexp.prototype.flags: 1.5.2 + set-function-name: 2.0.2 + side-channel: 1.0.6 dev: true /string.prototype.trim@1.2.8: resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.22.5 dev: true /string.prototype.trimend@1.0.7: resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.22.5 dev: true /string.prototype.trimstart@1.0.7: resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.22.3 + es-abstract: 1.22.5 dev: true /strip-ansi@6.0.1: @@ -4013,7 +4991,13 @@ packages: engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 - dev: true + + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: false /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} @@ -4024,18 +5008,18 @@ packages: resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} dev: false - /stylis@4.3.0: - resolution: {integrity: sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ==} + /stylis@4.3.1: + resolution: {integrity: sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==} dev: false - /sucrase@3.34.0: - resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==} - engines: {node: '>=8'} + /sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} hasBin: true dependencies: - '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/gen-mapping': 0.3.5 commander: 4.1.1 - glob: 7.1.6 + glob: 10.3.10 lines-and-columns: 1.2.4 mz: 2.7.0 pirates: 4.0.6 @@ -4059,48 +5043,45 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /tailwindcss@3.3.5: - resolution: {integrity: sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==} + /synckit@0.8.8: + resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} + engines: {node: ^14.18.0 || >=16.0.0} + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.6.2 + dev: true + + /tailwindcss@3.4.1: + resolution: {integrity: sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==} engines: {node: '>=14.0.0'} hasBin: true dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 - chokidar: 3.5.3 + chokidar: 3.6.0 didyoumean: 1.2.2 dlv: 1.1.3 - fast-glob: 3.3.1 + fast-glob: 3.3.2 glob-parent: 6.0.2 is-glob: 4.0.3 - jiti: 1.20.0 + jiti: 1.21.0 lilconfig: 2.1.0 micromatch: 4.0.5 normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.0 - postcss: 8.4.31 - postcss-import: 15.1.0(postcss@8.4.31) - postcss-js: 4.0.1(postcss@8.4.31) - postcss-load-config: 4.0.1(postcss@8.4.31) - postcss-nested: 6.0.1(postcss@8.4.31) - postcss-selector-parser: 6.0.13 + postcss: 8.4.35 + postcss-import: 15.1.0(postcss@8.4.35) + postcss-js: 4.0.1(postcss@8.4.35) + postcss-load-config: 4.0.2(postcss@8.4.35) + postcss-nested: 6.0.1(postcss@8.4.35) + postcss-selector-parser: 6.0.15 resolve: 1.22.8 - sucrase: 3.34.0 + sucrase: 3.35.0 transitivePeerDependencies: - ts-node dev: false - /terser@5.22.0: - resolution: {integrity: sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw==} - engines: {node: '>=10'} - hasBin: true - dependencies: - '@jridgewell/source-map': 0.3.5 - acorn: 8.11.2 - commander: 2.20.3 - source-map-support: 0.5.21 - dev: true - /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true @@ -4141,22 +5122,27 @@ packages: resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} dev: false - /ts-api-utils@1.0.3(typescript@5.2.2): - resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} - engines: {node: '>=16.13.0'} + /ts-api-utils@1.2.1(typescript@5.3.3): + resolution: {integrity: sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==} + engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.2.2 + typescript: 5.3.3 dev: true + /ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + dev: false + /ts-easing@0.2.0: resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==} dev: false /ts-error@1.0.6: resolution: {integrity: sha512-tLJxacIQUM82IR7JO1UUkKlYuUTmoY9HBJAmNWFzheSlDS5SPMcNIepejHJa4BpPQLAcbRhRf3GDJzyj6rbKvA==} - dev: false + dev: true /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} @@ -4177,46 +5163,52 @@ packages: engines: {node: '>=10'} dev: true - /typed-array-buffer@1.0.0: - resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} + /typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 - is-typed-array: 1.1.12 + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 dev: true - /typed-array-byte-length@1.0.0: - resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} + /typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 - has-proto: 1.0.1 - is-typed-array: 1.1.12 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 dev: true - /typed-array-byte-offset@1.0.0: - resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} + /typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} engines: {node: '>= 0.4'} dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 for-each: 0.3.3 - has-proto: 1.0.1 - is-typed-array: 1.1.12 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 dev: true - /typed-array-length@1.0.4: - resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + /typed-array-length@1.0.5: + resolution: {integrity: sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 for-each: 0.3.3 - is-typed-array: 1.1.12 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 dev: true - /typescript@5.2.2: - resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} engines: {node: '>=14.17'} hasBin: true dev: true @@ -4224,7 +5216,7 @@ packages: /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: - call-bind: 1.0.5 + call-bind: 1.0.7 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 @@ -4232,22 +5224,29 @@ packages: /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + + /unist-util-stringify-position@3.0.3: + resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} + dependencies: + '@types/unist': 2.0.10 + dev: false - /update-browserslist-db@1.0.13(browserslist@4.22.1): + /update-browserslist-db@1.0.13(browserslist@4.23.0): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.22.1 - escalade: 3.1.1 + browserslist: 4.23.0 + escalade: 3.1.2 picocolors: 1.0.0 dev: true /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 dev: true /use-sync-external-store@1.2.0(react@18.2.0): @@ -4267,12 +5266,23 @@ packages: hasBin: true dev: false - /vite@4.5.0(@types/node@18.18.7)(less@4.2.0)(terser@5.22.0): - resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} - engines: {node: ^14.18.0 || >=16.0.0} + /uvu@0.5.6: + resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + dequal: 2.0.3 + diff: 5.2.0 + kleur: 4.1.5 + sade: 1.8.1 + dev: false + + /vite@5.1.5(@types/node@20.11.24)(less@4.2.0): + resolution: {integrity: sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - '@types/node': '>= 14' + '@types/node': ^18.0.0 || >=20.0.0 less: '*' lightningcss: ^1.21.0 sass: '*' @@ -4295,12 +5305,11 @@ packages: terser: optional: true dependencies: - '@types/node': 18.18.7 - esbuild: 0.18.20 + '@types/node': 20.11.24 + esbuild: 0.19.12 less: 4.2.0 - postcss: 8.4.31 - rollup: 3.29.4 - terser: 5.22.0 + postcss: 8.4.35 + rollup: 4.12.1 optionalDependencies: fsevents: 2.3.3 dev: true @@ -4310,6 +5319,10 @@ packages: engines: {node: '>=0.10.0'} dev: false + /web-worker@1.3.0: + resolution: {integrity: sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==} + dev: false + /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: @@ -4325,7 +5338,7 @@ packages: engines: {node: '>= 0.4'} dependencies: function.prototype.name: 1.1.6 - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-async-function: 2.0.0 is-date-object: 1.0.5 is-finalizationregistry: 1.0.2 @@ -4335,7 +5348,7 @@ packages: isarray: 2.0.5 which-boxed-primitive: 1.0.2 which-collection: 1.0.1 - which-typed-array: 1.1.13 + which-typed-array: 1.1.14 dev: true /which-collection@1.0.1: @@ -4347,15 +5360,15 @@ packages: is-weakset: 2.0.2 dev: true - /which-typed-array@1.1.13: - resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} + /which-typed-array@1.1.14: + resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==} engines: {node: '>= 0.4'} dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /which@2.0.2: @@ -4364,13 +5377,31 @@ packages: hasBin: true dependencies: isexe: 2.0.0 - dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: false + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + dev: false /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true - /ws@8.14.2: - resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} + /ws@8.16.0: + resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -4380,7 +5411,7 @@ packages: optional: true utf-8-validate: optional: true - dev: false + dev: true /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -4388,15 +5419,17 @@ packages: /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true /yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} dev: false - /yaml@2.3.3: - resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==} + /yaml@2.4.1: + resolution: {integrity: sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==} engines: {node: '>= 14'} + hasBin: true dev: false /yocto-queue@0.1.0: @@ -4404,12 +5437,12 @@ packages: engines: {node: '>=10'} dev: true - /zustand@4.4.4(@types/react@18.2.33)(react@18.2.0): - resolution: {integrity: sha512-5UTUIAiHMNf5+mFp7/AnzJXS7+XxktULFN0+D1sCiZWyX7ZG+AQpqs2qpYrynRij4QvoDdCD+U+bmg/cG3Ucxw==} + /zustand@4.5.2(@types/react@18.2.63)(react@18.2.0): + resolution: {integrity: sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g==} engines: {node: '>=12.7.0'} peerDependencies: '@types/react': '>=16.8' - immer: '>=9.0' + immer: '>=9.0.6' react: '>=16.8' peerDependenciesMeta: '@types/react': @@ -4419,7 +5452,7 @@ packages: react: optional: true dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.63 react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) dev: false diff --git a/web/public/android-chrome-192x192.png b/web/public/android-chrome-192x192.png new file mode 100644 index 0000000000000..778cf7561dfda Binary files /dev/null and b/web/public/android-chrome-192x192.png differ diff --git a/web/public/android-chrome-512x512.png b/web/public/android-chrome-512x512.png new file mode 100644 index 0000000000000..5fd83fff786a2 Binary files /dev/null and b/web/public/android-chrome-512x512.png differ diff --git a/web/public/apple-touch-icon.png b/web/public/apple-touch-icon.png new file mode 100644 index 0000000000000..e816963292033 Binary files /dev/null and b/web/public/apple-touch-icon.png differ diff --git a/web/public/logo.png b/web/public/logo.png deleted file mode 100644 index 029df083aa269..0000000000000 Binary files a/web/public/logo.png and /dev/null differ diff --git a/web/public/logo.webp b/web/public/logo.webp index b17f939bf351e..522a5d9eccad7 100644 Binary files a/web/public/logo.webp and b/web/public/logo.webp differ diff --git a/web/public/manifest.json b/web/public/manifest.json deleted file mode 100644 index 5b74785cbc7a0..0000000000000 --- a/web/public/manifest.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "short_name": "memos", - "name": "memos", - "description": "usememos/memos", - "icons": [ - { - "src": "/logo.png", - "type": "image/png" - } - ], - "start_url": "/", - "scope": "/", - "display": "standalone", - "theme_color": "#f4f4f5", - "background_color": "#f4f4f5" -} diff --git a/web/public/site.webmanifest b/web/public/site.webmanifest new file mode 100644 index 0000000000000..3e37c16a11b4f --- /dev/null +++ b/web/public/site.webmanifest @@ -0,0 +1,11 @@ +{ + "name": "Memos", + "short_name": "", + "icons": [ + { "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, + { "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/web/public/sw.js b/web/public/sw.js deleted file mode 100644 index aeee59a0292b2..0000000000000 --- a/web/public/sw.js +++ /dev/null @@ -1,10 +0,0 @@ -self.addEventListener("install", (event) => { - event.waitUntil((async () => {})()); - }); - - self.addEventListener("activate", (event) => { - event.waitUntil((async () => {})()); - }); - - self.addEventListener("fetch", (event) => {}); - \ No newline at end of file diff --git a/web/src/App.tsx b/web/src/App.tsx index 13906505eef97..01c4a1e791751 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -1,23 +1,26 @@ import { useColorScheme } from "@mui/joy"; -import { Suspense, useEffect, useState } from "react"; +import { useEffect } from "react"; import { useTranslation } from "react-i18next"; import { Outlet } from "react-router-dom"; import storage from "./helpers/storage"; import { getSystemColorScheme } from "./helpers/utils"; import useNavigateTo from "./hooks/useNavigateTo"; -import Loading from "./pages/Loading"; -import store from "./store"; import { useGlobalStore } from "./store/module"; -import { useUserV1Store } from "./store/v1"; +import { useUserStore, useWorkspaceSettingStore } from "./store/v1"; +import { WorkspaceGeneralSetting, WorkspaceSettingKey } from "./types/proto/store/workspace_setting"; const App = () => { const { i18n } = useTranslation(); const navigateTo = useNavigateTo(); - const globalStore = useGlobalStore(); const { mode, setMode } = useColorScheme(); - const userV1Store = useUserV1Store(); - const [loading, setLoading] = useState(true); + const globalStore = useGlobalStore(); + const workspaceSettingStore = useWorkspaceSettingStore(); + const userStore = useUserStore(); const { appearance, locale, systemStatus } = globalStore.state; + const userSetting = userStore.userSetting; + const workspaceGeneralSetting = + workspaceSettingStore.getWorkspaceSettingByKey(WorkspaceSettingKey.WORKSPACE_SETTING_GENERAL).generalSetting || + WorkspaceGeneralSetting.fromPartial({}); // Redirect to sign up page if no host. useEffect(() => { @@ -26,18 +29,6 @@ const App = () => { } }, [systemStatus.host]); - useEffect(() => { - const initialState = async () => { - const { user } = store.getState().user; - if (user) { - await userV1Store.getOrFetchUserByUsername(user.username); - } - setLoading(false); - }; - - initialState(); - }, []); - useEffect(() => { const darkMediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); const handleColorSchemeChange = (e: MediaQueryListEvent) => { @@ -59,53 +50,63 @@ const App = () => { }, []); useEffect(() => { - if (systemStatus.additionalStyle) { + if (workspaceGeneralSetting.additionalStyle) { const styleEl = document.createElement("style"); - styleEl.innerHTML = systemStatus.additionalStyle; + styleEl.innerHTML = workspaceGeneralSetting.additionalStyle; styleEl.setAttribute("type", "text/css"); document.body.insertAdjacentElement("beforeend", styleEl); } - }, [systemStatus.additionalStyle]); + }, [workspaceGeneralSetting.additionalStyle]); useEffect(() => { - if (systemStatus.additionalScript) { + if (workspaceGeneralSetting.additionalScript) { const scriptEl = document.createElement("script"); - scriptEl.innerHTML = systemStatus.additionalScript; + scriptEl.innerHTML = workspaceGeneralSetting.additionalScript; document.head.appendChild(scriptEl); } - }, [systemStatus.additionalScript]); + }, [workspaceGeneralSetting.additionalScript]); + // Dynamic update metadata with customized profile. useEffect(() => { - // dynamic update metadata with customized profile. document.title = systemStatus.customizedProfile.name; const link = document.querySelector("link[rel~='icon']") as HTMLLinkElement; - link.href = systemStatus.customizedProfile.logoUrl || "/logo.png"; + link.href = systemStatus.customizedProfile.logoUrl || "/logo.webp"; }, [systemStatus.customizedProfile]); useEffect(() => { - document.documentElement.setAttribute("lang", locale); - i18n.changeLanguage(locale); - storage.set({ - locale: locale, - }); - if (locale === "ar") { + if (!userSetting) { + return; + } + + globalStore.setLocale(userSetting.locale); + globalStore.setAppearance(userSetting.appearance as Appearance); + }, [userSetting?.locale, userSetting?.appearance]); + + useEffect(() => { + const { locale: storageLocale } = storage.get(["locale"]); + const currentLocale = storageLocale || locale; + i18n.changeLanguage(currentLocale); + document.documentElement.setAttribute("lang", currentLocale); + if (currentLocale === "ar") { document.documentElement.setAttribute("dir", "rtl"); } else { document.documentElement.setAttribute("dir", "ltr"); } - }, [locale]); - - useEffect(() => { storage.set({ - appearance: appearance, + locale: currentLocale, }); + }, [locale]); - let currentAppearance = appearance; - if (appearance === "system") { + useEffect(() => { + const { appearance: storageAppearance } = storage.get(["appearance"]); + let currentAppearance = (storageAppearance || appearance) as Appearance; + if (currentAppearance === "system") { currentAppearance = getSystemColorScheme(); } - setMode(currentAppearance); + storage.set({ + appearance: currentAppearance, + }); }, [appearance]); useEffect(() => { @@ -117,13 +118,7 @@ const App = () => { } }, [mode]); - return loading ? ( - - ) : ( - }> - - - ); + return ; }; export default App; diff --git a/web/src/assets/gomark.wasm b/web/src/assets/gomark.wasm new file mode 100755 index 0000000000000..aa876e5db6f32 Binary files /dev/null and b/web/src/assets/gomark.wasm differ diff --git a/web/src/assets/wasm_exec.js b/web/src/assets/wasm_exec.js new file mode 100644 index 0000000000000..480c2a4f75415 --- /dev/null +++ b/web/src/assets/wasm_exec.js @@ -0,0 +1,587 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This file has been modified for use by the TinyGo compiler. + +(() => { + // Map multiple JavaScript environments to a single common API, + // preferring web standards over Node.js API. + // + // Environments considered: + // - Browsers + // - Node.js + // - Electron + // - Parcel + + if (typeof global !== "undefined") { + // global already exists + } else if (typeof window !== "undefined") { + window.global = window; + } else if (typeof self !== "undefined") { + self.global = self; + } else { + throw new Error("cannot export Go (neither global, window nor self is defined)"); + } + + if (!global.require && typeof require !== "undefined") { + global.require = require; + } + + if (!global.fs && global.require) { + global.fs = require("fs"); + } + + const enosys = () => { + const err = new Error("not implemented"); + err.code = "ENOSYS"; + return err; + }; + + if (!global.fs) { + let outputBuf = ""; + global.fs = { + constants: { O_WRONLY: -1, O_RDWR: -1, O_CREAT: -1, O_TRUNC: -1, O_APPEND: -1, O_EXCL: -1 }, // unused + writeSync(fd, buf) { + outputBuf += decoder.decode(buf); + const nl = outputBuf.lastIndexOf("\n"); + if (nl != -1) { + console.log(outputBuf.substr(0, nl)); + outputBuf = outputBuf.substr(nl + 1); + } + return buf.length; + }, + write(fd, buf, offset, length, position, callback) { + if (offset !== 0 || length !== buf.length || position !== null) { + callback(enosys()); + return; + } + const n = this.writeSync(fd, buf); + callback(null, n); + }, + chmod(path, mode, callback) { + callback(enosys()); + }, + chown(path, uid, gid, callback) { + callback(enosys()); + }, + close(fd, callback) { + callback(enosys()); + }, + fchmod(fd, mode, callback) { + callback(enosys()); + }, + fchown(fd, uid, gid, callback) { + callback(enosys()); + }, + fstat(fd, callback) { + callback(enosys()); + }, + fsync(fd, callback) { + callback(null); + }, + ftruncate(fd, length, callback) { + callback(enosys()); + }, + lchown(path, uid, gid, callback) { + callback(enosys()); + }, + link(path, link, callback) { + callback(enosys()); + }, + lstat(path, callback) { + callback(enosys()); + }, + mkdir(path, perm, callback) { + callback(enosys()); + }, + open(path, flags, mode, callback) { + callback(enosys()); + }, + read(fd, buffer, offset, length, position, callback) { + callback(enosys()); + }, + readdir(path, callback) { + callback(enosys()); + }, + readlink(path, callback) { + callback(enosys()); + }, + rename(from, to, callback) { + callback(enosys()); + }, + rmdir(path, callback) { + callback(enosys()); + }, + stat(path, callback) { + callback(enosys()); + }, + symlink(path, link, callback) { + callback(enosys()); + }, + truncate(path, length, callback) { + callback(enosys()); + }, + unlink(path, callback) { + callback(enosys()); + }, + utimes(path, atime, mtime, callback) { + callback(enosys()); + }, + }; + } + + if (!global.process) { + global.process = { + getuid() { + return -1; + }, + getgid() { + return -1; + }, + geteuid() { + return -1; + }, + getegid() { + return -1; + }, + getgroups() { + throw enosys(); + }, + pid: -1, + ppid: -1, + umask() { + throw enosys(); + }, + cwd() { + throw enosys(); + }, + chdir() { + throw enosys(); + }, + }; + } + + if (!global.crypto) { + const nodeCrypto = require("crypto"); + global.crypto = { + getRandomValues(b) { + nodeCrypto.randomFillSync(b); + }, + }; + } + + if (!global.performance) { + global.performance = { + now() { + const [sec, nsec] = process.hrtime(); + return sec * 1000 + nsec / 1000000; + }, + }; + } + + if (!global.TextEncoder) { + global.TextEncoder = require("util").TextEncoder; + } + + if (!global.TextDecoder) { + global.TextDecoder = require("util").TextDecoder; + } + + // End of polyfills for common API. + + const encoder = new TextEncoder("utf-8"); + const decoder = new TextDecoder("utf-8"); + let reinterpretBuf = new DataView(new ArrayBuffer(8)); + var logLine = []; + + global.Go = class { + constructor() { + this._callbackTimeouts = new Map(); + this._nextCallbackTimeoutID = 1; + + const mem = () => { + // The buffer may change when requesting more memory. + return new DataView(this._inst.exports.memory.buffer); + }; + + const unboxValue = (v_ref) => { + reinterpretBuf.setBigInt64(0, v_ref, true); + const f = reinterpretBuf.getFloat64(0, true); + if (f === 0) { + return undefined; + } + if (!isNaN(f)) { + return f; + } + + const id = v_ref & 0xffffffffn; + return this._values[id]; + }; + + const loadValue = (addr) => { + let v_ref = mem().getBigUint64(addr, true); + return unboxValue(v_ref); + }; + + const boxValue = (v) => { + const nanHead = 0x7ff80000n; + + if (typeof v === "number") { + if (isNaN(v)) { + return nanHead << 32n; + } + if (v === 0) { + return (nanHead << 32n) | 1n; + } + reinterpretBuf.setFloat64(0, v, true); + return reinterpretBuf.getBigInt64(0, true); + } + + switch (v) { + case undefined: + return 0n; + case null: + return (nanHead << 32n) | 2n; + case true: + return (nanHead << 32n) | 3n; + case false: + return (nanHead << 32n) | 4n; + } + + let id = this._ids.get(v); + if (id === undefined) { + id = this._idPool.pop(); + if (id === undefined) { + id = BigInt(this._values.length); + } + this._values[id] = v; + this._goRefCounts[id] = 0; + this._ids.set(v, id); + } + this._goRefCounts[id]++; + let typeFlag = 1n; + switch (typeof v) { + case "string": + typeFlag = 2n; + break; + case "symbol": + typeFlag = 3n; + break; + case "function": + typeFlag = 4n; + break; + } + return id | ((nanHead | typeFlag) << 32n); + }; + + const storeValue = (addr, v) => { + let v_ref = boxValue(v); + mem().setBigUint64(addr, v_ref, true); + }; + + const loadSlice = (array, len, cap) => { + return new Uint8Array(this._inst.exports.memory.buffer, array, len); + }; + + const loadSliceOfValues = (array, len, cap) => { + const a = new Array(len); + for (let i = 0; i < len; i++) { + a[i] = loadValue(array + i * 8); + } + return a; + }; + + const loadString = (ptr, len) => { + return decoder.decode(new DataView(this._inst.exports.memory.buffer, ptr, len)); + }; + + const timeOrigin = Date.now() - performance.now(); + this.importObject = { + wasi_snapshot_preview1: { + // https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#fd_write + fd_write: function (fd, iovs_ptr, iovs_len, nwritten_ptr) { + let nwritten = 0; + if (fd == 1) { + for (let iovs_i = 0; iovs_i < iovs_len; iovs_i++) { + let iov_ptr = iovs_ptr + iovs_i * 8; // assuming wasm32 + let ptr = mem().getUint32(iov_ptr + 0, true); + let len = mem().getUint32(iov_ptr + 4, true); + nwritten += len; + for (let i = 0; i < len; i++) { + let c = mem().getUint8(ptr + i); + if (c == 13) { + // CR + // ignore + } else if (c == 10) { + // LF + // write line + let line = decoder.decode(new Uint8Array(logLine)); + logLine = []; + console.log(line); + } else { + logLine.push(c); + } + } + } + } else { + console.error("invalid file descriptor:", fd); + } + mem().setUint32(nwritten_ptr, nwritten, true); + return 0; + }, + fd_close: () => 0, // dummy + fd_fdstat_get: () => 0, // dummy + fd_seek: () => 0, // dummy + proc_exit: (code) => { + if (global.process) { + // Node.js + process.exit(code); + } else { + // Can't exit in a browser. + throw "trying to exit with code " + code; + } + }, + random_get: (bufPtr, bufLen) => { + crypto.getRandomValues(loadSlice(bufPtr, bufLen)); + return 0; + }, + }, + gojs: { + // func ticks() float64 + "runtime.ticks": () => { + return timeOrigin + performance.now(); + }, + + // func sleepTicks(timeout float64) + "runtime.sleepTicks": (timeout) => { + // Do not sleep, only reactivate scheduler after the given timeout. + setTimeout(this._inst.exports.go_scheduler, timeout); + }, + + // func finalizeRef(v ref) + "syscall/js.finalizeRef": (v_ref) => { + // Note: TinyGo does not support finalizers so this should never be + // called. + console.warn("syscall/js.finalizeRef not implemented"); + }, + + // func stringVal(value string) ref + "syscall/js.stringVal": (value_ptr, value_len) => { + const s = loadString(value_ptr, value_len); + return boxValue(s); + }, + + // func valueGet(v ref, p string) ref + "syscall/js.valueGet": (v_ref, p_ptr, p_len) => { + let prop = loadString(p_ptr, p_len); + let v = unboxValue(v_ref); + let result = Reflect.get(v, prop); + return boxValue(result); + }, + + // func valueSet(v ref, p string, x ref) + "syscall/js.valueSet": (v_ref, p_ptr, p_len, x_ref) => { + const v = unboxValue(v_ref); + const p = loadString(p_ptr, p_len); + const x = unboxValue(x_ref); + Reflect.set(v, p, x); + }, + + // func valueDelete(v ref, p string) + "syscall/js.valueDelete": (v_ref, p_ptr, p_len) => { + const v = unboxValue(v_ref); + const p = loadString(p_ptr, p_len); + Reflect.deleteProperty(v, p); + }, + + // func valueIndex(v ref, i int) ref + "syscall/js.valueIndex": (v_ref, i) => { + return boxValue(Reflect.get(unboxValue(v_ref), i)); + }, + + // valueSetIndex(v ref, i int, x ref) + "syscall/js.valueSetIndex": (v_ref, i, x_ref) => { + Reflect.set(unboxValue(v_ref), i, unboxValue(x_ref)); + }, + + // func valueCall(v ref, m string, args []ref) (ref, bool) + "syscall/js.valueCall": (ret_addr, v_ref, m_ptr, m_len, args_ptr, args_len, args_cap) => { + const v = unboxValue(v_ref); + const name = loadString(m_ptr, m_len); + const args = loadSliceOfValues(args_ptr, args_len, args_cap); + try { + const m = Reflect.get(v, name); + storeValue(ret_addr, Reflect.apply(m, v, args)); + mem().setUint8(ret_addr + 8, 1); + } catch (err) { + storeValue(ret_addr, err); + mem().setUint8(ret_addr + 8, 0); + } + }, + + // func valueInvoke(v ref, args []ref) (ref, bool) + "syscall/js.valueInvoke": (ret_addr, v_ref, args_ptr, args_len, args_cap) => { + try { + const v = unboxValue(v_ref); + const args = loadSliceOfValues(args_ptr, args_len, args_cap); + storeValue(ret_addr, Reflect.apply(v, undefined, args)); + mem().setUint8(ret_addr + 8, 1); + } catch (err) { + storeValue(ret_addr, err); + mem().setUint8(ret_addr + 8, 0); + } + }, + + // func valueNew(v ref, args []ref) (ref, bool) + "syscall/js.valueNew": (ret_addr, v_ref, args_ptr, args_len, args_cap) => { + const v = unboxValue(v_ref); + const args = loadSliceOfValues(args_ptr, args_len, args_cap); + try { + storeValue(ret_addr, Reflect.construct(v, args)); + mem().setUint8(ret_addr + 8, 1); + } catch (err) { + storeValue(ret_addr, err); + mem().setUint8(ret_addr + 8, 0); + } + }, + + // func valueLength(v ref) int + "syscall/js.valueLength": (v_ref) => { + return unboxValue(v_ref).length; + }, + + // valuePrepareString(v ref) (ref, int) + "syscall/js.valuePrepareString": (ret_addr, v_ref) => { + const s = String(unboxValue(v_ref)); + const str = encoder.encode(s); + storeValue(ret_addr, str); + mem().setInt32(ret_addr + 8, str.length, true); + }, + + // valueLoadString(v ref, b []byte) + "syscall/js.valueLoadString": (v_ref, slice_ptr, slice_len, slice_cap) => { + const str = unboxValue(v_ref); + loadSlice(slice_ptr, slice_len, slice_cap).set(str); + }, + + // func valueInstanceOf(v ref, t ref) bool + "syscall/js.valueInstanceOf": (v_ref, t_ref) => { + return unboxValue(v_ref) instanceof unboxValue(t_ref); + }, + + // func copyBytesToGo(dst []byte, src ref) (int, bool) + "syscall/js.copyBytesToGo": (ret_addr, dest_addr, dest_len, dest_cap, src_ref) => { + let num_bytes_copied_addr = ret_addr; + let returned_status_addr = ret_addr + 4; // Address of returned boolean status variable + + const dst = loadSlice(dest_addr, dest_len); + const src = unboxValue(src_ref); + if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) { + mem().setUint8(returned_status_addr, 0); // Return "not ok" status + return; + } + const toCopy = src.subarray(0, dst.length); + dst.set(toCopy); + mem().setUint32(num_bytes_copied_addr, toCopy.length, true); + mem().setUint8(returned_status_addr, 1); // Return "ok" status + }, + + // copyBytesToJS(dst ref, src []byte) (int, bool) + // Originally copied from upstream Go project, then modified: + // https://github.com/golang/go/blob/3f995c3f3b43033013013e6c7ccc93a9b1411ca9/misc/wasm/wasm_exec.js#L404-L416 + "syscall/js.copyBytesToJS": (ret_addr, dst_ref, src_addr, src_len, src_cap) => { + let num_bytes_copied_addr = ret_addr; + let returned_status_addr = ret_addr + 4; // Address of returned boolean status variable + + const dst = unboxValue(dst_ref); + const src = loadSlice(src_addr, src_len); + if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) { + mem().setUint8(returned_status_addr, 0); // Return "not ok" status + return; + } + const toCopy = src.subarray(0, dst.length); + dst.set(toCopy); + mem().setUint32(num_bytes_copied_addr, toCopy.length, true); + mem().setUint8(returned_status_addr, 1); // Return "ok" status + }, + }, + }; + + // Go 1.20 uses 'env'. Go 1.21 uses 'gojs'. + // For compatibility, we use both as long as Go 1.20 is supported. + this.importObject.env = this.importObject.gojs; + } + + async run(instance) { + this._inst = instance; + this._values = [ + // JS values that Go currently has references to, indexed by reference id + NaN, + 0, + null, + true, + false, + global, + this, + ]; + this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference id + this._ids = new Map(); // mapping from JS values to reference ids + this._idPool = []; // unused ids that have been garbage collected + this.exited = false; // whether the Go program has exited + + while (true) { + const callbackPromise = new Promise((resolve) => { + this._resolveCallbackPromise = () => { + if (this.exited) { + throw new Error("bad callback: Go program has already exited"); + } + setTimeout(resolve, 0); // make sure it is asynchronous + }; + }); + this._inst.exports._start(); + if (this.exited) { + break; + } + await callbackPromise; + } + } + + _resume() { + if (this.exited) { + throw new Error("Go program has already exited"); + } + this._inst.exports.resume(); + if (this.exited) { + this._resolveExitPromise(); + } + } + + _makeFuncWrapper(id) { + const go = this; + return function () { + const event = { id: id, this: this, args: arguments }; + go._pendingEvent = event; + go._resume(); + return event.result; + }; + } + }; + + if (global.require && global.require.main === module && global.process && global.process.versions && !global.process.versions.electron) { + if (process.argv.length != 3) { + console.error("usage: go_js_wasm_exec [wasm binary] [arguments]"); + process.exit(1); + } + + const go = new Go(); + WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject) + .then((result) => { + return go.run(result.instance); + }) + .catch((err) => { + console.error(err); + process.exit(1); + }); + } +})(); diff --git a/web/src/components/AboutSiteDialog.tsx b/web/src/components/AboutSiteDialog.tsx deleted file mode 100644 index bff26dbf71248..0000000000000 --- a/web/src/components/AboutSiteDialog.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { Divider } from "@mui/joy"; -import { useGlobalStore } from "@/store/module"; -import { useTranslate } from "@/utils/i18n"; -import { generateDialog } from "./Dialog"; -import Icon from "./Icon"; - -type Props = DialogProps; - -const AboutSiteDialog: React.FC = ({ destroy }: Props) => { - const t = useTranslate(); - const globalStore = useGlobalStore(); - const profile = globalStore.state.systemStatus.profile; - const customizedProfile = globalStore.state.systemStatus.customizedProfile; - - const handleCloseBtnClick = () => { - destroy(); - }; - - return ( - <> -
-

- {t("common.about")} {customizedProfile.name} -

- -
-
-

{t("about.memos-description")}

-

{customizedProfile.description || t("about.no-server-description")}

- -
- {t("about.powered-by")} - - - - v{profile.version} -
-
- - ); -}; - -export default function showAboutSiteDialog(): void { - generateDialog( - { - className: "about-site-dialog", - dialogName: "about-site-dialog", - }, - AboutSiteDialog - ); -} diff --git a/web/src/components/ActivityCalendar.tsx b/web/src/components/ActivityCalendar.tsx new file mode 100644 index 0000000000000..feb030408b05c --- /dev/null +++ b/web/src/components/ActivityCalendar.tsx @@ -0,0 +1,83 @@ +import { Tooltip } from "@mui/joy"; +import classNames from "classnames"; +import { getNormalizedDateString, getDateWithOffset } from "@/helpers/datetime"; + +interface Props { + // Format: 2021-1 + month: string; + data: Record; + onClick?: (date: string) => void; +} + +const getCellAdditionalStyles = (count: number, maxCount: number) => { + if (count === 0) { + return "bg-gray-100 text-gray-400 dark:bg-gray-700 dark:text-gray-500"; + } + + const ratio = count / maxCount; + if (ratio > 0.7) { + return "bg-blue-600 text-gray-100 dark:opacity-80"; + } else if (ratio > 0.4) { + return "bg-blue-400 text-gray-200 dark:opacity-80"; + } else { + return "bg-blue-300 text-gray-600 dark:opacity-80"; + } +}; + +const ActivityCalendar = (props: Props) => { + const { month: monthStr, data, onClick } = props; + const year = new Date(monthStr).getUTCFullYear(); + const month = new Date(monthStr).getUTCMonth() + 1; + const dayInMonth = new Date(year, month, 0).getDate(); + const firstDay = new Date(year, month - 1, 1).getDay(); + const lastDay = new Date(year, month - 1, dayInMonth).getDay(); + const maxCount = Math.max(...Object.values(data)); + const days = []; + + for (let i = 0; i < firstDay; i++) { + days.push(0); + } + for (let i = 1; i <= dayInMonth; i++) { + days.push(i); + } + for (let i = 0; i < 6 - lastDay; i++) { + days.push(0); + } + + return ( +
+ {days.map((day, index) => { + const date = getNormalizedDateString( + getDateWithOffset(`${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`), + ); + const count = data[date] || 0; + const isToday = new Date().toDateString() === new Date(date).toDateString(); + const tooltipText = count ? `${count} memos in ${date}` : date; + return day ? ( + +
count && onClick && onClick(date)} + > + {day} +
+
+ ) : ( +
+ ); + })} +
+ ); +}; + +export default ActivityCalendar; diff --git a/web/src/components/ArchivedMemo.tsx b/web/src/components/ArchivedMemo.tsx deleted file mode 100644 index 4ac5786918d27..0000000000000 --- a/web/src/components/ArchivedMemo.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { Tooltip } from "@mui/joy"; -import { toast } from "react-hot-toast"; -import { getDateTimeString } from "@/helpers/datetime"; -import { useMemoStore } from "@/store/module"; -import { useTranslate } from "@/utils/i18n"; -import { showCommonDialog } from "./Dialog/CommonDialog"; -import Icon from "./Icon"; -import MemoContent from "./MemoContent"; -import MemoResourceListView from "./MemoResourceListView"; -import "@/less/memo.less"; - -interface Props { - memo: Memo; -} - -const ArchivedMemo: React.FC = (props: Props) => { - const { memo } = props; - const t = useTranslate(); - const memoStore = useMemoStore(); - - const handleDeleteMemoClick = async () => { - showCommonDialog({ - title: t("memo.delete-memo"), - content: t("memo.delete-confirm"), - style: "danger", - dialogName: "delete-memo-dialog", - onConfirm: async () => { - await memoStore.deleteMemoById(memo.id); - }, - }); - }; - - const handleRestoreMemoClick = async () => { - try { - await memoStore.patchMemo({ - id: memo.id, - rowStatus: "NORMAL", - }); - await memoStore.fetchMemos(); - toast(t("message.restored-successfully")); - } catch (error: any) { - console.error(error); - toast.error(error.response.data.message); - } - }; - - return ( -
-
-
- {getDateTimeString(memo.displayTs)} -
-
- - - - - - -
-
- - -
- ); -}; - -export default ArchivedMemo; diff --git a/web/src/components/ArchivedMemoDialog.tsx b/web/src/components/ArchivedMemoDialog.tsx deleted file mode 100644 index d86dc7bec81a4..0000000000000 --- a/web/src/components/ArchivedMemoDialog.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { useEffect, useState } from "react"; -import { toast } from "react-hot-toast"; -import useLoading from "@/hooks/useLoading"; -import { useMemoStore } from "@/store/module"; -import { useTranslate } from "@/utils/i18n"; -import ArchivedMemo from "./ArchivedMemo"; -import { generateDialog } from "./Dialog"; -import Icon from "./Icon"; -import "@/less/archived-memo-dialog.less"; - -type Props = DialogProps; - -const ArchivedMemoDialog: React.FC = (props: Props) => { - const t = useTranslate(); - const { destroy } = props; - const memoStore = useMemoStore(); - const memos = memoStore.state.memos; - const loadingState = useLoading(); - const [archivedMemos, setArchivedMemos] = useState([]); - - useEffect(() => { - memoStore - .fetchArchivedMemos() - .then((result) => { - setArchivedMemos(result); - }) - .catch((error) => { - console.error(error); - toast.error(error.response.data.message); - }) - .finally(() => { - loadingState.setFinish(); - }); - }, [memos]); - - return ( - <> -
-

{t("memo.archived-memos")}

- -
-
- {loadingState.isLoading ? ( -
-

{t("memo.fetching-data")}

-
- ) : archivedMemos.length === 0 ? ( -
-

{t("memo.no-archived-memos")}

-
- ) : ( -
- {archivedMemos.map((memo) => ( - - ))} -
- )} -
- - ); -}; - -export default function showArchivedMemoDialog(): void { - generateDialog( - { - className: "archived-memo-dialog", - dialogName: "archived-memo-dialog", - }, - ArchivedMemoDialog, - {} - ); -} diff --git a/web/src/components/BetaBadge.tsx b/web/src/components/BetaBadge.tsx index 917af1eceacf0..26822674f39b4 100644 --- a/web/src/components/BetaBadge.tsx +++ b/web/src/components/BetaBadge.tsx @@ -10,7 +10,9 @@ const BetaBadge: React.FC = (props: Props) => { return ( {t("common.beta")} diff --git a/web/src/components/ChangeMemberPasswordDialog.tsx b/web/src/components/ChangeMemberPasswordDialog.tsx index a9477790eefd0..adab6060bfbea 100644 --- a/web/src/components/ChangeMemberPasswordDialog.tsx +++ b/web/src/components/ChangeMemberPasswordDialog.tsx @@ -1,6 +1,8 @@ +import { Button, IconButton, Input } from "@mui/joy"; import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; -import { useUserStore } from "@/store/module"; +import { useUserStore } from "@/store/v1"; +import { User } from "@/types/proto/api/v2/user_service"; import { useTranslate } from "@/utils/i18n"; import { generateDialog } from "./Dialog"; import Icon from "./Icon"; @@ -10,7 +12,7 @@ interface Props extends DialogProps { } const ChangeMemberPasswordDialog: React.FC = (props: Props) => { - const { user: propsUser, destroy } = props; + const { user, destroy } = props; const t = useTranslate(); const userStore = useUserStore(); const [newPassword, setNewPassword] = useState(""); @@ -47,10 +49,13 @@ const ChangeMemberPasswordDialog: React.FC = (props: Props) => { } try { - await userStore.patchUser({ - id: propsUser.id, - password: newPassword, - }); + await userStore.updateUser( + { + name: user.name, + password: newPassword, + }, + ["password"], + ); toast(t("message.password-changed")); handleCloseBtnClick(); } catch (error: any) { @@ -63,36 +68,36 @@ const ChangeMemberPasswordDialog: React.FC = (props: Props) => { <>

- {t("setting.account-section.change-password")} ({propsUser.username}) + {t("setting.account-section.change-password")} ({user.nickname})

- + + +

{t("auth.new-password")}

-

{t("auth.repeat-new-password")}

- -
- +
+ +
@@ -106,7 +111,7 @@ function showChangeMemberPasswordDialog(user: User) { dialogName: "change-member-password-dialog", }, ChangeMemberPasswordDialog, - { user } + { user }, ); } diff --git a/web/src/components/ChangeMemoCreatedTsDialog.tsx b/web/src/components/ChangeMemoCreatedTsDialog.tsx index c4d1a70a11cc1..a07c1c867b1b3 100644 --- a/web/src/components/ChangeMemoCreatedTsDialog.tsx +++ b/web/src/components/ChangeMemoCreatedTsDialog.tsx @@ -1,14 +1,14 @@ -import { Button } from "@mui/joy"; +import { Button, IconButton, Input } from "@mui/joy"; import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; -import { getNormalizedTimeString, getUnixTime } from "@/helpers/datetime"; -import { useMemoStore } from "@/store/module"; +import { getNormalizedTimeString } from "@/helpers/datetime"; +import { useMemoStore } from "@/store/v1"; import { useTranslate } from "@/utils/i18n"; import { generateDialog } from "./Dialog"; import Icon from "./Icon"; interface Props extends DialogProps { - memoId: MemoId; + memoId: number; } const ChangeMemoCreatedTsDialog: React.FC = (props: Props) => { @@ -19,9 +19,9 @@ const ChangeMemoCreatedTsDialog: React.FC = (props: Props) => { const maxDatetimeValue = getNormalizedTimeString(); useEffect(() => { - memoStore.getMemoById(memoId).then((memo) => { + memoStore.getOrFetchMemoById(memoId).then((memo) => { if (memo) { - const datetime = getNormalizedTimeString(memo.createdTs); + const datetime = getNormalizedTimeString(memo.createTime); setCreatedAt(datetime); } else { toast.error(t("message.memo-not-found")); @@ -40,19 +40,14 @@ const ChangeMemoCreatedTsDialog: React.FC = (props: Props) => { }; const handleSaveBtnClick = async () => { - const nowTs = getUnixTime(); - const createdTs = getUnixTime(createdAt); - - if (createdTs > nowTs) { - toast.error(t("message.invalid-created-datetime")); - return; - } - try { - await memoStore.patchMemo({ - id: memoId, - createdTs, - }); + await memoStore.updateMemo( + { + id: memoId, + createTime: new Date(createdAt), + }, + ["created_ts"], + ); toast.success(t("message.memo-updated-datetime")); handleCloseBtnClick(); } catch (error: any) { @@ -65,16 +60,20 @@ const ChangeMemoCreatedTsDialog: React.FC = (props: Props) => { <>

{t("message.change-memo-created-time")}

- + + +
-
@@ -90,7 +89,7 @@ const ChangeMemoCreatedTsDialog: React.FC = (props: Props) => { ); }; -function showChangeMemoCreatedTsDialog(memoId: MemoId) { +function showChangeMemoCreatedTsDialog(memoId: number) { generateDialog( { className: "change-memo-created-ts-dialog", @@ -99,7 +98,7 @@ function showChangeMemoCreatedTsDialog(memoId: MemoId) { ChangeMemoCreatedTsDialog, { memoId, - } + }, ); } diff --git a/web/src/components/ChangePasswordDialog.tsx b/web/src/components/ChangePasswordDialog.tsx index fe894c3a5ba19..1139662acb38e 100644 --- a/web/src/components/ChangePasswordDialog.tsx +++ b/web/src/components/ChangePasswordDialog.tsx @@ -1,7 +1,9 @@ +import { Button, IconButton, Input } from "@mui/joy"; import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; -import { useGlobalStore, useUserStore } from "@/store/module"; -import { useUserV1Store } from "@/store/v1"; +import useCurrentUser from "@/hooks/useCurrentUser"; +import { useGlobalStore } from "@/store/module"; +import { useUserStore } from "@/store/v1"; import { useTranslate } from "@/utils/i18n"; import { generateDialog } from "./Dialog"; import Icon from "./Icon"; @@ -10,15 +12,15 @@ type Props = DialogProps; const ChangePasswordDialog: React.FC = ({ destroy }: Props) => { const t = useTranslate(); + const currentUser = useCurrentUser(); const userStore = useUserStore(); - const userV1Store = useUserV1Store(); const globalStore = useGlobalStore(); const profile = globalStore.state.systemStatus.profile; const [newPassword, setNewPassword] = useState(""); const [newPasswordAgain, setNewPasswordAgain] = useState(""); useEffect(() => { - if (profile.mode === "demo" && userStore.state.user?.id === userStore.state.host?.id) { + if (profile.mode === "demo") { toast.error("Demo mode does not support this operation."); destroy(); } @@ -29,13 +31,11 @@ const ChangePasswordDialog: React.FC = ({ destroy }: Props) => { }; const handleNewPasswordChanged = (e: React.ChangeEvent) => { - const text = e.target.value as string; - setNewPassword(text); + setNewPassword(e.target.value); }; const handleNewPasswordAgainChanged = (e: React.ChangeEvent) => { - const text = e.target.value as string; - setNewPasswordAgain(text); + setNewPasswordAgain(e.target.value); }; const handleSaveBtnClick = async () => { @@ -51,13 +51,12 @@ const ChangePasswordDialog: React.FC = ({ destroy }: Props) => { } try { - const user = userStore.getState().user as User; - await userV1Store.updateUser( + await userStore.updateUser( { - username: user.username, + name: currentUser.name, password: newPassword, }, - ["password"] + ["password"], ); toast.success(t("message.password-changed")); handleCloseBtnClick(); @@ -71,36 +70,34 @@ const ChangePasswordDialog: React.FC = ({ destroy }: Props) => { <>

{t("setting.account-section.change-password")}

- + + +

{t("auth.new-password")}

-

{t("auth.repeat-new-password")}

- -
- +
+ +
@@ -113,7 +110,7 @@ function showChangePasswordDialog() { className: "change-password-dialog", dialogName: "change-password-dialog", }, - ChangePasswordDialog + ChangePasswordDialog, ); } diff --git a/web/src/components/CreateAccessTokenDialog.tsx b/web/src/components/CreateAccessTokenDialog.tsx index 463ac1f53e8ec..ae54a262a25c4 100644 --- a/web/src/components/CreateAccessTokenDialog.tsx +++ b/web/src/components/CreateAccessTokenDialog.tsx @@ -1,4 +1,4 @@ -import { Button, Input, Radio, RadioGroup } from "@mui/joy"; +import { Button, IconButton, Input, Radio, RadioGroup } from "@mui/joy"; import React, { useState } from "react"; import { toast } from "react-hot-toast"; import { userServiceClient } from "@/grpcweb"; @@ -69,7 +69,7 @@ const CreateAccessTokenDialog: React.FC = (props: Props) => { try { await userServiceClient.createUserAccessToken({ - username: currentUser.username, + name: currentUser.name, description: state.description, expiresAt: state.expiration ? new Date(Date.now() + state.expiration * 1000) : undefined, }); @@ -86,9 +86,9 @@ const CreateAccessTokenDialog: React.FC = (props: Props) => { <>

Create access token

- + destroy()}> + +
@@ -139,7 +139,7 @@ function showCreateAccessTokenDialog(onConfirm: () => void) { CreateAccessTokenDialog, { onConfirm, - } + }, ); } diff --git a/web/src/components/CreateIdentityProviderDialog.tsx b/web/src/components/CreateIdentityProviderDialog.tsx index 3a648891cdb1d..25712223884de 100644 --- a/web/src/components/CreateIdentityProviderDialog.tsx +++ b/web/src/components/CreateIdentityProviderDialog.tsx @@ -1,4 +1,4 @@ -import { Button, Divider, Input, Option, Select, Typography } from "@mui/joy"; +import { Button, Divider, IconButton, Input, Option, Select, Typography } from "@mui/joy"; import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import * as api from "@/helpers/api"; @@ -21,7 +21,7 @@ const templateList: IdentityProvider[] = [ authUrl: "https://github.com/login/oauth/authorize", tokenUrl: "https://github.com/login/oauth/access_token", userInfoUrl: "https://api.github.com/user", - scopes: ["user"], + scopes: ["read:user"], fieldMapping: { identifier: "login", displayName: "name", @@ -237,9 +237,9 @@ const CreateIdentityProviderDialog: React.FC = (props: Props) => { <>

{t(isCreating ? "setting.sso-section.create-sso" : "setting.sso-section.update-sso")}

- + + +
{isCreating && ( @@ -426,7 +426,7 @@ function showCreateIdentityProviderDialog(identityProvider?: IdentityProvider, c dialogName: "create-identity-provider-dialog", }, CreateIdentityProviderDialog, - { identityProvider, confirmCallback } + { identityProvider, confirmCallback }, ); } diff --git a/web/src/components/CreateMemoRelationDialog.tsx b/web/src/components/CreateMemoRelationDialog.tsx index cc78d4a17b4bd..dcc6aad59f5b0 100644 --- a/web/src/components/CreateMemoRelationDialog.tsx +++ b/web/src/components/CreateMemoRelationDialog.tsx @@ -1,118 +1,142 @@ -import { Button, Input } from "@mui/joy"; -import { isNaN, unionBy } from "lodash-es"; +import { Autocomplete, AutocompleteOption, Button, Checkbox, Chip, IconButton } from "@mui/joy"; import React, { useState } from "react"; import { toast } from "react-hot-toast"; +import useDebounce from "react-use/lib/useDebounce"; import { memoServiceClient } from "@/grpcweb"; +import { DEFAULT_LIST_MEMOS_PAGE_SIZE } from "@/helpers/consts"; +import { getDateTimeString } from "@/helpers/datetime"; +import useCurrentUser from "@/hooks/useCurrentUser"; import { Memo } from "@/types/proto/api/v2/memo_service"; import { useTranslate } from "@/utils/i18n"; import { generateDialog } from "./Dialog"; import Icon from "./Icon"; interface Props extends DialogProps { - onCancel?: () => void; - onConfirm?: (memoIdList: number[]) => void; + onConfirm: (memos: Memo[], embedded?: boolean) => void; } const CreateMemoRelationDialog: React.FC = (props: Props) => { - const { destroy, onCancel, onConfirm } = props; + const { destroy, onConfirm } = props; const t = useTranslate(); - const [memoId, setMemoId] = useState(""); - const [memoList, setMemoList] = useState([]); + const user = useCurrentUser(); + const [searchText, setSearchText] = useState(""); + const [isFetching, setIsFetching] = useState(true); + const [fetchedMemos, setFetchedMemos] = useState([]); + const [selectedMemos, setSelectedMemos] = useState([]); + const [embedded, setEmbedded] = useState(false); + const filteredMemos = fetchedMemos.filter((memo) => !selectedMemos.includes(memo)); - const handleMemoIdInputKeyDown = (event: React.KeyboardEvent) => { - if (event.key === "Enter") { - handleSaveBtnClick(); - } - }; - - const handleMemoIdChanged = (event: React.ChangeEvent) => { - const memoId = event.target.value; - setMemoId(memoId.trim()); - }; - - const handleSaveBtnClick = async () => { - const id = Number(memoId); - if (isNaN(id)) { - toast.error("Invalid memo id"); - return; - } - - try { - const { memo } = await memoServiceClient.getMemo({ - id, - }); - if (!memo) { - toast.error("Not found memo"); - return; + useDebounce( + async () => { + setIsFetching(true); + try { + const filters = [`creator == "${user.name}"`, `row_status == "NORMAL"`]; + if (searchText) { + filters.push(`content_search == [${JSON.stringify(searchText)}]`); + } + const { memos } = await memoServiceClient.listMemos({ + pageSize: DEFAULT_LIST_MEMOS_PAGE_SIZE, + filter: filters.length > 0 ? filters.join(" && ") : undefined, + }); + setFetchedMemos(memos); + } catch (error: any) { + console.error(error); + toast.error(error.response.data.message); } + setIsFetching(false); + }, + 300, + [searchText], + ); - setMemoId(""); - setMemoList(unionBy([memo, ...memoList], "id")); - } catch (error: any) { - console.error(error); - toast.error(error.response.data.message); + const getHighlightedContent = (content: string) => { + const index = content.toLowerCase().indexOf(searchText.toLowerCase()); + if (index === -1) { + return content; + } + let before = content.slice(0, index); + if (before.length > 20) { + before = "..." + before.slice(before.length - 20); + } + const highlighted = content.slice(index, index + searchText.length); + let after = content.slice(index + searchText.length); + if (after.length > 20) { + after = after.slice(0, 20) + "..."; } - }; - const handleDeleteMemoRelation = async (memo: Memo) => { - setMemoList(memoList.filter((m) => m !== memo)); + return ( + <> + {before} + {highlighted} + {after} + + ); }; const handleCloseDialog = () => { - if (onCancel) { - onCancel(); - } destroy(); }; const handleConfirmBtnClick = async () => { - if (onConfirm) { - onConfirm(memoList.map((memo) => memo.id)); - } + onConfirm(selectedMemos, embedded); destroy(); }; return ( <> -
+

{"Add references"}

- + destroy()}> + +
-
- + } - /> - {memoList.length > 0 && ( - <> -
- {memoList.map((memo) => ( -
handleDeleteMemoRelation(memo)} - > - #{memo.id} - {memo.content} - + clearOnBlur + disableClearable + placeholder={"Search content"} + noOptionsText={"No memos found"} + options={filteredMemos} + loading={isFetching} + inputValue={searchText} + value={selectedMemos} + multiple + onInputChange={(_, value) => setSearchText(value.trim())} + getOptionKey={(option) => option.name} + getOptionLabel={(option) => option.content} + isOptionEqualToValue={(option, value) => option.id === value.id} + renderOption={(props, option) => ( + +
+

{getDateTimeString(option.displayTime)}

+

+ {searchText ? getHighlightedContent(option.content) : option.content} +

+
+
+ )} + renderTags={(memos) => + memos.map((memo) => ( + +
+

{getDateTimeString(memo.displayTime)}

+ {memo.content}
- ))} -
- - )} -
+ + )) + } + onChange={(_, value) => setSelectedMemos(value)} + /> +
+ setEmbedded(e.target.checked)} /> +
+
-
@@ -128,7 +152,7 @@ function showCreateMemoRelationDialog(props: Omit) { dialogName: "create-memo-relation-dialog", }, CreateMemoRelationDialog, - props + props, ); } diff --git a/web/src/components/CreateResourceDialog.tsx b/web/src/components/CreateResourceDialog.tsx index 156c2f43b64cb..e3e92a872f5fa 100644 --- a/web/src/components/CreateResourceDialog.tsx +++ b/web/src/components/CreateResourceDialog.tsx @@ -1,4 +1,4 @@ -import { Autocomplete, Button, Input, List, ListItem, Option, Select, Typography } from "@mui/joy"; +import { Autocomplete, Button, IconButton, Input, List, ListItem, Option, Select, Typography } from "@mui/joy"; import React, { useRef, useState } from "react"; import { toast } from "react-hot-toast"; import { Resource } from "@/types/proto/api/v2/resource_service"; @@ -180,9 +180,9 @@ const CreateResourceDialog: React.FC = (props: Props) => { <>

{t("resource.create-dialog.title")}

- + + +
@@ -299,7 +299,7 @@ function showCreateResourceDialog(props: Omit) { dialogName: "create-resource-dialog", }, CreateResourceDialog, - props + props, ); } diff --git a/web/src/components/CreateStorageServiceDialog.tsx b/web/src/components/CreateStorageServiceDialog.tsx index a4fe59ad33f4b..d9be9dac846cf 100644 --- a/web/src/components/CreateStorageServiceDialog.tsx +++ b/web/src/components/CreateStorageServiceDialog.tsx @@ -1,5 +1,5 @@ -import { Button, Input, Typography } from "@mui/joy"; -import { useEffect, useState } from "react"; +import { Button, IconButton, Input, Checkbox, Typography } from "@mui/joy"; +import React, { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import * as api from "@/helpers/api"; import { useTranslate } from "@/utils/i18n"; @@ -29,6 +29,7 @@ const CreateStorageServiceDialog: React.FC = (props: Props) => { bucket: "", urlPrefix: "", urlSuffix: "", + presign: false, }); const isCreating = storage === undefined; @@ -109,9 +110,9 @@ const CreateStorageServiceDialog: React.FC = (props: Props) => { {t(isCreating ? "setting.storage-section.create-storage" : "setting.storage-section.update-storage")} - + + +
@@ -220,6 +221,12 @@ const CreateStorageServiceDialog: React.FC = (props: Props) => { onChange={(e) => setPartialS3Config({ urlSuffix: e.target.value })} fullWidth /> + setPartialS3Config({ presign: e.target.checked })} + />
+

{t("tag.create-tag")}

+ destroy()}> + +
= (props: Props) => { /> {tagNameList.length > 0 && ( <> -

{t("tag-list.all-tags")}

+

{t("tag.all-tags")}

{Array.from(tagNameList) .sort() .map((tag) => ( - handleDeleteTag(tag)} + className="max-w-[120px] text-sm mr-2 mt-1 font-mono cursor-pointer dark:text-gray-300 hover:opacity-60 hover:line-through" > - #{tag} - + handleDeleteTag(tag)}> + #{tag} + + ))}
@@ -123,29 +130,30 @@ const CreateTagDialog: React.FC = (props: Props) => { {shownSuggestTagNameList.length > 0 && ( <>
- {t("tag-list.tag-suggestions")} + {t("tag.tag-suggestions")} - {showTagSuggestions ? t("tag-list.hide") : t("tag-list.show")} + {showTagSuggestions ? t("tag.hide") : t("tag.show")}
{showTagSuggestions && ( <>
{shownSuggestTagNameList.map((tag) => ( - handleUpsertTag(tag)} + className="max-w-[120px] text-sm mr-2 mt-1 font-mono cursor-pointer dark:text-gray-300 hover:opacity-60" > - #{tag} - + handleUpsertTag(tag)}> + #{tag} + + ))}
)} @@ -162,7 +170,7 @@ function showCreateTagDialog() { className: "create-tag-dialog", dialogName: "create-tag-dialog", }, - CreateTagDialog + CreateTagDialog, ); } diff --git a/web/src/components/CreateWebhookDialog.tsx b/web/src/components/CreateWebhookDialog.tsx new file mode 100644 index 0000000000000..f573f9547c2a6 --- /dev/null +++ b/web/src/components/CreateWebhookDialog.tsx @@ -0,0 +1,162 @@ +import { Button, IconButton, Input } from "@mui/joy"; +import React, { useEffect, useState } from "react"; +import { toast } from "react-hot-toast"; +import { webhookServiceClient } from "@/grpcweb"; +import useLoading from "@/hooks/useLoading"; +import { useTranslate } from "@/utils/i18n"; +import { generateDialog } from "./Dialog"; +import Icon from "./Icon"; + +interface Props extends DialogProps { + webhookId?: number; + onConfirm: () => void; +} + +interface State { + name: string; + url: string; +} + +const CreateWebhookDialog: React.FC = (props: Props) => { + const { webhookId, destroy, onConfirm } = props; + const t = useTranslate(); + const [state, setState] = useState({ + name: "", + url: "", + }); + const requestState = useLoading(false); + const isCreating = webhookId === undefined; + + useEffect(() => { + if (webhookId) { + webhookServiceClient + .getWebhook({ + id: webhookId, + }) + .then(({ webhook }) => { + if (!webhook) { + return; + } + + setState({ + name: webhook.name, + url: webhook.url, + }); + }); + } + }, []); + + const setPartialState = (partialState: Partial) => { + setState({ + ...state, + ...partialState, + }); + }; + + const handleTitleInputChange = (e: React.ChangeEvent) => { + setPartialState({ + name: e.target.value, + }); + }; + + const handleUrlInputChange = (e: React.ChangeEvent) => { + setPartialState({ + url: e.target.value, + }); + }; + + const handleSaveBtnClick = async () => { + if (!state.name || !state.url) { + toast.error("Please fill all required fields"); + return; + } + + try { + if (isCreating) { + await webhookServiceClient.createWebhook({ + name: state.name, + url: state.url, + }); + } else { + await webhookServiceClient.updateWebhook({ + webhook: { + id: webhookId, + name: state.name, + url: state.url, + }, + updateMask: ["name", "url"], + }); + } + + onConfirm(); + destroy(); + } catch (error: any) { + console.error(error); + toast.error(error.details); + } + }; + + return ( + <> +
+

{isCreating ? "Create webhook" : "Edit webhook"}

+ destroy()}> + + +
+
+
+ + Title * + +
+ +
+
+
+ + Payload URL * + +
+ +
+
+
+ + +
+
+ + ); +}; + +function showCreateWebhookDialog(onConfirm: () => void) { + generateDialog( + { + className: "create-webhook-dialog", + dialogName: "create-webhook-dialog", + }, + CreateWebhookDialog, + { + onConfirm, + }, + ); +} + +export default showCreateWebhookDialog; diff --git a/web/src/components/DemoBanner.tsx b/web/src/components/DemoBanner.tsx deleted file mode 100644 index 87fc054895e70..0000000000000 --- a/web/src/components/DemoBanner.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { useEffect, useState } from "react"; -import { useGlobalStore } from "@/store/module"; -import Icon from "./Icon"; - -interface State { - show: boolean; -} - -const DemoBanner: React.FC = () => { - const globalStore = useGlobalStore(); - const profile = globalStore.state.systemStatus.profile; - const [state, setState] = useState({ - show: false, - }); - - useEffect(() => { - const isDemo = profile.mode === "demo"; - setState({ - show: isDemo, - }); - }, []); - - if (!state.show) return null; - - return ( -
-
- ✨ A lightweight, self-hosted memo hub. Open Source and Free forever. ✨ - - Install - - -
-
- ); -}; - -export default DemoBanner; diff --git a/web/src/components/Dialog/BaseDialog.tsx b/web/src/components/Dialog/BaseDialog.tsx index 2aa14eb767b52..50e13b59aeda4 100644 --- a/web/src/components/Dialog/BaseDialog.tsx +++ b/web/src/components/Dialog/BaseDialog.tsx @@ -68,11 +68,12 @@ const BaseDialog: React.FC = (props: Props) => { export function generateDialog( config: DialogConfig, DialogComponent: React.FC, - props?: Omit + props?: Omit, ): DialogCallback { const tempDiv = document.createElement("div"); const dialog = createRoot(tempDiv); document.body.append(tempDiv); + document.body.style.overflow = "hidden"; setTimeout(() => { tempDiv.firstElementChild?.classList.add("showup"); @@ -82,6 +83,7 @@ export function generateDialog( destroy: () => { tempDiv.firstElementChild?.classList.remove("showup"); tempDiv.firstElementChild?.classList.add("showoff"); + document.body.style.removeProperty("overflow"); setTimeout(() => { dialog.unmount(); tempDiv.remove(); diff --git a/web/src/components/Dialog/CommonDialog.tsx b/web/src/components/Dialog/CommonDialog.tsx index f0cc40ad4b5ca..f43aea90b5e7b 100644 --- a/web/src/components/Dialog/CommonDialog.tsx +++ b/web/src/components/Dialog/CommonDialog.tsx @@ -1,4 +1,4 @@ -import { Button } from "@mui/joy"; +import { Button, IconButton } from "@mui/joy"; import { DefaultColorPalette } from "@mui/joy/styles/types"; import { useTranslate } from "@/utils/i18n"; import Icon from "../Icon"; @@ -48,9 +48,9 @@ const CommonDialog: React.FC = (props: Props) => { <>

{title}

- + + +

{content}

@@ -86,6 +86,6 @@ export const showCommonDialog = (props: CommonDialogProps) => { dialogName: `common-dialog ${props?.className ?? ""}`, }, CommonDialog, - props + props, ); }; diff --git a/web/src/components/DisablePasswordLoginDialog.tsx b/web/src/components/DisablePasswordLoginDialog.tsx index 061586df36dbd..18499324c6c32 100644 --- a/web/src/components/DisablePasswordLoginDialog.tsx +++ b/web/src/components/DisablePasswordLoginDialog.tsx @@ -1,4 +1,4 @@ -import { Button } from "@mui/joy"; +import { Button, IconButton, Input } from "@mui/joy"; import { useState } from "react"; import { toast } from "react-hot-toast"; import * as api from "@/helpers/api"; @@ -45,7 +45,7 @@ const DisablePasswordLoginDialog: React.FC = ({ destroy }: Props) => { handleCloseBtnClick(); } catch (error: any) { console.error(error); - toast.error(error.response.data.message || t("message.updating-setting-failed")); + toast.error(error.response.data.message); } } }; @@ -57,20 +57,20 @@ const DisablePasswordLoginDialog: React.FC = ({ destroy }: Props) => { return ( <> -
+

{t("setting.system-section.disable-password-login")}

- + + +
-
+
{confirmedOnce ? ( <> -

{t("setting.system-section.disable-password-login-final-warning")}

- +

{t("setting.system-section.disable-password-login-final-warning")}

+ ) : ( -

{t("setting.system-section.disable-password-login-warning")}

+

{t("setting.system-section.disable-password-login-warning")}

)}
-
-
-

{t("embed-memo.text")}

-
-          {memoEmbeddedCode()}
-        
-

- {t("embed-memo.only-public-supported")} - - {t("embed-memo.copy")} - -

-
- - ); -}; - -function showEmbedMemoDialog(memoId: MemoId) { - generateDialog( - { - className: "embed-memo-dialog", - dialogName: "embed-memo-dialog", - }, - EmbedMemoDialog, - { - memoId, - } - ); -} - -export default showEmbedMemoDialog; diff --git a/web/src/components/FloatingNavButton.tsx b/web/src/components/FloatingNavButton.tsx deleted file mode 100644 index 9f627432b2fff..0000000000000 --- a/web/src/components/FloatingNavButton.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { Dropdown, IconButton, Menu, MenuButton } from "@mui/joy"; -import { useEffect } from "react"; -import useNavigateTo from "@/hooks/useNavigateTo"; -import { useTranslate } from "@/utils/i18n"; -import Icon from "./Icon"; - -const FloatingNavButton = () => { - const t = useTranslate(); - const navigateTo = useNavigateTo(); - - useEffect(() => { - handleScrollToTop(); - }, []); - - const handleScrollToTop = () => { - document.body.querySelector("#root")?.scrollTo({ top: 0, behavior: "smooth" }); - }; - - return ( - <> - -
- - - -
- - - - -
- - ); -}; - -export default FloatingNavButton; diff --git a/web/src/components/HomeSidebar.tsx b/web/src/components/HomeSidebar.tsx index 86dff6a78d450..c8548931ded2d 100644 --- a/web/src/components/HomeSidebar.tsx +++ b/web/src/components/HomeSidebar.tsx @@ -1,36 +1,27 @@ -import { useLayoutStore } from "../store/module"; +import classNames from "classnames"; +import useCurrentUser from "@/hooks/useCurrentUser"; +import PersonalStatistics from "./PersonalStatistics"; import SearchBar from "./SearchBar"; import TagList from "./TagList"; -import UsageHeatMap from "./UsageHeatMap"; -const HomeSidebar = () => { - const layoutStore = useLayoutStore(); - const showHomeSidebar = layoutStore.state.showHomeSidebar; +interface Props { + className?: string; +} + +const HomeSidebar = (props: Props) => { + const currentUser = useCurrentUser(); return ( -
-
layoutStore.setHomeSidebarStatus(false)} - >
- -
+ + + + ); }; diff --git a/web/src/components/HomeSidebarDrawer.tsx b/web/src/components/HomeSidebarDrawer.tsx new file mode 100644 index 0000000000000..49320f64db288 --- /dev/null +++ b/web/src/components/HomeSidebarDrawer.tsx @@ -0,0 +1,37 @@ +import { Drawer, IconButton } from "@mui/joy"; +import { useEffect, useState } from "react"; +import { useLocation } from "react-router-dom"; +import HomeSidebar from "./HomeSidebar"; +import Icon from "./Icon"; + +const HomeSidebarDrawer = () => { + const location = useLocation(); + const [open, setOpen] = useState(false); + + useEffect(() => { + setOpen(false); + }, [location.pathname]); + + const toggleDrawer = (inOpen: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => { + if (event.type === "keydown" && ((event as React.KeyboardEvent).key === "Tab" || (event as React.KeyboardEvent).key === "Shift")) { + return; + } + + setOpen(inOpen); + }; + + return ( + <> + + + + +
+ +
+
+ + ); +}; + +export default HomeSidebarDrawer; diff --git a/web/src/components/Inbox/MemoCommentMessage.tsx b/web/src/components/Inbox/MemoCommentMessage.tsx index a43009b691b59..e6cfbf13a659b 100644 --- a/web/src/components/Inbox/MemoCommentMessage.tsx +++ b/web/src/components/Inbox/MemoCommentMessage.tsx @@ -4,10 +4,9 @@ import { useEffect, useState } from "react"; import toast from "react-hot-toast"; import { activityServiceClient } from "@/grpcweb"; import useNavigateTo from "@/hooks/useNavigateTo"; -import useInboxStore from "@/store/v1/inbox"; -import { extractUsernameFromName } from "@/store/v1/user"; -import { Activity } from "@/types/proto/api/v2/activity_service"; +import { useInboxStore, extractUsernameFromName, useMemoStore } from "@/store/v1"; import { Inbox, Inbox_Status } from "@/types/proto/api/v2/inbox_service"; +import { Memo } from "@/types/proto/api/v2/memo_service"; import { useTranslate } from "@/utils/i18n"; import Icon from "../Icon"; @@ -19,27 +18,36 @@ const MemoCommentMessage = ({ inbox }: Props) => { const t = useTranslate(); const navigateTo = useNavigateTo(); const inboxStore = useInboxStore(); - const [activity, setActivity] = useState(undefined); + const memoStore = useMemoStore(); + const [relatedMemo, setRelatedMemo] = useState(undefined); useEffect(() => { if (!inbox.activityId) { return; } - activityServiceClient - .getActivity({ + (async () => { + const { activity } = await activityServiceClient.getActivity({ id: inbox.activityId, - }) - .then(({ activity }) => { - setActivity(activity); }); + if (!activity) { + return; + } + if (activity.payload?.memoComment?.relatedMemoId) { + const memo = await memoStore.getOrFetchMemoById(activity.payload?.memoComment?.relatedMemoId, { + skipStore: true, + }); + setRelatedMemo(memo); + } + })(); }, [inbox.activityId]); - const handleNavigateToMemo = () => { - if (!activity?.payload?.memoComment?.relatedMemoId) { + const handleNavigateToMemo = async () => { + if (!relatedMemo) { return; } - navigateTo(`/m/${activity?.payload?.memoComment?.relatedMemoId}`); + + navigateTo(`/m/${relatedMemo.name}`); if (inbox.status === Inbox_Status.UNREAD) { handleArchiveMessage(true); } @@ -51,7 +59,7 @@ const MemoCommentMessage = ({ inbox }: Props) => { name: inbox.name, status: Inbox_Status.ARCHIVED, }, - ["status"] + ["status"], ); if (!silence) { toast.success("Archived"); @@ -65,7 +73,7 @@ const MemoCommentMessage = ({ inbox }: Props) => { "shrink-0 mt-2 p-2 rounded-full border", inbox.status === Inbox_Status.UNREAD ? "border-blue-600 text-blue-600 bg-blue-50 dark:bg-zinc-800" - : "border-gray-400 text-gray-400 bg-gray-50 dark:bg-zinc-800" + : "border-gray-500 text-gray-500 bg-gray-50 dark:bg-zinc-800", )} > @@ -74,8 +82,8 @@ const MemoCommentMessage = ({ inbox }: Props) => {
@@ -97,7 +105,7 @@ const MemoCommentMessage = ({ inbox }: Props) => { > {t("inbox.memo-comment", { user: extractUsernameFromName(inbox.sender), - memo: `memo#${activity?.payload?.memoComment?.relatedMemoId}`, + memo: `memos#${relatedMemo?.name}`, })}

diff --git a/web/src/components/Inbox/VersionUpdateMessage.tsx b/web/src/components/Inbox/VersionUpdateMessage.tsx new file mode 100644 index 0000000000000..f0f3d3cd7a8a8 --- /dev/null +++ b/web/src/components/Inbox/VersionUpdateMessage.tsx @@ -0,0 +1,108 @@ +import { Tooltip } from "@mui/joy"; +import classNames from "classnames"; +import { useEffect, useState } from "react"; +import toast from "react-hot-toast"; +import { activityServiceClient } from "@/grpcweb"; +import { useInboxStore } from "@/store/v1"; +import { Activity } from "@/types/proto/api/v2/activity_service"; +import { Inbox, Inbox_Status } from "@/types/proto/api/v2/inbox_service"; +import { useTranslate } from "@/utils/i18n"; +import Icon from "../Icon"; + +interface Props { + inbox: Inbox; +} + +const VersionUpdateMessage = ({ inbox }: Props) => { + const t = useTranslate(); + const inboxStore = useInboxStore(); + const [activity, setActivity] = useState(undefined); + + useEffect(() => { + if (!inbox.activityId) { + return; + } + + (async () => { + const { activity } = await activityServiceClient.getActivity({ + id: inbox.activityId, + }); + if (!activity) { + return; + } + + setActivity(activity); + })(); + }, [inbox.activityId]); + + const handleNavigate = () => { + if (!activity?.payload?.versionUpdate?.version) { + return; + } + + window.open(`https://github.com/usememos/memos/releases/tag/v${activity?.payload?.versionUpdate?.version}`); + if (inbox.status === Inbox_Status.UNREAD) { + handleArchiveMessage(true); + } + }; + + const handleArchiveMessage = async (silence = false) => { + await inboxStore.updateInbox( + { + name: inbox.name, + status: Inbox_Status.ARCHIVED, + }, + ["status"], + ); + if (!silence) { + toast.success("Archived"); + } + }; + + return ( +
+
+ + + +
+
+
+ {inbox.createTime?.toLocaleString()} +
+ {inbox.status === Inbox_Status.UNREAD && ( + + handleArchiveMessage()} + /> + + )} +
+
+

+ {t("inbox.version-update", { + version: activity?.payload?.versionUpdate?.version, + })} +

+
+
+ ); +}; + +export default VersionUpdateMessage; diff --git a/web/src/components/LocaleSelect.tsx b/web/src/components/LocaleSelect.tsx index 8c19149dc06bf..bf760a669e12d 100644 --- a/web/src/components/LocaleSelect.tsx +++ b/web/src/components/LocaleSelect.tsx @@ -1,6 +1,6 @@ import { Option, Select } from "@mui/joy"; import { FC } from "react"; -import { availableLocales } from "@/i18n"; +import { locales } from "@/i18n"; import Icon from "./Icon"; interface Props { @@ -23,7 +23,7 @@ const LocaleSelect: FC = (props: Props) => { value={value} onChange={(_, value) => handleSelectChange(value as Locale)} > - {availableLocales.map((locale) => { + {locales.map((locale) => { try { const languageName = new Intl.DisplayNames([locale], { type: "language" }).of(locale); if (languageName) { diff --git a/web/src/components/Memo.tsx b/web/src/components/Memo.tsx deleted file mode 100644 index b0f74ef3f2677..0000000000000 --- a/web/src/components/Memo.tsx +++ /dev/null @@ -1,338 +0,0 @@ -import { Divider, Tooltip } from "@mui/joy"; -import { memo, useEffect, useRef, useState } from "react"; -import { toast } from "react-hot-toast"; -import { useTranslation } from "react-i18next"; -import { Link } from "react-router-dom"; -import { UNKNOWN_ID } from "@/helpers/consts"; -import { getRelativeTimeString } from "@/helpers/datetime"; -import useCurrentUser from "@/hooks/useCurrentUser"; -import useNavigateTo from "@/hooks/useNavigateTo"; -import { useFilterStore, useMemoStore, useUserStore } from "@/store/module"; -import { useUserV1Store } from "@/store/v1"; -import { useTranslate } from "@/utils/i18n"; -import showChangeMemoCreatedTsDialog from "./ChangeMemoCreatedTsDialog"; -import { showCommonDialog } from "./Dialog/CommonDialog"; -import Icon from "./Icon"; -import MemoContent from "./MemoContent"; -import showMemoEditorDialog from "./MemoEditor/MemoEditorDialog"; -import MemoRelationListView from "./MemoRelationListView"; -import MemoResourceListView from "./MemoResourceListView"; -import showPreviewImageDialog from "./PreviewImageDialog"; -import UserAvatar from "./UserAvatar"; -import VisibilityIcon from "./VisibilityIcon"; -import "@/less/memo.less"; - -interface Props { - memo: Memo; - showVisibility?: boolean; - showPinnedStyle?: boolean; - lazyRendering?: boolean; -} - -const Memo: React.FC = (props: Props) => { - const { memo, lazyRendering } = props; - const t = useTranslate(); - const navigateTo = useNavigateTo(); - const { i18n } = useTranslation(); - const filterStore = useFilterStore(); - const userStore = useUserStore(); - const memoStore = useMemoStore(); - const userV1Store = useUserV1Store(); - const user = useCurrentUser(); - const [shouldRender, setShouldRender] = useState(lazyRendering ? false : true); - const [displayTime, setDisplayTime] = useState(getRelativeTimeString(memo.displayTs)); - const memoContainerRef = useRef(null); - const readonly = memo.creatorUsername !== user?.username; - const creator = userV1Store.getUserByUsername(memo.creatorUsername); - const referenceRelations = memo.relationList.filter((relation) => relation.type === "REFERENCE"); - const commentRelations = memo.relationList.filter((relation) => relation.relatedMemoId === memo.id && relation.type === "COMMENT"); - - // Prepare memo creator. - useEffect(() => { - userV1Store.getOrFetchUserByUsername(memo.creatorUsername); - }, [memo.creatorUsername]); - - // Update display time string. - useEffect(() => { - let intervalFlag: any = -1; - if (Date.now() - memo.displayTs < 1000 * 60 * 60 * 24) { - intervalFlag = setInterval(() => { - setDisplayTime(getRelativeTimeString(memo.displayTs)); - }, 1000 * 1); - } - - return () => { - clearInterval(intervalFlag); - }; - }, [i18n.language]); - - // Lazy rendering. - useEffect(() => { - if (shouldRender) { - return; - } - - const root = document.body.querySelector("#root"); - if (root) { - const checkShouldRender = () => { - if (root.scrollTop + window.innerHeight > (memoContainerRef.current?.offsetTop || 0)) { - setShouldRender(true); - root.removeEventListener("scroll", checkShouldRender); - return true; - } - }; - - if (checkShouldRender()) { - return; - } - root.addEventListener("scroll", checkShouldRender); - } - }, [lazyRendering, filterStore.state]); - - if (!shouldRender) { - // Render a placeholder to occupy the space. - return
; - } - - const handleGotoMemoDetailPage = (event: React.MouseEvent) => { - if (event.altKey) { - showChangeMemoCreatedTsDialog(memo.id); - } else { - navigateTo(`/m/${memo.id}`); - } - }; - - const handleTogglePinMemoBtnClick = async () => { - try { - if (memo.pinned) { - await memoStore.unpinMemo(memo.id); - } else { - await memoStore.pinMemo(memo.id); - } - } catch (error) { - // do nth - } - }; - - const handleEditMemoClick = () => { - showMemoEditorDialog({ - memoId: memo.id, - }); - }; - - const handleMarkMemoClick = () => { - showMemoEditorDialog({ - relationList: [ - { - memoId: UNKNOWN_ID, - relatedMemoId: memo.id, - type: "REFERENCE", - }, - ], - }); - }; - - const handleArchiveMemoClick = async () => { - try { - await memoStore.patchMemo({ - id: memo.id, - rowStatus: "ARCHIVED", - }); - } catch (error: any) { - console.error(error); - toast.error(error.response.data.message); - } - }; - - const handleDeleteMemoClick = async () => { - showCommonDialog({ - title: t("memo.delete-memo"), - content: t("memo.delete-confirm"), - style: "danger", - dialogName: "delete-memo-dialog", - onConfirm: async () => { - await memoStore.deleteMemoById(memo.id); - }, - }); - }; - - const handleMemoContentClick = async (e: React.MouseEvent) => { - const targetEl = e.target as HTMLElement; - - if (targetEl.className === "tag-span") { - const tagName = targetEl.innerText.slice(1); - const currTagQuery = filterStore.getState().tag; - if (currTagQuery === tagName) { - filterStore.setTagFilter(undefined); - } else { - filterStore.setTagFilter(tagName); - } - } else if (targetEl.classList.contains("todo-block")) { - if (readonly) { - return; - } - - const status = targetEl.dataset?.value; - const todoElementList = [...(memoContainerRef.current?.querySelectorAll(`span.todo-block[data-value=${status}]`) ?? [])]; - for (const element of todoElementList) { - if (element === targetEl) { - const index = todoElementList.indexOf(element); - const tempList = memo.content.split(status === "DONE" ? /- \[x\] / : /- \[ \] /); - let finalContent = ""; - - for (let i = 0; i < tempList.length; i++) { - if (i === 0) { - finalContent += `${tempList[i]}`; - } else { - if (i === index + 1) { - finalContent += status === "DONE" ? "- [ ] " : "- [x] "; - } else { - finalContent += status === "DONE" ? "- [x] " : "- [ ] "; - } - finalContent += `${tempList[i]}`; - } - } - await memoStore.patchMemo({ - id: memo.id, - content: finalContent, - }); - } - } - } else if (targetEl.tagName === "IMG") { - const imgUrl = targetEl.getAttribute("src"); - if (imgUrl) { - showPreviewImageDialog([imgUrl], 0); - } - } - }; - - const handleMemoContentDoubleClick = (e: React.MouseEvent) => { - if (readonly) { - return; - } - - const loginUser = userStore.state.user; - if (loginUser && !loginUser.localSetting.enableDoubleClickEditing) { - return; - } - const targetEl = e.target as HTMLElement; - - if (targetEl.className === "tag-span") { - return; - } else if (targetEl.classList.contains("todo-block")) { - return; - } - - handleEditMemoClick(); - }; - - return ( - <> -
-
-
- - {displayTime} - -
-
- {!readonly && ( - <> - - - -
-
- {!memo.parent && ( - - {memo.pinned ? ( - - ) : ( - - )} - {memo.pinned ? t("common.unpin") : t("common.pin")} - - )} - - - {t("common.edit")} - - {!memo.parent && ( - - - {t("common.mark")} - - )} - - - - {t("common.archive")} - - - - {t("common.delete")} - -
-
- - )} -
-
- - - -
-
- {creator && ( - <> - - - #{memo.id} - - - - - - - - {creator.nickname} - - - - {memo.pinned && props.showPinnedStyle && ( - <> - - - - - - )} - {props.showVisibility && memo.visibility !== "PRIVATE" && ( - <> - - - - - - - - )} - - - - {commentRelations.length} - - - )} -
-
-
- - ); -}; - -export default memo(Memo); diff --git a/web/src/components/MemoActionMenu.tsx b/web/src/components/MemoActionMenu.tsx new file mode 100644 index 0000000000000..c91e8f0501fdc --- /dev/null +++ b/web/src/components/MemoActionMenu.tsx @@ -0,0 +1,141 @@ +import { Divider, Dropdown, Menu, MenuButton, MenuItem } from "@mui/joy"; +import classNames from "classnames"; +import copy from "copy-to-clipboard"; +import toast from "react-hot-toast"; +import Icon from "@/components/Icon"; +import { useMemoStore } from "@/store/v1"; +import { RowStatus } from "@/types/proto/api/v2/common"; +import { Memo } from "@/types/proto/api/v2/memo_service"; +import { useTranslate } from "@/utils/i18n"; +import { showCommonDialog } from "./Dialog/CommonDialog"; +import showMemoEditorDialog from "./MemoEditor/MemoEditorDialog"; +import showShareMemoDialog from "./ShareMemoDialog"; + +interface Props { + memo: Memo; + className?: string; + hiddenActions?: ("edit" | "archive" | "delete" | "share" | "pin")[]; + onArchived?: () => void; + onDeleted?: () => void; +} + +const MemoActionMenu = (props: Props) => { + const { memo, hiddenActions } = props; + const t = useTranslate(); + const memoStore = useMemoStore(); + + const handleTogglePinMemoBtnClick = async () => { + try { + if (memo.pinned) { + await memoStore.updateMemo( + { + id: memo.id, + pinned: false, + }, + ["pinned"], + ); + } else { + await memoStore.updateMemo( + { + id: memo.id, + pinned: true, + }, + ["pinned"], + ); + } + } catch (error) { + // do nth + } + }; + + const handleEditMemoClick = () => { + showMemoEditorDialog({ + memoId: memo.id, + cacheKey: `${memo.id}-${memo.updateTime}`, + }); + }; + + const handleArchiveMemoClick = async () => { + try { + await memoStore.updateMemo( + { + id: memo.id, + rowStatus: RowStatus.ARCHIVED, + }, + ["row_status"], + ); + } catch (error: any) { + console.error(error); + toast.error(error.response.data.message); + } + if (props.onArchived) { + props.onArchived(); + } + }; + + const handleDeleteMemoClick = async () => { + showCommonDialog({ + title: t("memo.delete-memo"), + content: t("memo.delete-confirm"), + style: "danger", + dialogName: "delete-memo-dialog", + onConfirm: async () => { + await memoStore.deleteMemo(memo.id); + if (props.onDeleted) { + props.onDeleted(); + } + }, + }); + }; + + const handleCopyMemoId = () => { + copy(memo.name); + toast.success("Copied to clipboard!"); + }; + + return ( + + + + + + + + {!hiddenActions?.includes("pin") && ( + + {memo.pinned ? : } + {memo.pinned ? t("common.unpin") : t("common.pin")} + + )} + {!hiddenActions?.includes("edit") && ( + + + {t("common.edit")} + + )} + {!hiddenActions?.includes("share") && ( + showShareMemoDialog(memo.id)}> + + {t("common.share")} + + )} + + + {t("common.archive")} + + + + {t("common.delete")} + + +
+
+ ID: {memo.name} +
+
+
+
+ ); +}; + +export default MemoActionMenu; diff --git a/web/src/components/MemoContent.tsx b/web/src/components/MemoContent.tsx deleted file mode 100644 index 4dc2f2cc8d9a7..0000000000000 --- a/web/src/components/MemoContent.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { useRef } from "react"; -import { marked } from "@/labs/marked"; -import "@/less/memo-content.less"; - -interface Props { - content: string; - className?: string; - onMemoContentClick?: (e: React.MouseEvent) => void; - onMemoContentDoubleClick?: (e: React.MouseEvent) => void; -} - -const MemoContent: React.FC = (props: Props) => { - const { className, content, onMemoContentClick, onMemoContentDoubleClick } = props; - const memoContentContainerRef = useRef(null); - - const handleMemoContentClick = async (e: React.MouseEvent) => { - if (onMemoContentClick) { - onMemoContentClick(e); - } - }; - - const handleMemoContentDoubleClick = async (e: React.MouseEvent) => { - if (onMemoContentDoubleClick) { - onMemoContentDoubleClick(e); - } - }; - - return ( -
-
- {marked(content)} -
-
- ); -}; - -export default MemoContent; diff --git a/web/src/components/MemoContent/Blockquote.tsx b/web/src/components/MemoContent/Blockquote.tsx new file mode 100644 index 0000000000000..c895446f51be0 --- /dev/null +++ b/web/src/components/MemoContent/Blockquote.tsx @@ -0,0 +1,19 @@ +import { Node } from "@/types/node"; +import Renderer from "./Renderer"; +import { BaseProps } from "./types"; + +interface Props extends BaseProps { + children: Node[]; +} + +const Blockquote: React.FC = ({ children }: Props) => { + return ( +
+ {children.map((child, index) => ( + + ))} +
+ ); +}; + +export default Blockquote; diff --git a/web/src/components/MemoContent/Bold.tsx b/web/src/components/MemoContent/Bold.tsx new file mode 100644 index 0000000000000..b7651d11e11d2 --- /dev/null +++ b/web/src/components/MemoContent/Bold.tsx @@ -0,0 +1,19 @@ +import { Node } from "@/types/node"; +import Renderer from "./Renderer"; + +interface Props { + symbol: string; + children: Node[]; +} + +const Bold: React.FC = ({ children }: Props) => { + return ( + + {children.map((child, index) => ( + + ))} + + ); +}; + +export default Bold; diff --git a/web/src/components/MemoContent/BoldItalic.tsx b/web/src/components/MemoContent/BoldItalic.tsx new file mode 100644 index 0000000000000..d59bc8bb0bd2c --- /dev/null +++ b/web/src/components/MemoContent/BoldItalic.tsx @@ -0,0 +1,14 @@ +interface Props { + symbol: string; + content: string; +} + +const BoldItalic: React.FC = ({ content }: Props) => { + return ( + + {content} + + ); +}; + +export default BoldItalic; diff --git a/web/src/components/MemoContent/Code.tsx b/web/src/components/MemoContent/Code.tsx new file mode 100644 index 0000000000000..19f0a39a2c988 --- /dev/null +++ b/web/src/components/MemoContent/Code.tsx @@ -0,0 +1,9 @@ +interface Props { + content: string; +} + +const Code: React.FC = ({ content }: Props) => { + return {content}; +}; + +export default Code; diff --git a/web/src/components/MemoContent/CodeBlock.tsx b/web/src/components/MemoContent/CodeBlock.tsx new file mode 100644 index 0000000000000..3165b01000172 --- /dev/null +++ b/web/src/components/MemoContent/CodeBlock.tsx @@ -0,0 +1,64 @@ +import classNames from "classnames"; +import copy from "copy-to-clipboard"; +import hljs from "highlight.js"; +import toast from "react-hot-toast"; +import Icon from "../Icon"; +import MermaidBlock from "./MermaidBlock"; +import { BaseProps } from "./types"; + +// Special languages that are rendered differently. +enum SpecialLanguage { + HTML = "__html", + MERMAID = "mermaid", +} + +interface Props extends BaseProps { + language: string; + content: string; +} + +const CodeBlock: React.FC = ({ language, content }: Props) => { + const formatedLanguage = (language || "").toLowerCase() || "text"; + // Users can set Markdown code blocks as `__html` to render HTML directly. + if (formatedLanguage === SpecialLanguage.HTML) { + return
; + } else if (formatedLanguage === SpecialLanguage.MERMAID) { + return ; + } + + let highlightedCode = content; + try { + const lang = hljs.getLanguage(formatedLanguage); + if (lang) { + const temp = hljs.highlight(content, { + language: formatedLanguage, + }).value; + highlightedCode = temp; + } + } catch (error) { + // Skip error and use default highlighted code. + } + + const handleCopyButtonClick = () => { + copy(content); + toast.success("Copied to clipboard!"); + }; + + return ( +
+
+ {formatedLanguage} + +
+ +
+        
+      
+
+ ); +}; + +export default CodeBlock; diff --git a/web/src/components/MemoContent/EmbeddedContent/EmbeddedMemo.tsx b/web/src/components/MemoContent/EmbeddedContent/EmbeddedMemo.tsx new file mode 100644 index 0000000000000..a3cc4a9a6633b --- /dev/null +++ b/web/src/components/MemoContent/EmbeddedContent/EmbeddedMemo.tsx @@ -0,0 +1,65 @@ +import { useContext, useEffect } from "react"; +import { Link } from "react-router-dom"; +import Icon from "@/components/Icon"; +import MemoResourceListView from "@/components/MemoResourceListView"; +import { getDateTimeString } from "@/helpers/datetime"; +import useLoading from "@/hooks/useLoading"; +import { useMemoStore } from "@/store/v1"; +import MemoContent from ".."; +import { RendererContext } from "../types"; +import Error from "./Error"; + +interface Props { + resourceId: string; + params: string; +} + +const EmbeddedMemo = ({ resourceId, params: paramsStr }: Props) => { + const context = useContext(RendererContext); + const loadingState = useLoading(); + const memoStore = useMemoStore(); + const memo = memoStore.getMemoByName(resourceId); + const resourceName = `memos/${resourceId}`; + + useEffect(() => { + memoStore.getOrFetchMemoByName(resourceId).finally(() => loadingState.setFinish()); + }, [resourceId]); + + if (loadingState.isLoading) { + return null; + } + if (!memo) { + return ; + } + if (memo.id === context.memoId || context.embeddedMemos.has(resourceName)) { + return ; + } + + // Add the memo to the set of embedded memos. This is used to prevent infinite loops when a memo embeds itself. + context.embeddedMemos.add(resourceName); + const params = new URLSearchParams(paramsStr); + const inlineMode = params.has("inline"); + if (inlineMode) { + return ( +
+ + +
+ ); + } + + return ( +
+
+ {getDateTimeString(memo.displayTime)} + + + +
+ + +
+ ); +}; + +export default EmbeddedMemo; diff --git a/web/src/components/MemoContent/EmbeddedContent/EmbeddedResource.tsx b/web/src/components/MemoContent/EmbeddedContent/EmbeddedResource.tsx new file mode 100644 index 0000000000000..fe5ba648b01d4 --- /dev/null +++ b/web/src/components/MemoContent/EmbeddedContent/EmbeddedResource.tsx @@ -0,0 +1,62 @@ +import classNames from "classnames"; +import { useEffect } from "react"; +import MemoResourceListView from "@/components/MemoResourceListView"; +import useLoading from "@/hooks/useLoading"; +import { useResourceStore } from "@/store/v1"; +import Error from "./Error"; + +interface Props { + resourceId: string; + params: string; +} + +const getAdditionalClassNameWithParams = (params: URLSearchParams) => { + const additionalClassNames = []; + if (params.has("align")) { + const align = params.get("align"); + if (align === "center") { + additionalClassNames.push("mx-auto"); + } + } + if (params.has("size")) { + const size = params.get("size"); + if (size === "lg") { + additionalClassNames.push("w-full"); + } else if (size === "md") { + additionalClassNames.push("w-2/3"); + } else if (size === "sm") { + additionalClassNames.push("w-1/3"); + } + } + if (params.has("width")) { + const width = params.get("width"); + additionalClassNames.push(`w-[${width}]`); + } + return additionalClassNames.join(" "); +}; + +const EmbeddedResource = ({ resourceId, params: paramsStr }: Props) => { + const loadingState = useLoading(); + const resourceStore = useResourceStore(); + const resource = resourceStore.getResourceByName(resourceId); + const params = new URLSearchParams(paramsStr); + + useEffect(() => { + resourceStore.getOrFetchResourceByName(resourceId).finally(() => loadingState.setFinish()); + }, [resourceId]); + + if (loadingState.isLoading) { + return null; + } + if (!resource) { + return ; + } + + return ( +
+ +
+ ); +}; + +export default EmbeddedResource; diff --git a/web/src/components/MemoContent/EmbeddedContent/Error.tsx b/web/src/components/MemoContent/EmbeddedContent/Error.tsx new file mode 100644 index 0000000000000..844f3bae66470 --- /dev/null +++ b/web/src/components/MemoContent/EmbeddedContent/Error.tsx @@ -0,0 +1,9 @@ +interface Props { + message: string; +} + +const Error = ({ message }: Props) => { + return

{message}

; +}; + +export default Error; diff --git a/web/src/components/MemoContent/EmbeddedContent/index.tsx b/web/src/components/MemoContent/EmbeddedContent/index.tsx new file mode 100644 index 0000000000000..b44db2d714ee4 --- /dev/null +++ b/web/src/components/MemoContent/EmbeddedContent/index.tsx @@ -0,0 +1,25 @@ +import EmbeddedMemo from "./EmbeddedMemo"; +import EmbeddedResource from "./EmbeddedResource"; +import Error from "./Error"; + +interface Props { + resourceName: string; + params: string; +} + +const extractResourceTypeAndId = (resourceName: string) => { + const [resourceType, resourceId] = resourceName.split("/"); + return { resourceType, resourceId }; +}; + +const EmbeddedContent = ({ resourceName, params }: Props) => { + const { resourceType, resourceId } = extractResourceTypeAndId(resourceName); + if (resourceType === "memos") { + return ; + } else if (resourceType === "resources") { + return ; + } + return ; +}; + +export default EmbeddedContent; diff --git a/web/src/components/MemoContent/EscapingCharacter.tsx b/web/src/components/MemoContent/EscapingCharacter.tsx new file mode 100644 index 0000000000000..ffd567250b877 --- /dev/null +++ b/web/src/components/MemoContent/EscapingCharacter.tsx @@ -0,0 +1,9 @@ +interface Props { + symbol: string; +} + +const EscapingCharacter: React.FC = ({ symbol }: Props) => { + return {symbol}; +}; + +export default EscapingCharacter; diff --git a/web/src/components/MemoContent/Heading.tsx b/web/src/components/MemoContent/Heading.tsx new file mode 100644 index 0000000000000..a1fbe1a9d70c1 --- /dev/null +++ b/web/src/components/MemoContent/Heading.tsx @@ -0,0 +1,34 @@ +import { Node } from "@/types/node"; +import Renderer from "./Renderer"; +import { BaseProps } from "./types"; + +interface Props extends BaseProps { + level: number; + children: Node[]; +} + +const Heading: React.FC = ({ level, children }: Props) => { + const Head = `h${level}` as keyof JSX.IntrinsicElements; + const className = (() => { + switch (level) { + case 1: + return "text-5xl leading-normal font-bold"; + case 2: + return "text-3xl leading-normal font-medium"; + case 3: + return "text-xl leading-normal font-medium"; + case 4: + return "text-lg font-bold"; + } + })(); + + return ( + + {children.map((child, index) => ( + + ))} + + ); +}; + +export default Heading; diff --git a/web/src/components/MemoContent/Highlight.tsx b/web/src/components/MemoContent/Highlight.tsx new file mode 100644 index 0000000000000..0946d69968e5b --- /dev/null +++ b/web/src/components/MemoContent/Highlight.tsx @@ -0,0 +1,9 @@ +interface Props { + content: string; +} + +const Highlight: React.FC = ({ content }: Props) => { + return {content}; +}; + +export default Highlight; diff --git a/web/src/components/MemoContent/HorizontalRule.tsx b/web/src/components/MemoContent/HorizontalRule.tsx new file mode 100644 index 0000000000000..adaa19390a4e1 --- /dev/null +++ b/web/src/components/MemoContent/HorizontalRule.tsx @@ -0,0 +1,12 @@ +import { Divider } from "@mui/joy"; +import { BaseProps } from "./types"; + +interface Props extends BaseProps { + symbol: string; +} + +const HorizontalRule: React.FC = () => { + return ; +}; + +export default HorizontalRule; diff --git a/web/src/components/MemoContent/Image.tsx b/web/src/components/MemoContent/Image.tsx new file mode 100644 index 0000000000000..76ae0cdd47f66 --- /dev/null +++ b/web/src/components/MemoContent/Image.tsx @@ -0,0 +1,10 @@ +interface Props { + altText: string; + url: string; +} + +const Image: React.FC = ({ altText, url }: Props) => { + return {altText}; +}; + +export default Image; diff --git a/web/src/components/MemoContent/Italic.tsx b/web/src/components/MemoContent/Italic.tsx new file mode 100644 index 0000000000000..ccd2be9cd6201 --- /dev/null +++ b/web/src/components/MemoContent/Italic.tsx @@ -0,0 +1,10 @@ +interface Props { + symbol: string; + content: string; +} + +const Italic: React.FC = ({ content }: Props) => { + return {content}; +}; + +export default Italic; diff --git a/web/src/components/MemoContent/LineBreak.tsx b/web/src/components/MemoContent/LineBreak.tsx new file mode 100644 index 0000000000000..2d5db554773fb --- /dev/null +++ b/web/src/components/MemoContent/LineBreak.tsx @@ -0,0 +1,9 @@ +import { BaseProps } from "./types"; + +interface Props extends BaseProps {} + +const LineBreak: React.FC = () => { + return
; +}; + +export default LineBreak; diff --git a/web/src/components/MemoContent/Link.tsx b/web/src/components/MemoContent/Link.tsx new file mode 100644 index 0000000000000..1acd8726b159a --- /dev/null +++ b/web/src/components/MemoContent/Link.tsx @@ -0,0 +1,19 @@ +interface Props { + url: string; + text?: string; +} + +const Link: React.FC = ({ text, url }: Props) => { + return ( + + {text || url} + + ); +}; + +export default Link; diff --git a/web/src/components/MemoContent/Math.tsx b/web/src/components/MemoContent/Math.tsx new file mode 100644 index 0000000000000..2f60dd23d85d0 --- /dev/null +++ b/web/src/components/MemoContent/Math.tsx @@ -0,0 +1,13 @@ +import TeX from "@matejmazur/react-katex"; +import "katex/dist/katex.min.css"; + +interface Props { + content: string; + block?: boolean; +} + +const Math: React.FC = ({ content, block }: Props) => { + return ; +}; + +export default Math; diff --git a/web/src/components/MemoContent/MermaidBlock.tsx b/web/src/components/MemoContent/MermaidBlock.tsx new file mode 100644 index 0000000000000..7c11eb149a7f1 --- /dev/null +++ b/web/src/components/MemoContent/MermaidBlock.tsx @@ -0,0 +1,32 @@ +import { useColorScheme } from "@mui/joy"; +import mermaid from "mermaid"; +import { useEffect, useRef } from "react"; + +interface Props { + content: string; +} + +const MermaidBlock: React.FC = ({ content }: Props) => { + const { mode } = useColorScheme(); + const mermaidDockBlock = useRef(null); + mermaid.initialize({ startOnLoad: false, theme: mode }); + + useEffect(() => { + if (!mermaidDockBlock.current) { + return; + } + + // Render mermaid when mounted. + mermaid.run({ + nodes: [mermaidDockBlock.current], + }); + }); + + return ( +
+      {content}
+    
+ ); +}; + +export default MermaidBlock; diff --git a/web/src/components/MemoContent/OrderedList.tsx b/web/src/components/MemoContent/OrderedList.tsx new file mode 100644 index 0000000000000..75d5f99b6d7dd --- /dev/null +++ b/web/src/components/MemoContent/OrderedList.tsx @@ -0,0 +1,36 @@ +import { repeat } from "lodash-es"; +import { Node } from "@/types/node"; +import Renderer from "./Renderer"; +import { BaseProps } from "./types"; + +interface Props extends BaseProps { + number: string; + indent: number; + children: Node[]; +} + +const OrderedList: React.FC = ({ number, indent, children }: Props) => { + return ( +
    +
  1. + {indent > 0 && ( +
    + {repeat(" ", indent)} +
    + )} +
    +
    + {number}. +
    +
    + {children.map((child, index) => ( + + ))} +
    +
    +
  2. +
+ ); +}; + +export default OrderedList; diff --git a/web/src/components/MemoContent/Paragraph.tsx b/web/src/components/MemoContent/Paragraph.tsx new file mode 100644 index 0000000000000..a0565fce2b79a --- /dev/null +++ b/web/src/components/MemoContent/Paragraph.tsx @@ -0,0 +1,19 @@ +import { Node } from "@/types/node"; +import Renderer from "./Renderer"; +import { BaseProps } from "./types"; + +interface Props extends BaseProps { + children: Node[]; +} + +const Paragraph: React.FC = ({ children }: Props) => { + return ( +

+ {children.map((child, index) => ( + + ))} +

+ ); +}; + +export default Paragraph; diff --git a/web/src/components/MemoContent/ReferencedContent/Error.tsx b/web/src/components/MemoContent/ReferencedContent/Error.tsx new file mode 100644 index 0000000000000..844f3bae66470 --- /dev/null +++ b/web/src/components/MemoContent/ReferencedContent/Error.tsx @@ -0,0 +1,9 @@ +interface Props { + message: string; +} + +const Error = ({ message }: Props) => { + return

{message}

; +}; + +export default Error; diff --git a/web/src/components/MemoContent/ReferencedContent/ReferencedMemo.tsx b/web/src/components/MemoContent/ReferencedContent/ReferencedMemo.tsx new file mode 100644 index 0000000000000..5112ef5936a1a --- /dev/null +++ b/web/src/components/MemoContent/ReferencedContent/ReferencedMemo.tsx @@ -0,0 +1,47 @@ +import { useEffect } from "react"; +import useLoading from "@/hooks/useLoading"; +import useNavigateTo from "@/hooks/useNavigateTo"; +import { useMemoStore } from "@/store/v1"; +import Error from "./Error"; + +interface Props { + resourceId: string; + params: string; +} + +const ReferencedMemo = ({ resourceId, params: paramsStr }: Props) => { + const navigateTo = useNavigateTo(); + const loadingState = useLoading(); + const memoStore = useMemoStore(); + const memo = memoStore.getMemoByName(resourceId); + const params = new URLSearchParams(paramsStr); + + useEffect(() => { + memoStore.getOrFetchMemoByName(resourceId).finally(() => loadingState.setFinish()); + }, [resourceId]); + + if (loadingState.isLoading) { + return null; + } + if (!memo) { + return ; + } + + const paramsText = params.has("text") ? params.get("text") : undefined; + const displayContent = paramsText || (memo.content.length > 12 ? `${memo.content.slice(0, 12)}...` : memo.content); + + const handleGotoMemoDetailPage = () => { + navigateTo(`/m/${memo.name}`); + }; + + return ( + + {displayContent} + + ); +}; + +export default ReferencedMemo; diff --git a/web/src/components/MemoContent/ReferencedContent/index.tsx b/web/src/components/MemoContent/ReferencedContent/index.tsx new file mode 100644 index 0000000000000..374aec2d13caa --- /dev/null +++ b/web/src/components/MemoContent/ReferencedContent/index.tsx @@ -0,0 +1,22 @@ +import Error from "./Error"; +import ReferencedMemo from "./ReferencedMemo"; + +interface Props { + resourceName: string; + params: string; +} + +const extractResourceTypeAndId = (resourceName: string) => { + const [resourceType, resourceId] = resourceName.split("/"); + return { resourceType, resourceId }; +}; + +const ReferencedContent = ({ resourceName, params }: Props) => { + const { resourceType, resourceId } = extractResourceTypeAndId(resourceName); + if (resourceType === "memos") { + return ; + } + return ; +}; + +export default ReferencedContent; diff --git a/web/src/components/MemoContent/Renderer.tsx b/web/src/components/MemoContent/Renderer.tsx new file mode 100644 index 0000000000000..7667e84169383 --- /dev/null +++ b/web/src/components/MemoContent/Renderer.tsx @@ -0,0 +1,130 @@ +import { + AutoLinkNode, + BlockquoteNode, + BoldItalicNode, + BoldNode, + CodeBlockNode, + CodeNode, + EmbeddedContentNode, + EscapingCharacterNode, + HeadingNode, + HighlightNode, + HorizontalRuleNode, + ImageNode, + ItalicNode, + LinkNode, + MathNode, + Node, + NodeType, + OrderedListNode, + ParagraphNode, + ReferencedContentNode, + SpoilerNode, + StrikethroughNode, + SubscriptNode, + SuperscriptNode, + TableNode, + TagNode, + TaskListNode, + TextNode, + UnorderedListNode, +} from "@/types/node"; +import Blockquote from "./Blockquote"; +import Bold from "./Bold"; +import BoldItalic from "./BoldItalic"; +import Code from "./Code"; +import CodeBlock from "./CodeBlock"; +import EmbeddedContent from "./EmbeddedContent"; +import EscapingCharacter from "./EscapingCharacter"; +import Heading from "./Heading"; +import Highlight from "./Highlight"; +import HorizontalRule from "./HorizontalRule"; +import Image from "./Image"; +import Italic from "./Italic"; +import LineBreak from "./LineBreak"; +import Link from "./Link"; +import Math from "./Math"; +import OrderedList from "./OrderedList"; +import Paragraph from "./Paragraph"; +import ReferencedContent from "./ReferencedContent"; +import Spoiler from "./Spoiler"; +import Strikethrough from "./Strikethrough"; +import Subscript from "./Subscript"; +import Superscript from "./Superscript"; +import Table from "./Table"; +import Tag from "./Tag"; +import TaskList from "./TaskList"; +import Text from "./Text"; +import UnorderedList from "./UnorderedList"; + +interface Props { + index: string; + node: Node; +} + +const Renderer: React.FC = ({ index, node }: Props) => { + switch (node.type) { + case NodeType.LINE_BREAK: + return ; + case NodeType.PARAGRAPH: + return ; + case NodeType.CODE_BLOCK: + return ; + case NodeType.HEADING: + return ; + case NodeType.HORIZONTAL_RULE: + return ; + case NodeType.BLOCKQUOTE: + return
; + case NodeType.ORDERED_LIST: + return ; + case NodeType.UNORDERED_LIST: + return ; + case NodeType.TASK_LIST: + return ; + case NodeType.MATH_BLOCK: + return ; + case NodeType.TABLE: + return ; + case NodeType.EMBEDDED_CONTENT: + return ; + case NodeType.TEXT: + return ; + case NodeType.BOLD: + return ; + case NodeType.ITALIC: + return ; + case NodeType.BOLD_ITALIC: + return ; + case NodeType.CODE: + return ; + case NodeType.IMAGE: + return ; + case NodeType.LINK: + return ; + case NodeType.AUTO_LINK: + return ; + case NodeType.TAG: + return ; + case NodeType.STRIKETHROUGH: + return ; + case NodeType.MATH: + return ; + case NodeType.HIGHLIGHT: + return ; + case NodeType.ESCAPING_CHARACTER: + return ; + case NodeType.SUBSCRIPT: + return ; + case NodeType.SUPERSCRIPT: + return ; + case NodeType.REFERENCED_CONTENT: + return ; + case NodeType.SPOILER: + return ; + default: + return null; + } +}; + +export default Renderer; diff --git a/web/src/components/MemoContent/Spoiler.tsx b/web/src/components/MemoContent/Spoiler.tsx new file mode 100644 index 0000000000000..3855ffadebdae --- /dev/null +++ b/web/src/components/MemoContent/Spoiler.tsx @@ -0,0 +1,21 @@ +import classNames from "classnames"; +import { useState } from "react"; + +interface Props { + content: string; +} + +const Spoiler: React.FC = ({ content }: Props) => { + const [isRevealed, setIsRevealed] = useState(false); + + return ( + setIsRevealed(!isRevealed)} + > + {content} + + ); +}; + +export default Spoiler; diff --git a/web/src/components/MemoContent/Strikethrough.tsx b/web/src/components/MemoContent/Strikethrough.tsx new file mode 100644 index 0000000000000..0bfcde6d80c28 --- /dev/null +++ b/web/src/components/MemoContent/Strikethrough.tsx @@ -0,0 +1,9 @@ +interface Props { + content: string; +} + +const Strikethrough: React.FC = ({ content }: Props) => { + return {content}; +}; + +export default Strikethrough; diff --git a/web/src/components/MemoContent/Subscript.tsx b/web/src/components/MemoContent/Subscript.tsx new file mode 100644 index 0000000000000..1878f59b0546c --- /dev/null +++ b/web/src/components/MemoContent/Subscript.tsx @@ -0,0 +1,9 @@ +interface Props { + content: string; +} + +const Subscript: React.FC = ({ content }: Props) => { + return {content}; +}; + +export default Subscript; diff --git a/web/src/components/MemoContent/Superscript.tsx b/web/src/components/MemoContent/Superscript.tsx new file mode 100644 index 0000000000000..3816925118cd4 --- /dev/null +++ b/web/src/components/MemoContent/Superscript.tsx @@ -0,0 +1,9 @@ +interface Props { + content: string; +} + +const Superscript: React.FC = ({ content }: Props) => { + return {content}; +}; + +export default Superscript; diff --git a/web/src/components/MemoContent/Table.tsx b/web/src/components/MemoContent/Table.tsx new file mode 100644 index 0000000000000..093a7e9c89313 --- /dev/null +++ b/web/src/components/MemoContent/Table.tsx @@ -0,0 +1,35 @@ +import { TableNode_Row } from "@/types/node"; + +interface Props { + header: string[]; + rows: TableNode_Row[]; +} + +const Table = ({ header, rows }: Props) => { + return ( +
+ + + {header.map((h, i) => ( + + ))} + + + + {rows.map((row, i) => ( + + {row.cells.map((r, j) => ( + + ))} + + ))} + +
+ {h} +
+ {r} +
+ ); +}; + +export default Table; diff --git a/web/src/components/MemoContent/Tag.tsx b/web/src/components/MemoContent/Tag.tsx new file mode 100644 index 0000000000000..a4070c3ba3f90 --- /dev/null +++ b/web/src/components/MemoContent/Tag.tsx @@ -0,0 +1,40 @@ +import classNames from "classnames"; +import { useContext } from "react"; +import { useFilterStore } from "@/store/module"; +import { RendererContext } from "./types"; + +interface Props { + content: string; +} + +const Tag: React.FC = ({ content }: Props) => { + const context = useContext(RendererContext); + const filterStore = useFilterStore(); + + const handleTagClick = () => { + if (context.disableFilter) { + return; + } + + const currTagQuery = filterStore.getState().tag; + if (currTagQuery === content) { + filterStore.setTagFilter(undefined); + } else { + filterStore.setTagFilter(content); + } + }; + + return ( + + #{content} + + ); +}; + +export default Tag; diff --git a/web/src/components/MemoContent/TaskList.tsx b/web/src/components/MemoContent/TaskList.tsx new file mode 100644 index 0000000000000..90d8f11d23026 --- /dev/null +++ b/web/src/components/MemoContent/TaskList.tsx @@ -0,0 +1,72 @@ +import { Checkbox } from "@mui/joy"; +import classNames from "classnames"; +import { repeat } from "lodash-es"; +import { useContext, useState } from "react"; +import { useMemoStore } from "@/store/v1"; +import { Node, NodeType, TaskListNode } from "@/types/node"; +import Renderer from "./Renderer"; +import { RendererContext } from "./types"; + +interface Props { + index: string; + symbol: string; + indent: number; + complete: boolean; + children: Node[]; +} + +const TaskList: React.FC = ({ index, indent, complete, children }: Props) => { + const context = useContext(RendererContext); + const memoStore = useMemoStore(); + const [checked] = useState(complete); + + const handleCheckboxChange = async (on: boolean) => { + if (context.readonly || !context.memoId) { + return; + } + + const nodeIndex = Number(index); + if (isNaN(nodeIndex)) { + return; + } + + const node = context.nodes[nodeIndex]; + if (node.type !== NodeType.TASK_LIST || !node.value) { + return; + } + + (node.value as TaskListNode)!.complete = on; + const content = window.restore(context.nodes); + await memoStore.updateMemo( + { + id: context.memoId, + content, + }, + ["content"], + ); + }; + + return ( +
    +
  • + {indent > 0 && ( +
    + {repeat(" ", indent)} +
    + )} +
    +
    + handleCheckboxChange(e.target.checked)} /> +
    +
    + {children.map((child, index) => ( + + ))} +
    +
    +
  • +
+ ); +}; + +export default TaskList; diff --git a/web/src/components/MemoContent/Text.tsx b/web/src/components/MemoContent/Text.tsx new file mode 100644 index 0000000000000..3cacdffeb1222 --- /dev/null +++ b/web/src/components/MemoContent/Text.tsx @@ -0,0 +1,9 @@ +interface Props { + content: string; +} + +const Text: React.FC = ({ content }: Props) => { + return {content}; +}; + +export default Text; diff --git a/web/src/components/MemoContent/UnorderedList.tsx b/web/src/components/MemoContent/UnorderedList.tsx new file mode 100644 index 0000000000000..a83d8569100c3 --- /dev/null +++ b/web/src/components/MemoContent/UnorderedList.tsx @@ -0,0 +1,35 @@ +import { repeat } from "lodash-es"; +import { Node } from "@/types/node"; +import Renderer from "./Renderer"; + +interface Props { + symbol: string; + indent: number; + children: Node[]; +} + +const UnorderedList: React.FC = ({ indent, children }: Props) => { + return ( +
    +
  • + {indent > 0 && ( +
    + {repeat(" ", indent)} +
    + )} +
    +
    + +
    +
    + {children.map((child, index) => ( + + ))} +
    +
    +
  • +
+ ); +}; + +export default UnorderedList; diff --git a/web/src/components/MemoContent/index.tsx b/web/src/components/MemoContent/index.tsx new file mode 100644 index 0000000000000..09ed45b9add0d --- /dev/null +++ b/web/src/components/MemoContent/index.tsx @@ -0,0 +1,110 @@ +import classNames from "classnames"; +import { memo, useEffect, useRef, useState } from "react"; +import { Link } from "react-router-dom"; +import useCurrentUser from "@/hooks/useCurrentUser"; +import { useMemoStore } from "@/store/v1"; +import { Node, NodeType } from "@/types/node"; +import { useTranslate } from "@/utils/i18n"; +import Icon from "../Icon"; +import Renderer from "./Renderer"; +import { RendererContext } from "./types"; + +// MAX_DISPLAY_HEIGHT is the maximum height of the memo content to display in compact mode. +const MAX_DISPLAY_HEIGHT = 256; + +interface Props { + content: string; + memoId?: number; + compact?: boolean; + readonly?: boolean; + disableFilter?: boolean; + // embeddedMemos is a set of memo resource names that are embedded in the current memo. + // This is used to prevent infinite loops when a memo embeds itself. + embeddedMemos?: Set; + className?: string; + onClick?: (e: React.MouseEvent) => void; +} + +const MemoContent: React.FC = (props: Props) => { + const { className, content, memoId, embeddedMemos, onClick } = props; + const t = useTranslate(); + const currentUser = useCurrentUser(); + const memoStore = useMemoStore(); + const memoContentContainerRef = useRef(null); + const [showCompactMode, setShowCompactMode] = useState(false); + const memo = memoId ? memoStore.getMemoById(memoId) : null; + const nodes = window.parse(content); + const allowEdit = !props.readonly && memo && currentUser?.id === memo.creatorId; + + // Initial compact mode. + useEffect(() => { + if (!props.compact) { + return; + } + if (!memoContentContainerRef.current) { + return; + } + + if ((memoContentContainerRef.current as HTMLDivElement).getBoundingClientRect().height > MAX_DISPLAY_HEIGHT) { + setShowCompactMode(true); + } + }, []); + + const handleMemoContentClick = async (e: React.MouseEvent) => { + if (onClick) { + onClick(e); + } + }; + + let prevNode: Node | null = null; + let skipNextLineBreakFlag = false; + + return ( + <> + +
+
+ {nodes.map((node, index) => { + if (prevNode?.type !== NodeType.LINE_BREAK && node.type === NodeType.LINE_BREAK && skipNextLineBreakFlag) { + skipNextLineBreakFlag = false; + return null; + } + + prevNode = node; + skipNextLineBreakFlag = true; + return ; + })} +
+
+
+ {memo && showCompactMode && ( +
+ + {t("memo.show-more")} + + +
+ )} + + ); +}; + +export default memo(MemoContent); diff --git a/web/src/components/MemoContent/types/context.ts b/web/src/components/MemoContent/types/context.ts new file mode 100644 index 0000000000000..b885df28e30d1 --- /dev/null +++ b/web/src/components/MemoContent/types/context.ts @@ -0,0 +1,17 @@ +import { createContext } from "react"; +import { Node } from "@/types/node"; + +interface Context { + nodes: Node[]; + // embeddedMemos is a set of memo resource names that are embedded in the current memo. + // This is used to prevent infinite loops when a memo embeds itself. + embeddedMemos: Set; + memoId?: number; + readonly?: boolean; + disableFilter?: boolean; +} + +export const RendererContext = createContext({ + nodes: [], + embeddedMemos: new Set(), +}); diff --git a/web/src/components/MemoContent/types/index.ts b/web/src/components/MemoContent/types/index.ts new file mode 100644 index 0000000000000..0103e4f651961 --- /dev/null +++ b/web/src/components/MemoContent/types/index.ts @@ -0,0 +1,6 @@ +export * from "./context"; + +export interface BaseProps { + index: string; + className?: string; +} diff --git a/web/src/components/MemoEditor/ActionButton/AddMemoRelationButton.tsx b/web/src/components/MemoEditor/ActionButton/AddMemoRelationButton.tsx new file mode 100644 index 0000000000000..0ee434391e6a3 --- /dev/null +++ b/web/src/components/MemoEditor/ActionButton/AddMemoRelationButton.tsx @@ -0,0 +1,65 @@ +import { IconButton } from "@mui/joy"; +import { uniqBy } from "lodash-es"; +import { useContext } from "react"; +import toast from "react-hot-toast"; +import showCreateMemoRelationDialog from "@/components/CreateMemoRelationDialog"; +import Icon from "@/components/Icon"; +import { UNKNOWN_ID } from "@/helpers/consts"; +import { MemoRelation_Type } from "@/types/proto/api/v2/memo_relation_service"; +import { EditorRefActions } from "../Editor"; +import { MemoEditorContext } from "../types"; + +interface Props { + editorRef: React.RefObject; +} + +const AddMemoRelationButton = (props: Props) => { + const { editorRef } = props; + const context = useContext(MemoEditorContext); + + const handleAddMemoRelationBtnClick = () => { + showCreateMemoRelationDialog({ + onConfirm: (memos, embedded) => { + // If embedded mode is enabled, embed the memo instead of creating a relation. + if (embedded) { + if (!editorRef.current) { + toast.error("Failed to embed memo"); + return; + } + + const cursorPosition = editorRef.current.getCursorPosition(); + const prevValue = editorRef.current.getContent().slice(0, cursorPosition); + if (prevValue !== "" && !prevValue.endsWith("\n")) { + editorRef.current.insertText("\n"); + } + for (const memo of memos) { + editorRef.current.insertText(`![[memos/${memo.name}]]\n`); + } + setTimeout(() => { + editorRef.current?.scrollToCursor(); + editorRef.current?.focus(); + }); + return; + } + + context.setRelationList( + uniqBy( + [ + ...memos.map((memo) => ({ memoId: context.memoId || UNKNOWN_ID, relatedMemoId: memo.id, type: MemoRelation_Type.REFERENCE })), + ...context.relationList, + ].filter((relation) => relation.relatedMemoId !== (context.memoId || UNKNOWN_ID)), + "relatedMemoId", + ), + ); + }, + }); + }; + + return ( + + + + ); +}; + +export default AddMemoRelationButton; diff --git a/web/src/components/MemoEditor/ActionButton/MarkdownMenu.tsx b/web/src/components/MemoEditor/ActionButton/MarkdownMenu.tsx new file mode 100644 index 0000000000000..af0b51490fe99 --- /dev/null +++ b/web/src/components/MemoEditor/ActionButton/MarkdownMenu.tsx @@ -0,0 +1,107 @@ +import { Dropdown, IconButton, Menu, MenuButton, MenuItem } from "@mui/joy"; +import { Link } from "@mui/joy"; +import toast from "react-hot-toast"; +import Icon from "@/components/Icon"; +import showPreviewMarkdownDialog from "@/components/PreviewMarkdownDialog"; +import { EditorRefActions } from "../Editor"; + +interface Props { + editorRef: React.RefObject; +} + +const MarkdownMenu = (props: Props) => { + const { editorRef } = props; + + const handleCodeBlockClick = () => { + if (!editorRef.current) { + return; + } + + const cursorPosition = editorRef.current.getCursorPosition(); + const prevValue = editorRef.current.getContent().slice(0, cursorPosition); + if (prevValue === "" || prevValue.endsWith("\n")) { + editorRef.current.insertText("", "```\n", "\n```"); + } else { + editorRef.current.insertText("", "\n```\n", "\n```"); + } + setTimeout(() => { + editorRef.current?.scrollToCursor(); + editorRef.current?.focus(); + }); + }; + + const handleCheckboxClick = () => { + if (!editorRef.current) { + return; + } + + const currentPosition = editorRef.current.getCursorPosition(); + const currentLineNumber = editorRef.current.getCursorLineNumber(); + const currentLine = editorRef.current.getLine(currentLineNumber); + let newLine = ""; + let cursorChange = 0; + if (/^- \[( |x|X)\] /.test(currentLine)) { + newLine = currentLine.replace(/^- \[( |x|X)\] /, ""); + cursorChange = -6; + } else if (/^\d+\. |- /.test(currentLine)) { + const match = currentLine.match(/^\d+\. |- /) ?? [""]; + newLine = currentLine.replace(/^\d+\. |- /, "- [ ] "); + cursorChange = -match[0].length + 6; + } else { + newLine = "- [ ] " + currentLine; + cursorChange = 6; + } + editorRef.current.setLine(currentLineNumber, newLine); + editorRef.current.setCursorPosition(currentPosition + cursorChange); + setTimeout(() => { + editorRef.current?.scrollToCursor(); + editorRef.current?.focus(); + }); + }; + + const handlePreviewClick = () => { + const content = editorRef.current?.getContent() ?? ""; + if (content === "") { + toast.error("Nothing to preview"); + return; + } + + showPreviewMarkdownDialog(editorRef.current?.getContent() ?? ""); + }; + + return ( + + + + + + + + Code block + + + + Checkbox + + + + Preview + +
+ + Content syntax + +
+
+
+ ); +}; + +export default MarkdownMenu; diff --git a/web/src/components/MemoEditor/ActionButton/TagSelector.tsx b/web/src/components/MemoEditor/ActionButton/TagSelector.tsx index e7409369e1d56..186c87ea19f5c 100644 --- a/web/src/components/MemoEditor/ActionButton/TagSelector.tsx +++ b/web/src/components/MemoEditor/ActionButton/TagSelector.tsx @@ -1,39 +1,85 @@ -import { IconButton } from "@mui/joy"; +import { Dropdown, IconButton, Menu, MenuButton } from "@mui/joy"; +import { useEffect, useRef, useState } from "react"; +import useClickAway from "react-use/lib/useClickAway"; import Icon from "@/components/Icon"; +import OverflowTip from "@/components/kit/OverflowTip"; import { useTagStore } from "@/store/module"; +import { EditorRefActions } from "../Editor"; interface Props { - onTagSelectorClick: (tag: string) => void; + editorRef: React.RefObject; } const TagSelector = (props: Props) => { - const { onTagSelectorClick } = props; + const { editorRef } = props; const tagStore = useTagStore(); + const [open, setOpen] = useState(false); + const containerRef = useRef(null); const tags = tagStore.state.tags; + useEffect(() => { + (async () => { + try { + await tagStore.fetchTags(); + } catch (error) { + // do nothing. + } + })(); + }, []); + + useClickAway(containerRef, () => { + setOpen(false); + }); + + const handleTagClick = (tag: string) => { + const current = editorRef.current; + if (current === null) return; + + const line = current.getLine(current.getCursorLineNumber()); + const lastCharOfLine = line.slice(-1); + + if (lastCharOfLine !== " " && lastCharOfLine !== " " && line !== "") { + current.insertText("\n"); + } + current.insertText(`#${tag} `); + }; + return ( - - -
- {tags.length > 0 ? ( - tags.map((tag) => { - return ( - onTagSelectorClick(tag)} - key={tag} - > - #{tag} - - ); - }) - ) : ( -

e.stopPropagation()}> - No tags found -

- )} -
-
+ setOpen(isOpen)}> + + + + +
+ {tags.length > 0 ? ( +
+ {tags.map((tag) => { + return ( +
handleTagClick(tag)} + > + #{tag} +
+ ); + })} +
+ ) : ( +

e.stopPropagation()}> + No tag found +

+ )} +
+
+
); }; diff --git a/web/src/components/MemoEditor/Editor/TagSuggestions.tsx b/web/src/components/MemoEditor/Editor/TagSuggestions.tsx index 6383926bcdc0e..35fdf763545f8 100644 --- a/web/src/components/MemoEditor/Editor/TagSuggestions.tsx +++ b/web/src/components/MemoEditor/Editor/TagSuggestions.tsx @@ -1,6 +1,8 @@ import classNames from "classnames"; +import Fuse from "fuse.js"; import { useEffect, useRef, useState } from "react"; import getCaretCoordinates from "textarea-caret"; +import OverflowTip from "@/components/kit/OverflowTip"; import { useTagStore } from "@/store/module"; import { EditorRefActions } from "."; @@ -8,6 +10,7 @@ type Props = { editorRef: React.RefObject; editorActions: React.ForwardedRef; }; + type Position = { left: number; top: number; height: number }; const TagSuggestions = ({ editorRef, editorActions }: Props) => { @@ -33,28 +36,9 @@ const TagSuggestions = ({ editorRef, editorActions }: Props) => { const suggestionsRef = useRef([]); suggestionsRef.current = (() => { - const input = getCurrentWord()[0].slice(1).toLowerCase(); - - const customMatches = (tag: string, input: string) => { - const tagLowerCase = tag.toLowerCase(); - const inputLowerCase = input.toLowerCase(); - let inputIndex = 0; - - for (let i = 0; i < tagLowerCase.length; i++) { - if (tagLowerCase[i] === inputLowerCase[inputIndex]) { - inputIndex++; - if (inputIndex === inputLowerCase.length) { - return true; - } - } - } - - return false; - }; - - const matchedTags = tagsRef.current.filter((tag) => customMatches(tag, input)); - - return matchedTags.slice(0, 5); + const search = getCurrentWord()[0].slice(1).toLowerCase(); + const fuse = new Fuse(tagsRef.current); + return fuse.search(search).map((result) => result.item); })(); const isVisibleRef = useRef(false); @@ -91,11 +75,17 @@ const TagSuggestions = ({ editorRef, editorActions }: Props) => { }; const handleInput = () => { - if (!editorRef.current) return; + const editor = editorRef.current; + if (!editor) return; + select(0); const [word, index] = getCurrentWord(); - const isActive = word.startsWith("#") && !word.slice(1).includes("#"); - isActive ? setPosition(getCaretCoordinates(editorRef.current, index)) : hide(); + const currentChar = editor.value[editor.selectionEnd]; + const isActive = word.startsWith("#") && currentChar !== "#"; + + const caretCordinates = getCaretCoordinates(editor, index); + caretCordinates.top -= editor.scrollTop; + isActive ? setPosition(caretCordinates) : hide(); }; const listenersAreRegisteredRef = useRef(false); @@ -113,7 +103,7 @@ const TagSuggestions = ({ editorRef, editorActions }: Props) => { if (!isVisibleRef.current || !position) return null; return (
{suggestionsRef.current.map((tag, i) => ( @@ -121,11 +111,11 @@ const TagSuggestions = ({ editorRef, editorActions }: Props) => { key={tag} onMouseDown={() => autocomplete(tag)} className={classNames( - "rounded p-1 px-2 w-full truncate text-sm dark:text-gray-300 cursor-pointer hover:bg-zinc-300 dark:hover:bg-zinc-700", - i === selected ? "bg-zinc-300 dark:bg-zinc-700" : "" + "rounded p-1 px-2 w-full truncate text-sm dark:text-gray-300 cursor-pointer hover:bg-zinc-200 dark:hover:bg-zinc-800", + i === selected ? "bg-zinc-300 dark:bg-zinc-600" : "", )} > - #{tag} + #{tag}
))}
diff --git a/web/src/components/MemoEditor/Editor/index.tsx b/web/src/components/MemoEditor/Editor/index.tsx index 41fa11eb843f2..0b82591ffe095 100644 --- a/web/src/components/MemoEditor/Editor/index.tsx +++ b/web/src/components/MemoEditor/Editor/index.tsx @@ -136,7 +136,7 @@ const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef< } }, }), - [] + [], ); const handleEditorInput = useCallback(() => { @@ -145,9 +145,14 @@ const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef< }, []); return ( -
+