diff --git a/.github/workflows/backend-ci.yml b/.github/workflows/backend-ci.yml index 47bd4857..4315d586 100644 --- a/.github/workflows/backend-ci.yml +++ b/.github/workflows/backend-ci.yml @@ -42,6 +42,10 @@ jobs: run: mvn -B test - name: Integration tests run: mvn -B verify + - name: Export OpenAPI spec + run: mvn exec:java@export-openapi + - name: Verify committed OpenAPI spec is up to date + run: git diff --exit-code -- ../frontend/openapi.json - name: Update third-party licenses (Renovate PRs only) if: > github.event_name == 'pull_request' && diff --git a/.github/workflows/frontend-ci.yml b/.github/workflows/frontend-ci.yml index c68cad27..58e323f3 100644 --- a/.github/workflows/frontend-ci.yml +++ b/.github/workflows/frontend-ci.yml @@ -37,6 +37,8 @@ jobs: echo "PUBLIC_REPOSITORY_URL=https://github.com/${GITHUB_REPOSITORY}" >> "$GITHUB_ENV" - name: Clean install run: npm run clean-install + - name: Generate API client + run: npm run api:generate - name: Update third party licenses (Renovate PRs only) if: > github.event_name == 'pull_request' && diff --git a/.github/workflows/publish-test-images.yml b/.github/workflows/publish-test-images.yml index 60f82ac5..efe9e5e0 100644 --- a/.github/workflows/publish-test-images.yml +++ b/.github/workflows/publish-test-images.yml @@ -30,6 +30,8 @@ jobs: echo "PUBLIC_REPOSITORY_URL=https://github.com/${GITHUB_REPOSITORY}" >> "$GITHUB_ENV" - name: Clean install run: npm run clean-install + - name: Generate API client + run: npm run api:generate - name: Build env: PUBLIC_APP_VERSION: ${{ env.APP_VERSION }} diff --git a/README.md b/README.md index 275b1207..94778810 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,30 @@ When the backend is running, Swagger UI is available at: - `http://localhost:8080/swagger-ui.html` +### Generated frontend API client + +The frontend calls the backend through a typed client generated by +[`@hey-api/openapi-ts`](https://heyapi.dev/) from the backend's OpenAPI spec. To keep CI and +Docker builds independent of a running backend, the spec is committed as a contract at +`frontend/openapi.json` and the client (`frontend/src/lib/api/generated`, git-ignored) is +generated from it: + +```bash +cd frontend +npm run api:generate # writes src/lib/api/generated from ./openapi.json +``` + +When backend routes or DTOs change, regenerate and commit the contract from the backend module: + +```bash +cd backend +mvn exec:java@export-openapi +# writes ../frontend/openapi.json - commit the result +``` + +Backend CI runs the same export and fails if `frontend/openapi.json` is out of date, so the +committed contract can never drift from the controllers. + ## Development Workflows ### Backend @@ -140,6 +164,7 @@ mvn -B verify ```bash cd frontend npm run clean-install +npm run api:generate npm run test npm run lint npm run build diff --git a/backend/pom.xml b/backend/pom.xml index 55e6825f..87c51df9 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -194,6 +194,23 @@ + + org.codehaus.mojo + exec-maven-plugin + 3.6.3 + + + export-openapi + none + java + + org.rdfarchitect.OpenApiSpecExport + runtime + false + + + + diff --git a/backend/src/main/java/org/rdfarchitect/OpenApiSpecExport.java b/backend/src/main/java/org/rdfarchitect/OpenApiSpecExport.java new file mode 100644 index 00000000..70d212fb --- /dev/null +++ b/backend/src/main/java/org/rdfarchitect/OpenApiSpecExport.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2024-2026 SOPTIM AG + * + * 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 + * + * 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. + * + */ + +package org.rdfarchitect; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.core.util.DefaultIndenter; +import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.web.client.RestClient; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * * Exports the springdoc OpenAPI document to a deterministic JSON file so the frontend can + * generate * its API client offline (in CI and in Docker) without a running backend. * * + * + *

Runs as a standalone Maven goal: {@code mvn compile exec:java@export-openapi}. The output * + * path defaults to {@code ../frontend/openapi.json} (relative to the backend module) and can be * + * overridden with the first program argument or {@code -Dopenapi.export.path=...}. * * + * + *

