Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: E2E Tests

on:
push:
branches: [main]
branches: [develop]
pull_request:
branches: [main]
branches: [develop]

jobs:
e2e:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/github-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
env:
USE_META_CONFIGURATOR_BASE_PATH: true # Set to true for GitHub Pages deployment
VITE_FRONTEND_HOSTNAME: https://metaconfigurator.github.io/meta-configurator
EXPERIMENTAL: true
run: |
cd meta_configurator
npm ci
Expand Down
28 changes: 28 additions & 0 deletions .github/workflows/tag-version.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Tag Version
on:
push:
branches:
- main
- develop
permissions:
contents: write
jobs:
tag-version:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Create tag if version is new
run: |
VERSION=$(node -p "require('./meta_configurator/package.json').version")
TAG="v$VERSION"
if git rev-parse "$TAG" >/dev/null 2>&1; then
echo "Tag $TAG already exists, skipping."
else
git tag "$TAG"
git push origin "$TAG"
echo "Created and pushed tag $TAG."
fi
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

---

## [2.3.0] - 2026-04-14

### Changed

- Remove prototypical STML mapping in favor of more powerful Jsonata
- Refactor the code base to use a newly implemented JSON Schema visitor pattern instead of having schema traversal logic implemented in different places

### Fixed

- Fix schema diagram: it now correctly draws multiple edges if a sub-schema defines its own structure and additionally has a reference

## [2.2.0] - 2026-03-27

### Added

- Add word-wrap for text editor
- Add `experimental` tag in the About page for the experimental deployment
- Add workflow to automatically generate a git tag when a PR is merged into `main` or `develop` with an incremented version in the package.json

### Changed

- Update multiple dependencies (picomatch, handlebars, yaml)

## [2.1.0] - 2026-03-25

Initial versioned release. Introduces semantic versioning, a structured branching model (`develop` / `main`), and contribution guidelines.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ pages = {1--9}

MetaConfigurator runs entirely **inside your browser** - it does **not** send your schemas, data, or anything you type to any server. The website itself is just a static page delivered by GitHub Pages (like downloading a PDF or image), and all the work happens locally on your computer.

The only exception is if you **click the “Share Snapshot” button**. Then, and only then, the snapshot you create is sent to a **University of Stuttgart** server so you can share a unique link with others.
The exception is if you **click the “Share Snapshot” button**. Then, and only then, the snapshot you create is sent to a **University of Stuttgart** server so you can share a unique link with others.

Additionally, if you use the optional AI assistance functionality, relevant subsets of your schema and data are shared with the AI endpoint you configure in the MetaConfigurator settings (by default OpenAI). This will not accidentally happen, as an authentification key from the AI endpoint provider is needed to use the AI assistance features.

**See our [full Privacy Policy](PRIVACY.md)** for more information.

Expand Down
1 change: 1 addition & 0 deletions meta_configurator/env.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/// <reference types="vite/client" />

