Repository files navigation

Visual Mapper

GitHub release (latest by date)LanguageFrameworkNode.js

Visual Mapper is a Vue 3 + TypeScript front-end for enriching OpenAPI or AsyncAPI definitions with x-apigen-* metadata, mapping API resources to relational database structures, and exporting the resulting specification back to a parent application or to downstream code-generation services.

What the application does

Visual Mapper helps you:

  • import an OpenAPI definition (.yaml, .yml, .json) or an AsyncAPI definition (.yaml, .yml)
  • connect to an existing database and inspect tables
  • create a temporary database from a SQL file
  • derive entities, controllers, relations, and validations from the connected schema
  • enrich the API definition with x-apigen-* extensions
  • preview or download the enriched OpenAPI / AsyncAPI document
  • optionally trigger archetype/code generation through configured Apigen backends
  • run embedded inside an iframe and exchange data with a parent application through window.postMessage

Tech stack

AreaDetails
FrameworkVue 3
LanguageTypeScript
StateVuex
RoutingVue Router
UIBootstrap 5 + bootstrap-vue-3
i18nvue-i18n
HTTPAxios
Build toolingVue CLI 5 / Webpack
TestingMocha + Chai via vue-cli-service test:unit

Requirements

  • Node.js >= 24.13.0
  • npm >= 8.3.0

Installation

npm install

Available scripts

CommandDescription
npm run serveStarts the local development server
npm run buildBuilds the production bundle into dist/
npm run lintRuns ESLint
npm run test:unitRuns the unit test suite

Environment configuration

The project uses .env files at the repository root. .env is loaded by default. Additional files such as .env.production or .env.<mode> can be used with Vue CLI modes.

The repository currently exposes generic scripts only. If you need a specific mode, use Vue CLI mode support directly, for example: npx vue-cli-service build --mode production.

Environment variables

VariableRequiredDescription
VUE_APP_ENVYesRuntime environment label, typically development or production
VUE_APP_PUBLIC_PATHYesBase public path used by Vue Router and static assets
VUE_APP_CONFIG_GEN_API_URLYesBase URL for the configuration generator backend
VUE_APP_PROJECT_GEN_API_URLYesBase URL for the project/archetype generator backend
VUE_APP_AUTH_URLIf OAuth is enabledOAuth 2 client credentials token endpoint
VUE_APP_AUTH_CLIENT_IDIf OAuth is enabledOAuth client ID
VUE_APP_AUTH_CLIENT_SECRETIf OAuth is enabledOAuth client secret
VUE_APP_REQUEST_RETRYNoRetry count used by project generation requests
VUE_APP_OAUTH_GENERATE_ACCESS_TOKENNo1 enables token retrieval and bearer token injection; 0 disables it
VUE_APP_CONFIG_GEN_STATUS_URLNoHealth/status URL for the configuration generator backend
VUE_APP_PROJECT_GEN_STATUS_URLNoHealth/status URL for the project generator backend
VUE_APP_WSO2_STATUS_URLNoOptional status URL shown in the footer connectivity modal
VUE_APP_APIGEN_DOTNET_URLNo.NET Apigen backend URL
VUE_APP_APIGEN_SPRINGBOOT_URLNoSpring Boot Apigen backend URL
VUE_APP_APIGEN_PYTHON_URLNoPython Apigen backend URL
VUE_APP_DB_EXPLORER_URLYes in productionDatabase Explorer backend URL
VUE_APP_API_KEYOptional, backend-dependentAPI key forwarded to the Database Explorer service
VUE_APP_DEBUG_PODSNoEnables round-robin requests between debug pod URLs when set to 1
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD1NoAlternate config generator URL for debug routing
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD2NoAlternate config generator URL for debug routing
PORTNoLocal development server port

Automatically injected build metadata

The application also injects these values at build time from package.json:

  • VUE_APP_VERSION
  • VUE_APP_NAME
  • VUE_APP_DESCRIPTION
  • VUE_COMPILATION_DATE

You normally do not define them manually.

Local development

npm run serve

The development server uses proxies defined in vue.config.js for:

  • /api-apigen-dotnet
  • /api-apigen-springboot
  • /api-apigen-python-dev
  • /db-explorer
  • /api-apiquality

Production build

npm run build

The output directory is dist/.

Real application workflow

In normal usage, the flow is:

  1. Fill in application metadata (name, description, version).
  2. Choose the target framework when running standalone.
  3. Connect to an existing database or create a temporary one from a SQL file.
  4. Import an OpenAPI or AsyncAPI definition, or receive it from a parent iframe host.
  5. Review generated resources/entities and adjust mappings.
  6. Preview or export the enriched specification.
  7. Optionally trigger archetype/code generation through a configured Apigen backend.

Database support

Connect to an existing database

The connection form supports these database types:

  • POSTGRES
  • ORACLE
  • MYSQL
  • SQLSERVER
  • MARIADB

Create a temporary database from SQL

The "create database" flow currently exposes:

  • POSTGRES
  • MYSQL

You can upload a .sql file, preview an ER diagram, or generate SQL from an already loaded OpenAPI document before creating the temporary database.

API definition import support

OpenAPI

  • Accepted formats: .yaml, .yml, .json
  • Extracts info.title, info.description, and info.version
  • Imports controllers/resources from the specification
  • If a database connection is active, it continues with the table/config import pipeline

AsyncAPI

  • Accepted formats: .yaml, .yml
  • Extracts info.title, info.description, and info.version
  • Extracts server names
  • Loads AsyncAPI controllers/entities locally before continuing with mapping

Supported Apigen technologies

Visual Mapper generates x-apigen-* extensions compatible with these target technologies:

ValueFrameworkNotes
pythonPython ApigenDefault value
springbootSpring Boot ApigenRequires group-id and artifact-id
dotnet.NET ApigenSupported by the backend integration layer

In the current standalone UI, the visible target framework selector exposes Python and Spring Boot. The iframe contract and backend service layer also recognize dotnet.

x-apigen-project differences by technology

Python / .NET

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysql

Spring Boot

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysqljava-properties:
group-id: com.exampleartifact-id: my-api

x-apigen-models

Generated from the database schema to describe the relational model:

x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Longrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: ownertype: Ownerrelational-persistence:
column: owner_id
- name: visitstype: Arrayitems-type: Visitrelational-persistence:
foreign-column: pet_id

x-tyk-anonymization

Marks response fields that should be anonymized by the Tyk gateway:

x-tyk-anonymization:
- field: emailtype: email
- field: phonetype: phone
- field: nametype: swapswap-list: names

Available anonymization types:

  • email
  • phone
  • name
  • dni
  • iban
  • swap (requires swap-list)

Iframe integration (postMessage)

Visual Mapper can run embedded inside an <iframe>. Communication is done through window.postMessage.

Incoming message (parent -> Visual Mapper)

The parent page can send this object after the iframe is loaded:

{
"openapi_yaml_in_base64": "<base64-encoded OpenAPI or JSON content>",
"apigen_type": "springboot",
"database": {
"credentials": {
"type": "POSTGRES",
"host": "localhost",
"port": "5432",
"name": "mydb",
"schema": "public",
"username": "admin"
},
"generated": {
"connection_id": "abc-123"
}
}
}
FieldRequiredDescription
openapi_yaml_in_base64YesOpenAPI content in YAML or JSON format, encoded in base64
apigen_typeNoTarget technology: python (default), springboot, dotnet
database.credentialsNoExisting database connection data used to prefill the connection form
database.credentials.typeNoDatabase type: POSTGRES, MYSQL, MARIADB, SQLSERVER, ORACLE
database.credentials.hostNoDatabase host
database.credentials.portNoDatabase port
database.credentials.nameNoDatabase name
database.credentials.schemaNoDatabase schema
database.credentials.usernameNoDatabase username
database.generatedNoModel field reserved for previously generated database sessions
database.generated.connection_idNoPreviously stored temporary connection identifier

What happens when the message is received

The current frontend implementation:

  • stores the iframe configuration in Vuex
  • extracts title, description, and version from the provided OpenAPI document
  • applies apigen_type to the target framework
  • prefills database connection fields from database.credentials
  • does not prefill the database password
  • auto-imports the OpenAPI definition once the connection and application data are ready

Important note about database.generated.connection_id

The data model includes database.generated.connection_id, and the original README describes an auto-connect flow for it. However, the current frontend code does not consume that value during iframe initialization. Treat it as part of the contract model, not as an implemented auto-reconnect feature in the present UI.

Parent page example

constiframe=document.getElementById('visual-mapper');iframe.contentWindow.postMessage({openapi_yaml_in_base64: btoa(yamlContent),apigen_type: 'springboot',database: {credentials: {type: 'POSTGRES',host: 'localhost',port: '5432',name: 'mydb',schema: 'public',username: 'admin'}}},'*');

Outgoing messages (Visual Mapper -> parent)

Temporary database created

Emitted when the user creates a temporary database from a SQL file:

{
"type": "connection-created",
"connection_id": "abc-123"
}

Example listener:

window.addEventListener('message',(event)=>{if(event.data?.type==='connection-created'){localStorage.setItem('vm_connection_id',event.data.connection_id);}});

Enriched OpenAPI / AsyncAPI document

Emitted when the user clicks Send to API Quality:

{
"type": "openapi-update",
"content_in_base64": "<base64-encoded enriched OpenAPI>"
}
{
"type": "asyncapi-update",
"content_in_base64": "<base64-encoded enriched AsyncAPI>"
}

Example decode logic:

