@appkit/dek-lib 0.46.0 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ export declare const DEK_AUTH_TOKEN_KEY = "dek_auth_token";
2
+ type Props = {
3
+ onSuccess: (token: string) => void;
4
+ };
5
+ declare const LoginScreen: ({ onSuccess }: Props) => import("react/jsx-runtime").JSX.Element;
6
+ export default LoginScreen;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export { default as Board } from './components/Board/Board';
2
+ export { default as LoginScreen } from './components/LoginScreen/LoginScreen';
3
+ export { DEK_AUTH_TOKEN_KEY } from './components/LoginScreen/LoginScreen';
2
4
  export { default as BoardProvider } from './components/BoardProvider/BoardProvider';
3
5
  export { default as Command } from './components/Command/Command';
4
6
  export { default as CommandGroup } from './components/CommandGroup/CommandGroup';
package/dist/index.es.js CHANGED
@@ -64519,6 +64519,115 @@ function watchForDataChanges(authToken, cb2) {
64519
64519
  async function authorize(email, password) {
64520
64520
  return fetchUserToken(email, password);
64521
64521
  }
64522
+ const DEK_AUTH_TOKEN_KEY = "dek_auth_token";
64523
+ const DEK_EMAIL_KEY = "dek_auth_email";
64524
+ const FullScreen = styled.div`
64525
+ position: fixed;
64526
+ inset: 0;
64527
+ background: #1a1a1a;
64528
+ display: flex;
64529
+ align-items: center;
64530
+ justify-content: center;
64531
+ padding-top: 70px;
64532
+ `;
64533
+ const StyledInput = styled.input`
64534
+ width: 100%;
64535
+ height: 56px;
64536
+ background: rgba(255, 255, 255, 0.08);
64537
+ border: 1px solid rgba(255, 255, 255, 0.15);
64538
+ border-radius: 8px;
64539
+ color: #fff;
64540
+ font-family: Heebo, Arial, Helvetica, sans-serif;
64541
+ font-size: 18px;
64542
+ font-weight: 300;
64543
+ padding: 0 16px;
64544
+ box-sizing: border-box;
64545
+ outline: none;
64546
+
64547
+ &::placeholder {
64548
+ color: rgba(255, 255, 255, 0.4);
64549
+ }
64550
+
64551
+ &:focus {
64552
+ border-color: rgba(255, 255, 255, 0.4);
64553
+ background: rgba(255, 255, 255, 0.12);
64554
+ }
64555
+ `;
64556
+ const LoginScreen = ({ onSuccess }) => {
64557
+ const [email, setEmail] = useState$1(() => localStorage.getItem(DEK_EMAIL_KEY) || "");
64558
+ const [password, setPassword] = useState$1("");
64559
+ const [error2, setError] = useState$1("");
64560
+ const [loading, setLoading] = useState$1(false);
64561
+ useEffect$1(() => {
64562
+ const savedToken = localStorage.getItem(DEK_AUTH_TOKEN_KEY);
64563
+ if (savedToken) {
64564
+ onSuccess(savedToken);
64565
+ }
64566
+ }, []);
64567
+ const handleSubmit = async () => {
64568
+ if (loading)
64569
+ return;
64570
+ setError("");
64571
+ setLoading(true);
64572
+ try {
64573
+ const token2 = await authorize(email, password);
64574
+ localStorage.setItem(DEK_AUTH_TOKEN_KEY, token2);
64575
+ localStorage.setItem(DEK_EMAIL_KEY, email);
64576
+ onSuccess(token2);
64577
+ } catch {
64578
+ localStorage.removeItem(DEK_AUTH_TOKEN_KEY);
64579
+ setError("Invalid email or password.");
64580
+ } finally {
64581
+ setLoading(false);
64582
+ }
64583
+ };
64584
+ const handleKeyDown = (e2) => {
64585
+ if (e2.key === "Enter")
64586
+ handleSubmit();
64587
+ };
64588
+ return /* @__PURE__ */ jsxs(FullScreen, { children: [
64589
+ /* @__PURE__ */ jsx(Q42, { transitionDelay: 0 }),
64590
+ /* @__PURE__ */ jsx(q42, { direction: "vert", valign: "center", halign: "center", children: /* @__PURE__ */ jsxs(g0, { direction: "vert", gap: 20, style: { width: 380, paddingTop: 150 }, children: [
64591
+ /* @__PURE__ */ jsxs(g0, { direction: "vert", gap: 12, collapse: true, children: [
64592
+ /* @__PURE__ */ jsx(
64593
+ StyledInput,
64594
+ {
64595
+ type: "email",
64596
+ placeholder: "Email",
64597
+ value: email,
64598
+ onChange: (e2) => setEmail(e2.target.value),
64599
+ onKeyDown: handleKeyDown,
64600
+ autoComplete: "email",
64601
+ style: { width: 380 }
64602
+ }
64603
+ ),
64604
+ /* @__PURE__ */ jsx(
64605
+ StyledInput,
64606
+ {
64607
+ type: "password",
64608
+ placeholder: "Password",
64609
+ value: password,
64610
+ onChange: (e2) => setPassword(e2.target.value),
64611
+ onKeyDown: handleKeyDown,
64612
+ autoComplete: "current-password",
64613
+ style: { width: 380 }
64614
+ }
64615
+ )
64616
+ ] }),
64617
+ error2 && /* @__PURE__ */ jsx(g0, { collapse: true, children: /* @__PURE__ */ jsx(l4, { color: "#ff6b6b", children: error2 }) }),
64618
+ /* @__PURE__ */ jsx(g0, { collapse: true, children: /* @__PURE__ */ jsx(
64619
+ ee,
64620
+ {
64621
+ title: loading ? "Signing in..." : "Sign In",
64622
+ icon: "none",
64623
+ width: 380,
64624
+ onClick: handleSubmit
64625
+ }
64626
+ ) })
64627
+ ] }) }),
64628
+ /* @__PURE__ */ jsx(a52, { title: "Sign In", noclose: true })
64629
+ ] });
64630
+ };
64522
64631
  const USER_PLUGIN_AND_INTEGRATIONS_QUERY = gql(`
64523
64632
  query userPluginsAndIntegrations {
64524
64633
  currentUser {
@@ -64548,7 +64657,7 @@ async function fetchUserPlugins(authToken) {
64548
64657
  result.integrations.unshift({
64549
64658
  key: "base",
64550
64659
  pluginName: "base",
64551
- pluginVersion: "0.46.0",
64660
+ pluginVersion: "0.47.0",
64552
64661
  pluginConfig: []
64553
64662
  });
64554
64663
  return result;
@@ -64617,7 +64726,7 @@ const ClockComponent = () => {
64617
64726
  };
64618
64727
  const About = () => {
64619
64728
  return /* @__PURE__ */ jsxs(g0, { padding: 20, direction: "vert", children: [
64620
- /* @__PURE__ */ jsx(uq1, { children: `Dek ${"0.46.0"}` }),
64729
+ /* @__PURE__ */ jsx(uq1, { children: `Dek ${"0.47.0"}` }),
64621
64730
  /* @__PURE__ */ jsx(l4, { children: "From Appkit" })
64622
64731
  ] });
64623
64732
  };
@@ -64786,6 +64895,44 @@ const PluginDev = ({ api: api2 }) => {
64786
64895
  ) })
64787
64896
  ] });
64788
64897
  };
64898
+ const Avatar = styled.div`
64899
+ width: 72px;
64900
+ height: 72px;
64901
+ border-radius: 50%;
64902
+ background: ${({ $hasImage }) => $hasImage ? "transparent" : "#1B75D0"};
64903
+ display: flex;
64904
+ align-items: center;
64905
+ justify-content: center;
64906
+ font-size: 28px;
64907
+ font-weight: 500;
64908
+ color: white;
64909
+ flex-shrink: 0;
64910
+ overflow: hidden;
64911
+ `;
64912
+ const AvatarImage = styled.img`
64913
+ width: 100%;
64914
+ height: 100%;
64915
+ object-fit: cover;
64916
+ `;
64917
+ const Profile = (_props) => {
64918
+ const snap = useSnapshot(state$1);
64919
+ const user = snap.data;
64920
+ const initials = (user == null ? void 0 : user.name) ? user.name.split(" ").map((n2) => n2[0]).join("").toUpperCase().slice(0, 2) : "?";
64921
+ const handleSignOut = () => {
64922
+ window.location.href = "/settings/signout";
64923
+ };
64924
+ return /* @__PURE__ */ jsxs(g0, { direction: "vert", padding: 20, gap: 24, children: [
64925
+ /* @__PURE__ */ jsxs(g0, { direction: "horz", gap: 20, valign: "center", collapse: true, children: [
64926
+ /* @__PURE__ */ jsx(Avatar, { $hasImage: !!(user == null ? void 0 : user.avatar), children: (user == null ? void 0 : user.avatar) ? /* @__PURE__ */ jsx(AvatarImage, { src: user.avatar, alt: user.name || "" }) : initials }),
64927
+ /* @__PURE__ */ jsxs(g0, { direction: "vert", gap: 4, children: [
64928
+ (user == null ? void 0 : user.name) && /* @__PURE__ */ jsx(l4, { size: "large", weight: "bold", children: user.name }),
64929
+ (user == null ? void 0 : user.email) && /* @__PURE__ */ jsx(l4, { color: "subtle", children: user.email }),
64930
+ (user == null ? void 0 : user.location) && /* @__PURE__ */ jsx(l4, { color: "subtle", children: user.location })
64931
+ ] })
64932
+ ] }),
64933
+ /* @__PURE__ */ jsx(g0, { collapse: true, children: /* @__PURE__ */ jsx(ee, { title: "Sign Out", icon: "none", onClick: handleSignOut }) })
64934
+ ] });
64935
+ };
64789
64936
  const Theme = ({ api: api2 }) => {
64790
64937
  const [selectedKey, setSelectedKey] = usePluginState(
64791
64938
  api2,
@@ -65040,6 +65187,10 @@ const SettingsScreen = ({ api: api2, isPluginDev }) => {
65040
65187
  title: "Messages",
65041
65188
  key: "messages"
65042
65189
  },
65190
+ {
65191
+ title: "Profile",
65192
+ key: "profile"
65193
+ },
65043
65194
  {
65044
65195
  title: "About",
65045
65196
  key: "about"
@@ -65073,7 +65224,8 @@ const SettingsScreen = ({ api: api2, isPluginDev }) => {
65073
65224
  selectedKey === "theme" && /* @__PURE__ */ jsx(Theme, { api: api2 }),
65074
65225
  selectedKey === "messages" && /* @__PURE__ */ jsx(Messages, { api: api2 }),
65075
65226
  selectedKey === "about" && /* @__PURE__ */ jsx(About, {}),
65076
- selectedKey === "boards" && /* @__PURE__ */ jsx(Boards, { api: api2 })
65227
+ selectedKey === "boards" && /* @__PURE__ */ jsx(Boards, { api: api2 }),
65228
+ selectedKey === "profile" && /* @__PURE__ */ jsx(Profile, { api: api2 })
65077
65229
  ] }),
65078
65230
  /* @__PURE__ */ jsx(a52, { title, noclose: isPluginDev })
65079
65231
  ] });
@@ -104328,7 +104480,7 @@ async function updatePlugins(authToken) {
104328
104480
  {
104329
104481
  key: "base",
104330
104482
  pluginName: "base",
104331
- pluginVersion: "0.46.0",
104483
+ pluginVersion: "0.47.0",
104332
104484
  pluginConfig: []
104333
104485
  }
104334
104486
  ],
@@ -104583,6 +104735,8 @@ export {
104583
104735
  Command,
104584
104736
  CommandGroup$1 as CommandGroup,
104585
104737
  Component,
104738
+ DEK_AUTH_TOKEN_KEY,
104739
+ LoginScreen,
104586
104740
  RouteResolver,
104587
104741
  Router,
104588
104742
  Zone,
package/dist/index.umd.js CHANGED
@@ -64535,6 +64535,115 @@ Arguments: ` + Array.prototype.slice.call(n2).join("") + `
64535
64535
  async function authorize(email, password) {
64536
64536
  return fetchUserToken(email, password);
64537
64537
  }
64538
+ const DEK_AUTH_TOKEN_KEY = "dek_auth_token";
64539
+ const DEK_EMAIL_KEY = "dek_auth_email";
64540
+ const FullScreen = styled.div`
64541
+ position: fixed;
64542
+ inset: 0;
64543
+ background: #1a1a1a;
64544
+ display: flex;
64545
+ align-items: center;
64546
+ justify-content: center;
64547
+ padding-top: 70px;
64548
+ `;
64549
+ const StyledInput = styled.input`
64550
+ width: 100%;
64551
+ height: 56px;
64552
+ background: rgba(255, 255, 255, 0.08);
64553
+ border: 1px solid rgba(255, 255, 255, 0.15);
64554
+ border-radius: 8px;
64555
+ color: #fff;
64556
+ font-family: Heebo, Arial, Helvetica, sans-serif;
64557
+ font-size: 18px;
64558
+ font-weight: 300;
64559
+ padding: 0 16px;
64560
+ box-sizing: border-box;
64561
+ outline: none;
64562
+
64563
+ &::placeholder {
64564
+ color: rgba(255, 255, 255, 0.4);
64565
+ }
64566
+
64567
+ &:focus {
64568
+ border-color: rgba(255, 255, 255, 0.4);
64569
+ background: rgba(255, 255, 255, 0.12);
64570
+ }
64571
+ `;
64572
+ const LoginScreen = ({ onSuccess }) => {
64573
+ const [email, setEmail] = React$3.useState(() => localStorage.getItem(DEK_EMAIL_KEY) || "");
64574
+ const [password, setPassword] = React$3.useState("");
64575
+ const [error2, setError] = React$3.useState("");
64576
+ const [loading, setLoading] = React$3.useState(false);
64577
+ React$3.useEffect(() => {
64578
+ const savedToken = localStorage.getItem(DEK_AUTH_TOKEN_KEY);
64579
+ if (savedToken) {
64580
+ onSuccess(savedToken);
64581
+ }
64582
+ }, []);
64583
+ const handleSubmit = async () => {
64584
+ if (loading)
64585
+ return;
64586
+ setError("");
64587
+ setLoading(true);
64588
+ try {
64589
+ const token2 = await authorize(email, password);
64590
+ localStorage.setItem(DEK_AUTH_TOKEN_KEY, token2);
64591
+ localStorage.setItem(DEK_EMAIL_KEY, email);
64592
+ onSuccess(token2);
64593
+ } catch {
64594
+ localStorage.removeItem(DEK_AUTH_TOKEN_KEY);
64595
+ setError("Invalid email or password.");
64596
+ } finally {
64597
+ setLoading(false);
64598
+ }
64599
+ };
64600
+ const handleKeyDown = (e2) => {
64601
+ if (e2.key === "Enter")
64602
+ handleSubmit();
64603
+ };
64604
+ return /* @__PURE__ */ jsxRuntimeModule.jsxs(FullScreen, { children: [
64605
+ /* @__PURE__ */ jsxRuntimeModule.jsx(Q42, { transitionDelay: 0 }),
64606
+ /* @__PURE__ */ jsxRuntimeModule.jsx(q42, { direction: "vert", valign: "center", halign: "center", children: /* @__PURE__ */ jsxRuntimeModule.jsxs(g0, { direction: "vert", gap: 20, style: { width: 380, paddingTop: 150 }, children: [
64607
+ /* @__PURE__ */ jsxRuntimeModule.jsxs(g0, { direction: "vert", gap: 12, collapse: true, children: [
64608
+ /* @__PURE__ */ jsxRuntimeModule.jsx(
64609
+ StyledInput,
64610
+ {
64611
+ type: "email",
64612
+ placeholder: "Email",
64613
+ value: email,
64614
+ onChange: (e2) => setEmail(e2.target.value),
64615
+ onKeyDown: handleKeyDown,
64616
+ autoComplete: "email",
64617
+ style: { width: 380 }
64618
+ }
64619
+ ),
64620
+ /* @__PURE__ */ jsxRuntimeModule.jsx(
64621
+ StyledInput,
64622
+ {
64623
+ type: "password",
64624
+ placeholder: "Password",
64625
+ value: password,
64626
+ onChange: (e2) => setPassword(e2.target.value),
64627
+ onKeyDown: handleKeyDown,
64628
+ autoComplete: "current-password",
64629
+ style: { width: 380 }
64630
+ }
64631
+ )
64632
+ ] }),
64633
+ error2 && /* @__PURE__ */ jsxRuntimeModule.jsx(g0, { collapse: true, children: /* @__PURE__ */ jsxRuntimeModule.jsx(l4, { color: "#ff6b6b", children: error2 }) }),
64634
+ /* @__PURE__ */ jsxRuntimeModule.jsx(g0, { collapse: true, children: /* @__PURE__ */ jsxRuntimeModule.jsx(
64635
+ ee,
64636
+ {
64637
+ title: loading ? "Signing in..." : "Sign In",
64638
+ icon: "none",
64639
+ width: 380,
64640
+ onClick: handleSubmit
64641
+ }
64642
+ ) })
64643
+ ] }) }),
64644
+ /* @__PURE__ */ jsxRuntimeModule.jsx(a52, { title: "Sign In", noclose: true })
64645
+ ] });
64646
+ };
64538
64647
  const USER_PLUGIN_AND_INTEGRATIONS_QUERY = gql(`
64539
64648
  query userPluginsAndIntegrations {
64540
64649
  currentUser {
@@ -64564,7 +64673,7 @@ Arguments: ` + Array.prototype.slice.call(n2).join("") + `
64564
64673
  result.integrations.unshift({
64565
64674
  key: "base",
64566
64675
  pluginName: "base",
64567
- pluginVersion: "0.46.0",
64676
+ pluginVersion: "0.47.0",
64568
64677
  pluginConfig: []
64569
64678
  });
64570
64679
  return result;
@@ -64633,7 +64742,7 @@ Arguments: ` + Array.prototype.slice.call(n2).join("") + `
64633
64742
  };
64634
64743
  const About = () => {
64635
64744
  return /* @__PURE__ */ jsxRuntimeModule.jsxs(g0, { padding: 20, direction: "vert", children: [
64636
- /* @__PURE__ */ jsxRuntimeModule.jsx(uq1, { children: `Dek ${"0.46.0"}` }),
64745
+ /* @__PURE__ */ jsxRuntimeModule.jsx(uq1, { children: `Dek ${"0.47.0"}` }),
64637
64746
  /* @__PURE__ */ jsxRuntimeModule.jsx(l4, { children: "From Appkit" })
64638
64747
  ] });
64639
64748
  };
@@ -64802,6 +64911,44 @@ Arguments: ` + Array.prototype.slice.call(n2).join("") + `
64802
64911
  ) })
