diff --git a/.gitignore b/.gitignore
index 4e80219..22cfdea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,5 +27,6 @@
**/mvnw.cmd
**/.yarn
**/.yarnrc.yml
+**/*.jar
/extension/*.cjs
/extension/*.mjs
\ No newline at end of file
diff --git a/c4-server/pom.xml b/c4-server/pom.xml
index 6618c43..546ad38 100644
--- a/c4-server/pom.xml
+++ b/c4-server/pom.xml
@@ -1,191 +1,216 @@
-
- 4.0.0
-
- ru.beeatlas.c4
- c4-server
- 1.0
-
- c4-server
- http://www.beeatlas.ru
-
-
- UTF-8
- 17
- 1.9.24
- 4.1.0
-
-
-
-
-
- org.apache.commons
- commons-text
- 1.14.0
-
-
-
- ch.qos.logback
- logback-classic
- 1.5.20
- compile
-
-
-
- info.picocli
- picocli
- 4.7.7
-
-
-
- com.google.inject
- guice
- 7.0.0
-
-
-
- org.eclipse.lsp4j
- org.eclipse.lsp4j
- 0.24.0
-
-
-
- com.structurizr
- structurizr-dsl
- ${structurizr.version}
-
-
-
- com.structurizr
- structurizr-export
- ${structurizr.version}
-
-
-
- org.aspectj
- aspectjrt
- ${aspectj.version}
-
-
-
- org.aspectj
- aspectjweaver
- ${aspectj.version}
-
-
- junit
- junit
- 4.11
- test
-
-
-
- org.mockito
- mockito-core
- 5.18.0
- test
-
-
-
- org.junit.jupiter
- junit-jupiter
- 5.13.1
- test
-
-
-
- org.assertj
- assertj-core
- 3.27.3
- test
-
-
-
-
- ${project.artifactId}
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.15.0
-
- false
-
-
-
- maven-jar-plugin
- 3.4.2
-
-
-
-
-
- true
- lib/
-
- ru.beeatlas.c4.C4LanguageServerLauncher
-
-
-
-
-
- org.codehaus.mojo
- aspectj-maven-plugin
- 1.15.0
-
-
+ 4.0.0
+ ru.beeatlas.c4
+ c4-server
+ 1.0
+ c4-server
+ http://www.beeatlas.ru
+
+ UTF-8
+ 17
+ 1.9.24
+ 4.1.0
+
+
+
+
+ org.apache.commons
+ commons-text
+ 1.14.0
+
+
+
+ ch.qos.logback
+ logback-classic
+ 1.5.20
+ compile
+
+
+
+ com.google.inject
+ guice
+ 7.0.0
+
+
+
+ org.eclipse.lsp4j
+ org.eclipse.lsp4j
+ 1.0.0
+
+
+
+ com.structurizr
+ structurizr-dsl
+ ${structurizr.version}
+
+
+
+ com.structurizr
+ structurizr-export
+ ${structurizr.version}
+
+
+
org.aspectj
- aspectjtools
+ aspectjrt
${aspectj.version}
-
-
-
- 17
- true
- true
- ignore
- ${project.build.sourceEncoding}
-
-
- com.structurizr
- structurizr-dsl
-
-
- com.structurizr
- structurizr-client
-
-
-
-
-
-
- compile
-
-
-
-
-
- maven-assembly-plugin
- 3.7.1
-
- server
- ${outputDirectory}
- false
-
- src/assembly/assembly.xml
-
-
-
-
- package
-
- single
-
-
-
-
-
-
+
+
+
+ org.aspectj
+ aspectjweaver
+ ${aspectj.version}
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+
+ org.mockito
+ mockito-core
+ 5.18.0
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.13.1
+ test
+
+
+
+ org.assertj
+ assertj-core
+ 3.27.3
+ test
+
+
+
+ ${project.artifactId}
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.15.0
+
+ false
+
+
+
+ org.codehaus.mojo
+ aspectj-maven-plugin
+ 1.16.0
+
+
+ org.aspectj
+ aspectjtools
+ ${aspectj.version}
+
+
+
+ 17
+ true
+ true
+ ignore
+ ${project.build.sourceEncoding}
+
+
+ com.structurizr
+ structurizr-dsl
+
+
+ com.structurizr
+ structurizr-client
+
+
+
+
+
+
+ compile
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.6.1
+
+
+ package
+
+ shade
+
+
+ ${outputDirectory}
+ server
+ false
+ true
+ false
+
+
+ junit:junit
+ org.junit.jupiter:*
+ org.mockito:*
+ org.assertj:*
+ org.hamcrest:*
+ org.checkerframework:checker-qual
+ com.google.errorprone:error_prone_annotations
+ com.google.j2objc:j2objc-annotations
+ com.google.code.findbugs:jsr305
+ javax.activation:javax.activation-api
+ javax.xml.bind:jaxb-api
+ com.structurizr:structurizr-dsl
+ com.structurizr:structurizr-client
+ org.aspectj:aspectjrt
+ com.google.guava:listenablefuture
+
+
+
+
+ commons-logging:commons-logging
+ **
+
+ META-INF/versions/**
+ org/apache/commons/logging/impl/Jdk13*
+ org/apache/commons/logging/impl/Jdk14*
+ org/apache/commons/logging/impl/Avalon*
+ org/apache/commons/logging/impl/LogKit*
+
+
+
+ *:*
+
+ META-INF/*.SF
+ META-INF/*.DSA
+ META-INF/*.RSA
+ META-INF/MANIFEST.MF*
+ META-INF/DEPENDENCIES
+ META-INF/*LICENSE*
+ META-INF/*NOTICE*
+ module-info.class
+ META-INF/versions/*/module-info.class
+ about.html
+
+
+
+
+
+ ru.beeatlas.c4.C4LanguageServerLauncher
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/c4-server/src/assembly/assembly.xml b/c4-server/src/assembly/assembly.xml
deleted file mode 100644
index 234953f..0000000
--- a/c4-server/src/assembly/assembly.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
- bin
-
- dir
-
- false
-
-
-
- javax.activation:*
- javax.xml.bind:jaxb-api
- com.google.code.findbugs:jsr305
- com.structurizr:structurizr-dsl
- com.structurizr:structurizr-client
- com.structurizr:structurizr-import
-
- false
- lib
- false
-
-
-
-
-
- ${project.build.directory}
-
-
- *.jar
-
-
-
-
\ No newline at end of file
diff --git a/c4-server/src/main/java/ru/beeatlas/c4/C4LanguageServerLauncher.java b/c4-server/src/main/java/ru/beeatlas/c4/C4LanguageServerLauncher.java
index 446f546..95f712c 100644
--- a/c4-server/src/main/java/ru/beeatlas/c4/C4LanguageServerLauncher.java
+++ b/c4-server/src/main/java/ru/beeatlas/c4/C4LanguageServerLauncher.java
@@ -16,75 +16,38 @@
package ru.beeatlas.c4;
-import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.net.StandardSocketOptions;
-import java.nio.channels.Channels;
-import java.nio.channels.AsynchronousServerSocketChannel;
-import java.nio.channels.AsynchronousSocketChannel;
-import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.eclipse.lsp4j.jsonrpc.Launcher;
import org.eclipse.lsp4j.launch.LSPLauncher;
import org.eclipse.lsp4j.services.LanguageClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import ru.beeatlas.c4.custom.Custom;
import ru.beeatlas.c4.service.C4LanguageServer;
-import picocli.CommandLine;
-import picocli.CommandLine.Option;
-
-public class C4LanguageServerLauncher implements Callable {
-
- private static final Logger logger = LoggerFactory.getLogger(C4LanguageServerLauncher.class);
-
- @Option(names = {"-e", "--echo"}, description = "Echo to the client, to inform that socket can now accept incoming connections")
- private String echo = "READY_TO_CONNECT";
-
- @Override
- public Integer call() throws Exception {
-
- try {
-
- final AsynchronousServerSocketChannel serverSocket = AsynchronousServerSocketChannel.open();
- if (serverSocket.isOpen()) {
- serverSocket.setOption(StandardSocketOptions.SO_RCVBUF, 1024);
- serverSocket.setOption(StandardSocketOptions.SO_REUSEADDR, true);
- serverSocket.bind(new InetSocketAddress("127.0.0.1", 5008));
- Future acceptFuture = serverSocket.accept();
- // echo to the client, that server is ready to receive incoming connections
- System.out.println(echo);
- final AsynchronousSocketChannel socketChannel = acceptFuture.get();
- serverSocket.close();
- InputStream in = Channels.newInputStream(socketChannel);
- OutputStream out = Channels.newOutputStream(socketChannel);
- C4LanguageServer c4LanguageServer = new C4LanguageServer();
- Launcher launcher = LSPLauncher.createServerLauncher(c4LanguageServer, in, out);
- // Get the client that request to launch the LS.
- LanguageClient client = launcher.getRemoteProxy();
- // Set the client to language server
- c4LanguageServer.connect(client);
- Custom.getInstance().setClient(client);
- // Start the listener for JsonRPC
- Future> startListening = launcher.startListening();
- // Get the computed result from LS.
- startListening.get();
- }
- } catch (ExecutionException | InterruptedException | IOException e) {
- logger.error(e.getMessage());
- Thread.currentThread().interrupt();
- }
- return 1;
- }
+public class C4LanguageServerLauncher {
public static void main(String[] args) {
- int exitCode = new CommandLine( new C4LanguageServerLauncher()).execute(args);
- System.exit(exitCode);
+ InputStream in = System.in;
+ OutputStream out = System.out;
+ System.setOut(System.err);
+ C4LanguageServer c4LanguageServer = new C4LanguageServer();
+ Launcher launcher = LSPLauncher.createServerLauncher(c4LanguageServer, in, out);
+ // Get the client that request to launch the LS.
+ LanguageClient client = launcher.getRemoteProxy();
+ // Set the client to language server
+ c4LanguageServer.connect(client);
+ Custom.getInstance().setClient(client);
+ // Start the listener for JsonRPC
+ Future> startListening = launcher.startListening();
+ // Get the computed result from LS.
+ try {
+ startListening.get();
+ } catch (InterruptedException | ExecutionException e) {
+ System.exit(1);
+ }
+ System.exit(0);
}
}
diff --git a/c4-server/src/main/java/ru/beeatlas/c4/custom/Custom.java b/c4-server/src/main/java/ru/beeatlas/c4/custom/Custom.java
index cf657d6..556c5c8 100644
--- a/c4-server/src/main/java/ru/beeatlas/c4/custom/Custom.java
+++ b/c4-server/src/main/java/ru/beeatlas/c4/custom/Custom.java
@@ -44,6 +44,7 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
@@ -78,6 +79,7 @@
import ru.beeatlas.c4.dto.CodeLensCommandArgs;
import ru.beeatlas.c4.model.C4DocumentModel;
import ru.beeatlas.c4.model.C4ObjectWithContext;
+import ru.beeatlas.c4.model.DecoratorRange;
import ru.beeatlas.c4.model.C4DocumentModel.C4CompletionScope;
import ru.beeatlas.c4.utils.LineToken;
import ru.beeatlas.c4.utils.LineTokenizer;
@@ -126,6 +128,7 @@ private boolean isValidURL(String url) {
new URL(url).toURI();
return true;
} catch (Exception e) {
+ logger.debug(e.getMessage());
return false;
}
}
@@ -278,6 +281,7 @@ public void checkServerTrusted(X509Certificate[] certs, String authType) {
allTrustingTrustManager = sc.getSocketFactory();
allTrustingHostnameVerifier = (String hostname, SSLSession session) -> true;
} catch (Exception e) {
+ logger.debug(e.getMessage());
}
}
@@ -296,7 +300,7 @@ private void updateTechCapabilities() {
URLConnection conn = archOpsApiConnection("GET", path, null, null);
try (BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
techCapabilities.set(Arrays.stream((new Gson()).fromJson(in, TechCapability[].class))
- .collect(Collectors.toMap(TechCapability::code, Function.identity())));
+ .collect(Collectors.toMap(cap -> cap.code().toLowerCase(), Function.identity())));
} catch(IOException e) {
throw e;
}
@@ -330,7 +334,7 @@ private void updateCapabilities() {
URLConnection conn = archOpsApiConnection("GET", path, null, null);
try (BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
capabilities.set(Arrays.stream((new Gson()).fromJson(in, Capability[].class))
- .collect(Collectors.toMap(Capability::code, Function.identity(), (existingCapability, newCapability) -> existingCapability)));
+ .collect(Collectors.toMap(c -> c.code().toLowerCase(), Function.identity(), (existingCapability, newCapability) -> existingCapability)));
} catch(IOException e) {
throw e;
}
@@ -416,6 +420,7 @@ public String loadFrom(String themeLocation, int timeoutInMilliseconds) {
return in.lines().collect(Collectors.joining());
}
} catch (IOException e) {
+ logger.debug(e.getMessage());
return "";
}
}
@@ -465,7 +470,7 @@ public List technologicalCapabilitiesCompletion() {
CompletionItemLabelDetails details = new CompletionItemLabelDetails();
details.setDetail(" " + e.getValue().name());
item.setKind(CompletionItemKind.Property);
- item.setLabel(e.getKey());
+ item.setLabel(e.getValue().code());
item.setLabelDetails(details);
return item;
}).toList();
@@ -477,7 +482,7 @@ public List businessCapabilitiesCompletion() {
CompletionItemLabelDetails details = new CompletionItemLabelDetails();
details.setDetail(" " + e.getValue().name());
item.setKind(CompletionItemKind.Property);
- item.setLabel(e.getKey());
+ item.setLabel(e.getValue().code());
item.setLabelDetails(details);
return item;
}).toList();
@@ -562,7 +567,7 @@ public List cloudFlavorsCompletion(String vegaProject) {
}
public Hover businessCapabilitiesHover(String code) {
- Capability capability = capabilities.get().get(code);
+ Capability capability = capabilities.get().get(code.toLowerCase());
if (capability != null) {
String name = capability.name();
if (name != null) {
@@ -579,7 +584,7 @@ public Hover businessCapabilitiesHover(String code) {
}
public Hover technologicalCapabilitiesHover(String code) {
- TechCapability capability = techCapabilities.get().get(code);
+ TechCapability capability = techCapabilities.get().get(code.toLowerCase());
if (capability != null) {
String name = capability.name();
if (name != null) {
@@ -659,7 +664,7 @@ public List dynamicViewCompletion(String destination, C4Document
container.getComponents().stream()
.filter(c -> c.getProperties().getOrDefault("type", "").equalsIgnoreCase("capability"))
.map(c -> c.getProperties().get("code")).filter(Objects::nonNull).forEach(c -> {
- TechCapability capability = techCapabilities.get().get(c);
+ TechCapability capability = techCapabilities.get().get(c.toLowerCase());
CompletionItem item = new CompletionItem();
item.setLabel(c);
@@ -732,6 +737,27 @@ public Hover getPropertiesHover(List tokens, CursorLocation cursorAt,
return null;
}
+ public Stream getDecorations(C4DocumentModel docModel) {
+ return isApiConfigured() ? docModel.getProperties().stream().mapMulti( (p, consumer) -> {
+ List tokens = LineTokenizer.tokenize(p.line());
+ int character = tokens.get(1).end();
+ if(p.name().equalsIgnoreCase("tc")) {
+ TechCapability tc = techCapabilities.get().get(p.value().toLowerCase());
+ if(tc == null && cmdb != null) {
+ tc = techCapabilities.get().get(cmdb.toLowerCase() + "." + p.value().toLowerCase());
+ }
+ if(tc!= null) {
+ consumer.accept(new DecoratorRange("# " + tc.name(),new Range(new Position(p.lineNumber() - 1, character), new Position(p.lineNumber() - 1, character))));
+ }
+ } else if(p.name().equalsIgnoreCase("parents")) {
+ Capability c = capabilities.get().get(p.value().toLowerCase());
+ if(c!= null) {
+ consumer.accept(new DecoratorRange("# " + c.name(),new Range(new Position(p.lineNumber() - 1, character), new Position(p.lineNumber() - 1, character))));
+ }
+ }
+ }) : Stream.empty();
+ }
+
public List comleteProperties(List tokens, CursorLocation cursor, C4DocumentModel docModel, Position position) {
logger.info("completeProperties");
int lineNumberBackward = position.getLine();
@@ -1039,6 +1065,7 @@ private boolean sendTelemetry(String message) {
outStream.close();
return true;
} catch (Exception e) {
+ logger.debug(e.getMessage());
return false;
}
}
diff --git a/c4-server/src/main/java/ru/beeatlas/c4/model/C4DocumentManager.java b/c4-server/src/main/java/ru/beeatlas/c4/model/C4DocumentManager.java
index 6b30eb4..81d736c 100644
--- a/c4-server/src/main/java/ru/beeatlas/c4/model/C4DocumentManager.java
+++ b/c4-server/src/main/java/ru/beeatlas/c4/model/C4DocumentManager.java
@@ -230,7 +230,7 @@ public void onException(StructurizrDslParserException e) throws StructurizrDslPa
@Override
public void onParsedProperty(String name, String value) {
if(context != null) {
- context.model.addProperty(new C4Property(context.line.number(), name, value));
+ context.model.addProperty(new C4Property(context.line.number(), context.line.source(), name, value));
} else {
logger.error("onParsedProperty() - Context is null");
}
diff --git a/c4-server/src/main/java/ru/beeatlas/c4/model/C4DocumentModel.java b/c4-server/src/main/java/ru/beeatlas/c4/model/C4DocumentModel.java
index 42eee0f..4f5e7d4 100644
--- a/c4-server/src/main/java/ru/beeatlas/c4/model/C4DocumentModel.java
+++ b/c4-server/src/main/java/ru/beeatlas/c4/model/C4DocumentModel.java
@@ -199,7 +199,7 @@ public void setValid(boolean valid) {
}
public List calculateDecorations() {
- return decorations;
+ return Stream.concat(decorations.stream(), Custom.getInstance().getDecorations(this)).toList();
}
public View findViewByKey(String viewKey) throws Exception {
@@ -251,6 +251,10 @@ public int getRelationshipsCount() {
return relationShipsToLineNumber.size();
}
+ public List getProperties() {
+ return properties;
+ }
+
public List calculateTokens() {
List sorted = tokens.stream().sorted(Comparator.comparing(C4SemanticToken::lineNumber)).toList();
diff --git a/c4-server/src/main/java/ru/beeatlas/c4/model/C4Property.java b/c4-server/src/main/java/ru/beeatlas/c4/model/C4Property.java
index 0a6b055..b92eff3 100644
--- a/c4-server/src/main/java/ru/beeatlas/c4/model/C4Property.java
+++ b/c4-server/src/main/java/ru/beeatlas/c4/model/C4Property.java
@@ -16,5 +16,5 @@
package ru.beeatlas.c4.model;
-public record C4Property(int lineNumber, String name, String value) {
+public record C4Property(int lineNumber, String line, String name, String value) {
}
\ No newline at end of file
diff --git a/c4-server/src/main/java/ru/beeatlas/c4/utils/MxExporter.java b/c4-server/src/main/java/ru/beeatlas/c4/utils/MxExporter.java
index 4144c1d..6d53b83 100644
--- a/c4-server/src/main/java/ru/beeatlas/c4/utils/MxExporter.java
+++ b/c4-server/src/main/java/ru/beeatlas/c4/utils/MxExporter.java
@@ -26,7 +26,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.Stack;
import java.util.UUID;
import java.util.stream.Collectors;
diff --git a/extension/CHANGELOG.md b/extension/CHANGELOG.md
index ae909c7..1a903ac 100644
--- a/extension/CHANGELOG.md
+++ b/extension/CHANGELOG.md
@@ -1,5 +1,14 @@
# Change Log
+## 1.0.16
+
+- Using stdin/stdout instead of sockets (during iteraction with lang server)
+- Using maven shade (with minimizeJar) instead of maven assembly
+- Removing picocli dependency
+- Up lsp4j to 1.0.0
+- Minor TypeScript code cleanup
+- Some custom code decoration
+
## 1.0.15
- Updating JS dependencies
diff --git a/extension/esbuild.js b/extension/esbuild.js
index aa1e5ec..ccc0f36 100644
--- a/extension/esbuild.js
+++ b/extension/esbuild.js
@@ -15,6 +15,7 @@ async function main() {
outfile: 'dist/extension.js',
external: ['vscode'],
logLevel: 'warning',
+ treeShaking: true,
plugins: [
/* add to the end of plugins array */
esbuildProblemMatcherPlugin
diff --git a/extension/package.json b/extension/package.json
index ee9c9a8..5b94eb9 100644
--- a/extension/package.json
+++ b/extension/package.json
@@ -9,7 +9,7 @@
},
"license": "Apache-2.0",
"icon": "images/logo.png",
- "version": "1.0.15",
+ "version": "1.0.16",
"engines": {
"vscode": "^1.73.0"
},
@@ -284,6 +284,7 @@
"activationEvents": [
"onLanguage:c4"
],
+ "browser": "./dist/extension",
"main": "./dist/extension",
"devDependencies": {
"@hpcc-js/wasm-graphviz": "^1.10.0",
@@ -303,7 +304,7 @@
"scripts": {
"check-types": "tsc --noEmit",
"prepare": "yarn run clean && yarn run build",
- "clean": "rimraf lib pack",
+ "clean": "rimraf --glob \"*.jar\"",
"build": "npm run check-types && node esbuild.js --production",
"build-server": "cd ../c4-server && mvnw package -f ./pom.xml -Djps.track.ap.dependencies=false -DassembleDirectory=../extension/server -DoutputDirectory=../extension/",
"clean-server": "cd ../c4-server && mvnw clean -f ./pom.xml",
diff --git a/extension/src/custom/ArchitectureAsACodeView.ts b/extension/src/custom/ArchitectureAsACodeView.ts
index 2969f1a..d696cf5 100644
--- a/extension/src/custom/ArchitectureAsACodeView.ts
+++ b/extension/src/custom/ArchitectureAsACodeView.ts
@@ -1,68 +1,67 @@
/*
- Copyright 2025 VimpelCom PJSC
+ Copyright 2025 VimpelCom PJSC
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
+ http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
*/
-import * as vscode from 'vscode';
-import { Uri } from 'vscode';
-import * as fs from 'fs';
+import { readFileSync } from 'node:fs';
+import { ExtensionContext, MarkdownString, TreeDataProvider, TreeItem, TreeItemCollapsibleState, Uri, window } from 'vscode';
-class Pattern extends vscode.TreeItem {
- label: string;
+class Pattern extends TreeItem {
+ label: string;
langId: string;
snippetName: string;
hover: string[];
- childrens: Pattern[];
+ childrens: Pattern[];
}
-export class PatternProvider implements vscode.TreeDataProvider {
- private uri : Uri;
- constructor(context: vscode.ExtensionContext) {
- const view = vscode.window.createTreeView('architectureAsACodeView', { treeDataProvider: this, showCollapseAll: true, canSelectMany: true });
+export class PatternProvider implements TreeDataProvider {
+ private readonly uri: Uri;
+ constructor(context: ExtensionContext) {
+ const view = window.createTreeView('architectureAsACodeView', { treeDataProvider: this, showCollapseAll: true, canSelectMany: true });
context.subscriptions.push(view);
this.uri = Uri.file(context.asAbsolutePath('snippets.json'));
}
- getTreeItem(element: Pattern): vscode.TreeItem {
+ getTreeItem(element: Pattern): TreeItem {
return element;
- }
+ }
- initChapter(patterns: Pattern[]) : Pattern[] {
+ initChapter(patterns: Pattern[]): Pattern[] {
patterns.forEach(pattern => {
if (pattern.childrens.length === 0) {
pattern.command = {
command: "c4.insert.snippet",
title: "Insert Snippet",
- arguments:[{ langId: pattern.langId, name: pattern.snippetName }]
+ arguments: [{ langId: pattern.langId, name: pattern.snippetName }]
};
- let tooltip = new vscode.MarkdownString("", true);
+ let tooltip = new MarkdownString("", true);
pattern.hover.forEach(h => tooltip.appendMarkdown(h));
pattern.tooltip = tooltip;
} else {
- pattern.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;
+ pattern.collapsibleState = TreeItemCollapsibleState.Collapsed;
}
this.initChapter(pattern.childrens);
- });
- return patterns;
- }
+ });
+ return patterns;
+ }
- async getChildren(element?: Pattern): Promise {
- if(element) {
- return Promise.resolve(element.childrens);
+ async getChildren(element?: Pattern): Promise {
+ if (element) {
+ return element.childrens;
}
- let data = fs.readFileSync(this.uri.fsPath);
+ let data = readFileSync(this.uri.fsPath);
let pattern = JSON.parse(data.toString()) as Pattern
return this.initChapter(pattern.childrens);
- }
+ }
}
\ No newline at end of file
diff --git a/extension/src/custom/ArchitectureCatalogueView.ts b/extension/src/custom/ArchitectureCatalogueView.ts
index 6e0253e..66bef2a 100644
--- a/extension/src/custom/ArchitectureCatalogueView.ts
+++ b/extension/src/custom/ArchitectureCatalogueView.ts
@@ -14,44 +14,43 @@
limitations under the License.
*/
-import * as vscode from 'vscode';
-import * as fs from 'node:fs';
-import * as path from 'node:path';
-import * as httpm from 'typed-rest-client/HttpClient';
import * as config from '../config';
-import { workspace } from 'vscode';
+import { ExtensionContext, TreeDataProvider, TreeItem, WebviewPanel, workspace, window, TreeItemCollapsibleState, commands, EventEmitter, Event, ViewColumn } from 'vscode';
import { generateHmac } from './hmac';
import { IRequestOptions } from 'typed-rest-client/Interfaces';
import { C4Utils } from '../utils/c4-utils';
+import { HttpClient } from 'typed-rest-client/HttpClient';
+import { basename, join } from 'node:path';
+import { writeFile } from 'node:fs';
-class Item extends vscode.TreeItem {
+class Item extends TreeItem {
title: string;
docs: string;
dsl: string;
childrens: Item[];
}
-export class ArchitectureCatalogueProvider implements vscode.TreeDataProvider- {
+export class ArchitectureCatalogueProvider implements TreeDataProvider
- {
private readonly INDEX_ID: string = '/index';
private readonly CONTENT_ID: string = '/content/';
private readonly PATH = '/architecture-center';
- private currentPanel: vscode.WebviewPanel | undefined = undefined;
+ private currentPanel: WebviewPanel | undefined = undefined;
private lastDocs: string | undefined = undefined;
private readonly initItem: (items: Item[]) => Item[];
private readonly initRoot: () => Promise
- ;
- constructor(context: vscode.ExtensionContext) {
+ constructor(context: ExtensionContext) {
- const view = vscode.window.createTreeView('architectureCatalogueView', { treeDataProvider: this, showCollapseAll: true, canSelectMany: true });
+ const view = window.createTreeView('architectureCatalogueView', { treeDataProvider: this, showCollapseAll: true, canSelectMany: true });
context.subscriptions.push(view);
const options: IRequestOptions = {};
options.ignoreSslError = !(workspace.getConfiguration().get(config.BEELINE_CERT_VERIFICATION) as boolean);
const archopsApiUrl = C4Utils.removeTrailingSlash(workspace.getConfiguration().get(config.BEELINE_API_URL) as string);
- const httpc = new httpm.HttpClient('vscode-c4-dsl-plugin', [], options);
+ const httpc = new HttpClient('vscode-c4-dsl-plugin', [], options);
this.initItem = (items: Item[]) : Item[] => {
items.forEach(item => {
@@ -67,7 +66,7 @@ export class ArchitectureCatalogueProvider implements vscode.TreeDataProvider 0) {
- item.collapsibleState = vscode.TreeItemCollapsibleState.None;
+ item.collapsibleState = TreeItemCollapsibleState.None;
item.command = {
command: "c4.architectureCatalogue.showDescription",
title: "Show pattern description",
@@ -82,10 +81,10 @@ export class ArchitectureCatalogueProvider implements vscode.TreeDataProvider 0) ? 'leaf' : 'chapter';
+ const basenamePath = basename(item.dsl);
+ item.contextValue = (basenamePath.length > 0) ? 'leaf' : 'chapter';
} else {
- item.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;
+ item.collapsibleState = TreeItemCollapsibleState.Collapsed;
item.contextValue = 'chapter';
}
@@ -111,24 +110,24 @@ export class ArchitectureCatalogueProvider implements vscode.TreeDataProvider {
+ commands.registerCommand('c4.architectureCatalogue.refresh', async (...args: string[]) => {
this.refresh();
});
- vscode.commands.registerCommand('c4.architectureCatalogue.add', async (element: Item) => {
+ commands.registerCommand('c4.architectureCatalogue.add', async (element: Item) => {
const createFile = (id: string, body: string) => {
- const basename = path.basename(id);
- if (basename.length > 0) {
- const paths = vscode.workspace.workspaceFolders;
+ const basenamePath = basename(id);
+ if (basenamePath.length > 0) {
+ const paths = workspace.workspaceFolders;
if (paths !== undefined && paths.length > 0) {
- const filepath = path.join(paths[0].uri.fsPath, basename);
- fs.writeFile(filepath, body, (error) => {
+ const filepath = join(paths[0].uri.fsPath, basenamePath);
+ writeFile(filepath, body, (error) => {
if (error) {
- vscode.window.showErrorMessage(error.message);
+ window.showErrorMessage(error.message);
} else {
- vscode.workspace.openTextDocument(filepath).then((doc) => { vscode.window.showTextDocument(doc); });
- vscode.commands.executeCommand('c4-server.send-pattern-telemetry', { patternId: id, action: 'pattern' });
+ workspace.openTextDocument(filepath).then((doc) => { window.showTextDocument(doc); });
+ commands.executeCommand('c4-server.send-pattern-telemetry', { patternId: id, action: 'pattern' });
}
});
}
@@ -150,15 +149,15 @@ export class ArchitectureCatalogueProvider implements vscode.TreeDataProvider {
+ commands.registerCommand('c4.architectureCatalogue.showDescription', async (...args: string[]) => {
- const columnToShowIn = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined;
+ const columnToShowIn = window.activeTextEditor ? window.activeTextEditor.viewColumn : undefined;
if (this.currentPanel === undefined) {
- this.currentPanel = vscode.window.createWebviewPanel(
+ this.currentPanel = window.createWebviewPanel(
'architectureCatalogueDescription',
args[0],
- columnToShowIn || vscode.ViewColumn.One,
+ columnToShowIn || ViewColumn.One,
{}
);
} else {
@@ -181,7 +180,7 @@ export class ArchitectureCatalogueProvider implements vscode.TreeDataProvider {
@@ -192,14 +191,14 @@ export class ArchitectureCatalogueProvider implements vscode.TreeDataProvider = new vscode.EventEmitter
- ();
- readonly onDidChangeTreeData: vscode.Event
- = this._onDidChangeTreeData.event;
+ private readonly _onDidChangeTreeData: EventEmitter
- = new EventEmitter
- ();
+ readonly onDidChangeTreeData: Event
- = this._onDidChangeTreeData.event;
refresh(): void {
this._onDidChangeTreeData.fire();
}
- getTreeItem(element: Item): vscode.TreeItem {
+ getTreeItem(element: Item): TreeItem {
return element;
}
diff --git a/extension/src/custom/BusinessCapabilitiesView.ts b/extension/src/custom/BusinessCapabilitiesView.ts
index 876d265..ed4a4ac 100644
--- a/extension/src/custom/BusinessCapabilitiesView.ts
+++ b/extension/src/custom/BusinessCapabilitiesView.ts
@@ -14,14 +14,14 @@
limitations under the License.
*/
-import * as vscode from 'vscode';
-import * as httpm from 'typed-rest-client/HttpClient';
import * as config from '../config';
import { IRequestOptions } from 'typed-rest-client/Interfaces';
import { C4Utils } from '../utils';
import { generateHmac } from './hmac';
+import { EventEmitter, ExtensionContext, MarkdownString, ThemeIcon, TreeDataProvider, TreeItem, TreeItemCollapsibleState, window, workspace, Event, commands, env } from 'vscode';
+import { HttpClient } from 'typed-rest-client/HttpClient';
-class Item extends vscode.TreeItem {
+class Item extends TreeItem {
name: string;
bcid: string | undefined;
hasChildren: boolean | undefined;
@@ -35,7 +35,7 @@ class Child {
businessCapabilities: Item[];
}
-export class BusinessCapabilityProvider implements vscode.TreeDataProvider
- {
+export class BusinessCapabilityProvider implements TreeDataProvider
- {
private readonly PARAMS = '?findBy=CORE';
private readonly ROOT_ID: string = '/business-capability';
private readonly PATH = '/capability/api/v1';
@@ -44,15 +44,15 @@ export class BusinessCapabilityProvider implements vscode.TreeDataProvider
-
private readonly initChild: (items: Item) => Promise
- ;
private readonly initRoot: () => Promise
- ;
- constructor(context: vscode.ExtensionContext) {
+ constructor(context: ExtensionContext) {
- const view = vscode.window.createTreeView('bcCatalogueView', { treeDataProvider: this, showCollapseAll: true, canSelectMany: true });
+ const view = window.createTreeView('bcCatalogueView', { treeDataProvider: this, showCollapseAll: true, canSelectMany: true });
context.subscriptions.push(view);
const options: IRequestOptions = {};
- options.ignoreSslError = !(vscode.workspace.getConfiguration().get(config.BEELINE_CERT_VERIFICATION) as boolean);
- const archopsApiUrl = C4Utils.removeTrailingSlash(vscode.workspace.getConfiguration().get(config.BEELINE_API_URL) as string);
- const httpc = new httpm.HttpClient('vscode-c4-dsl-plugin', [], options);
+ options.ignoreSslError = !(workspace.getConfiguration().get(config.BEELINE_CERT_VERIFICATION) as boolean);
+ const archopsApiUrl = C4Utils.removeTrailingSlash(workspace.getConfiguration().get(config.BEELINE_API_URL) as string);
+ const httpc = new HttpClient('vscode-c4-dsl-plugin', [], options);
this.initChild = async (chapter: Item): Promise
- => {
const children: string = `/${chapter.bcid}/children`;
@@ -70,12 +70,12 @@ export class BusinessCapabilityProvider implements vscode.TreeDataProvider
-
this.initItem = (items: Item[], istc: boolean): Item[] => {
items.forEach(item => {
if (item.hasChildren) {
- item.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;
+ item.collapsibleState = TreeItemCollapsibleState.Collapsed;
}
if (typeof item.description === 'string') {
- item.tooltip = new vscode.MarkdownString(item.description);
+ item.tooltip = new MarkdownString(item.description);
}
- item.iconPath = (istc) ? vscode.ThemeIcon.File : vscode.ThemeIcon.Folder;
+ item.iconPath = (istc) ? ThemeIcon.File : ThemeIcon.Folder;
item.label = item.name;
item.description = item.code;
item.bcid = item.id;
@@ -96,24 +96,24 @@ export class BusinessCapabilityProvider implements vscode.TreeDataProvider
-
catch((error) => []);
};
- vscode.commands.registerCommand('c4.capabilitiesCatalogue.copy', async (element: Item) => {
- vscode.env.clipboard.writeText(element.code).then(() => {
- vscode.window.showInformationMessage(`Capability code ${element.code} copied to clipboard!`);
+ commands.registerCommand('c4.capabilitiesCatalogue.copy', async (element: Item) => {
+ env.clipboard.writeText(element.code).then(() => {
+ window.showInformationMessage(`Capability code ${element.code} copied to clipboard!`);
}, (error) => {
- vscode.window.showErrorMessage(`Failed to copy capability code: ${error.message}`);
+ window.showErrorMessage(`Failed to copy capability code: ${error.message}`);
});
});
}
- private readonly _onDidChangeTreeData: vscode.EventEmitter
- = new vscode.EventEmitter
- ();
- readonly onDidChangeTreeData: vscode.Event
- = this._onDidChangeTreeData.event;
+ private readonly _onDidChangeTreeData: EventEmitter
- = new EventEmitter
- ();
+ readonly onDidChangeTreeData: Event
- = this._onDidChangeTreeData.event;
refresh(): void {
this._onDidChangeTreeData.fire();
}
- getTreeItem(element: Item): vscode.TreeItem {
+ getTreeItem(element: Item): TreeItem {
return element;
}
diff --git a/extension/src/custom/C4InsertSla.ts b/extension/src/custom/C4InsertSla.ts
index 6f5af76..9400319 100644
--- a/extension/src/custom/C4InsertSla.ts
+++ b/extension/src/custom/C4InsertSla.ts
@@ -22,20 +22,21 @@ import {
workspace
} from "vscode";
-import * as fs from 'node:fs';
-import * as httpm from 'typed-rest-client/HttpClient';
import { IRequestOptions } from "typed-rest-client/Interfaces";
import { BEELINE_API_URL, BEELINE_CERT_VERIFICATION } from "../config";
import { generateHmac } from "./hmac";
import { CodeLensCommandArgs } from "../types/CodeLensCommandArgs";
import { dirname, join } from 'node:path';
import { C4Utils } from "../utils/c4-utils";
+import { HttpClient } from "typed-rest-client/HttpClient";
+import { existsSync, readFile } from "node:fs";
+import { EOL } from "node:os";
export function c4InsertSla() {
commands.registerCommand("c4.insert.sla", async (args : CodeLensCommandArgs) => {
const options: IRequestOptions = {};
options.ignoreSslError = !(workspace.getConfiguration().get(BEELINE_CERT_VERIFICATION) as boolean);
- const httpc = new httpm.HttpClient('vscode-c4-dsl-plugin', [], options);
+ const httpc = new HttpClient('vscode-c4-dsl-plugin', [], options);
window.withProgress({
location: ProgressLocation.Notification,
@@ -54,7 +55,7 @@ export function c4InsertSla() {
progress.report({ message: "Формирование SLA..." });
httpc.post(beelineApiUrl + path, content, headers)
.then((result) => { return result.readBody() }).then((body) => {
- var lines = body.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).map((line) => " ".repeat(args.padding) + line);
+ let lines = body.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0).map((line) => " ".repeat(args.padding) + line);
const editor = window.activeTextEditor;
if (editor) {
editor.edit(editBuilder => {
@@ -72,8 +73,7 @@ export function c4InsertSla() {
return;
}
}
- var os = require('os');
- editBuilder.insert(new Position(args.lastLine, 0), lines.join(os.EOL) + os.EOL);
+ editBuilder.insert(new Position(args.lastLine, 0), lines.join(EOL) + EOL);
});
}
})
@@ -98,8 +98,8 @@ export function c4InsertSla() {
if(fileName !== undefined) {
const directoryPath = dirname(fileName);
const fullPath = join(directoryPath, args.apiUrl);
- if(fs.existsSync(fullPath)) {
- fs.readFile(fullPath, 'utf8', (error, data) => {
+ if(existsSync(fullPath)) {
+ readFile(fullPath, 'utf8', (error, data) => {
if (error) {
window.showErrorMessage(error.message);
} else {
diff --git a/extension/src/custom/CjCatalogueView.ts b/extension/src/custom/CjCatalogueView.ts
index e41efc3..f01d36f 100644
--- a/extension/src/custom/CjCatalogueView.ts
+++ b/extension/src/custom/CjCatalogueView.ts
@@ -14,30 +14,30 @@
limitations under the License.
*/
-import * as vscode from 'vscode';
-import * as httpm from 'typed-rest-client/HttpClient';
import * as config from '../config';
import { IRequestOptions } from 'typed-rest-client/Interfaces';
import { C4Utils } from '../utils';
import { generateHmac } from './hmac';
+import { HttpClient } from 'typed-rest-client/HttpClient';
+import { ExtensionContext, TreeDataProvider, TreeItem, TreeItemCollapsibleState, window, workspace } from 'vscode';
-class Cj extends vscode.TreeItem {
+class Cj extends TreeItem {
name: string;
bpmn: boolean;
childrens: Cj[];
}
-export class CjProvider implements vscode.TreeDataProvider {
+export class CjProvider implements TreeDataProvider {
private readonly PARAMS = '?sample=ALL';
private readonly CJ_ID = '/cj';
private readonly PATH = '/cx/api/cx/v1/product';
- constructor(context: vscode.ExtensionContext) {
- const view = vscode.window.createTreeView('cjCatalogueView', { treeDataProvider: this, showCollapseAll: true, canSelectMany: true });
+ constructor(context: ExtensionContext) {
+ const view = window.createTreeView('cjCatalogueView', { treeDataProvider: this, showCollapseAll: true, canSelectMany: true });
context.subscriptions.push(view);
}
- getTreeItem(element: Cj): vscode.TreeItem {
+ getTreeItem(element: Cj): TreeItem {
return element;
}
@@ -45,7 +45,7 @@ export class CjProvider implements vscode.TreeDataProvider {
cjs.forEach(cj => {
cj.label = cj.name;
if (cj.childrens.length === 0) { /* empty */ } else {
- cj.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;
+ cj.collapsibleState = TreeItemCollapsibleState.Collapsed;
}
this.initChapter(cj.childrens);
});
@@ -59,9 +59,9 @@ export class CjProvider implements vscode.TreeDataProvider {
const headers = generateHmac('GET', this.PATH + this.CJ_ID);
const options: IRequestOptions = {};
- options.ignoreSslError = !(vscode.workspace.getConfiguration().get(config.BEELINE_CERT_VERIFICATION) as boolean);
- const beelineApiUrl = C4Utils.removeTrailingSlash(vscode.workspace.getConfiguration().get(config.BEELINE_API_URL) as string);
- const httpc = new httpm.HttpClient('vscode-c4-dsl-plugin', [], options);
+ options.ignoreSslError = !(workspace.getConfiguration().get(config.BEELINE_CERT_VERIFICATION) as boolean);
+ const beelineApiUrl = C4Utils.removeTrailingSlash(workspace.getConfiguration().get(config.BEELINE_API_URL) as string);
+ const httpc = new HttpClient('vscode-c4-dsl-plugin', [], options);
let path = beelineApiUrl + this.PATH + this.CJ_ID + this.PARAMS;
return httpc.get(path, headers).
diff --git a/extension/src/extension.ts b/extension/src/extension.ts
index 413abc7..1c3eccf 100644
--- a/extension/src/extension.ts
+++ b/extension/src/extension.ts
@@ -26,16 +26,14 @@ import {
TextEditor
} from "vscode";
-import * as path from "node:path";
-import * as cp from "node:child_process";
-import * as readline from "node:readline";
+import { exec } from "node:child_process";
import {
LanguageClientOptions,
StateChangeEvent,
State
} from "vscode-languageclient";
-import { LanguageClient } from "vscode-languageclient/node";
+import { LanguageClient, ServerOptions } from "vscode-languageclient/node";
import {
CommandResultCode,
ConfigurationOptions,
@@ -43,8 +41,6 @@ import {
TextDocumentChangeConfig,
} from "./types";
import { C4Utils } from "./utils";
-import { PatternProvider } from "./custom/ArchitectureAsACodeView";
-import { ArchitectureCatalogueProvider } from "./custom/ArchitectureCatalogueView";
import { c4InsertSnippet } from "./custom/C4InsertSnippet";
import { c4InsertSla } from "./custom/C4InsertSla";
import { c4ExportDeployment } from "./custom/C4ExportDeployment";
@@ -53,34 +49,34 @@ import { StructurizrPreviewService } from "./services/StructurizrPreviewService"
import { CodeLensCommandArgs } from "./types/CodeLensCommandArgs";
import { PreviewService } from "./services/PreviewService";
import { DecorationService } from "./services/DecorationService";
-import { basename, dirname, join } from "node:path";
+import { basename, dirname, join, delimiter } from "node:path";
import { writeFile } from "node:fs";
import { BEELINE_CERT_VERIFICATION } from "./config";
+import { ArchitectureCatalogueProvider } from "./custom/ArchitectureCatalogueView";
+import { PatternProvider } from "./custom/ArchitectureAsACodeView";
import { BusinessCapabilityProvider } from "./custom/BusinessCapabilitiesView";
-let proc: cp.ChildProcess;
-
export function activate(context: ExtensionContext) {
let envJava = process.env;
const javaPath = workspace.getConfiguration().get(config.JAVA_PATH) as string;
if(javaPath !== undefined && javaPath.length > 0) {
- const javaBinPath = path.join(javaPath, "bin");
+ const javaBinPath = join(javaPath, "bin");
let envPath = process.env.PATH;
if(envPath !== undefined) {
- const pathParts = envPath.split(path.delimiter);
+ const pathParts = envPath.split(delimiter);
const filteredPathParts = pathParts.filter(part => !part.toLowerCase().includes('jdk-') && !part.toLowerCase().includes('jre-'));
- envPath = filteredPathParts.join(path.delimiter);
+ envPath = filteredPathParts.join(delimiter);
}
envJava = {
...process.env,
- PATH: `${javaBinPath}${path.delimiter}${envPath}`
+ PATH: `${javaBinPath}${delimiter}${envPath}`
};
}
- cp.exec("java -version", { env: envJava }, (err, stdOut, stdErr) => {
+ exec("java -version", { env: envJava }, (err, stdOut, stdErr) => {
if (
err?.message.includes("'java' is not recognized") ||
err?.message.includes("'java' not found") ||
@@ -113,10 +109,28 @@ function initExtension(context: ExtensionContext, env: NodeJS.ProcessEnv) {
},
};
+ const jarPath = context.asAbsolutePath('server.jar');
+
+ const args = ["-XX:+UseParallelGC", "-XX:TieredStopAtLevel=1", "-Dfile.encoding=UTF8", "-jar", jarPath];
+ const opts = (workspace.workspaceFolders) ? { cwd: workspace.workspaceFolders[0].uri.fsPath, shell: true, env : env } : { shell: true, env : env };
+
+ const serverOptions: ServerOptions = {
+ run: {
+ command: 'java',
+ args: args,
+ options : opts
+ },
+ debug: {
+ command: 'java',
+ args: args,
+ options : opts
+ }
+ };
+
const languageClient = new LanguageClient(
"c4LanguageClient",
"C4 Language Server",
- C4Utils.getServerOptions(),
+ serverOptions,
clientOptions
);
@@ -143,175 +157,153 @@ function initExtension(context: ExtensionContext, env: NodeJS.ProcessEnv) {
}
});
- const READY_ECHO = "READY_TO_CONNECT";
const STRUCTURIZ_COM = "https://structurizr.com/json";
statusBarItem.text = "C4 DSL Socket Server is starting up...";
statusBarItem.color = "white";
- const jar = path.join('server','c4-server.jar');
- const jarPath = context.asAbsolutePath(jar);
-
- const args = ["-Dfile.encoding=UTF8", "-jar", jarPath, "-e=" + READY_ECHO];
- const opts = (workspace.workspaceFolders) ? { cwd: workspace.workspaceFolders[0].uri.fsPath, shell: true, env : env } : { shell: true, env : env };
- proc = cp.spawn("java", args, opts);
-
- if (proc.stdout) {
- const reader = readline.createInterface({ input: proc.stdout, terminal: false, });
-
- const startListener = (line: string) => {
- if (line.endsWith(READY_ECHO)) {
- reader.removeListener("line", startListener);
- languageClient.start().then(() => {
-
- updateServerConfigurationIndent();
- updateServerConfiguration(context);
-
- commands.registerCommand("c4.workspace.save.json", async () => {
- const doc = window.activeTextEditor?.document as TextDocument;
- const refreshOptions: RefreshOptions = {
- viewKey: undefined,
- document: doc.uri.fsPath,
- svg: undefined,
- mx: undefined
- };
- commands.executeCommand("c4-server.get-json", refreshOptions).then(async (callback) => {
- const result = callback as CommandResultCode;
- if (result.message !== undefined) {
- const directoryPath = dirname(doc.uri.fsPath);
- const bname = basename('workspace.json');
- const filepath = join(directoryPath, bname);
- writeFile(filepath, result.message, function (error) {
- if (error) {
- window.showErrorMessage(error.message);
- }
- });
- }
- });
- });
-
- const statusBarJsonItem = window.createStatusBarItem(StatusBarAlignment.Left, 100);
- statusBarJsonItem.command = "c4.workspace.save.json";
- context.subscriptions.push(statusBarJsonItem);
- statusBarJsonItem.text = "Write workspace.json";
-
- const decType = window.createTextEditorDecorationType({});
- const textDecorations = workspace.getConfiguration().get(config.TEXT_DECORATIONS) as TextDocumentChangeConfig;
-
- const switchJson = (editor: TextEditor | undefined) => {
- if (editor && editor?.document && editor?.document.languageId === "c4" && editor?.document.fileName && editor?.document.fileName.toLowerCase().endsWith('workspace.dsl')) {
- statusBarJsonItem.show();
- } else {
- statusBarJsonItem.hide();
- }
- };
-
- if (textDecorations !== "off") {
- const decorationService = new DecorationService(decType);
-
- if (textDecorations === "onSave") {
- workspace.onDidSaveTextDocument((savedDocument) => {
- decorationService.triggerDecorations(undefined, savedDocument);
- });
- } else if (textDecorations === "onChange") {
- workspace.onDidChangeTextDocument((changed) => {
- decorationService.triggerDecorations(undefined, changed.document);
- });
+ languageClient.start().then(() => {
+
+ updateServerConfigurationIndent();
+ updateServerConfiguration(context);
+
+ commands.registerCommand("c4.workspace.save.json", async () => {
+ const doc = window.activeTextEditor?.document as TextDocument;
+ const refreshOptions: RefreshOptions = {
+ viewKey: undefined,
+ document: doc.uri.fsPath,
+ svg: undefined,
+ mx: undefined
+ };
+ commands.executeCommand("c4-server.get-json", refreshOptions).then(async (callback) => {
+ const result = callback as CommandResultCode;
+ if (result.message !== undefined) {
+ const directoryPath = dirname(doc.uri.fsPath);
+ const bname = basename('workspace.json');
+ const filepath = join(directoryPath, bname);
+ writeFile(filepath, result.message, function (error) {
+ if (error) {
+ window.showErrorMessage(error.message);
}
+ });
+ }
+ });
+ });
+
+ const statusBarJsonItem = window.createStatusBarItem(StatusBarAlignment.Left, 100);
+ statusBarJsonItem.command = "c4.workspace.save.json";
+ context.subscriptions.push(statusBarJsonItem);
+ statusBarJsonItem.text = "Write workspace.json";
+
+ const decType = window.createTextEditorDecorationType({});
+ const textDecorations = workspace.getConfiguration().get(config.TEXT_DECORATIONS) as TextDocumentChangeConfig;
+
+ const switchJson = (editor: TextEditor | undefined) => {
+ if (editor?.document && editor?.document.languageId === "c4" && editor?.document.fileName?.toLowerCase().endsWith('workspace.dsl')) {
+ statusBarJsonItem.show();
+ } else {
+ statusBarJsonItem.hide();
+ }
+ };
- window.onDidChangeActiveTextEditor((editor) => {
- editor ??= window.activeTextEditor;
- switchJson(editor);
- decorationService.triggerDecorations(editor, undefined);
- });
- decorationService.triggerDecorations(window.activeTextEditor, undefined);
- } else {
- window.onDidChangeActiveTextEditor((editor) => {
- editor ??= window.activeTextEditor;
- switchJson(editor);
- });
- }
-
- commands.executeCommand('setContext', 'extension:c4', true);
+ if (textDecorations === "off") {
+ window.onDidChangeActiveTextEditor((editor) => {
+ editor ??= window.activeTextEditor;
+ switchJson(editor);
+ });
+ } else {
+ const decorationService = new DecorationService(decType);
- const embeddedPreviewService = new PreviewService(context);
- const structurizrPreviewService = new StructurizrPreviewService(STRUCTURIZ_COM);
- c4InsertSnippet();
- c4InsertSla();
- c4ExportDeployment();
+ if (textDecorations === "onSave") {
+ workspace.onDidSaveTextDocument((savedDocument) => {
+ decorationService.triggerDecorations(undefined, savedDocument);
+ });
+ } else if (textDecorations === "onChange") {
+ workspace.onDidChangeTextDocument((changed) => {
+ decorationService.triggerDecorations(undefined, changed.document);
+ });
+ }
- commands.registerCommand("c4.diagram.export.svg", async () => {
- embeddedPreviewService.getSvg(context);
- });
+ window.onDidChangeActiveTextEditor((editor) => {
+ editor ??= window.activeTextEditor;
+ switchJson(editor);
+ decorationService.triggerDecorations(editor, undefined);
+ });
+ decorationService.triggerDecorations(window.activeTextEditor, undefined);
+ }
- commands.registerCommand("c4.diagram.export.mx", async () => {
- embeddedPreviewService.getMx(context);
- });
+ commands.executeCommand('setContext', 'extension:c4', true);
- commands.registerCommand("c4.diagram.import.layout.mx", async () => {
- embeddedPreviewService.importLayoutMax(context);
- });
+ const embeddedPreviewService = new PreviewService(context);
+ const structurizrPreviewService = new StructurizrPreviewService(STRUCTURIZ_COM);
+ c4InsertSnippet();
+ c4InsertSla();
+ c4ExportDeployment();
- commands.registerCommand("c4.show.diagram", async (args : CodeLensCommandArgs) => {
+ commands.registerCommand("c4.diagram.export.svg", async () => {
+ embeddedPreviewService.getSvg(context);
+ });
- const render = workspace.getConfiguration().get(config.DIAGRAM_RENDER) as string;
+ commands.registerCommand("c4.diagram.export.mx", async () => {
+ embeddedPreviewService.getMx(context);
+ });
- if(render === 'https://structurizr.com') {
- structurizrPreviewService.currentDiagram = args.diagramKey;
- structurizrPreviewService.currentDocument = window.activeTextEditor?.document as TextDocument;
- await structurizrPreviewService.updateWebView(args.encodedWorkspace);
- } else {
- embeddedPreviewService.currentDiagramAsDot = args.diagramAsDot;
- embeddedPreviewService.currentDiagram = args.diagramKey;
- embeddedPreviewService.currentDocument = window.activeTextEditor?.document as TextDocument;
- await embeddedPreviewService.updateWebView();
- }
- });
+ commands.registerCommand("c4.diagram.import.layout.mx", async () => {
+ embeddedPreviewService.importLayoutMax(context);
+ });
- workspace.onDidSaveTextDocument((document: TextDocument) => {
- const autolayoutUrl = workspace.getConfiguration().get(config.DIAGRAM_RENDER) as string;
- if (autolayoutUrl === 'https://structurizr.com') {
- structurizrPreviewService.triggerRefresh(document);
- } else {
- embeddedPreviewService.triggerRefresh(document);
- }
- });
+ commands.registerCommand("c4.show.diagram", async (args : CodeLensCommandArgs) => {
- workspace.onDidChangeConfiguration(event => {
- if (event.affectsConfiguration(config.AUTO_FORMAT_INDENT)) {
- updateServerConfigurationIndent()
- }
- updateServerConfiguration(context);
- });
+ const render = workspace.getConfiguration().get(config.DIAGRAM_RENDER) as string;
- const beelineApiUrl = C4Utils.removeTrailingSlash(workspace.getConfiguration().get(config.BEELINE_API_URL) as string);
- const beelineApiSecret = workspace.getConfiguration().get(config.BEELINE_API_SECRET) as string;
- const beelineApiKey = workspace.getConfiguration().get(config.BEELINE_API_KEY) as string;
- if(beelineApiUrl.length === 0 || beelineApiSecret.length === 0 || beelineApiKey.length === 0) {
- window.showInformationMessage(
- 'You haven\'t filled out all the extension settings yet. Complete the configuration to use all the features.',
- 'Open settings'
- ).then(selection => {
- if (selection === 'Open settings') {
- commands.executeCommand( 'workbench.action.openSettings', '@ext:vimpelcom.c4-varp');
- }
- });
- }
- });
+ if(render === 'https://structurizr.com') {
+ structurizrPreviewService.currentDiagram = args.diagramKey;
+ structurizrPreviewService.currentDocument = window.activeTextEditor?.document as TextDocument;
+ await structurizrPreviewService.updateWebView(args.encodedWorkspace);
+ } else {
+ embeddedPreviewService.currentDiagramAsDot = args.diagramAsDot;
+ embeddedPreviewService.currentDiagram = args.diagramKey;
+ embeddedPreviewService.currentDocument = window.activeTextEditor?.document as TextDocument;
+ await embeddedPreviewService.updateWebView();
}
- };
+ });
+
+ workspace.onDidSaveTextDocument((document: TextDocument) => {
+ const autolayoutUrl = workspace.getConfiguration().get(config.DIAGRAM_RENDER) as string;
+ if (autolayoutUrl === 'https://structurizr.com') {
+ structurizrPreviewService.triggerRefresh(document);
+ } else {
+ embeddedPreviewService.triggerRefresh(document);
+ }
+ });
- reader.on('line', startListener);
+ workspace.onDidChangeConfiguration(event => {
+ if (event.affectsConfiguration(config.AUTO_FORMAT_INDENT)) {
+ updateServerConfigurationIndent()
+ }
+ updateServerConfiguration(context);
+ });
+
+ const beelineApiUrl = C4Utils.removeTrailingSlash(workspace.getConfiguration().get(config.BEELINE_API_URL) as string);
+ const beelineApiSecret = workspace.getConfiguration().get(config.BEELINE_API_SECRET) as string;
+ const beelineApiKey = workspace.getConfiguration().get(config.BEELINE_API_KEY) as string;
+ if(beelineApiUrl.length === 0 || beelineApiSecret.length === 0 || beelineApiKey.length === 0) {
+ window.showInformationMessage(
+ 'You haven\'t filled out all the extension settings yet. Complete the configuration to use all the features.',
+ 'Open settings'
+ ).then(selection => {
+ if (selection === 'Open settings') {
+ commands.executeCommand( 'workbench.action.openSettings', '@ext:vimpelcom.c4-varp');
+ }
+ });
+ }
new PatternProvider(context);
new BusinessCapabilityProvider(context);
const architectureCatalogueProvider : ArchitectureCatalogueProvider = new ArchitectureCatalogueProvider(context);
architectureCatalogueProvider.refresh();
- } else {
- statusBarItem.text = "Connection to C4 DSL Socket Server could not be established";
- statusBarItem.color = "red";
- }
+ });
}
function updateServerConfigurationIndent() {
@@ -327,10 +319,4 @@ export function updateServerConfiguration(context: ExtensionContext) {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = (workspace.getConfiguration().get(BEELINE_CERT_VERIFICATION) as boolean) ? "1" : "0";
commands.executeCommand("c4-server.configuration", configOptions);
-}
-
-export function deactivate() {
- if (proc) {
- proc.kill("SIGINT");
- }
}
\ No newline at end of file
diff --git a/extension/src/services/DecorationService.ts b/extension/src/services/DecorationService.ts
index 69a9ac1..bb0458f 100644
--- a/extension/src/services/DecorationService.ts
+++ b/extension/src/services/DecorationService.ts
@@ -25,7 +25,7 @@ import {
import { CommandResultTextDecorations, DecoratedRange } from "../types";
class DecorationService {
- private decorationType: TextEditorDecorationType;
+ private readonly decorationType: TextEditorDecorationType;
constructor(decorationType: TextEditorDecorationType) {
this.decorationType = decorationType;
@@ -35,13 +35,9 @@ class DecorationService {
editor: TextEditor | undefined,
document: TextDocument | undefined
) {
- if (!editor) {
- editor = window.activeTextEditor;
- }
- if (!document) {
- document = editor?.document;
- }
- if (editor && document && document.languageId === "c4") {
+ editor ??= window.activeTextEditor;
+ document ??= editor?.document;
+ if (editor && document?.languageId === "c4") {
commands.executeCommand("c4-server.text-decorations", { uri: document.uri.path, }).then((callback) => {
editor?.setDecorations(
this.decorationType,
diff --git a/extension/src/services/StructurizrPreviewService.ts b/extension/src/services/StructurizrPreviewService.ts
index d54ccf7..cd1b8d1 100644
--- a/extension/src/services/StructurizrPreviewService.ts
+++ b/extension/src/services/StructurizrPreviewService.ts
@@ -25,12 +25,12 @@ import { RefreshOptions } from "../types/RefreshOptions";
import { CommandResultCode } from "../types/CommandResultCode";
class StructurizrPreviewService {
- private renderService: string;
+ private readonly renderService: string;
private panel: WebviewPanel | undefined;
private _currentDiagram: string;
private _currentDocument: TextDocument;
- private VIEW_TYPE: string = 'Structurizr Preview';
+ private readonly VIEW_TYPE: string = 'Structurizr Preview';
constructor(renderService: string) {
this.renderService = renderService;
diff --git a/extension/src/utils/c4-utils.ts b/extension/src/utils/c4-utils.ts
index b19224f..65e5066 100644
--- a/extension/src/utils/c4-utils.ts
+++ b/extension/src/utils/c4-utils.ts
@@ -14,31 +14,12 @@
limitations under the License.
*/
-import * as net from "net";
-import { ServerOptions, StreamInfo } from "vscode-languageclient/node";
-
class C4Utils {
static getJavaVersion(versionDetails: string): number {
- const matchedRegex = versionDetails.match(/version\s"\d\d/i)?.at(0);
- if (matchedRegex) {
- const version = parseInt(
+ const matchedRegex = new RegExp(/version\s"\d\d/i).exec(versionDetails)?.at(0);
+ return (matchedRegex) ? Number.parseInt(
matchedRegex.slice('version "'.length, matchedRegex.length)
- );
- return version;
- }
- return 0;
- }
-
- static getServerOptions(): ServerOptions {
- const serverDebugOptions = () => {
- let socket = net.connect({ port: 5008 });
- let result: StreamInfo = {
- writer: socket,
- reader: socket,
- };
- return Promise.resolve(result);
- };
- return serverDebugOptions;
+ ) : 0;
}
static removeTrailingSlash(str: string): string {