mirror of
https://github.com/aykhans/slash-e.git
synced 2025-07-06 21:22:36 +00:00
Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
09f7c33135 | |||
fe3b78f844 | |||
0fd54426e6 | |||
690e14e4ed | |||
7795b17fd1 | |||
c7dd4dc3eb | |||
6ee6a5166e | |||
8c753e9557 | |||
6126701025 | |||
8ef7d5f0d0 | |||
fa8d2f6639 | |||
8cd976791e | |||
010271c668 | |||
383d4f27f0 | |||
cb9786ef7c | |||
e936bb6f15 | |||
60c440ae10 | |||
fc8808ce04 | |||
e88327f2a3 | |||
159dfc9446 |
@ -36,15 +36,15 @@ func extractTokenFromHeader(c echo.Context) (string, error) {
|
||||
}
|
||||
|
||||
func findAccessToken(c echo.Context) string {
|
||||
accessToken := ""
|
||||
// Check the HTTP request header first.
|
||||
accessToken, _ := extractTokenFromHeader(c)
|
||||
if accessToken == "" {
|
||||
// Check the cookie.
|
||||
cookie, _ := c.Cookie(auth.AccessTokenCookieName)
|
||||
if cookie != nil {
|
||||
accessToken = cookie.Value
|
||||
}
|
||||
if accessToken == "" {
|
||||
accessToken, _ = extractTokenFromHeader(c)
|
||||
}
|
||||
|
||||
return accessToken
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ func (s *APIV1Service) registerRedirectorRoutes(g *echo.Group) {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to get shortcut, err: %s", err)).SetInternal(err)
|
||||
}
|
||||
if shortcut == nil {
|
||||
return echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("not found shortcut with name: %s", shortcutName))
|
||||
return c.Redirect(http.StatusSeeOther, fmt.Sprintf("/404?shortcut=%s", shortcutName))
|
||||
}
|
||||
if shortcut.Visibility != storepb.Visibility_PUBLIC {
|
||||
userID, ok := c.Get(userIDContextKey).(int32)
|
||||
|
@ -1,31 +0,0 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"go.deanishe.net/favicon"
|
||||
)
|
||||
|
||||
func (*APIV1Service) registerURLUtilRoutes(g *echo.Group) {
|
||||
// GET /url/favicon?url=...
|
||||
g.GET("/url/favicon", func(c echo.Context) error {
|
||||
url := c.QueryParam("url")
|
||||
icons, err := favicon.Find(url)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("failed to find favicon, err: %s", err))
|
||||
}
|
||||
|
||||
availableIcons := []*favicon.Icon{}
|
||||
for _, icon := range icons {
|
||||
if icon.Width == icon.Height {
|
||||
availableIcons = append(availableIcons, icon)
|
||||
}
|
||||
}
|
||||
if len(availableIcons) == 0 {
|
||||
return echo.NewHTTPError(http.StatusNotFound, "no favicon found")
|
||||
}
|
||||
return c.JSON(http.StatusOK, availableIcons[0].URL)
|
||||
})
|
||||
}
|
@ -27,7 +27,6 @@ func (s *APIV1Service) Start(apiGroup *echo.Group, secret string) {
|
||||
apiV1Group.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return JWTMiddleware(s, next, secret)
|
||||
})
|
||||
s.registerURLUtilRoutes(apiV1Group)
|
||||
s.registerWorkspaceRoutes(apiV1Group)
|
||||
s.registerAuthRoutes(apiV1Group, secret)
|
||||
s.registerUserRoutes(apiV1Group)
|
||||
|
@ -4,6 +4,7 @@ import "strings"
|
||||
|
||||
var allowedMethodsWhenUnauthorized = map[string]bool{
|
||||
"/slash.api.v2.WorkspaceService/GetWorkspaceProfile": true,
|
||||
"/slash.api.v2.WorkspaceService/GetWorkspaceSetting": true,
|
||||
}
|
||||
|
||||
// isUnauthorizeAllowedMethod returns true if the method is allowed to be called when the user is not authorized.
|
||||
|
@ -74,7 +74,9 @@ func (s *WorkspaceService) GetWorkspaceSetting(ctx context.Context, _ *apiv2pb.G
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to list workspace settings: %v", err)
|
||||
}
|
||||
workspaceSetting := &apiv2pb.WorkspaceSetting{}
|
||||
workspaceSetting := &apiv2pb.WorkspaceSetting{
|
||||
EnableSignup: true,
|
||||
}
|
||||
for _, v := range workspaceSettings {
|
||||
if v.Key == storepb.WorkspaceSettingKey_WORKSAPCE_SETTING_ENABLE_SIGNUP {
|
||||
workspaceSetting.EnableSignup = v.GetEnableSignup()
|
||||
@ -86,8 +88,6 @@ func (s *WorkspaceService) GetWorkspaceSetting(ctx context.Context, _ *apiv2pb.G
|
||||
// For some settings, only admin can get the value.
|
||||
if v.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_LICENSE_KEY {
|
||||
workspaceSetting.LicenseKey = v.GetLicenseKey()
|
||||
} else if v.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH {
|
||||
workspaceSetting.ResourceRelativePath = v.GetResourceRelativePath()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,15 +120,6 @@ func (s *WorkspaceService) UpdateWorkspaceSetting(ctx context.Context, request *
|
||||
}); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to update workspace setting: %v", err)
|
||||
}
|
||||
} else if path == "resource_relative_path" {
|
||||
if _, err := s.Store.UpsertWorkspaceSetting(ctx, &storepb.WorkspaceSetting{
|
||||
Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH,
|
||||
Value: &storepb.WorkspaceSetting_ResourceRelativePath{
|
||||
ResourceRelativePath: request.Setting.ResourceRelativePath,
|
||||
},
|
||||
}); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to update workspace setting: %v", err)
|
||||
}
|
||||
} else if path == "custom_style" {
|
||||
if !s.LicenseService.IsFeatureEnabled(license.FeatureTypeCustomeStyle) {
|
||||
return nil, status.Errorf(codes.PermissionDenied, "feature custom style is not available")
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "slash-extension",
|
||||
"displayName": "Slash",
|
||||
"version": "0.1.4",
|
||||
"version": "1.0.0",
|
||||
"description": "An open source, self-hosted bookmarks and link sharing platform. Save and share your links very easily.",
|
||||
"scripts": {
|
||||
"dev": "plasmo dev",
|
||||
@ -15,7 +15,7 @@
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@mui/joy": "5.0.0-beta.0",
|
||||
"@plasmohq/storage": "^1.8.0",
|
||||
"axios": "^1.5.0",
|
||||
"axios": "^1.5.1",
|
||||
"classnames": "^2.3.2",
|
||||
"lodash-es": "^4.17.21",
|
||||
"lucide-react": "^0.264.0",
|
||||
@ -32,15 +32,15 @@
|
||||
"@types/node": "20.4.2",
|
||||
"@types/react": "18.2.15",
|
||||
"@types/react-dom": "18.2.7",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.0",
|
||||
"@typescript-eslint/parser": "^6.7.0",
|
||||
"autoprefixer": "^10.4.15",
|
||||
"eslint": "^8.49.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
||||
"@typescript-eslint/parser": "^6.7.3",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"eslint": "^8.50.0",
|
||||
"eslint-config-prettier": "^8.10.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"long": "^5.2.3",
|
||||
"postcss": "^8.4.29",
|
||||
"postcss": "^8.4.31",
|
||||
"prettier": "2.6.2",
|
||||
"protobufjs": "^7.2.5",
|
||||
"tailwindcss": "^3.3.3",
|
||||
|
771
frontend/extension/pnpm-lock.yaml
generated
771
frontend/extension/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,7 @@
|
||||
import type { Shortcut } from "@/types/proto/api/v2/shortcut_service";
|
||||
import { useStorage } from "@plasmohq/storage/hook";
|
||||
import classNames from "classnames";
|
||||
import { useEffect, useState } from "react";
|
||||
import useFaviconStore from "../stores/favicon";
|
||||
import { getFaviconWithGoogleS2 } from "@/helpers/utils";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props {
|
||||
@ -11,17 +10,8 @@ interface Props {
|
||||
|
||||
const ShortcutView = (props: Props) => {
|
||||
const { shortcut } = props;
|
||||
const faviconStore = useFaviconStore();
|
||||
const [domain] = useStorage<string>("domain", "");
|
||||
const [favicon, setFavicon] = useState<string | undefined>(undefined);
|
||||
|
||||
useEffect(() => {
|
||||
faviconStore.getOrFetchUrlFavicon(shortcut.link).then((url) => {
|
||||
if (url) {
|
||||
setFavicon(url);
|
||||
}
|
||||
});
|
||||
}, [shortcut.link]);
|
||||
const favicon = getFaviconWithGoogleS2(shortcut.link);
|
||||
|
||||
const handleShortcutLinkClick = () => {
|
||||
const shortcutLink = `${domain}/s/${shortcut.name}`;
|
||||
@ -32,7 +22,7 @@ const ShortcutView = (props: Props) => {
|
||||
<>
|
||||
<div
|
||||
className={classNames(
|
||||
"group w-full px-3 py-2 flex flex-col justify-start items-start border rounded-lg hover:bg-gray-100 hover:shadow"
|
||||
"group w-full px-3 py-2 flex flex-col justify-start items-start border rounded-lg hover:bg-gray-100 hover:shadow dark:border-zinc-800 dark:hover:bg-zinc-800"
|
||||
)}
|
||||
>
|
||||
<div className="w-full flex flex-row justify-start items-center">
|
||||
@ -52,13 +42,13 @@ const ShortcutView = (props: Props) => {
|
||||
onClick={handleShortcutLinkClick}
|
||||
>
|
||||
<div className="truncate">
|
||||
<span>{shortcut.title}</span>
|
||||
<span className="dark:text-gray-400">{shortcut.title}</span>
|
||||
{shortcut.title ? (
|
||||
<span className="text-gray-400">(s/{shortcut.name})</span>
|
||||
<span className="text-gray-500">(s/{shortcut.name})</span>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-gray-400">s/</span>
|
||||
<span className="truncate">{shortcut.name}</span>
|
||||
<span className="text-gray-400 dark:text-gray-500">s/</span>
|
||||
<span className="truncate dark:text-gray-400">{shortcut.name}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
@ -1,14 +0,0 @@
|
||||
import { Storage } from "@plasmohq/storage";
|
||||
import axios from "axios";
|
||||
|
||||
const storage = new Storage();
|
||||
|
||||
export const getUrlFavicon = async (url: string) => {
|
||||
const domain = await storage.getItem<string>("domain");
|
||||
const accessToken = await storage.getItem<string>("access_token");
|
||||
return axios.get<string>(`${domain}/api/v1/url/favicon?url=${url}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
},
|
||||
});
|
||||
};
|
@ -3,3 +3,12 @@ import { isNull, isUndefined } from "lodash-es";
|
||||
export const isNullorUndefined = (value: any) => {
|
||||
return isNull(value) || isUndefined(value);
|
||||
};
|
||||
|
||||
export const getFaviconWithGoogleS2 = (url: string) => {
|
||||
try {
|
||||
const urlObject = new URL(url);
|
||||
return `https://www.google.com/s2/favicons?sz=128&domain=${urlObject.hostname}`;
|
||||
} catch (error) {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
43
frontend/extension/src/hooks/useColorTheme.ts
Normal file
43
frontend/extension/src/hooks/useColorTheme.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { useColorScheme } from "@mui/joy";
|
||||
import { useEffect } from "react";
|
||||
|
||||
const useColorTheme = () => {
|
||||
const { mode: colorTheme, setMode: setColorTheme } = useColorScheme();
|
||||
|
||||
useEffect(() => {
|
||||
const root = document.documentElement;
|
||||
if (colorTheme === "light") {
|
||||
root.classList.remove("dark");
|
||||
} else if (colorTheme === "dark") {
|
||||
root.classList.add("dark");
|
||||
} else {
|
||||
const darkMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
if (darkMediaQuery.matches) {
|
||||
root.classList.add("dark");
|
||||
} else {
|
||||
root.classList.remove("dark");
|
||||
}
|
||||
|
||||
const handleColorSchemeChange = (e: MediaQueryListEvent) => {
|
||||
if (e.matches) {
|
||||
root.classList.add("dark");
|
||||
} else {
|
||||
root.classList.remove("dark");
|
||||
}
|
||||
};
|
||||
try {
|
||||
darkMediaQuery.addEventListener("change", handleColorSchemeChange);
|
||||
} catch (error) {
|
||||
console.error("failed to initial color scheme listener", error);
|
||||
}
|
||||
|
||||
return () => {
|
||||
darkMediaQuery.removeEventListener("change", handleColorSchemeChange);
|
||||
};
|
||||
}
|
||||
}, [colorTheme]);
|
||||
|
||||
return { colorTheme, setColorTheme };
|
||||
};
|
||||
|
||||
export default useColorTheme;
|
@ -1,5 +1,5 @@
|
||||
import type { Shortcut } from "@/types/proto/api/v2/shortcut_service";
|
||||
import { Button, Divider, Input } from "@mui/joy";
|
||||
import { Button, CssVarsProvider, Divider, Input, Select, Option } from "@mui/joy";
|
||||
import { useStorage } from "@plasmohq/storage/hook";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Toaster, toast } from "react-hot-toast";
|
||||
@ -7,6 +7,7 @@ import Icon from "./components/Icon";
|
||||
import Logo from "./components/Logo";
|
||||
import PullShortcutsButton from "./components/PullShortcutsButton";
|
||||
import ShortcutsContainer from "./components/ShortcutsContainer";
|
||||
import useColorTheme from "./hooks/useColorTheme";
|
||||
import "./style.css";
|
||||
|
||||
interface SettingState {
|
||||
@ -14,7 +15,23 @@ interface SettingState {
|
||||
accessToken: string;
|
||||
}
|
||||
|
||||
const colorThemeOptions = [
|
||||
{
|
||||
value: "system",
|
||||
label: "System",
|
||||
},
|
||||
{
|
||||
value: "light",
|
||||
label: "Light",
|
||||
},
|
||||
{
|
||||
value: "dark",
|
||||
label: "Dark",
|
||||
},
|
||||
];
|
||||
|
||||
const IndexOptions = () => {
|
||||
const { colorTheme, setColorTheme } = useColorTheme();
|
||||
const [domain, setDomain] = useStorage<string>("domain", (v) => (v ? v : ""));
|
||||
const [accessToken, setAccessToken] = useStorage<string>("access_token", (v) => (v ? v : ""));
|
||||
const [settingState, setSettingState] = useState<SettingState>({
|
||||
@ -44,12 +61,15 @@ const IndexOptions = () => {
|
||||
toast.success("Setting saved");
|
||||
};
|
||||
|
||||
const handleSelectColorTheme = async (colorTheme: string) => {
|
||||
setColorTheme(colorTheme as any);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full">
|
||||
<div className="w-full flex flex-row justify-center items-center">
|
||||
<a
|
||||
className="bg-yellow-100 mt-12 py-2 px-3 rounded-full border flex flex-row justify-start items-center cursor-pointer shadow hover:underline hover:text-blue-600"
|
||||
className="bg-yellow-100 dark:bg-yellow-500 dark:opacity-70 mt-12 py-2 px-3 rounded-full border dark:border-yellow-600 flex flex-row justify-start items-center cursor-pointer shadow hover:underline hover:text-blue-600"
|
||||
href="https://github.com/boojack/slash#browser-extension"
|
||||
target="_blank"
|
||||
>
|
||||
@ -60,7 +80,7 @@ const IndexOptions = () => {
|
||||
</div>
|
||||
|
||||
<div className="w-full max-w-lg mx-auto flex flex-col justify-start items-start mt-12">
|
||||
<h2 className="flex flex-row justify-start items-center mb-6 text-2xl">
|
||||
<h2 className="flex flex-row justify-start items-center mb-6 text-2xl dark:text-gray-400">
|
||||
<Logo className="w-10 h-auto mr-2" />
|
||||
<span>Slash</span>
|
||||
<span className="mx-2 text-gray-400">/</span>
|
||||
@ -70,10 +90,10 @@ const IndexOptions = () => {
|
||||
<div className="w-full flex flex-col justify-start items-start">
|
||||
<div className="w-full flex flex-col justify-start items-start mb-4">
|
||||
<div className="mb-2 text-base w-full flex flex-row justify-between items-center">
|
||||
<span>Domain</span>
|
||||
<span className="dark:text-gray-400">Domain</span>
|
||||
{domain !== "" && (
|
||||
<a
|
||||
className="text-sm flex flex-row justify-start items-center hover:underline hover:text-blue-600"
|
||||
className="text-sm flex flex-row justify-start items-center dark:text-gray-400 hover:underline hover:text-blue-600"
|
||||
href={domain}
|
||||
target="_blank"
|
||||
>
|
||||
@ -94,7 +114,7 @@ const IndexOptions = () => {
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col justify-start items-start">
|
||||
<span className="mb-2 text-base">Access Token</span>
|
||||
<span className="mb-2 text-base dark:text-gray-400">Access Token</span>
|
||||
<div className="relative w-full">
|
||||
<Input
|
||||
className="w-full"
|
||||
@ -106,9 +126,28 @@ const IndexOptions = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full mt-6">
|
||||
<div className="w-full mt-6 flex flex-row justify-end">
|
||||
<Button onClick={handleSaveSetting}>Save</Button>
|
||||
</div>
|
||||
|
||||
<Divider className="!my-6" />
|
||||
|
||||
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">Preference</p>
|
||||
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<div className="flex flex-row justify-start items-center gap-x-1">
|
||||
<span className="dark:text-gray-400">Color Theme</span>
|
||||
</div>
|
||||
<Select defaultValue={colorTheme} onChange={(_, value) => handleSelectColorTheme(value)}>
|
||||
{colorThemeOptions.map((option) => {
|
||||
return (
|
||||
<Option key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isInitialized && (
|
||||
@ -116,7 +155,7 @@ const IndexOptions = () => {
|
||||
<Divider className="!my-6" />
|
||||
|
||||
<h2 className="flex flex-row justify-start items-center mb-4">
|
||||
<span className="text-lg">Shortcuts</span>
|
||||
<span className="text-lg dark:text-gray-400">Shortcuts</span>
|
||||
<span className="text-gray-500 mr-1">({shortcuts.length})</span>
|
||||
<PullShortcutsButton />
|
||||
</h2>
|
||||
@ -125,10 +164,16 @@ const IndexOptions = () => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Toaster position="top-center" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default IndexOptions;
|
||||
const Options = () => {
|
||||
return (
|
||||
<CssVarsProvider>
|
||||
<IndexOptions />
|
||||
<Toaster position="top-right" />
|
||||
</CssVarsProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default Options;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { Shortcut } from "@/types/proto/api/v2/shortcut_service";
|
||||
import { Button, Divider, IconButton } from "@mui/joy";
|
||||
import { Button, CssVarsProvider, Divider, IconButton } from "@mui/joy";
|
||||
import { useStorage } from "@plasmohq/storage/hook";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
import CreateShortcutsButton from "@/components/CreateShortcutsButton";
|
||||
@ -7,9 +7,11 @@ import Icon from "@/components/Icon";
|
||||
import Logo from "@/components/Logo";
|
||||
import PullShortcutsButton from "@/components/PullShortcutsButton";
|
||||
import ShortcutsContainer from "@/components/ShortcutsContainer";
|
||||
import useColorTheme from "./hooks/useColorTheme";
|
||||
import "./style.css";
|
||||
|
||||
const IndexPopup = () => {
|
||||
useColorTheme();
|
||||
const [domain] = useStorage<string>("domain", "");
|
||||
const [accessToken] = useStorage<string>("access_token", "");
|
||||
const [shortcuts] = useStorage<Shortcut[]>("shortcuts", []);
|
||||
@ -25,10 +27,9 @@ const IndexPopup = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full min-w-[512px] px-4 pt-4">
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<div className="flex flex-row justify-start items-center">
|
||||
<div className="flex flex-row justify-start items-center dark:text-gray-400">
|
||||
<Logo className="w-6 h-auto mr-2" />
|
||||
<span className="">Slash</span>
|
||||
{isInitialized && (
|
||||
@ -59,22 +60,15 @@ const IndexPopup = () => {
|
||||
<div className="w-full flex flex-row justify-between items-center mb-2">
|
||||
<div className="flex flex-row justify-start items-center">
|
||||
<IconButton size="sm" variant="plain" color="neutral" onClick={handleSettingButtonClick}>
|
||||
<Icon.Settings className="w-5 h-auto text-gray-500" />
|
||||
<Icon.Settings className="w-5 h-auto text-gray-500 dark:text-gray-400" />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
size="sm"
|
||||
variant="plain"
|
||||
color="neutral"
|
||||
component="a"
|
||||
href="https://github.com/boojack/slash"
|
||||
target="_blank"
|
||||
>
|
||||
<Icon.Github className="w-5 h-auto text-gray-500" />
|
||||
<IconButton size="sm" variant="plain" color="neutral" component="a" href="https://github.com/boojack/slash" target="_blank">
|
||||
<Icon.Github className="w-5 h-auto text-gray-500 dark:text-gray-400" />
|
||||
</IconButton>
|
||||
</div>
|
||||
<div className="flex flex-row justify-end items-center">
|
||||
<a
|
||||
className="text-sm flex flex-row justify-start items-center text-gray-500 hover:underline hover:text-blue-600"
|
||||
className="text-sm flex flex-row justify-start items-center text-gray-500 dark:text-gray-400 hover:underline hover:text-blue-600"
|
||||
href={domain}
|
||||
target="_blank"
|
||||
>
|
||||
@ -86,12 +80,13 @@ const IndexPopup = () => {
|
||||
</>
|
||||
) : (
|
||||
<div className="w-full flex flex-col justify-start items-center">
|
||||
<p>No domain and access token found.</p>
|
||||
<Icon.Cookie strokeWidth={1} className="w-20 h-auto mb-4 text-gray-400" />
|
||||
<p className="dark:text-gray-400">Please set your domain and access token first.</p>
|
||||
<div className="w-full flex flex-row justify-center items-center py-4">
|
||||
<Button size="sm" color="primary" onClick={handleSettingButtonClick}>
|
||||
<Icon.Settings className="w-5 h-auto mr-1" /> Setting
|
||||
</Button>
|
||||
<span className="mx-2">Or</span>
|
||||
<span className="mx-2 dark:text-gray-400">Or</span>
|
||||
<Button size="sm" variant="outlined" color="neutral" onClick={handleRefreshButtonClick}>
|
||||
<Icon.RefreshCcw className="w-5 h-auto mr-1" /> Refresh
|
||||
</Button>
|
||||
@ -100,10 +95,16 @@ const IndexPopup = () => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Toaster position="top-right" />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default IndexPopup;
|
||||
const Popup = () => {
|
||||
return (
|
||||
<CssVarsProvider>
|
||||
<IndexPopup />
|
||||
<Toaster position="top-right" />
|
||||
</CssVarsProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default Popup;
|
||||
|
@ -1,41 +0,0 @@
|
||||
import { create } from "zustand";
|
||||
import { persist } from "zustand/middleware";
|
||||
import { getUrlFavicon } from "../helpers/api";
|
||||
|
||||
interface FaviconState {
|
||||
cache: {
|
||||
[key: string]: string;
|
||||
};
|
||||
getOrFetchUrlFavicon: (url: string) => Promise<string>;
|
||||
}
|
||||
|
||||
const useFaviconStore = create<FaviconState>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
cache: {},
|
||||
getOrFetchUrlFavicon: async (url: string) => {
|
||||
const cache = get().cache;
|
||||
if (cache[url]) {
|
||||
return cache[url];
|
||||
}
|
||||
|
||||
try {
|
||||
const { data: favicon } = await getUrlFavicon(url);
|
||||
if (favicon) {
|
||||
cache[url] = favicon;
|
||||
set(cache);
|
||||
return favicon;
|
||||
}
|
||||
} catch (error) {
|
||||
// do nothing
|
||||
}
|
||||
return "";
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: "favicon_cache",
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
export default useFaviconStore;
|
@ -5,7 +5,7 @@
|
||||
body,
|
||||
html,
|
||||
#root {
|
||||
@apply text-base;
|
||||
@apply text-base dark:bg-zinc-900;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Noto Sans", "Noto Sans CJK SC", "Microsoft YaHei UI", "Microsoft YaHei",
|
||||
"WenQuanYi Micro Hei", sans-serif, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
||||
"Noto Color Emoji";
|
||||
|
@ -11,7 +11,14 @@
|
||||
"language": "Language",
|
||||
"search": "Search",
|
||||
"email": "Email",
|
||||
"password": "Password"
|
||||
"password": "Password",
|
||||
"account": "Account"
|
||||
},
|
||||
"auth": {
|
||||
"sign-in": "Sign in",
|
||||
"sign-up": "Sign up",
|
||||
"sign-out": "Sign out",
|
||||
"create-your-account": "Create your account"
|
||||
},
|
||||
"analytics": {
|
||||
"self": "Analytics",
|
||||
@ -24,6 +31,7 @@
|
||||
"operating-system": "Operating System"
|
||||
},
|
||||
"shortcut": {
|
||||
"visits": "{{count}} visits",
|
||||
"visibility": {
|
||||
"private": {
|
||||
"self": "Private",
|
||||
@ -38,5 +46,37 @@
|
||||
"description": "Visible to everyone on the internet"
|
||||
}
|
||||
}
|
||||
},
|
||||
"filter": {
|
||||
"all": "All",
|
||||
"mine": "Mine",
|
||||
"compact-mode": "Compact mode",
|
||||
"order-by": "Order by",
|
||||
"direction": "Direction"
|
||||
},
|
||||
"user": {
|
||||
"self": "User",
|
||||
"nickname": "Nickname",
|
||||
"email": "Email",
|
||||
"role": "Role",
|
||||
"profile": "Profile",
|
||||
"action": {
|
||||
"add-user": "Add user"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"self": "Setting",
|
||||
"preference": {
|
||||
"self": "Preference",
|
||||
"color-theme": "Color theme"
|
||||
},
|
||||
"workspace": {
|
||||
"self": "Workspace settings",
|
||||
"custom-style": "Custom style",
|
||||
"enable-user-signup": {
|
||||
"self": "Enable user signup",
|
||||
"description": "Once enabled, other users can signup."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,14 @@
|
||||
"language": "语言",
|
||||
"search": "搜索",
|
||||
"email": "邮箱",
|
||||
"password": "密码"
|
||||
"password": "密码",
|
||||
"account": "账号"
|
||||
},
|
||||
"auth": {
|
||||
"sign-in": "登录",
|
||||
"sign-up": "注册",
|
||||
"sign-out": "退出登录",
|
||||
"create-your-account": "创建账号"
|
||||
},
|
||||
"analytics": {
|
||||
"self": "分析",
|
||||
@ -24,6 +31,7 @@
|
||||
"operating-system": "操作系统"
|
||||
},
|
||||
"shortcut": {
|
||||
"visits": "{{count}} 次访问",
|
||||
"visibility": {
|
||||
"private": {
|
||||
"self": "私有的",
|
||||
@ -38,5 +46,37 @@
|
||||
"description": "对任何人可见"
|
||||
}
|
||||
}
|
||||
},
|
||||
"filter": {
|
||||
"all": "所有",
|
||||
"mine": "我的",
|
||||
"compact-mode": "紧凑模式",
|
||||
"order-by": "排序方式",
|
||||
"direction": "方向"
|
||||
},
|
||||
"user": {
|
||||
"self": "用户",
|
||||
"nickname": "昵称",
|
||||
"email": "邮箱",
|
||||
"role": "角色",
|
||||
"profile": "账号",
|
||||
"action": {
|
||||
"add-user": "添加用户"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"self": "设置",
|
||||
"preference": {
|
||||
"self": "偏好设置",
|
||||
"color-theme": "主题"
|
||||
},
|
||||
"workspace": {
|
||||
"self": "系统设置",
|
||||
"custom-style": "自定义样式",
|
||||
"enable-user-signup": {
|
||||
"self": "启用用户注册",
|
||||
"description": "允许其他用户注册新账号"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@mui/joy": "5.0.0-beta.7",
|
||||
"@reduxjs/toolkit": "^1.9.5",
|
||||
"@reduxjs/toolkit": "^1.9.6",
|
||||
"axios": "^0.27.2",
|
||||
"classnames": "^2.3.2",
|
||||
"copy-to-clipboard": "^3.3.3",
|
||||
@ -34,18 +34,18 @@
|
||||
"devDependencies": {
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
|
||||
"@types/lodash-es": "^4.17.9",
|
||||
"@types/react": "^18.2.22",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.2",
|
||||
"@typescript-eslint/parser": "^6.7.2",
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"@types/react": "^18.2.23",
|
||||
"@types/react-dom": "^18.2.8",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
||||
"@typescript-eslint/parser": "^6.7.3",
|
||||
"@vitejs/plugin-react-swc": "^3.4.0",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"eslint": "^8.50.0",
|
||||
"eslint-config-prettier": "^8.10.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"long": "^5.2.3",
|
||||
"postcss": "^8.4.30",
|
||||
"postcss": "^8.4.31",
|
||||
"prettier": "2.6.2",
|
||||
"protobufjs": "^7.2.5",
|
||||
"typescript": "^5.2.2",
|
||||
|
463
frontend/web/pnpm-lock.yaml
generated
463
frontend/web/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,15 +1,17 @@
|
||||
import { Button, Divider, Input, Modal, ModalDialog, Radio, RadioGroup, Textarea } from "@mui/joy";
|
||||
import classnames from "classnames";
|
||||
import { isUndefined } from "lodash-es";
|
||||
import { isUndefined, uniq } from "lodash-es";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAppSelector } from "@/stores";
|
||||
import useLoading from "../hooks/useLoading";
|
||||
import { shortcutService } from "../services";
|
||||
import Icon from "./Icon";
|
||||
|
||||
interface Props {
|
||||
shortcutId?: ShortcutId;
|
||||
initialShortcut?: Partial<Shortcut>;
|
||||
onClose: () => void;
|
||||
onConfirm?: () => void;
|
||||
}
|
||||
@ -21,8 +23,9 @@ interface State {
|
||||
const visibilities: Visibility[] = ["PRIVATE", "WORKSPACE", "PUBLIC"];
|
||||
|
||||
const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
||||
const { onClose, onConfirm, shortcutId } = props;
|
||||
const { onClose, onConfirm, shortcutId, initialShortcut } = props;
|
||||
const { t } = useTranslation();
|
||||
const { shortcutList } = useAppSelector((state) => state.shortcut);
|
||||
const [state, setState] = useState<State>({
|
||||
shortcutCreate: {
|
||||
name: "",
|
||||
@ -36,11 +39,13 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
||||
description: "",
|
||||
image: "",
|
||||
},
|
||||
...initialShortcut,
|
||||
},
|
||||
});
|
||||
const [showAdditionalFields, setShowAdditionalFields] = useState<boolean>(false);
|
||||
const [showOpenGraphMetadata, setShowOpenGraphMetadata] = useState<boolean>(false);
|
||||
const [tag, setTag] = useState<string>("");
|
||||
const tagSuggestions = uniq(shortcutList.map((shortcut) => shortcut.tags).flat());
|
||||
const requestState = useLoading(false);
|
||||
const isCreating = isUndefined(shortcutId);
|
||||
|
||||
@ -149,6 +154,14 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
||||
});
|
||||
};
|
||||
|
||||
const handleTagSuggestionsClick = (suggestion: string) => {
|
||||
if (tag === "") {
|
||||
setTag(suggestion);
|
||||
} else {
|
||||
setTag(`${tag} ${suggestion}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSaveBtnClick = async () => {
|
||||
if (!state.shortcutCreate.name) {
|
||||
toast.error("Name is required");
|
||||
@ -220,6 +233,22 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||
<span className="mb-2">Tags</span>
|
||||
<Input className="w-full" type="text" placeholder="github slash" value={tag} onChange={handleTagsInputChange} />
|
||||
{tagSuggestions.length > 0 && (
|
||||
<div className="w-full flex flex-row justify-start items-start mt-2">
|
||||
<Icon.Asterisk className="w-4 h-auto shrink-0 mx-1 text-gray-400 dark:text-gray-600" />
|
||||
<div className="w-auto flex flex-row justify-start items-start flex-wrap gap-x-2 gap-y-1">
|
||||
{tagSuggestions.map((tag) => (
|
||||
<span
|
||||
className="text-gray-600 dark:text-gray-500 cursor-pointer max-w-[6rem] truncate block text-sm flex-nowrap leading-4 hover:text-black dark:hover:text-gray-400"
|
||||
key={tag}
|
||||
onClick={() => handleTagSuggestionsClick(tag)}
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||
<span className="mb-2">Visibility</span>
|
||||
@ -283,10 +312,7 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
||||
)}
|
||||
onClick={() => setShowOpenGraphMetadata(!showOpenGraphMetadata)}
|
||||
>
|
||||
<span className="text-sm flex flex-row justify-start items-center">
|
||||
Social media metadata
|
||||
<Icon.Sparkles className="ml-1 w-4 h-auto text-blue-600" />
|
||||
</span>
|
||||
<span className="text-sm flex flex-row justify-start items-center">Social media metadata</span>
|
||||
<button className="w-7 h-7 p-1 rounded-md">
|
||||
<Icon.ChevronDown className={classnames("w-4 h-auto text-gray-500", showOpenGraphMetadata ? "transform rotate-180" : "")} />
|
||||
</button>
|
||||
|
@ -66,11 +66,11 @@ const EditUserinfoDialog: React.FC<Props> = (props: Props) => {
|
||||
</div>
|
||||
<div>
|
||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||
<span className="mb-2">Email</span>
|
||||
<span className="mb-2">{t("common.email")}</span>
|
||||
<Input className="w-full" type="text" value={email} onChange={handleEmailChanged} />
|
||||
</div>
|
||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||
<span className="mb-2">Nickname</span>
|
||||
<span className="mb-2">{t("user.nickname")}</span>
|
||||
<Input className="w-full" type="text" value={nickname} onChange={handleNicknameChanged} />
|
||||
</div>
|
||||
<div className="w-full flex flex-row justify-end items-center space-x-2">
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Avatar } from "@mui/joy";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
import useWorkspaceStore from "@/stores/v1/workspace";
|
||||
import { PlanType } from "@/types/proto/api/v2/subscription_service";
|
||||
@ -10,6 +11,7 @@ import Icon from "./Icon";
|
||||
import Dropdown from "./common/Dropdown";
|
||||
|
||||
const Header: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const workspaceStore = useWorkspaceStore();
|
||||
const currentUser = useUserStore().getCurrentUser();
|
||||
const [showAboutDialog, setShowAboutDialog] = useState<boolean>(false);
|
||||
@ -52,27 +54,27 @@ const Header: React.FC = () => {
|
||||
to="/setting/general"
|
||||
className="w-full px-2 flex flex-row justify-start items-center text-left dark:text-gray-400 leading-8 cursor-pointer rounded hover:bg-gray-100 dark:hover:bg-zinc-800 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
|
||||
>
|
||||
<Icon.User className="w-4 h-auto mr-2" /> Profile
|
||||
<Icon.User className="w-4 h-auto mr-2" /> {t("user.profile")}
|
||||
</Link>
|
||||
{isAdmin && (
|
||||
<Link
|
||||
to="/setting/workspace"
|
||||
className="w-full px-2 flex flex-row justify-start items-center text-left dark:text-gray-400 leading-8 cursor-pointer rounded hover:bg-gray-100 dark:hover:bg-zinc-800 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
|
||||
>
|
||||
<Icon.Settings className="w-4 h-auto mr-2" /> Setting
|
||||
<Icon.Settings className="w-4 h-auto mr-2" /> {t("settings.self")}
|
||||
</Link>
|
||||
)}
|
||||
<button
|
||||
className="w-full px-2 flex flex-row justify-start items-center text-left dark:text-gray-400 leading-8 cursor-pointer rounded hover:bg-gray-100 dark:hover:bg-zinc-800 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
|
||||
onClick={() => setShowAboutDialog(true)}
|
||||
>
|
||||
<Icon.Info className="w-4 h-auto mr-2" /> About
|
||||
<Icon.Info className="w-4 h-auto mr-2" /> {t("common.about")}
|
||||
</button>
|
||||
<button
|
||||
className="w-full px-2 flex flex-row justify-start items-center text-left dark:text-gray-400 leading-8 cursor-pointer rounded hover:bg-gray-100 dark:hover:bg-zinc-800 disabled:cursor-not-allowed disabled:bg-gray-100 disabled:opacity-60"
|
||||
onClick={() => handleSignOutButtonClick()}
|
||||
>
|
||||
<Icon.LogOut className="w-4 h-auto mr-2" /> Sign out
|
||||
<Icon.LogOut className="w-4 h-auto mr-2" /> {t("auth.sign-out")}
|
||||
</button>
|
||||
</>
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
import classNames from "classnames";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAppSelector } from "../stores";
|
||||
import useViewStore from "../stores/v1/view";
|
||||
import Icon from "./Icon";
|
||||
|
||||
const Navigator = () => {
|
||||
const { t } = useTranslation();
|
||||
const viewStore = useViewStore();
|
||||
const { shortcutList } = useAppSelector((state) => state.shortcut);
|
||||
const tags = shortcutList.map((shortcut) => shortcut.tags).flat();
|
||||
@ -22,7 +24,7 @@ const Navigator = () => {
|
||||
onClick={() => viewStore.setFilter({ tab: "tab:all" })}
|
||||
>
|
||||
<Icon.CircleSlash className="w-4 h-auto mr-1" />
|
||||
<span className="font-normal">All</span>
|
||||
<span className="font-normal">{t("filter.all")}</span>
|
||||
</button>
|
||||
<button
|
||||
className={classNames(
|
||||
@ -34,7 +36,7 @@ const Navigator = () => {
|
||||
onClick={() => viewStore.setFilter({ tab: "tab:mine" })}
|
||||
>
|
||||
<Icon.User className="w-4 h-auto mr-1" />
|
||||
<span className="font-normal">Mine</span>
|
||||
<span className="font-normal">{t("filter.mine")}</span>
|
||||
</button>
|
||||
{Array.from(sortedTagMap.keys()).map((tag) => (
|
||||
<button
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import { shortcutService } from "../services";
|
||||
import useUserStore from "../stores/v1/user";
|
||||
import { showCommonDialog } from "./Alert";
|
||||
@ -16,7 +16,7 @@ interface Props {
|
||||
const ShortcutActionsDropdown = (props: Props) => {
|
||||
const { shortcut } = props;
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const navigateTo = useNavigateTo();
|
||||
const currentUser = useUserStore().getCurrentUser();
|
||||
const [showEditDialog, setShowEditDialog] = useState<boolean>(false);
|
||||
const [showQRCodeDialog, setShowQRCodeDialog] = useState<boolean>(false);
|
||||
@ -34,7 +34,7 @@ const ShortcutActionsDropdown = (props: Props) => {
|
||||
};
|
||||
|
||||
const gotoAnalytics = () => {
|
||||
navigate(`/shortcut/${shortcut.id}#analytics`);
|
||||
navigateTo(`/shortcut/${shortcut.id}#analytics`);
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -1,12 +1,10 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import classNames from "classnames";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { useEffect, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
import { absolutifyLink } from "../helpers/utils";
|
||||
import useFaviconStore from "../stores/v1/favicon";
|
||||
import { absolutifyLink, getFaviconWithGoogleS2 } from "../helpers/utils";
|
||||
import useViewStore from "../stores/v1/view";
|
||||
import Icon from "./Icon";
|
||||
import ShortcutActionsDropdown from "./ShortcutActionsDropdown";
|
||||
@ -20,17 +18,8 @@ const ShortcutView = (props: Props) => {
|
||||
const { shortcut } = props;
|
||||
const { t } = useTranslation();
|
||||
const viewStore = useViewStore();
|
||||
const faviconStore = useFaviconStore();
|
||||
const [favicon, setFavicon] = useState<string | undefined>(undefined);
|
||||
const shortcutLink = absolutifyLink(`/s/${shortcut.name}`);
|
||||
|
||||
useEffect(() => {
|
||||
faviconStore.getOrFetchUrlFavicon(shortcut.link).then((url) => {
|
||||
if (url) {
|
||||
setFavicon(url);
|
||||
}
|
||||
});
|
||||
}, [shortcut.link]);
|
||||
const favicon = getFaviconWithGoogleS2(shortcut.link);
|
||||
|
||||
const handleCopyButtonClick = () => {
|
||||
copy(shortcutLink);
|
||||
@ -63,9 +52,9 @@ const ShortcutView = (props: Props) => {
|
||||
href={shortcutLink}
|
||||
>
|
||||
<div className="truncate">
|
||||
<span>{shortcut.title}</span>
|
||||
<span className="dark:text-gray-400">{shortcut.title}</span>
|
||||
{shortcut.title ? (
|
||||
<span className="text-gray-400">(s/{shortcut.name})</span>
|
||||
<span className="text-gray-500">(s/{shortcut.name})</span>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-gray-400 dark:text-gray-500">s/</span>
|
||||
@ -113,16 +102,16 @@ const ShortcutView = (props: Props) => {
|
||||
})}
|
||||
{shortcut.tags.length === 0 && <span className="text-gray-400 text-sm font-mono leading-4 italic">No tags</span>}
|
||||
</div>
|
||||
<div className="w-full flex mt-2 gap-2">
|
||||
<div className="w-full flex mt-2 gap-2 overflow-x-auto">
|
||||
<Tooltip title="Creator" variant="solid" placement="top" arrow>
|
||||
<div className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full text-gray-500 text-sm dark:border-zinc-800">
|
||||
<div className="w-auto px-2 leading-6 flex flex-row justify-start items-center flex-nowra whitespace-nowrap border rounded-full text-gray-500 text-sm dark:border-zinc-800">
|
||||
<Icon.User className="w-4 h-auto mr-1" />
|
||||
<span className="max-w-[4rem] sm:max-w-[6rem] truncate">{shortcut.creator.nickname}</span>
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title={t(`shortcut.visibility.${shortcut.visibility.toLowerCase()}.description`)} variant="solid" placement="top" arrow>
|
||||
<div
|
||||
className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full cursor-pointer text-gray-500 text-sm dark:border-zinc-800"
|
||||
className="w-auto px-2 leading-6 flex flex-row justify-start items-center flex-nowrap whitespace-nowrap border rounded-full cursor-pointer text-gray-500 text-sm dark:border-zinc-800"
|
||||
onClick={() => viewStore.setFilter({ visibility: shortcut.visibility })}
|
||||
>
|
||||
<VisibilityIcon className="w-4 h-auto mr-1" visibility={shortcut.visibility} />
|
||||
@ -132,10 +121,10 @@ const ShortcutView = (props: Props) => {
|
||||
<Tooltip title="View count" variant="solid" placement="top" arrow>
|
||||
<Link
|
||||
to={`/shortcut/${shortcut.id}#analytics`}
|
||||
className="w-auto px-2 leading-6 flex flex-row justify-start items-center border rounded-full cursor-pointer text-gray-500 text-sm dark:border-zinc-800"
|
||||
className="w-auto px-2 leading-6 flex flex-row justify-start items-center flex-nowrap whitespace-nowrap border rounded-full cursor-pointer text-gray-500 text-sm dark:border-zinc-800"
|
||||
>
|
||||
<Icon.BarChart2 className="w-4 h-auto mr-1" />
|
||||
{shortcut.view} visits
|
||||
{t("shortcut.visits", { count: shortcut.view })}
|
||||
</Link>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
@ -1,8 +1,6 @@
|
||||
import classNames from "classnames";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { absolutifyLink } from "../helpers/utils";
|
||||
import useFaviconStore from "../stores/v1/favicon";
|
||||
import { absolutifyLink, getFaviconWithGoogleS2 } from "../helpers/utils";
|
||||
import Icon from "./Icon";
|
||||
import ShortcutActionsDropdown from "./ShortcutActionsDropdown";
|
||||
|
||||
@ -12,17 +10,8 @@ interface Props {
|
||||
|
||||
const ShortcutView = (props: Props) => {
|
||||
const { shortcut } = props;
|
||||
const faviconStore = useFaviconStore();
|
||||
const [favicon, setFavicon] = useState<string | undefined>(undefined);
|
||||
const shortcutLink = absolutifyLink(`/s/${shortcut.name}`);
|
||||
|
||||
useEffect(() => {
|
||||
faviconStore.getOrFetchUrlFavicon(shortcut.link).then((url) => {
|
||||
if (url) {
|
||||
setFavicon(url);
|
||||
}
|
||||
});
|
||||
}, [shortcut.link]);
|
||||
const favicon = getFaviconWithGoogleS2(shortcut.link);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -50,9 +39,9 @@ const ShortcutView = (props: Props) => {
|
||||
target="_blank"
|
||||
>
|
||||
<div className="truncate">
|
||||
<span>{shortcut.title}</span>
|
||||
<span className="dark:text-gray-400">{shortcut.title}</span>
|
||||
{shortcut.title ? (
|
||||
<span className="text-gray-400">(s/{shortcut.name})</span>
|
||||
<span className="text-gray-500">(s/{shortcut.name})</span>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-gray-400 dark:text-gray-500">s/</span>
|
||||
|
@ -16,8 +16,8 @@ const ShortcutsContainer: React.FC<Props> = (props: Props) => {
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
"w-full grid grid-cols-1 gap-y-2 sm:gap-2",
|
||||
displayStyle === "full" ? "sm:grid-cols-2" : "grid-cols-2 sm:grid-cols-4 gap-2"
|
||||
"w-full grid grid-cols-1 gap-3 sm:gap-4",
|
||||
displayStyle === "full" ? "sm:grid-cols-2 lg:grid-cols-3" : "grid-cols-2 sm:grid-cols-4"
|
||||
)}
|
||||
>
|
||||
{shortcutList.map((shortcut) => {
|
||||
|
@ -1,9 +1,11 @@
|
||||
import { Divider, Option, Select, Switch } from "@mui/joy";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import useViewStore from "../stores/v1/view";
|
||||
import Icon from "./Icon";
|
||||
import Dropdown from "./common/Dropdown";
|
||||
|
||||
const ViewSetting = () => {
|
||||
const { t } = useTranslation();
|
||||
const viewStore = useViewStore();
|
||||
const order = viewStore.getOrder();
|
||||
const { field, direction } = order;
|
||||
@ -20,7 +22,7 @@ const ViewSetting = () => {
|
||||
actions={
|
||||
<div className="w-52 p-2 gap-2 flex flex-col justify-start items-start" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span className="text-sm shrink-0 mr-2">Compact mode</span>
|
||||
<span className="text-sm shrink-0 mr-2">{t("filter.compact-mode")}</span>
|
||||
<Switch
|
||||
size="sm"
|
||||
checked={displayStyle === "compact"}
|
||||
@ -29,7 +31,7 @@ const ViewSetting = () => {
|
||||
</div>
|
||||
<Divider className="!my-1" />
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span className="text-sm shrink-0 mr-2">Order by</span>
|
||||
<span className="text-sm shrink-0 mr-2">{t("filter.order-by")}</span>
|
||||
<Select size="sm" value={field} onChange={(_, value) => viewStore.setOrder({ field: value as any })}>
|
||||
<Option value={"name"}>Name</Option>
|
||||
<Option value={"updatedTs"}>CreatedAt</Option>
|
||||
@ -38,7 +40,7 @@ const ViewSetting = () => {
|
||||
</Select>
|
||||
</div>
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span className="text-sm shrink-0 mr-2">Direction</span>
|
||||
<span className="text-sm shrink-0 mr-2">{t("filter.direction")}</span>
|
||||
<Select size="sm" value={direction} onChange={(_, value) => viewStore.setOrder({ direction: value as any })}>
|
||||
<Option value={"asc"}>ASC</Option>
|
||||
<Option value={"desc"}>DESC</Option>
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { ReactNode, useEffect, useRef } from "react";
|
||||
import useToggle from "../../hooks/useToggle";
|
||||
import { ReactNode, useEffect, useRef, useState } from "react";
|
||||
import Icon from "../Icon";
|
||||
|
||||
interface Props {
|
||||
@ -11,14 +10,14 @@ interface Props {
|
||||
|
||||
const Dropdown: React.FC<Props> = (props: Props) => {
|
||||
const { trigger, actions, className, actionsClassName } = props;
|
||||
const [dropdownStatus, toggleDropdownStatus] = useToggle(false);
|
||||
const [dropdownStatus, setDropdownStatus] = useState(false);
|
||||
const dropdownWrapperRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (dropdownStatus) {
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
if (!dropdownWrapperRef.current?.contains(event.target as Node)) {
|
||||
toggleDropdownStatus(false);
|
||||
setDropdownStatus(false);
|
||||
}
|
||||
};
|
||||
|
||||
@ -35,7 +34,7 @@ const Dropdown: React.FC<Props> = (props: Props) => {
|
||||
|
||||
const handleToggleDropdownStatus = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
e.stopPropagation();
|
||||
toggleDropdownStatus();
|
||||
setDropdownStatus(!dropdownStatus);
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -15,7 +15,7 @@ const AccountSection: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="w-full flex flex-col justify-start items-start gap-y-2">
|
||||
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">Account</p>
|
||||
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">{t("common.account")}</p>
|
||||
<p className="flex flex-row justify-start items-center mt-2 dark:text-gray-400">
|
||||
<span className="text-xl">{currentUser.nickname}</span>
|
||||
{isAdmin && <span className="ml-2 bg-blue-600 text-white px-2 leading-6 text-sm rounded-full">Admin</span>}
|
||||
|
@ -1,12 +1,14 @@
|
||||
import { Button, IconButton } from "@mui/joy";
|
||||
import { useEffect, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import useUserStore from "../../stores/v1/user";
|
||||
import { showCommonDialog } from "../Alert";
|
||||
import CreateUserDialog from "../CreateUserDialog";
|
||||
import Icon from "../Icon";
|
||||
|
||||
const MemberSection = () => {
|
||||
const { t } = useTranslation();
|
||||
const userStore = useUserStore();
|
||||
const [showCreateUserDialog, setShowCreateUserDialog] = useState<boolean>(false);
|
||||
const [currentEditingUser, setCurrentEditingUser] = useState<User | undefined>(undefined);
|
||||
@ -43,7 +45,7 @@ const MemberSection = () => {
|
||||
<div className="w-full">
|
||||
<div className="sm:flex sm:items-center">
|
||||
<div className="sm:flex-auto">
|
||||
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">Users</p>
|
||||
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">{t("user.self")}</p>
|
||||
<p className="mt-2 text-sm text-gray-700 dark:text-gray-600">
|
||||
A list of all the users in your workspace including their nickname, email and role.
|
||||
</p>
|
||||
@ -57,7 +59,7 @@ const MemberSection = () => {
|
||||
setCurrentEditingUser(undefined);
|
||||
}}
|
||||
>
|
||||
Add user
|
||||
{t("user.action.add-user")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@ -68,20 +70,20 @@ const MemberSection = () => {
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-500">
|
||||
Nickname
|
||||
{t("user.nickname")}
|
||||
</th>
|
||||
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-500">
|
||||
Email
|
||||
{t("user.email")}
|
||||
</th>
|
||||
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 dark:text-gray-500">
|
||||
Role
|
||||
{t("user.role")}
|
||||
</th>
|
||||
<th scope="col" className="relative py-3.5 pl-3 pr-4">
|
||||
<span className="sr-only">Edit</span>
|
||||
<span className="sr-only">{t("common.edit")}</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200">
|
||||
<tbody className="divide-y divide-gray-200 dark:divide-zinc-800">
|
||||
{userList.map((user) => (
|
||||
<tr key={user.email}>
|
||||
<td className="whitespace-nowrap py-4 pl-4 pr-3 text-sm text-gray-900 dark:text-gray-500">{user.nickname}</td>
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Option, Select } from "@mui/joy";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { releaseGuard } from "@/helpers/utils";
|
||||
import { UserSetting, UserSetting_ColorTheme, UserSetting_Locale } from "@/types/proto/api/v2/user_setting_service";
|
||||
import useUserStore from "../../stores/v1/user";
|
||||
import BetaBadge from "../BetaBadge";
|
||||
@ -61,10 +60,10 @@ const PreferenceSection: React.FC = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="w-full flex flex-col justify-start items-start gap-y-2">
|
||||
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">Preference</p>
|
||||
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">{t("settings.preference.self")}</p>
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<div className="flex flex-row justify-start items-center gap-x-1">
|
||||
<span className="dark:text-gray-400">Color Theme</span>
|
||||
<span className="dark:text-gray-400">{t("settings.preference.color-theme")}</span>
|
||||
</div>
|
||||
<Select defaultValue={colorTheme} onChange={(_, value) => handleSelectColorTheme(value as UserSetting_ColorTheme)}>
|
||||
{colorThemeOptions.map((option) => {
|
||||
@ -76,7 +75,6 @@ const PreferenceSection: React.FC = () => {
|
||||
})}
|
||||
</Select>
|
||||
</div>
|
||||
{releaseGuard() && (
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<div className="flex flex-row justify-start items-center gap-x-1">
|
||||
<span className="dark:text-gray-400">{t("common.language")}</span>
|
||||
@ -92,7 +90,6 @@ const PreferenceSection: React.FC = () => {
|
||||
})}
|
||||
</Select>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
@ -2,11 +2,13 @@ import { Button, Checkbox, Textarea } from "@mui/joy";
|
||||
import { isEqual } from "lodash-es";
|
||||
import { useRef, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { workspaceServiceClient } from "@/grpcweb";
|
||||
import useWorkspaceStore from "@/stores/v1/workspace";
|
||||
import { WorkspaceSetting } from "@/types/proto/api/v2/workspace_service";
|
||||
|
||||
const WorkspaceSection: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const workspaceStore = useWorkspaceStore();
|
||||
const [workspaceSetting, setWorkspaceSetting] = useState<WorkspaceSetting>(workspaceStore.setting);
|
||||
const originalWorkspaceSetting = useRef<WorkspaceSetting>(workspaceStore.setting);
|
||||
@ -56,9 +58,9 @@ const WorkspaceSection: React.FC = () => {
|
||||
|
||||
return (
|
||||
<div className="w-full flex flex-col justify-start items-start space-y-4">
|
||||
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">Workspace settings</p>
|
||||
<p className="text-base font-semibold leading-6 text-gray-900 dark:text-gray-500">{t("settings.workspace.self")}</p>
|
||||
<div className="w-full flex flex-col justify-start items-start">
|
||||
<p className="mt-2 dark:text-gray-400">Custom style</p>
|
||||
<p className="mt-2 dark:text-gray-400">{t("settings.workspace.custom-style")}</p>
|
||||
<Textarea
|
||||
className="w-full mt-2"
|
||||
minRows={2}
|
||||
@ -69,15 +71,15 @@ const WorkspaceSection: React.FC = () => {
|
||||
</div>
|
||||
<div className="w-full flex flex-col justify-start items-start">
|
||||
<Checkbox
|
||||
label="Enable user signup"
|
||||
label={t("settings.workspace.enable-user-signup.self")}
|
||||
checked={workspaceSetting.enableSignup}
|
||||
onChange={(event) => handleEnableSignUpChange(event.target.checked)}
|
||||
/>
|
||||
<p className="mt-2 text-gray-500">Once enabled, other users can signup.</p>
|
||||
<p className="mt-2 text-gray-500">{t("settings.workspace.enable-user-signup.description")}</p>
|
||||
</div>
|
||||
<div>
|
||||
<Button variant="outlined" color="neutral" disabled={!allowSave} onClick={handleSaveWorkspaceSetting}>
|
||||
Save
|
||||
{t("common.save")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -71,7 +71,3 @@ export function patchShortcut(shortcutPatch: ShortcutPatch) {
|
||||
export function deleteShortcutById(shortcutId: ShortcutId) {
|
||||
return axios.delete(`/api/v1/shortcut/${shortcutId}`);
|
||||
}
|
||||
|
||||
export function getUrlFavicon(url: string) {
|
||||
return axios.get<string>(`/api/v1/url/favicon?url=${url}`);
|
||||
}
|
||||
|
@ -13,3 +13,12 @@ export const absolutifyLink = (rel: string): string => {
|
||||
export const releaseGuard = () => {
|
||||
return import.meta.env.MODE === "development";
|
||||
};
|
||||
|
||||
export const getFaviconWithGoogleS2 = (url: string) => {
|
||||
try {
|
||||
const urlObject = new URL(url);
|
||||
return `https://www.google.com/s2/favicons?sz=128&domain=${urlObject.hostname}`;
|
||||
} catch (error) {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
20
frontend/web/src/hooks/useNavigateTo.ts
Normal file
20
frontend/web/src/hooks/useNavigateTo.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { NavigateOptions, useNavigate } from "react-router-dom";
|
||||
|
||||
const useNavigateTo = () => {
|
||||
const navigateTo = useNavigate();
|
||||
|
||||
const navigateToWithViewTransition = (to: string, options?: NavigateOptions) => {
|
||||
const document = window.document as any;
|
||||
if (!document.startViewTransition) {
|
||||
navigateTo(to, options);
|
||||
} else {
|
||||
document.startViewTransition(() => {
|
||||
navigateTo(to, options);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return navigateToWithViewTransition;
|
||||
};
|
||||
|
||||
export default useNavigateTo;
|
@ -1,21 +0,0 @@
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
// Parameter is the boolean, with default "false" value
|
||||
const useToggle = (initialState = false): [boolean, (nextState?: boolean) => void] => {
|
||||
// Initialize the state
|
||||
const [state, setState] = useState(initialState);
|
||||
|
||||
// Define and memorize toggler function in case we pass down the comopnent,
|
||||
// This function change the boolean value to it's opposite value
|
||||
const toggle = useCallback((nextState?: boolean) => {
|
||||
if (nextState !== undefined) {
|
||||
setState(nextState);
|
||||
} else {
|
||||
setState((state) => !state);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return [state, toggle];
|
||||
};
|
||||
|
||||
export default useToggle;
|
@ -2,13 +2,14 @@ import { useColorScheme } from "@mui/joy";
|
||||
import { isEqual } from "lodash-es";
|
||||
import { useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Outlet, useNavigate } from "react-router-dom";
|
||||
import { UserSetting_ColorTheme } from "@/types/proto/api/v2/user_setting_service";
|
||||
import { Outlet } from "react-router-dom";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import { UserSetting_ColorTheme, UserSetting_Locale } from "@/types/proto/api/v2/user_setting_service";
|
||||
import Header from "../components/Header";
|
||||
import useUserStore from "../stores/v1/user";
|
||||
|
||||
const Root: React.FC = () => {
|
||||
const navigate = useNavigate();
|
||||
const navigateTo = useNavigateTo();
|
||||
const { setMode } = useColorScheme();
|
||||
const { i18n } = useTranslation();
|
||||
const userStore = useUserStore();
|
||||
@ -18,7 +19,7 @@ const Root: React.FC = () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentUser) {
|
||||
navigate("/auth", {
|
||||
navigateTo("/auth", {
|
||||
replace: true,
|
||||
});
|
||||
return;
|
||||
@ -33,7 +34,7 @@ const Root: React.FC = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isEqual(currentUserSetting.locale, "LOCALE_ZH")) {
|
||||
if (isEqual(currentUserSetting.locale, UserSetting_Locale.LOCALE_ZH)) {
|
||||
i18n.changeLanguage("zh");
|
||||
} else {
|
||||
i18n.changeLanguage("en");
|
||||
|
@ -69,9 +69,9 @@ const Home: React.FC = () => {
|
||||
</div>
|
||||
<FilterView />
|
||||
{loadingState.isLoading ? (
|
||||
<div className="py-12 w-full flex flex-row justify-center items-center opacity-80">
|
||||
<div className="py-12 w-full flex flex-row justify-center items-center opacity-80 dark:text-gray-500">
|
||||
<Icon.Loader className="mr-2 w-5 h-auto animate-spin" />
|
||||
loading
|
||||
{t("common.loading")}
|
||||
</div>
|
||||
) : orderedShortcutList.length === 0 ? (
|
||||
<div className="py-16 w-full flex flex-col justify-center items-center text-gray-400">
|
||||
|
62
frontend/web/src/pages/NotFound.tsx
Normal file
62
frontend/web/src/pages/NotFound.tsx
Normal file
@ -0,0 +1,62 @@
|
||||
import { Button } from "@mui/joy";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import CreateShortcutDialog from "@/components/CreateShortcutDialog";
|
||||
import Icon from "@/components/Icon";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import useUserStore from "@/stores/v1/user";
|
||||
|
||||
interface State {
|
||||
showCreateShortcutButton: boolean;
|
||||
}
|
||||
|
||||
const NotFound = () => {
|
||||
const location = useLocation();
|
||||
const navigateTo = useNavigateTo();
|
||||
const currentUser = useUserStore().getCurrentUser();
|
||||
const [state, setState] = useState<State>({
|
||||
showCreateShortcutButton: false,
|
||||
});
|
||||
const [showCreateShortcutDialog, setShowCreateShortcutDialog] = useState(false);
|
||||
const params = new URLSearchParams(location.search);
|
||||
|
||||
useEffect(() => {
|
||||
const shortcut = params.get("shortcut");
|
||||
if (currentUser && shortcut) {
|
||||
setState({
|
||||
...state,
|
||||
showCreateShortcutButton: true,
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full h-full overflow-y-auto overflow-x-hidden bg-zinc-100 dark:bg-zinc-800">
|
||||
<div className="w-full h-full flex flex-col justify-center items-center">
|
||||
<Icon.Meh strokeWidth={1} className="w-20 h-auto opacity-80 dark:text-gray-300" />
|
||||
<p className="mt-4 mb-8 text-4xl font-mono dark:text-gray-300">404</p>
|
||||
{state.showCreateShortcutButton && (
|
||||
<Button
|
||||
variant="outlined"
|
||||
startDecorator={<Icon.Plus className="w-5 h-auto" />}
|
||||
onClick={() => setShowCreateShortcutDialog(true)}
|
||||
>
|
||||
Create shortcut
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{showCreateShortcutDialog && (
|
||||
<CreateShortcutDialog
|
||||
initialShortcut={{ name: params.get("shortcut") || "" }}
|
||||
onClose={() => setShowCreateShortcutDialog(false)}
|
||||
onConfirm={() => navigateTo("/")}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default NotFound;
|
@ -1,10 +1,11 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import classNames from "classnames";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useLoaderData, useNavigate } from "react-router-dom";
|
||||
import { useLoaderData } from "react-router-dom";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import { showCommonDialog } from "../components/Alert";
|
||||
import AnalyticsView from "../components/AnalyticsView";
|
||||
import CreateShortcutDialog from "../components/CreateShortcutDialog";
|
||||
@ -12,9 +13,8 @@ import GenerateQRCodeDialog from "../components/GenerateQRCodeDialog";
|
||||
import Icon from "../components/Icon";
|
||||
import VisibilityIcon from "../components/VisibilityIcon";
|
||||
import Dropdown from "../components/common/Dropdown";
|
||||
import { absolutifyLink } from "../helpers/utils";
|
||||
import { absolutifyLink, getFaviconWithGoogleS2 } from "../helpers/utils";
|
||||
import { shortcutService } from "../services";
|
||||
import useFaviconStore from "../stores/v1/favicon";
|
||||
import useUserStore from "../stores/v1/user";
|
||||
|
||||
interface State {
|
||||
@ -23,26 +23,17 @@ interface State {
|
||||
|
||||
const ShortcutDetail = () => {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const navigateTo = useNavigateTo();
|
||||
const shortcutId = (useLoaderData() as Shortcut).id;
|
||||
const shortcut = shortcutService.getShortcutById(shortcutId) as Shortcut;
|
||||
const currentUser = useUserStore().getCurrentUser();
|
||||
const faviconStore = useFaviconStore();
|
||||
const [state, setState] = useState<State>({
|
||||
showEditModal: false,
|
||||
});
|
||||
const [favicon, setFavicon] = useState<string | undefined>(undefined);
|
||||
const [showQRCodeDialog, setShowQRCodeDialog] = useState<boolean>(false);
|
||||
const havePermission = currentUser.role === "ADMIN" || shortcut.creatorId === currentUser.id;
|
||||
const shortcutLink = absolutifyLink(`/s/${shortcut.name}`);
|
||||
|
||||
useEffect(() => {
|
||||
faviconStore.getOrFetchUrlFavicon(shortcut.link).then((url) => {
|
||||
if (url) {
|
||||
setFavicon(url);
|
||||
}
|
||||
});
|
||||
}, [shortcut.link]);
|
||||
const favicon = getFaviconWithGoogleS2(shortcut.link);
|
||||
|
||||
const handleCopyButtonClick = () => {
|
||||
copy(shortcutLink);
|
||||
@ -56,7 +47,7 @@ const ShortcutDetail = () => {
|
||||
style: "danger",
|
||||
onConfirm: async () => {
|
||||
await shortcutService.deleteShortcutById(shortcut.id);
|
||||
navigate("/", {
|
||||
navigateTo("/", {
|
||||
replace: true,
|
||||
});
|
||||
},
|
||||
|
@ -2,7 +2,8 @@ import { Button, Input } from "@mui/joy";
|
||||
import React, { FormEvent, useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { Link } from "react-router-dom";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import useWorkspaceStore from "@/stores/v1/workspace";
|
||||
import * as api from "../helpers/api";
|
||||
import useLoading from "../hooks/useLoading";
|
||||
@ -10,7 +11,7 @@ import useUserStore from "../stores/v1/user";
|
||||
|
||||
const SignIn: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const navigateTo = useNavigateTo();
|
||||
const userStore = useUserStore();
|
||||
const workspaceStore = useWorkspaceStore();
|
||||
const [email, setEmail] = useState("");
|
||||
@ -20,7 +21,7 @@ const SignIn: React.FC = () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (userStore.getCurrentUser()) {
|
||||
return navigate("/", {
|
||||
return navigateTo("/", {
|
||||
replace: true,
|
||||
});
|
||||
}
|
||||
@ -52,7 +53,7 @@ const SignIn: React.FC = () => {
|
||||
await api.signin(email, password);
|
||||
const user = await userStore.fetchCurrentUser();
|
||||
if (user) {
|
||||
navigate("/", {
|
||||
navigateTo("/", {
|
||||
replace: true,
|
||||
});
|
||||
} else {
|
||||
@ -99,15 +100,15 @@ const SignIn: React.FC = () => {
|
||||
disabled={actionBtnLoadingState.isLoading || !allowConfirm}
|
||||
onClick={handleSigninBtnClick}
|
||||
>
|
||||
Sign in
|
||||
{t("auth.sign-in")}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
{workspaceStore.setting.enableSignup && (
|
||||
{workspaceStore.profile.enableSignup && (
|
||||
<p className="w-full mt-4 text-sm">
|
||||
<span className="dark:text-gray-500">{"Don't have an account yet?"}</span>
|
||||
<Link to="/auth/signup" className="cursor-pointer ml-2 text-blue-600 hover:underline">
|
||||
Sign up
|
||||
{t("auth.sign-up")}
|
||||
</Link>
|
||||
</p>
|
||||
)}
|
||||
|
@ -2,7 +2,8 @@ import { Button, Input } from "@mui/joy";
|
||||
import React, { FormEvent, useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { Link } from "react-router-dom";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import useWorkspaceStore from "@/stores/v1/workspace";
|
||||
import * as api from "../helpers/api";
|
||||
import useLoading from "../hooks/useLoading";
|
||||
@ -10,7 +11,7 @@ import useUserStore from "../stores/v1/user";
|
||||
|
||||
const SignUp: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const navigateTo = useNavigateTo();
|
||||
const userStore = useUserStore();
|
||||
const workspaceStore = useWorkspaceStore();
|
||||
const [email, setEmail] = useState("");
|
||||
@ -21,13 +22,13 @@ const SignUp: React.FC = () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (userStore.getCurrentUser()) {
|
||||
return navigate("/", {
|
||||
return navigateTo("/", {
|
||||
replace: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (!workspaceStore.setting.enableSignup) {
|
||||
return navigate("/auth", {
|
||||
if (!workspaceStore.profile.enableSignup) {
|
||||
return navigateTo("/auth", {
|
||||
replace: true,
|
||||
});
|
||||
}
|
||||
@ -59,7 +60,7 @@ const SignUp: React.FC = () => {
|
||||
await api.signup(email, nickname, password);
|
||||
const user = await userStore.fetchCurrentUser();
|
||||
if (user) {
|
||||
navigate("/", {
|
||||
navigateTo("/", {
|
||||
replace: true,
|
||||
});
|
||||
} else {
|
||||
@ -80,7 +81,7 @@ const SignUp: React.FC = () => {
|
||||
<img id="logo-img" src="/logo.png" className="w-12 h-auto mr-2 -mt-1" alt="logo" />
|
||||
<span className="text-3xl opacity-80 dark:text-gray-500">Slash</span>
|
||||
</div>
|
||||
<p className="w-full text-2xl mt-6 dark:text-gray-500">Create your account</p>
|
||||
<p className="w-full text-2xl mt-6 dark:text-gray-500">{t("auth.create-your-account")}</p>
|
||||
<form className="w-full mt-4" onSubmit={handleSignupBtnClick}>
|
||||
<div className={`flex flex-col justify-start items-start w-full ${actionBtnLoadingState.isLoading ? "opacity-80" : ""}`}>
|
||||
<div className="w-full flex flex-col mb-2">
|
||||
@ -111,14 +112,14 @@ const SignUp: React.FC = () => {
|
||||
disabled={actionBtnLoadingState.isLoading || !allowConfirm}
|
||||
onClick={handleSignupBtnClick}
|
||||
>
|
||||
Sign up
|
||||
{t("auth.sign-up")}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
<p className="w-full mt-4 text-sm">
|
||||
<span className="dark:text-gray-500">{"Already has an account?"}</span>
|
||||
<Link to="/auth" className="cursor-pointer ml-2 text-blue-600 hover:underline">
|
||||
Sign in
|
||||
{t("auth.sign-in")}
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Button, Divider, Link, Textarea } from "@mui/joy";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Alert, Button, Divider, Link, Textarea } from "@mui/joy";
|
||||
import { useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import Icon from "@/components/Icon";
|
||||
import SubscriptionFAQ from "@/components/SubscriptionFAQ";
|
||||
@ -16,17 +16,12 @@ const SubscriptionSetting: React.FC = () => {
|
||||
const isAdmin = currentUser.role === "ADMIN";
|
||||
const profile = workspaceStore.profile;
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAdmin) {
|
||||
window.location.href = "/";
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (!isAdmin) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const handleUpdateLicenseKey = async () => {
|
||||
if (!isAdmin) {
|
||||
toast.error("Only admin can upload license key");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { subscription } = await subscriptionServiceClient.updateSubscription({
|
||||
licenseKey,
|
||||
@ -60,7 +55,7 @@ const SubscriptionSetting: React.FC = () => {
|
||||
<div className="w-full flex justify-between items-center mt-4">
|
||||
<div>
|
||||
{profile.plan === PlanType.FREE && (
|
||||
<Link href="https://yourselfhosted.lemonsqueezy.com/checkout?cart=df958121-81ad-4815-8b28-3f2d8e9c8e51" target="_blank">
|
||||
<Link href="https://yourselfhosted.lemonsqueezy.com/checkout/buy/d03a2696-8a8b-49c9-9e19-d425e3884fd7" target="_blank">
|
||||
Buy a license key
|
||||
<Icon.ExternalLink className="w-4 h-auto ml-1" />
|
||||
</Link>
|
||||
@ -74,6 +69,10 @@ const SubscriptionSetting: React.FC = () => {
|
||||
<Divider />
|
||||
<section className="w-full pb-8 dark:bg-zinc-900 flex items-center justify-center">
|
||||
<div className="w-full px-6">
|
||||
<Alert className="!inline-block mb-12">
|
||||
Slash is open source bookmarks and link sharing platform. Our source code is available and accessible on{" "}
|
||||
<Link href="https://github.com/boojack/slash">GitHub</Link> so anyone can get it, inspect it and review it.
|
||||
</Alert>
|
||||
<div className="w-full grid grid-cols-1 gap-12 mt-8 md:grid-cols-3">
|
||||
<div className="flex flex-col p-6 bg-white dark:bg-zinc-800 shadow-lg rounded-lg justify-between border border-gray-300 dark:border-zinc-700">
|
||||
<div>
|
||||
@ -138,7 +137,7 @@ const SubscriptionSetting: React.FC = () => {
|
||||
<Link
|
||||
className="w-full"
|
||||
underline="none"
|
||||
href="https://yourselfhosted.lemonsqueezy.com/checkout?cart=df958121-81ad-4815-8b28-3f2d8e9c8e51"
|
||||
href="https://yourselfhosted.lemonsqueezy.com/checkout/buy/d03a2696-8a8b-49c9-9e19-d425e3884fd7"
|
||||
target="_blank"
|
||||
>
|
||||
<Button className="w-full bg-gradient-to-r from-pink-500 to-purple-500 shadow hover:opacity-80">Get Started</Button>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { createBrowserRouter } from "react-router-dom";
|
||||
import NotFound from "@/pages/NotFound";
|
||||
import SignIn from "@/pages/SignIn";
|
||||
import SignUp from "@/pages/SignUp";
|
||||
import SubscriptionSetting from "@/pages/SubscriptionSetting";
|
||||
@ -53,6 +54,10 @@ const router = createBrowserRouter([
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "*",
|
||||
element: <NotFound />,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
@ -1,41 +0,0 @@
|
||||
import { create } from "zustand";
|
||||
import { persist } from "zustand/middleware";
|
||||
import * as api from "../../helpers/api";
|
||||
|
||||
interface FaviconState {
|
||||
cache: {
|
||||
[key: string]: string;
|
||||
};
|
||||
getOrFetchUrlFavicon: (url: string) => Promise<string>;
|
||||
}
|
||||
|
||||
const useFaviconStore = create<FaviconState>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
cache: {},
|
||||
getOrFetchUrlFavicon: async (url: string) => {
|
||||
const cache = get().cache;
|
||||
if (cache[url]) {
|
||||
return cache[url];
|
||||
}
|
||||
|
||||
try {
|
||||
const { data: favicon } = await api.getUrlFavicon(url);
|
||||
if (favicon) {
|
||||
cache[url] = favicon;
|
||||
set(cache);
|
||||
return favicon;
|
||||
}
|
||||
} catch (error) {
|
||||
// do nothing
|
||||
}
|
||||
return "";
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: "favicon_cache",
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
export default useFaviconStore;
|
@ -2,6 +2,12 @@ import react from "@vitejs/plugin-react-swc";
|
||||
import { resolve } from "path";
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
let devProxyServer = "http://localhost:8082/";
|
||||
if (process.env.DEV_PROXY_SERVER && process.env.DEV_PROXY_SERVER.length > 0) {
|
||||
console.log("Use devProxyServer from environment: ", process.env.DEV_PROXY_SERVER);
|
||||
devProxyServer = process.env.DEV_PROXY_SERVER;
|
||||
}
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
@ -9,13 +15,17 @@ export default defineConfig({
|
||||
host: "0.0.0.0",
|
||||
port: 3000,
|
||||
proxy: {
|
||||
"/api/": {
|
||||
target: "http://localhost:8082/",
|
||||
changeOrigin: true,
|
||||
"^/api": {
|
||||
target: devProxyServer,
|
||||
xfwd: true,
|
||||
},
|
||||
"/s/": {
|
||||
target: "http://localhost:8082/",
|
||||
changeOrigin: true,
|
||||
"^/slash.api.v2": {
|
||||
target: devProxyServer,
|
||||
xfwd: true,
|
||||
},
|
||||
"^/s/": {
|
||||
target: devProxyServer,
|
||||
xfwd: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
5
go.mod
5
go.mod
@ -29,13 +29,10 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/PuerkitoBio/goquery v1.6.0 // indirect
|
||||
github.com/andybalholm/cascadia v1.1.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/friendsofgo/errors v0.9.2 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
@ -57,7 +54,6 @@ require (
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
golang.org/x/tools v0.6.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230726155614-23370e0ffb3e // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
@ -82,7 +78,6 @@ require (
|
||||
github.com/mssola/useragent v1.0.0
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
go.deanishe.net/favicon v0.1.0
|
||||
go.uber.org/zap v1.21.0
|
||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df
|
||||
golang.org/x/mod v0.11.0
|
||||
|
76
go.sum
76
go.sum
@ -39,8 +39,6 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
|
||||
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=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/PuerkitoBio/goquery v1.6.0 h1:j7taAbelrdcsOlGeMenZxc2AWXD5fieT1/znArdnx94=
|
||||
github.com/PuerkitoBio/goquery v1.6.0/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
@ -50,18 +48,14 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
|
||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
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 v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
@ -116,8 +110,6 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
|
||||
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
|
||||
github.com/friendsofgo/errors v0.9.2 h1:X6NYxef4efCBdwI7BgS820zFaN7Cphrmb+Pljdzjtgk=
|
||||
github.com/friendsofgo/errors v0.9.2/go.mod h1:yCvFW5AkDIL9qn7suHVLiI/gH228n7PC4Pn44IGoTOI=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
@ -135,8 +127,6 @@ github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgO
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
|
||||
github.com/go-openapi/strfmt v0.19.8/go.mod h1:qBBipho+3EoIqn6YDI+4RnQEtj6jT/IdKm+PAlXxSUc=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
@ -145,32 +135,7 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+
|
||||
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
|
||||
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
|
||||
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
|
||||
github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||
github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
|
||||
github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
|
||||
github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
|
||||
github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
|
||||
github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
|
||||
github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
|
||||
github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
|
||||
github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
|
||||
github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
|
||||
github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
|
||||
github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
|
||||
github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
|
||||
github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
||||
github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
||||
github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
|
||||
github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
|
||||
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
|
||||
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
|
||||
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
|
||||
@ -217,7 +182,6 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
@ -250,7 +214,6 @@ github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbu
|
||||
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.1/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 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@ -304,11 +267,7 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
|
||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4FwCTKeG3oo7hrHJAoznj9nag=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
@ -323,18 +282,14 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
|
||||
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/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
|
||||
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||
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.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg=
|
||||
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.2/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=
|
||||
@ -356,8 +311,6 @@ github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0U
|
||||
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=
|
||||
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||
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=
|
||||
@ -370,7 +323,6 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
@ -391,7 +343,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/mssola/useragent v1.0.0 h1:WRlDpXyxHDNfvZaPEut5Biveq86Ze4o4EMffyMxmH5o=
|
||||
github.com/mssola/useragent v1.0.0/go.mod h1:hz9Cqz4RXusgg1EdI4Al0INR62kP7aPSRNHnpU+b85Y=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
@ -425,7 +376,6 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
@ -467,8 +417,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qq
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
@ -481,8 +429,6 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
@ -500,7 +446,6 @@ github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUq
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3/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.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU=
|
||||
@ -510,14 +455,12 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
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=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
@ -526,7 +469,6 @@ 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.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
||||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
@ -539,19 +481,14 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
|
||||
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/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
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/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.deanishe.net/favicon v0.1.0 h1:Afy941gjRik+DjUUcYHUxcztFEeFse2ITBkMMOlgefM=
|
||||
go.deanishe.net/favicon v0.1.0/go.mod h1:vIKVI+lUh8k3UAzaN4gjC+cpyatLQWmx0hVX4vLE8jU=
|
||||
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.mongodb.org/mongo-driver v1.4.2/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
||||
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=
|
||||
@ -581,9 +518,7 @@ go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
|
||||
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-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/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=
|
||||
@ -631,7 +566,6 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
|
||||
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
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=
|
||||
@ -689,7 +623,6 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
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-20190412183630-56d357773e84/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=
|
||||
@ -709,13 +642,10 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/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-20190531175056-4c3a928424d2/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=
|
||||
@ -789,13 +719,9 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||
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-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/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-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
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=
|
||||
@ -844,8 +770,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
||||
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=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
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=
|
||||
|
@ -39,14 +39,12 @@ message WorkspaceSetting {
|
||||
string license_key = 1;
|
||||
// Whether to enable other users to sign up.
|
||||
bool enable_signup = 2;
|
||||
// The relative path of the resource directory.
|
||||
string resource_relative_path = 3;
|
||||
// The custom style.
|
||||
string custom_style = 4;
|
||||
string custom_style = 3;
|
||||
// The custom script.
|
||||
string custom_script = 5;
|
||||
string custom_script = 4;
|
||||
// The auto backup setting.
|
||||
AutoBackupWorkspaceSetting auto_backup = 6;
|
||||
AutoBackupWorkspaceSetting auto_backup = 5;
|
||||
}
|
||||
|
||||
message AutoBackupWorkspaceSetting {
|
||||
|
@ -1006,7 +1006,6 @@
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| license_key | [string](#string) | | |
|
||||
| enable_signup | [bool](#bool) | | Whether to enable other users to sign up. |
|
||||
| resource_relative_path | [string](#string) | | The relative path of the resource directory. |
|
||||
| custom_style | [string](#string) | | The custom style. |
|
||||
| custom_script | [string](#string) | | The custom script. |
|
||||
| auto_backup | [AutoBackupWorkspaceSetting](#slash-api-v2-AutoBackupWorkspaceSetting) | | The auto backup setting. |
|
||||
|
@ -113,14 +113,12 @@ type WorkspaceSetting struct {
|
||||
LicenseKey string `protobuf:"bytes,1,opt,name=license_key,json=licenseKey,proto3" json:"license_key,omitempty"`
|
||||
// Whether to enable other users to sign up.
|
||||
EnableSignup bool `protobuf:"varint,2,opt,name=enable_signup,json=enableSignup,proto3" json:"enable_signup,omitempty"`
|
||||
// The relative path of the resource directory.
|
||||
ResourceRelativePath string `protobuf:"bytes,3,opt,name=resource_relative_path,json=resourceRelativePath,proto3" json:"resource_relative_path,omitempty"`
|
||||
// The custom style.
|
||||
CustomStyle string `protobuf:"bytes,4,opt,name=custom_style,json=customStyle,proto3" json:"custom_style,omitempty"`
|
||||
CustomStyle string `protobuf:"bytes,3,opt,name=custom_style,json=customStyle,proto3" json:"custom_style,omitempty"`
|
||||
// The custom script.
|
||||
CustomScript string `protobuf:"bytes,5,opt,name=custom_script,json=customScript,proto3" json:"custom_script,omitempty"`
|
||||
CustomScript string `protobuf:"bytes,4,opt,name=custom_script,json=customScript,proto3" json:"custom_script,omitempty"`
|
||||
// The auto backup setting.
|
||||
AutoBackup *AutoBackupWorkspaceSetting `protobuf:"bytes,6,opt,name=auto_backup,json=autoBackup,proto3" json:"auto_backup,omitempty"`
|
||||
AutoBackup *AutoBackupWorkspaceSetting `protobuf:"bytes,5,opt,name=auto_backup,json=autoBackup,proto3" json:"auto_backup,omitempty"`
|
||||
}
|
||||
|
||||
func (x *WorkspaceSetting) Reset() {
|
||||
@ -169,13 +167,6 @@ func (x *WorkspaceSetting) GetEnableSignup() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *WorkspaceSetting) GetResourceRelativePath() string {
|
||||
if x != nil {
|
||||
return x.ResourceRelativePath
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *WorkspaceSetting) GetCustomStyle() string {
|
||||
if x != nil {
|
||||
return x.CustomStyle
|
||||
@ -564,101 +555,98 @@ var file_api_v2_workspace_service_proto_rawDesc = []byte{
|
||||
0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d,
|
||||
0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x53, 0x63, 0x72, 0x69, 0x70,
|
||||
0x74, 0x22, 0xa1, 0x02, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53,
|
||||
0x74, 0x22, 0xeb, 0x01, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53,
|
||||
0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73,
|
||||
0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6c, 0x69, 0x63,
|
||||
0x65, 0x6e, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c,
|
||||
0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x12, 0x34, 0x0a, 0x16,
|
||||
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76,
|
||||
0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61,
|
||||
0x74, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x73, 0x74, 0x79,
|
||||
0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d,
|
||||
0x53, 0x74, 0x79, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f,
|
||||
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75,
|
||||
0x73, 0x74, 0x6f, 0x6d, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x49, 0x0a, 0x0b, 0x61, 0x75,
|
||||
0x74, 0x6f, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x28, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41,
|
||||
0x75, 0x74, 0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
|
||||
0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x42,
|
||||
0x61, 0x63, 0x6b, 0x75, 0x70, 0x22, 0x7a, 0x0a, 0x1a, 0x41, 0x75, 0x74, 0x6f, 0x42, 0x61, 0x63,
|
||||
0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x12, 0x21, 0x0a, 0x0c,
|
||||
0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x12,
|
||||
0x23, 0x0a, 0x0d, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x53, 0x63,
|
||||
0x72, 0x69, 0x70, 0x74, 0x12, 0x49, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x62, 0x61, 0x63,
|
||||
0x6b, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x6c, 0x61, 0x73,
|
||||
0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x42, 0x61, 0x63,
|
||||
0x6b, 0x75, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74,
|
||||
0x69, 0x6e, 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, 0x27, 0x0a,
|
||||
0x0f, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x72, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x72,
|
||||
0x65, 0x73, 0x73, 0x69, 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, 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,
|
||||
0x57, 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, 0x38,
|
||||
0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1e, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 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,
|
||||
0x07, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x1c, 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, 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, 0x73, 0x6c, 0x61, 0x73, 0x68, 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,
|
||||
0x7a, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
|
||||
0x69, 0x6e, 0x67, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x22,
|
||||
0x7a, 0x0a, 0x1a, 0x41, 0x75, 0x74, 0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x57, 0x6f, 0x72,
|
||||
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 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, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x6f, 0x6e, 0x5f,
|
||||
0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0e, 0x63, 0x72, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 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, 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, 0x57, 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, 0x38, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x6c, 0x61, 0x73,
|
||||
0x68, 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, 0x07, 0x70, 0x72, 0x6f, 0x66, 0x69,
|
||||
0x6c, 0x65, 0x22, 0x1c, 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, 0x38, 0x0a, 0x07, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 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, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52,
|
||||
0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x5a, 0x0a, 0x1e, 0x55,
|
||||
0x70, 0x64, 0x61, 0x74, 0x65, 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, 0x73, 0x6c, 0x61, 0x73, 0x68, 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, 0x32, 0xce, 0x03, 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, 0x73, 0x6c, 0x61, 0x73, 0x68, 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,
|
||||
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, 0x73, 0x6c, 0x61, 0x73, 0x68, 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, 0x7a, 0x0a, 0x1d, 0x55, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 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, 0x73, 0x6c,
|
||||
0x61, 0x73, 0x68, 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, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d,
|
||||
0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74,
|
||||
0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x5a, 0x0a, 0x1e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 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, 0x73, 0x6c, 0x61, 0x73, 0x68,
|
||||
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, 0x32, 0xce, 0x03, 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, 0x73, 0x6c, 0x61, 0x73, 0x68, 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, 0x12, 0x8d, 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, 0x73, 0x6c, 0x61, 0x73, 0x68, 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,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
|
||||
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, 0x12, 0x8d, 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, 0x73, 0x6c, 0x61, 0x73, 0x68, 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, 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, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x99, 0x01, 0x0a,
|
||||
0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
|
||||
0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x2b, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e,
|
||||
0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72,
|
||||
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69,
|
||||
0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 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, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f,
|
||||
0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
|
||||
0x2f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x42, 0xac, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d,
|
||||
0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 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, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x2f, 0x62, 0x6f, 0x6f, 0x6a, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68,
|
||||
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, 0x53, 0x41, 0x58, 0xaa, 0x02, 0x0c,
|
||||
0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x53,
|
||||
0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x53, 0x6c,
|
||||
0x61, 0x73, 0x68, 0x5c, 0x41, 0x70, 0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65,
|
||||
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a,
|
||||
0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
|
||||
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, 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, 0x73,
|
||||
0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x99, 0x01, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74,
|
||||
0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e,
|
||||
0x67, 0x12, 0x2b, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,
|
||||
0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
|
||||
0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c,
|
||||
0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 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, 0x24, 0x82, 0xd3,
|
||||
0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32,
|
||||
0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x65, 0x74, 0x74, 0x69,
|
||||
0x6e, 0x67, 0x42, 0xac, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68,
|
||||
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, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6f, 0x6f,
|
||||
0x6a, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 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, 0x53, 0x41, 0x58, 0xaa, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e,
|
||||
0x41, 0x70, 0x69, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41,
|
||||
0x70, 0x69, 0x5c, 0x56, 0x32, 0xe2, 0x02, 0x18, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x41, 0x70,
|
||||
0x69, 0x5c, 0x56, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0xea, 0x02, 0x0e, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a, 0x41, 0x70, 0x69, 0x3a, 0x3a, 0x56,
|
||||
0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -310,7 +310,6 @@
|
||||
| license_key | [string](#string) | | |
|
||||
| secret_session | [string](#string) | | |
|
||||
| enable_signup | [bool](#bool) | | |
|
||||
| resource_relative_path | [string](#string) | | |
|
||||
| custom_style | [string](#string) | | |
|
||||
| custom_script | [string](#string) | | |
|
||||
| auto_backup | [AutoBackupWorkspaceSetting](#slash-store-AutoBackupWorkspaceSetting) | | |
|
||||
@ -333,10 +332,9 @@
|
||||
| WORKSPACE_SETTING_LICENSE_KEY | 1 | The license key. |
|
||||
| WORKSPACE_SETTING_SECRET_SESSION | 2 | The secret session key used to encrypt session data. |
|
||||
| WORKSAPCE_SETTING_ENABLE_SIGNUP | 3 | Whether to enable other users to sign up. |
|
||||
| WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH | 4 | The relative path of the resource directory. |
|
||||
| WORKSPACE_SETTING_CUSTOM_STYLE | 5 | The custom style. |
|
||||
| WORKSPACE_SETTING_CUSTOM_SCRIPT | 6 | The custom script. |
|
||||
| WORKSPACE_SETTING_AUTO_BACKUP | 7 | The auto backup setting. |
|
||||
| WORKSPACE_SETTING_CUSTOM_STYLE | 4 | The custom style. |
|
||||
| WORKSPACE_SETTING_CUSTOM_SCRIPT | 5 | The custom script. |
|
||||
| WORKSPACE_SETTING_AUTO_BACKUP | 6 | The auto backup setting. |
|
||||
|
||||
|
||||
|
||||
|
@ -30,14 +30,12 @@ const (
|
||||
WorkspaceSettingKey_WORKSPACE_SETTING_SECRET_SESSION WorkspaceSettingKey = 2
|
||||
// Whether to enable other users to sign up.
|
||||
WorkspaceSettingKey_WORKSAPCE_SETTING_ENABLE_SIGNUP WorkspaceSettingKey = 3
|
||||
// The relative path of the resource directory.
|
||||
WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH WorkspaceSettingKey = 4
|
||||
// The custom style.
|
||||
WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_STYLE WorkspaceSettingKey = 5
|
||||
WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_STYLE WorkspaceSettingKey = 4
|
||||
// The custom script.
|
||||
WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_SCRIPT WorkspaceSettingKey = 6
|
||||
WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_SCRIPT WorkspaceSettingKey = 5
|
||||
// The auto backup setting.
|
||||
WorkspaceSettingKey_WORKSPACE_SETTING_AUTO_BACKUP WorkspaceSettingKey = 7
|
||||
WorkspaceSettingKey_WORKSPACE_SETTING_AUTO_BACKUP WorkspaceSettingKey = 6
|
||||
)
|
||||
|
||||
// Enum value maps for WorkspaceSettingKey.
|
||||
@ -47,20 +45,18 @@ var (
|
||||
1: "WORKSPACE_SETTING_LICENSE_KEY",
|
||||
2: "WORKSPACE_SETTING_SECRET_SESSION",
|
||||
3: "WORKSAPCE_SETTING_ENABLE_SIGNUP",
|
||||
4: "WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH",
|
||||
5: "WORKSPACE_SETTING_CUSTOM_STYLE",
|
||||
6: "WORKSPACE_SETTING_CUSTOM_SCRIPT",
|
||||
7: "WORKSPACE_SETTING_AUTO_BACKUP",
|
||||
4: "WORKSPACE_SETTING_CUSTOM_STYLE",
|
||||
5: "WORKSPACE_SETTING_CUSTOM_SCRIPT",
|
||||
6: "WORKSPACE_SETTING_AUTO_BACKUP",
|
||||
}
|
||||
WorkspaceSettingKey_value = map[string]int32{
|
||||
"WORKSPACE_SETTING_KEY_UNSPECIFIED": 0,
|
||||
"WORKSPACE_SETTING_LICENSE_KEY": 1,
|
||||
"WORKSPACE_SETTING_SECRET_SESSION": 2,
|
||||
"WORKSAPCE_SETTING_ENABLE_SIGNUP": 3,
|
||||
"WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH": 4,
|
||||
"WORKSPACE_SETTING_CUSTOM_STYLE": 5,
|
||||
"WORKSPACE_SETTING_CUSTOM_SCRIPT": 6,
|
||||
"WORKSPACE_SETTING_AUTO_BACKUP": 7,
|
||||
"WORKSPACE_SETTING_CUSTOM_STYLE": 4,
|
||||
"WORKSPACE_SETTING_CUSTOM_SCRIPT": 5,
|
||||
"WORKSPACE_SETTING_AUTO_BACKUP": 6,
|
||||
}
|
||||
)
|
||||
|
||||
@ -102,7 +98,6 @@ type WorkspaceSetting struct {
|
||||
// *WorkspaceSetting_LicenseKey
|
||||
// *WorkspaceSetting_SecretSession
|
||||
// *WorkspaceSetting_EnableSignup
|
||||
// *WorkspaceSetting_ResourceRelativePath
|
||||
// *WorkspaceSetting_CustomStyle
|
||||
// *WorkspaceSetting_CustomScript
|
||||
// *WorkspaceSetting_AutoBackup
|
||||
@ -176,13 +171,6 @@ func (x *WorkspaceSetting) GetEnableSignup() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *WorkspaceSetting) GetResourceRelativePath() string {
|
||||
if x, ok := x.GetValue().(*WorkspaceSetting_ResourceRelativePath); ok {
|
||||
return x.ResourceRelativePath
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *WorkspaceSetting) GetCustomStyle() string {
|
||||
if x, ok := x.GetValue().(*WorkspaceSetting_CustomStyle); ok {
|
||||
return x.CustomStyle
|
||||
@ -220,20 +208,16 @@ type WorkspaceSetting_EnableSignup struct {
|
||||
EnableSignup bool `protobuf:"varint,4,opt,name=enable_signup,json=enableSignup,proto3,oneof"`
|
||||
}
|
||||
|
||||
type WorkspaceSetting_ResourceRelativePath struct {
|
||||
ResourceRelativePath string `protobuf:"bytes,5,opt,name=resource_relative_path,json=resourceRelativePath,proto3,oneof"`
|
||||
}
|
||||
|
||||
type WorkspaceSetting_CustomStyle struct {
|
||||
CustomStyle string `protobuf:"bytes,6,opt,name=custom_style,json=customStyle,proto3,oneof"`
|
||||
CustomStyle string `protobuf:"bytes,5,opt,name=custom_style,json=customStyle,proto3,oneof"`
|
||||
}
|
||||
|
||||
type WorkspaceSetting_CustomScript struct {
|
||||
CustomScript string `protobuf:"bytes,7,opt,name=custom_script,json=customScript,proto3,oneof"`
|
||||
CustomScript string `protobuf:"bytes,6,opt,name=custom_script,json=customScript,proto3,oneof"`
|
||||
}
|
||||
|
||||
type WorkspaceSetting_AutoBackup struct {
|
||||
AutoBackup *AutoBackupWorkspaceSetting `protobuf:"bytes,8,opt,name=auto_backup,json=autoBackup,proto3,oneof"`
|
||||
AutoBackup *AutoBackupWorkspaceSetting `protobuf:"bytes,7,opt,name=auto_backup,json=autoBackup,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*WorkspaceSetting_LicenseKey) isWorkspaceSetting_Value() {}
|
||||
@ -242,8 +226,6 @@ func (*WorkspaceSetting_SecretSession) isWorkspaceSetting_Value() {}
|
||||
|
||||
func (*WorkspaceSetting_EnableSignup) isWorkspaceSetting_Value() {}
|
||||
|
||||
func (*WorkspaceSetting_ResourceRelativePath) isWorkspaceSetting_Value() {}
|
||||
|
||||
func (*WorkspaceSetting_CustomStyle) isWorkspaceSetting_Value() {}
|
||||
|
||||
func (*WorkspaceSetting_CustomScript) isWorkspaceSetting_Value() {}
|
||||
@ -323,7 +305,7 @@ 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, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0x92, 0x03, 0x0a,
|
||||
0x0b, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x22, 0xda, 0x02, 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, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x57, 0x6f, 0x72,
|
||||
@ -335,59 +317,53 @@ var file_store_workspace_setting_proto_rawDesc = []byte{
|
||||
0x48, 0x00, 0x52, 0x0d, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x25, 0x0a, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x75, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0c, 0x65, 0x6e, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x12, 0x36, 0x0a, 0x16, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61,
|
||||
0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x14, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68,
|
||||
0x12, 0x23, 0x0a, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d,
|
||||
0x53, 0x74, 0x79, 0x6c, 0x65, 0x12, 0x25, 0x0a, 0x0d, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f,
|
||||
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c,
|
||||
0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x4a, 0x0a, 0x0b,
|
||||
0x61, 0x75, 0x74, 0x6f, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x18, 0x08, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x27, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e,
|
||||
0x41, 0x75, 0x74, 0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70,
|
||||
0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x75,
|
||||
0x74, 0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x22, 0x7a, 0x0a, 0x1a, 0x41, 0x75, 0x74, 0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x57,
|
||||
0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 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, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x6f,
|
||||
0x6e, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0e, 0x63, 0x72, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69,
|
||||
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, 0xc4, 0x02,
|
||||
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, 0x21, 0x0a, 0x1d,
|
||||
0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e,
|
||||
0x47, 0x5f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x12,
|
||||
0x24, 0x0a, 0x20, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54,
|
||||
0x54, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x45, 0x43, 0x52, 0x45, 0x54, 0x5f, 0x53, 0x45, 0x53, 0x53,
|
||||
0x49, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x41, 0x50,
|
||||
0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c,
|
||||
0x45, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x55, 0x50, 0x10, 0x03, 0x12, 0x2c, 0x0a, 0x28, 0x57, 0x4f,
|
||||
0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f,
|
||||
0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x52, 0x45, 0x4c, 0x41, 0x54, 0x49, 0x56,
|
||||
0x45, 0x5f, 0x50, 0x41, 0x54, 0x48, 0x10, 0x04, 0x12, 0x22, 0x0a, 0x1e, 0x57, 0x4f, 0x52, 0x4b,
|
||||
0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x43, 0x55,
|
||||
0x53, 0x54, 0x4f, 0x4d, 0x5f, 0x53, 0x54, 0x59, 0x4c, 0x45, 0x10, 0x05, 0x12, 0x23, 0x0a, 0x1f,
|
||||
0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e,
|
||||
0x47, 0x5f, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x10,
|
||||
0x06, 0x12, 0x21, 0x0a, 0x1d, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53,
|
||||
0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x42, 0x41, 0x43, 0x4b,
|
||||
0x55, 0x50, 0x10, 0x07, 0x42, 0x9f, 0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61,
|
||||
0x73, 0x68, 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, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6f,
|
||||
0x6f, 0x6a, 0x61, 0x63, 0x6b, 0x2f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x53, 0x53,
|
||||
0x58, 0xaa, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca,
|
||||
0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17,
|
||||
0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d,
|
||||
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a,
|
||||
0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x6c, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x12, 0x23, 0x0a, 0x0c, 0x63, 0x75, 0x73, 0x74,
|
||||
0x6f, 0x6d, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00,
|
||||
0x52, 0x0b, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x12, 0x25, 0x0a,
|
||||
0x0d, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x06,
|
||||
0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x53, 0x63,
|
||||
0x72, 0x69, 0x70, 0x74, 0x12, 0x4a, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x62, 0x61, 0x63,
|
||||
0x6b, 0x75, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x73, 0x6c, 0x61, 0x73,
|
||||
0x68, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x42, 0x61, 0x63, 0x6b,
|
||||
0x75, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69,
|
||||
0x6e, 0x67, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70,
|
||||
0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x7a, 0x0a, 0x1a, 0x41, 0x75, 0x74,
|
||||
0x6f, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
|
||||
0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 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, 0x27, 0x0a, 0x0f, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x72, 0x6f, 0x6e,
|
||||
0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 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, 0x96, 0x02, 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, 0x21, 0x0a, 0x1d, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43,
|
||||
0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53,
|
||||
0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x57, 0x4f, 0x52, 0x4b, 0x53,
|
||||
0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x45, 0x43,
|
||||
0x52, 0x45, 0x54, 0x5f, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x23, 0x0a,
|
||||
0x1f, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x41, 0x50, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49,
|
||||
0x4e, 0x47, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x55, 0x50,
|
||||
0x10, 0x03, 0x12, 0x22, 0x0a, 0x1e, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f,
|
||||
0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x5f, 0x53,
|
||||
0x54, 0x59, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x23, 0x0a, 0x1f, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x50,
|
||||
0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x43, 0x55, 0x53, 0x54,
|
||||
0x4f, 0x4d, 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x10, 0x05, 0x12, 0x21, 0x0a, 0x1d, 0x57,
|
||||
0x4f, 0x52, 0x4b, 0x53, 0x50, 0x41, 0x43, 0x45, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47,
|
||||
0x5f, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x55, 0x50, 0x10, 0x06, 0x42, 0x9f,
|
||||
0x01, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x6c, 0x61, 0x73, 0x68, 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, 0x28, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6f, 0x6f, 0x6a, 0x61, 0x63, 0x6b, 0x2f,
|
||||
0x73, 0x6c, 0x61, 0x73, 0x68, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f,
|
||||
0x73, 0x74, 0x6f, 0x72, 0x65, 0xa2, 0x02, 0x03, 0x53, 0x53, 0x58, 0xaa, 0x02, 0x0b, 0x53, 0x6c,
|
||||
0x61, 0x73, 0x68, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xca, 0x02, 0x0b, 0x53, 0x6c, 0x61, 0x73,
|
||||
0x68, 0x5c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0xe2, 0x02, 0x17, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x5c,
|
||||
0x53, 0x74, 0x6f, 0x72, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0xea, 0x02, 0x0c, 0x53, 0x6c, 0x61, 0x73, 0x68, 0x3a, 0x3a, 0x53, 0x74, 0x6f, 0x72, 0x65,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -454,7 +430,6 @@ func file_store_workspace_setting_proto_init() {
|
||||
(*WorkspaceSetting_LicenseKey)(nil),
|
||||
(*WorkspaceSetting_SecretSession)(nil),
|
||||
(*WorkspaceSetting_EnableSignup)(nil),
|
||||
(*WorkspaceSetting_ResourceRelativePath)(nil),
|
||||
(*WorkspaceSetting_CustomStyle)(nil),
|
||||
(*WorkspaceSetting_CustomScript)(nil),
|
||||
(*WorkspaceSetting_AutoBackup)(nil),
|
||||
|
@ -11,10 +11,9 @@ message WorkspaceSetting {
|
||||
string license_key = 2;
|
||||
string secret_session = 3;
|
||||
bool enable_signup = 4;
|
||||
string resource_relative_path = 5;
|
||||
string custom_style = 6;
|
||||
string custom_script = 7;
|
||||
AutoBackupWorkspaceSetting auto_backup = 8;
|
||||
string custom_style = 5;
|
||||
string custom_script = 6;
|
||||
AutoBackupWorkspaceSetting auto_backup = 7;
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,14 +25,12 @@ enum WorkspaceSettingKey {
|
||||
WORKSPACE_SETTING_SECRET_SESSION = 2;
|
||||
// Whether to enable other users to sign up.
|
||||
WORKSAPCE_SETTING_ENABLE_SIGNUP = 3;
|
||||
// The relative path of the resource directory.
|
||||
WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH = 4;
|
||||
// The custom style.
|
||||
WORKSPACE_SETTING_CUSTOM_STYLE = 5;
|
||||
WORKSPACE_SETTING_CUSTOM_STYLE = 4;
|
||||
// The custom script.
|
||||
WORKSPACE_SETTING_CUSTOM_SCRIPT = 6;
|
||||
WORKSPACE_SETTING_CUSTOM_SCRIPT = 5;
|
||||
// The auto backup setting.
|
||||
WORKSPACE_SETTING_AUTO_BACKUP = 7;
|
||||
WORKSPACE_SETTING_AUTO_BACKUP = 6;
|
||||
}
|
||||
|
||||
message AutoBackupWorkspaceSetting {
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
storepb "github.com/boojack/slash/proto/gen/store"
|
||||
"github.com/boojack/slash/server/profile"
|
||||
"github.com/boojack/slash/server/service/license"
|
||||
"github.com/boojack/slash/server/service/resource"
|
||||
"github.com/boojack/slash/store"
|
||||
)
|
||||
|
||||
@ -110,7 +111,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
|
||||
}
|
||||
|
||||
// Register resource service.
|
||||
resourceService := NewResourceService(profile, store)
|
||||
resourceService := resource.NewResourceService(profile, store)
|
||||
resourceService.Register(rootGroup)
|
||||
|
||||
return s, nil
|
||||
|
@ -1,4 +1,4 @@
|
||||
package server
|
||||
package resource
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -9,11 +9,14 @@ import (
|
||||
"github.com/h2non/filetype"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
storepb "github.com/boojack/slash/proto/gen/store"
|
||||
"github.com/boojack/slash/server/profile"
|
||||
"github.com/boojack/slash/store"
|
||||
)
|
||||
|
||||
const (
|
||||
resourceRelativePath = "resources"
|
||||
)
|
||||
|
||||
type ResourceService struct {
|
||||
Profile *profile.Profile
|
||||
Store *store.Store
|
||||
@ -27,21 +30,9 @@ func NewResourceService(profile *profile.Profile, store *store.Store) *ResourceS
|
||||
}
|
||||
|
||||
// Register registers the resource service to the echo server.
|
||||
func (s *ResourceService) Register(g *echo.Group) {
|
||||
func (*ResourceService) Register(g *echo.Group) {
|
||||
g.GET("/resources/:id", func(c echo.Context) error {
|
||||
ctx := c.Request().Context()
|
||||
resourceID := c.Param("resourceId")
|
||||
resourceRelativePathSetting, err := s.Store.GetWorkspaceSetting(ctx, &store.FindWorkspaceSetting{
|
||||
Key: storepb.WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH,
|
||||
})
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "failed to workspace resource relative path setting").SetInternal(err)
|
||||
}
|
||||
if resourceRelativePathSetting == nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "found no workspace resource relative path setting")
|
||||
}
|
||||
|
||||
resourceRelativePath := resourceRelativePathSetting.GetResourceRelativePath()
|
||||
resourcePath := fmt.Sprintf("%s/%s", resourceRelativePath, resourceID)
|
||||
buf, err := os.ReadFile(resourcePath)
|
||||
if err != nil {
|
@ -9,10 +9,10 @@ import (
|
||||
|
||||
// Version is the service current released version.
|
||||
// Semantic versioning: https://semver.org/
|
||||
var Version = "0.4.4"
|
||||
var Version = "0.4.5"
|
||||
|
||||
// DevVersion is the service current development version.
|
||||
var DevVersion = "0.4.4"
|
||||
var DevVersion = "0.4.5"
|
||||
|
||||
func GetCurrentVersion(mode string) string {
|
||||
if mode == "dev" || mode == "demo" {
|
||||
|
@ -62,21 +62,30 @@ func (db *DB) Open(ctx context.Context) (err error) {
|
||||
return errors.Wrapf(err, "failed to open db with dsn: %s", db.profile.DSN)
|
||||
}
|
||||
db.DBInstance = sqliteDB
|
||||
currentVersion := version.GetCurrentVersion(db.profile.Mode)
|
||||
|
||||
if db.profile.Mode == "prod" {
|
||||
_, err := os.Stat(db.profile.DSN)
|
||||
if err != nil {
|
||||
// If db file not exists, we should create a new one with latest schema.
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
if err := db.applyLatestSchema(ctx); err != nil {
|
||||
return errors.Wrap(err, "failed to apply latest schema")
|
||||
}
|
||||
} else {
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
return errors.Wrap(err, "failed to get db file stat")
|
||||
}
|
||||
} else {
|
||||
|
||||
// If db file not exists, we should create a new one with latest schema.
|
||||
err := db.applyLatestSchema(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to apply latest schema")
|
||||
}
|
||||
_, err = db.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{
|
||||
Version: currentVersion,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to upsert migration history")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// If db file exists, we should check if we need to migrate the database.
|
||||
currentVersion := version.GetCurrentVersion(db.profile.Mode)
|
||||
migrationHistoryList, err := db.FindMigrationHistoryList(ctx, &MigrationHistoryFind{})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to find migration history")
|
||||
@ -129,7 +138,6 @@ func (db *DB) Open(ctx context.Context) (err error) {
|
||||
println(fmt.Sprintf("Failed to remove temp database file, err %v", err))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// In non-prod mode, we should always migrate the database.
|
||||
if _, err := os.Stat(db.profile.DSN); errors.Is(err, os.ErrNotExist) {
|
||||
@ -157,7 +165,7 @@ func (db *DB) applyLatestSchema(ctx context.Context) error {
|
||||
if db.profile.Mode == "prod" {
|
||||
schemaMode = "prod"
|
||||
}
|
||||
latestSchemaPath := fmt.Sprintf("%s/%s/%s", "migration", schemaMode, latestSchemaFileName)
|
||||
latestSchemaPath := fmt.Sprintf("migration/%s/%s", schemaMode, latestSchemaFileName)
|
||||
buf, err := migrationFS.ReadFile(latestSchemaPath)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to read latest schema %q", latestSchemaPath)
|
||||
@ -170,9 +178,9 @@ func (db *DB) applyLatestSchema(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion string) error {
|
||||
filenames, err := fs.Glob(migrationFS, fmt.Sprintf("%s/%s/*.sql", "migration/prod", minorVersion))
|
||||
filenames, err := fs.Glob(migrationFS, fmt.Sprintf("migration/prod/%s/*.sql", minorVersion))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to read ddl files")
|
||||
return errors.Wrap(err, "failed to read migrate files")
|
||||
}
|
||||
|
||||
sort.Strings(filenames)
|
||||
@ -203,13 +211,12 @@ func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion st
|
||||
}
|
||||
|
||||
func (db *DB) seed(ctx context.Context) error {
|
||||
filenames, err := fs.Glob(seedFS, fmt.Sprintf("%s/*.sql", "seed"))
|
||||
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)
|
||||
|
@ -32,8 +32,6 @@ func (s *Store) UpsertWorkspaceSetting(ctx context.Context, upsert *storepb.Work
|
||||
valueString = upsert.GetSecretSession()
|
||||
} else if upsert.Key == storepb.WorkspaceSettingKey_WORKSAPCE_SETTING_ENABLE_SIGNUP {
|
||||
valueString = strconv.FormatBool(upsert.GetEnableSignup())
|
||||
} else if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH {
|
||||
valueString = upsert.GetResourceRelativePath()
|
||||
} else if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_STYLE {
|
||||
valueString = upsert.GetCustomStyle()
|
||||
} else if upsert.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_SCRIPT {
|
||||
@ -98,8 +96,6 @@ func (s *Store) ListWorkspaceSettings(ctx context.Context, find *FindWorkspaceSe
|
||||
return nil, err
|
||||
}
|
||||
workspaceSetting.Value = &storepb.WorkspaceSetting_EnableSignup{EnableSignup: enableSignup}
|
||||
} else if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_RESOURCE_RELATIVE_PATH {
|
||||
workspaceSetting.Value = &storepb.WorkspaceSetting_ResourceRelativePath{ResourceRelativePath: valueString}
|
||||
} else if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_STYLE {
|
||||
workspaceSetting.Value = &storepb.WorkspaceSetting_CustomStyle{CustomStyle: valueString}
|
||||
} else if workspaceSetting.Key == storepb.WorkspaceSettingKey_WORKSPACE_SETTING_CUSTOM_SCRIPT {
|
||||
|
Reference in New Issue
Block a user