64803
64912
  ] });
64804
64913
  };
64914
+ const Avatar = styled.div`
64915
+ width: 72px;
64916
+ height: 72px;
64917
+ border-radius: 50%;
64918
+ background: ${({ $hasImage }) => $hasImage ? "transparent" : "#1B75D0"};
64919
+ display: flex;
64920
+ align-items: center;
64921
+ justify-content: center;
64922
+ font-size: 28px;
64923
+ font-weight: 500;
64924
+ color: white;
64925
+ flex-shrink: 0;
64926
+ overflow: hidden;
64927
+ `;
64928
+ const AvatarImage = styled.img`
64929
+ width: 100%;
64930
+ height: 100%;
64931
+ object-fit: cover;
64932
+ `;
64933
+ const Profile = (_props) => {
64934
+ const snap = useSnapshot(state$1);
64935
+ const user = snap.data;
64936
+ const initials = (user == null ? void 0 : user.name) ? user.name.split(" ").map((n2) => n2[0]).join("").toUpperCase().slice(0, 2) : "?";
64937
+ const handleSignOut = () => {
64938
+ window.location.href = "/settings/signout";
64939
+ };
64940
+ return /* @__PURE__ */ jsxRuntimeModule.jsxs(g0, { direction: "vert", padding: 20, gap: 24, children: [
64941
+ /* @__PURE__ */ jsxRuntimeModule.jsxs(g0, { direction: "horz", gap: 20, valign: "center", collapse: true, children: [
64942
+ /* @__PURE__ */ jsxRuntimeModule.jsx(Avatar, { $hasImage: !!(user == null ? void 0 : user.avatar), children: (user == null ? void 0 : user.avatar) ? /* @__PURE__ */ jsxRuntimeModule.jsx(AvatarImage, { src: user.avatar, alt: user.name || "" }) : initials }),
64943
+ /* @__PURE__ */ jsxRuntimeModule.jsxs(g0, { direction: "vert", gap: 4, children: [
64944
+ (user == null ? void 0 : user.name) && /* @__PURE__ */ jsxRuntimeModule.jsx(l4, { size: "large", weight: "bold", children: user.name }),
64945
+ (user == null ? void 0 : user.email) && /* @__PURE__ */ jsxRuntimeModule.jsx(l4, { color: "subtle", children: user.email }),
64946
+ (user == null ? void 0 : user.location) && /* @__PURE__ */ jsxRuntimeModule.jsx(l4, { color: "subtle", children: user.location })
64947
+ ] })
64948
+ ] }),
64949
+ /* @__PURE__ */ jsxRuntimeModule.jsx(g0, { collapse: true, children: /* @__PURE__ */ jsxRuntimeModule.jsx(ee, { title: "Sign Out", icon: "none", onClick: handleSignOut }) })
64950
+ ] });
64951
+ };
64805
64952
  const Theme = ({ api: api2 }) => {
64806
64953
  const [selectedKey, setSelectedKey] = usePluginState(
64807
64954
  api2,
@@ -65056,6 +65203,10 @@ Arguments: ` + Array.prototype.slice.call(n2).join("") + `
65056
65203
  title: "Messages",
65057
65204
  key: "messages"
65058
65205
  },
65206
+ {
65207
+ title: "Profile",
65208
+ key: "profile"
65209
+ },
65059
65210
  {
65060
65211
  title: "About",
65061
65212
  key: "about"
@@ -65089,7 +65240,8 @@ Arguments: ` + Array.prototype.slice.call(n2).join("") + `
65089
65240
  selectedKey === "theme" && /* @__PURE__ */ jsxRuntimeModule.jsx(Theme, { api: api2 }),
65090
65241
  selectedKey === "messages" && /* @__PURE__ */ jsxRuntimeModule.jsx(Messages, { api: api2 }),
65091
65242
  selectedKey === "about" && /* @__PURE__ */ jsxRuntimeModule.jsx(About, {}),
65092
- selectedKey === "boards" && /* @__PURE__ */ jsxRuntimeModule.jsx(Boards, { api: api2 })
65243
+ selectedKey === "boards" && /* @__PURE__ */ jsxRuntimeModule.jsx(Boards, { api: api2 }),
65244
+ selectedKey === "profile" && /* @__PURE__ */ jsxRuntimeModule.jsx(Profile, { api: api2 })
65093
65245
  ] }),
