Skip to content

Commit be0b8ea

Browse files
init
0 parents  commit be0b8ea

26 files changed

+2113
-0
lines changed

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Prisma Graph Visualizer Plugin
2+
3+
Ein JetBrains IntelliJ IDEA / WebStorm / PHPStorm Plugin zur graphischen Darstellung von Prisma Schema Dateien.
4+
5+
## Features
6+
7+
- **Automatische Erkennung**: Erkennt automatisch alle `.prisma` Dateien in Ihrem Projekt
8+
- **Graphische Darstellung**: Zeigt Models, Felder und Relationen in einem interaktiven Graph
9+
- **Live-Updates**: Aktualisiert sich automatisch bei Änderungen an Schema-Dateien
10+
- **Interaktive Navigation**:
11+
- Zoom mit Mausrad
12+
- Pan mit Rechtsklick + Ziehen
13+
- Model-Auswahl durch Klicken
14+
- Model-Verschiebung durch Ziehen
15+
- **Mehrere Schema-Dateien**: Unterstützt mehrere Schema-Dateien und kombiniert sie zu einem Graph
16+
- **Beziehungsvisualisierung**: Zeigt One-to-One, One-to-Many und Many-to-Many Beziehungen
17+
18+
## Installation
19+
20+
### Voraussetzungen
21+
- JDK 17 oder höher
22+
- Gradle 7.0 oder höher (oder verwenden Sie den Gradle Wrapper)
23+
24+
## Lizenz
25+
26+
MIT License

build.gradle.kts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
plugins {
2+
id("java")
3+
id("org.jetbrains.kotlin.jvm") version "1.8.22"
4+
id("org.jetbrains.intellij") version "1.16.1"
5+
}
6+
7+
group = "com.alexanderkoch.prismagraph"
8+
version = "1.0.0"
9+
10+
repositories {
11+
mavenCentral()
12+
}
13+
14+
dependencies {
15+
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
16+
testImplementation("junit:junit:4.13.2")
17+
}
18+
19+
intellij {
20+
version.set("2024.3.1")
21+
type.set("IC") // IntelliJ Community - compatible with WebStorm
22+
plugins.set(listOf())
23+
}
24+
25+
tasks {
26+
withType<JavaCompile> {
27+
sourceCompatibility = "17"
28+
targetCompatibility = "17"
29+
}
30+
31+
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
32+
kotlinOptions.jvmTarget = "17"
33+
}
34+
35+
patchPluginXml {
36+
sinceBuild.set("232")
37+
untilBuild.set("252.*")
38+
39+
// Plugin-Beschreibung aktualisieren
40+
changeNotes.set("""
41+
Version 1.0.0:
42+
- Kompatibilität mit WebStorm 2025.1 (Build 251.*)
43+
- Erste Version des Prisma Graph Visualizers
44+
- Grundlegende Schema-Parsing-Funktionalität
45+
- Graphische Darstellung von Models und Relationen
46+
""".trimIndent())
47+
}
48+
}