Boots the full Spring application on an ephemeral port (server.port=0), fetches the spec, * + * normalizes it, writes it to disk, and shuts the context down. CI runs this and diffs the result * + * so the committed spec can never drift from the controllers. + */ +public final class OpenApiSpecExport { + + private static final String DEFAULT_OUTPUT_PATH = "../frontend/openapi.json"; + + private OpenApiSpecExport() {} + + public static void main(String[] args) throws IOException { + // Use an ephemeral port so we never collide with a developer's running backend. + System.setProperty("server.port", "0"); + + try (ConfigurableApplicationContext ctx = SpringApplication.run(Launcher.class, args)) { + if (!(ctx instanceof WebServerApplicationContext webCtx)) { + throw new IllegalStateException( + "Expected a WebServerApplicationContext but got " + ctx.getClass()); + } + int port = Objects.requireNonNull(webCtx.getWebServer()).getPort(); + String rawSpec = + RestClient.create() + .get() + .uri("http://localhost:" + port + "/v3/api-docs") + .retrieve() + .body(String.class); + + if (rawSpec == null || !rawSpec.contains("\"openapi\"")) { + throw new IllegalStateException( + "Unexpected response from /v3/api-docs: " + rawSpec); + } + + String formattedSpec = formatDeterministically(rawSpec); + + Path target = resolveTargetPath(args); + Path parent = target.toAbsolutePath().normalize().getParent(); + if (parent != null) { + Files.createDirectories(parent); + } + Files.writeString(target, formattedSpec, StandardCharsets.UTF_8); + + System.out.println("Wrote OpenAPI spec to " + target.toAbsolutePath().normalize()); + } + } + + private static Path resolveTargetPath(String[] args) { + if (args.length > 0 && !args[0].isBlank()) { + return Path.of(args[0]); + } + return Path.of(System.getProperty("openapi.export.path", DEFAULT_OUTPUT_PATH)); + } + + /** + * * Re-serializes the spec with sorted keys and a fixed {@code \n} indenter so the output is * + * stable across runs and operating systems. The {@code servers} entry is dropped because it * + * reflects the request URL and is overridden at runtime by the frontend client ({@code * + * src/lib/api/hey-api.ts}); keeping it adds no value to the committed contract. The {@code * + * info.version} is pinned to {@code 0.0.0} because it is derived from the build version (git * + * describe), which changes on every commit and would otherwise make the committed contract * + * drift on every build. + */ + private static String formatDeterministically(String rawSpec) throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + mapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS); + + DefaultIndenter indenter = new DefaultIndenter(" ", "\n"); + DefaultPrettyPrinter printer = new DefaultPrettyPrinter(); + printer.indentObjectsWith(indenter); + printer.indentArraysWith(indenter); + + Map spec = mapper.readValue(rawSpec, new TypeReference<>() {}); + spec.remove("servers"); + if (spec.get("info") instanceof Map info) { + @SuppressWarnings("unchecked") + Map writableInfo = (Map) info; + writableInfo.put("version", "0.0.0"); + } + sortRequiredArrays(spec); + return mapper.writer(printer).writeValueAsString(spec) + "\n"; + } + + /** + * * Sorts every {@code required} string array in the document. springdoc derives this list from + * * field reflection, whose order is not guaranteed across JVMs; {@code required} is an + * unordered * set in OpenAPI, so sorting it makes the committed contract robust against that + * variance. + */ + private static void sortRequiredArrays(Object node) { + if (node instanceof Map map) { + Object required = map.get("required"); + if (required instanceof List values + && values.stream().allMatch(String.class::isInstance)) { + List sorted = values.stream().map(String.class::cast).sorted().toList(); + @SuppressWarnings("unchecked") + Map writableMap = (Map) map; + writableMap.put("required", sorted); + } + map.values().forEach(OpenApiSpecExport::sortRequiredArrays); + } else if (node instanceof List values) { + values.forEach(OpenApiSpecExport::sortRequiredArrays); + } + } +} diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/OntologyKnownInformationRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/OntologyKnownInformationRESTController.java index 9788c1b5..352786d9 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/OntologyKnownInformationRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/OntologyKnownInformationRESTController.java @@ -19,6 +19,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -57,10 +58,16 @@ public class OntologyKnownInformationRESTController { content = @Content( mediaType = "application/json", - schema = @Schema(implementation = OntologyField.class))) + array = + @ArraySchema( + schema = + @Schema( + implementation = + OntologyField + .class)))) }) @GetMapping - public List getOntology( + public List getKnownOntologyFields( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/SchemaComparisonFromFilesRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/SchemaComparisonFromFilesRESTController.java index af7ca7a8..4056c6f5 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/SchemaComparisonFromFilesRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/SchemaComparisonFromFilesRESTController.java @@ -53,6 +53,7 @@ public class SchemaComparisonFromFilesRESTController { @Operation( summary = "compare schemas", description = "Compare two given graphs", + tags = {"comparison"}, responses = { @ApiResponse( responseCode = "200", @@ -68,7 +69,7 @@ public class SchemaComparisonFromFilesRESTController { .class)))) }) @PostMapping - public List compareSchemas( + public List compareSchemasFromFiles( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/SchemaValidationFromFileRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/SchemaValidationFromFileRESTController.java index 92703d70..ac28644a 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/SchemaValidationFromFileRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/SchemaValidationFromFileRESTController.java @@ -68,7 +68,7 @@ public class SchemaValidationFromFileRESTController { SchemaValidationReportDTO.class))) }) @PostMapping - public SchemaValidationReportDTO validateSchema( + public SchemaValidationReportDTO validateFile( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/DatasetRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/DatasetRESTController.java index 097df960..84058152 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/DatasetRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/DatasetRESTController.java @@ -24,6 +24,7 @@ import lombok.RequiredArgsConstructor; import org.rdfarchitect.api.controller.Response; +import org.rdfarchitect.api.dto.DatasetDTO; import org.rdfarchitect.services.select.ListDatasetsUseCase; import org.rdfarchitect.services.update.dataset.DeleteDatasetUseCase; import org.slf4j.Logger; @@ -50,11 +51,12 @@ public class DatasetRESTController { @Operation( summary = "List datasets", - description = "Lists all non-snapshots datasets", + description = + "Lists all non-snapshots datasets including their prefixes and read-only status.", tags = {"dataset"}, responses = {@ApiResponse(responseCode = "200")}) @GetMapping - public List listDatasets( + public List listDatasets( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/GlobalClassLayoutDataRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/GlobalClassLayoutDataRESTController.java index e109d105..b6994a34 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/GlobalClassLayoutDataRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/GlobalClassLayoutDataRESTController.java @@ -50,12 +50,12 @@ public class GlobalClassLayoutDataRESTController { private final UpdateClassPositionsUseCase updateClassPositionsUseCase; @Operation( - summary = "updates class positions", + summary = "updates class positions on dataset level", description = "Updates the positions for all the classes provided in the request body with the provided coordinates.", tags = {"diagram", "layout", "class"}) @PutMapping - public String updateClassPositions( + public String updateDatasetClassPositions( @Parameter(description = "The name/url of the inquirer.") @RequestHeader(value = "origin", required = false, defaultValue = "unknown") String originURL, diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/AllCustomDatasetDiagramsRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/AllCustomDatasetDiagramsRESTController.java index 0991d2e9..b347c854 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/AllCustomDatasetDiagramsRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/AllCustomDatasetDiagramsRESTController.java @@ -17,7 +17,12 @@ package org.rdfarchitect.api.controller.datasets.diagrams; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; @@ -44,8 +49,26 @@ public class AllCustomDatasetDiagramsRESTController { private final GetCustomDiagramsUseCase getCustomDiagramsUseCase; + @Operation( + summary = "list custom diagrams for dataset", + description = + "Returns a list of all custom diagrams for the specified dataset. Each diagram includes its ID, name, and other relevant information.", + tags = {"diagram"}, + responses = + @ApiResponse( + responseCode = "200", + content = + @Content( + mediaType = "application/json", + array = + @ArraySchema( + schema = + @Schema( + implementation = + CustomDiagram + .class))))) @GetMapping - public List getCustomDiagramList( + public List getCustomDatasetDiagramList( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramIDRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramIDRESTController.java index 5c6eb29b..70cc0609 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramIDRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramIDRESTController.java @@ -42,7 +42,7 @@ public class CrossProfileDiagramIDRESTController { private final DatabasePort databasePort; @GetMapping - public String getCrossProfileRenderingData( + public String getCrossProfileDiagramId( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramRestController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramRestController.java index 06cfcda4..40ae1e42 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramRestController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramRestController.java @@ -43,7 +43,7 @@ public class CrossProfileDiagramRestController { private final GetCustomDiagramsUseCase getCustomDiagramsUseCase; @GetMapping - public CrossProfileDiagramDTO getCrossProfileRenderingData( + public CrossProfileDiagramDTO getCrossProfileDiagram( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CustomDatasetDiagramAllClassesRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CustomDatasetDiagramAllClassesRESTController.java index e4a10b96..1ff2e5dd 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CustomDatasetDiagramAllClassesRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CustomDatasetDiagramAllClassesRESTController.java @@ -49,7 +49,7 @@ public class CustomDatasetDiagramAllClassesRESTController { private final CustomDiagramLayoutUseCase customDiagramLayoutUseCase; @PostMapping - public String addToDiagram( + public String addToCustomDatasetDiagram( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, @@ -80,7 +80,7 @@ public String addToDiagram( } @DeleteMapping - public String removeFromDiagram( + public String removeFromCustomDatasetDiagram( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CustomDatasetDiagramsRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CustomDatasetDiagramsRESTController.java index b97b122d..7072b178 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CustomDatasetDiagramsRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/diagrams/CustomDatasetDiagramsRESTController.java @@ -51,12 +51,12 @@ public class CustomDatasetDiagramsRESTController { private final RenderCIMCollectionUseCase renderer; - private final DeleteCustomDiagramUseCase deleteCustomDiagram; + private final DeleteCustomDiagramUseCase deleteCustomDiagramUseCase; - private final ReplaceCustomDiagramUseCase replaceCustomDiagram; + private final ReplaceCustomDiagramUseCase replaceCustomDiagramUseCase; @GetMapping - public RenderingDataDTO getDiagramRenderingData( + public RenderingDataDTO getCustomDatasetViewRenderingData( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, @@ -83,7 +83,7 @@ public RenderingDataDTO getDiagramRenderingData( } @PutMapping - public String replaceDiagram( + public String replaceCustomDatasetDiagram( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, @@ -101,7 +101,7 @@ public String replaceDiagram( diagramId, originURL); - replaceCustomDiagram.replaceCustomDiagram(datasetName, diagramId, diagram); + replaceCustomDiagramUseCase.replaceCustomDatasetDiagram(datasetName, diagramId, diagram); logger.info( "Sending response to PUT request: \"/api/datasets/{{}}/diagrams/{{}}\" from \"{}\"", @@ -112,7 +112,7 @@ public String replaceDiagram( } @DeleteMapping - public String deleteDiagram( + public String deleteCustomDatasetDiagram( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, @@ -128,7 +128,7 @@ public String deleteDiagram( diagramId, originURL); - deleteCustomDiagram.deleteCustomDiagram(datasetName, diagramId); + deleteCustomDiagramUseCase.deleteCustomDatasetDiagram(datasetName, diagramId); logger.info( "Sending response to DELETE request: \"/api/datasets/{{}}/diagrams/{{}}\" from \"{}\"", diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/AllPackagesRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/AllPackagesRESTController.java index f7b4ed14..2f92113c 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/AllPackagesRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/AllPackagesRESTController.java @@ -19,7 +19,6 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; @@ -72,13 +71,10 @@ public record ListPackagesResponse( content = @Content( mediaType = "application/json", - array = - @ArraySchema( - schema = - @Schema( - implementation = - ListPackagesResponse - .class)))) + schema = + @Schema( + implementation = + ListPackagesResponse.class))) }) @GetMapping public ListPackagesResponse listPackages( diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/OntologyGenerateEntriesRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/OntologyGenerateEntriesRESTController.java index 4911151a..0d700b5b 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/OntologyGenerateEntriesRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/OntologyGenerateEntriesRESTController.java @@ -71,7 +71,7 @@ public class OntologyGenerateEntriesRESTController { .class)))) }) @GetMapping - public List getOntology( + public List getOntologyEntries( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/SchemaComparisonRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/SchemaComparisonRESTController.java index 2a038fe0..1a10833e 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/SchemaComparisonRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/SchemaComparisonRESTController.java @@ -58,7 +58,7 @@ public class SchemaComparisonRESTController { @Operation( summary = "compare schemas", description = "Compare a given graph with the specified graph from the dataset", - tags = {"graph"}, + tags = {"comparison"}, responses = { @ApiResponse( responseCode = "200", @@ -113,7 +113,7 @@ public List compareSchemas( @Operation( summary = "compare schemas", description = "Compare two graphs stored in the database", - tags = {"graph"}, + tags = {"comparison"}, responses = { @ApiResponse( responseCode = "200", @@ -129,7 +129,7 @@ public List compareSchemas( .class)))) }) @GetMapping() - public List compareDatasetSchemas( + public List compareStoredSchemas( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/classes/ClassAllEnumEntriesRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/classes/ClassAllEnumEntriesRESTController.java index c50c8678..9d093b43 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/classes/ClassAllEnumEntriesRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/classes/ClassAllEnumEntriesRESTController.java @@ -19,6 +19,8 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; @@ -52,9 +54,13 @@ public class ClassAllEnumEntriesRESTController { @Operation( summary = "Create enum entry", - description = "Creates a new enum entry for a specified class..", + description = "Creates a new enum entry for a specified class.", tags = {"enum"}, - responses = {@ApiResponse(responseCode = "200")}) + responses = + @ApiResponse( + responseCode = "200", + description = "UUID of the newly created enum entry.", + content = @Content(schema = @Schema(implementation = UUID.class)))) @PostMapping public UUID createEnumEntry( @Parameter(description = "The name/url of the inquirer.") diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/classes/attributes/ClassAttributesRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/classes/attributes/ClassAttributesRESTController.java index 2ae3fb67..d2527fe1 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/classes/attributes/ClassAttributesRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/classes/attributes/ClassAttributesRESTController.java @@ -21,6 +21,7 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; @@ -55,7 +56,12 @@ public class ClassAttributesRESTController { @Operation( summary = "Replace/Create attribute", description = "Replaces an attribute of a specified class.", - tags = {"class"}) + tags = {"class"}, + responses = + @ApiResponse( + responseCode = "200", + description = "The uuid of the new attribute.", + content = @Content(schema = @Schema(implementation = UUID.class)))) @PutMapping public UUID replaceAttribute( @Parameter(description = "The name/url of the inquirer.") diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/AllCustomDiagramsRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/AllCustomDiagramsRESTController.java index be587b6c..0365b96f 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/AllCustomDiagramsRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/AllCustomDiagramsRESTController.java @@ -17,7 +17,12 @@ package org.rdfarchitect.api.controller.datasets.graphs.diagrams; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; @@ -47,8 +52,26 @@ public class AllCustomDiagramsRESTController { private final ExpandURIUseCase expandURIUseCase; private final GetCustomDiagramsUseCase getCustomDiagramsUseCase; + @Operation( + summary = "list custom diagrams for graph", + description = + "Returns a list of all custom diagrams for the specified graph. Each diagram includes its ID, name, and other relevant information.", + tags = {"diagram"}, + responses = + @ApiResponse( + responseCode = "200", + content = + @Content( + mediaType = "application/json", + array = + @ArraySchema( + schema = + @Schema( + implementation = + CustomDiagram + .class))))) @GetMapping - public List getCustomDiagramList( + public List getCustomGraphDiagramList( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/CustomDiagramAllClassesRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/CustomDiagramAllClassesRESTController.java index 8b3e6d0a..e5ec5d7d 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/CustomDiagramAllClassesRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/CustomDiagramAllClassesRESTController.java @@ -53,7 +53,7 @@ public class CustomDiagramAllClassesRESTController { private final CustomDiagramLayoutUseCase customDiagramLayoutUseCase; @PostMapping - public String addToDiagram( + public String addToCustomGraphDiagram( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/CustomDiagramClassRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/CustomDiagramClassRESTController.java new file mode 100644 index 00000000..0efa98e9 --- /dev/null +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/CustomDiagramClassRESTController.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2024-2026 SOPTIM AG + * + * 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 + * + * 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. + * + */ + +package org.rdfarchitect.api.controller.datasets.graphs.diagrams; + +import io.swagger.v3.oas.annotations.Parameter; + +import lombok.RequiredArgsConstructor; + +import org.rdfarchitect.api.controller.Response; +import org.rdfarchitect.database.GraphIdentifier; +import org.rdfarchitect.services.ExpandURIUseCase; +import org.rdfarchitect.services.diagrams.RemoveFromCustomDiagramUseCase; +import org.rdfarchitect.services.dl.update.classlayout.CustomDiagramLayoutUseCase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.UUID; + +@RestController +@RequestMapping( + "/api/datasets/{datasetName}/graphs/{graphURI}/diagrams/{diagramId}/classes/{classId}") +@RequiredArgsConstructor +public class CustomDiagramClassRESTController { + + private static final Logger logger = + LoggerFactory.getLogger(CustomDiagramClassRESTController.class); + + private final ExpandURIUseCase expandURIUseCase; + + private final CustomDiagramLayoutUseCase customDiagramLayoutUseCase; + + private final RemoveFromCustomDiagramUseCase removeFromCustomDiagramUseCase; + + @DeleteMapping + public String removeFromCustomGraphDiagram( + @Parameter(description = "The name/url of the inquirer.") + @RequestHeader( + value = HttpHeaders.ORIGIN, + required = false, + defaultValue = "unknown") + String originURL, + @Parameter(description = "The literal name of the dataset.") @PathVariable + String datasetName, + @Parameter( + description = + "The url encoded uri of the graph, or \"default\" to access the default graph.") + @PathVariable + String graphURI, + @Parameter(description = "The uuid of the diagram.") @PathVariable String diagramId, + @Parameter(description = "The uuid of the class to be removed from the diagram.") + @PathVariable + UUID classId) { + logger.info( + "Received DELETE request: \"/api/datasets/{{}}/graphs/{{}}/diagrams/{{}}/classes/{{}}\" from \"{}\"", + datasetName, + graphURI, + diagramId, + classId, + originURL); + + var extendedGraphURI = expandURIUseCase.expandUri(datasetName, graphURI); + removeFromCustomDiagramUseCase.removeFromCustomGraphDiagram( + new GraphIdentifier(datasetName, extendedGraphURI), diagramId, classId); + + logger.info( + "Sending response to DELETE request: \"/api/datasets/{{}}/graphs/{{}}/diagrams/{{}}/classes/{{}}\" from \"{}\"", + datasetName, + graphURI, + diagramId, + classId, + originURL); + return Response.SUCCESS; + } +} diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/CustomDiagramsRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/CustomDiagramsRESTController.java index aaecb3d1..bf6be111 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/CustomDiagramsRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/diagrams/CustomDiagramsRESTController.java @@ -53,14 +53,14 @@ public class CustomDiagramsRESTController { private final RenderGraphDiagramUseCase renderGraphDiagramUseCase; - private final DeleteCustomDiagramUseCase deleteCustomDiagram; + private final DeleteCustomDiagramUseCase deleteCustomDiagramUseCase; - private final ReplaceCustomDiagramUseCase replaceCustomDiagram; + private final ReplaceCustomDiagramUseCase replaceCustomDiagramUseCase; private final ExpandURIUseCase expandURIUseCase; @GetMapping - public RenderingDataDTO getDiagramRenderingData( + public RenderingDataDTO getCustomProfileViewRenderingData( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, @@ -99,7 +99,7 @@ public RenderingDataDTO getDiagramRenderingData( } @PutMapping - public String replaceDiagram( + public String replaceCustomGraphDiagram( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, @@ -124,7 +124,7 @@ public String replaceDiagram( originURL); var extendedGraphURI = expandURIUseCase.expandUri(datasetName, graphURI); - replaceCustomDiagram.replaceCustomDiagram( + replaceCustomDiagramUseCase.replaceCustomGraphDiagram( new GraphIdentifier(datasetName, extendedGraphURI), diagramId, diagram); logger.info( @@ -137,7 +137,7 @@ public String replaceDiagram( } @DeleteMapping - public String deleteDiagram( + public String deleteCustomGraphDiagram( @Parameter(description = "The name/url of the inquirer.") @RequestHeader( value = HttpHeaders.ORIGIN, @@ -160,7 +160,7 @@ public String deleteDiagram( originURL); var extendedGraphURI = expandURIUseCase.expandUri(datasetName, graphURI); - deleteCustomDiagram.deleteCustomDiagram( + deleteCustomDiagramUseCase.deleteCustomGraphDiagram( new GraphIdentifier(datasetName, extendedGraphURI), diagramId); logger.info( diff --git a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/migration/MigrationContextRESTController.java b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/migration/MigrationContextRESTController.java index 59189772..9e491a31 100644 --- a/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/migration/MigrationContextRESTController.java +++ b/backend/src/main/java/org/rdfarchitect/api/controller/datasets/graphs/migration/MigrationContextRESTController.java @@ -28,6 +28,7 @@ import org.rdfarchitect.services.schemamigration.SetMigrationContextUseCase; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestHeader; @@ -55,7 +56,7 @@ public class MigrationContextRESTController { "Computes the diff of two given graphs and stores it in the session for later usage in migration endpoints. " + "Accepts the graphs either as file uploads, GraphIdentifiers or a combination of both.", tags = {"migration"}) - @PostMapping + @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public void computeMigrationContext( @Parameter(description = "The name/url of the inquirer.") @RequestHeader(value = "origin", required = false, defaultValue = "unknown") diff --git a/frontend/src/lib/api/apiGlobalUtils.js b/backend/src/main/java/org/rdfarchitect/api/dto/DatasetDTO.java similarity index 60% rename from frontend/src/lib/api/apiGlobalUtils.js rename to backend/src/main/java/org/rdfarchitect/api/dto/DatasetDTO.java index c3d68a39..3a0cc00f 100644 --- a/frontend/src/lib/api/apiGlobalUtils.js +++ b/backend/src/main/java/org/rdfarchitect/api/dto/DatasetDTO.java @@ -15,17 +15,19 @@ * */ -import { BackendConnection } from "$lib/api/backend.js"; -import { PUBLIC_BACKEND_URL } from "$lib/config/runtime"; +package org.rdfarchitect.api.dto; -const bec = new BackendConnection(fetch, PUBLIC_BACKEND_URL); +import lombok.AllArgsConstructor; +import lombok.Data; -export async function getXSDPrimitives() { - const res = await bec.getXSDPrimitives(); - return await res.json(); -} +import org.rdfarchitect.models.cim.data.dto.CIMPrefixPair; + +import java.util.List; -export async function getKnownFields() { - const res = await bec.getKnownOntologyFields(); - return await res.json(); +@Data +@AllArgsConstructor +public class DatasetDTO { + private String name; + private boolean readOnly; + private List prefixes; } diff --git a/backend/src/main/java/org/rdfarchitect/models/cim/umladapted/data/CIMClassUMLAdapted.java b/backend/src/main/java/org/rdfarchitect/models/cim/umladapted/data/CIMClassUMLAdapted.java index 1e9f2333..de92b9b7 100644 --- a/backend/src/main/java/org/rdfarchitect/models/cim/umladapted/data/CIMClassUMLAdapted.java +++ b/backend/src/main/java/org/rdfarchitect/models/cim/umladapted/data/CIMClassUMLAdapted.java @@ -66,5 +66,8 @@ public void nullEmptyLists() { if (associationPairs.isEmpty()) { associationPairs = null; } + if (enumEntries.isEmpty()) { + enumEntries = null; + } } } diff --git a/backend/src/main/java/org/rdfarchitect/services/diagrams/CustomDiagramService.java b/backend/src/main/java/org/rdfarchitect/services/diagrams/CustomDiagramService.java index 005c76a1..2e41a6a5 100644 --- a/backend/src/main/java/org/rdfarchitect/services/diagrams/CustomDiagramService.java +++ b/backend/src/main/java/org/rdfarchitect/services/diagrams/CustomDiagramService.java @@ -58,7 +58,7 @@ public class CustomDiagramService implements GetCustomDiagramsUseCase, ReplaceCustomDiagramUseCase, DeleteCustomDiagramUseCase, - RemoveFromDiagramUseCase, + RemoveFromCustomDiagramUseCase, CrossProfileColorUseCase { private final DatabasePort databasePort; @@ -226,13 +226,14 @@ private static void doDiagramLayout( } @Override - public void deleteCustomDiagram(String datasetName, String diagramId) { + public void deleteCustomDatasetDiagram(String datasetName, String diagramId) { var diagrams = databasePort.getDatasetDiagrams(datasetName); diagrams.remove(UUID.fromString(diagramId)); } @Override - public void replaceCustomDiagram(String datasetName, String diagramId, CustomDiagram diagram) { + public void replaceCustomDatasetDiagram( + String datasetName, String diagramId, CustomDiagram diagram) { if (!Objects.equals(diagramId, diagram.getDiagramId().toString())) { throw new IllegalArgumentException( "Diagram ID mismatch: URL parameter '" @@ -246,7 +247,7 @@ public void replaceCustomDiagram(String datasetName, String diagramId, CustomDia } @Override - public void removeFromDiagram(String datasetName, String diagramId, UUID classId) { + public void removeFromCustomDatasetDiagram(String datasetName, String diagramId, UUID classId) { var diagrams = databasePort.getDatasetDiagrams(datasetName); var diagram = diagrams.get(UUID.fromString(diagramId)); if (diagram != null) { @@ -257,7 +258,7 @@ public void removeFromDiagram(String datasetName, String diagramId, UUID classId } @Override - public void deleteCustomDiagram(GraphIdentifier graphIdentifier, String diagramId) { + public void deleteCustomGraphDiagram(GraphIdentifier graphIdentifier, String diagramId) { try (var ctx = databasePort.getGraphWithContext(graphIdentifier).begin(ReadWrite.WRITE)) { ctx.getCustomDiagrams().remove(UUID.fromString(diagramId)); ctx.commit("deleted diagram %s".formatted(diagramId)); @@ -265,7 +266,7 @@ public void deleteCustomDiagram(GraphIdentifier graphIdentifier, String diagramI } @Override - public void replaceCustomDiagram( + public void replaceCustomGraphDiagram( GraphIdentifier graphIdentifier, String diagramId, CustomDiagram diagram) { if (!Objects.equals(diagramId, diagram.getDiagramId().toString())) { throw new IllegalArgumentException( @@ -282,7 +283,8 @@ public void replaceCustomDiagram( } @Override - public void removeFromDiagram(GraphIdentifier graphIdentifier, String diagramId, UUID classId) { + public void removeFromCustomGraphDiagram( + GraphIdentifier graphIdentifier, String diagramId, UUID classId) { try (var ctx = databasePort.getGraphWithContext(graphIdentifier).begin(ReadWrite.WRITE)) { var diagram = ctx.getCustomDiagrams().get(UUID.fromString(diagramId)); if (diagram != null) { diff --git a/backend/src/main/java/org/rdfarchitect/services/diagrams/DeleteCustomDiagramUseCase.java b/backend/src/main/java/org/rdfarchitect/services/diagrams/DeleteCustomDiagramUseCase.java index 2bd502cf..82e09b04 100644 --- a/backend/src/main/java/org/rdfarchitect/services/diagrams/DeleteCustomDiagramUseCase.java +++ b/backend/src/main/java/org/rdfarchitect/services/diagrams/DeleteCustomDiagramUseCase.java @@ -27,7 +27,7 @@ public interface DeleteCustomDiagramUseCase { * @param graphIdentifier The graph containing the diagram * @param diagramId The ID of the diagram to be deleted. */ - void deleteCustomDiagram(GraphIdentifier graphIdentifier, String diagramId); + void deleteCustomGraphDiagram(GraphIdentifier graphIdentifier, String diagramId); /** * Deletes a custom diagram defined in a dataset. @@ -35,5 +35,5 @@ public interface DeleteCustomDiagramUseCase { * @param datasetName The dataset containing the diagram * @param diagramId The ID of the diagram to be deleted */ - void deleteCustomDiagram(String datasetName, String diagramId); + void deleteCustomDatasetDiagram(String datasetName, String diagramId); } diff --git a/backend/src/main/java/org/rdfarchitect/services/diagrams/RemoveFromDiagramUseCase.java b/backend/src/main/java/org/rdfarchitect/services/diagrams/RemoveFromCustomDiagramUseCase.java similarity index 87% rename from backend/src/main/java/org/rdfarchitect/services/diagrams/RemoveFromDiagramUseCase.java rename to backend/src/main/java/org/rdfarchitect/services/diagrams/RemoveFromCustomDiagramUseCase.java index 92633237..a7081394 100644 --- a/backend/src/main/java/org/rdfarchitect/services/diagrams/RemoveFromDiagramUseCase.java +++ b/backend/src/main/java/org/rdfarchitect/services/diagrams/RemoveFromCustomDiagramUseCase.java @@ -21,7 +21,7 @@ import java.util.UUID; -public interface RemoveFromDiagramUseCase { +public interface RemoveFromCustomDiagramUseCase { /** * Removes a class from a specified custom diagram. @@ -30,7 +30,8 @@ public interface RemoveFromDiagramUseCase { * @param diagramId the id of the custom diagram * @param classId the uuid of the class to remove from the custom diagram */ - void removeFromDiagram(GraphIdentifier graphIdentifier, String diagramId, UUID classId); + void removeFromCustomGraphDiagram( + GraphIdentifier graphIdentifier, String diagramId, UUID classId); /** * Removes a class from a specified custom diagram. @@ -39,7 +40,7 @@ public interface RemoveFromDiagramUseCase { * @param diagramId the id of the custom diagram * @param classId the uuid of the class to remove from the custom diagram */ - void removeFromDiagram(String datasetName, String diagramId, UUID classId); + void removeFromCustomDatasetDiagram(String datasetName, String diagramId, UUID classId); /** * Removes a class from all diagrams diff --git a/backend/src/main/java/org/rdfarchitect/services/diagrams/ReplaceCustomDiagramUseCase.java b/backend/src/main/java/org/rdfarchitect/services/diagrams/ReplaceCustomDiagramUseCase.java index 0cc5d441..ffc47fd8 100644 --- a/backend/src/main/java/org/rdfarchitect/services/diagrams/ReplaceCustomDiagramUseCase.java +++ b/backend/src/main/java/org/rdfarchitect/services/diagrams/ReplaceCustomDiagramUseCase.java @@ -29,7 +29,7 @@ public interface ReplaceCustomDiagramUseCase { * @param diagramId the id of the diagram to be replaced * @param diagram the new diagram to replace the old one with */ - void replaceCustomDiagram( + void replaceCustomGraphDiagram( GraphIdentifier graphIdentifier, String diagramId, CustomDiagram diagram); /** @@ -39,5 +39,5 @@ void replaceCustomDiagram( * @param diagramId the id of the diagram to be replaced * @param diagram the new diagram to replace the old one with */ - void replaceCustomDiagram(String datasetName, String diagramId, CustomDiagram diagram); + void replaceCustomDatasetDiagram(String datasetName, String diagramId, CustomDiagram diagram); } diff --git a/backend/src/main/java/org/rdfarchitect/services/select/ListDatasetsUseCase.java b/backend/src/main/java/org/rdfarchitect/services/select/ListDatasetsUseCase.java index 9b264f49..8bac8692 100644 --- a/backend/src/main/java/org/rdfarchitect/services/select/ListDatasetsUseCase.java +++ b/backend/src/main/java/org/rdfarchitect/services/select/ListDatasetsUseCase.java @@ -17,9 +17,17 @@ package org.rdfarchitect.services.select; +import org.rdfarchitect.api.dto.DatasetDTO; + import java.util.List; public interface ListDatasetsUseCase { - List listDatasets(); + /** + * List all datasets including their prefixes and read-only status. Snapshots are excluded from + * the list. + * + * @return List of dataset objects + */ + List listDatasets(); } diff --git a/backend/src/main/java/org/rdfarchitect/services/select/QueryDatasetService.java b/backend/src/main/java/org/rdfarchitect/services/select/QueryDatasetService.java index f6925328..ab508242 100644 --- a/backend/src/main/java/org/rdfarchitect/services/select/QueryDatasetService.java +++ b/backend/src/main/java/org/rdfarchitect/services/select/QueryDatasetService.java @@ -26,6 +26,7 @@ import org.apache.jena.riot.Lang; import org.apache.jena.riot.RDFDataMgr; import org.apache.jena.riot.RDFFormat; +import org.rdfarchitect.api.dto.DatasetDTO; import org.rdfarchitect.database.DatabasePort; import org.rdfarchitect.database.GraphIdentifier; import org.rdfarchitect.models.cim.data.dto.CIMPrefixPair; @@ -119,7 +120,18 @@ public String listFormattedPrefixes(String datasetName, String format) { } @Override - public List listDatasets() { - return databasePort.listDatasets(); + public List listDatasets() { + var result = new ArrayList(); + for (var datasetName : databasePort.listDatasets()) { + var readonly = databasePort.isReadOnly(datasetName); + var prefixMapping = databasePort.getPrefixMapping(datasetName); + + var prefixPairs = new ArrayList(); + for (var prefix : prefixMapping.getNsPrefixMap().entrySet()) { + prefixPairs.add(new CIMPrefixPair(prefix.getKey() + ":", prefix.getValue())); + } + result.add(new DatasetDTO(datasetName, readonly, prefixPairs)); + } + return result; } } diff --git a/backend/src/main/java/org/rdfarchitect/services/update/classes/UpdateClassService.java b/backend/src/main/java/org/rdfarchitect/services/update/classes/UpdateClassService.java index e1088e56..7f3e3fff 100644 --- a/backend/src/main/java/org/rdfarchitect/services/update/classes/UpdateClassService.java +++ b/backend/src/main/java/org/rdfarchitect/services/update/classes/UpdateClassService.java @@ -36,7 +36,7 @@ import org.rdfarchitect.models.cim.queries.update.CIMUpdates; import org.rdfarchitect.models.cim.rdf.resources.CIMS; import org.rdfarchitect.models.cim.relations.model.CIMResourceUtils; -import org.rdfarchitect.services.diagrams.RemoveFromDiagramUseCase; +import org.rdfarchitect.services.diagrams.RemoveFromCustomDiagramUseCase; import org.rdfarchitect.services.dl.update.classlayout.CreateClassLayoutDataUseCase; import org.rdfarchitect.services.dl.update.classlayout.CrossProfileDiagramLayoutUseCase; import org.rdfarchitect.services.dl.update.classlayout.DeleteClassLayoutDataUseCase; @@ -59,8 +59,8 @@ public class UpdateClassService private final CreateClassLayoutDataUseCase createClassLayoutDataUseCase; private final UpdateDiagramObjectNameUseCase updateDiagramObjectNameUseCase; private final DeleteClassLayoutDataUseCase deleteClassLayoutDataUseCase; + private final RemoveFromCustomDiagramUseCase removeFromCustomDiagramUseCase; private final CrossProfileDiagramLayoutUseCase crossProfileDiagramLayoutUseCase; - private final RemoveFromDiagramUseCase removeFromDiagramUseCase; public UpdateClassService( DatabasePort databasePort, @@ -71,7 +71,7 @@ public UpdateClassService( DeleteClassLayoutDataUseCase deleteClassLayoutDataUseCase, @Value("${attributes.newValuesBlankNode:false}") boolean newValuesAsBlankNode, CrossProfileDiagramLayoutUseCase crossProfileDiagramLayoutUseCase, - RemoveFromDiagramUseCase removeFromDiagramUseCase) { + RemoveFromCustomDiagramUseCase removeFromCustomDiagramUseCase) { this.databasePort = databasePort; this.classMapper = classMapper; this.packageMapper = packageMapper; @@ -80,7 +80,7 @@ public UpdateClassService( this.deleteClassLayoutDataUseCase = deleteClassLayoutDataUseCase; this.newValuesAsBlankNode = newValuesAsBlankNode; this.crossProfileDiagramLayoutUseCase = crossProfileDiagramLayoutUseCase; - this.removeFromDiagramUseCase = removeFromDiagramUseCase; + this.removeFromCustomDiagramUseCase = removeFromCustomDiagramUseCase; } @Override @@ -185,6 +185,6 @@ public void deleteClass(GraphIdentifier graphIdentifier, UUID classUUID) { } deleteClassLayoutDataUseCase.deleteClassLayoutData(graphIdentifier, classUUID); - removeFromDiagramUseCase.removeFromAllDiagrams(graphIdentifier, classUUID); + removeFromCustomDiagramUseCase.removeFromAllDiagrams(graphIdentifier, classUUID); } } diff --git a/backend/src/test/java/org/rdfarchitect/api/controller/datasets/DatasetRESTControllerTest.java b/backend/src/test/java/org/rdfarchitect/api/controller/datasets/DatasetRESTControllerTest.java index a39d9a67..64510f35 100644 --- a/backend/src/test/java/org/rdfarchitect/api/controller/datasets/DatasetRESTControllerTest.java +++ b/backend/src/test/java/org/rdfarchitect/api/controller/datasets/DatasetRESTControllerTest.java @@ -23,6 +23,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.rdfarchitect.api.controller.Response; +import org.rdfarchitect.api.dto.DatasetDTO; import org.rdfarchitect.services.select.ListDatasetsUseCase; import org.rdfarchitect.services.update.dataset.DeleteDatasetUseCase; import org.springframework.http.HttpHeaders; @@ -44,11 +45,13 @@ void setUp() { @Test void listDatasets_returnsValueFromUseCase() { - when(listDatasetsUseCase.listDatasets()).thenReturn(List.of("dataset-a", "dataset-b")); + var dataset1 = new DatasetDTO("dataset-a", false, List.of()); + var dataset2 = new DatasetDTO("dataset-b", false, List.of()); + when(listDatasetsUseCase.listDatasets()).thenReturn(List.of(dataset1, dataset2)); var result = controller.listDatasets(HttpHeaders.ORIGIN); - assertThat(result).containsExactly("dataset-a", "dataset-b"); + assertThat(result).containsExactly(dataset1, dataset2); verify(listDatasetsUseCase).listDatasets(); } diff --git a/backend/src/test/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramIDRESTControllerTest.java b/backend/src/test/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramIDRESTControllerTest.java index dd24cce0..f850caba 100644 --- a/backend/src/test/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramIDRESTControllerTest.java +++ b/backend/src/test/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramIDRESTControllerTest.java @@ -40,14 +40,14 @@ void setUp() { } @Test - void getCrossProfileRenderingData_validDataset_returnsUUIDString() { + void getCrossProfileDiagramId_validDataset_returnsUUIDString() { var uuid = UUID.randomUUID(); var crossProfileDiagramInfo = mock(CrossProfileDiagramInfo.class); when(crossProfileDiagramInfo.getCrossProfileDiagramUUID()).thenReturn(uuid); when(databasePort.getCrossProfileDiagramInfo("my-dataset")) .thenReturn(crossProfileDiagramInfo); - var result = controller.getCrossProfileRenderingData(HttpHeaders.ORIGIN, "my-dataset"); + var result = controller.getCrossProfileDiagramId(HttpHeaders.ORIGIN, "my-dataset"); assertThat(result).isEqualTo(uuid.toString()); verify(databasePort).getCrossProfileDiagramInfo("my-dataset"); diff --git a/backend/src/test/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramRestControllerTest.java b/backend/src/test/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramRestControllerTest.java index 37790eee..da40cd95 100644 --- a/backend/src/test/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramRestControllerTest.java +++ b/backend/src/test/java/org/rdfarchitect/api/controller/datasets/diagrams/CrossProfileDiagramRestControllerTest.java @@ -46,7 +46,7 @@ void getCrossProfileRenderingData_validDataset_returnsDTOFromUseCase() { when(getCustomDiagramsUseCase.getCrossProfileDiagram("my-dataset", false, false)) .thenReturn(expectedDTO); - var result = controller.getCrossProfileRenderingData(HttpHeaders.ORIGIN, "my-dataset"); + var result = controller.getCrossProfileDiagram(HttpHeaders.ORIGIN, "my-dataset"); assertThat(result).isEqualTo(expectedDTO); verify(getCustomDiagramsUseCase).getCrossProfileDiagram("my-dataset", false, false); diff --git a/backend/src/test/java/org/rdfarchitect/services/diagrams/CustomDiagramsServiceTest.java b/backend/src/test/java/org/rdfarchitect/services/diagrams/CustomDiagramsServiceTest.java index 8c5eff86..f9c99a66 100644 --- a/backend/src/test/java/org/rdfarchitect/services/diagrams/CustomDiagramsServiceTest.java +++ b/backend/src/test/java/org/rdfarchitect/services/diagrams/CustomDiagramsServiceTest.java @@ -18,7 +18,6 @@ package org.rdfarchitect.services.diagrams; import static org.assertj.core.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; import org.apache.jena.query.ReadWrite; @@ -92,7 +91,7 @@ void deleteCustomDiagram_diagramExistsInDataset_removesFromMap() { when(databasePort.getDatasetDiagrams("dataset")).thenReturn(map); - service.deleteCustomDiagram("dataset", diagramId.toString()); + service.deleteCustomDatasetDiagram("dataset", diagramId.toString()); assertThat(map).doesNotContainKey(diagramId); } @@ -106,7 +105,7 @@ void deleteCustomDiagram_diagramExistsInGraph_removesFromMap() { var graph = mockGraph(map); when(databasePort.getGraphWithContext(graphIdentifier)).thenReturn(graph); - service.deleteCustomDiagram(graphIdentifier, diagramId.toString()); + service.deleteCustomGraphDiagram(graphIdentifier, diagramId.toString()); assertThat(map).doesNotContainKey(diagramId); } @@ -119,7 +118,7 @@ void replaceCustomDiagram_newDiagramForDataset_replacesInMap() { when(databasePort.getDatasetDiagrams("dataset")).thenReturn(map); - service.replaceCustomDiagram("dataset", diagramId.toString(), newDiagram); + service.replaceCustomDatasetDiagram("dataset", diagramId.toString(), newDiagram); assertThat(map).containsEntry(diagramId, newDiagram); } @@ -133,7 +132,7 @@ void replaceCustomDiagram_newDiagramForGraph_replacesInMap() { var graph = mockGraph(map); when(databasePort.getGraphWithContext(graphIdentifier)).thenReturn(graph); - service.replaceCustomDiagram(graphIdentifier, diagramId.toString(), newDiagram); + service.replaceCustomGraphDiagram(graphIdentifier, diagramId.toString(), newDiagram); assertThat(map).containsEntry(diagramId, newDiagram); } @@ -150,7 +149,7 @@ void removeFromDiagram_classRemovedFromDatasetDiagram_diagramIsEmpty() { when(databasePort.getDatasetDiagrams("dataset")).thenReturn(map); - service.removeFromDiagram("dataset", diagramId.toString(), classId); + service.removeFromCustomDatasetDiagram("dataset", diagramId.toString(), classId); assertThat(diagram.getClasses()).isEmpty(); } @@ -168,7 +167,7 @@ void removeFromDiagram_classRemovedFromGraphDiagram_diagramIsEmpty() { var graph = mockGraph(map); when(databasePort.getGraphWithContext(graphIdentifier)).thenReturn(graph); - service.removeFromDiagram(graphIdentifier, diagramId.toString(), classId); + service.removeFromCustomGraphDiagram(graphIdentifier, diagramId.toString(), classId); assertThat(diagram.getClasses()).isEmpty(); } diff --git a/frontend/.gitignore b/frontend/.gitignore index e1c5b032..daaadd1d 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -6,6 +6,8 @@ node_modules /.svelte-kit /build +src/lib/api/generated + # OS .DS_Store Thumbs.db diff --git a/frontend/.prettierignore b/frontend/.prettierignore index a880ac06..352aeb76 100644 --- a/frontend/.prettierignore +++ b/frontend/.prettierignore @@ -1 +1,7 @@ -LICENSES-THIRD-PARTY.md \ No newline at end of file +LICENSES-THIRD-PARTY.md + +# Generated from the backend OpenAPI spec (see openapi-ts.config.ts) +src/lib/api/generated + +# Committed API contract, formatted by the backend exporter (OpenApiSpecExportTest) +openapi.json diff --git a/frontend/Dockerfile b/frontend/Dockerfile index a6be5cb9..6b3576af 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -11,6 +11,9 @@ RUN npm ci # Copy source code COPY . . +# Generate the API client from the committed OpenAPI spec (offline, no backend needed) +RUN npm run api:generate + # Build frontend RUN npm run build diff --git a/frontend/LICENSES-THIRD-PARTY.md b/frontend/LICENSES-THIRD-PARTY.md index aacf54d2..b34ee8cc 100644 --- a/frontend/LICENSES-THIRD-PARTY.md +++ b/frontend/LICENSES-THIRD-PARTY.md @@ -42,6 +42,12 @@ - **License:** (CC-BY-4.0 AND MIT) - **URL:** [https://fontawesome.com](https://fontawesome.com) +### @hey-api/openapi-ts +- **Package:** @hey-api/openapi-ts +- **Version:** 0.97.1 +- **License:** MIT +- **URL:** [https://heyapi.dev/](https://heyapi.dev/) + ### @sveltejs/adapter-auto - **Package:** @sveltejs/adapter-auto - **Version:** 7.0.1 diff --git a/frontend/licenses-third-party.js b/frontend/licenses-third-party.js index 1744573c..eb71d0f2 100644 --- a/frontend/licenses-third-party.js +++ b/frontend/licenses-third-party.js @@ -15,9 +15,9 @@ * */ -import fs from "fs"; -import path from "path"; -import { fileURLToPath } from "url"; +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; const __filepath = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filepath); @@ -65,7 +65,9 @@ function generateLicenseContent() { let markdown = "# Third-Party Licenses\n\n"; - for (const pkg of packages.sort((a, b) => a.name.localeCompare(b.name))) { + for (const pkg of packages.toSorted((a, b) => + a.name.localeCompare(b.name), + )) { markdown += `### ${pkg.name}\n`; markdown += `- **Package:** ${pkg.name}\n`; markdown += `- **Version:** ${pkg.version}\n`; diff --git a/frontend/openapi-ts.config.ts b/frontend/openapi-ts.config.ts new file mode 100644 index 00000000..002bbd39 --- /dev/null +++ b/frontend/openapi-ts.config.ts @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024-2026 SOPTIM AG + * + * 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 + * + * 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 { defineConfig } from "@hey-api/openapi-ts"; + +export default defineConfig({ + input: "./openapi.json", + output: "src/lib/api/generated", + plugins: [ + { + name: "@hey-api/client-fetch", + runtimeConfigPath: "./src/lib/api/hey-api", + }, + ], +}); diff --git a/frontend/openapi.json b/frontend/openapi.json new file mode 100644 index 00000000..4b75bb83 --- /dev/null +++ b/frontend/openapi.json @@ -0,0 +1,8308 @@ +{ + "components" : { + "schemas" : { + "AddNewClassRequest" : { + "properties" : { + "classLayoutPosition" : { + "$ref" : "#/components/schemas/ClassLayoutPositionDTO" + }, + "className" : { + "type" : "string" + }, + "classURIPrefix" : { + "type" : "string" + }, + "packageDTO" : { + "$ref" : "#/components/schemas/PackageDTO" + } + }, + "type" : "object" + }, + "AffectedResource" : { + "properties" : { + "actions" : { + "items" : { + "enum" : [ + "DELETE", + "KEEP", + "REMOVE_PACKAGE_REFERENCE", + "REMOVE_SUBCLASS_REFERENCE" + ], + "type" : "string" + }, + "type" : "array" + }, + "children" : { + "items" : { + "$ref" : "#/components/schemas/AffectedResource" + }, + "type" : "array" + }, + "context" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + }, + "reason" : { + "enum" : [ + "CONTAINED_IN_PACKAGE", + "USES_DELETED_CLASS_AS_DATATYPE", + "REFENCES_DELETED_CLASS_VIA_ASSOCIATION", + "CHILD_OF", + "USES_DELETED_CLASS_AS_DEFAULT_VALUE", + "USES_DELETED_CLASS_AS_FIXED_VALUE", + "DELETION_REQUESTED_BY_USER" + ], + "type" : "string" + }, + "resourceIdentifier" : { + "$ref" : "#/components/schemas/ResourceIdentifier" + }, + "type" : { + "enum" : [ + "PACKAGE", + "CLASS", + "ATTRIBUTE", + "ASSOCIATION", + "ENUM_ENTRY", + "ONTOLOGY", + "UNKNOWN" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "AssociationDTO" : { + "properties" : { + "associationUsed" : { + "type" : "boolean" + }, + "comment" : { + "type" : "string" + }, + "domain" : { + "type" : "string" + }, + "label" : { + "type" : "string" + }, + "multiplicity" : { + "type" : "string" + }, + "prefix" : { + "type" : "string" + }, + "range" : { + "$ref" : "#/components/schemas/DataTypeDTO" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "AssociationPairDTO" : { + "properties" : { + "from" : { + "$ref" : "#/components/schemas/AssociationDTO" + }, + "to" : { + "$ref" : "#/components/schemas/AssociationDTO" + } + }, + "type" : "object" + }, + "AssociationUUIDs" : { + "properties" : { + "fromUUID" : { + "format" : "uuid", + "type" : "string" + }, + "toUUID" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "AttributeDTO" : { + "properties" : { + "comment" : { + "type" : "string" + }, + "dataType" : { + "$ref" : "#/components/schemas/DataTypeDTO" + }, + "defaultValue" : { + "type" : "string" + }, + "domain" : { + "type" : "string" + }, + "fixedValue" : { + "type" : "string" + }, + "label" : { + "type" : "string" + }, + "multiplicity" : { + "type" : "string" + }, + "prefix" : { + "type" : "string" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "BelongsToCategoryDTO" : { + "properties" : { + "label" : { + "type" : "string" + }, + "prefix" : { + "type" : "string" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "CIMAttribute" : { + "properties" : { + "comment" : { + "$ref" : "#/components/schemas/RDFSComment" + }, + "dataType" : { + "$ref" : "#/components/schemas/CIMSDataType" + }, + "defaultValue" : { + "$ref" : "#/components/schemas/CIMSIsDefault" + }, + "domain" : { + "$ref" : "#/components/schemas/RDFSDomain" + }, + "fixedValue" : { + "$ref" : "#/components/schemas/CIMSIsFixed" + }, + "label" : { + "$ref" : "#/components/schemas/RDFSLabel" + }, + "multiplicity" : { + "$ref" : "#/components/schemas/CIMSMultiplicity" + }, + "stereotype" : { + "type" : "string" + }, + "uri" : { + "$ref" : "#/components/schemas/URI" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "CIMClass" : { + "properties" : { + "comment" : { + "$ref" : "#/components/schemas/RDFSComment" + }, + "graphUri" : { + "type" : "string" + }, + "label" : { + "$ref" : "#/components/schemas/RDFSLabel" + }, + "package" : { + "$ref" : "#/components/schemas/CIMSBelongsToCategory" + }, + "stereotypes" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "superClass" : { + "$ref" : "#/components/schemas/RDFSSubClassOf" + }, + "uri" : { + "$ref" : "#/components/schemas/URI" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "CIMPrefixPair" : { + "properties" : { + "prefix" : { + "type" : "string" + }, + "substitutedPrefix" : { + "type" : "string" + } + }, + "type" : "object" + }, + "CIMSBelongsToCategory" : { + "properties" : { + "label" : { + "$ref" : "#/components/schemas/RDFSLabel" + }, + "uri" : { + "$ref" : "#/components/schemas/URI" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "CIMSDataType" : { + "properties" : { + "label" : { + "$ref" : "#/components/schemas/RDFSLabel" + }, + "type" : { + "enum" : [ + "PRIMITIVE", + "RANGE", + "UNKNOWN" + ], + "type" : "string" + }, + "uri" : { + "$ref" : "#/components/schemas/URI" + } + }, + "type" : "object" + }, + "CIMSIsDefault" : { + "properties" : { + "blankNode" : { + "type" : "boolean" + }, + "dataType" : { + "$ref" : "#/components/schemas/URI" + }, + "value" : { + "type" : "string" + } + }, + "type" : "object" + }, + "CIMSIsFixed" : { + "properties" : { + "blankNode" : { + "type" : "boolean" + }, + "dataType" : { + "$ref" : "#/components/schemas/URI" + }, + "value" : { + "type" : "string" + } + }, + "type" : "object" + }, + "CIMSMultiplicity" : { + "properties" : { + "uri" : { + "$ref" : "#/components/schemas/URI" + } + }, + "type" : "object" + }, + "ChangeLog" : { + "properties" : { + "redoHistory" : { + "items" : { + "$ref" : "#/components/schemas/ChangeLogEntry" + }, + "type" : "array" + }, + "undoHistory" : { + "items" : { + "$ref" : "#/components/schemas/ChangeLogEntry" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "ChangeLogEntry" : { + "properties" : { + "changeId" : { + "format" : "uuid", + "type" : "string" + }, + "contextDeltas" : { + "items" : { + "$ref" : "#/components/schemas/ContextDelta" + }, + "type" : "array" + }, + "message" : { + "type" : "string" + }, + "steps" : { + "format" : "int32", + "type" : "integer" + }, + "timestamp" : { + "format" : "date-time", + "type" : "string" + } + }, + "type" : "object" + }, + "ClassDTO" : { + "properties" : { + "belongsToCategory" : { + "format" : "uuid", + "type" : "string" + }, + "comment" : { + "type" : "string" + }, + "graphUri" : { + "type" : "string" + }, + "label" : { + "type" : "string" + }, + "prefix" : { + "type" : "string" + }, + "stereotypes" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "superClass" : { + "$ref" : "#/components/schemas/SuperClassDTO" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "ClassInDiagram" : { + "properties" : { + "graphUri" : { + "$ref" : "#/components/schemas/URI" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "ClassLayoutPositionDTO" : { + "properties" : { + "xposition" : { + "format" : "float", + "type" : "number" + }, + "yposition" : { + "format" : "float", + "type" : "number" + } + }, + "type" : "object" + }, + "ClassPositionDTO" : { + "properties" : { + "classUUID" : { + "format" : "uuid", + "type" : "string" + }, + "xPosition" : { + "format" : "float", + "type" : "number" + }, + "xposition" : { + "format" : "float", + "type" : "number" + }, + "yPosition" : { + "format" : "float", + "type" : "number" + }, + "yposition" : { + "format" : "float", + "type" : "number" + }, + "zPosition" : { + "format" : "int32", + "type" : "integer" + }, + "zposition" : { + "format" : "int32", + "type" : "integer" + } + }, + "type" : "object" + }, + "ClassRelationsDTO" : { + "properties" : { + "classesReferencingThisClass" : { + "additionalProperties" : { + "items" : { + "$ref" : "#/components/schemas/ClassDTO" + }, + "type" : "array" + }, + "type" : "object" + }, + "classesReferencingThisClassFromCIM" : { + "additionalProperties" : { + "items" : { + "$ref" : "#/components/schemas/CIMClass" + }, + "type" : "array" + }, + "type" : "object", + "writeOnly" : true + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "ClassSourceDTO" : { + "properties" : { + "classUUID" : { + "format" : "uuid", + "type" : "string" + }, + "graphUri" : { + "type" : "string" + } + }, + "type" : "object" + }, + "ClassUMLAdaptedDTO" : { + "properties" : { + "associationPairs" : { + "items" : { + "$ref" : "#/components/schemas/AssociationPairDTO" + }, + "type" : "array" + }, + "attributes" : { + "items" : { + "$ref" : "#/components/schemas/AttributeDTO" + }, + "type" : "array" + }, + "comment" : { + "type" : "string" + }, + "enumEntries" : { + "items" : { + "$ref" : "#/components/schemas/EnumEntryDTO" + }, + "type" : "array" + }, + "label" : { + "type" : "string" + }, + "package" : { + "$ref" : "#/components/schemas/BelongsToCategoryDTO" + }, + "prefix" : { + "type" : "string" + }, + "stereotypes" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "superClass" : { + "$ref" : "#/components/schemas/SuperClassDTO" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "ContextDelta" : { + "properties" : { + "additions" : { + "properties" : { + "enqueued" : { + "deprecated" : true, + "type" : "boolean" + } + }, + "type" : "object" + }, + "contextName" : { + "type" : "string" + }, + "deletions" : { + "properties" : { + "enqueued" : { + "deprecated" : true, + "type" : "boolean" + } + }, + "type" : "object" + } + }, + "type" : "object" + }, + "CopyClassResponseDTO" : { + "properties" : { + "name" : { + "type" : "string" + }, + "uuid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "CrossProfileDiagramColorDataDTO" : { + "properties" : { + "graphColors" : { + "additionalProperties" : { + "type" : "string" + }, + "type" : "object" + } + }, + "type" : "object" + }, + "CrossProfileDiagramDTO" : { + "properties" : { + "classes" : { + "items" : { + "$ref" : "#/components/schemas/MergedClassDTO" + }, + "type" : "array" + }, + "diagramId" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "CustomAndGeneratedTupleListPropertyShape" : { + "properties" : { + "custom" : { + "items" : { + "$ref" : "#/components/schemas/PropertyShape" + }, + "type" : "array" + }, + "generated" : { + "items" : { + "$ref" : "#/components/schemas/PropertyShape" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "CustomAndGeneratedTupleSHACLToClassRelations" : { + "properties" : { + "custom" : { + "$ref" : "#/components/schemas/SHACLToClassRelations" + }, + "generated" : { + "$ref" : "#/components/schemas/SHACLToClassRelations" + } + }, + "type" : "object" + }, + "CustomDiagram" : { + "description" : "DTO for the diagram to be replaced." + }, + "DataTypeDTO" : { + "properties" : { + "label" : { + "type" : "string" + }, + "prefix" : { + "type" : "string" + }, + "type" : { + "enum" : [ + "PRIMITIVE", + "RANGE", + "UNKNOWN" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "DatasetDTO" : { + "properties" : { + "name" : { + "type" : "string" + }, + "prefixes" : { + "items" : { + "$ref" : "#/components/schemas/CIMPrefixPair" + }, + "type" : "array" + }, + "readOnly" : { + "type" : "boolean" + } + }, + "type" : "object" + }, + "DefaultValueView" : { + "properties" : { + "associations" : { + "items" : { + "$ref" : "#/components/schemas/SemanticAssociationChange" + }, + "type" : "array" + }, + "attributes" : { + "items" : { + "$ref" : "#/components/schemas/SemanticAttributeChange" + }, + "type" : "array" + }, + "classLabel" : { + "type" : "string" + }, + "enumEntries" : { + "items" : { + "$ref" : "#/components/schemas/SemanticEnumEntryChange" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "EnumEntryDTO" : { + "properties" : { + "comment" : { + "type" : "string" + }, + "label" : { + "type" : "string" + }, + "prefix" : { + "type" : "string" + }, + "stereotype" : { + "type" : "string" + }, + "type" : { + "type" : "string" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "GraphBulkImportResponse" : { + "properties" : { + "failedImports" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "importedGraphUris" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "message" : { + "type" : "string" + }, + "warnings" : { + "items" : { + "$ref" : "#/components/schemas/ImportWarning" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "GraphFilter" : { + "properties" : { + "allowedUUIDs" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "includeAssociations" : { + "type" : "boolean" + }, + "includeAttributes" : { + "type" : "boolean" + }, + "includeEnumEntries" : { + "type" : "boolean" + }, + "includeInheritance" : { + "type" : "boolean" + }, + "includeRelationsToExternalPackages" : { + "type" : "boolean" + }, + "packageUUID" : { + "type" : "string" + } + }, + "type" : "object" + }, + "GraphSourceDTOAssociationPairDTO" : { + "properties" : { + "graphColor" : { + "type" : "string" + }, + "graphUri" : { + "type" : "string" + }, + "value" : { + "$ref" : "#/components/schemas/AssociationPairDTO" + } + }, + "type" : "object" + }, + "GraphSourceDTOAttributeDTO" : { + "properties" : { + "graphColor" : { + "type" : "string" + }, + "graphUri" : { + "type" : "string" + }, + "value" : { + "$ref" : "#/components/schemas/AttributeDTO" + } + }, + "type" : "object" + }, + "GraphSourceDTOEnumEntryDTO" : { + "properties" : { + "graphColor" : { + "type" : "string" + }, + "graphUri" : { + "type" : "string" + }, + "value" : { + "$ref" : "#/components/schemas/EnumEntryDTO" + } + }, + "type" : "object" + }, + "GraphSourceDTOSuperClassDTO" : { + "properties" : { + "graphColor" : { + "type" : "string" + }, + "graphUri" : { + "type" : "string" + }, + "value" : { + "$ref" : "#/components/schemas/SuperClassDTO" + } + }, + "type" : "object" + }, + "ImportWarning" : { + "properties" : { + "fileName" : { + "type" : "string" + }, + "undisplayableProperties" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "ListPackagesResponse" : { + "properties" : { + "externalPackageList" : { + "items" : { + "$ref" : "#/components/schemas/PackageDTO" + }, + "type" : "array" + }, + "internalPackageList" : { + "items" : { + "$ref" : "#/components/schemas/PackageDTO" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "MergedClassDTO" : { + "properties" : { + "associationPairs" : { + "items" : { + "$ref" : "#/components/schemas/GraphSourceDTOAssociationPairDTO" + }, + "type" : "array" + }, + "attributes" : { + "items" : { + "$ref" : "#/components/schemas/GraphSourceDTOAttributeDTO" + }, + "type" : "array" + }, + "classUri" : { + "type" : "string" + }, + "enumEntries" : { + "items" : { + "$ref" : "#/components/schemas/GraphSourceDTOEnumEntryDTO" + }, + "type" : "array" + }, + "label" : { + "type" : "string" + }, + "sources" : { + "items" : { + "$ref" : "#/components/schemas/ClassSourceDTO" + }, + "type" : "array" + }, + "stereotypes" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "superClasses" : { + "items" : { + "$ref" : "#/components/schemas/GraphSourceDTOSuperClassDTO" + }, + "type" : "array" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "NodeShape" : { + "properties" : { + "id" : { + "type" : "string" + }, + "triples" : { + "type" : "string" + } + }, + "type" : "object" + }, + "OntologyDTO" : { + "properties" : { + "entries" : { + "items" : { + "$ref" : "#/components/schemas/OntologyEntry" + }, + "type" : "array" + }, + "namespace" : { + "type" : "string" + }, + "uuid" : { + "type" : "string" + } + }, + "type" : "object" + }, + "OntologyEntry" : { + "properties" : { + "datatypeIri" : { + "type" : "string" + }, + "iri" : { + "type" : "string" + }, + "isIriEntry" : { + "type" : "boolean" + }, + "value" : { + "type" : "string" + } + }, + "type" : "object" + }, + "OntologyField" : { + "properties" : { + "datatypeIri" : { + "type" : "string" + }, + "iri" : { + "type" : "string" + }, + "iriEntry" : { + "type" : "boolean" + }, + "isIriEntry" : { + "type" : "boolean" + } + }, + "type" : "object" + }, + "PackageDTO" : { + "properties" : { + "comment" : { + "type" : "string" + }, + "label" : { + "type" : "string" + }, + "package" : { + "$ref" : "#/components/schemas/BelongsToCategoryDTO" + }, + "prefix" : { + "type" : "string" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "PasteClassesRequestDTO" : { + "properties" : { + "copyAsAbstract" : { + "type" : "boolean" + }, + "copyAssociations" : { + "type" : "boolean" + }, + "copyAttributes" : { + "type" : "boolean" + }, + "sources" : { + "items" : { + "$ref" : "#/components/schemas/PasteSourceClassDTO" + }, + "type" : "array" + }, + "targetPackage" : { + "$ref" : "#/components/schemas/PackageDTO" + } + }, + "type" : "object" + }, + "PasteSourceClassDTO" : { + "properties" : { + "classUUID" : { + "type" : "string" + }, + "sourceDatasetName" : { + "type" : "string" + }, + "sourceGraphURI" : { + "type" : "string" + } + }, + "type" : "object" + }, + "PropertyOverview" : { + "properties" : { + "associations" : { + "$ref" : "#/components/schemas/ResourceRenameOverviewSemanticAssociationChange" + }, + "attributes" : { + "$ref" : "#/components/schemas/ResourceRenameOverviewSemanticAttributeChange" + }, + "enumEntries" : { + "$ref" : "#/components/schemas/ResourceRenameOverviewSemanticEnumEntryChange" + }, + "label" : { + "type" : "string" + } + }, + "type" : "object" + }, + "PropertyRenamings" : { + "properties" : { + "associationRenames" : { + "items" : { + "$ref" : "#/components/schemas/RenameCandidateSemanticAssociationChange" + }, + "type" : "array" + }, + "attributeRenames" : { + "items" : { + "$ref" : "#/components/schemas/RenameCandidateSemanticAttributeChange" + }, + "type" : "array" + }, + "classLabel" : { + "type" : "string" + }, + "enumEntryRenames" : { + "items" : { + "$ref" : "#/components/schemas/RenameCandidateSemanticEnumEntryChange" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "PropertyShape" : { + "properties" : { + "id" : { + "type" : "string" + }, + "order" : { + "format" : "double", + "type" : "number" + }, + "triples" : { + "type" : "string" + } + }, + "type" : "object" + }, + "PropertyShapesWrapper" : { + "properties" : { + "domain" : { + "format" : "uuid", + "type" : "string" + }, + "label" : { + "type" : "string" + }, + "propertyShapes" : { + "items" : { + "$ref" : "#/components/schemas/PropertyShape" + }, + "type" : "array" + }, + "propertyType" : { + "type" : "string" + } + }, + "type" : "object" + }, + "RDFSComment" : { + "properties" : { + "format" : { + "$ref" : "#/components/schemas/URI" + }, + "value" : { + "type" : "string" + } + }, + "type" : "object" + }, + "RDFSDomain" : { + "properties" : { + "label" : { + "$ref" : "#/components/schemas/RDFSLabel" + }, + "uri" : { + "$ref" : "#/components/schemas/URI" + } + }, + "type" : "object" + }, + "RDFSLabel" : { + "properties" : { + "lang" : { + "type" : "string" + }, + "value" : { + "type" : "string" + } + }, + "type" : "object" + }, + "RDFSSubClassOf" : { + "properties" : { + "label" : { + "$ref" : "#/components/schemas/RDFSLabel" + }, + "uri" : { + "$ref" : "#/components/schemas/URI" + } + }, + "type" : "object" + }, + "RenameCandidateSemanticAssociationChange" : { + "properties" : { + "confidenceScore" : { + "format" : "double", + "type" : "number" + }, + "newResource" : { + "$ref" : "#/components/schemas/SemanticAssociationChange" + }, + "oldResource" : { + "$ref" : "#/components/schemas/SemanticAssociationChange" + } + }, + "type" : "object" + }, + "RenameCandidateSemanticAttributeChange" : { + "properties" : { + "confidenceScore" : { + "format" : "double", + "type" : "number" + }, + "newResource" : { + "$ref" : "#/components/schemas/SemanticAttributeChange" + }, + "oldResource" : { + "$ref" : "#/components/schemas/SemanticAttributeChange" + } + }, + "type" : "object" + }, + "RenameCandidateSemanticClassChange" : { + "properties" : { + "confidenceScore" : { + "format" : "double", + "type" : "number" + }, + "newResource" : { + "$ref" : "#/components/schemas/SemanticClassChange" + }, + "oldResource" : { + "$ref" : "#/components/schemas/SemanticClassChange" + } + }, + "type" : "object" + }, + "RenameCandidateSemanticEnumEntryChange" : { + "properties" : { + "confidenceScore" : { + "format" : "double", + "type" : "number" + }, + "newResource" : { + "$ref" : "#/components/schemas/SemanticEnumEntryChange" + }, + "oldResource" : { + "$ref" : "#/components/schemas/SemanticEnumEntryChange" + } + }, + "type" : "object" + }, + "RenameCandidateSemanticResourceChange" : { + "properties" : { + "confidenceScore" : { + "format" : "double", + "type" : "number" + }, + "newResource" : { + "oneOf" : [ + { + "$ref" : "#/components/schemas/SemanticResourceChange" + }, + { + "$ref" : "#/components/schemas/SemanticAssociationChange" + }, + { + "$ref" : "#/components/schemas/SemanticAttributeChange" + }, + { + "$ref" : "#/components/schemas/SemanticClassChange" + }, + { + "$ref" : "#/components/schemas/SemanticEnumEntryChange" + }, + { + "$ref" : "#/components/schemas/SemanticPackageChange" + } + ] + }, + "oldResource" : { + "oneOf" : [ + { + "$ref" : "#/components/schemas/SemanticResourceChange" + }, + { + "$ref" : "#/components/schemas/SemanticAssociationChange" + }, + { + "$ref" : "#/components/schemas/SemanticAttributeChange" + }, + { + "$ref" : "#/components/schemas/SemanticClassChange" + }, + { + "$ref" : "#/components/schemas/SemanticEnumEntryChange" + }, + { + "$ref" : "#/components/schemas/SemanticPackageChange" + } + ] + } + }, + "type" : "object" + }, + "RenderingDataDTO" : { + "properties" : { + "format" : { + "enum" : [ + "MERMAID", + "SVELTEFLOW" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "ResourceDeleteRequest" : { + "properties" : { + "action" : { + "enum" : [ + "DELETE", + "KEEP", + "REMOVE_PACKAGE_REFERENCE", + "REMOVE_SUBCLASS_REFERENCE" + ], + "type" : "string" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "ResourceIdentifier" : { + "properties" : { + "label" : { + "type" : "string" + }, + "namespace" : { + "type" : "string" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "ResourceRenameOverview" : { + "properties" : { + "added" : { + "items" : { + "oneOf" : [ + { + "$ref" : "#/components/schemas/SemanticResourceChange" + }, + { + "$ref" : "#/components/schemas/SemanticAssociationChange" + }, + { + "$ref" : "#/components/schemas/SemanticAttributeChange" + }, + { + "$ref" : "#/components/schemas/SemanticEnumEntryChange" + }, + { + "$ref" : "#/components/schemas/SemanticPackageChange" + } + ] + }, + "type" : "array" + }, + "deletedAndRenamed" : { + "items" : { + "$ref" : "#/components/schemas/RenameCandidateSemanticResourceChange" + }, + "type" : "array" + }, + "modified" : { + "items" : { + "oneOf" : [ + { + "$ref" : "#/components/schemas/SemanticResourceChange" + }, + { + "$ref" : "#/components/schemas/SemanticAssociationChange" + }, + { + "$ref" : "#/components/schemas/SemanticAttributeChange" + }, + { + "$ref" : "#/components/schemas/SemanticClassChange" + }, + { + "$ref" : "#/components/schemas/SemanticEnumEntryChange" + }, + { + "$ref" : "#/components/schemas/SemanticPackageChange" + } + ] + }, + "type" : "array" + } + }, + "type" : "object" + }, + "ResourceRenameOverviewSemanticAssociationChange" : { + "properties" : { + "added" : { + "items" : { + "$ref" : "#/components/schemas/SemanticAssociationChange" + }, + "type" : "array" + }, + "deletedAndRenamed" : { + "items" : { + "$ref" : "#/components/schemas/RenameCandidateSemanticAssociationChange" + }, + "type" : "array" + }, + "modified" : { + "items" : { + "$ref" : "#/components/schemas/SemanticAssociationChange" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "ResourceRenameOverviewSemanticAttributeChange" : { + "properties" : { + "added" : { + "items" : { + "$ref" : "#/components/schemas/SemanticAttributeChange" + }, + "type" : "array" + }, + "deletedAndRenamed" : { + "items" : { + "$ref" : "#/components/schemas/RenameCandidateSemanticAttributeChange" + }, + "type" : "array" + }, + "modified" : { + "items" : { + "$ref" : "#/components/schemas/SemanticAttributeChange" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "ResourceRenameOverviewSemanticEnumEntryChange" : { + "properties" : { + "added" : { + "items" : { + "$ref" : "#/components/schemas/SemanticEnumEntryChange" + }, + "type" : "array" + }, + "deletedAndRenamed" : { + "items" : { + "$ref" : "#/components/schemas/RenameCandidateSemanticEnumEntryChange" + }, + "type" : "array" + }, + "modified" : { + "items" : { + "$ref" : "#/components/schemas/SemanticEnumEntryChange" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "SHACLToClassRelations" : { + "properties" : { + "derivedPropertyShapes" : { + "items" : { + "$ref" : "#/components/schemas/PropertyShapesWrapper" + }, + "type" : "array" + }, + "namespaces" : { + "type" : "string" + }, + "nodeShapes" : { + "items" : { + "$ref" : "#/components/schemas/NodeShape" + }, + "type" : "array" + }, + "propertyShapes" : { + "items" : { + "$ref" : "#/components/schemas/PropertyShapesWrapper" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "SchemaValidationIssueDTO" : { + "properties" : { + "message" : { + "type" : "string" + }, + "resourceUri" : { + "type" : "string" + }, + "severity" : { + "enum" : [ + "ERROR", + "WARNING", + "INFO" + ], + "type" : "string" + } + }, + "type" : "object" + }, + "SchemaValidationReportDTO" : { + "properties" : { + "issues" : { + "items" : { + "$ref" : "#/components/schemas/SchemaValidationIssueDTO" + }, + "type" : "array" + }, + "valid" : { + "type" : "boolean" + } + }, + "type" : "object" + }, + "SearchFilter" : { + "description" : "The scope where the search is performed.", + "properties" : { + "datasetName" : { + "type" : "string" + }, + "graphUri" : { + "type" : "string" + }, + "packageUUID" : { + "type" : "string" + } + }, + "type" : "object" + }, + "SearchResult" : { + "properties" : { + "datasetName" : { + "type" : "string" + }, + "graphUri" : { + "type" : "string" + }, + "label" : { + "$ref" : "#/components/schemas/RDFSLabel" + }, + "packageLabel" : { + "$ref" : "#/components/schemas/RDFSLabel" + }, + "packageUUID" : { + "format" : "uuid", + "type" : "string" + }, + "parentClassUUID" : { + "format" : "uuid", + "type" : "string" + }, + "parentClassUri" : { + "$ref" : "#/components/schemas/URI" + }, + "type" : { + "enum" : [ + "CLASS", + "PACKAGE", + "ATTRIBUTE", + "ASSOCIATION", + "ENUMTYPE" + ], + "type" : "string" + }, + "uri" : { + "$ref" : "#/components/schemas/URI" + }, + "uuid" : { + "format" : "uuid", + "type" : "string" + } + }, + "type" : "object" + }, + "SearchResults" : { + "properties" : { + "externalSearchResults" : { + "items" : { + "$ref" : "#/components/schemas/SearchResult" + }, + "type" : "array" + }, + "internalSearchResults" : { + "items" : { + "$ref" : "#/components/schemas/SearchResult" + }, + "type" : "array" + } + }, + "type" : "object" + }, + "SemanticAssociationChange" : { + "allOf" : [ + { + "$ref" : "#/components/schemas/SemanticResourceChange" + }, + { + "properties" : { + "associationUsed" : { + "type" : "boolean" + }, + "mapping" : { + "type" : "string" + }, + "range" : { + "type" : "string" + } + }, + "type" : "object" + } + ] + }, + "SemanticAttributeChange" : { + "allOf" : [ + { + "$ref" : "#/components/schemas/SemanticResourceChange" + }, + { + "properties" : { + "allowedValues" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "dataType" : { + "type" : "string" + }, + "defaultValue" : { + "type" : "string" + }, + "forceDefaultValue" : { + "type" : "boolean" + }, + "optional" : { + "type" : "boolean" + }, + "primitiveDataType" : { + "type" : "string" + } + }, + "type" : "object" + } + ] + }, + "SemanticClassChange" : { + "allOf" : [ + { + "$ref" : "#/components/schemas/SemanticResourceChange" + }, + { + "properties" : { + "associationRenameCandidates" : { + "items" : { + "$ref" : "#/components/schemas/RenameCandidateSemanticAssociationChange" + }, + "type" : "array" + }, + "associations" : { + "items" : { + "$ref" : "#/components/schemas/SemanticAssociationChange" + }, + "type" : "array" + }, + "attributeRenameCandidates" : { + "items" : { + "$ref" : "#/components/schemas/RenameCandidateSemanticAttributeChange" + }, + "type" : "array" + }, + "attributes" : { + "items" : { + "$ref" : "#/components/schemas/SemanticAttributeChange" + }, + "type" : "array" + }, + "enumEntries" : { + "items" : { + "$ref" : "#/components/schemas/SemanticEnumEntryChange" + }, + "type" : "array" + }, + "enumEntryRenameCandidates" : { + "items" : { + "$ref" : "#/components/schemas/RenameCandidateSemanticEnumEntryChange" + }, + "type" : "array" + } + }, + "type" : "object" + } + ] + }, + "SemanticEnumEntryChange" : { + "allOf" : [ + { + "$ref" : "#/components/schemas/SemanticResourceChange" + }, + { + "properties" : { + "allowedValues" : { + "items" : { + "type" : "string" + }, + "type" : "array" + }, + "replacementValue" : { + "type" : "string" + } + }, + "type" : "object" + } + ] + }, + "SemanticFieldChange" : { + "properties" : { + "from" : { + "type" : "string" + }, + "semanticFieldChangeType" : { + "enum" : [ + "LABEL_CHANGE", + "COMMENT_CHANGE", + "SUPERCLASS_CHANGE", + "BELONGS_TO_CATEGORY_CHANGE", + "DATATYPE_CHANGE", + "DATATYPE_RENAME", + "MADE_OPTIONAL", + "MADE_REQUIRED", + "MULTIPLICITY_CHANGE", + "STEREOTYPE_ADDED", + "STEREOTYPE_REMOVED", + "MADE_ABSTRACT", + "DOMAIN_CHANGE", + "DOMAIN_RENAME", + "TARGET_CHANGE", + "ASSOCIATION_USED_CHANGE", + "DEFAULT_VALUE_CHANGE", + "FIXED_VALUE_CHANGE" + ], + "type" : "string" + }, + "to" : { + "type" : "string" + } + }, + "type" : "object" + }, + "SemanticPackageChange" : { + "allOf" : [ + { + "$ref" : "#/components/schemas/SemanticResourceChange" + }, + { + "properties" : { + "classChanges" : { + "items" : { + "$ref" : "#/components/schemas/SemanticClassChange" + }, + "type" : "array" + } + }, + "type" : "object" + } + ] + }, + "SemanticResourceChange" : { + "discriminator" : { + "propertyName" : "type" + }, + "properties" : { + "changes" : { + "items" : { + "$ref" : "#/components/schemas/SemanticFieldChange" + }, + "type" : "array" + }, + "iri" : { + "type" : "string" + }, + "label" : { + "type" : "string" + }, + "oldIRI" : { + "type" : "string" + }, + "semanticResourceChangeType" : { + "enum" : [ + "ADD", + "ADDED_FROM_INHERITANCE", + "DELETE", + "DELETED_FROM_INHERITANCE", + "CHANGE", + "RENAME" + ], + "type" : "string" + }, + "type" : { + "type" : "string" + } + }, + "required" : [ + "type" + ], + "type" : "object" + }, + "SuperClassDTO" : { + "properties" : { + "label" : { + "type" : "string" + }, + "prefix" : { + "type" : "string" + } + }, + "type" : "object" + }, + "TripleClassChange" : { + "properties" : { + "associations" : { + "items" : { + "$ref" : "#/components/schemas/TripleResourceChange" + }, + "type" : "array" + }, + "attributes" : { + "items" : { + "$ref" : "#/components/schemas/TripleResourceChange" + }, + "type" : "array" + }, + "changes" : { + "items" : { + "$ref" : "#/components/schemas/TriplePropertyChange" + }, + "type" : "array" + }, + "enumEntries" : { + "items" : { + "$ref" : "#/components/schemas/TripleResourceChange" + }, + "type" : "array" + }, + "label" : { + "type" : "string" + }, + "uri" : { + "type" : "string" + } + }, + "type" : "object" + }, + "TriplePackageChange" : { + "properties" : { + "changes" : { + "items" : { + "$ref" : "#/components/schemas/TriplePropertyChange" + }, + "type" : "array" + }, + "classes" : { + "items" : { + "$ref" : "#/components/schemas/TripleClassChange" + }, + "type" : "array" + }, + "external" : { + "type" : "boolean" + }, + "label" : { + "type" : "string" + }, + "uri" : { + "type" : "string" + } + }, + "type" : "object" + }, + "TriplePropertyChange" : { + "properties" : { + "from" : { + "type" : "string" + }, + "predicate" : { + "type" : "string" + }, + "to" : { + "type" : "string" + } + }, + "type" : "object" + }, + "TripleResourceChange" : { + "properties" : { + "changes" : { + "items" : { + "$ref" : "#/components/schemas/TriplePropertyChange" + }, + "type" : "array" + }, + "label" : { + "type" : "string" + }, + "uri" : { + "type" : "string" + } + }, + "type" : "object" + }, + "URI" : { + "description" : "When deserializing (parsing json to object), it is possible to alternatively only put a String containing the whole uri. For serializing (parsing object to json), the object structure ist always used.", + "properties" : { + "prefix" : { + "type" : "string" + }, + "suffix" : { + "type" : "string" + } + }, + "type" : "object" + } + } + }, + "info" : { + "contact" : { + "name" : "soptim", + "url" : "https://www.soptim.de/" + }, + "description" : "This API provides utilities for editing RDFGraphs that model UML classes using the CIM standard.", + "license" : { + "name" : "Apache License 2.0", + "url" : "https://www.apache.org/licenses/LICENSE-2.0" + }, + "title" : "RDFArchitect backend", + "version" : "0.0.0" + }, + "openapi" : "3.1.0", + "paths" : { + "/api/compare" : { + "post" : { + "description" : "Compare two given graphs", + "operationId" : "compareSchemasFromFiles", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "properties" : { + "fileA" : { + "description" : "The first graph file.", + "format" : "binary", + "type" : "string" + }, + "fileB" : { + "description" : "The second graph file.", + "format" : "binary", + "type" : "string" + } + }, + "required" : [ + "fileA", + "fileB" + ], + "type" : "object" + } + } + } + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/TriplePackageChange" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "compare schemas", + "tags" : [ + "comparison" + ] + } + }, + "/api/datasets" : { + "get" : { + "description" : "Lists all non-snapshots datasets including their prefixes and read-only status.", + "operationId" : "listDatasets", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/DatasetDTO" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "List datasets", + "tags" : [ + "dataset" + ] + } + }, + "/api/datasets/{datasetName}" : { + "delete" : { + "description" : "Deletes a dataset including all of its graphs.", + "operationId" : "deleteDataset", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Delete dataset", + "tags" : [ + "dataset" + ] + } + }, + "/api/datasets/{datasetName}/content" : { + "get" : { + "description" : "Export a file storing all RDFSchema graphs from a dataset", + "operationId" : "getDatasetSchema", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/n-quads" : { }, + "application/trig" : { } + }, + "description" : "OK" + } + }, + "summary" : "export dataset", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/crossprofilediagram" : { + "get" : { + "operationId" : "getCrossProfileDiagram", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/CrossProfileDiagramDTO" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "cross-profile-diagram-rest-controller" + ] + } + }, + "/api/datasets/{datasetName}/crossprofilediagramColors" : { + "get" : { + "operationId" : "getCrossProfileColors", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/CrossProfileDiagramColorDataDTO" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "cross-profile-diagram-color-rest-controller" + ] + }, + "put" : { + "operationId" : "updateCrossProfileColors", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/CrossProfileDiagramColorDataDTO" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "OK" + } + }, + "tags" : [ + "cross-profile-diagram-color-rest-controller" + ] + } + }, + "/api/datasets/{datasetName}/crossprofilediagramID" : { + "get" : { + "operationId" : "getCrossProfileDiagramId", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "cross-profile-diagram-idrest-controller" + ] + } + }, + "/api/datasets/{datasetName}/crossprofilediagramRendering" : { + "get" : { + "operationId" : "getCrossProfileRenderingData", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/RenderingDataDTO" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "cross-profile-diagram-rendering-rest-controller" + ] + } + }, + "/api/datasets/{datasetName}/diagrams" : { + "get" : { + "description" : "Returns a list of all custom diagrams for the specified dataset. Each diagram includes its ID, name, and other relevant information.", + "operationId" : "getCustomDatasetDiagramList", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "list custom diagrams for dataset", + "tags" : [ + "diagram" + ] + } + }, + "/api/datasets/{datasetName}/diagrams/{diagramId}" : { + "delete" : { + "operationId" : "deleteCustomDatasetDiagram", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the diagram.", + "in" : "path", + "name" : "diagramId", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "custom-dataset-diagrams-rest-controller" + ] + }, + "get" : { + "operationId" : "getCustomDatasetViewRenderingData", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the diagram.", + "in" : "path", + "name" : "diagramId", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/RenderingDataDTO" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "custom-dataset-diagrams-rest-controller" + ] + }, + "put" : { + "operationId" : "replaceCustomDatasetDiagram", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the diagram.", + "in" : "path", + "name" : "diagramId", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/CustomDiagram" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "custom-dataset-diagrams-rest-controller" + ] + } + }, + "/api/datasets/{datasetName}/diagrams/{diagramId}/classes" : { + "delete" : { + "operationId" : "removeFromCustomDatasetDiagram", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the diagram.", + "in" : "path", + "name" : "diagramId", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The list of class uuids to be removed from the diagram", + "items" : { + "format" : "uuid", + "type" : "string" + }, + "type" : "array" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "custom-dataset-diagram-all-classes-rest-controller" + ] + }, + "post" : { + "operationId" : "addToCustomDatasetDiagram", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the diagram.", + "in" : "path", + "name" : "diagramId", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The list of the classes to be added to the diagram", + "items" : { + "$ref" : "#/components/schemas/ClassInDiagram" + }, + "type" : "array" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "custom-dataset-diagram-all-classes-rest-controller" + ] + } + }, + "/api/datasets/{datasetName}/graphs" : { + "get" : { + "description" : "Lists all graphs in a specified datasets", + "operationId" : "listGraphs", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/URI" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "List graphs", + "tags" : [ + "dataset" + ] + } + }, + "/api/datasets/{datasetName}/graphs/content" : { + "put" : { + "description" : "Replace or insert one or more rdf graphs for the dataset. Accepts multiple files and/or zip archives containing several graph files.", + "operationId" : "replaceGraphs", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "Optional graph URIs, one per file. Defaults to file names.", + "in" : "query", + "name" : "graphUris", + "required" : false, + "schema" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + } + ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "properties" : { + "files" : { + "description" : "The files containing the graph data", + "items" : { + "format" : "binary", + "type" : "string" + }, + "type" : "array" + } + }, + "required" : [ + "files" + ], + "type" : "object" + } + } + } + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/GraphBulkImportResponse" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Replace/Insert multiple graphs", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/canRedo" : { + "post" : { + "description" : "Check whether the last undone change can be redone", + "operationId" : "canRedo", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "boolean" + } + } + }, + "description" : "OK" + } + }, + "summary" : "can Redo", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/canUndo" : { + "post" : { + "description" : "Check whether an undo operation is possible.", + "operationId" : "canUndo", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "boolean" + } + } + }, + "description" : "OK" + } + }, + "summary" : "can undo", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/changes" : { + "get" : { + "description" : "Get a list containing all changes made to a graph", + "operationId" : "getChangeLog", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ChangeLog" + } + } + }, + "description" : "OK" + } + }, + "summary" : "list changes for graph", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes" : { + "get" : { + "description" : "Get a list containing all classes. Doesn't include: stereotypes, attributes and associations.", + "operationId" : "getClassList", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "Whether to include external classes.", + "in" : "query", + "name" : "includeExternalClasses", + "required" : false, + "schema" : { + "default" : false, + "type" : "boolean" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/ClassUMLAdaptedDTO" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "list classes", + "tags" : [ + "graph" + ] + }, + "post" : { + "description" : "Create a new class with default name and no attributes, stereotypes or associations. Because no concrete stereotype is added the class is abstract by default.", + "operationId" : "addClass", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AddNewClassRequest" + } + } + }, + "description" : "Helper record, functions as DTO for accepting the necessary information for adding a new class", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "create new class", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}" : { + "delete" : { + "description" : "Deletes a whole class.", + "operationId" : "deleteClass", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Delete class", + "tags" : [ + "class" + ] + }, + "get" : { + "description" : "Get all information about a specified class.", + "operationId" : "getClassInformation", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ClassUMLAdaptedDTO" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Get class information", + "tags" : [ + "class" + ] + }, + "put" : { + "description" : "Replace a whole class.", + "operationId" : "replaceClass", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ClassUMLAdaptedDTO" + } + } + }, + "description" : "The new class", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Replace class", + "tags" : [ + "class" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}/associations" : { + "post" : { + "description" : "Creates a new association for a specified class.", + "operationId" : "createAssociation", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AssociationPairDTO" + } + } + }, + "description" : "The new association", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/AssociationUUIDs" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Creates association", + "tags" : [ + "class" + ] + }, + "put" : { + "description" : "Replaces all associations of a specified class.", + "operationId" : "replaceAllAssociations", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/AssociationPairDTO" + }, + "type" : "array" + } + } + }, + "description" : "The new association", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Replace all association", + "tags" : [ + "class" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}/associations/{associationUUID}" : { + "put" : { + "description" : "Replaces an association of a specified class.", + "operationId" : "replaceAssociation", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The old, to be replaced association.", + "in" : "path", + "name" : "associationUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AssociationPairDTO" + } + } + }, + "description" : "The new association", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/AssociationUUIDs" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Replace/Create association", + "tags" : [ + "class" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}/associations/{associationUUID}/shacl" : { + "get" : { + "description" : "GET the shacl rules that can be related to a specified association.", + "operationId" : "getAssociationSHACL", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the association.", + "in" : "path", + "name" : "associationUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/CustomAndGeneratedTupleListPropertyShape" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Get SHACL related to an association", + "tags" : [ + "shacl" + ] + }, + "put" : { + "description" : "Replace the SHACL rules of an association.", + "operationId" : "replaceAssociationSHACL", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the association.", + "in" : "path", + "name" : "associationUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The SHACL shapes to be inserted.", + "type" : "string" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "replace SHACL of an association", + "tags" : [ + "shacl" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}/attributes" : { + "post" : { + "description" : "Creates a new attribute for a specified class.", + "operationId" : "createAttribute", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AttributeDTO" + } + } + }, + "description" : "The new attribute", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "format" : "uuid", + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Create attribute", + "tags" : [ + "class" + ] + }, + "put" : { + "description" : "Replaces all attributes of a specified class.", + "operationId" : "replaceAllAttributes", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/CIMAttribute" + }, + "type" : "array" + } + } + }, + "description" : "The new attribute", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Replace all attributes", + "tags" : [ + "class" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}/attributes/{attributeUUID}" : { + "put" : { + "description" : "Replaces an attribute of a specified class.", + "operationId" : "replaceAttribute", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the old, to be replaced attribute.", + "in" : "path", + "name" : "attributeUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AttributeDTO" + } + } + }, + "description" : "The new attribute", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "format" : "uuid", + "type" : "string" + } + } + }, + "description" : "The uuid of the new attribute." + } + }, + "summary" : "Replace/Create attribute", + "tags" : [ + "class" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}/attributes/{attributeUUID}/shacl" : { + "get" : { + "description" : "GET the shacl rules that can be related to a specified attribute.", + "operationId" : "getAttributeSHACL", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the attribute.", + "in" : "path", + "name" : "attributeUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/CustomAndGeneratedTupleListPropertyShape" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Get SHACL related to an attribute", + "tags" : [ + "shacl" + ] + }, + "put" : { + "description" : "Replace the SHACL rules of an attribute.", + "operationId" : "replaceAttributeSHACL", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the association.", + "in" : "path", + "name" : "attributeUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The SHACL shapes to be inserted.", + "type" : "string" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "replace SHACL of an attribute", + "tags" : [ + "shacl" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}/enumentries" : { + "post" : { + "description" : "Creates a new enum entry for a specified class.", + "operationId" : "createEnumEntry", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the enum.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/EnumEntryDTO" + } + } + }, + "description" : "The new enum entry.", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "format" : "uuid", + "type" : "string" + } + } + }, + "description" : "UUID of the newly created enum entry." + } + }, + "summary" : "Create enum entry", + "tags" : [ + "enum" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}/enumentries/{enumEntryUUID}" : { + "put" : { + "description" : "Replaces the enum entry for a given enum URI and labels", + "operationId" : "replaceEnumEntry", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the enum.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the enum entry.", + "in" : "path", + "name" : "enumEntryUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/EnumEntryDTO" + } + } + }, + "description" : "The new enum entry.", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "format" : "uuid", + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Replace enum entry", + "tags" : [ + "enum" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}/extend" : { + "post" : { + "description" : "extends a class in another graph", + "operationId" : "extendClass", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/AttributeDTO" + } + } + }, + "description" : "The new attribute", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/ClassDTO" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Extend class", + "tags" : [ + "class" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}/referencedByClasses" : { + "get" : { + "description" : "Get all classes referencing this class.", + "operationId" : "getClassesReferencingThisClass", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/ClassRelationsDTO" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Get classes referencing this class", + "tags" : [ + "class" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}/shacl" : { + "get" : { + "description" : "Get the shacl rules that can be related to a specified class.", + "operationId" : "getSHACLRelatedToClass", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/CustomAndGeneratedTupleSHACLToClassRelations" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Get SHACL related to a class", + "tags" : [ + "shacl" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}/shacl/custom" : { + "put" : { + "description" : "Replace or insert SHACL rules related to a class.", + "operationId" : "putSHACL", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The SHACL shapes to be inserted.", + "type" : "string" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Replace or insert SHACL", + "tags" : [ + "shacl" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/classes/{classUUID}/shacl/propertyShapes" : { + "get" : { + "description" : "Get the shacl rules that can be related to a specified class.", + "operationId" : "getPropertyShapes", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class.", + "in" : "path", + "name" : "classUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/PropertyShapesWrapper" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Get SHACL related to a class", + "tags" : [ + "shacl" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/compare" : { + "get" : { + "description" : "Compare two graphs stored in the database", + "operationId" : "compareStoredSchemas", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the base dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the base graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset to compare against.", + "in" : "query", + "name" : "otherDataset", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph to compare against.", + "in" : "query", + "name" : "otherGraph", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/TriplePackageChange" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "compare schemas", + "tags" : [ + "comparison" + ] + }, + "post" : { + "description" : "Compare a given graph with the specified graph from the dataset", + "operationId" : "compareSchemas", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "properties" : { + "file" : { + "description" : "The file containing the graph to be compared.", + "format" : "binary", + "type" : "string" + } + }, + "required" : [ + "file" + ], + "type" : "object" + } + } + } + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/TriplePackageChange" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "compare schemas", + "tags" : [ + "comparison" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/content" : { + "delete" : { + "description" : "Delete an rdf-schema graph", + "operationId" : "deleteGraph", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "delete graph", + "tags" : [ + "graph" + ] + }, + "get" : { + "description" : "Export the rdf-schema graph", + "operationId" : "getSchema", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/n-triples" : { }, + "application/rdf+json" : { }, + "application/rdf+xml" : { }, + "text/turtle" : { } + }, + "description" : "OK" + } + }, + "summary" : "export graph", + "tags" : [ + "graph" + ] + }, + "put" : { + "description" : "Replace or insert an rdf-schema graph", + "operationId" : "replaceGraph", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "properties" : { + "file" : { + "description" : "The file containing the graph to be inserted", + "format" : "binary", + "type" : "string" + } + }, + "type" : "object" + } + } + } + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Replace/Insert graph", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/datatypes" : { + "get" : { + "description" : "Get a list of datatypes/classes. Doesn't include: Primitive Datatypes, stereotypes, attributes and associations.", + "operationId" : "listDatatypes", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/ClassUMLAdaptedDTO" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "list datatypes", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/delete-requests" : { + "post" : { + "description" : "Processes a list of delete requests, each specifying a resource UUID and the desired action.", + "operationId" : "deleteResources", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "A list of resource delete requests, each containing the uuid of the resource to delete and the type of deletion", + "items" : { + "$ref" : "#/components/schemas/ResourceDeleteRequest" + }, + "type" : "array" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Delete resources", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/deletion-impact" : { + "post" : { + "description" : "Returns, per requested UUID, a tree of affected resources for deleting that resource.", + "operationId" : "getDeletionImpact", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The uuids of the cim resources to analyse.", + "items" : { + "format" : "uuid", + "type" : "string" + }, + "type" : "array" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "additionalProperties" : { + "$ref" : "#/components/schemas/AffectedResource" + }, + "type" : "object" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Get deletion impact", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/diagrams" : { + "get" : { + "description" : "Returns a list of all custom diagrams for the specified graph. Each diagram includes its ID, name, and other relevant information.", + "operationId" : "getCustomGraphDiagramList", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "list custom diagrams for graph", + "tags" : [ + "diagram" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/diagrams/{diagramId}" : { + "delete" : { + "operationId" : "deleteCustomGraphDiagram", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the diagram.", + "in" : "path", + "name" : "diagramId", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "custom-diagrams-rest-controller" + ] + }, + "get" : { + "operationId" : "getCustomProfileViewRenderingData", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the diagram.", + "in" : "path", + "name" : "diagramId", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/RenderingDataDTO" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "custom-diagrams-rest-controller" + ] + }, + "put" : { + "operationId" : "replaceCustomGraphDiagram", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the diagram.", + "in" : "path", + "name" : "diagramId", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "custom-diagrams-rest-controller" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/diagrams/{diagramId}/classes" : { + "delete" : { + "operationId" : "removeFromDiagram", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the diagram.", + "in" : "path", + "name" : "diagramId", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The list of class uuids to be removed from the diagram", + "items" : { + "format" : "uuid", + "type" : "string" + }, + "type" : "array" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "custom-diagram-all-classes-rest-controller" + ] + }, + "post" : { + "operationId" : "addToCustomGraphDiagram", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the diagram.", + "in" : "path", + "name" : "diagramId", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The list of the classes to be added to the diagram", + "items" : { + "$ref" : "#/components/schemas/ClassInDiagram" + }, + "type" : "array" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "custom-diagram-all-classes-rest-controller" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/diagrams/{diagramId}/classes/{classId}" : { + "delete" : { + "operationId" : "removeFromCustomGraphDiagram", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the diagram.", + "in" : "path", + "name" : "diagramId", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The uuid of the class to be removed from the diagram.", + "in" : "path", + "name" : "classId", + "required" : true, + "schema" : { + "format" : "uuid", + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "tags" : [ + "custom-diagram-class-rest-controller" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/layout/{diagramUUID}/classes" : { + "put" : { + "description" : "Updates the positions for all the classes provided in the request body with the provided coordinates.", + "operationId" : "updateClassPositions", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The UUID of the package or custom diagram being updated.", + "in" : "path", + "name" : "diagramUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/ClassPositionDTO" + }, + "type" : "array" + } + } + }, + "description" : "The DTO with necessary information for class reposition", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "updates class positions", + "tags" : [ + "diagram", + "layout", + "class" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/ontology" : { + "delete" : { + "description" : "Deletes the currently stored ontology.", + "operationId" : "deleteOntology", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Delete ontology", + "tags" : [ + "ontology" + ] + }, + "get" : { + "description" : "Get the currently stored ontology. null if none stored.", + "operationId" : "getOntology", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/OntologyDTO" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Get ontology", + "tags" : [ + "ontology" + ] + }, + "post" : { + "description" : "create a new ontology.", + "operationId" : "createOntology", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/OntologyDTO" + } + } + }, + "description" : "The new ontology", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Create ontology", + "tags" : [ + "ontology" + ] + }, + "put" : { + "description" : "Replace the currently stored ontology with a new one.", + "operationId" : "replaceOntology", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/OntologyDTO" + } + } + }, + "description" : "The new ontology", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Replace ontology", + "tags" : [ + "ontology" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/ontology/generate" : { + "get" : { + "description" : "Get the Ontology fields that can be automatically generated.", + "operationId" : "getOntologyEntries", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/OntologyEntry" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Get generated ontology entries", + "tags" : [ + "ontology" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/packages" : { + "get" : { + "description" : "Get two lists of packages: internal and external packages.", + "operationId" : "listPackages", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ListPackagesResponse" + } + } + }, + "description" : "OK" + } + }, + "summary" : "list packages", + "tags" : [ + "graph" + ] + }, + "post" : { + "description" : "Create a new package with a given name and optional comment, sub-package relation is nulled", + "operationId" : "addPackage", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PackageDTO" + } + } + }, + "description" : "DTO for the package to be created", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "format" : "uuid", + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "create new package", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/packages/{packageUUID}" : { + "delete" : { + "description" : "Deletes a package by UUID.", + "operationId" : "deletePackage", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The UUID of the package to be deleted.", + "in" : "path", + "name" : "packageUUID", + "required" : true, + "schema" : { + "format" : "uuid", + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "delete package", + "tags" : [ + "package", + "graph" + ] + }, + "get" : { + "description" : "Returns the package DTO for the given UUID.", + "operationId" : "getPackage", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The UUID of the package to retrieve.", + "in" : "path", + "name" : "packageUUID", + "required" : true, + "schema" : { + "format" : "uuid", + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/PackageDTO" + } + } + }, + "description" : "OK" + } + }, + "summary" : "get package", + "tags" : [ + "package", + "graph" + ] + }, + "put" : { + "description" : "Replaces a whole package.", + "operationId" : "replacePackage", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The UUID of the package to be replaced.", + "in" : "path", + "name" : "packageUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PackageDTO" + } + } + }, + "description" : "DTO for the package to be replaced", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "replace package", + "tags" : [ + "package", + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/primitives" : { + "get" : { + "description" : "Get a list of primitive datatypes/classes. Doesn't include: stereotypes, attributes and associations.", + "operationId" : "listPrimitives", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/ClassUMLAdaptedDTO" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "list primitives", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/redo" : { + "post" : { + "description" : "Redo the last undone change", + "operationId" : "redo", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "redo ", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/rendering" : { + "post" : { + "description" : "Returns rendering data for UML diagrams. The content varies based on environment configuration (Mermaid or Svelteflow).", + "operationId" : "getRenderingDataParameterized", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/GraphFilter" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/RenderingDataDTO" + } + } + }, + "description" : "Rendering data (Mermaid or Svelteflow)" + } + }, + "summary" : "Get rendering data", + "tags" : [ + "svelteflow", + "mermaid" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/resolve/iri/{iriIdentifier}" : { + "get" : { + "description" : "Resolve iri identifier of a cim resource to its uuid.", + "operationId" : "resolveIri", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded iri identifier of the cim resource.", + "in" : "path", + "name" : "iriIdentifier", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "resolve iri identifier", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/restore" : { + "post" : { + "description" : "restores the graph to the state specified by the version id", + "operationId" : "restoreVersion", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "The ID of the version to restore.", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "restore ", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/shacl/combined/file" : { + "get" : { + "description" : "Export the combined rdf-shacl graph of the generated and custom shapes for a graph.", + "operationId" : "getCombinedSHACLAsFile", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/n-triples" : { }, + "application/rdf+json" : { }, + "application/rdf+xml" : { }, + "text/turtle" : { } + }, + "description" : "OK" + } + }, + "summary" : "export shacl", + "tags" : [ + "shacl" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/shacl/custom/file" : { + "get" : { + "description" : "Export the rdf-shacl graph", + "operationId" : "getCustomSHACLAsFile", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/n-triples" : { }, + "application/rdf+json" : { }, + "application/rdf+xml" : { }, + "text/turtle" : { } + }, + "description" : "OK" + } + }, + "summary" : "export shacl", + "tags" : [ + "shacl" + ] + }, + "put" : { + "description" : "Replace or insert a shacl graph stored in a file", + "operationId" : "replaceGraphWithFile", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "properties" : { + "file" : { + "description" : "The file containing the shacl graph to be inserted", + "format" : "binary", + "type" : "string" + } + }, + "required" : [ + "file" + ], + "type" : "object" + } + } + } + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Replace/Insert shacl", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/shacl/custom/namespaces/ttl" : { + "get" : { + "description" : "Export the namespaces of the custom SHACL graph for a given graph identifier.", + "operationId" : "getCustomSHACLNamespacesAsString", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "text/turtle" : { } + }, + "description" : "OK" + } + }, + "summary" : "export custom SHACL namespaces", + "tags" : [ + "shacl" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/shacl/custom/string" : { + "get" : { + "description" : "Export the rdf-shacl graph as String", + "operationId" : "getCustomSHACLAsString", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "text/turtle" : { } + }, + "description" : "OK" + } + }, + "summary" : "export shacl", + "tags" : [ + "shacl" + ] + }, + "put" : { + "description" : "Replace or insert a shacl graph stored in a Turtle String", + "operationId" : "replaceGraphWithGraphString", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The entire SHACL graph as a string", + "type" : "string" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Replace/Insert shacl", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/shacl/custom/{shaclShapeURI}" : { + "delete" : { + "description" : "Delete a shacl shape form a shacl graph", + "operationId" : "deleteShape", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The property shape to delete.", + "in" : "path", + "name" : "shaclShapeURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "delete a shacl shape", + "tags" : [ + "shacl" + ] + }, + "put" : { + "description" : "Replace or insert a shacl shape from a shacl graph with the given triples in a valid turtle syntax.", + "operationId" : "replaceShape", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The property shape to replace.", + "in" : "path", + "name" : "shaclShapeURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "the triples to replace, requires valid turtle syntax.", + "type" : "string" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Replace/Insert shacl shape", + "tags" : [ + "shacl" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/shacl/generate/file" : { + "get" : { + "description" : "Export the rdf-shacl graph as a file", + "operationId" : "getGeneratedSHACLAsFile", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/n-triples" : { }, + "application/rdf+json" : { }, + "application/rdf+xml" : { }, + "text/turtle" : { } + }, + "description" : "OK" + } + }, + "summary" : "export shacl", + "tags" : [ + "shacl" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/shacl/generate/string" : { + "get" : { + "description" : "generate shacl for the whole graph and return it as a Turtle string.", + "operationId" : "getGeneratedSHACLAsString", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "generate shacl", + "tags" : [ + "shacl" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/shacl/generated/namespaces/ttl" : { + "get" : { + "description" : "Export the namespaces of the generated SHACL graph for a given graph identifier.", + "operationId" : "getGeneratedSHACLNamespacesAsString", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "text/turtle" : { } + }, + "description" : "OK" + } + }, + "summary" : "export generated SHACL namespaces", + "tags" : [ + "shacl" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/stereotypes" : { + "get" : { + "description" : "Get a list of all occurring stereotypes in the graph.", + "operationId" : "listStereotypes", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "type" : "string" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "list stereotypes", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/undo" : { + "post" : { + "description" : "Undo the last change", + "operationId" : "undo", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "undo ", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/validate/{cgmesVersion}" : { + "get" : { + "description" : "Validates the RDFS schema of a graph for completeness, including the profile header.", + "operationId" : "validateSchema", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "in" : "path", + "name" : "cgmesVersion", + "required" : true, + "schema" : { + "enum" : [ + "V2_4_15", + "V3_0" + ], + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/SchemaValidationReportDTO" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Validate schema", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/graphs/{graphURI}/writeToDatabase" : { + "post" : { + "description" : "Write a graph to a database to persist it.", + "operationId" : "writeToDatabase", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "graphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Write to database", + "tags" : [ + "graph" + ] + } + }, + "/api/datasets/{datasetName}/layout/{diagramUUID}/classes" : { + "put" : { + "description" : "Updates the positions for all the classes provided in the request body with the provided coordinates.", + "operationId" : "updateDatasetClassPositions", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The UUID of the package or custom diagram being updated.", + "in" : "path", + "name" : "diagramUUID", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/ClassPositionDTO" + }, + "type" : "array" + } + } + }, + "description" : "The DTO with necessary information for class reposition", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "updates class positions on dataset level", + "tags" : [ + "diagram", + "layout", + "class" + ] + } + }, + "/api/datasets/{datasetName}/namespaces" : { + "get" : { + "description" : "Get a list of namespaces stored in a specified dataset.", + "operationId" : "listNamespaces", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/CIMPrefixPair" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "List namespaces", + "tags" : [ + "dataset" + ] + }, + "put" : { + "description" : "Replace all namespaces of a specified dataset.", + "operationId" : "replaceNamespaces", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The new Namespaces.", + "items" : { + "$ref" : "#/components/schemas/CIMPrefixPair" + }, + "type" : "array" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Replace namespaces", + "tags" : [ + "dataset" + ] + } + }, + "/api/datasets/{datasetName}/namespaces/{format}" : { + "get" : { + "description" : "Get a list of namespaces stored in a specified dataset formatted in a specified format.", + "operationId" : "listFormattedNamespaces", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The format of the namespaces.", + "in" : "path", + "name" : "format", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "List formatted namespaces", + "tags" : [ + "dataset" + ] + } + }, + "/api/datasets/{datasetName}/readonly" : { + "delete" : { + "description" : "Disables editing for specified dataset", + "operationId" : "disableEditing", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "disable editing", + "tags" : [ + "dataset", + "read-only" + ] + }, + "get" : { + "description" : "Check whether dataset is read-only", + "operationId" : "isReadOnly", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "boolean" + } + } + }, + "description" : "OK" + } + }, + "summary" : "is read only", + "tags" : [ + "dataset", + "read-only" + ] + }, + "put" : { + "description" : "Enables editing for specified dataset", + "operationId" : "enableEditing", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "datasetName", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "enable editing", + "tags" : [ + "dataset", + "read-only" + ] + } + }, + "/api/datasets/{targetDatasetName}/graphs/{targetGraphURI}/paste" : { + "post" : { + "description" : "Create copies of one or more previously copied classes in the target graph.", + "operationId" : "pasteClasses", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the target dataset.", + "in" : "path", + "name" : "targetDatasetName", + "required" : true, + "schema" : { + "type" : "string" + } + }, + { + "description" : "The url encoded uri of the target graph, or \"default\" to access the default graph.", + "in" : "path", + "name" : "targetGraphURI", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PasteClassesRequestDTO" + } + } + }, + "description" : "The target package, copy options and the list of source classes to paste.", + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/CopyClassResponseDTO" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "paste classes", + "tags" : [ + "paste-rest-controller" + ] + } + }, + "/api/migrations/class-renamings" : { + "get" : { + "description" : "Provides an overview of the migration classes including added, modified, deleted and potentially renamed classes.", + "operationId" : "getClassRenamings", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/ResourceRenameOverview" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "migration class overview", + "tags" : [ + "migration" + ] + }, + "post" : { + "description" : "Confirms the previously suggested renamed classes and updates the migration context accordingly.", + "operationId" : "confirmRenamedClasses", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The updated class renamings", + "items" : { + "$ref" : "#/components/schemas/RenameCandidateSemanticClassChange" + }, + "type" : "array" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "OK" + } + }, + "summary" : "confirm renamed classes", + "tags" : [ + "migration" + ] + } + }, + "/api/migrations/context" : { + "delete" : { + "description" : "Resets the current migration context, removing all stored data related to the ongoing migration session.", + "operationId" : "clearMigrationContext", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "description" : "OK" + } + }, + "summary" : "reset migration context", + "tags" : [ + "migration" + ] + }, + "post" : { + "description" : "Computes the diff of two given graphs and stores it in the session for later usage in migration endpoints. Accepts the graphs either as file uploads, GraphIdentifiers or a combination of both.", + "operationId" : "computeMigrationContext", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "Dataset of graph A. Required together with graph_uri_a when not uploading graph A as a file.", + "in" : "query", + "name" : "datasetA", + "required" : false, + "schema" : { + "type" : "string" + } + }, + { + "description" : "URI of graph A. Required together with dataset_a when not uploading graph A as a file.", + "in" : "query", + "name" : "graphA", + "required" : false, + "schema" : { + "type" : "string" + } + }, + { + "description" : "Dataset of graph B. Required together with graph_uri_b when not uploading graph B as a file.", + "in" : "query", + "name" : "datasetB", + "required" : false, + "schema" : { + "type" : "string" + } + }, + { + "description" : "URI of graph B. Required together with dataset_b when not uploading graph B as a file.", + "in" : "query", + "name" : "graphB", + "required" : false, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "multipart/form-data" : { + "schema" : { + "properties" : { + "fileA" : { + "description" : "The file containing graph A. Mutually exclusive with dataset_a and graph_uri_a.", + "format" : "binary", + "type" : "string" + }, + "fileB" : { + "description" : "The file containing graph B. Mutually exclusive with dataset_b and graph_uri_b.", + "format" : "binary", + "type" : "string" + } + }, + "type" : "object" + } + } + } + }, + "responses" : { + "200" : { + "description" : "OK" + } + }, + "summary" : "compute migration context", + "tags" : [ + "migration" + ] + } + }, + "/api/migrations/default-values" : { + "get" : { + "description" : "Provides an overview of attributes that require default values to be set for migration.", + "operationId" : "getDefaultValuesViews", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/DefaultValueView" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "get default values overview", + "tags" : [ + "migration" + ] + }, + "post" : { + "description" : "Sets the default values for attributes as provided by the user.", + "operationId" : "submitDefaultValues", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The updated default values for attributes.", + "items" : { + "$ref" : "#/components/schemas/DefaultValueView" + }, + "type" : "array" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "OK" + } + }, + "summary" : "submit default values", + "tags" : [ + "migration" + ] + } + }, + "/api/migrations/export" : { + "get" : { + "description" : "Generates a migration script based on the previously computed migration actions and the shacl shapes of the new schema.", + "operationId" : "generateMigrationScript", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/zip" : { } + }, + "description" : "OK" + } + }, + "summary" : "generate migration script", + "tags" : [ + "migration" + ] + } + }, + "/api/migrations/property-renames" : { + "get" : { + "description" : "Provides an overview of the properties on migration classes including added, modified, deleted and potentially renamed properties.", + "operationId" : "migrationPropertiesOverview", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/PropertyOverview" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "migration class property overview", + "tags" : [ + "migration" + ] + }, + "post" : { + "description" : "Confirms the previously suggested renamed properties and updates the migration context accordingly.", + "operationId" : "confirmRenamedProperties", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The updated property renames", + "items" : { + "$ref" : "#/components/schemas/PropertyRenamings" + }, + "type" : "array" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "description" : "OK" + } + }, + "summary" : "confirm renamed properties", + "tags" : [ + "migration" + ] + } + }, + "/api/ontology-fields" : { + "get" : { + "description" : "Get a list of all known ontology fields.", + "operationId" : "getKnownOntologyFields", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/OntologyField" + }, + "type" : "array" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Get known ontology fields", + "tags" : [ + "ontology" + ] + } + }, + "/api/primitiveDatatypes" : { + "get" : { + "description" : "Get a list of all supported xsd datatypes.", + "operationId" : "getPrimitiveDatatypes", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "items" : { + "$ref" : "#/components/schemas/URI" + }, + "type" : "array" + } + } + }, + "description" : "A list containing the uris of xsd datatypes." + } + }, + "summary" : "Get primitive datatypes", + "tags" : [ + "data" + ] + } + }, + "/api/search" : { + "post" : { + "description" : "Searches the given graph for a specific query", + "operationId" : "search", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The query to search for", + "in" : "query", + "name" : "query", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/SearchFilter" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "$ref" : "#/components/schemas/SearchResults" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Search the graph", + "tags" : [ + "dataset" + ] + } + }, + "/api/session" : { + "delete" : { + "description" : "Invalidates the current session, discarding all unsaved changes. A new session is created on the next request.", + "operationId" : "resetSession", + "responses" : { + "204" : { + "description" : "No Content" + } + }, + "summary" : "Reset session", + "tags" : [ + "session" + ] + } + }, + "/api/snapshots" : { + "post" : { + "description" : "Creates a snapshot for a dataset and persists it in the database", + "operationId" : "createSnapshot", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "description" : "The literal name of the dataset.", + "type" : "string" + } + } + }, + "required" : true + }, + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "snapshot dataset", + "tags" : [ + "snapshot", + "dataset" + ] + } + }, + "/api/snapshots/{base64Token}" : { + "get" : { + "description" : "Fetch a snapshot", + "operationId" : "loadSnapshot", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "description" : "The literal name of the dataset.", + "in" : "path", + "name" : "base64Token", + "required" : true, + "schema" : { + "type" : "string" + } + } + ], + "responses" : { + "200" : { + "content" : { + "*/*" : { + "schema" : { + "type" : "string" + } + } + }, + "description" : "OK" + } + }, + "summary" : "get snapshot", + "tags" : [ + "snapshot", + "dataset" + ] + } + }, + "/api/validate/{cgmesVersion}" : { + "post" : { + "description" : "Validates the RDFS schema of a given graph file for completeness, including the profile header.", + "operationId" : "validateFile", + "parameters" : [ + { + "description" : "The name/url of the inquirer.", + "in" : "header", + "name" : "Origin", + "required" : false, + "schema" : { + "default" : "unknown", + "type" : "string" + } + }, + { + "in" : "path", + "name" : "cgmesVersion", + "required" : true, + "schema" : { + "enum" : [ + "V2_4_15", + "V3_0" + ], + "type" : "string" + } + } + ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "properties" : { + "file" : { + "description" : "The graph file to validate.", + "format" : "binary", + "type" : "string" + } + }, + "required" : [ + "file" + ], + "type" : "object" + } + } + } + }, + "responses" : { + "200" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/SchemaValidationReportDTO" + } + } + }, + "description" : "OK" + } + }, + "summary" : "Validate schema", + "tags" : [ + "schema-validation-from-file-rest-controller" + ] + } + } + } +} diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 553b90e2..cd879f17 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -31,6 +31,7 @@ "@eslint/compat": "^2.0.0", "@eslint/js": "^10.0.0", "@faker-js/faker": "^10.0.0", + "@hey-api/openapi-ts": "0.97.1", "@sveltejs/adapter-auto": "^7.0.0", "@sveltejs/kit": "^2.5.27", "@sveltejs/vite-plugin-svelte": "^7.0.0", @@ -620,6 +621,132 @@ "node": ">=6" } }, + "node_modules/@hey-api/codegen-core": { + "version": "0.8.1", + "integrity": "sha512-Iciv2vUCJTW9lWM/ROvyZLblmcbYJHPuXfzb1SzeDVVn4xEXu2ilLU1pq3fn+09FZ/Y0P7VyvRE47UDU6om8xA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hey-api/types": "0.1.4", + "ansi-colors": "4.1.3", + "c12": "3.3.4", + "color-support": "1.1.3" + }, + "engines": { + "node": ">=22.13.0" + }, + "funding": { + "url": "https://github.com/sponsors/hey-api" + } + }, + "node_modules/@hey-api/json-schema-ref-parser": { + "version": "1.4.2", + "integrity": "sha512-ZhCFSKI2ipZHEbgmtUHdyddvRU3wJ4elgCfYUC7T7hZa4EivSrVflTQf2w+v3TuaYxR1Y2V2kq3otqTttrrK8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jsdevtools/ono": "7.1.3", + "@types/json-schema": "7.0.15", + "js-yaml": "4.1.1" + }, + "engines": { + "node": ">=22.13.0" + }, + "funding": { + "url": "https://github.com/sponsors/hey-api" + } + }, + "node_modules/@hey-api/openapi-ts": { + "version": "0.97.1", + "integrity": "sha512-LksUJeXAqwf6OhcCCr3/B4YjnBs5rqSqjDUKMBvkgp4OhaCQiJrOvntctFxdnugy8jUojP4yi/eJf5xYzcYzCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hey-api/codegen-core": "0.8.1", + "@hey-api/json-schema-ref-parser": "1.4.2", + "@hey-api/shared": "0.4.3", + "@hey-api/spec-types": "0.2.0", + "@hey-api/types": "0.1.4", + "@lukeed/ms": "2.0.2", + "ansi-colors": "4.1.3", + "color-support": "1.1.3", + "commander": "14.0.3", + "get-tsconfig": "4.14.0" + }, + "bin": { + "openapi-ts": "bin/run.js" + }, + "engines": { + "node": ">=22.13.0" + }, + "funding": { + "url": "https://github.com/sponsors/hey-api" + }, + "peerDependencies": { + "typescript": ">=5.5.3 || >=6.0.0 || 6.0.1-rc" + } + }, + "node_modules/@hey-api/openapi-ts/node_modules/commander": { + "version": "14.0.3", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/@hey-api/shared": { + "version": "0.4.3", + "integrity": "sha512-3tHfZNXgGOt+3P3Kq9cvqmZ9i7e3jtrkip1uDpZTX1+hTNboHhYdjxnT8AbrDuvslTaQHoAOlP4/iCDdzd9Jag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hey-api/codegen-core": "0.8.1", + "@hey-api/json-schema-ref-parser": "1.4.2", + "@hey-api/spec-types": "0.2.0", + "@hey-api/types": "0.1.4", + "ansi-colors": "4.1.3", + "cross-spawn": "7.0.6", + "open": "11.0.0", + "semver": "7.7.4" + }, + "engines": { + "node": ">=22.13.0" + }, + "funding": { + "url": "https://github.com/sponsors/hey-api" + } + }, + "node_modules/@hey-api/shared/node_modules/semver": { + "version": "7.7.4", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@hey-api/spec-types": { + "version": "0.2.0", + "integrity": "sha512-ibQ8Is7evMavzr8GNyJCcTg975d8DpaMUyLmOrQ85UBdy1l6t1KuRAwgChAbesJsIlNV6gjmlXruWyegDX18Fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hey-api/types": "0.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/hey-api" + } + }, + "node_modules/@hey-api/types": { + "version": "0.1.4", + "integrity": "sha512-thWfawrDIP7wSI9ioT13I5soaaqB5vAPIiZmgD8PbeEVKNrkonc0N/Sjj97ezl7oQgusZmaNphGdMKipPO6IBg==", + "dev": true, + "license": "MIT" + }, "node_modules/@humanfs/core": { "version": "0.19.2", "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", @@ -745,6 +872,12 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true, + "license": "MIT" + }, "node_modules/@lezer/common": { "version": "1.5.2", "integrity": "sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==", @@ -766,6 +899,15 @@ "@lezer/common": "^1.0.0" } }, + "node_modules/@lukeed/ms": { + "version": "2.0.2", + "integrity": "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/@marijn/find-cluster-break": { "version": "1.0.2", "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==", @@ -2514,6 +2656,21 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/aria-query": { "version": "5.3.1", "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", @@ -2696,6 +2853,49 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bundle-name": { + "version": "4.1.0", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/c12": { + "version": "3.3.4", + "integrity": "sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^5.0.0", + "confbox": "^0.2.4", + "defu": "^6.1.6", + "dotenv": "^17.3.1", + "exsolve": "^1.0.8", + "giget": "^3.2.0", + "jiti": "^2.6.1", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "perfect-debounce": "^2.1.0", + "pkg-types": "^2.3.0", + "rc9": "^3.0.1" + }, + "peerDependencies": { + "magicast": "*" + }, + "peerDependenciesMeta": { + "magicast": { + "optional": true + } + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001799", "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", @@ -2725,6 +2925,21 @@ "node": ">=18" } }, + "node_modules/chokidar": { + "version": "5.0.0", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/clsx": { "version": "2.1.1", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", @@ -2757,6 +2972,15 @@ "@lezer/lr": "^1.0.0" } }, + "node_modules/color-support": { + "version": "1.1.3", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/commander": { "version": "7.2.0", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", @@ -2774,6 +2998,12 @@ "node": ">= 12.0.0" } }, + "node_modules/confbox": { + "version": "0.2.4", + "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==", + "dev": true, + "license": "MIT" + }, "node_modules/convert-source-map": { "version": "2.0.0", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", @@ -3352,6 +3582,52 @@ "node": ">=0.10.0" } }, + "node_modules/default-browser": { + "version": "5.5.0", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defu": { + "version": "6.1.7", + "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==", + "dev": true, + "license": "MIT" + }, "node_modules/delaunator": { "version": "5.1.0", "integrity": "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==", @@ -3368,6 +3644,12 @@ "node": ">=6" } }, + "node_modules/destr": { + "version": "2.0.5", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "dev": true, + "license": "MIT" + }, "node_modules/detect-libc": { "version": "2.1.2", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", @@ -3389,6 +3671,18 @@ "@types/trusted-types": "^2.0.7" } }, + "node_modules/dotenv": { + "version": "17.4.2", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.381", "integrity": "sha512-n9Wa6yB+vDsGuA8AKbl/0z7HbvWqt5jxIdvr1IUicd0ryPrk7/xzwqLv8D9AbbvZ6avVNtXYLTfmgFHkwkyelg==", @@ -3766,6 +4060,12 @@ "node": ">=12.0.0" } }, + "node_modules/exsolve": { + "version": "1.1.0", + "integrity": "sha512-D+42+T12DdIlJM3uepa55qGiL3sYdLBOxIl2ifQCzCHz4c7eiolaHsi3BIqEr7JxBzxv2pYZQX9kw16ziMcEmw==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", @@ -3885,6 +4185,15 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/giget": { + "version": "3.3.0", + "integrity": "sha512-gzi2D96p+AMfDcmJHGDj3KJ9NRiwvlFAU5yfa3ROwWZmFUjX4P43x3BcyRaOMMLto1vUo7C+86+MFhYTl6Ryiw==", + "dev": true, + "license": "MIT", + "bin": { + "giget": "dist/cli.mjs" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", @@ -3982,6 +4291,21 @@ "node": ">=12" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", @@ -4003,6 +4327,36 @@ "node": ">=0.10.0" } }, + "node_modules/is-in-ssh": { + "version": "1.0.0", + "integrity": "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", @@ -4017,6 +4371,21 @@ "@types/estree": "^1.0.6" } }, + "node_modules/is-wsl": { + "version": "3.1.1", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", @@ -4031,6 +4400,18 @@ "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/js-yaml": { + "version": "4.1.1", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/jsdom": { "version": "29.1.1", "integrity": "sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==", @@ -4595,6 +4976,32 @@ ], "license": "MIT" }, + "node_modules/ohash": { + "version": "2.0.11", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/open": { + "version": "11.0.0", + "integrity": "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.4.0", + "define-lazy-prop": "^3.0.0", + "is-in-ssh": "^1.0.0", + "is-inside-container": "^1.0.0", + "powershell-utils": "^0.1.0", + "wsl-utils": "^0.3.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.4", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", @@ -4688,6 +5095,12 @@ "dev": true, "license": "MIT" }, + "node_modules/perfect-debounce": { + "version": "2.1.0", + "integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==", + "dev": true, + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", @@ -4704,6 +5117,17 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pkg-types": { + "version": "2.3.1", + "integrity": "sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.2.4", + "exsolve": "^1.0.8", + "pathe": "^2.0.3" + } + }, "node_modules/points-on-curve": { "version": "0.2.0", "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==", @@ -4854,6 +5278,18 @@ "dev": true, "license": "MIT" }, + "node_modules/powershell-utils": { + "version": "0.1.0", + "integrity": "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", @@ -4978,6 +5414,29 @@ "node": ">=6" } }, + "node_modules/rc9": { + "version": "3.0.1", + "integrity": "sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "defu": "^6.1.6", + "destr": "^2.0.5" + } + }, + "node_modules/readdirp": { + "version": "5.0.0", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/require-from-string": { "version": "2.0.2", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", @@ -5044,6 +5503,18 @@ "points-on-path": "^0.2.1" } }, + "node_modules/run-applescript": { + "version": "7.1.0", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/runed": { "version": "0.35.1", "integrity": "sha512-2F4Q/FZzbeJTFdIS/PuOoPRSm92sA2LhzTnv6FXhCoENb3huf5+fDuNOg1LNvGOouy3u/225qxmuJvcV3IZK5Q==", @@ -5911,6 +6382,22 @@ "node": ">=0.10.0" } }, + "node_modules/wsl-utils": { + "version": "0.3.1", + "integrity": "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0", + "powershell-utils": "^0.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/xml-name-validator": { "version": "5.0.0", "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", diff --git a/frontend/package.json b/frontend/package.json index fc723be0..d18e1c13 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,12 +10,14 @@ "clean-install": "rm -rf node_modules && npm install", "test": "vitest --run", "licenses:generate": "node licenses-third-party.js generate", - "licenses:check": "node licenses-third-party.js check" + "licenses:check": "node licenses-third-party.js check", + "api:generate": "openapi-ts" }, "devDependencies": { "@eslint/compat": "^2.0.0", "@eslint/js": "^10.0.0", "@faker-js/faker": "^10.0.0", + "@hey-api/openapi-ts": "0.97.1", "@sveltejs/adapter-auto": "^7.0.0", "@sveltejs/kit": "^2.5.27", "@sveltejs/vite-plugin-svelte": "^7.0.0", diff --git a/frontend/src/lib/GraphExport.svelte b/frontend/src/lib/GraphExport.svelte index f1adffe5..2a09b7a3 100644 --- a/frontend/src/lib/GraphExport.svelte +++ b/frontend/src/lib/GraphExport.svelte @@ -20,18 +20,17 @@ import { onMount } from "svelte"; import { Fa } from "svelte-fa"; - import { getNamespaces } from "$lib/api/apiDatasetUtils.js"; - import { BackendConnection } from "$lib/api/backend.js"; import { DropdownMenu } from "$lib/components/bitsui/dropdown/index"; import DatasetAndGraphSelection from "$lib/components/DatasetAndGraphSelection.svelte"; - import { PUBLIC_BACKEND_URL } from "$lib/config/runtime"; import { toastStore } from "$lib/eventhandling/toastStore.svelte.js"; import { ReactiveOntology } from "$lib/models/reactive/models/ontology/reactive-ontology.svelte.js"; import { forceReloadTrigger } from "$lib/sharedState.svelte.js"; + import { ontologyStore } from "$lib/stores/OntologyStore.ts"; import { userSettings } from "$lib/userSettings.svelte.js"; import { saveFile, supportedRDFMediaTypes } from "$lib/utils/fileUtils.ts"; import { editorState } from "../lib/sharedState.svelte.js"; + import { datasetStore } from "../lib/stores/DatasetStore.ts"; let { showDialog = $bindable(), @@ -42,8 +41,6 @@ supportedMediaTypes = supportedRDFMediaTypes, } = $props(); - const bec = new BackendConnection(fetch, PUBLIC_BACKEND_URL); - let selectedDatasetName = $state(null); let graphURI = $state(null); let selectedMediaType = $state(); @@ -51,7 +48,10 @@ let ontology = $state(); let generatedOntologyEntries = $state([]); - let namespaces = $state([]); + let namespaces = $derived( + $datasetStore.data?.find(d => d.label === selectedDatasetName) + ?.prefixes ?? new Set(), + ); let hasOntology = $derived(!!ontology); // Derived state for checkbox @@ -69,25 +69,21 @@ !selectedDatasetName || !graphURI || !selectedMediaType), ); - $effect(async () => { - if (selectedDatasetName) { - namespaces = await getNamespaces(selectedDatasetName); - } else { - namespaces = []; - } - }); - $effect(async () => { if (selectedDatasetName && graphURI) { - let ontologyJSON = await getOntology(selectedDatasetName, graphURI); - if (!ontologyJSON) { + await ontologyStore.loadOntology(selectedDatasetName, graphURI); + const result = await ontologyStore.getOntologyForGraph( + selectedDatasetName, + graphURI, + ); + if (result == null) { ontology = null; return; } ontology = new ReactiveOntology( - ontologyJSON.uuid, - ontologyJSON.namespace, - ontologyJSON.entries, + result.uuid, + result.namespace, + result.entries, namespaces, ); } @@ -95,11 +91,11 @@ $effect(async () => { if (selectedDatasetName && graphURI && hasOntology) { - const res = await bec.generateOntologyEntries( + const { data } = await ontologyStore.generateOntologyEntries( selectedDatasetName, graphURI, ); - generatedOntologyEntries = await res.json(); + generatedOntologyEntries = data; generatedOntologyEntries.forEach(entry => (entry.generate = true)); return; } @@ -110,9 +106,6 @@ selectedDatasetName = lockedDatasetName ?? editorState.selectedDataset.getValue(); graphURI = lockedGraphUri ?? editorState.selectedGraph.getValue(); - if (selectedDatasetName) { - namespaces = await getNamespaces(selectedDatasetName); - } const saved = userSettings.get("defaultExportFormat", null); selectedMediaType = saved ? (supportedMediaTypes.find(m => m.mimeType === saved) ?? @@ -133,15 +126,6 @@ }); } - async function getOntology(datasetName) { - const res = await bec.getOntology(datasetName, graphURI); - let content = await res.text(); - if (!content) { - return content; - } - return JSON.parse(content); - } - // This function is called from the parent component when the user clicks the export button export async function handleExport(getAPIRoute) { if ( @@ -158,19 +142,14 @@ ontology.entries.append(entry); } } - const ontologyRes = await bec.putOntology( + const { error } = await ontologyStore.replaceOntology( selectedDatasetName, graphURI, ontology.getPlainObject(), ); - if (ontologyRes && ontologyRes.ok === false) { - toastStore.error( - "Profile header update failed", - "Could not persist the generated profile header entries; export aborted.", - ); - return; + if (!error) { + forceReloadTrigger.trigger(); } - forceReloadTrigger.trigger(); } try { const response = await fetchGraphFile(getAPIRoute); @@ -280,7 +259,7 @@ bind:value={selectedMediaType} > {#each supportedMediaTypes as mediaType} - + {/each} diff --git a/frontend/src/lib/actions/editingActions.js b/frontend/src/lib/actions/editingActions.js deleted file mode 100644 index 0990b6f0..00000000 --- a/frontend/src/lib/actions/editingActions.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2024-2026 SOPTIM AG - * - * 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 - * - * 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. - * - */ - -/** - * Shared actions for toggling the read-only state of a dataset. - * - * Each function performs the API call, surfaces a success or error toast, - * and returns `true` when the write succeeded. Reactive state updates that - * are local to a call site (refreshing local `readonly` flags, triggering - * editor state, etc.) remain the caller's responsibility. - */ - -import { BackendConnection } from "$lib/api/backend.js"; -import { PUBLIC_BACKEND_URL } from "$lib/config/runtime"; -import { toastStore } from "$lib/eventhandling/toastStore.svelte.js"; - -const bec = new BackendConnection(fetch, PUBLIC_BACKEND_URL); - -/** - * Make the dataset editable. Toasts on success and failure. - * - * @param {string} datasetName - * @returns {Promise} `true` when the dataset is now editable. - */ -export async function enableEditing(datasetName) { - if (!datasetName) return false; - const res = await bec.enableEditing(datasetName); - if (res && res.ok === false) { - toastStore.error( - "Could not enable editing", - `Dataset "${datasetName}" remains read-only.`, - ); - return false; - } - toastStore.success( - "Editing enabled", - `Dataset "${datasetName}" is now editable.`, - ); - return true; -} - -/** - * Mark the dataset read-only. Toasts on success and failure. - * - * @param {string} datasetName - * @returns {Promise} `true` when the dataset is now read-only. - */ -export async function disableEditing(datasetName) { - if (!datasetName) return false; - const res = await bec.disableEditing(datasetName); - if (res && res.ok === false) { - toastStore.error( - "Could not disable editing", - `Dataset "${datasetName}" remains editable.`, - ); - return false; - } - toastStore.success( - "Editing disabled", - `Dataset "${datasetName}" is now read-only.`, - ); - return true; -} diff --git a/frontend/src/lib/actions/versionControlActions.js b/frontend/src/lib/actions/versionControlActions.js deleted file mode 100644 index 71ba7be9..00000000 --- a/frontend/src/lib/actions/versionControlActions.js +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2024-2026 SOPTIM AG - * - * 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 - * - * 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 { PUBLIC_BACKEND_URL } from "$lib/config/runtime"; -import { eventStack } from "$lib/eventhandling/closeEventManager.svelte.js"; -import { toastStore } from "$lib/eventhandling/toastStore.svelte.js"; -import { editorState, forceReloadTrigger } from "$lib/sharedState.svelte.js"; - -function resolveTargets(datasetName, graphURI) { - const dataset = datasetName ?? editorState.selectedDataset.getValue(); - const graph = graphURI ?? editorState.selectedGraph.getValue(); - - if (!dataset || !graph) return null; - - return { - dataset, - graph, - encodedDataset: encodeURIComponent(dataset), - encodedGraph: encodeURIComponent(graph), - }; -} - -export async function fetchCanUndo(datasetName, graphURI) { - const targets = resolveTargets(datasetName, graphURI); - if (!targets) return false; - - const res = await fetch( - `${PUBLIC_BACKEND_URL}/datasets/${targets.encodedDataset}/graphs/${targets.encodedGraph}/canUndo`, - { - method: "POST", - credentials: "include", - }, - ); - - if (res.ok) { - const text = await res.text(); - return text === "true"; - } - - console.log("Failed to fetch canUndo status."); - return false; -} - -export function undo(datasetName, graphURI) { - return eventStack.guardAction(async () => { - const targets = resolveTargets(datasetName, graphURI); - if (!targets) return false; - - const res = await fetch( - `${PUBLIC_BACKEND_URL}/datasets/${targets.encodedDataset}/graphs/${targets.encodedGraph}/undo`, - { - method: "POST", - credentials: "include", - }, - ); - - if (res.ok) { - console.log("Undo successful."); - forceReloadTrigger.trigger(); - toastStore.info("Undone"); - return true; - } else { - console.log("Undo failed."); - toastStore.error("Undo failed", "Could not undo the last change."); - return false; - } - }); -} - -export async function fetchCanRedo(datasetName, graphURI) { - const targets = resolveTargets(datasetName, graphURI); - if (!targets) return false; - - const res = await fetch( - `${PUBLIC_BACKEND_URL}/datasets/${targets.encodedDataset}/graphs/${targets.encodedGraph}/canRedo`, - { - method: "POST", - credentials: "include", - }, - ); - - if (res.ok) { - const text = await res.text(); - return text === "true"; - } - - console.log("Failed to fetch canRedo status."); - return false; -} - -export function redo(datasetName, graphURI) { - return eventStack.guardAction(async () => { - const targets = resolveTargets(datasetName, graphURI); - if (!targets) return false; - - const res = await fetch( - `${PUBLIC_BACKEND_URL}/datasets/${targets.encodedDataset}/graphs/${targets.encodedGraph}/redo`, - { - method: "POST", - credentials: "include", - }, - ); - - if (res.ok) { - console.log("Redo successful."); - forceReloadTrigger.trigger(); - toastStore.info("Redone"); - return true; - } else { - console.log("Redo failed."); - toastStore.error("Redo failed", "Could not redo the change."); - return false; - } - }); -} diff --git a/frontend/src/lib/api/apiDatasetUtils.js b/frontend/src/lib/api/apiDatasetUtils.js deleted file mode 100644 index e2a1aaf9..00000000 --- a/frontend/src/lib/api/apiDatasetUtils.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2024-2026 SOPTIM AG - * - * 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 - * - * 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 { BackendConnection } from "$lib/api/backend.js"; -import { PUBLIC_BACKEND_URL } from "$lib/config/runtime"; - -const bec = new BackendConnection(fetch, PUBLIC_BACKEND_URL); - -export async function isReadOnly(datasetName) { - const res = await bec.isReadOnly(datasetName); - return await res.json(); -} - -export async function getNamespaces(datasetName) { - if (!datasetName) { - return []; - } - const res = await bec.getNamespaces(datasetName); - return await res.json(); -} - -export async function getDatasetNames() { - const res = await bec.getDatasetNames(); - let datasetNames = await res.json(); - let readOnlyDatasets = []; - let modifiableDatasets = []; - - for (const dataset of datasetNames) { - if (await isReadOnly(dataset)) { - readOnlyDatasets.push(dataset); - } else { - modifiableDatasets.push(dataset); - } - } - return { modifiable: modifiableDatasets, readonly: readOnlyDatasets }; -} - -export async function getCrossProfileDiagram(datasetName) { - if (!datasetName) return null; - const res = await bec.getCrossProfileDiagramForDataset(datasetName); - return await res.json(); -} diff --git a/frontend/src/lib/api/backend.js b/frontend/src/lib/api/backend.js deleted file mode 100644 index 69555506..00000000 --- a/frontend/src/lib/api/backend.js +++ /dev/null @@ -1,744 +0,0 @@ -/* - * Copyright (c) 2024-2026 SOPTIM AG - * - * 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 - * - * 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 { PUBLIC_BACKEND_URL } from "$lib/config/runtime"; -import { CGMESVersion } from "$lib/models/cgmes-constants.js"; - -export class BackendConnection { - fetch; - url; - - constructor(fetch, url) { - this.fetch = fetch; - this.url = url; - } - - async fetchFilteredRenderingData(datasetName, graphURI, graphFilter) { - const url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/rendering`; - return fetch(url, { - method: "POST", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(graphFilter), - credentials: "include", - }); - } - - async getDatasetNames() { - const url = `${PUBLIC_BACKEND_URL}/datasets`; - return fetch(url, { - method: "GET", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getCrossProfileID(datasetName) { - const url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/crossprofilediagramID`; - return fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getGraphNames(datasetName) { - const url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs`; - return fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async deleteDataset(datasetName) { - const url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}`; - return fetch(url, { - method: "DELETE", - credentials: "include", - }); - } - - async getClassInfo(datasetName, graphURI, classUUID) { - const url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/classes/${encodeURIComponent(classUUID)}`; - return fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async replaceClass(datasetName, graphURI, classUUID, newClass) { - const url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/classes/${encodeURIComponent(classUUID)}`; - return fetch(url, { - method: "PUT", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(newClass), - credentials: "include", - }); - } - - async postClass(datasetName, graphURI, newClass) { - const url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/classes`; - return fetch(url, { - method: "POST", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(newClass), - credentials: "include", - }); - } - - async getPackages(datasetName, graphURI) { - const url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/packages`; - return fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getPackage(datasetName, graphURI, packageUUID) { - const url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/packages/${encodeURIComponent(packageUUID)}`; - return fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getClasses(datasetName, graphURI, includeExternalClasses = false) { - const url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/classes?includeExternalClasses=${includeExternalClasses}`; - return fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getXSDPrimitives() { - const url = `${PUBLIC_BACKEND_URL}/primitiveDatatypes`; - return fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getPrimitives(datasetName, graphURI) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/primitives`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getDataTypes(datasetName, graphURI) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/datatypes`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getStereotypes(datasetName, graphURI) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/stereotypes`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async putAttribute(datasetName, graphURI, classUUID, attribute) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/classes/${encodeURIComponent(classUUID)}/attributes/${encodeURIComponent(attribute.uuid)}`; - return await fetch(url, { - method: "PUT", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(attribute), - credentials: "include", - }); - } - - async postAttribute(datasetName, graphURI, classUUID, attribute) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/classes/${encodeURIComponent(classUUID)}/attributes`; - return await fetch(url, { - method: "POST", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(attribute), - credentials: "include", - }); - } - - async putAssociationPair( - datasetName, - graphURI, - classUUID, - associationPair, - ) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/classes/${encodeURIComponent(classUUID)}/associations/${encodeURIComponent(associationPair.from.uuid)}`; - return await fetch(url, { - method: "PUT", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(associationPair), - credentials: "include", - }); - } - - async postAssociationPair(datasetName, graphURI, classUUID, association) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/classes/${encodeURIComponent(classUUID)}/associations`; - return await fetch(url, { - method: "POST", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(association), - credentials: "include", - }); - } - - async getDeletionImpact(datasetName, graphURI, resourceUuids) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/deletion-impact`; - return await fetch(url, { - method: "POST", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(resourceUuids), - credentials: "include", - }); - } - - async deleteClass(datasetName, graphURI, classUUID) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/classes/${encodeURIComponent(classUUID)}`; - return await fetch(url, { - method: "DELETE", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async deleteResources(datasetName, graphURI, deleteRequests) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/delete-requests`; - return await fetch(url, { - method: "POST", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(deleteRequests), - credentials: "include", - }); - } - - async postEnumEntry(datasetName, graphURI, classUUID, enumEntry) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/classes/${encodeURIComponent(classUUID)}/enumentries`; - return await fetch(url, { - method: "POST", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(enumEntry), - credentials: "include", - }); - } - - async putEnumEntry(datasetName, graphURI, classUUID, enumEntry) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/classes/${encodeURIComponent(classUUID)}/enumentries/${encodeURIComponent(enumEntry.uuid)}`; - return await fetch(url, { - method: "PUT", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(enumEntry), - credentials: "include", - }); - } - - async getNamespaces(datasetName) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/namespaces`; - return await fetch(url, { - method: "GET", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async replaceNamespaces(datasetName, namespaces) { - const url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/namespaces`; - return fetch(url, { - method: "PUT", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(namespaces), - credentials: "include", - }); - } - - async getSearchResults(query, body) { - let url = `${PUBLIC_BACKEND_URL}/search?query=${encodeURIComponent(query)}`; - return await fetch(url, { - method: "POST", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(body), - credentials: "include", - }); - } - - async validateSchema( - datasetName, - graphURI, - cgmesVersion = CGMESVersion.V3_0, - ) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/validate/${encodeURIComponent(cgmesVersion)}`; - return await fetch(url, { - method: "GET", - mode: "cors", - credentials: "include", - }); - } - - async validateFile(file, cgmesVersion = CGMESVersion.V3_0) { - const url = `${PUBLIC_BACKEND_URL}/validate/${encodeURIComponent(cgmesVersion)}`; - - const formData = new FormData(); - formData.append("file", file); - - return fetch(url, { - method: "POST", - mode: "cors", - body: formData, - credentials: "include", - }); - } - - async compareSchemas(datasetName, graphURI, file) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/compare`; - const formData = new FormData(); - formData.append("file", file); - return await fetch(url, { - method: "POST", - mode: "cors", - body: formData, - credentials: "include", - }); - } - - async compareDatasetSchemas( - datasetName, - graphURI, - otherDatasetName, - otherGraphURI, - ) { - const url = - `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}` + - `/graphs/${encodeURIComponent(graphURI)}/compare` + - `?otherDataset=${encodeURIComponent(otherDatasetName)}` + - `&otherGraph=${encodeURIComponent(otherGraphURI)}`; - - return fetch(url, { - method: "GET", - mode: "cors", - credentials: "include", - }); - } - - async compareSchemasFromFiles(fileA, fileB) { - const url = `${PUBLIC_BACKEND_URL}/compare`; - - const formData = new FormData(); - formData.append("fileA", fileA); - formData.append("fileB", fileB); - - return fetch(url, { - method: "POST", - mode: "cors", - body: formData, - credentials: "include", - }); - } - - async createSnapshot(datasetName) { - let url = `${PUBLIC_BACKEND_URL}/snapshots`; - return await fetch(url, { - method: "POST", - mode: "cors", - body: datasetName, - credentials: "include", - }); - } - - async loadSnapshot(base64Token) { - let url = `${PUBLIC_BACKEND_URL}/snapshots/${encodeURIComponent(base64Token)}`; - return await fetch(url, { - method: "GET", - mode: "cors", - credentials: "include", - }); - } - - async isReadOnly(datasetName) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/readonly`; - return await fetch(url, { - method: "GET", - mode: "cors", - credentials: "include", - }); - } - - async enableEditing(datasetName) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/readonly`; - return await fetch(url, { - method: "PUT", - mode: "cors", - credentials: "include", - }); - } - - async disableEditing(datasetName) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/readonly`; - return await fetch(url, { - method: "DELETE", - mode: "cors", - credentials: "include", - }); - } - - async getChangelog(datasetName, graphURI) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/changes`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async restoreVersion(datasetName, graphURI, version) { - console.log(`Restoring version ${version}`); - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/restore`; - return await fetch(url, { - method: "POST", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: version, - credentials: "include", - }); - } - - async putPackage(datasetName, graphURI, pack) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/packages/${encodeURIComponent(pack.uuid)}`; - return await fetch(url, { - method: "PUT", - headers: new Headers({ "Content-Type": "application/json" }), - mode: "cors", - body: JSON.stringify(pack), - credentials: "include", - }); - } - - async updateClassPositions( - datasetName, - graphURI, - packageUUID, - classPositionDTOList, - ) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/layout/${encodeURIComponent(packageUUID)}/classes`; - return await fetch(url, { - method: "PUT", - headers: new Headers({ "Content-Type": "application/json" }), - mode: "cors", - body: JSON.stringify(classPositionDTOList), - credentials: "include", - }); - } - - async updateGlobalClassPositions( - datasetName, - packageUUID, - classPositionDTOList, - ) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/layout/${encodeURIComponent(packageUUID)}/classes`; - return await fetch(url, { - method: "PUT", - headers: new Headers({ "Content-Type": "application/json" }), - mode: "cors", - body: JSON.stringify(classPositionDTOList), - credentials: "include", - }); - } - - async getKnownOntologyFields() { - let url = `${PUBLIC_BACKEND_URL}/ontology-fields`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getOntology(datasetName, graphURI) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/ontology`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async postOntology(datasetName, graphURI, newOntology) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/ontology`; - return await fetch(url, { - method: "POST", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(newOntology), - credentials: "include", - }); - } - - async putOntology(datasetName, graphURI, newOntology) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/ontology`; - return await fetch(url, { - method: "PUT", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(newOntology), - credentials: "include", - }); - } - - async deleteOntology(datasetName, graphURI) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/ontology`; - return await fetch(url, { - method: "DELETE", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async generateOntologyEntries(datasetName, graphURI) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/ontology/generate`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async postPasteClasses(targetDatasetName, targetGraphURI, pasteRequest) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(targetDatasetName)}/graphs/${encodeURIComponent(targetGraphURI)}/paste`; - return await fetch(url, { - method: "POST", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(pasteRequest), - credentials: "include", - }); - } - - async extendClass(datasetName, graphURI, classUUID, body) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/classes/${encodeURIComponent(classUUID)}/extend`; - return await fetch(url, { - method: "POST", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(body), - credentials: "include", - }); - } - - async getCustomDiagramsForGraph(datasetName, graphURI) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/diagrams`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getCustomDiagramsForDataset(datasetName) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/diagrams`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getCustomGraphDiagramRenderingData(datasetName, graphURI, diagramId) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/diagrams/${encodeURIComponent(diagramId)}`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getCustomDatasetDiagramRenderingData(datasetName, diagramId) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/diagrams/${encodeURIComponent(diagramId)}`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getCrossProfileDiagramRenderingDataForDataset(datasetName) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/crossprofilediagramRendering`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getCrossProfileDiagramForDataset(datasetName) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/crossprofilediagram`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async getCrossProfileColorData(datasetName) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/crossprofilediagramColors`; - return await fetch(url, { - method: "GET", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - credentials: "include", - }); - } - - async putCrossProfileColorData(datasetName, colorData) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/crossprofilediagramColors`; - return await fetch(url, { - method: "PUT", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(colorData), - credentials: "include", - }); - } - - async putCustomDiagram(datasetName, graphURI, diagramId, newDiagram) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/diagrams/${encodeURIComponent(diagramId)}`; - return await fetch(url, { - method: "PUT", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(newDiagram), - credentials: "include", - }); - } - - async putCustomDatasetDiagram(datasetName, diagramId, newDiagram) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/diagrams/${encodeURIComponent(diagramId)}`; - return await fetch(url, { - method: "PUT", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(newDiagram), - credentials: "include", - }); - } - - async addToCustomGraphDiagram(datasetName, graphURI, diagramId, classes) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/diagrams/${encodeURIComponent(diagramId)}/classes`; - return await fetch(url, { - method: "POST", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(classes), - credentials: "include", - }); - } - - async addToCustomDatasetDiagram(datasetName, diagramId, classes) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/diagrams/${encodeURIComponent(diagramId)}/classes`; - return await fetch(url, { - method: "POST", - mode: "cors", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(classes), - credentials: "include", - }); - } - - async removeFromCustomGraphDiagram( - datasetName, - graphURI, - diagramId, - classIds, - ) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphURI)}/diagrams/${encodeURIComponent(diagramId)}/classes`; - return await fetch(url, { - method: "DELETE", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(classIds), - credentials: "include", - }); - } - - async removeFromCustomDatasetDiagram(datasetName, diagramId, classIds) { - let url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/diagrams/${encodeURIComponent(diagramId)}/classes`; - return await fetch(url, { - method: "DELETE", - headers: new Headers({ "Content-Type": "application/json" }), - body: JSON.stringify(classIds), - credentials: "include", - }); - } - - async deleteCustomDatasetDiagram(datasetName, diagramId) { - const url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/diagrams/${encodeURIComponent(diagramId)}`; - return await fetch(url, { - method: "DELETE", - credentials: "include", - }); - } - - async deleteCustomGraphDiagram(datasetName, graphUri, diagramId) { - const url = `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetName)}/graphs/${encodeURIComponent(graphUri)}/diagrams/${encodeURIComponent(diagramId)}`; - return await fetch(url, { - method: "DELETE", - credentials: "include", - }); - } - - async resetSession() { - const url = `${PUBLIC_BACKEND_URL}/session`; - return fetch(url, { - method: "DELETE", - credentials: "include", - }); - } -} diff --git a/frontend/src/lib/api/backendConnectionMonitor.svelte.js b/frontend/src/lib/api/backendConnectionMonitor.svelte.js index ea1387e4..c8a39bb9 100644 --- a/frontend/src/lib/api/backendConnectionMonitor.svelte.js +++ b/frontend/src/lib/api/backendConnectionMonitor.svelte.js @@ -127,7 +127,7 @@ export function installBackendFetchInterceptor() { export async function probeBackendConnection() { if (!PUBLIC_BACKEND_URL || typeof window === "undefined") return; try { - await fetch(`${PUBLIC_BACKEND_URL}/datasets`, { + await fetch(`${PUBLIC_BACKEND_URL}/api/datasets`, { method: "GET", credentials: "include", }); diff --git a/frontend/src/lib/api/hey-api.ts b/frontend/src/lib/api/hey-api.ts new file mode 100644 index 00000000..feafbec6 --- /dev/null +++ b/frontend/src/lib/api/hey-api.ts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024-2026 SOPTIM AG + * + * 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 + * + * 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 { PUBLIC_BACKEND_URL } from "../config/runtime"; +import { CreateClientConfig } from "./generated/client"; + +export const createClientConfig: CreateClientConfig = config => ({ + ...config, + baseUrl: PUBLIC_BACKEND_URL, + credentials: "include", +}); diff --git a/frontend/src/lib/components/DatasetAndGraphSelection.svelte b/frontend/src/lib/components/DatasetAndGraphSelection.svelte index 3ce5dd22..526f1f17 100644 --- a/frontend/src/lib/components/DatasetAndGraphSelection.svelte +++ b/frontend/src/lib/components/DatasetAndGraphSelection.svelte @@ -18,10 +18,9 @@ import { onMount } from "svelte"; import { v4 as uuidv4 } from "uuid"; - import { isReadOnly } from "$lib/api/apiDatasetUtils.js"; - import { BackendConnection } from "$lib/api/backend.js"; import SelectEditControl from "$lib/components/SelectEditControl.svelte"; - import { PUBLIC_BACKEND_URL } from "$lib/config/runtime"; + import { datasetStore } from "$lib/stores/DatasetStore.ts"; + import { graphStore } from "$lib/stores/GraphStore.ts"; let { dataset = $bindable(), @@ -32,12 +31,9 @@ displayAsCard = true, } = $props(); - const bec = new BackendConnection(fetch, PUBLIC_BACKEND_URL); - const datasetSelectId = `datasetSelect-${uuidv4()}`; const graphSelectId = `graphSelect-${uuidv4()}`; - let datasets = $state([]); let graphNames = $state([]); const datasetLocked = $derived(lockedDatasetName !== undefined); @@ -45,69 +41,46 @@ const graphSelectDisabled = $derived(graphLocked || !dataset); - $effect(() => { + $effect(async () => { if (datasetLocked) return; if (!dataset) { graph = graphLocked ? lockedGraphUri : null; graphNames = []; return; } - loadGraphsFor(dataset); + + await graphStore.load(dataset); + graphNames = graphStore.getGraphs(dataset); + const valid = graphNames.some(graphName => getUri(graphName) === graph); + if (!valid && !graphLocked) { + graph = null; + } }); onMount(async () => { + await datasetStore.load(); if (datasetLocked) dataset = lockedDatasetName; if (graphLocked) graph = lockedGraphUri; - await loadDatasets(); - if (dataset) { - await loadGraphsFor(dataset); - } else { - graphNames = []; - } - }); - - function getUri(graph) { - return (!graph.prefix ? "" : graph.prefix) + graph.suffix; - } - - async function loadDatasets() { - const res = await bec.getDatasetNames(); - const datasetNames = await res.json(); - const newDatasets = datasetNames.map(name => ({ - label: name, - readonly: false, - })); - if (!allowSelectionOfReadonlyDatasets) { - for (const dataset of newDatasets) { - dataset.readonly = await isReadOnly(dataset.label); - } - } - datasets = newDatasets; - if (!datasetLocked && dataset && !allowSelectionOfReadonlyDatasets) { - const selectedDataset = newDatasets.find( + const selectedDataset = $datasetStore.data.find( option => option.label === dataset, ); - if (!selectedDataset || selectedDataset.readonly) { + if (!selectedDataset || selectedDataset.readOnly) { dataset = null; } } - } - async function loadGraphsFor(dataset) { - if (!dataset) { + if (dataset) { + await graphStore.load(dataset); + graphNames = graphStore.getGraphs(dataset); + } else { graphNames = []; - return; } + }); - const res = await bec.getGraphNames(dataset); - graphNames = await res.json(); - - const valid = graphNames.some(graphName => getUri(graphName) === graph); - if (!valid && !graphLocked) { - graph = null; - } + function getUri(graph) { + return (!graph.prefix ? "" : graph.prefix) + graph.suffix; } @@ -120,13 +93,13 @@ - !allowSelectionOfReadonlyDatasets && dataset.readonly} + !allowSelectionOfReadonlyDatasets && dataset.readOnly} getOptionValue={dataset => dataset.label} getOptionLabel={dataset => - dataset.label + (dataset.readonly ? " (readonly)" : "")} - disabled={datasetLocked || datasets.length === 0} + dataset.label + (dataset.readOnly ? " (readonly)" : "")} + disabled={datasetLocked || ($datasetStore.data?.length ?? 0) === 0} placeholder="Select dataset" onchange={() => (graph = null)} /> diff --git a/frontend/src/lib/models/reactive/validity-rules/validityFunctions.js b/frontend/src/lib/models/reactive/validity-rules/validityFunctions.js index 43c15565..f3e6fd73 100644 --- a/frontend/src/lib/models/reactive/validity-rules/validityFunctions.js +++ b/frontend/src/lib/models/reactive/validity-rules/validityFunctions.js @@ -84,7 +84,7 @@ export function isValidDiagramName(diagramName, compareDiagrams) { violations.push("must not be empty"); } - if (compareDiagrams?.some(d => d.name === diagramName)) { + if (compareDiagrams?.some(d => d.label === diagramName)) { violations.push("must be unique"); } @@ -101,12 +101,12 @@ export function isInvalidAssociationLabel(association, associations) { : (associations?.values ?? []); if (violations.length === 0) { if ( - assocList.filter( + assocList.some( a => a.label.value === association?.label?.value && a.namespace.value === association.namespace?.value && a !== association, - ).length > 0 + ) ) { violations.push("must be unique"); } else if ( @@ -136,12 +136,12 @@ export function isInvalidInverseAssociationLabel(association, getClassByUuid) { const assocList = targetClassDto?.associationPairs?.map(pair => pair) ?? []; if (violations.length === 0) { if ( - assocList.filter( + assocList.some( a => a.from.label === association?.inverse?.label?.value && a.from.prefix === association.inverse?.namespace?.value && a.from.uuid !== association.inverse?.uuid?.value, - ).length > 0 + ) ) { violations.push("must be unique"); } else if ( diff --git a/frontend/src/lib/rendering/svelteflow/components/SvelteFlowPaneContextMenu.svelte b/frontend/src/lib/rendering/svelteflow/components/SvelteFlowPaneContextMenu.svelte index 95c29518..d93e1fbe 100644 --- a/frontend/src/lib/rendering/svelteflow/components/SvelteFlowPaneContextMenu.svelte +++ b/frontend/src/lib/rendering/svelteflow/components/SvelteFlowPaneContextMenu.svelte @@ -18,14 +18,13 @@ diff --git a/frontend/src/routes/ImportDialog.svelte b/frontend/src/routes/ImportDialog.svelte index 51a0c7c7..33bb47e2 100644 --- a/frontend/src/routes/ImportDialog.svelte +++ b/frontend/src/routes/ImportDialog.svelte @@ -20,11 +20,10 @@ import { Fa } from "svelte-fa"; import { v4 as uuidv4 } from "uuid"; - import { getDatasetNames } from "$lib/api/apiDatasetUtils.js"; import ButtonControl from "$lib/components/ButtonControl.svelte"; - import { PUBLIC_BACKEND_URL } from "$lib/config/runtime"; import ActionDialog from "$lib/dialog/ActionDialog.svelte"; - import { toastStore } from "$lib/eventhandling/toastStore.svelte.js"; + import { datasetStore } from "$lib/stores/DatasetStore.ts"; + import { graphStore } from "$lib/stores/GraphStore.ts"; import { supportedRDFMediaTypes } from "$lib/utils/fileUtils"; import { @@ -65,14 +64,20 @@ datasetNameUserInput = lockedDatasetName ?? editorState.selectedDataset.getValue(); - const datasetNames = await getDatasetNames(); - modifiableDatasets = datasetNames.modifiable; - readOnlyDatasets = datasetNames.readonly; + await datasetStore.load(); + for (const dataset of $datasetStore.data) { + if (dataset.readOnly) { + readOnlyDatasets.push(dataset.label); + } else { + modifiableDatasets.push(dataset.label); + } + } } function onClose() { clearInputs(); } + function clearInputs() { datasetNameUserInput = ""; files = []; @@ -178,124 +183,30 @@ return datasetNameUserInput || DEFAULT_DATASET_NAME; } - function buildRequestBody(files) { - let formData = new FormData(); - files.forEach(fileEntry => { - formData.append("files", fileEntry.file); - formData.append( - "graphUris", - fileEntry.isZip - ? "" - : ensureGraphNamespaceUri( - fileEntry.graphUri, - fileEntry.file.name, - ), - ); - }); - return formData; - } - - function putFiles(files, datasetname) { - return fetch( - `${PUBLIC_BACKEND_URL}/datasets/${encodeURIComponent(datasetname)}/graphs/content`, - { - method: "PUT", - body: buildRequestBody(files), - credentials: "include", - }, - ); - } - async function parseResponse(response, datasetName) { - if (!response.ok) { - console.log("failed to insert data"); - toastStore.error( - "Import failed", - `Could not import into "${datasetName}".`, - ); - return; - } - - const body = await response.json(); - console.log(body.message); - - const failedImports = body.failedImports ?? []; - if (failedImports.length > 0) { - console.warn("failed imports:", failedImports); - } - - //only update the selected dataset and graph if at least one import was successful, otherwise keep the old selection - const importedGraphUris = body.importedGraphUris ?? []; - if (importedGraphUris.length === 0) { - toastStore.error( - "Import failed", - failedImports.length > 0 - ? `${failedImports.length} file(s) could not be imported.` - : "No graphs were imported.", - ); - return; - } - console.log("imported graphs:", importedGraphUris); - - editorState.selectedDataset.updateValue(datasetName); - editorState.selectedGraph.updateValue(importedGraphUris[0]); - editorState.selectedDiagram.updateValue({ type: null, id: null }); - editorState.selectedClassDataset.updateValue(null); - editorState.selectedClassGraph.updateValue(null); - editorState.selectedClass.updateValue({ type: null, id: null }); - - const importedCount = importedGraphUris.length; - const summary = `${importedCount} graph${importedCount === 1 ? "" : "s"} imported into "${datasetName}".`; - if (failedImports.length > 0) { - toastStore.warning( - "Import partially succeeded", - `${summary} ${failedImports.length} file(s) were skipped.`, - ); - } else { - toastStore.success("Import complete", summary); - } - - notifyUndisplayableProperties(body.warnings ?? []); - } - - function notifyUndisplayableProperties(warnings) { - if (warnings.length === 0) { - return; - } - const total = warnings.reduce( - (sum, warning) => - sum + (warning.undisplayableProperties?.length ?? 0), - 0, - ); - const details = warnings - .map( - warning => - `${warning.fileName}: ${(warning.undisplayableProperties ?? []).join(", ")}`, - ) - .join("; "); - toastStore.warning( - "Some properties could not be displayed", - `${total} propert${total === 1 ? "y" : "ies"} ${total === 1 ? "is" : "are"} missing the CIM stereotype or association metadata RDFArchitect needs to show ${total === 1 ? "it" : "them"} (${details}).`, - ); - } - async function importGraphs() { const datasetNameUserInputLocal = getUserInputDatasetName(); - const filesLocal = files; - console.warn( - "Importing files into dataset:", + const filesLocal = files.map(entry => entry.file); + const graphUrisLocal = files.map(entry => + entry.isZip + ? "" + : ensureGraphNamespaceUri(entry.graphUri, entry.file.name), + ); + const { data, error } = await graphStore.importGraphs( datasetNameUserInputLocal, + filesLocal, + graphUrisLocal, ); - try { - const res = await putFiles(filesLocal, datasetNameUserInputLocal); - await parseResponse(res, datasetNameUserInputLocal); - } catch (e) { - console.log("failed to insert data:"); - console.log(e); - toastStore.error( - "Import failed", - "An unexpected error occurred while importing.", + + if (!error && data.importedGraphUris?.length > 0) { + editorState.selectedDataset.updateValue(datasetNameUserInputLocal); + editorState.selectedGraph.updateValue( + data.importedGraphUris[0] || null, ); - } finally { + editorState.selectedDiagram.updateValue({ type: null, id: null }); + editorState.selectedClassDataset.updateValue(null); + editorState.selectedClassGraph.updateValue(null); + editorState.selectedClass.updateValue({ type: null, id: null }); + datasetStore.invalidate(); forceReloadTrigger.trigger(); } } diff --git a/frontend/src/routes/NamespacesDialog.svelte b/frontend/src/routes/NamespacesDialog.svelte index bd545c15..21ad1d27 100644 --- a/frontend/src/routes/NamespacesDialog.svelte +++ b/frontend/src/routes/NamespacesDialog.svelte @@ -18,16 +18,12 @@ import { tick } from "svelte"; import { Fa } from "svelte-fa"; - import { getNamespaces } from "$lib/api/apiDatasetUtils.js"; - import { BackendConnection } from "$lib/api/backend.js"; import ButtonControl from "$lib/components/ButtonControl.svelte"; import FaIconButton from "$lib/components/FaIconButton.svelte"; import List from "$lib/components/List.svelte"; import TextEditControl from "$lib/components/TextEditControl.svelte"; import ViolationMessages from "$lib/components/ViolationMessages.svelte"; - import { PUBLIC_BACKEND_URL } from "$lib/config/runtime"; import ModifyDataDialog from "$lib/dialog/ModifyDataDialog.svelte"; - import { toastStore } from "$lib/eventhandling/toastStore.svelte.js"; import { mapNamespaceDtoToReactiveNamespace } from "$lib/models/reactive/mapper/map-dto-to-reactive-object.js"; import { mapReactiveNamespaceToNamespaceDto } from "$lib/models/reactive/mapper/map-reactive-object-to-dto.js"; import { ReactiveNamespace } from "$lib/models/reactive/models/reactive-namespace.svelte.js"; @@ -38,11 +34,10 @@ editorState, forceReloadTrigger, } from "$lib/sharedState.svelte.js"; + import { datasetStore } from "$lib/stores/DatasetStore.ts"; let { showDialog = $bindable() } = $props(); - const bec = new BackendConnection(fetch, PUBLIC_BACKEND_URL); - let datasetName = $state(""); let readonly = $state(false); let namespaces = $state([]); @@ -52,12 +47,12 @@ async function onOpen() { datasetName = editorState.selectedDataset.getValue(); if (!datasetName) return; - readonly = await isReadOnly(datasetName); + readonly = datasetStore.isReadOnly(datasetName); await loadNamespaces(datasetName); } async function loadNamespaces(datasetNameLocal) { - const namespaceDTOs = await getNamespaces(datasetNameLocal); + const namespaceDTOs = datasetStore.getNamespaces(datasetNameLocal); const objectsForReactiveNamespaces = namespaceDTOs.map(namespaceDto => { return mapNamespaceDtoToReactiveNamespace(namespaceDto); }); @@ -72,11 +67,6 @@ ); } - async function isReadOnly(datasetNameLocal) { - const res = await bec.isReadOnly(datasetNameLocal); - return await res.json(); - } - async function saveNamespaces() { // Colon normalization: add trailing ":" if missing namespaces.values.forEach(namespace => { @@ -92,26 +82,12 @@ const namespaceDTOs = plainReactiveNamespaces.map(namespace => { return mapReactiveNamespaceToNamespaceDto(namespace); }); - try { - const res = await bec.replaceNamespaces(datasetName, namespaceDTOs); - if (res && res.ok === false) { - toastStore.error( - "Save failed", - `Could not save namespaces for "${datasetName}".`, - ); - return; - } - toastStore.success( - "Namespaces saved", - `Updated for "${datasetName}".`, - ); - } catch (err) { - console.error("Failed to save namespaces:", err); - toastStore.error( - "Save failed", - "An unexpected error occurred while saving namespaces.", - ); - } finally { + const { error } = await datasetStore.saveNamespaces( + datasetName, + namespaceDTOs, + ); + + if (!error) { forceReloadTrigger.trigger(); } } diff --git a/frontend/src/routes/NewClassDialog.svelte b/frontend/src/routes/NewClassDialog.svelte index 5d94b7ad..679461de 100644 --- a/frontend/src/routes/NewClassDialog.svelte +++ b/frontend/src/routes/NewClassDialog.svelte @@ -19,16 +19,16 @@ import { untrack } from "svelte"; import { v4 as uuidv4 } from "uuid"; - import { BackendConnection } from "$lib/api/backend.js"; import DatasetAndGraphSelection from "$lib/components/DatasetAndGraphSelection.svelte"; import SelectEditControl from "$lib/components/SelectEditControl.svelte"; import TextEditControl from "$lib/components/TextEditControl.svelte"; import ViolationMessages from "$lib/components/ViolationMessages.svelte"; - import { PUBLIC_BACKEND_URL } from "$lib/config/runtime"; import ActionDialog from "$lib/dialog/ActionDialog.svelte"; - import { toastStore } from "$lib/eventhandling/toastStore.svelte.js"; import { ReactiveValueWrapper } from "$lib/models/reactive/reactive-wrappers/reactive-value-wrapper.svelte.js"; import { isInvalidClassLabel } from "$lib/models/reactive/validity-rules/validityFunctions.js"; + import { classStore } from "$lib/stores/ClassStore.ts"; + import { datasetStore } from "$lib/stores/DatasetStore.ts"; + import { packageStore } from "$lib/stores/PackageStore.ts"; import { getPackageDisplayLabel } from "$lib/utils/package-label.js"; import { @@ -56,7 +56,6 @@ classURINamespace: "classURINamespaceNewClass" + uuid, className: "classNameNewClass" + uuid, }; - const bec = new BackendConnection(fetch, PUBLIC_BACKEND_URL); const DEFAULT_PACKAGE = Object.freeze({ uuid: null, @@ -96,7 +95,7 @@ }); async function onDatasetOrGraphChanged(ds, graph) { - namespaces = await fetchNamespaces(ds); + namespaces = await datasetStore.getNamespaces(ds); if (classURINamespace) classURINamespace.value = null; classPackage = null; @@ -141,14 +140,10 @@ isInvalidClassLabel(label, classURINamespace, compareClasses), ); - if (!datasetName) { - return; - } - namespaces = await fetchNamespaces(datasetName); - - if (!graphURI) { + if (!datasetName || !graphURI) { return; } + namespaces = datasetStore.getNamespaces(datasetName); await getPackages(datasetName, graphURI); compareClasses = await getClasses(datasetName, graphURI); @@ -183,25 +178,15 @@ classPackage = null; } - async function fetchNamespaces(datasetName) { - if (!datasetName) { - return []; - } - const res = await bec.getNamespaces(datasetName); - return await res.json(); - } - async function getPackages(datasetName, graphURI) { if (!datasetName || !graphURI) { packages = []; return; } - const res = await bec.getPackages(datasetName, graphURI); - const packagesJSON = await res.json(); - packages = [ - ...packagesJSON.internalPackageList, - ...packagesJSON.externalPackageList, - ]; + + await packageStore.load(datasetName, graphURI); + const result = await packageStore.getPackages(datasetName, graphURI); + packages = [...result.internal, ...result.external]; } function snapshotFormState() { @@ -225,7 +210,11 @@ requestBody.classLayoutPosition = classLayoutPosition; } - return bec.postClass(form.datasetName, form.graphURI, requestBody); + return classStore.addClass( + form.datasetName, + form.graphURI, + requestBody, + ); } function updateEditorSelection(form, classUUID) { @@ -244,7 +233,6 @@ } function handleClassCreated(form, classUUID) { - console.log("successfully added class"); onClassCreated({ classUUID, datasetName: form.datasetName, @@ -253,37 +241,17 @@ className: form.className, }); updateEditorSelection(form, classUUID); - toastStore.success("Class created", `"${form.className}" was added.`); - } - - function triggerEditorRefresh() { - forceReloadTrigger.trigger(); } async function newClass() { const form = snapshotFormState(); - try { - const res = await postNewClass(form); - if (res.ok) { - const classUUID = await res.text(); - handleClassCreated(form, classUUID); - } else { - console.log("failed to insert data"); - toastStore.error( - "Create failed", - `Could not create class "${form.className}".`, - ); - } - } catch (e) { - console.log("failed to add class:", e); - toastStore.error( - "Create failed", - "An unexpected error occurred while creating the class.", - ); - } finally { - triggerEditorRefresh(); + const { data, error } = await postNewClass(form); + if (!error) { + const classUUID = data; + handleClassCreated(form, classUUID); } + forceReloadTrigger.trigger(); } diff --git a/frontend/src/routes/NewGraphDialog.svelte b/frontend/src/routes/NewGraphDialog.svelte index 6c9512de..ded38dfa 100644 --- a/frontend/src/routes/NewGraphDialog.svelte +++ b/frontend/src/routes/NewGraphDialog.svelte @@ -18,12 +18,10 @@ diff --git a/frontend/src/routes/NewPackageDialog.svelte b/frontend/src/routes/NewPackageDialog.svelte index ac10c4a2..f568090f 100644 --- a/frontend/src/routes/NewPackageDialog.svelte +++ b/frontend/src/routes/NewPackageDialog.svelte @@ -16,18 +16,17 @@ --> diff --git a/frontend/src/routes/ResetSessionDialog.svelte b/frontend/src/routes/ResetSessionDialog.svelte index 7b1a1f27..c6239df9 100644 --- a/frontend/src/routes/ResetSessionDialog.svelte +++ b/frontend/src/routes/ResetSessionDialog.svelte @@ -16,19 +16,15 @@ --> diff --git a/frontend/src/routes/changelog/ChangesRow.svelte b/frontend/src/routes/changelog/ChangesRow.svelte index 39633ee2..54fb087e 100644 --- a/frontend/src/routes/changelog/ChangesRow.svelte +++ b/frontend/src/routes/changelog/ChangesRow.svelte @@ -18,9 +18,8 @@ import { faCaretDown, faCaretUp } from "@fortawesome/free-solid-svg-icons"; import { Fa } from "svelte-fa"; - import { BackendConnection } from "$lib/api/backend.js"; + import { restoreVersion } from "$lib/api/generated/index.ts"; import ButtonControl from "$lib/components/ButtonControl.svelte"; - import { PUBLIC_BACKEND_URL } from "$lib/config/runtime"; import { toastStore } from "$lib/eventhandling/toastStore.svelte.js"; import { editorState, @@ -37,20 +36,19 @@ readonly, } = $props(); - const bec = new BackendConnection(fetch, PUBLIC_BACKEND_URL); - const rowKey = $derived(`${change.changeId}::row`); - async function restoreVersion(changeId) { + async function callRestoreVersion(changeId) { console.log("restoreVersion", changeId); - const res = await bec.restoreVersion( - editorState.selectedDataset.getValue(), - editorState.selectedGraph.getValue(), - changeId, - ); - - if (res.ok) { + const { error } = await restoreVersion({ + path: { + datasetName: editorState.selectedDataset.getValue(), + graphURI: editorState.selectedGraph.getValue(), + }, + query: { changeId: changeId }, + }); + if (!error) { console.log("Version restored successfully"); forceReloadTrigger.trigger(); toastStore.success( @@ -58,7 +56,7 @@ "The selected version has been restored.", ); } else { - console.error("Failed to restore version:", res.statusText); + console.error("Failed to restore version:", error); toastStore.error( "Restore failed", "Could not restore the selected version.", @@ -135,7 +133,7 @@ restoreVersion(change.changeId)} + callOnClick={() => callRestoreVersion(change.changeId)} > Restore Version diff --git a/frontend/src/routes/changelog/Navigation.svelte b/frontend/src/routes/changelog/Navigation.svelte index 51f859d2..aef4a75e 100644 --- a/frontend/src/routes/changelog/Navigation.svelte +++ b/frontend/src/routes/changelog/Navigation.svelte @@ -20,17 +20,16 @@ faDiagramProject, } from "@fortawesome/free-solid-svg-icons"; - import { BackendConnection } from "$lib/api/backend.js"; import NavigationEntry from "$lib/components/navigation/NavigationEntry.svelte"; - import { PUBLIC_BACKEND_URL } from "$lib/config/runtime"; import { forceReloadTrigger, editorState, } from "$lib/sharedState.svelte.js"; + import { datasetStore } from "$lib/stores/DatasetStore.ts"; + import { graphStore } from "$lib/stores/GraphStore.ts"; import { getUri } from "../mainpage/packageNavigation/packageNavigationUtils.svelte.js"; - const bec = new BackendConnection(fetch, PUBLIC_BACKEND_URL); let datasetList = $state([]); let selectedDatasetName = $derived(editorState.selectedDataset.getValue()); let selectedGraphUri = $derived(editorState.selectedGraph.getValue()); @@ -41,9 +40,10 @@ }); async function fetchNavigationObject() { - const datasetNames = await getDatasetNames(); + await datasetStore.load(); const newDatasetList = []; - for (const datasetName of datasetNames) { + for (const dataset of $datasetStore.data) { + const datasetName = dataset.label; let showDatasetContents = datasetName === selectedDatasetName; showDatasetContents |= datasetList.find( datasetObject => datasetObject.label === datasetName, @@ -53,23 +53,15 @@ graphs: [], showContents: showDatasetContents, }); - const graphUris = await getGraphUris(datasetName); - graphUris.forEach(graphUri => - newDatasetList.at(-1).graphs.push(graphUri), - ); + await graphStore.load(datasetName); + graphStore + .getGraphs(datasetName) + .forEach(graphUri => + newDatasetList.at(-1).graphs.push(graphUri), + ); } datasetList = newDatasetList; } - - async function getDatasetNames() { - const res = await bec.getDatasetNames(); - return await res.json(); - } - - async function getGraphUris(datasetName) { - const res = await bec.getGraphNames(datasetName); - return await res.json(); - }