65094
65246
  /* @__PURE__ */ jsxRuntimeModule.jsx(a52, { title, noclose: isPluginDev })
65095
65247
  ] });
@@ -104344,7 +104496,7 @@ Arguments: ` + Array.prototype.slice.call(n2).join("") + `
104344
104496
  {
104345
104497
  key: "base",
104346
104498
  pluginName: "base",
104347
- pluginVersion: "0.46.0",
104499
+ pluginVersion: "0.47.0",
104348
104500
  pluginConfig: []
104349
104501
  }
104350
104502
  ],
@@ -104598,6 +104750,8 @@ Arguments: ` + Array.prototype.slice.call(n2).join("") + `
104598
104750
  exports2.Command = Command;
104599
104751
  exports2.CommandGroup = CommandGroup$1;
104600
104752
  exports2.Component = Component;
104753
+ exports2.DEK_AUTH_TOKEN_KEY = DEK_AUTH_TOKEN_KEY;
104754
+ exports2.LoginScreen = LoginScreen;
104601
104755
  exports2.RouteResolver = RouteResolver;
104602
104756
  exports2.Router = Router;
104603
104757
  exports2.Zone = Zone;
@@ -0,0 +1,6 @@
1
+ import { DekApi } from '@appkit/dek-plugin';
2
+ type Props = {
3
+ api: DekApi;
4
+ };
5
+ declare const Profile: (_props: Props) => import("react/jsx-runtime").JSX.Element;
6
+ export default Profile;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@appkit/dek-lib",
3
3
  "private": false,
4
- "version": "0.46.0",
4
+ "version": "0.47.0",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "dev": "vite --port 5173 --host",