From e19bd0a7ca81469c8a1a5d8a52565fac5a41dd4a Mon Sep 17 00:00:00 2001
From: Shahriar <31452340+ShahriarKh@users.noreply.github.com>
Date: Fri, 14 Jul 2023 02:44:38 +0330
Subject: [PATCH] Add files via upload
---
content-type-explorer/README.md | 3 +
.../admin/src/api/explorer-api.js | 11 ++
.../admin/src/components/CustomNode.css | 35 ++++
.../admin/src/components/CustomNode.js | 116 ++++++++++++
.../admin/src/components/Initializer/index.js | 26 +++
.../admin/src/components/OptionsBar.js | 110 +++++++++++
.../admin/src/components/PluginIcon/index.js | 12 ++
.../admin/src/components/RelationIndicator.js | 21 +++
content-type-explorer/admin/src/index.js | 65 +++++++
.../admin/src/pages/App/index.js | 25 +++
.../admin/src/pages/HomePage/index.js | 175 ++++++++++++++++++
.../admin/src/pages/HomePage/styles.css | 12 ++
content-type-explorer/admin/src/pluginId.js | 5 +
.../admin/src/translations/en.json | 1 +
.../admin/src/translations/fr.json | 1 +
.../admin/src/utils/dataUtils.js | 54 ++++++
.../admin/src/utils/getTrad.js | 5 +
.../admin/src/utils/themeUtils.js | 86 +++++++++
content-type-explorer/package.json | 42 +++++
content-type-explorer/server/bootstrap.js | 5 +
content-type-explorer/server/config/index.js | 6 +
.../server/content-types/index.js | 3 +
.../server/controllers/explorer-controller.js | 20 ++
.../server/controllers/index.js | 7 +
content-type-explorer/server/destroy.js | 5 +
content-type-explorer/server/index.js | 25 +++
.../server/middlewares/index.js | 3 +
.../server/policies/index.js | 3 +
content-type-explorer/server/register.js | 5 +
content-type-explorer/server/routes/index.js | 10 +
.../server/services/explorer-service.js | 7 +
.../server/services/index.js | 7 +
content-type-explorer/strapi-admin.js | 3 +
content-type-explorer/strapi-server.js | 3 +
34 files changed, 917 insertions(+)
create mode 100644 content-type-explorer/README.md
create mode 100644 content-type-explorer/admin/src/api/explorer-api.js
create mode 100644 content-type-explorer/admin/src/components/CustomNode.css
create mode 100644 content-type-explorer/admin/src/components/CustomNode.js
create mode 100644 content-type-explorer/admin/src/components/Initializer/index.js
create mode 100644 content-type-explorer/admin/src/components/OptionsBar.js
create mode 100644 content-type-explorer/admin/src/components/PluginIcon/index.js
create mode 100644 content-type-explorer/admin/src/components/RelationIndicator.js
create mode 100644 content-type-explorer/admin/src/index.js
create mode 100644 content-type-explorer/admin/src/pages/App/index.js
create mode 100644 content-type-explorer/admin/src/pages/HomePage/index.js
create mode 100644 content-type-explorer/admin/src/pages/HomePage/styles.css
create mode 100644 content-type-explorer/admin/src/pluginId.js
create mode 100644 content-type-explorer/admin/src/translations/en.json
create mode 100644 content-type-explorer/admin/src/translations/fr.json
create mode 100644 content-type-explorer/admin/src/utils/dataUtils.js
create mode 100644 content-type-explorer/admin/src/utils/getTrad.js
create mode 100644 content-type-explorer/admin/src/utils/themeUtils.js
create mode 100644 content-type-explorer/package.json
create mode 100644 content-type-explorer/server/bootstrap.js
create mode 100644 content-type-explorer/server/config/index.js
create mode 100644 content-type-explorer/server/content-types/index.js
create mode 100644 content-type-explorer/server/controllers/explorer-controller.js
create mode 100644 content-type-explorer/server/controllers/index.js
create mode 100644 content-type-explorer/server/destroy.js
create mode 100644 content-type-explorer/server/index.js
create mode 100644 content-type-explorer/server/middlewares/index.js
create mode 100644 content-type-explorer/server/policies/index.js
create mode 100644 content-type-explorer/server/register.js
create mode 100644 content-type-explorer/server/routes/index.js
create mode 100644 content-type-explorer/server/services/explorer-service.js
create mode 100644 content-type-explorer/server/services/index.js
create mode 100644 content-type-explorer/strapi-admin.js
create mode 100644 content-type-explorer/strapi-server.js
diff --git a/content-type-explorer/README.md b/content-type-explorer/README.md
new file mode 100644
index 0000000..406287a
--- /dev/null
+++ b/content-type-explorer/README.md
@@ -0,0 +1,3 @@
+# Strapi plugin content-type-explorer
+
+A quick description of content-type-explorer.
diff --git a/content-type-explorer/admin/src/api/explorer-api.js b/content-type-explorer/admin/src/api/explorer-api.js
new file mode 100644
index 0000000..60bed31
--- /dev/null
+++ b/content-type-explorer/admin/src/api/explorer-api.js
@@ -0,0 +1,11 @@
+import { request } from "@strapi/helper-plugin";
+
+const explorerRequests = {
+ getContentTypes: async () => {
+ return await request("/content-type-explorer/get-content-types", {
+ method: "GET",
+ });
+ },
+};
+
+export default explorerRequests;
diff --git a/content-type-explorer/admin/src/components/CustomNode.css b/content-type-explorer/admin/src/components/CustomNode.css
new file mode 100644
index 0000000..708a5fc
--- /dev/null
+++ b/content-type-explorer/admin/src/components/CustomNode.css
@@ -0,0 +1,35 @@
+.cte-plugin-box {
+ position: relative;
+ min-width: 280px;
+}
+
+.cte-plugin-header {
+ user-select: text;
+ cursor: auto;
+}
+
+.cte-plugin-line {
+ margin-right: auto;
+ padding-right: 12px; /*minimum gap*/
+ margin-top: -2px;
+ user-select: text;
+ cursor: auto;
+}
+
+.cte-plugin-handle {
+ position: absolute;
+ right: -27px;
+ top: 6px;
+ bottom: 0;
+ margin: auto;
+ visibility: hidden;
+ position: absolute;
+ padding: 0;
+}
+
+.cte-plugin-field {
+ display: flex;
+ align-items: center;
+ margin-bottom: 6px;
+ position: relative;
+}
diff --git a/content-type-explorer/admin/src/components/CustomNode.js b/content-type-explorer/admin/src/components/CustomNode.js
new file mode 100644
index 0000000..12fc021
--- /dev/null
+++ b/content-type-explorer/admin/src/components/CustomNode.js
@@ -0,0 +1,116 @@
+/**
+ *
+ * PluginIcon
+ *
+ */
+
+import React from "react";
+import {
+ Badge,
+ Box,
+ Divider,
+ Tooltip,
+ Typography,
+} from "@strapi/design-system";
+import { useTheme } from "styled-components";
+import { Handle } from "reactflow";
+import { RelationIndicator } from "./RelationIndicator";
+import { getIcon } from "../utils/themeUtils";
+import "./CustomNode.css";
+
+export default function CustomNode({ data }) {
+ let attributesToShow = Object.entries(data.attributes);
+
+ if (data.options.showRelationsOnly) {
+ attributesToShow = attributesToShow.filter((x) => x[1].type === "relation");
+ }
+
+ if (!data.options.showDefaultFields) {
+ attributesToShow = attributesToShow.filter(
+ (x) =>
+ !(
+ x[0] === "updatedAt" ||
+ x[0] === "createdAt" ||
+ x[0] === "updatedBy" ||
+ x[0] === "createdBy" ||
+ x[0] === "publishedAt"
+ )
+ );
+ }
+
+ const theme = useTheme();
+ return (
+
+
+ {data.info.displayName}
+
+
+
+
+ {data.key}
+
+
+
+
+
+ {attributesToShow.map((attr) => {
+ return (
+
+
+
{attr[0]}
+
+ {data.options.showTypes && (
+
+ {attr[1].type}
+
+ )}
+
+ {data.options.showIcons && getIcon(attr[1].type)}
+ {attr[1].type === "relation" && (
+ <>
+
+
+ {getIcon(attr[1].relation)}
+
+
+
+ >
+ )}
+
+
+ );
+ })}
+
+ );
+}
diff --git a/content-type-explorer/admin/src/components/Initializer/index.js b/content-type-explorer/admin/src/components/Initializer/index.js
new file mode 100644
index 0000000..71dc50e
--- /dev/null
+++ b/content-type-explorer/admin/src/components/Initializer/index.js
@@ -0,0 +1,26 @@
+/**
+ *
+ * Initializer
+ *
+ */
+
+import { useEffect, useRef } from 'react';
+import PropTypes from 'prop-types';
+import pluginId from '../../pluginId';
+
+const Initializer = ({ setPlugin }) => {
+ const ref = useRef();
+ ref.current = setPlugin;
+
+ useEffect(() => {
+ ref.current(pluginId);
+ }, []);
+
+ return null;
+};
+
+Initializer.propTypes = {
+ setPlugin: PropTypes.func.isRequired,
+};
+
+export default Initializer;
diff --git a/content-type-explorer/admin/src/components/OptionsBar.js b/content-type-explorer/admin/src/components/OptionsBar.js
new file mode 100644
index 0000000..0ffa0bd
--- /dev/null
+++ b/content-type-explorer/admin/src/components/OptionsBar.js
@@ -0,0 +1,110 @@
+import {
+ Checkbox,
+ SingleSelect,
+ SingleSelectOption,
+} from "@strapi/design-system";
+import React from "react";
+
+export default function OptionsBar({ options, toggleOption }) {
+ return (
+
+
{
+ toggleOption("showTypes");
+ }}
+ value={options.showTypes}
+ >
+ Fields Data Types
+
+
toggleOption("showIcons")}
+ value={options.showIcons}
+ >
+ Fields Icons
+
+
toggleOption("showDefaultFields")}
+ value={options.showDefaultFields}
+ >
+ Default Fields
+
+
toggleOption("showRelationsOnly")}
+ value={options.showRelationsOnly}
+ >
+ Relational Fields Only
+
+
toggleOption("showAdminTypes")}
+ value={options.showAdminTypes}
+ >
+ admin:: Types
+
+
toggleOption("showPluginTypes")}
+ value={options.showPluginTypes}
+ >
+ plugin:: Types
+
+
toggleOption("showEdges")}
+ value={options.showEdges}
+ >
+ Edges
+
+
toggleOption("snapToGrid")}
+ value={options.snapToGrid}
+ >
+ Snap To Grid
+
+
+
toggleOption("edgeType", type)}
+ >
+
+ Smart Bezier
+
+
+ Smart Straight
+
+ Smart Step
+ Bezier
+
+ Simple Bezier
+
+ Straight
+ Step
+ Smooth Step
+
+
toggleOption("backgroundPattern", pattern)}
+ >
+ Dots
+ Lines
+ Cross
+ None
+
+
+ );
+}
diff --git a/content-type-explorer/admin/src/components/PluginIcon/index.js b/content-type-explorer/admin/src/components/PluginIcon/index.js
new file mode 100644
index 0000000..f4787d7
--- /dev/null
+++ b/content-type-explorer/admin/src/components/PluginIcon/index.js
@@ -0,0 +1,12 @@
+/**
+ *
+ * PluginIcon
+ *
+ */
+
+import React from "react";
+import { OneToMany } from "@strapi/icons";
+
+const PluginIcon = () => ;
+
+export default PluginIcon;
diff --git a/content-type-explorer/admin/src/components/RelationIndicator.js b/content-type-explorer/admin/src/components/RelationIndicator.js
new file mode 100644
index 0000000..d47725a
--- /dev/null
+++ b/content-type-explorer/admin/src/components/RelationIndicator.js
@@ -0,0 +1,21 @@
+import styled from "styled-components";
+
+export const RelationIndicator = styled.span`
+ height: 20px;
+ width: 20px;
+ font-size: 12px;
+ border-radius: 4px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background: ${(props) => props.theme.colors.neutral0};
+ position: absolute;
+ right: -32px;
+ top: 0;
+ bottom: 0;
+ margin: auto;
+
+ svg path {
+ fill: ${(props) => props.theme.colors.buttonPrimary500};
+ }
+`;
diff --git a/content-type-explorer/admin/src/index.js b/content-type-explorer/admin/src/index.js
new file mode 100644
index 0000000..ddd5492
--- /dev/null
+++ b/content-type-explorer/admin/src/index.js
@@ -0,0 +1,65 @@
+import { prefixPluginTranslations } from "@strapi/helper-plugin";
+import pluginPkg from "../../package.json";
+import pluginId from "./pluginId";
+import Initializer from "./components/Initializer";
+import PluginIcon from "./components/PluginIcon";
+
+const name = pluginPkg.strapi.name;
+
+export default {
+ register(app) {
+ app.addMenuLink({
+ to: `/plugins/${pluginId}`,
+ icon: PluginIcon,
+ intlLabel: {
+ id: `${pluginId}.plugin.name`,
+ defaultMessage: "Content-Type Explorer",
+ },
+ Component: async () => {
+ const component = await import(
+ /* webpackChunkName: "[request]" */ "./pages/App"
+ );
+
+ return component;
+ },
+ permissions: [
+ // Uncomment to set the permissions of the plugin here
+ // {
+ // action: '', // the action name should be plugin::plugin-name.actionType
+ // subject: null,
+ // },
+ ],
+ });
+ app.registerPlugin({
+ id: pluginId,
+ initializer: Initializer,
+ isReady: false,
+ name,
+ });
+ },
+
+ bootstrap(app) {},
+ async registerTrads({ locales }) {
+ const importedTrads = await Promise.all(
+ locales.map((locale) => {
+ return import(
+ /* webpackChunkName: "translation-[request]" */ `./translations/${locale}.json`
+ )
+ .then(({ default: data }) => {
+ return {
+ data: prefixPluginTranslations(data, pluginId),
+ locale,
+ };
+ })
+ .catch(() => {
+ return {
+ data: {},
+ locale,
+ };
+ });
+ })
+ );
+
+ return Promise.resolve(importedTrads);
+ },
+};
diff --git a/content-type-explorer/admin/src/pages/App/index.js b/content-type-explorer/admin/src/pages/App/index.js
new file mode 100644
index 0000000..c87a263
--- /dev/null
+++ b/content-type-explorer/admin/src/pages/App/index.js
@@ -0,0 +1,25 @@
+/**
+ *
+ * This component is the skeleton around the actual pages, and should only
+ * contain code that should be seen on all pages. (e.g. navigation bar)
+ *
+ */
+
+import React from 'react';
+import { Switch, Route } from 'react-router-dom';
+import { AnErrorOccurred } from '@strapi/helper-plugin';
+import pluginId from '../../pluginId';
+import HomePage from '../HomePage';
+
+const App = () => {
+ return (
+
+
+
+
+
+
+ );
+};
+
+export default App;
diff --git a/content-type-explorer/admin/src/pages/HomePage/index.js b/content-type-explorer/admin/src/pages/HomePage/index.js
new file mode 100644
index 0000000..676a211
--- /dev/null
+++ b/content-type-explorer/admin/src/pages/HomePage/index.js
@@ -0,0 +1,175 @@
+/*
+ *
+ * HomePage
+ *
+ */
+
+import React, { useCallback, useEffect, useMemo, useState } from "react";
+import { Button, HeaderLayout, Icon, LinkButton } from "@strapi/design-system";
+import explorerRequests from "../../api/explorer-api";
+import { Question, Search, Drag } from "@strapi/icons";
+import { useTheme } from "styled-components";
+import {
+ SmartBezierEdge,
+ SmartStepEdge,
+ SmartStraightEdge,
+} from "@tisoap/react-flow-smart-edge";
+import CustomNode from "../../components/CustomNode";
+import { createEdegs, createNodes } from "../../utils/dataUtils";
+import {
+ Background,
+ ControlButton,
+ Controls,
+ ReactFlow,
+ useEdgesState,
+ useNodesState,
+} from "reactflow";
+import { getBackgroundColor } from "../../utils/themeUtils";
+import "reactflow/dist/style.css";
+import OptionsBar from "../../components/OptionsBar";
+import "./styles.css";
+
+const HomePage = () => {
+ const theme = useTheme();
+
+ const [contentTypes, setContentTypes] = useState([]);
+
+ const [options, setOptions] = useState({
+ snapToGrid: false,
+ showTypes: true,
+ showIcons: true,
+ showRelationsOnly: false,
+ showAdminTypes: false,
+ showDefaultFields: false,
+ showPluginTypes: false,
+ showEdges: false,
+ scrollMode: true,
+ edgeType: "smartbezier",
+ backgroundPattern: "dots",
+ });
+
+ function toggleOption(optionName, optionValue = null) {
+ setOptions({
+ ...options,
+ [optionName]: optionValue || !options[optionName],
+ });
+ }
+
+ const nodeTypes = useMemo(() => ({ special: CustomNode }), []);
+ const edgeTypes = useMemo(
+ () => ({
+ smartbezier: SmartBezierEdge,
+ smartstep: SmartStepEdge,
+ smartstraight: SmartStraightEdge,
+ }),
+ []
+ );
+
+ const [nodes, setNodes, onNodesChange] = useNodesState([]);
+ const [edges, setEdges, onEdgesChange] = useEdgesState([]);
+
+ const onConnect = useCallback(
+ (params) => setEdges((eds) => addEdge(params, eds)),
+ [setEdges]
+ );
+
+ // Show/hide content types on options change
+ useEffect(() => {
+ const fetchData = async () => {
+ let allTypes = await explorerRequests.getContentTypes();
+ if (!options.showAdminTypes) {
+ allTypes = allTypes.filter((x) => !x.name.startsWith("admin::"));
+ }
+ if (!options.showPluginTypes) {
+ allTypes = allTypes.filter((x) => !x.name.startsWith("plugin::"));
+ }
+ setContentTypes(allTypes);
+ };
+
+ fetchData();
+ }, [options.showAdminTypes, options.showPluginTypes]);
+
+ // Create/update nodes & edges
+ useEffect(() => {
+ if (contentTypes.length > 0) {
+ let newNodes = createNodes(contentTypes, options);
+ setNodes(newNodes);
+ if (options.showEdges) {
+ let newEdges = createEdegs(contentTypes, options);
+ setEdges(newEdges);
+ } else {
+ setEdges([]);
+ }
+ }
+ }, [contentTypes, options]);
+
+ return (
+ <>
+ Download as Image}
+ secondaryAction={
+ }
+ href="https://github.com/shahriarkh/strapi-content-type-explorer"
+ >
+ Help
+
+ }
+ />
+
+
+
+
+ toggleOption("scrollMode")}
+ title="Toggle Mouse Wheel Behavior (Zoom/Scroll)"
+ >
+
+
+
+
+
+
+ >
+ );
+};
+
+export default HomePage;
diff --git a/content-type-explorer/admin/src/pages/HomePage/styles.css b/content-type-explorer/admin/src/pages/HomePage/styles.css
new file mode 100644
index 0000000..0231a11
--- /dev/null
+++ b/content-type-explorer/admin/src/pages/HomePage/styles.css
@@ -0,0 +1,12 @@
+.cte-plugin-controls button {
+ background-color: var(--button-background);
+ border: none;
+}
+
+.cte-plugin-controls button:hover {
+ background-color: var(--button-hover);
+}
+
+.cte-plugin-controls button svg {
+ fill: var(--button-foreground);
+}
diff --git a/content-type-explorer/admin/src/pluginId.js b/content-type-explorer/admin/src/pluginId.js
new file mode 100644
index 0000000..695317c
--- /dev/null
+++ b/content-type-explorer/admin/src/pluginId.js
@@ -0,0 +1,5 @@
+import pluginPkg from '../../package.json';
+
+const pluginId = pluginPkg.name.replace(/^(@[^-,.][\w,-]+\/|strapi-)plugin-/i, '');
+
+export default pluginId;
diff --git a/content-type-explorer/admin/src/translations/en.json b/content-type-explorer/admin/src/translations/en.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/content-type-explorer/admin/src/translations/en.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/content-type-explorer/admin/src/translations/fr.json b/content-type-explorer/admin/src/translations/fr.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/content-type-explorer/admin/src/translations/fr.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/content-type-explorer/admin/src/utils/dataUtils.js b/content-type-explorer/admin/src/utils/dataUtils.js
new file mode 100644
index 0000000..204fad3
--- /dev/null
+++ b/content-type-explorer/admin/src/utils/dataUtils.js
@@ -0,0 +1,54 @@
+const CARDS_PER_ROW = 6;
+
+export function createNodes(contentTypes, options) {
+ let newNodes = [];
+ contentTypes.map(
+ (node, index) =>
+ (newNodes = [
+ ...newNodes,
+ {
+ id: node.key,
+ position: {
+ x: (index % CARDS_PER_ROW) * 320,
+ y: ((index - (index % CARDS_PER_ROW)) / CARDS_PER_ROW) * 560,
+ },
+ type: "special",
+
+ data: {
+ ...node,
+ options: options,
+ },
+ },
+ ])
+ );
+ return newNodes;
+}
+
+export function createEdegs(contentTypes, options) {
+ let newEdges = [];
+
+ contentTypes.map((contentType) => {
+ Object.keys(contentType.attributes).map((attr) => {
+ if (contentType.attributes[attr].type == "relation") {
+ // only add edge if target node is not excluded (not hidden)
+ if (
+ contentTypes.some(
+ (node) => node.key === contentType.attributes[attr].target
+ )
+ ) {
+ newEdges = [
+ ...newEdges,
+ {
+ id: `${contentType.attributes[attr].target}-${contentType.key}.${attr}`,
+ source: contentType.key,
+ target: contentType.attributes[attr].target,
+ type: options.edgeType,
+ sourceHandle: attr,
+ },
+ ];
+ }
+ }
+ });
+ });
+ return newEdges;
+}
diff --git a/content-type-explorer/admin/src/utils/getTrad.js b/content-type-explorer/admin/src/utils/getTrad.js
new file mode 100644
index 0000000..d0a071b
--- /dev/null
+++ b/content-type-explorer/admin/src/utils/getTrad.js
@@ -0,0 +1,5 @@
+import pluginId from '../pluginId';
+
+const getTrad = (id) => `${pluginId}.${id}`;
+
+export default getTrad;
diff --git a/content-type-explorer/admin/src/utils/themeUtils.js b/content-type-explorer/admin/src/utils/themeUtils.js
new file mode 100644
index 0000000..0ceb0fc
--- /dev/null
+++ b/content-type-explorer/admin/src/utils/themeUtils.js
@@ -0,0 +1,86 @@
+import React from "react";
+import { darkTheme } from "@strapi/design-system";
+
+import {
+ Text,
+ Email,
+ Password,
+ Number,
+ Enumeration,
+ Date,
+ Media,
+ Boolean,
+ Json,
+ Relation,
+ Uid,
+ OneToMany,
+ OneToOne,
+ ManyToMany,
+ ManyToOne,
+ OneWay,
+ ManyWays,
+ RichText,
+} from "@strapi/icons";
+
+export function getBackgroundColor(variant, theme) {
+ switch (variant) {
+ case "cross":
+ return theme.colors.neutral200;
+ case "dots":
+ return darkTheme.colors.neutral300;
+ case "lines":
+ return theme.colors.neutral150;
+ case "none":
+ return theme.colors.neutral100;
+ }
+}
+
+export function getIcon(attrType) {
+ switch (attrType.toLowerCase()) {
+ case "string":
+ case "text":
+ return ;
+ case "email":
+ return ;
+ case "enumeration":
+ return ;
+ case "password":
+ return ;
+ case "boolean":
+ return ;
+ case "relation":
+ return ;
+ case "datetime":
+ case "date":
+ case "time":
+ return ;
+ case "integer":
+ case "decimal":
+ case "biginteger":
+ case "float":
+ return ;
+ case "json":
+ return ;
+ case "uid":
+ return ;
+ case "richtext":
+ return ;
+ case "media":
+ return ;
+
+ case "onetomany": //
+ return ;
+ case "oneway":
+ return ;
+ case "onetoone": //
+ return ;
+ case "manytomany": //
+ return ;
+ case "manytoone": //
+ return ;
+ case "manyways":
+ // Not sure
+ case "morphtomany":
+ return ;
+ }
+}
diff --git a/content-type-explorer/package.json b/content-type-explorer/package.json
new file mode 100644
index 0000000..fbcd423
--- /dev/null
+++ b/content-type-explorer/package.json
@@ -0,0 +1,42 @@
+{
+ "name": "content-type-explorer",
+ "version": "0.0.0",
+ "description": "This is the description of the plugin.",
+ "strapi": {
+ "name": "content-type-explorer",
+ "description": "Description of Content Type Explorer plugin",
+ "kind": "plugin",
+ "displayName": "Content Type Explorer"
+ },
+ "dependencies": {
+ "@strapi/design-system": "^1.6.3",
+ "@strapi/helper-plugin": "^4.6.0",
+ "@strapi/icons": "^1.6.3",
+ "prop-types": "^15.7.2"
+ },
+ "devDependencies": {
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^5.3.4",
+ "styled-components": "^5.3.6"
+ },
+ "peerDependencies": {
+ "react": "^17.0.0 || ^18.0.0",
+ "react-dom": "^17.0.0 || ^18.0.0",
+ "react-router-dom": "^5.3.4",
+ "styled-components": "^5.3.6"
+ },
+ "author": {
+ "name": "A Strapi developer"
+ },
+ "maintainers": [
+ {
+ "name": "A Strapi developer"
+ }
+ ],
+ "engines": {
+ "node": ">=14.19.1 <=18.x.x",
+ "npm": ">=6.0.0"
+ },
+ "license": "MIT"
+}
diff --git a/content-type-explorer/server/bootstrap.js b/content-type-explorer/server/bootstrap.js
new file mode 100644
index 0000000..2aa48af
--- /dev/null
+++ b/content-type-explorer/server/bootstrap.js
@@ -0,0 +1,5 @@
+'use strict';
+
+module.exports = ({ strapi }) => {
+ // bootstrap phase
+};
diff --git a/content-type-explorer/server/config/index.js b/content-type-explorer/server/config/index.js
new file mode 100644
index 0000000..56b5ae6
--- /dev/null
+++ b/content-type-explorer/server/config/index.js
@@ -0,0 +1,6 @@
+'use strict';
+
+module.exports = {
+ default: {},
+ validator() {},
+};
diff --git a/content-type-explorer/server/content-types/index.js b/content-type-explorer/server/content-types/index.js
new file mode 100644
index 0000000..8b46fbb
--- /dev/null
+++ b/content-type-explorer/server/content-types/index.js
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = {};
diff --git a/content-type-explorer/server/controllers/explorer-controller.js b/content-type-explorer/server/controllers/explorer-controller.js
new file mode 100644
index 0000000..5aac94b
--- /dev/null
+++ b/content-type-explorer/server/controllers/explorer-controller.js
@@ -0,0 +1,20 @@
+"use strict";
+
+module.exports = ({ strapi }) => ({
+ getContentTypes(ctx) {
+ const data = strapi
+ .plugin("content-type-explorer")
+ .service("explorerService")
+ .getContentTypes();
+
+ let neededData = Object.keys(data).map((key) => ({
+ name: key,
+ attributes: data[key]["attributes"],
+ info: data[key]["info"],
+ // kind: data[key]["kind"],
+ key: data[key]["uid"],
+ }));
+
+ ctx.body = neededData;
+ },
+});
diff --git a/content-type-explorer/server/controllers/index.js b/content-type-explorer/server/controllers/index.js
new file mode 100644
index 0000000..e383559
--- /dev/null
+++ b/content-type-explorer/server/controllers/index.js
@@ -0,0 +1,7 @@
+"use strict";
+
+const explorerController = require("./explorer-controller");
+
+module.exports = {
+ explorerController,
+};
diff --git a/content-type-explorer/server/destroy.js b/content-type-explorer/server/destroy.js
new file mode 100644
index 0000000..75f32f4
--- /dev/null
+++ b/content-type-explorer/server/destroy.js
@@ -0,0 +1,5 @@
+'use strict';
+
+module.exports = ({ strapi }) => {
+ // destroy phase
+};
diff --git a/content-type-explorer/server/index.js b/content-type-explorer/server/index.js
new file mode 100644
index 0000000..5b524b1
--- /dev/null
+++ b/content-type-explorer/server/index.js
@@ -0,0 +1,25 @@
+'use strict';
+
+const register = require('./register');
+const bootstrap = require('./bootstrap');
+const destroy = require('./destroy');
+const config = require('./config');
+const contentTypes = require('./content-types');
+const controllers = require('./controllers');
+const routes = require('./routes');
+const middlewares = require('./middlewares');
+const policies = require('./policies');
+const services = require('./services');
+
+module.exports = {
+ register,
+ bootstrap,
+ destroy,
+ config,
+ controllers,
+ routes,
+ services,
+ contentTypes,
+ policies,
+ middlewares,
+};
diff --git a/content-type-explorer/server/middlewares/index.js b/content-type-explorer/server/middlewares/index.js
new file mode 100644
index 0000000..8b46fbb
--- /dev/null
+++ b/content-type-explorer/server/middlewares/index.js
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = {};
diff --git a/content-type-explorer/server/policies/index.js b/content-type-explorer/server/policies/index.js
new file mode 100644
index 0000000..8b46fbb
--- /dev/null
+++ b/content-type-explorer/server/policies/index.js
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = {};
diff --git a/content-type-explorer/server/register.js b/content-type-explorer/server/register.js
new file mode 100644
index 0000000..437d48e
--- /dev/null
+++ b/content-type-explorer/server/register.js
@@ -0,0 +1,5 @@
+'use strict';
+
+module.exports = ({ strapi }) => {
+ // registeration phase
+};
diff --git a/content-type-explorer/server/routes/index.js b/content-type-explorer/server/routes/index.js
new file mode 100644
index 0000000..06bde7b
--- /dev/null
+++ b/content-type-explorer/server/routes/index.js
@@ -0,0 +1,10 @@
+module.exports = [
+ {
+ method: "GET",
+ path: "/get-content-types",
+ handler: "explorerController.getContentTypes",
+ config: {
+ policies: [],
+ },
+ },
+];
diff --git a/content-type-explorer/server/services/explorer-service.js b/content-type-explorer/server/services/explorer-service.js
new file mode 100644
index 0000000..da76386
--- /dev/null
+++ b/content-type-explorer/server/services/explorer-service.js
@@ -0,0 +1,7 @@
+"use strict";
+
+module.exports = ({ strapi }) => ({
+ getContentTypes() {
+ return strapi.contentTypes;
+ },
+});
diff --git a/content-type-explorer/server/services/index.js b/content-type-explorer/server/services/index.js
new file mode 100644
index 0000000..156bc4a
--- /dev/null
+++ b/content-type-explorer/server/services/index.js
@@ -0,0 +1,7 @@
+"use strict";
+
+const explorerService = require("./explorer-service");
+
+module.exports = {
+ explorerService,
+};
diff --git a/content-type-explorer/strapi-admin.js b/content-type-explorer/strapi-admin.js
new file mode 100644
index 0000000..2d1a3d9
--- /dev/null
+++ b/content-type-explorer/strapi-admin.js
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./admin/src').default;
diff --git a/content-type-explorer/strapi-server.js b/content-type-explorer/strapi-server.js
new file mode 100644
index 0000000..8a908be
--- /dev/null
+++ b/content-type-explorer/strapi-server.js
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./server');