window.addEventListener('message',(event)=>{if(event.data?.type==='openapi-update'){constyaml=decodeURIComponent(escape(atob(event.data.content_in_base64)));// use the enriched yaml}});

Code generation response passthrough

When Visual Mapper is embedded and the user triggers full or partial code generation, the frontend forwards the JSON payload returned by the generator backend directly to the parent window:

window.addEventListener('message',(event)=>{// event.data shape depends on the configured generator backendconsole.log(event.data);});

Because the payload is forwarded as-is from the backend response, its exact structure depends on the configured generator service and is not enforced by this frontend.

Security note

The current implementation sends messages with '*' as target origin. Parent applications should validate event.origin and event.data in their message listeners.

Docker

The repository includes:

  • a Dockerfile
  • an nginx.conf

The Docker image builds the Vue application and serves the static dist/ output with Nginx.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Visual Mapper

GitHub release (latest by date)LanguageFrameworkNode.js

Visual Mapper is a Vue 3 + TypeScript front-end for enriching OpenAPI or AsyncAPI definitions with x-apigen-* metadata, mapping API resources to relational database structures, and exporting the resulting specification back to a parent application or to downstream code-generation services.

What the application does

Visual Mapper helps you:

  • import an OpenAPI definition (.yaml, .yml, .json) or an AsyncAPI definition (.yaml, .yml)
  • connect to an existing database and inspect tables
  • create a temporary database from a SQL file
  • derive entities, controllers, relations, and validations from the connected schema
  • enrich the API definition with x-apigen-* extensions
  • preview or download the enriched OpenAPI / AsyncAPI document
  • optionally trigger archetype/code generation through configured Apigen backends
  • run embedded inside an iframe and exchange data with a parent application through window.postMessage

Tech stack

AreaDetails
FrameworkVue 3
LanguageTypeScript
StateVuex
RoutingVue Router
UIBootstrap 5 + bootstrap-vue-3
i18nvue-i18n
HTTPAxios
Build toolingVue CLI 5 / Webpack
TestingMocha + Chai via vue-cli-service test:unit

Requirements

  • Node.js >= 24.13.0
  • npm >= 8.3.0

Installation

npm install

Available scripts

CommandDescription
npm run serveStarts the local development server
npm run buildBuilds the production bundle into dist/
npm run lintRuns ESLint
npm run test:unitRuns the unit test suite

Environment configuration

The project uses .env files at the repository root. .env is loaded by default. Additional files such as .env.production or .env.<mode> can be used with Vue CLI modes.

The repository currently exposes generic scripts only. If you need a specific mode, use Vue CLI mode support directly, for example: npx vue-cli-service build --mode production.

Environment variables

VariableRequiredDescription
VUE_APP_ENVYesRuntime environment label, typically development or production
VUE_APP_PUBLIC_PATHYesBase public path used by Vue Router and static assets
VUE_APP_CONFIG_GEN_API_URLYesBase URL for the configuration generator backend
VUE_APP_PROJECT_GEN_API_URLYesBase URL for the project/archetype generator backend
VUE_APP_AUTH_URLIf OAuth is enabledOAuth 2 client credentials token endpoint
VUE_APP_AUTH_CLIENT_IDIf OAuth is enabledOAuth client ID
VUE_APP_AUTH_CLIENT_SECRETIf OAuth is enabledOAuth client secret
VUE_APP_REQUEST_RETRYNoRetry count used by project generation requests
VUE_APP_OAUTH_GENERATE_ACCESS_TOKENNo1 enables token retrieval and bearer token injection; 0 disables it
VUE_APP_CONFIG_GEN_STATUS_URLNoHealth/status URL for the configuration generator backend
VUE_APP_PROJECT_GEN_STATUS_URLNoHealth/status URL for the project generator backend
VUE_APP_WSO2_STATUS_URLNoOptional status URL shown in the footer connectivity modal
VUE_APP_APIGEN_DOTNET_URLNo.NET Apigen backend URL
VUE_APP_APIGEN_SPRINGBOOT_URLNoSpring Boot Apigen backend URL
VUE_APP_APIGEN_PYTHON_URLNoPython Apigen backend URL
VUE_APP_DB_EXPLORER_URLYes in productionDatabase Explorer backend URL
VUE_APP_API_KEYOptional, backend-dependentAPI key forwarded to the Database Explorer service
VUE_APP_DEBUG_PODSNoEnables round-robin requests between debug pod URLs when set to 1
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD1NoAlternate config generator URL for debug routing
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD2NoAlternate config generator URL for debug routing
PORTNoLocal development server port

Automatically injected build metadata

The application also injects these values at build time from package.json:

  • VUE_APP_VERSION
  • VUE_APP_NAME
  • VUE_APP_DESCRIPTION
  • VUE_COMPILATION_DATE

You normally do not define them manually.

Local development

npm run serve

The development server uses proxies defined in vue.config.js for:

  • /api-apigen-dotnet
  • /api-apigen-springboot
  • /api-apigen-python-dev
  • /db-explorer
  • /api-apiquality

Production build

npm run build

The output directory is dist/.

Real application workflow

In normal usage, the flow is:

  1. Fill in application metadata (name, description, version).
  2. Choose the target framework when running standalone.
  3. Connect to an existing database or create a temporary one from a SQL file.
  4. Import an OpenAPI or AsyncAPI definition, or receive it from a parent iframe host.
  5. Review generated resources/entities and adjust mappings.
  6. Preview or export the enriched specification.
  7. Optionally trigger archetype/code generation through a configured Apigen backend.

Database support

Connect to an existing database

The connection form supports these database types:

  • POSTGRES
  • ORACLE
  • MYSQL
  • SQLSERVER
  • MARIADB

Create a temporary database from SQL

The "create database" flow currently exposes:

  • POSTGRES
  • MYSQL

You can upload a .sql file, preview an ER diagram, or generate SQL from an already loaded OpenAPI document before creating the temporary database.

API definition import support

OpenAPI

  • Accepted formats: .yaml, .yml, .json
  • Extracts info.title, info.description, and info.version
  • Imports controllers/resources from the specification
  • If a database connection is active, it continues with the table/config import pipeline

AsyncAPI

  • Accepted formats: .yaml, .yml
  • Extracts info.title, info.description, and info.version
  • Extracts server names
  • Loads AsyncAPI controllers/entities locally before continuing with mapping

Supported Apigen technologies

Visual Mapper generates x-apigen-* extensions compatible with these target technologies:

ValueFrameworkNotes
pythonPython ApigenDefault value
springbootSpring Boot ApigenRequires group-id and artifact-id
dotnet.NET ApigenSupported by the backend integration layer

In the current standalone UI, the visible target framework selector exposes Python and Spring Boot. The iframe contract and backend service layer also recognize dotnet.

x-apigen-project differences by technology

Python / .NET

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysql

Spring Boot

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysqljava-properties:
group-id: com.exampleartifact-id: my-api

x-apigen-models

Generated from the database schema to describe the relational model:

x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Longrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: ownertype: Ownerrelational-persistence:
column: owner_id
- name: visitstype: Arrayitems-type: Visitrelational-persistence:
foreign-column: pet_id

x-tyk-anonymization

Marks response fields that should be anonymized by the Tyk gateway:

x-tyk-anonymization:
- field: emailtype: email
- field: phonetype: phone
- field: nametype: swapswap-list: names

Available anonymization types:

  • email
  • phone
  • name
  • dni
  • iban
  • swap (requires swap-list)

Iframe integration (postMessage)

Visual Mapper can run embedded inside an <iframe>. Communication is done through window.postMessage.

Incoming message (parent -> Visual Mapper)

The parent page can send this object after the iframe is loaded:

{
"openapi_yaml_in_base64": "<base64-encoded OpenAPI or JSON content>",
"apigen_type": "springboot",
"database": {
"credentials": {
"type": "POSTGRES",
"host": "localhost",
"port": "5432",
"name": "mydb",
"schema": "public",
"username": "admin"
},
"generated": {
"connection_id": "abc-123"
}
}
}
FieldRequiredDescription
openapi_yaml_in_base64YesOpenAPI content in YAML or JSON format, encoded in base64
apigen_typeNoTarget technology: python (default), springboot, dotnet
database.credentialsNoExisting database connection data used to prefill the connection form
database.credentials.typeNoDatabase type: POSTGRES, MYSQL, MARIADB, SQLSERVER, ORACLE
database.credentials.hostNoDatabase host
database.credentials.portNoDatabase port
database.credentials.nameNoDatabase name
database.credentials.schemaNoDatabase schema
database.credentials.usernameNoDatabase username
database.generatedNoModel field reserved for previously generated database sessions
database.generated.connection_idNoPreviously stored temporary connection identifier

What happens when the message is received

The current frontend implementation:

  • stores the iframe configuration in Vuex
  • extracts title, description, and version from the provided OpenAPI document
  • applies apigen_type to the target framework
  • prefills database connection fields from database.credentials
  • does not prefill the database password
  • auto-imports the OpenAPI definition once the connection and application data are ready

Important note about database.generated.connection_id

The data model includes database.generated.connection_id, and the original README describes an auto-connect flow for it. However, the current frontend code does not consume that value during iframe initialization. Treat it as part of the contract model, not as an implemented auto-reconnect feature in the present UI.

Parent page example

constiframe=document.getElementById('visual-mapper');iframe.contentWindow.postMessage({openapi_yaml_in_base64: btoa(yamlContent),apigen_type: 'springboot',database: {credentials: {type: 'POSTGRES',host: 'localhost',port: '5432',name: 'mydb',schema: 'public',username: 'admin'}}},'*');

Outgoing messages (Visual Mapper -> parent)

Temporary database created

Emitted when the user creates a temporary database from a SQL file:

{
"type": "connection-created",
"connection_id": "abc-123"
}

Example listener:

window.addEventListener('message',(event)=>{if(event.data?.type==='connection-created'){localStorage.setItem('vm_connection_id',event.data.connection_id);}});

Enriched OpenAPI / AsyncAPI document

Emitted when the user clicks Send to API Quality:

{
"type": "openapi-update",
"content_in_base64": "<base64-encoded enriched OpenAPI>"
}
{
"type": "asyncapi-update",
"content_in_base64": "<base64-encoded enriched AsyncAPI>"
}

Example decode logic:

window.addEventListener('message',(event)=>{if(event.data?.type==='openapi-update'){constyaml=decodeURIComponent(escape(atob(event.data.content_in_base64)));// use the enriched yaml}});

Code generation response passthrough

When Visual Mapper is embedded and the user triggers full or partial code generation, the frontend forwards the JSON payload returned by the generator backend directly to the parent window:

window.addEventListener('message',(event)=>{// event.data shape depends on the configured generator backendconsole.log(event.data);});

Because the payload is forwarded as-is from the backend response, its exact structure depends on the configured generator service and is not enforced by this frontend.

Security note

The current implementation sends messages with '*' as target origin. Parent applications should validate event.origin and event.data in their message listeners.

Docker

The repository includes:

  • a Dockerfile
  • an nginx.conf

The Docker image builds the Vue application and serves the static dist/ output with Nginx.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Visual Mapper

GitHub release (latest by date)LanguageFrameworkNode.js

Visual Mapper is a Vue 3 + TypeScript front-end for enriching OpenAPI or AsyncAPI definitions with x-apigen-* metadata, mapping API resources to relational database structures, and exporting the resulting specification back to a parent application or to downstream code-generation services.

What the application does

Visual Mapper helps you:

  • import an OpenAPI definition (.yaml, .yml, .json) or an AsyncAPI definition (.yaml, .yml)
  • connect to an existing database and inspect tables
  • create a temporary database from a SQL file
  • derive entities, controllers, relations, and validations from the connected schema
  • enrich the API definition with x-apigen-* extensions
  • preview or download the enriched OpenAPI / AsyncAPI document
  • optionally trigger archetype/code generation through configured Apigen backends
  • run embedded inside an iframe and exchange data with a parent application through window.postMessage

Tech stack

AreaDetails
FrameworkVue 3
LanguageTypeScript
StateVuex
RoutingVue Router
UIBootstrap 5 + bootstrap-vue-3
i18nvue-i18n
HTTPAxios
Build toolingVue CLI 5 / Webpack
TestingMocha + Chai via vue-cli-service test:unit

Requirements

  • Node.js >= 24.13.0
  • npm >= 8.3.0

Installation

npm install

Available scripts

CommandDescription
npm run serveStarts the local development server
npm run buildBuilds the production bundle into dist/
npm run lintRuns ESLint
npm run test:unitRuns the unit test suite

Environment configuration

The project uses .env files at the repository root. .env is loaded by default. Additional files such as .env.production or .env.<mode> can be used with Vue CLI modes.

The repository currently exposes generic scripts only. If you need a specific mode, use Vue CLI mode support directly, for example: npx vue-cli-service build --mode production.

Environment variables

VariableRequiredDescription
VUE_APP_ENVYesRuntime environment label, typically development or production
VUE_APP_PUBLIC_PATHYesBase public path used by Vue Router and static assets
VUE_APP_CONFIG_GEN_API_URLYesBase URL for the configuration generator backend
VUE_APP_PROJECT_GEN_API_URLYesBase URL for the project/archetype generator backend
VUE_APP_AUTH_URLIf OAuth is enabledOAuth 2 client credentials token endpoint
VUE_APP_AUTH_CLIENT_IDIf OAuth is enabledOAuth client ID
VUE_APP_AUTH_CLIENT_SECRETIf OAuth is enabledOAuth client secret
VUE_APP_REQUEST_RETRYNoRetry count used by project generation requests
VUE_APP_OAUTH_GENERATE_ACCESS_TOKENNo1 enables token retrieval and bearer token injection; 0 disables it
VUE_APP_CONFIG_GEN_STATUS_URLNoHealth/status URL for the configuration generator backend
VUE_APP_PROJECT_GEN_STATUS_URLNoHealth/status URL for the project generator backend
VUE_APP_WSO2_STATUS_URLNoOptional status URL shown in the footer connectivity modal
VUE_APP_APIGEN_DOTNET_URLNo.NET Apigen backend URL
VUE_APP_APIGEN_SPRINGBOOT_URLNoSpring Boot Apigen backend URL
VUE_APP_APIGEN_PYTHON_URLNoPython Apigen backend URL
VUE_APP_DB_EXPLORER_URLYes in productionDatabase Explorer backend URL
VUE_APP_API_KEYOptional, backend-dependentAPI key forwarded to the Database Explorer service
VUE_APP_DEBUG_PODSNoEnables round-robin requests between debug pod URLs when set to 1
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD1NoAlternate config generator URL for debug routing
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD2NoAlternate config generator URL for debug routing
PORTNoLocal development server port

Automatically injected build metadata

The application also injects these values at build time from package.json:

  • VUE_APP_VERSION
  • VUE_APP_NAME
  • VUE_APP_DESCRIPTION
  • VUE_COMPILATION_DATE

You normally do not define them manually.

Local development

npm run serve

The development server uses proxies defined in vue.config.js for:

  • /api-apigen-dotnet
  • /api-apigen-springboot
  • /api-apigen-python-dev
  • /db-explorer
  • /api-apiquality

Production build

npm run build

The output directory is dist/.

Real application workflow

In normal usage, the flow is:

  1. Fill in application metadata (name, description, version).
  2. Choose the target framework when running standalone.
  3. Connect to an existing database or create a temporary one from a SQL file.
  4. Import an OpenAPI or AsyncAPI definition, or receive it from a parent iframe host.
  5. Review generated resources/entities and adjust mappings.
  6. Preview or export the enriched specification.
  7. Optionally trigger archetype/code generation through a configured Apigen backend.

Database support

Connect to an existing database

The connection form supports these database types:

  • POSTGRES
  • ORACLE
  • MYSQL
  • SQLSERVER
  • MARIADB

Create a temporary database from SQL

The "create database" flow currently exposes:

  • POSTGRES
  • MYSQL

You can upload a .sql file, preview an ER diagram, or generate SQL from an already loaded OpenAPI document before creating the temporary database.

API definition import support

OpenAPI

  • Accepted formats: .yaml, .yml, .json
  • Extracts info.title, info.description, and info.version
  • Imports controllers/resources from the specification
  • If a database connection is active, it continues with the table/config import pipeline

AsyncAPI

  • Accepted formats: .yaml, .yml
  • Extracts info.title, info.description, and info.version
  • Extracts server names
  • Loads AsyncAPI controllers/entities locally before continuing with mapping

Supported Apigen technologies

Visual Mapper generates x-apigen-* extensions compatible with these target technologies:

ValueFrameworkNotes
pythonPython ApigenDefault value
springbootSpring Boot ApigenRequires group-id and artifact-id
dotnet.NET ApigenSupported by the backend integration layer

In the current standalone UI, the visible target framework selector exposes Python and Spring Boot. The iframe contract and backend service layer also recognize dotnet.

x-apigen-project differences by technology

Python / .NET

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysql

Spring Boot

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysqljava-properties:
group-id: com.exampleartifact-id: my-api

x-apigen-models

Generated from the database schema to describe the relational model:

x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Longrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: ownertype: Ownerrelational-persistence:
column: owner_id
- name: visitstype: Arrayitems-type: Visitrelational-persistence:
foreign-column: pet_id

x-tyk-anonymization

Marks response fields that should be anonymized by the Tyk gateway:

x-tyk-anonymization:
- field: emailtype: email
- field: phonetype: phone
- field: nametype: swapswap-list: names

Available anonymization types:

  • email
  • phone
  • name
  • dni
  • iban
  • swap (requires swap-list)

Iframe integration (postMessage)

Visual Mapper can run embedded inside an <iframe>. Communication is done through window.postMessage.

Incoming message (parent -> Visual Mapper)

The parent page can send this object after the iframe is loaded:

{
"openapi_yaml_in_base64": "<base64-encoded OpenAPI or JSON content>",
"apigen_type": "springboot",
"database": {
"credentials": {
"type": "POSTGRES",
"host": "localhost",
"port": "5432",
"name": "mydb",
"schema": "public",
"username": "admin"
},
"generated": {
"connection_id": "abc-123"
}
}
}
FieldRequiredDescription
openapi_yaml_in_base64YesOpenAPI content in YAML or JSON format, encoded in base64
apigen_typeNoTarget technology: python (default), springboot, dotnet
database.credentialsNoExisting database connection data used to prefill the connection form
database.credentials.typeNoDatabase type: POSTGRES, MYSQL, MARIADB, SQLSERVER, ORACLE
database.credentials.hostNoDatabase host
database.credentials.portNoDatabase port
database.credentials.nameNoDatabase name
database.credentials.schemaNoDatabase schema
database.credentials.usernameNoDatabase username
database.generatedNoModel field reserved for previously generated database sessions
database.generated.connection_idNoPreviously stored temporary connection identifier

What happens when the message is received

The current frontend implementation:

  • stores the iframe configuration in Vuex
  • extracts title, description, and version from the provided OpenAPI document
  • applies apigen_type to the target framework
  • prefills database connection fields from database.credentials
  • does not prefill the database password
  • auto-imports the OpenAPI definition once the connection and application data are ready

Important note about database.generated.connection_id

The data model includes database.generated.connection_id, and the original README describes an auto-connect flow for it. However, the current frontend code does not consume that value during iframe initialization. Treat it as part of the contract model, not as an implemented auto-reconnect feature in the present UI.

Parent page example

constiframe=document.getElementById('visual-mapper');iframe.contentWindow.postMessage({openapi_yaml_in_base64: btoa(yamlContent),apigen_type: 'springboot',database: {credentials: {type: 'POSTGRES',host: 'localhost',port: '5432',name: 'mydb',schema: 'public',username: 'admin'}}},'*');

Outgoing messages (Visual Mapper -> parent)

Temporary database created

Emitted when the user creates a temporary database from a SQL file:

{
"type": "connection-created",
"connection_id": "abc-123"
}

Example listener:

window.addEventListener('message',(event)=>{if(event.data?.type==='connection-created'){localStorage.setItem('vm_connection_id',event.data.connection_id);}});

Enriched OpenAPI / AsyncAPI document

Emitted when the user clicks Send to API Quality:

{
"type": "openapi-update",
"content_in_base64": "<base64-encoded enriched OpenAPI>"
}
{
"type": "asyncapi-update",
"content_in_base64": "<base64-encoded enriched AsyncAPI>"
}

Example decode logic:

window.addEventListener('message',(event)=>{if(event.data?.type==='openapi-update'){constyaml=decodeURIComponent(escape(atob(event.data.content_in_base64)));// use the enriched yaml}});

Code generation response passthrough

When Visual Mapper is embedded and the user triggers full or partial code generation, the frontend forwards the JSON payload returned by the generator backend directly to the parent window:

window.addEventListener('message',(event)=>{// event.data shape depends on the configured generator backendconsole.log(event.data);});

Because the payload is forwarded as-is from the backend response, its exact structure depends on the configured generator service and is not enforced by this frontend.

Security note

The current implementation sends messages with '*' as target origin. Parent applications should validate event.origin and event.data in their message listeners.

Docker

The repository includes:

  • a Dockerfile
  • an nginx.conf

The Docker image builds the Vue application and serves the static dist/ output with Nginx.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Visual Mapper

GitHub release (latest by date)LanguageFrameworkNode.js

Visual Mapper is a Vue 3 + TypeScript front-end for enriching OpenAPI or AsyncAPI definitions with x-apigen-* metadata, mapping API resources to relational database structures, and exporting the resulting specification back to a parent application or to downstream code-generation services.

What the application does

Visual Mapper helps you:

  • import an OpenAPI definition (.yaml, .yml, .json) or an AsyncAPI definition (.yaml, .yml)
  • connect to an existing database and inspect tables
  • create a temporary database from a SQL file
  • derive entities, controllers, relations, and validations from the connected schema
  • enrich the API definition with x-apigen-* extensions
  • preview or download the enriched OpenAPI / AsyncAPI document
  • optionally trigger archetype/code generation through configured Apigen backends
  • run embedded inside an iframe and exchange data with a parent application through window.postMessage

Tech stack

AreaDetails
FrameworkVue 3
LanguageTypeScript
StateVuex
RoutingVue Router
UIBootstrap 5 + bootstrap-vue-3
i18nvue-i18n
HTTPAxios
Build toolingVue CLI 5 / Webpack
TestingMocha + Chai via vue-cli-service test:unit

Requirements

  • Node.js >= 24.13.0
  • npm >= 8.3.0

Installation

npm install

Available scripts

CommandDescription
npm run serveStarts the local development server
npm run buildBuilds the production bundle into dist/
npm run lintRuns ESLint
npm run test:unitRuns the unit test suite

Environment configuration

The project uses .env files at the repository root. .env is loaded by default. Additional files such as .env.production or .env.<mode> can be used with Vue CLI modes.

The repository currently exposes generic scripts only. If you need a specific mode, use Vue CLI mode support directly, for example: npx vue-cli-service build --mode production.

Environment variables

VariableRequiredDescription
VUE_APP_ENVYesRuntime environment label, typically development or production
VUE_APP_PUBLIC_PATHYesBase public path used by Vue Router and static assets
VUE_APP_CONFIG_GEN_API_URLYesBase URL for the configuration generator backend
VUE_APP_PROJECT_GEN_API_URLYesBase URL for the project/archetype generator backend
VUE_APP_AUTH_URLIf OAuth is enabledOAuth 2 client credentials token endpoint
VUE_APP_AUTH_CLIENT_IDIf OAuth is enabledOAuth client ID
VUE_APP_AUTH_CLIENT_SECRETIf OAuth is enabledOAuth client secret
VUE_APP_REQUEST_RETRYNoRetry count used by project generation requests
VUE_APP_OAUTH_GENERATE_ACCESS_TOKENNo1 enables token retrieval and bearer token injection; 0 disables it
VUE_APP_CONFIG_GEN_STATUS_URLNoHealth/status URL for the configuration generator backend
VUE_APP_PROJECT_GEN_STATUS_URLNoHealth/status URL for the project generator backend
VUE_APP_WSO2_STATUS_URLNoOptional status URL shown in the footer connectivity modal
VUE_APP_APIGEN_DOTNET_URLNo.NET Apigen backend URL
VUE_APP_APIGEN_SPRINGBOOT_URLNoSpring Boot Apigen backend URL
VUE_APP_APIGEN_PYTHON_URLNoPython Apigen backend URL
VUE_APP_DB_EXPLORER_URLYes in productionDatabase Explorer backend URL
VUE_APP_API_KEYOptional, backend-dependentAPI key forwarded to the Database Explorer service
VUE_APP_DEBUG_PODSNoEnables round-robin requests between debug pod URLs when set to 1
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD1NoAlternate config generator URL for debug routing
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD2NoAlternate config generator URL for debug routing
PORTNoLocal development server port

Automatically injected build metadata

The application also injects these values at build time from package.json:

  • VUE_APP_VERSION
  • VUE_APP_NAME
  • VUE_APP_DESCRIPTION
  • VUE_COMPILATION_DATE

You normally do not define them manually.

Local development

npm run serve

The development server uses proxies defined in vue.config.js for:

  • /api-apigen-dotnet
  • /api-apigen-springboot
  • /api-apigen-python-dev
  • /db-explorer
  • /api-apiquality

Production build

npm run build

The output directory is dist/.

Real application workflow

In normal usage, the flow is:

  1. Fill in application metadata (name, description, version).
  2. Choose the target framework when running standalone.
  3. Connect to an existing database or create a temporary one from a SQL file.
  4. Import an OpenAPI or AsyncAPI definition, or receive it from a parent iframe host.
  5. Review generated resources/entities and adjust mappings.
  6. Preview or export the enriched specification.
  7. Optionally trigger archetype/code generation through a configured Apigen backend.

Database support

Connect to an existing database

The connection form supports these database types:

  • POSTGRES
  • ORACLE
  • MYSQL
  • SQLSERVER
  • MARIADB

Create a temporary database from SQL

The "create database" flow currently exposes:

  • POSTGRES
  • MYSQL

You can upload a .sql file, preview an ER diagram, or generate SQL from an already loaded OpenAPI document before creating the temporary database.

API definition import support

OpenAPI

  • Accepted formats: .yaml, .yml, .json
  • Extracts info.title, info.description, and info.version
  • Imports controllers/resources from the specification
  • If a database connection is active, it continues with the table/config import pipeline

AsyncAPI

  • Accepted formats: .yaml, .yml
  • Extracts info.title, info.description, and info.version
  • Extracts server names
  • Loads AsyncAPI controllers/entities locally before continuing with mapping

Supported Apigen technologies

Visual Mapper generates x-apigen-* extensions compatible with these target technologies:

ValueFrameworkNotes
pythonPython ApigenDefault value
springbootSpring Boot ApigenRequires group-id and artifact-id
dotnet.NET ApigenSupported by the backend integration layer

In the current standalone UI, the visible target framework selector exposes Python and Spring Boot. The iframe contract and backend service layer also recognize dotnet.

x-apigen-project differences by technology

Python / .NET

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysql

Spring Boot

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysqljava-properties:
group-id: com.exampleartifact-id: my-api

x-apigen-models

Generated from the database schema to describe the relational model:

x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Longrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: ownertype: Ownerrelational-persistence:
column: owner_id
- name: visitstype: Arrayitems-type: Visitrelational-persistence:
foreign-column: pet_id

x-tyk-anonymization

Marks response fields that should be anonymized by the Tyk gateway:

x-tyk-anonymization:
- field: emailtype: email
- field: phonetype: phone
- field: nametype: swapswap-list: names

Available anonymization types:

  • email
  • phone
  • name
  • dni
  • iban
  • swap (requires swap-list)

Iframe integration (postMessage)

Visual Mapper can run embedded inside an <iframe>. Communication is done through window.postMessage.

Incoming message (parent -> Visual Mapper)

The parent page can send this object after the iframe is loaded:

{
"openapi_yaml_in_base64": "<base64-encoded OpenAPI or JSON content>",
"apigen_type": "springboot",
"database": {
"credentials": {
"type": "POSTGRES",
"host": "localhost",
"port": "5432",
"name": "mydb",
"schema": "public",
"username": "admin"
},
"generated": {
"connection_id": "abc-123"
}
}
}
FieldRequiredDescription
openapi_yaml_in_base64YesOpenAPI content in YAML or JSON format, encoded in base64
apigen_typeNoTarget technology: python (default), springboot, dotnet
database.credentialsNoExisting database connection data used to prefill the connection form
database.credentials.typeNoDatabase type: POSTGRES, MYSQL, MARIADB, SQLSERVER, ORACLE
database.credentials.hostNoDatabase host
database.credentials.portNoDatabase port
database.credentials.nameNoDatabase name
database.credentials.schemaNoDatabase schema
database.credentials.usernameNoDatabase username
database.generatedNoModel field reserved for previously generated database sessions
database.generated.connection_idNoPreviously stored temporary connection identifier

What happens when the message is received

The current frontend implementation:

  • stores the iframe configuration in Vuex
  • extracts title, description, and version from the provided OpenAPI document
  • applies apigen_type to the target framework
  • prefills database connection fields from database.credentials
  • does not prefill the database password
  • auto-imports the OpenAPI definition once the connection and application data are ready

Important note about database.generated.connection_id

The data model includes database.generated.connection_id, and the original README describes an auto-connect flow for it. However, the current frontend code does not consume that value during iframe initialization. Treat it as part of the contract model, not as an implemented auto-reconnect feature in the present UI.

Parent page example

constiframe=document.getElementById('visual-mapper');iframe.contentWindow.postMessage({openapi_yaml_in_base64: btoa(yamlContent),apigen_type: 'springboot',database: {credentials: {type: 'POSTGRES',host: 'localhost',port: '5432',name: 'mydb',schema: 'public',username: 'admin'}}},'*');

Outgoing messages (Visual Mapper -> parent)

Temporary database created

Emitted when the user creates a temporary database from a SQL file:

{
"type": "connection-created",
"connection_id": "abc-123"
}

Example listener:

window.addEventListener('message',(event)=>{if(event.data?.type==='connection-created'){localStorage.setItem('vm_connection_id',event.data.connection_id);}});

Enriched OpenAPI / AsyncAPI document

Emitted when the user clicks Send to API Quality:

{
"type": "openapi-update",
"content_in_base64": "<base64-encoded enriched OpenAPI>"
}
{
"type": "asyncapi-update",
"content_in_base64": "<base64-encoded enriched AsyncAPI>"
}

Example decode logic:

window.addEventListener('message',(event)=>{if(event.data?.type==='openapi-update'){constyaml=decodeURIComponent(escape(atob(event.data.content_in_base64)));// use the enriched yaml}});

Code generation response passthrough

When Visual Mapper is embedded and the user triggers full or partial code generation, the frontend forwards the JSON payload returned by the generator backend directly to the parent window:

window.addEventListener('message',(event)=>{// event.data shape depends on the configured generator backendconsole.log(event.data);});

Because the payload is forwarded as-is from the backend response, its exact structure depends on the configured generator service and is not enforced by this frontend.

Security note

The current implementation sends messages with '*' as target origin. Parent applications should validate event.origin and event.data in their message listeners.

Docker

The repository includes:

  • a Dockerfile
  • an nginx.conf

The Docker image builds the Vue application and serves the static dist/ output with Nginx.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Visual Mapper

GitHub release (latest by date)LanguageFrameworkNode.js

Visual Mapper is a Vue 3 + TypeScript front-end for enriching OpenAPI or AsyncAPI definitions with x-apigen-* metadata, mapping API resources to relational database structures, and exporting the resulting specification back to a parent application or to downstream code-generation services.

What the application does

Visual Mapper helps you:

  • import an OpenAPI definition (.yaml, .yml, .json) or an AsyncAPI definition (.yaml, .yml)
  • connect to an existing database and inspect tables
  • create a temporary database from a SQL file
  • derive entities, controllers, relations, and validations from the connected schema
  • enrich the API definition with x-apigen-* extensions
  • preview or download the enriched OpenAPI / AsyncAPI document
  • optionally trigger archetype/code generation through configured Apigen backends
  • run embedded inside an iframe and exchange data with a parent application through window.postMessage

Tech stack

AreaDetails
FrameworkVue 3
LanguageTypeScript
StateVuex
RoutingVue Router
UIBootstrap 5 + bootstrap-vue-3
i18nvue-i18n
HTTPAxios
Build toolingVue CLI 5 / Webpack
TestingMocha + Chai via vue-cli-service test:unit

Requirements

  • Node.js >= 24.13.0
  • npm >= 8.3.0

Installation

npm install

Available scripts

CommandDescription
npm run serveStarts the local development server
npm run buildBuilds the production bundle into dist/
npm run lintRuns ESLint
npm run test:unitRuns the unit test suite

Environment configuration

The project uses .env files at the repository root. .env is loaded by default. Additional files such as .env.production or .env.<mode> can be used with Vue CLI modes.

The repository currently exposes generic scripts only. If you need a specific mode, use Vue CLI mode support directly, for example: npx vue-cli-service build --mode production.

Environment variables

VariableRequiredDescription
VUE_APP_ENVYesRuntime environment label, typically development or production
VUE_APP_PUBLIC_PATHYesBase public path used by Vue Router and static assets
VUE_APP_CONFIG_GEN_API_URLYesBase URL for the configuration generator backend
VUE_APP_PROJECT_GEN_API_URLYesBase URL for the project/archetype generator backend
VUE_APP_AUTH_URLIf OAuth is enabledOAuth 2 client credentials token endpoint
VUE_APP_AUTH_CLIENT_IDIf OAuth is enabledOAuth client ID
VUE_APP_AUTH_CLIENT_SECRETIf OAuth is enabledOAuth client secret
VUE_APP_REQUEST_RETRYNoRetry count used by project generation requests
VUE_APP_OAUTH_GENERATE_ACCESS_TOKENNo1 enables token retrieval and bearer token injection; 0 disables it
VUE_APP_CONFIG_GEN_STATUS_URLNoHealth/status URL for the configuration generator backend
VUE_APP_PROJECT_GEN_STATUS_URLNoHealth/status URL for the project generator backend
VUE_APP_WSO2_STATUS_URLNoOptional status URL shown in the footer connectivity modal
VUE_APP_APIGEN_DOTNET_URLNo.NET Apigen backend URL
VUE_APP_APIGEN_SPRINGBOOT_URLNoSpring Boot Apigen backend URL
VUE_APP_APIGEN_PYTHON_URLNoPython Apigen backend URL
VUE_APP_DB_EXPLORER_URLYes in productionDatabase Explorer backend URL
VUE_APP_API_KEYOptional, backend-dependentAPI key forwarded to the Database Explorer service
VUE_APP_DEBUG_PODSNoEnables round-robin requests between debug pod URLs when set to 1
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD1NoAlternate config generator URL for debug routing
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD2NoAlternate config generator URL for debug routing
PORTNoLocal development server port

Automatically injected build metadata

The application also injects these values at build time from package.json:

  • VUE_APP_VERSION
  • VUE_APP_NAME
  • VUE_APP_DESCRIPTION
  • VUE_COMPILATION_DATE

You normally do not define them manually.

Local development

npm run serve

The development server uses proxies defined in vue.config.js for:

  • /api-apigen-dotnet
  • /api-apigen-springboot
  • /api-apigen-python-dev
  • /db-explorer
  • /api-apiquality

Production build

npm run build

The output directory is dist/.

Real application workflow

In normal usage, the flow is:

  1. Fill in application metadata (name, description, version).
  2. Choose the target framework when running standalone.
  3. Connect to an existing database or create a temporary one from a SQL file.
  4. Import an OpenAPI or AsyncAPI definition, or receive it from a parent iframe host.
  5. Review generated resources/entities and adjust mappings.
  6. Preview or export the enriched specification.
  7. Optionally trigger archetype/code generation through a configured Apigen backend.

Database support

Connect to an existing database

The connection form supports these database types:

  • POSTGRES
  • ORACLE
  • MYSQL
  • SQLSERVER
  • MARIADB

Create a temporary database from SQL

The "create database" flow currently exposes:

  • POSTGRES
  • MYSQL

You can upload a .sql file, preview an ER diagram, or generate SQL from an already loaded OpenAPI document before creating the temporary database.

API definition import support

OpenAPI

  • Accepted formats: .yaml, .yml, .json
  • Extracts info.title, info.description, and info.version
  • Imports controllers/resources from the specification
  • If a database connection is active, it continues with the table/config import pipeline

AsyncAPI

  • Accepted formats: .yaml, .yml
  • Extracts info.title, info.description, and info.version
  • Extracts server names
  • Loads AsyncAPI controllers/entities locally before continuing with mapping

Supported Apigen technologies

Visual Mapper generates x-apigen-* extensions compatible with these target technologies:

ValueFrameworkNotes
pythonPython ApigenDefault value
springbootSpring Boot ApigenRequires group-id and artifact-id
dotnet.NET ApigenSupported by the backend integration layer

In the current standalone UI, the visible target framework selector exposes Python and Spring Boot. The iframe contract and backend service layer also recognize dotnet.

x-apigen-project differences by technology

Python / .NET

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysql

Spring Boot

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysqljava-properties:
group-id: com.exampleartifact-id: my-api

x-apigen-models

Generated from the database schema to describe the relational model:

x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Longrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: ownertype: Ownerrelational-persistence:
column: owner_id
- name: visitstype: Arrayitems-type: Visitrelational-persistence:
foreign-column: pet_id

x-tyk-anonymization

Marks response fields that should be anonymized by the Tyk gateway:

x-tyk-anonymization:
- field: emailtype: email
- field: phonetype: phone
- field: nametype: swapswap-list: names

Available anonymization types:

  • email
  • phone
  • name
  • dni
  • iban
  • swap (requires swap-list)

Iframe integration (postMessage)

Visual Mapper can run embedded inside an <iframe>. Communication is done through window.postMessage.

Incoming message (parent -> Visual Mapper)

The parent page can send this object after the iframe is loaded:

{
"openapi_yaml_in_base64": "<base64-encoded OpenAPI or JSON content>",
"apigen_type": "springboot",
"database": {
"credentials": {
"type": "POSTGRES",
"host": "localhost",
"port": "5432",
"name": "mydb",
"schema": "public",
"username": "admin"
},
"generated": {
"connection_id": "abc-123"
}
}
}
FieldRequiredDescription
openapi_yaml_in_base64YesOpenAPI content in YAML or JSON format, encoded in base64
apigen_typeNoTarget technology: python (default), springboot, dotnet
database.credentialsNoExisting database connection data used to prefill the connection form
database.credentials.typeNoDatabase type: POSTGRES, MYSQL, MARIADB, SQLSERVER, ORACLE
database.credentials.hostNoDatabase host
database.credentials.portNoDatabase port
database.credentials.nameNoDatabase name
database.credentials.schemaNoDatabase schema
database.credentials.usernameNoDatabase username
database.generatedNoModel field reserved for previously generated database sessions
database.generated.connection_idNoPreviously stored temporary connection identifier

What happens when the message is received

The current frontend implementation:

  • stores the iframe configuration in Vuex
  • extracts title, description, and version from the provided OpenAPI document
  • applies apigen_type to the target framework
  • prefills database connection fields from database.credentials
  • does not prefill the database password
  • auto-imports the OpenAPI definition once the connection and application data are ready

Important note about database.generated.connection_id

The data model includes database.generated.connection_id, and the original README describes an auto-connect flow for it. However, the current frontend code does not consume that value during iframe initialization. Treat it as part of the contract model, not as an implemented auto-reconnect feature in the present UI.

Parent page example

constiframe=document.getElementById('visual-mapper');iframe.contentWindow.postMessage({openapi_yaml_in_base64: btoa(yamlContent),apigen_type: 'springboot',database: {credentials: {type: 'POSTGRES',host: 'localhost',port: '5432',name: 'mydb',schema: 'public',username: 'admin'}}},'*');

Outgoing messages (Visual Mapper -> parent)

Temporary database created

Emitted when the user creates a temporary database from a SQL file:

{
"type": "connection-created",
"connection_id": "abc-123"
}

Example listener:

window.addEventListener('message',(event)=>{if(event.data?.type==='connection-created'){localStorage.setItem('vm_connection_id',event.data.connection_id);}});

Enriched OpenAPI / AsyncAPI document

Emitted when the user clicks Send to API Quality:

{
"type": "openapi-update",
"content_in_base64": "<base64-encoded enriched OpenAPI>"
}
{
"type": "asyncapi-update",
"content_in_base64": "<base64-encoded enriched AsyncAPI>"
}

Example decode logic:

window.addEventListener('message',(event)=>{if(event.data?.type==='openapi-update'){constyaml=decodeURIComponent(escape(atob(event.data.content_in_base64)));// use the enriched yaml}});

Code generation response passthrough

When Visual Mapper is embedded and the user triggers full or partial code generation, the frontend forwards the JSON payload returned by the generator backend directly to the parent window:

window.addEventListener('message',(event)=>{// event.data shape depends on the configured generator backendconsole.log(event.data);});

Because the payload is forwarded as-is from the backend response, its exact structure depends on the configured generator service and is not enforced by this frontend.

Security note

The current implementation sends messages with '*' as target origin. Parent applications should validate event.origin and event.data in their message listeners.

Docker

The repository includes:

  • a Dockerfile
  • an nginx.conf

The Docker image builds the Vue application and serves the static dist/ output with Nginx.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Visual Mapper

GitHub release (latest by date)LanguageFrameworkNode.js

Visual Mapper is a Vue 3 + TypeScript front-end for enriching OpenAPI or AsyncAPI definitions with x-apigen-* metadata, mapping API resources to relational database structures, and exporting the resulting specification back to a parent application or to downstream code-generation services.

What the application does

Visual Mapper helps you:

  • import an OpenAPI definition (.yaml, .yml, .json) or an AsyncAPI definition (.yaml, .yml)
  • connect to an existing database and inspect tables
  • create a temporary database from a SQL file
  • derive entities, controllers, relations, and validations from the connected schema
  • enrich the API definition with x-apigen-* extensions
  • preview or download the enriched OpenAPI / AsyncAPI document
  • optionally trigger archetype/code generation through configured Apigen backends
  • run embedded inside an iframe and exchange data with a parent application through window.postMessage

Tech stack

AreaDetails
FrameworkVue 3
LanguageTypeScript
StateVuex
RoutingVue Router
UIBootstrap 5 + bootstrap-vue-3
i18nvue-i18n
HTTPAxios
Build toolingVue CLI 5 / Webpack
TestingMocha + Chai via vue-cli-service test:unit

Requirements

  • Node.js >= 24.13.0
  • npm >= 8.3.0

Installation

npm install

Available scripts

CommandDescription
npm run serveStarts the local development server
npm run buildBuilds the production bundle into dist/
npm run lintRuns ESLint
npm run test:unitRuns the unit test suite

Environment configuration

The project uses .env files at the repository root. .env is loaded by default. Additional files such as .env.production or .env.<mode> can be used with Vue CLI modes.

The repository currently exposes generic scripts only. If you need a specific mode, use Vue CLI mode support directly, for example: npx vue-cli-service build --mode production.

Environment variables

VariableRequiredDescription
VUE_APP_ENVYesRuntime environment label, typically development or production
VUE_APP_PUBLIC_PATHYesBase public path used by Vue Router and static assets
VUE_APP_CONFIG_GEN_API_URLYesBase URL for the configuration generator backend
VUE_APP_PROJECT_GEN_API_URLYesBase URL for the project/archetype generator backend
VUE_APP_AUTH_URLIf OAuth is enabledOAuth 2 client credentials token endpoint
VUE_APP_AUTH_CLIENT_IDIf OAuth is enabledOAuth client ID
VUE_APP_AUTH_CLIENT_SECRETIf OAuth is enabledOAuth client secret
VUE_APP_REQUEST_RETRYNoRetry count used by project generation requests
VUE_APP_OAUTH_GENERATE_ACCESS_TOKENNo1 enables token retrieval and bearer token injection; 0 disables it
VUE_APP_CONFIG_GEN_STATUS_URLNoHealth/status URL for the configuration generator backend
VUE_APP_PROJECT_GEN_STATUS_URLNoHealth/status URL for the project generator backend
VUE_APP_WSO2_STATUS_URLNoOptional status URL shown in the footer connectivity modal
VUE_APP_APIGEN_DOTNET_URLNo.NET Apigen backend URL
VUE_APP_APIGEN_SPRINGBOOT_URLNoSpring Boot Apigen backend URL
VUE_APP_APIGEN_PYTHON_URLNoPython Apigen backend URL
VUE_APP_DB_EXPLORER_URLYes in productionDatabase Explorer backend URL
VUE_APP_API_KEYOptional, backend-dependentAPI key forwarded to the Database Explorer service
VUE_APP_DEBUG_PODSNoEnables round-robin requests between debug pod URLs when set to 1
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD1NoAlternate config generator URL for debug routing
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD2NoAlternate config generator URL for debug routing
PORTNoLocal development server port

Automatically injected build metadata

The application also injects these values at build time from package.json:

  • VUE_APP_VERSION
  • VUE_APP_NAME
  • VUE_APP_DESCRIPTION
  • VUE_COMPILATION_DATE

You normally do not define them manually.

Local development

npm run serve

The development server uses proxies defined in vue.config.js for:

  • /api-apigen-dotnet
  • /api-apigen-springboot
  • /api-apigen-python-dev
  • /db-explorer
  • /api-apiquality

Production build

npm run build

The output directory is dist/.

Real application workflow

In normal usage, the flow is:

  1. Fill in application metadata (name, description, version).
  2. Choose the target framework when running standalone.
  3. Connect to an existing database or create a temporary one from a SQL file.
  4. Import an OpenAPI or AsyncAPI definition, or receive it from a parent iframe host.
  5. Review generated resources/entities and adjust mappings.
  6. Preview or export the enriched specification.
  7. Optionally trigger archetype/code generation through a configured Apigen backend.

Database support

Connect to an existing database

The connection form supports these database types:

  • POSTGRES
  • ORACLE
  • MYSQL
  • SQLSERVER
  • MARIADB

Create a temporary database from SQL

The "create database" flow currently exposes:

  • POSTGRES
  • MYSQL

You can upload a .sql file, preview an ER diagram, or generate SQL from an already loaded OpenAPI document before creating the temporary database.

API definition import support

OpenAPI

  • Accepted formats: .yaml, .yml, .json
  • Extracts info.title, info.description, and info.version
  • Imports controllers/resources from the specification
  • If a database connection is active, it continues with the table/config import pipeline

AsyncAPI

  • Accepted formats: .yaml, .yml
  • Extracts info.title, info.description, and info.version
  • Extracts server names
  • Loads AsyncAPI controllers/entities locally before continuing with mapping

Supported Apigen technologies

Visual Mapper generates x-apigen-* extensions compatible with these target technologies:

ValueFrameworkNotes
pythonPython ApigenDefault value
springbootSpring Boot ApigenRequires group-id and artifact-id
dotnet.NET ApigenSupported by the backend integration layer

In the current standalone UI, the visible target framework selector exposes Python and Spring Boot. The iframe contract and backend service layer also recognize dotnet.

x-apigen-project differences by technology

Python / .NET

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysql

Spring Boot

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysqljava-properties:
group-id: com.exampleartifact-id: my-api

x-apigen-models

Generated from the database schema to describe the relational model:

x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Longrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: ownertype: Ownerrelational-persistence:
column: owner_id
- name: visitstype: Arrayitems-type: Visitrelational-persistence:
foreign-column: pet_id

x-tyk-anonymization

Marks response fields that should be anonymized by the Tyk gateway:

x-tyk-anonymization:
- field: emailtype: email
- field: phonetype: phone
- field: nametype: swapswap-list: names

Available anonymization types:

  • email
  • phone
  • name
  • dni
  • iban
  • swap (requires swap-list)

Iframe integration (postMessage)

Visual Mapper can run embedded inside an <iframe>. Communication is done through window.postMessage.

Incoming message (parent -> Visual Mapper)

The parent page can send this object after the iframe is loaded:

{
"openapi_yaml_in_base64": "<base64-encoded OpenAPI or JSON content>",
"apigen_type": "springboot",
"database": {
"credentials": {
"type": "POSTGRES",
"host": "localhost",
"port": "5432",
"name": "mydb",
"schema": "public",
"username": "admin"
},
"generated": {
"connection_id": "abc-123"
}
}
}
FieldRequiredDescription
openapi_yaml_in_base64YesOpenAPI content in YAML or JSON format, encoded in base64
apigen_typeNoTarget technology: python (default), springboot, dotnet
database.credentialsNoExisting database connection data used to prefill the connection form
database.credentials.typeNoDatabase type: POSTGRES, MYSQL, MARIADB, SQLSERVER, ORACLE
database.credentials.hostNoDatabase host
database.credentials.portNoDatabase port
database.credentials.nameNoDatabase name
database.credentials.schemaNoDatabase schema
database.credentials.usernameNoDatabase username
database.generatedNoModel field reserved for previously generated database sessions
database.generated.connection_idNoPreviously stored temporary connection identifier

What happens when the message is received

The current frontend implementation:

  • stores the iframe configuration in Vuex
  • extracts title, description, and version from the provided OpenAPI document
  • applies apigen_type to the target framework
  • prefills database connection fields from database.credentials
  • does not prefill the database password
  • auto-imports the OpenAPI definition once the connection and application data are ready

Important note about database.generated.connection_id

The data model includes database.generated.connection_id, and the original README describes an auto-connect flow for it. However, the current frontend code does not consume that value during iframe initialization. Treat it as part of the contract model, not as an implemented auto-reconnect feature in the present UI.

Parent page example

constiframe=document.getElementById('visual-mapper');iframe.contentWindow.postMessage({openapi_yaml_in_base64: btoa(yamlContent),apigen_type: 'springboot',database: {credentials: {type: 'POSTGRES',host: 'localhost',port: '5432',name: 'mydb',schema: 'public',username: 'admin'}}},'*');

Outgoing messages (Visual Mapper -> parent)

Temporary database created

Emitted when the user creates a temporary database from a SQL file:

{
"type": "connection-created",
"connection_id": "abc-123"
}

Example listener:

window.addEventListener('message',(event)=>{if(event.data?.type==='connection-created'){localStorage.setItem('vm_connection_id',event.data.connection_id);}});

Enriched OpenAPI / AsyncAPI document

Emitted when the user clicks Send to API Quality:

{
"type": "openapi-update",
"content_in_base64": "<base64-encoded enriched OpenAPI>"
}
{
"type": "asyncapi-update",
"content_in_base64": "<base64-encoded enriched AsyncAPI>"
}

Example decode logic:

window.addEventListener('message',(event)=>{if(event.data?.type==='openapi-update'){constyaml=decodeURIComponent(escape(atob(event.data.content_in_base64)));// use the enriched yaml}});

Code generation response passthrough

When Visual Mapper is embedded and the user triggers full or partial code generation, the frontend forwards the JSON payload returned by the generator backend directly to the parent window:

window.addEventListener('message',(event)=>{// event.data shape depends on the configured generator backendconsole.log(event.data);});

Because the payload is forwarded as-is from the backend response, its exact structure depends on the configured generator service and is not enforced by this frontend.

Security note

The current implementation sends messages with '*' as target origin. Parent applications should validate event.origin and event.data in their message listeners.

Docker

The repository includes:

  • a Dockerfile
  • an nginx.conf

The Docker image builds the Vue application and serves the static dist/ output with Nginx.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Visual Mapper

GitHub release (latest by date)LanguageFrameworkNode.js

Visual Mapper is a Vue 3 + TypeScript front-end for enriching OpenAPI or AsyncAPI definitions with x-apigen-* metadata, mapping API resources to relational database structures, and exporting the resulting specification back to a parent application or to downstream code-generation services.

What the application does

Visual Mapper helps you:

  • import an OpenAPI definition (.yaml, .yml, .json) or an AsyncAPI definition (.yaml, .yml)
  • connect to an existing database and inspect tables
  • create a temporary database from a SQL file
  • derive entities, controllers, relations, and validations from the connected schema
  • enrich the API definition with x-apigen-* extensions
  • preview or download the enriched OpenAPI / AsyncAPI document
  • optionally trigger archetype/code generation through configured Apigen backends
  • run embedded inside an iframe and exchange data with a parent application through window.postMessage

Tech stack

AreaDetails
FrameworkVue 3
LanguageTypeScript
StateVuex
RoutingVue Router
UIBootstrap 5 + bootstrap-vue-3
i18nvue-i18n
HTTPAxios
Build toolingVue CLI 5 / Webpack
TestingMocha + Chai via vue-cli-service test:unit

Requirements

  • Node.js >= 24.13.0
  • npm >= 8.3.0

Installation

npm install

Available scripts

CommandDescription
npm run serveStarts the local development server
npm run buildBuilds the production bundle into dist/
npm run lintRuns ESLint
npm run test:unitRuns the unit test suite

Environment configuration

The project uses .env files at the repository root. .env is loaded by default. Additional files such as .env.production or .env.<mode> can be used with Vue CLI modes.

The repository currently exposes generic scripts only. If you need a specific mode, use Vue CLI mode support directly, for example: npx vue-cli-service build --mode production.

Environment variables

VariableRequiredDescription
VUE_APP_ENVYesRuntime environment label, typically development or production
VUE_APP_PUBLIC_PATHYesBase public path used by Vue Router and static assets
VUE_APP_CONFIG_GEN_API_URLYesBase URL for the configuration generator backend
VUE_APP_PROJECT_GEN_API_URLYesBase URL for the project/archetype generator backend
VUE_APP_AUTH_URLIf OAuth is enabledOAuth 2 client credentials token endpoint
VUE_APP_AUTH_CLIENT_IDIf OAuth is enabledOAuth client ID
VUE_APP_AUTH_CLIENT_SECRETIf OAuth is enabledOAuth client secret
VUE_APP_REQUEST_RETRYNoRetry count used by project generation requests
VUE_APP_OAUTH_GENERATE_ACCESS_TOKENNo1 enables token retrieval and bearer token injection; 0 disables it
VUE_APP_CONFIG_GEN_STATUS_URLNoHealth/status URL for the configuration generator backend
VUE_APP_PROJECT_GEN_STATUS_URLNoHealth/status URL for the project generator backend
VUE_APP_WSO2_STATUS_URLNoOptional status URL shown in the footer connectivity modal
VUE_APP_APIGEN_DOTNET_URLNo.NET Apigen backend URL
VUE_APP_APIGEN_SPRINGBOOT_URLNoSpring Boot Apigen backend URL
VUE_APP_APIGEN_PYTHON_URLNoPython Apigen backend URL
VUE_APP_DB_EXPLORER_URLYes in productionDatabase Explorer backend URL
VUE_APP_API_KEYOptional, backend-dependentAPI key forwarded to the Database Explorer service
VUE_APP_DEBUG_PODSNoEnables round-robin requests between debug pod URLs when set to 1
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD1NoAlternate config generator URL for debug routing
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD2NoAlternate config generator URL for debug routing
PORTNoLocal development server port

Automatically injected build metadata

The application also injects these values at build time from package.json:

  • VUE_APP_VERSION
  • VUE_APP_NAME
  • VUE_APP_DESCRIPTION
  • VUE_COMPILATION_DATE

You normally do not define them manually.

Local development

npm run serve

The development server uses proxies defined in vue.config.js for:

  • /api-apigen-dotnet
  • /api-apigen-springboot
  • /api-apigen-python-dev
  • /db-explorer
  • /api-apiquality

Production build

npm run build

The output directory is dist/.

Real application workflow

In normal usage, the flow is:

  1. Fill in application metadata (name, description, version).
  2. Choose the target framework when running standalone.
  3. Connect to an existing database or create a temporary one from a SQL file.
  4. Import an OpenAPI or AsyncAPI definition, or receive it from a parent iframe host.
  5. Review generated resources/entities and adjust mappings.
  6. Preview or export the enriched specification.
  7. Optionally trigger archetype/code generation through a configured Apigen backend.

Database support

Connect to an existing database

The connection form supports these database types:

  • POSTGRES
  • ORACLE
  • MYSQL
  • SQLSERVER
  • MARIADB

Create a temporary database from SQL

The "create database" flow currently exposes:

  • POSTGRES
  • MYSQL

You can upload a .sql file, preview an ER diagram, or generate SQL from an already loaded OpenAPI document before creating the temporary database.

API definition import support

OpenAPI

  • Accepted formats: .yaml, .yml, .json
  • Extracts info.title, info.description, and info.version
  • Imports controllers/resources from the specification
  • If a database connection is active, it continues with the table/config import pipeline

AsyncAPI

  • Accepted formats: .yaml, .yml
  • Extracts info.title, info.description, and info.version
  • Extracts server names
  • Loads AsyncAPI controllers/entities locally before continuing with mapping

Supported Apigen technologies

Visual Mapper generates x-apigen-* extensions compatible with these target technologies:

ValueFrameworkNotes
pythonPython ApigenDefault value
springbootSpring Boot ApigenRequires group-id and artifact-id
dotnet.NET ApigenSupported by the backend integration layer

In the current standalone UI, the visible target framework selector exposes Python and Spring Boot. The iframe contract and backend service layer also recognize dotnet.

x-apigen-project differences by technology

Python / .NET

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysql

Spring Boot

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysqljava-properties:
group-id: com.exampleartifact-id: my-api

x-apigen-models

Generated from the database schema to describe the relational model:

x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Longrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: ownertype: Ownerrelational-persistence:
column: owner_id
- name: visitstype: Arrayitems-type: Visitrelational-persistence:
foreign-column: pet_id

x-tyk-anonymization

Marks response fields that should be anonymized by the Tyk gateway:

x-tyk-anonymization:
- field: emailtype: email
- field: phonetype: phone
- field: nametype: swapswap-list: names

Available anonymization types:

  • email
  • phone
  • name
  • dni
  • iban
  • swap (requires swap-list)

Iframe integration (postMessage)

Visual Mapper can run embedded inside an <iframe>. Communication is done through window.postMessage.

Incoming message (parent -> Visual Mapper)

The parent page can send this object after the iframe is loaded:

{
"openapi_yaml_in_base64": "<base64-encoded OpenAPI or JSON content>",
"apigen_type": "springboot",
"database": {
"credentials": {
"type": "POSTGRES",
"host": "localhost",
"port": "5432",
"name": "mydb",
"schema": "public",
"username": "admin"
},
"generated": {
"connection_id": "abc-123"
}
}
}
FieldRequiredDescription
openapi_yaml_in_base64YesOpenAPI content in YAML or JSON format, encoded in base64
apigen_typeNoTarget technology: python (default), springboot, dotnet
database.credentialsNoExisting database connection data used to prefill the connection form
database.credentials.typeNoDatabase type: POSTGRES, MYSQL, MARIADB, SQLSERVER, ORACLE
database.credentials.hostNoDatabase host
database.credentials.portNoDatabase port
database.credentials.nameNoDatabase name
database.credentials.schemaNoDatabase schema
database.credentials.usernameNoDatabase username
database.generatedNoModel field reserved for previously generated database sessions
database.generated.connection_idNoPreviously stored temporary connection identifier

What happens when the message is received

The current frontend implementation:

  • stores the iframe configuration in Vuex
  • extracts title, description, and version from the provided OpenAPI document
  • applies apigen_type to the target framework
  • prefills database connection fields from database.credentials
  • does not prefill the database password
  • auto-imports the OpenAPI definition once the connection and application data are ready

Important note about database.generated.connection_id

The data model includes database.generated.connection_id, and the original README describes an auto-connect flow for it. However, the current frontend code does not consume that value during iframe initialization. Treat it as part of the contract model, not as an implemented auto-reconnect feature in the present UI.

Parent page example

constiframe=document.getElementById('visual-mapper');iframe.contentWindow.postMessage({openapi_yaml_in_base64: btoa(yamlContent),apigen_type: 'springboot',database: {credentials: {type: 'POSTGRES',host: 'localhost',port: '5432',name: 'mydb',schema: 'public',username: 'admin'}}},'*');

Outgoing messages (Visual Mapper -> parent)

Temporary database created

Emitted when the user creates a temporary database from a SQL file:

{
"type": "connection-created",
"connection_id": "abc-123"
}

Example listener:

window.addEventListener('message',(event)=>{if(event.data?.type==='connection-created'){localStorage.setItem('vm_connection_id',event.data.connection_id);}});

Enriched OpenAPI / AsyncAPI document

Emitted when the user clicks Send to API Quality:

{
"type": "openapi-update",
"content_in_base64": "<base64-encoded enriched OpenAPI>"
}
{
"type": "asyncapi-update",
"content_in_base64": "<base64-encoded enriched AsyncAPI>"
}

Example decode logic:

window.addEventListener('message',(event)=>{if(event.data?.type==='openapi-update'){constyaml=decodeURIComponent(escape(atob(event.data.content_in_base64)));// use the enriched yaml}});

Code generation response passthrough

When Visual Mapper is embedded and the user triggers full or partial code generation, the frontend forwards the JSON payload returned by the generator backend directly to the parent window:

window.addEventListener('message',(event)=>{// event.data shape depends on the configured generator backendconsole.log(event.data);});

Because the payload is forwarded as-is from the backend response, its exact structure depends on the configured generator service and is not enforced by this frontend.

Security note

The current implementation sends messages with '*' as target origin. Parent applications should validate event.origin and event.data in their message listeners.

Docker

The repository includes:

  • a Dockerfile
  • an nginx.conf

The Docker image builds the Vue application and serves the static dist/ output with Nginx.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Visual Mapper

GitHub release (latest by date)LanguageFrameworkNode.js

Visual Mapper is a Vue 3 + TypeScript front-end for enriching OpenAPI or AsyncAPI definitions with x-apigen-* metadata, mapping API resources to relational database structures, and exporting the resulting specification back to a parent application or to downstream code-generation services.

What the application does

Visual Mapper helps you:

  • import an OpenAPI definition (.yaml, .yml, .json) or an AsyncAPI definition (.yaml, .yml)
  • connect to an existing database and inspect tables
  • create a temporary database from a SQL file
  • derive entities, controllers, relations, and validations from the connected schema
  • enrich the API definition with x-apigen-* extensions
  • preview or download the enriched OpenAPI / AsyncAPI document
  • optionally trigger archetype/code generation through configured Apigen backends
  • run embedded inside an iframe and exchange data with a parent application through window.postMessage

Tech stack

AreaDetails
FrameworkVue 3
LanguageTypeScript
StateVuex
RoutingVue Router
UIBootstrap 5 + bootstrap-vue-3
i18nvue-i18n
HTTPAxios
Build toolingVue CLI 5 / Webpack
TestingMocha + Chai via vue-cli-service test:unit

Requirements

  • Node.js >= 24.13.0
  • npm >= 8.3.0

Installation

npm install

Available scripts

CommandDescription
npm run serveStarts the local development server
npm run buildBuilds the production bundle into dist/
npm run lintRuns ESLint
npm run test:unitRuns the unit test suite

Environment configuration

The project uses .env files at the repository root. .env is loaded by default. Additional files such as .env.production or .env.<mode> can be used with Vue CLI modes.

The repository currently exposes generic scripts only. If you need a specific mode, use Vue CLI mode support directly, for example: npx vue-cli-service build --mode production.

Environment variables

VariableRequiredDescription
VUE_APP_ENVYesRuntime environment label, typically development or production
VUE_APP_PUBLIC_PATHYesBase public path used by Vue Router and static assets
VUE_APP_CONFIG_GEN_API_URLYesBase URL for the configuration generator backend
VUE_APP_PROJECT_GEN_API_URLYesBase URL for the project/archetype generator backend
VUE_APP_AUTH_URLIf OAuth is enabledOAuth 2 client credentials token endpoint
VUE_APP_AUTH_CLIENT_IDIf OAuth is enabledOAuth client ID
VUE_APP_AUTH_CLIENT_SECRETIf OAuth is enabledOAuth client secret
VUE_APP_REQUEST_RETRYNoRetry count used by project generation requests
VUE_APP_OAUTH_GENERATE_ACCESS_TOKENNo1 enables token retrieval and bearer token injection; 0 disables it
VUE_APP_CONFIG_GEN_STATUS_URLNoHealth/status URL for the configuration generator backend
VUE_APP_PROJECT_GEN_STATUS_URLNoHealth/status URL for the project generator backend
VUE_APP_WSO2_STATUS_URLNoOptional status URL shown in the footer connectivity modal
VUE_APP_APIGEN_DOTNET_URLNo.NET Apigen backend URL
VUE_APP_APIGEN_SPRINGBOOT_URLNoSpring Boot Apigen backend URL
VUE_APP_APIGEN_PYTHON_URLNoPython Apigen backend URL
VUE_APP_DB_EXPLORER_URLYes in productionDatabase Explorer backend URL
VUE_APP_API_KEYOptional, backend-dependentAPI key forwarded to the Database Explorer service
VUE_APP_DEBUG_PODSNoEnables round-robin requests between debug pod URLs when set to 1
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD1NoAlternate config generator URL for debug routing
VUE_APP_CONFIG_GEN_API_URL_DEBUG_POD2NoAlternate config generator URL for debug routing
PORTNoLocal development server port

Automatically injected build metadata

The application also injects these values at build time from package.json:

  • VUE_APP_VERSION
  • VUE_APP_NAME
  • VUE_APP_DESCRIPTION
  • VUE_COMPILATION_DATE

You normally do not define them manually.

Local development

npm run serve

The development server uses proxies defined in vue.config.js for:

  • /api-apigen-dotnet
  • /api-apigen-springboot
  • /api-apigen-python-dev
  • /db-explorer
  • /api-apiquality

Production build

npm run build

The output directory is dist/.

Real application workflow

In normal usage, the flow is:

  1. Fill in application metadata (name, description, version).
  2. Choose the target framework when running standalone.
  3. Connect to an existing database or create a temporary one from a SQL file.
  4. Import an OpenAPI or AsyncAPI definition, or receive it from a parent iframe host.
  5. Review generated resources/entities and adjust mappings.
  6. Preview or export the enriched specification.
  7. Optionally trigger archetype/code generation through a configured Apigen backend.

Database support

Connect to an existing database

The connection form supports these database types:

  • POSTGRES
  • ORACLE
  • MYSQL
  • SQLSERVER
  • MARIADB

Create a temporary database from SQL

The "create database" flow currently exposes:

  • POSTGRES
  • MYSQL

You can upload a .sql file, preview an ER diagram, or generate SQL from an already loaded OpenAPI document before creating the temporary database.

API definition import support

OpenAPI

  • Accepted formats: .yaml, .yml, .json
  • Extracts info.title, info.description, and info.version
  • Imports controllers/resources from the specification
  • If a database connection is active, it continues with the table/config import pipeline

AsyncAPI

  • Accepted formats: .yaml, .yml
  • Extracts info.title, info.description, and info.version
  • Extracts server names
  • Loads AsyncAPI controllers/entities locally before continuing with mapping

Supported Apigen technologies

Visual Mapper generates x-apigen-* extensions compatible with these target technologies:

ValueFrameworkNotes
pythonPython ApigenDefault value
springbootSpring Boot ApigenRequires group-id and artifact-id
dotnet.NET ApigenSupported by the backend integration layer

In the current standalone UI, the visible target framework selector exposes Python and Spring Boot. The iframe contract and backend service layer also recognize dotnet.

x-apigen-project differences by technology

Python / .NET

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysql

Spring Boot

x-apigen-project:
name: my-apidescription: My APIversion: 1.0.0data-driver: mysqljava-properties:
group-id: com.exampleartifact-id: my-api

x-apigen-models

Generated from the database schema to describe the relational model:

x-apigen-models:
Pet:
relational-persistence:
table: petsattributes:
- name: idtype: Longrelational-persistence:
primary-key: trueautogenerated: true
- name: nametype: String
- name: ownertype: Ownerrelational-persistence:
column: owner_id
- name: visitstype: Arrayitems-type: Visitrelational-persistence:
foreign-column: pet_id

x-tyk-anonymization

Marks response fields that should be anonymized by the Tyk gateway:

x-tyk-anonymization:
- field: emailtype: email
- field: phonetype: phone
- field: nametype: swapswap-list: names

Available anonymization types:

  • email
  • phone
  • name
  • dni
  • iban
  • swap (requires swap-list)

Iframe integration (postMessage)

Visual Mapper can run embedded inside an <iframe>. Communication is done through window.postMessage.

Incoming message (parent -> Visual Mapper)

The parent page can send this object after the iframe is loaded:

{
"openapi_yaml_in_base64": "<base64-encoded OpenAPI or JSON content>",
"apigen_type": "springboot",
"database": {
"credentials": {
"type": "POSTGRES",
"host": "localhost",
"port": "5432",
"name": "mydb",
"schema": "public",
"username": "admin"
},
"generated": {
"connection_id": "abc-123"
}
}
}
FieldRequiredDescription
openapi_yaml_in_base64YesOpenAPI content in YAML or JSON format, encoded in base64
apigen_typeNoTarget technology: python (default), springboot, dotnet
database.credentialsNoExisting database connection data used to prefill the connection form
database.credentials.typeNoDatabase type: POSTGRES, MYSQL, MARIADB, SQLSERVER, ORACLE
database.credentials.hostNoDatabase host
database.credentials.portNoDatabase port
database.credentials.nameNoDatabase name
database.credentials.schemaNoDatabase schema
database.credentials.usernameNoDatabase username
database.generatedNoModel field reserved for previously generated database sessions
database.generated.connection_idNoPreviously stored temporary connection identifier

What happens when the message is received

The current frontend implementation:

  • stores the iframe configuration in Vuex
  • extracts title, description, and version from the provided OpenAPI document
  • applies apigen_type to the target framework
  • prefills database connection fields from database.credentials
  • does not prefill the database password
  • auto-imports the OpenAPI definition once the connection and application data are ready

Important note about database.generated.connection_id

The data model includes database.generated.connection_id, and the original README describes an auto-connect flow for it. However, the current frontend code does not consume that value during iframe initialization. Treat it as part of the contract model, not as an implemented auto-reconnect feature in the present UI.

Parent page example

constiframe=document.getElementById('visual-mapper');iframe.contentWindow.postMessage({openapi_yaml_in_base64: btoa(yamlContent),apigen_type: 'springboot',database: {credentials: {type: 'POSTGRES',host: 'localhost',port: '5432',name: 'mydb',schema: 'public',username: 'admin'}}},'*');

Outgoing messages (Visual Mapper -> parent)

Temporary database created

Emitted when the user creates a temporary database from a SQL file:

{
"type": "connection-created",
"connection_id": "abc-123"
}

Example listener:

window.addEventListener('message',(event)=>{if(event.data?.type==='connection-created'){localStorage.setItem('vm_connection_id',event.data.connection_id);}});

Enriched OpenAPI / AsyncAPI document

Emitted when the user clicks Send to API Quality:

{
"type": "openapi-update",
"content_in_base64": "<base64-encoded enriched OpenAPI>"
}
{
"type": "asyncapi-update",
"content_in_base64": "<base64-encoded enriched AsyncAPI>"
}

Example decode logic:

window.addEventListener('message',(event)=>{if(event.data?.type==='openapi-update'){constyaml=decodeURIComponent(escape(atob(event.data.content_in_base64)));// use the enriched yaml}});

Code generation response passthrough

When Visual Mapper is embedded and the user triggers full or partial code generation, the frontend forwards the JSON payload returned by the generator backend directly to the parent window:

window.addEventListener('message',(event)=>{// event.data shape depends on the configured generator backendconsole.log(event.data);});

Because the payload is forwarded as-is from the backend response, its exact structure depends on the configured generator service and is not enforced by this frontend.

Security note

The current implementation sends messages with '*' as target origin. Parent applications should validate event.origin and event.data in their message listeners.

Docker

The repository includes:

  • a Dockerfile
  • an nginx.conf

The Docker image builds the Vue application and serves the static dist/ output with Nginx.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages