tienjs-chartbrew-plugin-strapi 0.1.2 → 0.1.4

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.
@@ -6,8 +6,9 @@ const reactRouterDom = require("react-router-dom");
6
6
  const admin = require("@strapi/strapi/admin");
7
7
  const designSystem = require("@strapi/design-system");
8
8
  const icons = require("@strapi/icons");
9
- const index = require("./index-D2poyYLZ.js");
10
- const store = require("./store-DrVugT1Q.js");
9
+ const index = require("./index-BU939xMZ.js");
10
+ const store = require("./store-D2CP2hEa.js");
11
+ require("js-cookie");
11
12
  async function login() {
12
13
  const { host, token } = await store.getSettings();
13
14
  return fetch(`${host}/user/relog`, {
@@ -147,6 +148,7 @@ function Illo() {
147
148
  ] });
148
149
  }
149
150
  function Dashboard() {
151
+ const iframeRef = react.useRef(null);
150
152
  const [store$1, setStore] = react.useState({});
151
153
  const [user, setUser] = react.useState({});
152
154
  const [projects, setProjects] = react.useState([]);
@@ -170,15 +172,30 @@ function Dashboard() {
170
172
  setDropdownTeam(`${selectedTeam.name}-${selectedTeam.id}`);
171
173
  setProjects(selectedTeam.Projects);
172
174
  if (store$1.defaultProject) {
173
- const selectedProject2 = selectedTeam.Projects.find((p) => p.id === store$1.defaultProject);
175
+ const selectedProject2 = selectedTeam.Projects.find(
176
+ (p) => p.id === store$1.defaultProject
177
+ );
174
178
  if (selectedProject2) {
175
179
  setDropdownProject(`${selectedProject2.name}-${selectedProject2.id}`);
176
180
  setSelectedProject(selectedProject2);
181
+ _sendAuthToken(store$1.token);
177
182
  }
178
183
  }
179
184
  }
180
185
  }
181
186
  }, [teams, store$1, dropdownTeam]);
