Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
015040cc1d | |||
c8869e67c7 | |||
a9ae7d2e96 | |||
db9034ccf9 | |||
4d1705dca5 | |||
3225e7c47b | |||
328397612c | |||
c846cde5b4 | |||
5c2cb99866 | |||
742c7da2eb | |||
88b247410f | |||
01417943fb |
10
.github/workflows/extension-test.yml
vendored
@ -15,9 +15,6 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: bufbuild/buf-setup-action@v1
|
|
||||||
- run: buf generate
|
|
||||||
working-directory: proto
|
|
||||||
- uses: pnpm/action-setup@v2.2.4
|
- uses: pnpm/action-setup@v2.2.4
|
||||||
with:
|
with:
|
||||||
version: 8
|
version: 8
|
||||||
@ -28,6 +25,8 @@ jobs:
|
|||||||
cache-dependency-path: "frontend/extension/pnpm-lock.yaml"
|
cache-dependency-path: "frontend/extension/pnpm-lock.yaml"
|
||||||
- run: pnpm install
|
- run: pnpm install
|
||||||
working-directory: frontend/extension
|
working-directory: frontend/extension
|
||||||
|
- run: pnpm type-gen
|
||||||
|
working-directory: frontend/extension
|
||||||
- name: Run eslint check
|
- name: Run eslint check
|
||||||
run: pnpm lint
|
run: pnpm lint
|
||||||
working-directory: frontend/extension
|
working-directory: frontend/extension
|
||||||
@ -36,9 +35,6 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: bufbuild/buf-setup-action@v1
|
|
||||||
- run: buf generate
|
|
||||||
working-directory: proto
|
|
||||||
- uses: pnpm/action-setup@v2.2.4
|
- uses: pnpm/action-setup@v2.2.4
|
||||||
with:
|
with:
|
||||||
version: 8
|
version: 8
|
||||||
@ -49,6 +45,8 @@ jobs:
|
|||||||
cache-dependency-path: "frontend/extension/pnpm-lock.yaml"
|
cache-dependency-path: "frontend/extension/pnpm-lock.yaml"
|
||||||
- run: pnpm install
|
- run: pnpm install
|
||||||
working-directory: frontend/extension
|
working-directory: frontend/extension
|
||||||
|
- run: pnpm type-gen
|
||||||
|
working-directory: frontend/extension
|
||||||
- name: Run extension build
|
- name: Run extension build
|
||||||
run: pnpm build
|
run: pnpm build
|
||||||
working-directory: frontend/extension
|
working-directory: frontend/extension
|
||||||
|
10
.github/workflows/frontend-test.yml
vendored
@ -15,9 +15,6 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: bufbuild/buf-setup-action@v1
|
|
||||||
- run: buf generate
|
|
||||||
working-directory: proto
|
|
||||||
- uses: pnpm/action-setup@v2.2.4
|
- uses: pnpm/action-setup@v2.2.4
|
||||||
with:
|
with:
|
||||||
version: 8
|
version: 8
|
||||||
@ -28,6 +25,8 @@ jobs:
|
|||||||
cache-dependency-path: "frontend/web/pnpm-lock.yaml"
|
cache-dependency-path: "frontend/web/pnpm-lock.yaml"
|
||||||
- run: pnpm install
|
- run: pnpm install
|
||||||
working-directory: frontend/web
|
working-directory: frontend/web
|
||||||
|
- run: pnpm type-gen
|
||||||
|
working-directory: frontend/web
|
||||||
- name: Run eslint check
|
- name: Run eslint check
|
||||||
run: pnpm lint
|
run: pnpm lint
|
||||||
working-directory: frontend/web
|
working-directory: frontend/web
|
||||||
@ -36,9 +35,6 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: bufbuild/buf-setup-action@v1
|
|
||||||
- run: buf generate
|
|
||||||
working-directory: proto
|
|
||||||
- uses: pnpm/action-setup@v2.2.4
|
- uses: pnpm/action-setup@v2.2.4
|
||||||
with:
|
with:
|
||||||
version: 8
|
version: 8
|
||||||
@ -49,6 +45,8 @@ jobs:
|
|||||||
cache-dependency-path: "frontend/web/pnpm-lock.yaml"
|
cache-dependency-path: "frontend/web/pnpm-lock.yaml"
|
||||||
- run: pnpm install
|
- run: pnpm install
|
||||||
working-directory: frontend/web
|
working-directory: frontend/web
|
||||||
|
- run: pnpm type-gen
|
||||||
|
working-directory: frontend/web
|
||||||
- name: Run frontend build
|
- name: Run frontend build
|
||||||
run: pnpm build
|
run: pnpm build
|
||||||
working-directory: frontend/web
|
working-directory: frontend/web
|
||||||
|
24
Dockerfile
@ -1,26 +1,12 @@
|
|||||||
# Build protobuf.
|
|
||||||
FROM golang:1.21-alpine AS protobuf
|
|
||||||
WORKDIR /protobuf-generate
|
|
||||||
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
RUN GO111MODULE=on GOBIN=/usr/local/bin go install github.com/bufbuild/buf/cmd/buf@v1.26.1
|
|
||||||
|
|
||||||
WORKDIR /protobuf-generate/proto
|
|
||||||
|
|
||||||
RUN buf generate
|
|
||||||
|
|
||||||
# Build frontend dist.
|
# Build frontend dist.
|
||||||
FROM node:18-alpine AS frontend
|
FROM node:18-alpine AS frontend
|
||||||
WORKDIR /frontend-build
|
WORKDIR /frontend-build
|
||||||
|
|
||||||
COPY ./frontend .
|
COPY . .
|
||||||
|
|
||||||
COPY --from=protobuf /protobuf-generate/frontend/web/src/types/proto ./web/src/types/proto
|
WORKDIR /frontend-build/frontend/web
|
||||||
|
|
||||||
WORKDIR /frontend-build/web
|
RUN corepack enable && pnpm i --frozen-lockfile && pnpm type-gen
|
||||||
|
|
||||||
RUN corepack enable && pnpm i --frozen-lockfile
|
|
||||||
|
|
||||||
RUN pnpm build
|
RUN pnpm build
|
||||||
|
|
||||||
@ -29,9 +15,9 @@ FROM golang:1.21-alpine AS backend
|
|||||||
WORKDIR /backend-build
|
WORKDIR /backend-build
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
COPY --from=frontend /frontend-build/web/dist ./server/dist
|
COPY --from=frontend /frontend-build/frontend/web/dist ./server/dist
|
||||||
|
|
||||||
RUN CGO_ENABLED=0 go build -o slash ./cmd/slash/main.go
|
RUN CGO_ENABLED=0 go build -o slash ./bin/slash/main.go
|
||||||
|
|
||||||
# Make workspace with above generated files.
|
# Make workspace with above generated files.
|
||||||
FROM alpine:latest AS monolithic
|
FROM alpine:latest AS monolithic
|
||||||
|
11
README.md
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
**Slash** is an open source, self-hosted bookmarks and link sharing platform. It allows you to organize your links with tags, and share them using custom shortened URLs. Slash also supports team sharing of link libraries for easy collaboration.
|
**Slash** is an open source, self-hosted bookmarks and link sharing platform. It allows you to organize your links with tags, and share them using custom shortened URLs. Slash also supports team sharing of link libraries for easy collaboration.
|
||||||
|
|
||||||
|
🧩 Browser extension(v1.0.0) now available! - [Chrome Web Store](https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg), [Firefox Add-on](https://addons.mozilla.org/firefox/addon/your-slash/)
|
||||||
|
|
||||||
<a href="https://demo.slash.yourselfhosted.com">Live Demo</a> • <a href="https://discord.gg/QZqUuUAhDV">Discord</a>
|
<a href="https://demo.slash.yourselfhosted.com">Live Demo</a> • <a href="https://discord.gg/QZqUuUAhDV">Discord</a>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@ -11,9 +13,6 @@
|
|||||||
<a href="https://github.com/boojack/slash/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/boojack/slash?logo=github"/></a>
|
<a href="https://github.com/boojack/slash/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/boojack/slash?logo=github"/></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<a href="https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg"><b>🧩 Browser extension now available!</b></a></p>
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
@ -38,8 +37,12 @@ Slash provides a browser extension to help you use your shortcuts in the search
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
Learn more in [The Browser Extension of Slash](https://github.com/boojack/slash/blob/main/docs/install-browser-extension.md).
|
||||||
|
|
||||||
### Chromium based browsers
|
### Chromium based browsers
|
||||||
|
|
||||||
For Chromium based browsers(Chrome, Edge, Arc, ...), you can install the extension from the [Chrome Web Store](https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg).
|
For Chromium based browsers(Chrome, Edge, Arc, ...), you can install the extension from the [Chrome Web Store](https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg).
|
||||||
|
|
||||||
Learn more in [The Browser Extension of Slash](https://github.com/boojack/slash/blob/main/docs/install-browser-extension.md).
|
### Firefox
|
||||||
|
|
||||||
|
For Firefox, you can install the extension from the [Firefox Add-ons](https://addons.mozilla.org/firefox/addon/your-slash/).
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/mssola/useragent"
|
"github.com/mssola/useragent"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
|
|
||||||
|
"github.com/boojack/slash/server/metric"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -78,6 +79,7 @@ func (s *APIV1Service) registerAnalyticsRoutes(g *echo.Group) {
|
|||||||
browserMap[browserName]++
|
browserMap[browserName]++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metric.Enqueue("shortcut analytics")
|
||||||
return c.JSON(http.StatusOK, &AnalysisData{
|
return c.JSON(http.StatusOK, &AnalysisData{
|
||||||
ReferenceData: mapToReferenceInfoSlice(referenceMap),
|
ReferenceData: mapToReferenceInfoSlice(referenceMap),
|
||||||
DeviceData: mapToDeviceInfoSlice(deviceMap),
|
DeviceData: mapToDeviceInfoSlice(deviceMap),
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
|
|
||||||
"github.com/boojack/slash/api/auth"
|
"github.com/boojack/slash/api/auth"
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
|
"github.com/boojack/slash/server/metric"
|
||||||
"github.com/boojack/slash/server/service/license"
|
"github.com/boojack/slash/server/service/license"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
@ -63,6 +64,7 @@ func (s *APIV1Service) registerAuthRoutes(g *echo.Group, secret string) {
|
|||||||
|
|
||||||
cookieExp := time.Now().Add(auth.CookieExpDuration)
|
cookieExp := time.Now().Add(auth.CookieExpDuration)
|
||||||
setTokenCookie(c, auth.AccessTokenCookieName, accessToken, cookieExp)
|
setTokenCookie(c, auth.AccessTokenCookieName, accessToken, cookieExp)
|
||||||
|
metric.Enqueue("user sign in")
|
||||||
return c.JSON(http.StatusOK, convertUserFromStore(user))
|
return c.JSON(http.StatusOK, convertUserFromStore(user))
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -129,6 +131,7 @@ func (s *APIV1Service) registerAuthRoutes(g *echo.Group, secret string) {
|
|||||||
|
|
||||||
cookieExp := time.Now().Add(auth.CookieExpDuration)
|
cookieExp := time.Now().Add(auth.CookieExpDuration)
|
||||||
setTokenCookie(c, auth.AccessTokenCookieName, accessToken, cookieExp)
|
setTokenCookie(c, auth.AccessTokenCookieName, accessToken, cookieExp)
|
||||||
|
metric.Enqueue("user sign up")
|
||||||
return c.JSON(http.StatusOK, convertUserFromStore(user))
|
return c.JSON(http.StatusOK, convertUserFromStore(user))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
|
"github.com/boojack/slash/server/metric"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ func (s *APIV1Service) registerRedirectorRoutes(g *echo.Group) {
|
|||||||
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to create activity, err: %s", err)).SetInternal(err)
|
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to create activity, err: %s", err)).SetInternal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metric.Enqueue("shortcut redirect")
|
||||||
return redirectToShortcut(c, shortcut)
|
return redirectToShortcut(c, shortcut)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/boojack/slash/internal/util"
|
"github.com/boojack/slash/internal/util"
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
|
"github.com/boojack/slash/server/metric"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -121,6 +122,7 @@ func (s *APIV1Service) registerShortcutRoutes(g *echo.Group) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to compose shortcut, err: %s", err)).SetInternal(err)
|
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to compose shortcut, err: %s", err)).SetInternal(err)
|
||||||
}
|
}
|
||||||
|
metric.Enqueue("shortcut create")
|
||||||
return c.JSON(http.StatusOK, shortcutMessage)
|
return c.JSON(http.StatusOK, shortcutMessage)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
"github.com/boojack/slash/internal/util"
|
"github.com/boojack/slash/internal/util"
|
||||||
|
"github.com/boojack/slash/server/metric"
|
||||||
"github.com/boojack/slash/server/service/license"
|
"github.com/boojack/slash/server/service/license"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
@ -137,6 +138,7 @@ func (s *APIV1Service) registerUserRoutes(g *echo.Group) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
userMessage := convertUserFromStore(user)
|
userMessage := convertUserFromStore(user)
|
||||||
|
metric.Enqueue("user create")
|
||||||
return c.JSON(http.StatusOK, userMessage)
|
return c.JSON(http.StatusOK, userMessage)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -121,10 +121,6 @@ func (s *WorkspaceService) UpdateWorkspaceSetting(ctx context.Context, request *
|
|||||||
return nil, status.Errorf(codes.Internal, "failed to update workspace setting: %v", err)
|
return nil, status.Errorf(codes.Internal, "failed to update workspace setting: %v", err)
|
||||||
}
|
}
|
||||||
} else if path == "custom_style" {
|
} else if path == "custom_style" {
|
||||||
if !s.LicenseService.IsFeatureEnabled(license.FeatureTypeCustomeStyle) {
|
|
||||||
return nil, status.Errorf(codes.PermissionDenied, "feature custom style is not available")
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := s.Store.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{
|
if _, err := s.Store.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{
|
||||||
Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_STYLE,
|
Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_STYLE,
|
||||||
Value: &storepb.WorkspaceSetting_CustomStyle{
|
Value: &storepb.WorkspaceSetting_CustomStyle{
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
|
|
||||||
"github.com/boojack/slash/internal/log"
|
"github.com/boojack/slash/internal/log"
|
||||||
"github.com/boojack/slash/server"
|
"github.com/boojack/slash/server"
|
||||||
|
"github.com/boojack/slash/server/metric"
|
||||||
"github.com/boojack/slash/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/boojack/slash/store/db"
|
"github.com/boojack/slash/store/db"
|
||||||
@ -50,6 +51,9 @@ var (
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nolint
|
||||||
|
metric.NewMetricClient(s.Secret, *serverProfile)
|
||||||
|
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
// Trigger graceful shutdown on SIGINT or SIGTERM.
|
// Trigger graceful shutdown on SIGINT or SIGTERM.
|
||||||
// The default signal sent by the `kill` command is SIGTERM,
|
// The default signal sent by the `kill` command is SIGTERM,
|
@ -8,7 +8,7 @@ Slash provides a browser extension to help you use your shortcuts in the search
|
|||||||
|
|
||||||
For Chromuim based browsers, you can install the extension from the [Chrome Web Store](https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg).
|
For Chromuim based browsers, you can install the extension from the [Chrome Web Store](https://chrome.google.com/webstore/detail/slash/ebaiehmkammnacjadffpicipfckgeobg).
|
||||||
|
|
||||||
For Firefox, we don't support the Firefox Add-ons platform yet. And we are working on it.
|
For Firefox, you can install the extension from the [Firefox Add-ons](https://addons.mozilla.org/en-US/firefox/addon/your-slash/).
|
||||||
|
|
||||||
### Generate an access token
|
### Generate an access token
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 257 KiB |
@ -8,13 +8,14 @@
|
|||||||
"build": "plasmo build",
|
"build": "plasmo build",
|
||||||
"package": "plasmo package",
|
"package": "plasmo package",
|
||||||
"lint": "eslint --ext .js,.ts,.tsx, src",
|
"lint": "eslint --ext .js,.ts,.tsx, src",
|
||||||
"lint-fix": "eslint --ext .js,.ts,.tsx, src --fix"
|
"lint-fix": "eslint --ext .js,.ts,.tsx, src --fix",
|
||||||
|
"type-gen": "cd ../../proto && buf generate"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.11.1",
|
"@emotion/react": "^11.11.1",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@mui/joy": "5.0.0-beta.0",
|
"@mui/joy": "5.0.0-beta.0",
|
||||||
"@plasmohq/storage": "^1.8.0",
|
"@plasmohq/storage": "^1.8.1",
|
||||||
"axios": "^1.5.1",
|
"axios": "^1.5.1",
|
||||||
"classnames": "^2.3.2",
|
"classnames": "^2.3.2",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
@ -23,19 +24,20 @@
|
|||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-hot-toast": "^2.4.1",
|
"react-hot-toast": "^2.4.1",
|
||||||
"zustand": "^4.4.1"
|
"zustand": "^4.4.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@bufbuild/buf": "^1.27.0",
|
||||||
"@trivago/prettier-plugin-sort-imports": "4.1.0",
|
"@trivago/prettier-plugin-sort-imports": "4.1.0",
|
||||||
"@types/chrome": "0.0.241",
|
"@types/chrome": "0.0.241",
|
||||||
"@types/lodash-es": "^4.17.9",
|
"@types/lodash-es": "^4.17.9",
|
||||||
"@types/node": "20.4.2",
|
"@types/node": "20.4.2",
|
||||||
"@types/react": "18.2.15",
|
"@types/react": "18.2.15",
|
||||||
"@types/react-dom": "18.2.7",
|
"@types/react-dom": "18.2.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
||||||
"@typescript-eslint/parser": "^6.7.3",
|
"@typescript-eslint/parser": "^6.8.0",
|
||||||
"autoprefixer": "^10.4.16",
|
"autoprefixer": "^10.4.16",
|
||||||
"eslint": "^8.50.0",
|
"eslint": "^8.51.0",
|
||||||
"eslint-config-prettier": "^8.10.0",
|
"eslint-config-prettier": "^8.10.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint-plugin-react": "^7.33.2",
|
||||||
|
624
frontend/extension/pnpm-lock.yaml
generated
@ -5,13 +5,14 @@
|
|||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
"serve": "vite preview",
|
"serve": "vite preview",
|
||||||
"lint": "eslint --ext .js,.ts,.tsx, src",
|
"lint": "eslint --ext .js,.ts,.tsx, src",
|
||||||
"lint-fix": "eslint --ext .js,.ts,.tsx, src --fix"
|
"lint-fix": "eslint --ext .js,.ts,.tsx, src --fix",
|
||||||
|
"type-gen": "cd ../../proto && buf generate"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.11.1",
|
"@emotion/react": "^11.11.1",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@mui/joy": "5.0.0-beta.7",
|
"@mui/joy": "5.0.0-beta.7",
|
||||||
"@reduxjs/toolkit": "^1.9.6",
|
"@reduxjs/toolkit": "^1.9.7",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"classnames": "^2.3.2",
|
"classnames": "^2.3.2",
|
||||||
"copy-to-clipboard": "^3.3.3",
|
"copy-to-clipboard": "^3.3.3",
|
||||||
@ -24,23 +25,24 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hot-toast": "^2.4.1",
|
"react-hot-toast": "^2.4.1",
|
||||||
"react-i18next": "^13.2.2",
|
"react-i18next": "^13.3.0",
|
||||||
"react-redux": "^8.1.2",
|
"react-redux": "^8.1.3",
|
||||||
"react-router-dom": "^6.16.0",
|
"react-router-dom": "^6.17.0",
|
||||||
"react-use": "^17.4.0",
|
"react-use": "^17.4.0",
|
||||||
"tailwindcss": "^3.3.3",
|
"tailwindcss": "^3.3.3",
|
||||||
"zustand": "^4.4.1"
|
"zustand": "^4.4.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@bufbuild/buf": "^1.27.0",
|
||||||
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
|
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
|
||||||
"@types/lodash-es": "^4.17.9",
|
"@types/lodash-es": "^4.17.9",
|
||||||
"@types/react": "^18.2.23",
|
"@types/react": "^18.2.28",
|
||||||
"@types/react-dom": "^18.2.8",
|
"@types/react-dom": "^18.2.13",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
||||||
"@typescript-eslint/parser": "^6.7.3",
|
"@typescript-eslint/parser": "^6.8.0",
|
||||||
"@vitejs/plugin-react-swc": "^3.4.0",
|
"@vitejs/plugin-react-swc": "^3.4.0",
|
||||||
"autoprefixer": "^10.4.16",
|
"autoprefixer": "^10.4.16",
|
||||||
"eslint": "^8.50.0",
|
"eslint": "^8.51.0",
|
||||||
"eslint-config-prettier": "^8.10.0",
|
"eslint-config-prettier": "^8.10.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint-plugin-react": "^7.33.2",
|
||||||
@ -49,6 +51,6 @@
|
|||||||
"prettier": "2.6.2",
|
"prettier": "2.6.2",
|
||||||
"protobufjs": "^7.2.5",
|
"protobufjs": "^7.2.5",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.2.2",
|
||||||
"vite": "^4.4.9"
|
"vite": "^4.4.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
644
frontend/web/pnpm-lock.yaml
generated
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 257 KiB |
@ -29,7 +29,7 @@ const Header: React.FC = () => {
|
|||||||
<div className="w-full max-w-6xl mx-auto px-3 md:px-12 py-5 flex flex-row justify-between items-center">
|
<div className="w-full max-w-6xl mx-auto px-3 md:px-12 py-5 flex flex-row justify-between items-center">
|
||||||
<div className="flex flex-row justify-start items-center shrink mr-2">
|
<div className="flex flex-row justify-start items-center shrink mr-2">
|
||||||
<Link to="/" className="text-lg cursor-pointer flex flex-row justify-start items-center dark:text-gray-400">
|
<Link to="/" className="text-lg cursor-pointer flex flex-row justify-start items-center dark:text-gray-400">
|
||||||
<img id="logo-img" src="/logo.png" className="w-8 h-auto mr-2 -mt-0.5 dark:opacity-80" alt="" />
|
<img id="logo-img" src="/logo.png" className="w-8 h-auto mr-2 -mt-0.5 dark:opacity-80 rounded-full shadow" alt="" />
|
||||||
Slash
|
Slash
|
||||||
</Link>
|
</Link>
|
||||||
{profile.plan === PlanType.PRO && (
|
{profile.plan === PlanType.PRO && (
|
||||||
|
@ -93,14 +93,14 @@ const ShortcutView = (props: Props) => {
|
|||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
key={tag}
|
key={tag}
|
||||||
className="max-w-[8rem] truncate text-gray-400 dark:text-gray-500 text-sm font-mono leading-4 cursor-pointer hover:opacity-80"
|
className="max-w-[8rem] truncate text-gray-400 dark:text-gray-500 text-sm leading-4 cursor-pointer hover:opacity-80"
|
||||||
onClick={() => viewStore.setFilter({ tag: tag })}
|
onClick={() => viewStore.setFilter({ tag: tag })}
|
||||||
>
|
>
|
||||||
#{tag}
|
#{tag}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{shortcut.tags.length === 0 && <span className="text-gray-400 text-sm font-mono leading-4 italic">No tags</span>}
|
{shortcut.tags.length === 0 && <span className="text-gray-400 text-sm leading-4 italic">No tags</span>}
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex mt-2 gap-2 overflow-x-auto">
|
<div className="w-full flex mt-2 gap-2 overflow-x-auto">
|
||||||
<Tooltip title="Creator" variant="solid" placement="top" arrow>
|
<Tooltip title="Creator" variant="solid" placement="top" arrow>
|
||||||
|
@ -63,6 +63,7 @@ const WorkspaceSection: React.FC = () => {
|
|||||||
<p className="mt-2 dark:text-gray-400">{t("settings.workspace.custom-style")}</p>
|
<p className="mt-2 dark:text-gray-400">{t("settings.workspace.custom-style")}</p>
|
||||||
<Textarea
|
<Textarea
|
||||||
className="w-full mt-2"
|
className="w-full mt-2"
|
||||||
|
placeholder="* {font-family: ui-monospace Monaco Consolas;}"
|
||||||
minRows={2}
|
minRows={2}
|
||||||
maxRows={5}
|
maxRows={5}
|
||||||
value={workspaceSetting.customStyle}
|
value={workspaceSetting.customStyle}
|
||||||
|
@ -137,14 +137,12 @@ const ShortcutDetail = () => {
|
|||||||
<div className="mt-4 ml-1 flex flex-row justify-start items-start flex-wrap gap-2">
|
<div className="mt-4 ml-1 flex flex-row justify-start items-start flex-wrap gap-2">
|
||||||
{shortcut.tags.map((tag) => {
|
{shortcut.tags.map((tag) => {
|
||||||
return (
|
return (
|
||||||
<span key={tag} className="max-w-[8rem] truncate text-gray-400 text font-mono leading-4 dark:text-gray-500">
|
<span key={tag} className="max-w-[8rem] truncate text-gray-400 text leading-4 dark:text-gray-500">
|
||||||
#{tag}
|
#{tag}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{shortcut.tags.length === 0 && (
|
{shortcut.tags.length === 0 && <span className="text-gray-400 text-sm leading-4 italic dark:text-gray-500">No tags</span>}
|
||||||
<span className="text-gray-400 text-sm font-mono leading-4 italic dark:text-gray-500">No tags</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex mt-4 gap-2">
|
<div className="w-full flex mt-4 gap-2">
|
||||||
<Tooltip title="Creator" variant="solid" placement="top" arrow>
|
<Tooltip title="Creator" variant="solid" placement="top" arrow>
|
||||||
|
@ -71,7 +71,7 @@ const SignIn: React.FC = () => {
|
|||||||
<div className="w-80 max-w-full h-full py-4 flex flex-col justify-start items-center">
|
<div className="w-80 max-w-full h-full py-4 flex flex-col justify-start items-center">
|
||||||
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
||||||
<div className="flex flex-row justify-start items-center w-auto mx-auto gap-y-2 mb-4">
|
<div className="flex flex-row justify-start items-center w-auto mx-auto gap-y-2 mb-4">
|
||||||
<img id="logo-img" src="/logo.png" className="w-12 h-auto mr-2 -mt-1" alt="logo" />
|
<img id="logo-img" src="/logo.png" className="w-12 h-auto mr-2 -mt-1 rounded-full shadow" alt="logo" />
|
||||||
<span className="text-3xl opacity-80 dark:text-gray-500">Slash</span>
|
<span className="text-3xl opacity-80 dark:text-gray-500">Slash</span>
|
||||||
</div>
|
</div>
|
||||||
<form className="w-full mt-6" onSubmit={handleSigninBtnClick}>
|
<form className="w-full mt-6" onSubmit={handleSigninBtnClick}>
|
||||||
|
@ -78,7 +78,7 @@ const SignUp: React.FC = () => {
|
|||||||
<div className="w-80 max-w-full h-full py-4 flex flex-col justify-start items-center">
|
<div className="w-80 max-w-full h-full py-4 flex flex-col justify-start items-center">
|
||||||
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
||||||
<div className="flex flex-row justify-start items-center w-auto mx-auto gap-y-2 mb-4">
|
<div className="flex flex-row justify-start items-center w-auto mx-auto gap-y-2 mb-4">
|
||||||
<img id="logo-img" src="/logo.png" className="w-12 h-auto mr-2 -mt-1" alt="logo" />
|
<img id="logo-img" src="/logo.png" className="w-12 h-auto mr-2 -mt-1 rounded-full shadow" alt="logo" />
|
||||||
<span className="text-3xl opacity-80 dark:text-gray-500">Slash</span>
|
<span className="text-3xl opacity-80 dark:text-gray-500">Slash</span>
|
||||||
</div>
|
</div>
|
||||||
<p className="w-full text-2xl mt-6 dark:text-gray-500">{t("auth.create-your-account")}</p>
|
<p className="w-full text-2xl mt-6 dark:text-gray-500">{t("auth.create-your-account")}</p>
|
||||||
|
9
go.mod
@ -10,10 +10,10 @@ require (
|
|||||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||||
golang.org/x/crypto v0.11.0
|
golang.org/x/crypto v0.14.0
|
||||||
golang.org/x/net v0.12.0 // indirect
|
golang.org/x/net v0.17.0 // indirect
|
||||||
golang.org/x/sys v0.10.0 // indirect
|
golang.org/x/sys v0.13.0 // indirect
|
||||||
golang.org/x/text v0.11.0 // indirect
|
golang.org/x/text v0.13.0 // indirect
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -78,6 +78,7 @@ require (
|
|||||||
github.com/mssola/useragent v1.0.0
|
github.com/mssola/useragent v1.0.0
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
|
github.com/posthog/posthog-go v0.0.0-20230801140217-d607812dee69
|
||||||
go.uber.org/zap v1.21.0
|
go.uber.org/zap v1.21.0
|
||||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df
|
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df
|
||||||
golang.org/x/mod v0.11.0
|
golang.org/x/mod v0.11.0
|
||||||
|
19
go.sum
@ -390,6 +390,8 @@ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qR
|
|||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
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.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 v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
@ -476,6 +478,7 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs
|
|||||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
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.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.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 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
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.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||||
@ -525,8 +528,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
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-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
|
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
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-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-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@ -608,8 +611,8 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||||
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
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-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-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@ -692,8 +695,8 @@ golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
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.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -702,8 +705,8 @@ 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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.4/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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
|
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
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-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-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 257 KiB |
Before Width: | Height: | Size: 3.5 KiB |
@ -3,7 +3,7 @@ tmp_dir = ".air"
|
|||||||
|
|
||||||
[build]
|
[build]
|
||||||
bin = "./.air/slash --mode dev"
|
bin = "./.air/slash --mode dev"
|
||||||
cmd = "go build -o ./.air/slash ./cmd/slash/main.go"
|
cmd = "go build -o ./.air/slash ./bin/slash/main.go"
|
||||||
delay = 1000
|
delay = 1000
|
||||||
exclude_dir = [".air", "frontend", "build"]
|
exclude_dir = [".air", "frontend", "build"]
|
||||||
exclude_file = []
|
exclude_file = []
|
||||||
|
51
server/metric/metric.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package metric
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/posthog/posthog-go"
|
||||||
|
|
||||||
|
"github.com/boojack/slash/server/profile"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PostHogAPIKey = "phc_YFEi1aqUBW9sX2KDzdvMtK43DNu0mkeoKMKc0EQum2t"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
client *MetricClient
|
||||||
|
)
|
||||||
|
|
||||||
|
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: `slash-` + client.workspaceID,
|
||||||
|
Event: event,
|
||||||
|
})
|
||||||
|
}
|
@ -18,6 +18,7 @@ import (
|
|||||||
apiv2 "github.com/boojack/slash/api/v2"
|
apiv2 "github.com/boojack/slash/api/v2"
|
||||||
"github.com/boojack/slash/internal/log"
|
"github.com/boojack/slash/internal/log"
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
|
"github.com/boojack/slash/server/metric"
|
||||||
"github.com/boojack/slash/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/slash/server/service/license"
|
"github.com/boojack/slash/server/service/license"
|
||||||
"github.com/boojack/slash/server/service/resource"
|
"github.com/boojack/slash/server/service/resource"
|
||||||
@ -29,6 +30,7 @@ type Server struct {
|
|||||||
|
|
||||||
Profile *profile.Profile
|
Profile *profile.Profile
|
||||||
Store *store.Store
|
Store *store.Store
|
||||||
|
Secret string
|
||||||
|
|
||||||
licenseService *license.LicenseService
|
licenseService *license.LicenseService
|
||||||
|
|
||||||
@ -93,11 +95,12 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
|
|||||||
secret := "slash"
|
secret := "slash"
|
||||||
if profile.Mode == "prod" {
|
if profile.Mode == "prod" {
|
||||||
var err error
|
var err error
|
||||||
secret, err = s.getSystemSecretSessionName(ctx)
|
secret, err = s.getSecretSessionName(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s.Secret = secret
|
||||||
|
|
||||||
rootGroup := e.Group("")
|
rootGroup := e.Group("")
|
||||||
// Register API v1 routes.
|
// Register API v1 routes.
|
||||||
@ -133,6 +136,7 @@ func (s *Server) Start(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
metric.Enqueue("server start")
|
||||||
return s.e.Start(fmt.Sprintf(":%d", s.Profile.Port))
|
return s.e.Start(fmt.Sprintf(":%d", s.Profile.Port))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +165,7 @@ func grpcRequestSkipper(c echo.Context) bool {
|
|||||||
return strings.HasPrefix(c.Request().URL.Path, "/slash.api.v2.")
|
return strings.HasPrefix(c.Request().URL.Path, "/slash.api.v2.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) getSystemSecretSessionName(ctx context.Context) (string, error) {
|
func (s *Server) getSecretSessionName(ctx context.Context) (string, error) {
|
||||||
secretSessionSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{
|
secretSessionSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{
|
||||||
Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_SECRET_SESSION,
|
Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_SECRET_SESSION,
|
||||||
})
|
})
|
||||||
|
@ -9,10 +9,10 @@ import (
|
|||||||
|
|
||||||
// Version is the service current released version.
|
// Version is the service current released version.
|
||||||
// Semantic versioning: https://semver.org/
|
// Semantic versioning: https://semver.org/
|
||||||
var Version = "0.4.5"
|
var Version = "0.4.6"
|
||||||
|
|
||||||
// DevVersion is the service current development version.
|
// DevVersion is the service current development version.
|
||||||
var DevVersion = "0.4.5"
|
var DevVersion = "0.4.6"
|
||||||
|
|
||||||
func GetCurrentVersion(mode string) string {
|
func GetCurrentVersion(mode string) string {
|
||||||
if mode == "dev" || mode == "demo" {
|
if mode == "dev" || mode == "demo" {
|
||||||
|