declare const __APP_VERSION__: string;
declare const __APP_EXPERIMENTAL__: boolean;
49 changes: 28 additions & 21 deletions meta_configurator/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions meta_configurator/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "meta-configurator",
"version": "2.1.0",
"version": "2.3.0",
"private": true,
"scripts": {
"dev": "vite",
Expand Down Expand Up @@ -42,7 +42,7 @@
"dagrejs": "^0.2.1",
"fast-xml-parser": "^5.0.8",
"flowbite": "^1.6.5",
"handlebars": "^4.7.8",
"handlebars": "^4.7.9",
"js-yaml": "^4.1.0",
"json-cst": "^1.2.0",
"json-pointer": "^0.6.2",
Expand All @@ -62,7 +62,7 @@
"vue": "^3.5.13",
"vue-flow": "^0.3.0",
"vue-router": "^4.3.2",
"yaml": "^2.3.1"
"yaml": "^2.8.3"
},
"devDependencies": {
"@ls-lint/ls-lint": "^2.2.3",
Expand Down
25 changes: 12 additions & 13 deletions meta_configurator/src/components/panels/ai-prompts/ApiKey.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ Component for displaying the OpenAI API key input.
import {type Ref, ref} from 'vue';
import Password from 'primevue/password';
import SelectButton from 'primevue/selectbutton';
import {getApiKeyRef, getIsPersistKeyRef} from '@/utility/ai/apiKey';

const isShowPersistOption = false; // currently the option of whether to persist the key is not shown because without persistence the key currently can not be accessed
import {getApiKeyRef, getRememberInTabRef} from '@/utility/ai/apiKey';

const apiKey: Ref<string> = getApiKeyRef();
const isPersistKey: Ref<boolean> = getIsPersistKeyRef();
const rememberInTab: Ref<boolean> = getRememberInTabRef();

const persistOptions = ref([
{name: 'true', value: true},
{name: 'false', value: false},
const rememberOptions = ref([
{name: 'Remember in this tab', value: true},
{name: 'Forget on refresh', value: false},
]);
</script>

Expand All @@ -28,17 +26,18 @@ const persistOptions = ref([
possible without permanently connecting your credit card with your account. Check this
<a href="https://platform.openai.com/docs/pricing" target="_blank">link</a> for pricing.
<br />
<br />
MetaConfigurator by default uses the gpt-4o-mini model, which has very low cost. For improved
results you can change to more performant models in the settings tab.
<br />
<br />
Your key is stored only in your browser and sent directly to your chosen provider. It is never
sent to MetaConfigurator servers.
<span class="api-key-container">
<span>Key:</span>
<Password v-model="apiKey" placeholder="Enter your OpenAI API Key" :feedback="false" />
<span v-show="isShowPersistOption">Persist:</span>
<Password v-model="apiKey" placeholder="Enter your API Key" :feedback="false" />
<SelectButton
v-show="isShowPersistOption"
v-model="isPersistKey"
:options="persistOptions"
v-model="rememberInTab"
:options="rememberOptions"
option-label="name"
option-value="value" />
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,4 @@ function hasMoreOpeningBrackets(input: string): boolean {
return openingCount > closingCount;
}

export function getApiKey(): string {
return localStorage.getItem('openai_api_key') || '';
}
export {getApiKey} from '@/utility/ai/apiKey';
12 changes: 12 additions & 0 deletions meta_configurator/src/components/panels/code-editor/AceEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ let editor: Ref<Editor | undefined> = ref(undefined);

onMounted(() => {
editor.value = ace.edit(editor_id);

editor.value.getSession().setUseWrapMode(true);
editor.value.setOption('wrap', true);
editor.value.setOption('hScrollBarAlwaysVisible', false);

setupAceMode(editor.value, settings.value);
setupAceProperties(editor.value, settings.value);

Expand All @@ -45,6 +50,13 @@ onMounted(() => {
if (isEditorReadOnly()) {
editor.value.setReadOnly(true);
}

// watch for changes in the editor container size and resize the editor accordingly
const observer = new ResizeObserver(() => {
editor.value?.resize();
});
const el = document.getElementById(editor_id);
if (el) observer.observe(el);
});

// watch for changes in the data format and update the editor accordingly
Expand Down
16 changes: 13 additions & 3 deletions meta_configurator/src/components/toolbar/dialogs/AboutDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
Dialog that shows information about the application and the licenses of the used icons.
Emits an update:visible event when the dialog is closed.
-->
<script setup lang="ts">
<script setup lang="ts" xmlns="http://www.w3.org/1999/html">
import Dialog from 'primevue/dialog';
import Tag from 'primevue/tag';
import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome';

defineProps<{visible: boolean}>();
Expand All @@ -13,6 +14,7 @@ defineEmits<{
}>();

const appVersion = __APP_VERSION__;
const isExperimental = __APP_EXPERIMENTAL__;
</script>

<template>
Expand All @@ -26,7 +28,6 @@ const appVersion = __APP_VERSION__;
</p>
<p>It is currently in alpha stage, so expect bugs and missing features.</p>
<p>MetaConfigurator is open source and licensed under the MIT license.</p>
<p class="text-sm text-gray-500">Version {{ appVersion }}</p>
<p>
Check our
<a
Expand All @@ -39,6 +40,11 @@ const appVersion = __APP_VERSION__;
for more information
</p>
<hr class="my-2" />
<p class="text-sm text-gray-500">
Version {{ appVersion }}
<Tag v-if="isExperimental" severity="warn" value="Experimental" class="ml-2 tag" />
</p>
<hr class="my-2" />
<p>Felix Neubauer, Paul Bredl, Minye Xu, Keyuriben Patel, Jürgen Pleiss, Benjamin Uekermann</p>
<p>Institute for Visualization and Interactive Systems, University of Stuttgart</p>
<p>Universitätsstrasse 38D, 70569 Stuttgart, Germany</p>
Expand Down Expand Up @@ -67,4 +73,8 @@ const appVersion = __APP_VERSION__;
</Dialog>
</template>

<style scoped></style>
<style scoped>
.tag {
background-color: var(--p-primary-color);
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import Message from 'primevue/message';
import ApiKey from '@/components/panels/ai-prompts/ApiKey.vue';
import {SessionMode} from '@/store/sessionMode';
import {getDataForMode} from '@/data/useDataLink';
import {DataMappingServiceStml} from '@/data-mapping/stml/dataMappingServiceStml';
import {DataMappingServiceJsonata} from '@/data-mapping/jsonata/dataMappingServiceJsonata';
import type {DataMappingService} from '@/data-mapping/dataMappingService';
import type {Editor} from 'brace';
Expand All @@ -35,19 +34,15 @@ const isLoadingMapping = ref(false);

const settings = useSettings();

const mappingServiceTypes = ['Advanced (JSONata)', 'SimpleTransformationMappingLanguage (STML)'];
const mappingServiceTypes = ['Advanced (JSONata)'];

const mappingServiceWarnings = [
'The JSONata mapping service is very expressive flexible, but may generate invalid mappings for complex inputs, which have to manually be corrected.',
'The STML mapping service usually generates valid mappings, but it can perform only simple source to target path mappings and value transformations. WARNING: It supports executing arbitrary JavaScript functions as transformations, which may lead to security issues if the input is not properly sanitized.',
];

const selectedMappingServiceType: Ref<string> = ref(mappingServiceTypes[0]);

const mappingService: Ref<DataMappingService> = computed(() => {
if (selectedMappingServiceType.value === 'SimpleTransformationMappingLanguage (STML)') {
return new DataMappingServiceStml();
}
if (selectedMappingServiceType.value === 'Advanced (JSONata)') {
return new DataMappingServiceJsonata();
}
Expand Down
Loading
Loading