mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2025-07-18 17:38:07 +08:00
Delete Lark Drive (#201)
This commit is contained in:
@ -1,9 +0,0 @@
|
|||||||
//go:build (linux || darwin || windows) && (amd64 || arm64)
|
|
||||||
// +build linux darwin windows
|
|
||||||
// +build amd64 arm64
|
|
||||||
|
|
||||||
package drivers
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "github.com/OpenListTeam/OpenList/drivers/lark"
|
|
||||||
)
|
|
@ -1,403 +0,0 @@
|
|||||||
package lark
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/OpenListTeam/OpenList/internal/driver"
|
|
||||||
"github.com/OpenListTeam/OpenList/internal/errs"
|
|
||||||
"github.com/OpenListTeam/OpenList/internal/model"
|
|
||||||
lark "github.com/larksuite/oapi-sdk-go/v3"
|
|
||||||
larkcore "github.com/larksuite/oapi-sdk-go/v3/core"
|
|
||||||
larkdrive "github.com/larksuite/oapi-sdk-go/v3/service/drive/v1"
|
|
||||||
"golang.org/x/time/rate"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Lark struct {
|
|
||||||
model.Storage
|
|
||||||
Addition
|
|
||||||
|
|
||||||
client *lark.Client
|
|
||||||
rootFolderToken string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Lark) Config() driver.Config {
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Lark) GetAddition() driver.Additional {
|
|
||||||
return &c.Addition
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Lark) Init(ctx context.Context) error {
|
|
||||||
c.client = lark.NewClient(c.AppId, c.AppSecret, lark.WithTokenCache(newTokenCache()))
|
|
||||||
|
|
||||||
paths := strings.Split(c.RootFolderPath, "/")
|
|
||||||
token := ""
|
|
||||||
|
|
||||||
var ok bool
|
|
||||||
var file *larkdrive.File
|
|
||||||
for _, p := range paths {
|
|
||||||
if p == "" {
|
|
||||||
token = ""
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := c.client.Drive.File.ListByIterator(ctx, larkdrive.NewListFileReqBuilder().FolderToken(token).Build())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
ok, file, err = resp.Next()
|
|
||||||
if !ok {
|
|
||||||
return errs.ObjectNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if *file.Type == "folder" && *file.Name == p {
|
|
||||||
token = *file.Token
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.rootFolderToken = token
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Lark) Drop(ctx context.Context) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Lark) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
|
|
||||||
token, ok := c.getObjToken(ctx, dir.GetPath())
|
|
||||||
if !ok {
|
|
||||||
return nil, errs.ObjectNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
if token == emptyFolderToken {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := c.client.Drive.File.ListByIterator(ctx, larkdrive.NewListFileReqBuilder().FolderToken(token).Build())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ok = false
|
|
||||||
var file *larkdrive.File
|
|
||||||
var res []model.Obj
|
|
||||||
|
|
||||||
for {
|
|
||||||
ok, file, err = resp.Next()
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
modifiedUnix, _ := strconv.ParseInt(*file.ModifiedTime, 10, 64)
|
|
||||||
createdUnix, _ := strconv.ParseInt(*file.CreatedTime, 10, 64)
|
|
||||||
|
|
||||||
f := model.Object{
|
|
||||||
ID: *file.Token,
|
|
||||||
Path: strings.Join([]string{c.RootFolderPath, dir.GetPath(), *file.Name}, "/"),
|
|
||||||
Name: *file.Name,
|
|
||||||
Size: 0,
|
|
||||||
Modified: time.Unix(modifiedUnix, 0),
|
|
||||||
Ctime: time.Unix(createdUnix, 0),
|
|
||||||
IsFolder: *file.Type == "folder",
|
|
||||||
}
|
|
||||||
res = append(res, &f)
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Lark) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
|
||||||
token, ok := c.getObjToken(ctx, file.GetPath())
|
|
||||||
if !ok {
|
|
||||||
return nil, errs.ObjectNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := c.client.GetTenantAccessTokenBySelfBuiltApp(ctx, &larkcore.SelfBuiltTenantAccessTokenReq{
|
|
||||||
AppID: c.AppId,
|
|
||||||
AppSecret: c.AppSecret,
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !c.ExternalMode {
|
|
||||||
accessToken := resp.TenantAccessToken
|
|
||||||
|
|
||||||
url := fmt.Sprintf("https://open.feishu.cn/open-apis/drive/v1/files/%s/download", token)
|
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", accessToken))
|
|
||||||
req.Header.Set("Range", "bytes=0-1")
|
|
||||||
|
|
||||||
ar, err := http.DefaultClient.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if ar.StatusCode != http.StatusPartialContent {
|
|
||||||
return nil, errors.New("failed to get download link")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &model.Link{
|
|
||||||
URL: url,
|
|
||||||
Header: http.Header{
|
|
||||||
"Authorization": []string{fmt.Sprintf("Bearer %s", accessToken)},
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
} else {
|
|
||||||
url := strings.Join([]string{c.TenantUrlPrefix, "file", token}, "/")
|
|
||||||
|
|
||||||
return &model.Link{
|
|
||||||
URL: url,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Lark) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) {
|
|
||||||
token, ok := c.getObjToken(ctx, parentDir.GetPath())
|
|
||||||
if !ok {
|
|
||||||
return nil, errs.ObjectNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := larkdrive.NewCreateFolderFilePathReqBodyBuilder().FolderToken(token).Name(dirName).Build()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := c.client.Drive.File.CreateFolder(ctx,
|
|
||||||
larkdrive.NewCreateFolderFileReqBuilder().Body(body).Build())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !resp.Success() {
|
|
||||||
return nil, errors.New(resp.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return &model.Object{
|
|
||||||
ID: *resp.Data.Token,
|
|
||||||
Path: strings.Join([]string{c.RootFolderPath, parentDir.GetPath(), dirName}, "/"),
|
|
||||||
Name: dirName,
|
|
||||||
Size: 0,
|
|
||||||
IsFolder: true,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Lark) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
|
|
||||||
srcToken, ok := c.getObjToken(ctx, srcObj.GetPath())
|
|
||||||
if !ok {
|
|
||||||
return nil, errs.ObjectNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
dstDirToken, ok := c.getObjToken(ctx, dstDir.GetPath())
|
|
||||||
if !ok {
|
|
||||||
return nil, errs.ObjectNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
req := larkdrive.NewMoveFileReqBuilder().
|
|
||||||
Body(larkdrive.NewMoveFileReqBodyBuilder().
|
|
||||||
Type("file").
|
|
||||||
FolderToken(dstDirToken).
|
|
||||||
Build()).FileToken(srcToken).
|
|
||||||
Build()
|
|
||||||
|
|
||||||
// 发起请求
|
|
||||||
resp, err := c.client.Drive.File.Move(ctx, req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !resp.Success() {
|
|
||||||
return nil, errors.New(resp.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Lark) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) {
|
|
||||||
// TODO rename obj, optional
|
|
||||||
return nil, errs.NotImplement
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Lark) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
|
|
||||||
srcToken, ok := c.getObjToken(ctx, srcObj.GetPath())
|
|
||||||
if !ok {
|
|
||||||
return nil, errs.ObjectNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
dstDirToken, ok := c.getObjToken(ctx, dstDir.GetPath())
|
|
||||||
if !ok {
|
|
||||||
return nil, errs.ObjectNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
req := larkdrive.NewCopyFileReqBuilder().
|
|
||||||
Body(larkdrive.NewCopyFileReqBodyBuilder().
|
|
||||||
Name(srcObj.GetName()).
|
|
||||||
Type("file").
|
|
||||||
FolderToken(dstDirToken).
|
|
||||||
Build()).FileToken(srcToken).
|
|
||||||
Build()
|
|
||||||
|
|
||||||
// 发起请求
|
|
||||||
resp, err := c.client.Drive.File.Copy(ctx, req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !resp.Success() {
|
|
||||||
return nil, errors.New(resp.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Lark) Remove(ctx context.Context, obj model.Obj) error {
|
|
||||||
token, ok := c.getObjToken(ctx, obj.GetPath())
|
|
||||||
if !ok {
|
|
||||||
return errs.ObjectNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
req := larkdrive.NewDeleteFileReqBuilder().
|
|
||||||
FileToken(token).
|
|
||||||
Type("file").
|
|
||||||
Build()
|
|
||||||
|
|
||||||
// 发起请求
|
|
||||||
resp, err := c.client.Drive.File.Delete(ctx, req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !resp.Success() {
|
|
||||||
return errors.New(resp.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var uploadLimit = rate.NewLimiter(rate.Every(time.Second), 5)
|
|
||||||
|
|
||||||
func (c *Lark) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) (model.Obj, error) {
|
|
||||||
token, ok := c.getObjToken(ctx, dstDir.GetPath())
|
|
||||||
if !ok {
|
|
||||||
return nil, errs.ObjectNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare
|
|
||||||
req := larkdrive.NewUploadPrepareFileReqBuilder().
|
|
||||||
FileUploadInfo(larkdrive.NewFileUploadInfoBuilder().
|
|
||||||
FileName(stream.GetName()).
|
|
||||||
ParentType(`explorer`).
|
|
||||||
ParentNode(token).
|
|
||||||
Size(int(stream.GetSize())).
|
|
||||||
Build()).
|
|
||||||
Build()
|
|
||||||
|
|
||||||
// 发起请求
|
|
||||||
err := uploadLimit.Wait(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
resp, err := c.client.Drive.File.UploadPrepare(ctx, req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !resp.Success() {
|
|
||||||
return nil, errors.New(resp.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadId := *resp.Data.UploadId
|
|
||||||
blockSize := *resp.Data.BlockSize
|
|
||||||
blockCount := *resp.Data.BlockNum
|
|
||||||
|
|
||||||
// upload
|
|
||||||
for i := 0; i < blockCount; i++ {
|
|
||||||
length := int64(blockSize)
|
|
||||||
if i == blockCount-1 {
|
|
||||||
length = stream.GetSize() - int64(i*blockSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
reader := driver.NewLimitedUploadStream(ctx, io.LimitReader(stream, length))
|
|
||||||
|
|
||||||
req := larkdrive.NewUploadPartFileReqBuilder().
|
|
||||||
Body(larkdrive.NewUploadPartFileReqBodyBuilder().
|
|
||||||
UploadId(uploadId).
|
|
||||||
Seq(i).
|
|
||||||
Size(int(length)).
|
|
||||||
File(reader).
|
|
||||||
Build()).
|
|
||||||
Build()
|
|
||||||
|
|
||||||
// 发起请求
|
|
||||||
err = uploadLimit.Wait(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
resp, err := c.client.Drive.File.UploadPart(ctx, req)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !resp.Success() {
|
|
||||||
return nil, errors.New(resp.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
up(float64(i) / float64(blockCount))
|
|
||||||
}
|
|
||||||
|
|
||||||
//close
|
|
||||||
closeReq := larkdrive.NewUploadFinishFileReqBuilder().
|
|
||||||
Body(larkdrive.NewUploadFinishFileReqBodyBuilder().
|
|
||||||
UploadId(uploadId).
|
|
||||||
BlockNum(blockCount).
|
|
||||||
Build()).
|
|
||||||
Build()
|
|
||||||
|
|
||||||
// 发起请求
|
|
||||||
closeResp, err := c.client.Drive.File.UploadFinish(ctx, closeReq)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !closeResp.Success() {
|
|
||||||
return nil, errors.New(closeResp.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
return &model.Object{
|
|
||||||
ID: *closeResp.Data.FileToken,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
//func (d *Lark) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) {
|
|
||||||
// return nil, errs.NotSupport
|
|
||||||
//}
|
|
||||||
|
|
||||||
var _ driver.Driver = (*Lark)(nil)
|
|
@ -1,36 +0,0 @@
|
|||||||
package lark
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/OpenListTeam/OpenList/internal/driver"
|
|
||||||
"github.com/OpenListTeam/OpenList/internal/op"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Addition struct {
|
|
||||||
// Usually one of two
|
|
||||||
driver.RootPath
|
|
||||||
// define other
|
|
||||||
AppId string `json:"app_id" type:"text" help:"app id"`
|
|
||||||
AppSecret string `json:"app_secret" type:"text" help:"app secret"`
|
|
||||||
ExternalMode bool `json:"external_mode" type:"bool" help:"external mode"`
|
|
||||||
TenantUrlPrefix string `json:"tenant_url_prefix" type:"text" help:"tenant url prefix"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var config = driver.Config{
|
|
||||||
Name: "Lark",
|
|
||||||
LocalSort: false,
|
|
||||||
OnlyLocal: false,
|
|
||||||
OnlyProxy: false,
|
|
||||||
NoCache: false,
|
|
||||||
NoUpload: false,
|
|
||||||
NeedMs: false,
|
|
||||||
DefaultRoot: "/",
|
|
||||||
CheckStatus: false,
|
|
||||||
Alert: "",
|
|
||||||
NoOverwriteUpload: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
op.RegisterDriver(func() driver.Driver {
|
|
||||||
return &Lark{}
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package lark
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/Xhofe/go-cache"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TokenCache struct {
|
|
||||||
cache.ICache[string]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TokenCache) Set(_ context.Context, key string, value string, expireTime time.Duration) error {
|
|
||||||
t.ICache.Set(key, value, cache.WithEx[string](expireTime))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TokenCache) Get(_ context.Context, key string) (string, error) {
|
|
||||||
v, ok := t.ICache.Get(key)
|
|
||||||
if ok {
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTokenCache() *TokenCache {
|
|
||||||
c := cache.NewMemCache[string]()
|
|
||||||
|
|
||||||
return &TokenCache{c}
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
package lark
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/Xhofe/go-cache"
|
|
||||||
larkdrive "github.com/larksuite/oapi-sdk-go/v3/service/drive/v1"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"path"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const objTokenCacheDuration = 5 * time.Minute
|
|
||||||
const emptyFolderToken = "empty"
|
|
||||||
|
|
||||||
var objTokenCache = cache.NewMemCache[string]()
|
|
||||||
var exOpts = cache.WithEx[string](objTokenCacheDuration)
|
|
||||||
|
|
||||||
func (c *Lark) getObjToken(ctx context.Context, folderPath string) (string, bool) {
|
|
||||||
if token, ok := objTokenCache.Get(folderPath); ok {
|
|
||||||
return token, true
|
|
||||||
}
|
|
||||||
|
|
||||||
dir, name := path.Split(folderPath)
|
|
||||||
// strip the last slash of dir if it exists
|
|
||||||
if len(dir) > 0 && dir[len(dir)-1] == '/' {
|
|
||||||
dir = dir[:len(dir)-1]
|
|
||||||
}
|
|
||||||
if name == "" {
|
|
||||||
return c.rootFolderToken, true
|
|
||||||
}
|
|
||||||
|
|
||||||
var parentToken string
|
|
||||||
var found bool
|
|
||||||
parentToken, found = c.getObjToken(ctx, dir)
|
|
||||||
if !found {
|
|
||||||
return emptyFolderToken, false
|
|
||||||
}
|
|
||||||
|
|
||||||
req := larkdrive.NewListFileReqBuilder().FolderToken(parentToken).Build()
|
|
||||||
resp, err := c.client.Drive.File.ListByIterator(ctx, req)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.WithError(err).Error("failed to list files")
|
|
||||||
return emptyFolderToken, false
|
|
||||||
}
|
|
||||||
|
|
||||||
var file *larkdrive.File
|
|
||||||
for {
|
|
||||||
found, file, err = resp.Next()
|
|
||||||
if !found {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.WithError(err).Error("failed to get next file")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if *file.Name == name {
|
|
||||||
objTokenCache.Set(folderPath, *file.Token, exOpts)
|
|
||||||
return *file.Token, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return emptyFolderToken, false
|
|
||||||
}
|
|
1
go.mod
1
go.mod
@ -40,7 +40,6 @@ require (
|
|||||||
github.com/jlaffaye/ftp v0.2.0
|
github.com/jlaffaye/ftp v0.2.0
|
||||||
github.com/json-iterator/go v1.1.12
|
github.com/json-iterator/go v1.1.12
|
||||||
github.com/kdomanski/iso9660 v0.4.0
|
github.com/kdomanski/iso9660 v0.4.0
|
||||||
github.com/larksuite/oapi-sdk-go/v3 v3.3.1
|
|
||||||
github.com/maruel/natural v1.1.1
|
github.com/maruel/natural v1.1.1
|
||||||
github.com/meilisearch/meilisearch-go v0.27.2
|
github.com/meilisearch/meilisearch-go v0.27.2
|
||||||
github.com/mholt/archives v0.1.0
|
github.com/mholt/archives v0.1.0
|
||||||
|
2
go.sum
2
go.sum
@ -402,8 +402,6 @@ 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.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 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/larksuite/oapi-sdk-go/v3 v3.3.1 h1:DLQQEgHUAGZB6RVlceB1f6A94O206exxW2RIMH+gMUc=
|
|
||||||
github.com/larksuite/oapi-sdk-go/v3 v3.3.1/go.mod h1:ZEplY+kwuIrj/nqw5uSCINNATcH3KdxSN7y+UxYY5fI=
|
|
||||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
|
||||||
|
Reference in New Issue
Block a user