187
+ const _sendAuthToken = (token) => {
188
+ if (iframeRef.current && iframeRef.current.contentWindow) {
189
+ const targetOrigin = store$1.clientHost;
190
+ iframeRef.current.contentWindow.postMessage(
191
+ {
192
+ type: "AUTH_TOKEN",
193
+ token
194
+ },
195
+ targetOrigin
196
+ );
197
+ }
198
+ };
182
199
  const _init = () => {
183
200
  login().then(async (data) => {
184
201
  setUser(data);
@@ -194,7 +211,9 @@ function Dashboard() {
194
211
  };
195
212
  const _onSelectProject = async (projectValue) => {
196
213
  if (!projectValue) return;
197
- const project = projects.filter((p) => `${p.name}-${p.id}` === projectValue)[0];
214
+ const project = projects.filter(
215
+ (p) => `${p.name}-${p.id}` === projectValue
216
+ )[0];
198
217
  setSelectedProject(project);
199
218
  setDropdownProject(`${project.name}-${project.id}`);
200
219
  store.setSettings({ defaultProject: project.id }).then(() => {
@@ -203,7 +222,9 @@ function Dashboard() {
203
222
  };
204
223
  const _onSelectTeam = (teamValue) => {
205
224
  if (!teamValue) return;
206
- const selectedTeam = teams.filter((t) => `${t.name}-${t.id}` === teamValue)[0];
225
+ const selectedTeam = teams.filter(
226
+ (t) => `${t.name}-${t.id}` === teamValue
227
+ )[0];
207
228
  setTeam(selectedTeam);
208
229
  setDropdownTeam(`${selectedTeam.name}-${selectedTeam.id}`);
209
230
  setDropdownProject("");
@@ -218,7 +239,16 @@ function Dashboard() {
218
239
  {
219
240
  title: "Dashboard",
220
241
  subtitle: "Visualize your Strapi data",
221
- primaryAction: /* @__PURE__ */ jsxRuntime.jsx(designSystem.LinkButton, { tag: reactRouterDom.Link, startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.ChartCircle, {}), to: `/plugins/${index.PLUGIN_ID}/create`, disabled: !user.id, children: "Create new visualizations" })
242
+ primaryAction: /* @__PURE__ */ jsxRuntime.jsx(
243
+ designSystem.LinkButton,
244
+ {
245
+ tag: reactRouterDom.Link,
246
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.ChartCircle, {}),
247
+ to: `/plugins/${index.PLUGIN_ID}/create`,
248
+ disabled: !user.id,
249
+ children: "Create new visualizations"
250
+ }
251
+ )
222
252
  }
223
253
  ),
224
254
  /* @__PURE__ */ jsxRuntime.jsxs(admin.Layouts.Content, { children: [
@@ -258,7 +288,15 @@ function Dashboard() {
258
288
  {
259
289
  icon: /* @__PURE__ */ jsxRuntime.jsx(Illo, {}),
260
290
  content: "It looks like you don't have a dashboard yet",
261
- action: /* @__PURE__ */ jsxRuntime.jsx(designSystem.LinkButton, { variant: "secondary", startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}), to: `/plugins/${index.PLUGIN_ID}/create`, children: "Create your first dashboard" })
291
+ action: /* @__PURE__ */ jsxRuntime.jsx(
292
+ designSystem.LinkButton,
293
+ {
294
+ variant: "secondary",
295
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
296
+ to: `/plugins/${index.PLUGIN_ID}/create`,
297
+ children: "Create your first dashboard"
298
+ }
299
+ )
262
300
  }
263
301
  ) }),
264
302
  !pageLoading && authError && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, shadow: "filterShadow", background: "neutral0", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 4, children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -279,7 +317,14 @@ function Dashboard() {
279
317
  value: dropdownTeam,
280
318
  onChange: _onSelectTeam,
281
319
  children: teams.map((t) => {
282
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: `${t.name}-${t.id}`, children: t.name }, t.id);
320
+ return /* @__PURE__ */ jsxRuntime.jsx(
321
+ designSystem.SingleSelectOption,
322
+ {
323
+ value: `${t.name}-${t.id}`,
324
+ children: t.name
325
+ },
326
+ t.id
327
+ );
283
328
  })
284
329
  }
285
330
  ) }),
@@ -291,13 +336,34 @@ function Dashboard() {
291
336
  value: dropdownProject,
292
337
  onChange: _onSelectProject,
293
338
  children: projects.map((p) => {
294
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: `${p.name}-${p.id}`, children: p.name }, p.id);
339
+ return /* @__PURE__ */ jsxRuntime.jsx(
340
+ designSystem.SingleSelectOption,
341
+ {
342
+ value: `${p.name}-${p.id}`,
343
+ children: p.name
344
+ },
345
+ p.id
346
+ );
295
347
  })
296
348
  }
297
349
  ) }),
298
350
  selectedProject && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
299
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { paddingLeft: 4, onCheckedChange: () => setRemoveHeader(!removeHeader), children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: "Remove header" }) }),
300
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { paddingLeft: 4, onCheckedChange: () => setRemoveStyling(!removeStyling), children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: "Remove styling" }) })
351
+ /* @__PURE__ */ jsxRuntime.jsx(
352
+ designSystem.Checkbox,
353
+ {
354
+ paddingLeft: 4,
355
+ onCheckedChange: () => setRemoveHeader(!removeHeader),
356
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: "Remove header" })
357
+ }
358
+ ),
359
+ /* @__PURE__ */ jsxRuntime.jsx(
360
+ designSystem.Checkbox,
361
+ {
362
+ paddingLeft: 4,
363
+ onCheckedChange: () => setRemoveStyling(!removeStyling),
364
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: "Remove styling" })
365
+ }
366
+ )
301
367
  ] }),