example/schema.prisma

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Beispiel Prisma Schema für das Plugin
2+
generator client {
3+
provider = "prisma-client-js"
4+
}
5+
6+
datasource db {
7+
provider = "postgresql"
8+
url = env("DATABASE_URL")
9+
}
10+
11+
model User {
12+
id Int @id @default(autoincrement())
13+
email String @unique
14+
name String?
15+
posts Post[]
16+
profile Profile?
17+
comments Comment[]
18+
createdAt DateTime @default(now())
19+
updatedAt DateTime @updatedAt
20+
}
21+
22+
model Profile {
23+
id Int @id @default(autoincrement())
24+
bio String?
25+
avatar String?
26+
userId Int @unique
27+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
28+
}
29+
30+
model Post {
31+
id Int @id @default(autoincrement())
32+
title String
33+
content String?
34+
published Boolean @default(false)
35+
authorId Int
36+
author User @relation(fields: [authorId], references: [id])
37+
tags Tag[]
38+
comments Comment[]
39+
createdAt DateTime @default(now())
40+
updatedAt DateTime @updatedAt
41+
}
42+
43+
model Comment {
44+
id Int @id @default(autoincrement())
45+
content String
46+
postId Int
47+
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
48+
authorId Int
49+
author User @relation(fields: [authorId], references: [id])
50+
createdAt DateTime @default(now())
51+
}
52+
53+
model Tag {
54+
id Int @id @default(autoincrement())
55+
name String @unique
56+
color String @default("#000000")
57+
posts Post[]
58+
}
59+
60+
model Category {
61+
id Int @id @default(autoincrement())
62+
name String @unique
63+
description String?
64+
posts Post[]
65+
}
66+
67+
enum Role {
68+
USER
69+
ADMIN
70+
MODERATOR
71+
}
72+
73+
enum PostStatus {
74+
DRAFT
75+
PUBLISHED
76+
ARCHIVED
77+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
distributionBase=GRADLE_USER_HOME
2+
distributionPath=wrapper/dists
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
4+
networkTimeout=10000
5+
validateDistributionUrl=true
6+
zipStoreBase=GRADLE_USER_HOME
7+
zipStorePath=wrapper/dists

gradlew.bat

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
@rem
2+
@rem Copyright 2015 the original author or authors.
3+
@rem
4+
@rem Licensed under the Apache License, Version 2.0 (the "License");
5+
@rem you may not use this file except in compliance with the License.
6+
@rem You may obtain a copy of the License at
7+
@rem
8+
@rem https://www.apache.org/licenses/LICENSE-2.0
9+
@rem
10+
@rem Unless required by applicable law or agreed to in writing, software
11+
@rem distributed under the License is distributed on an "AS IS" BASIS,
12+
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
@rem See the License for the specific language governing permissions and
14+
@rem limitations under the License.
15+
@rem
16+
17+
@if "%DEBUG%"=="" @echo off
18+
@rem ##########################################################################
19+
@rem
20+
@rem Gradle startup script for Windows
21+
@rem
22+
@rem ##########################################################################
23+
24+
@rem Set local scope for the variables with windows NT shell
25+
if "%OS%"=="Windows_NT" setlocal
26+
27+
set DIRNAME=%~dp0
28+
if "%DIRNAME%"=="" set DIRNAME=.
29+
set APP_BASE_NAME=%~n0
30+
set APP_HOME=%DIRNAME%
31+
32+
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
33+
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34+
35+
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36+
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37+
38+
@rem Find java.exe
39+
if defined JAVA_HOME goto findJavaFromJavaHome
40+
41+
set JAVA_EXE=java.exe
42+
%JAVA_EXE% -version >NUL 2>&1
43+
if %ERRORLEVEL% equ 0 goto execute
44+
45+
echo.
46+
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47+
echo.
48+
echo Please set the JAVA_HOME variable in your environment to match the
49+
echo location of your Java installation.
50+
51+
goto fail
52+
53+
:findJavaFromJavaHome
54+
set JAVA_HOME=%JAVA_HOME:"=%
55+
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56+
57+
if exist "%JAVA_EXE%" goto execute
58+
59+
echo.
60+
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61+
echo.
62+
echo Please set the JAVA_HOME variable in your environment to match the
63+
echo location of your Java installation.
64+
65+
goto fail
66+
67+
:execute
68+
@rem Setup the command line
69+
70+
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71+
72+
73+
@rem Execute Gradle
74+
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75+
76+
:end
77+
@rem End local scope for the variables with windows NT shell
78+
if %ERRORLEVEL% equ 0 goto mainEnd
79+
80+
:fail
81+
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82+
rem the _cmd_ return code.
83+
if not "" == "%GRADLE_EXIT_CONSOLE%" exit /b %ERRORLEVEL%
84+
exit /b 1
85+
86+
:mainEnd
87+
if "%OS%"=="Windows_NT" endlocal
88+
89+
:omega
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.alexanderkoch.prismagraph.actions
2+
3+
import com.intellij.openapi.actionSystem.AnAction
4+
import com.intellij.openapi.actionSystem.AnActionEvent
5+
import com.intellij.openapi.project.Project
6+
import com.intellij.openapi.wm.ToolWindowManager
7+
8+
/**
9+
* Action zum Öffnen des Prisma Graph Tool Windows
10+
*/
11+
class OpenPrismaGraphAction : AnAction() {
12+
13+
override fun actionPerformed(e: AnActionEvent) {
14+
val project: Project = e.project ?: return
15+
16+
val toolWindowManager = ToolWindowManager.getInstance(project)
17+
val toolWindow = toolWindowManager.getToolWindow("PrismaGraph")
18+
19+
if (toolWindow != null) {
20+
toolWindow.activate(null)
21+
}
22+
}
23+
24+
override fun update(e: AnActionEvent) {
25+
val project = e.project
26+
e.presentation.isEnabledAndVisible = project != null
27+
}
28+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.alexanderkoch.prismagraph.actions
2+
3+
import com.alexanderkoch.prismagraph.service.PrismaSchemaService
4+
import com.intellij.openapi.actionSystem.AnAction
5+
import com.intellij.openapi.actionSystem.AnActionEvent
6+
import com.intellij.openapi.components.service
7+
8+
/**
9+
* Action zum Aktualisieren des Prisma Graphs
10+
*/
11+
class RefreshGraphAction : AnAction() {
12+
13+
override fun actionPerformed(e: AnActionEvent) {
14+
val project = e.project ?: return
15+
val schemaService = project.service<PrismaSchemaService>()
16+
schemaService.scanForSchemaFiles()
17+
}
18+
19+
override fun update(e: AnActionEvent) {
20+
e.presentation.isEnabled = e.project != null
21+
}
22+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.alexanderkoch.prismagraph.filetype
2+
3+
import com.intellij.openapi.fileTypes.LanguageFileType
4+
import com.intellij.openapi.util.IconLoader
5+
import javax.swing.Icon
6+
7+
/**
8+
* File Type Definition für Prisma Schema Dateien
9+
*/
10+
class PrismaFileType : LanguageFileType(PrismaLanguage.INSTANCE) {
11+
12+
override fun getName(): String = "Prisma Schema"
13+
14+
override fun getDescription(): String = "Prisma Schema File"
15+
16+
override fun getDefaultExtension(): String = "prisma"
17+
18+
override fun getIcon(): Icon? {
19+
return try {
20+
IconLoader.getIcon("/icons/prisma.png", PrismaFileType::class.java)
21+
} catch (e: Exception) {
22+
null // Fallback zu Standard-Icon
23+
}
24+
}
25+
26+
companion object {
27+
@JvmField
28+
val INSTANCE = PrismaFileType()
29+
}
30+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.alexanderkoch.prismagraph.filetype
2+
3+
import com.intellij.lang.Language
4+
5+
/**
6+
* Language Definition für Prisma Schema
7+
*/
8+
class PrismaLanguage : Language("PrismaGraph") {
9+
10+
companion object {
11+
@JvmField
12+
val INSTANCE = PrismaLanguage()
13+
}
14+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.alexanderkoch.prismagraph.icons
2+
3+
import com.alexanderkoch.prismagraph.filetype.PrismaFileType
4+
import com.intellij.ide.IconProvider
5+
import com.intellij.openapi.util.IconLoader
6+
import com.intellij.psi.PsiElement
7+
import com.intellij.psi.PsiFile
8+
import javax.swing.Icon
9+
10+
/**
11+
* Icon Provider für Prisma Schema Dateien
12+
*/
13+
class PrismaIconProvider : IconProvider() {
14+
15+
private val prismaIcon: Icon by lazy {
16+
// Fallback zu einem Standard-Icon falls das Prisma-Icon nicht gefunden wird
17+
try {
18+
IconLoader.getIcon("/icons/prisma.png", PrismaIconProvider::class.java)
19+
} catch (e: Exception) {
20+
// Verwende ein Standard-Icon als Fallback
21+
IconLoader.getIcon("/general/add.png", PrismaIconProvider::class.java)
22+
}
23+
}
24+
25+
override fun getIcon(element: PsiElement, flags: Int): Icon? {
26+
if (element is PsiFile && element.fileType == PrismaFileType.INSTANCE) {
27+
return prismaIcon
28+
}
29+
return null
30+
}
31+
}

0 commit comments

Comments
 (0)