302
368
  team && /* @__PURE__ */ jsxRuntime.jsx(
303
369
  designSystem.LinkButton,
@@ -314,6 +380,7 @@ function Dashboard() {
314
380
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 4, height: "100vh", children: /* @__PURE__ */ jsxRuntime.jsx(
315
381
  "iframe",
316
382
  {
383
+ ref: iframeRef,
317
384
  src: `${store$1.clientHost}/report/${selectedProject.brewName}?removeHeader=${removeHeader}&removeStyling=${removeStyling}`,
318
385
  width: "100%",
319
386
  height: "100%",
@@ -1,11 +1,12 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { useState, useEffect } from "react";
2
+ import { useRef, useState, useEffect } from "react";
3
3
  import { Link, Routes, Route } from "react-router-dom";
4
4
  import { Layouts, Page } from "@strapi/strapi/admin";
5
5
  import { LinkButton, Loader, Box, Flex, Typography, SingleSelect, SingleSelectOption, EmptyStateLayout, Alert, Link as Link$1, Checkbox, Grid, Button, Divider, Combobox, ComboboxOption } from "@strapi/design-system";
6
6
  import { ChartCircle, Plus, ExternalLink, ArrowLeft } from "@strapi/icons";
7
- import { P as PLUGIN_ID } from "./index-Cjgwr2aI.mjs";
8
- import { g as getSettings, s as setSettings, i as instance } from "./store-CDGc86NS.mjs";
7
+ import { P as PLUGIN_ID } from "./index-Ob7hTXVE.mjs";
8
+ import { g as getSettings, s as setSettings, i as instance } from "./store-BD7p4pKs.mjs";
9
+ import "js-cookie";
9
10
  async function login() {
10
11
  const { host, token } = await getSettings();
11
12
  return fetch(`${host}/user/relog`, {
@@ -145,6 +146,7 @@ function Illo() {
145
146
  ] });
146
147
  }
147
148
  function Dashboard() {
149
+ const iframeRef = useRef(null);
148
150
  const [store, setStore] = useState({});
149
151
  const [user, setUser] = useState({});
150
152
  const [projects, setProjects] = useState([]);
@@ -168,15 +170,30 @@ function Dashboard() {
168
170
  setDropdownTeam(`${selectedTeam.name}-${selectedTeam.id}`);
169
171
  setProjects(selectedTeam.Projects);
170
172
  if (store.defaultProject) {
171
- const selectedProject2 = selectedTeam.Projects.find((p) => p.id === store.defaultProject);
173
+ const selectedProject2 = selectedTeam.Projects.find(
174
+ (p) => p.id === store.defaultProject
175
+ );
172
176
  if (selectedProject2) {
173
177
  setDropdownProject(`${selectedProject2.name}-${selectedProject2.id}`);
174
178
  setSelectedProject(selectedProject2);
179
+ _sendAuthToken(store.token);
175
180
  }
176
181
  }
177
182
  }
178
183
  }
179
184
  }, [teams, store, dropdownTeam]);
185
+ const _sendAuthToken = (token) => {
186
+ if (iframeRef.current && iframeRef.current.contentWindow) {
187
+ const targetOrigin = store.clientHost;
188
+ iframeRef.current.contentWindow.postMessage(
189
+ {
190
+ type: "AUTH_TOKEN",
191
+ token
192
+ },
193
+ targetOrigin
194
+ );
195
+ }
196
+ };
180
197
  const _init = () => {
181
198
  login().then(async (data) => {
182
199
  setUser(data);
@@ -192,7 +209,9 @@ function Dashboard() {
192
209
  };
193
210
  const _onSelectProject = async (projectValue) => {
194
211
  if (!projectValue) return;
195
- const project = projects.filter((p) => `${p.name}-${p.id}` === projectValue)[0];
212
+ const project = projects.filter(
213
+ (p) => `${p.name}-${p.id}` === projectValue
214
+ )[0];
196
215
  setSelectedProject(project);
197
216
  setDropdownProject(`${project.name}-${project.id}`);
198
217
  setSettings({ defaultProject: project.id }).then(() => {
@@ -201,7 +220,9 @@ function Dashboard() {
201
220
  };
202
221
  const _onSelectTeam = (teamValue) => {
203
222
  if (!teamValue) return;
204
- const selectedTeam = teams.filter((t) => `${t.name}-${t.id}` === teamValue)[0];
223
+ const selectedTeam = teams.filter(
224
+ (t) => `${t.name}-${t.id}` === teamValue
225
+ )[0];
205
226
  setTeam(selectedTeam);
206
227
  setDropdownTeam(`${selectedTeam.name}-${selectedTeam.id}`);
207
228
  setDropdownProject("");
@@ -216,7 +237,16 @@ function Dashboard() {
216
237
  {
217
238
  title: "Dashboard",
218
239
  subtitle: "Visualize your Strapi data",
219
- primaryAction: /* @__PURE__ */ jsx(LinkButton, { tag: Link, startIcon: /* @__PURE__ */ jsx(ChartCircle, {}), to: `/plugins/${PLUGIN_ID}/create`, disabled: !user.id, children: "Create new visualizations" })
240
+ primaryAction: /* @__PURE__ */ jsx(
241
+ LinkButton,
242
+ {
243
+ tag: Link,
244
+ startIcon: /* @__PURE__ */ jsx(ChartCircle, {}),
245
+ to: `/plugins/${PLUGIN_ID}/create`,
246
+ disabled: !user.id,
247
+ children: "Create new visualizations"
248
+ }
249
+ )
220
250
  }
221
251
  ),
222
252
  /* @__PURE__ */ jsxs(Layouts.Content, { children: [
@@ -256,7 +286,15 @@ function Dashboard() {
256
286
  {
257
287
  icon: /* @__PURE__ */ jsx(Illo, {}),
258
288
  content: "It looks like you don't have a dashboard yet",
259
- action: /* @__PURE__ */ jsx(LinkButton, { variant: "secondary", startIcon: /* @__PURE__ */ jsx(Plus, {}), to: `/plugins/${PLUGIN_ID}/create`, children: "Create your first dashboard" })
289
+ action: /* @__PURE__ */ jsx(
290
+ LinkButton,
291
+ {
292
+ variant: "secondary",
293
+ startIcon: /* @__PURE__ */ jsx(Plus, {}),
294
+ to: `/plugins/${PLUGIN_ID}/create`,
295
+ children: "Create your first dashboard"
296
+ }
297
+ )
260
298
  }
261
299
  ) }),
262
300
  !pageLoading && authError && /* @__PURE__ */ jsx(Box, { padding: 4, shadow: "filterShadow", background: "neutral0", children: /* @__PURE__ */ jsx(Box, { paddingTop: 4, children: /* @__PURE__ */ jsx(
@@ -277,7 +315,14 @@ function Dashboard() {
277
315
  value: dropdownTeam,
278
316
  onChange: _onSelectTeam,
279
317
  children: teams.map((t) => {
280
- return /* @__PURE__ */ jsx(SingleSelectOption, { value: `${t.name}-${t.id}`, children: t.name }, t.id);
318
+ return /* @__PURE__ */ jsx(
319
+ SingleSelectOption,
320
+ {
321
+ value: `${t.name}-${t.id}`,
322
+ children: t.name
323
+ },
324
+ t.id
325
+ );
281
326
  })
282
327
  }
283
328
  ) }),
@@ -289,13 +334,34 @@ function Dashboard() {
289
334
  value: dropdownProject,
290
335
  onChange: _onSelectProject,
291
336
  children: projects.map((p) => {
292
- return /* @__PURE__ */ jsx(SingleSelectOption, { value: `${p.name}-${p.id}`, children: p.name }, p.id);
337
+ return /* @__PURE__ */ jsx(
338
+ SingleSelectOption,
339
+ {
340
+ value: `${p.name}-${p.id}`,
341
+ children: p.name
342
+ },
343
+ p.id
344
+ );
293
345
  })
294
346
  }
295
347
  ) }),
296
348
  selectedProject && /* @__PURE__ */ jsxs(Fragment, { children: [
297
- /* @__PURE__ */ jsx(Checkbox, { paddingLeft: 4, onCheckedChange: () => setRemoveHeader(!removeHeader), children: /* @__PURE__ */ jsx(Typography, { variant: "delta", children: "Remove header" }) }),
298
- /* @__PURE__ */ jsx(Checkbox, { paddingLeft: 4, onCheckedChange: () => setRemoveStyling(!removeStyling), children: /* @__PURE__ */ jsx(Typography, { variant: "delta", children: "Remove styling" }) })
349
+ /* @__PURE__ */ jsx(
350
+ Checkbox,
351
+ {
352
+ paddingLeft: 4,
353
+ onCheckedChange: () => setRemoveHeader(!removeHeader),
354
+ children: /* @__PURE__ */ jsx(Typography, { variant: "delta", children: "Remove header" })
355
+ }
356
+ ),
357
+ /* @__PURE__ */ jsx(
358
+ Checkbox,
359
+ {
360
+ paddingLeft: 4,
361
+ onCheckedChange: () => setRemoveStyling(!removeStyling),
362
+ children: /* @__PURE__ */ jsx(Typography, { variant: "delta", children: "Remove styling" })
363
+ }
364
+ )
299
365
  ] }),
300
366
  team && /* @__PURE__ */ jsx(
301
367
  LinkButton,
@@ -312,6 +378,7 @@ function Dashboard() {
312
378
  /* @__PURE__ */ jsx(Box, { paddingTop: 4, height: "100vh", children: /* @__PURE__ */ jsx(
313
379
  "iframe",
314
380
  {
381
+ ref: iframeRef,
315
382
  src: `${store.clientHost}/report/${selectedProject.brewName}?removeHeader=${removeHeader}&removeStyling=${removeStyling}`,
316
383
  width: "100%",
317
384
  height: "100%",
@@ -4,8 +4,8 @@ import { LinkButton, Box, Typography, Tabs, Field, Button, Link, Flex, Alert } f
4
4
  import { useNotification, Layouts } from "@strapi/strapi/admin";
5
5
  import { ExternalLink, Magic, Check, Cross, ChevronRight } from "@strapi/icons";
6
6
  import { Link as Link$1 } from "react-router-dom";
7
- import { P as PLUGIN_ID } from "./index-Cjgwr2aI.mjs";
8
- import { g as getSettings, s as setSettings } from "./store-CDGc86NS.mjs";
7
+ import { P as PLUGIN_ID } from "./index-Ob7hTXVE.mjs";
8
+ import { g as getSettings, s as setSettings } from "./store-BD7p4pKs.mjs";
9
9
  const defaultHost = "https://api.chartbrew.com";
10
10
  const defaultClientHost = "https://app.chartbrew.com";
11
11
  const strapiHostEnv = process.env.STRAPI_ADMIN_BACKEND_URL;
@@ -6,8 +6,8 @@ const designSystem = require("@strapi/design-system");
6
6
  const admin = require("@strapi/strapi/admin");
7
7
  const icons = require("@strapi/icons");
8
8
  const reactRouterDom = require("react-router-dom");
9
- const index = require("./index-D2poyYLZ.js");
10
- const store = require("./store-DrVugT1Q.js");
9
+ const index = require("./index-BU939xMZ.js");
10
+ const store = require("./store-D2CP2hEa.js");
11
11
  const defaultHost = "https://api.chartbrew.com";
12
12
  const defaultClientHost = "https://app.chartbrew.com";
13
13
  const strapiHostEnv = process.env.STRAPI_ADMIN_BACKEND_URL;
@@ -38,7 +38,7 @@ const index = {
38
38
  defaultMessage: "Chartbrew"
39
39
  },
40
40
  Component: async () => {
41
- const { App } = await Promise.resolve().then(() => require("./App-Dqp66kas.js"));
41
+ const { App } = await Promise.resolve().then(() => require("./App-DYsrUWaq.js"));
42
42
  return App;
43
43
  }
44
44
  });
@@ -59,7 +59,7 @@ const index = {
59
59
  id: "settings",
60
60
  to: `/settings/${PLUGIN_ID}`,
61
61
  Component: async () => {
62
- const { Setup } = await Promise.resolve().then(() => require("./Setup-D_mIow3G.js"));
62
+ const { Setup } = await Promise.resolve().then(() => require("./Setup-BCxwweFO.js"));
63
63
  return Setup;
64
64
  }
65
65
  }
@@ -37,7 +37,7 @@ const index = {
37
37
  defaultMessage: "Chartbrew"
38
38
  },
39
39
  Component: async () => {
40
- const { App } = await import("./App-BCYezLLX.mjs");
40
+ const { App } = await import("./App-MJAOBwBX.mjs");
41
41
  return App;
42
42
  }
43
43
  });
@@ -58,7 +58,7 @@ const index = {
58
58
  id: "settings",
59
59
  to: `/settings/${PLUGIN_ID}`,
60
60
  Component: async () => {
61
- const { Setup } = await import("./Setup-CFHScO45.mjs");
61
+ const { Setup } = await import("./Setup-BBCrCEZR.mjs");
62
62
  return Setup;
63
63
  }
64
64
  }
@@ -1,5 +1,5 @@
1
1
  import Cookies from "js-cookie";
2
- import { P as PLUGIN_ID } from "./index-Cjgwr2aI.mjs";
2
+ import { P as PLUGIN_ID } from "./index-Ob7hTXVE.mjs";
3
3
  function bind(fn, thisArg) {
4
4
  return function wrap() {
5
5
  return fn.apply(thisArg, arguments);
@@ -2496,6 +2496,11 @@ instance.interceptors.response.use(
2496
2496
  );
2497
2497
  async function getSettings() {
2498
2498
  const settings = await instance.get(`/${PLUGIN_ID}/settings`);
2499
+ const token = settings.data.token;
2500
+ Cookies.set("brewToken", token, {
2501
+ sameSite: "None",
2502
+ secure: true
2503
+ });
2499
2504
  return settings.data;
2500
2505
  }
2501
2506
  async function setSettings(data) {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  const Cookies = require("js-cookie");
3
- const index = require("./index-D2poyYLZ.js");
3
+ const index = require("./index-BU939xMZ.js");
4
4
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
5
5
  const Cookies__default = /* @__PURE__ */ _interopDefault(Cookies);
6
6
  function bind(fn, thisArg) {
@@ -2499,6 +2499,11 @@ instance.interceptors.response.use(
2499
2499
  );
2500
2500
  async function getSettings() {
2501
2501
  const settings = await instance.get(`/${index.PLUGIN_ID}/settings`);
2502
+ const token = settings.data.token;
2503
+ Cookies__default.default.set("brewToken", token, {
2504
+ sameSite: "None",
2505
+ secure: true
2506
+ });
2502
2507
  return settings.data;
2503
2508
  }
2504
2509
  async function setSettings(data) {
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-D2poyYLZ.js");
2
+ const index = require("../_chunks/index-BU939xMZ.js");
3
3
  module.exports = index.index;
@@ -1,4 +1,4 @@
1
- import { i } from "../_chunks/index-Cjgwr2aI.mjs";
1
+ import { i } from "../_chunks/index-Ob7hTXVE.mjs";
2
2
  export {
3
3
  i as default
4
4
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tienjs-chartbrew-plugin-strapi",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Chartbrew brings data visualization to your Strapi dashboard",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/chartbrew/strapi-plugin-chartbrew#readme",