From 7b01a65a4968c37f2dae4ead29314319fe997a3d Mon Sep 17 00:00:00 2001 From: ManuelGil Date: Tue, 14 Jan 2025 23:41:38 -0500 Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20add=20transform=20controlle?= =?UTF-8?q?r=20and=20enhance=20localization=20for=20conversion=20features?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 892 ++++++++++---------- package.nls.de.json | 2 + package.nls.es.json | 2 + package.nls.fr.json | 2 + package.nls.it.json | 2 + package.nls.json | 2 + package.nls.pt-br.json | 2 + src/app/controllers/files.controller.ts | 149 +--- src/app/controllers/index.ts | 1 + src/app/controllers/transform.controller.ts | 462 ++++++++++ src/app/helpers/json.helper.ts | 2 - src/extension.ts | 181 +++- 12 files changed, 1086 insertions(+), 613 deletions(-) create mode 100644 src/app/controllers/transform.controller.ts diff --git a/package.json b/package.json index 8a46d37..178bbb8 100644 --- a/package.json +++ b/package.json @@ -1,429 +1,467 @@ { - "name": "vscode-json-flow", - "displayName": "JSON Flow", - "description": "Transform JSON into interactive graphs in VSCode - Free & Open Source", - "version": "1.11.0", - "icon": "icon.png", - "license": "MIT", - "publisher": "imgildev", - "author": { - "name": "Manuel Gil", - "email": "support@imgil.dev", - "url": "https://imgil.dev/" - }, - "sponsor": { - "url": "https://github.com/sponsors/manuelgil" - }, - "engines": { - "vscode": "^1.88.0" - }, - "categories": [ - "Other" - ], - "keywords": [ - "cfg", - "csv", - "data", - "dotenv", - "env", - "explorer", - "fileview", - "flow view", - "flow", - "flowview", - "graph view", - "graph", - "graphview", - "hcl", - "ini", - "json flow", - "json schema", - "json view", - "json-flow", - "json-schema", - "json-xml", - "json", - "json5", - "jsonc", - "jsonflow", - "jsonschema", - "jsonview", - "live preview", - "manager", - "node", - "nodes", - "preview", - "properties", - "schema", - "toml", - "tree", - "treeview", - "tsv", - "view", - "visualizer", - "vscode-extension", - "vscode-json-flow", - "vscode", - "xml", - "yaml", - "yml" - ], - "homepage": "https://github.com/ManuelGil/vscode-json-flow", - "repository": { - "type": "git", - "url": "https://github.com/ManuelGil/vscode-json-flow" - }, - "bugs": { - "url": "https://github.com/ManuelGil/vscode-json-flow/issues" - }, - "activationEvents": [], - "main": "./out/extension.js", - "l10n": "./l10n", - "contributes": { - "configuration": { - "title": "JSON Flow", - "properties": { - "jsonFlow.enable": { - "type": "boolean", - "default": true, - "scope": "resource", - "description": "%jsonFlow.enable%" - }, - "jsonFlow.files.include": { - "type": "array", - "default": [ - "json", - "jsonc", - "json5", - "cfg", - "csv", - "env", - "hcl", - "ini", - "properties", - "toml", - "tsv", - "xml", - "yaml", - "yml" - ], - "scope": "resource", - "description": "%jsonFlow.files.include%" - }, - "jsonFlow.files.exclude": { - "type": "array", - "default": [ - "**/node_modules/**", - "**/dist/**", - "**/out/**", - "**/build/**", - "**/vendor/**" - ], - "scope": "resource", - "description": "%jsonFlow.files.exclude%" - }, - "jsonFlow.files.showPath": { - "type": "boolean", - "default": true, - "scope": "resource", - "description": "%jsonFlow.files.showPath%" - }, - "jsonFlow.graph.showValues": { - "type": "boolean", - "default": true, - "scope": "resource", - "description": "%jsonFlow.graph.showValues%" - }, - "jsonFlow.graph.nodeWidth": { - "type": "number", - "default": 200, - "scope": "resource", - "description": "%jsonFlow.graph.nodeWidth%" - }, - "jsonFlow.graph.nodeHeight": { - "type": "number", - "default": 50, - "scope": "resource", - "description": "%jsonFlow.graph.nodeHeight%" - }, - "jsonFlow.graph.nodeBorderColor": { - "type": "string", - "default": "white", - "scope": "resource", - "description": "%jsonFlow.graph.nodeBorderColor%" - }, - "jsonFlow.graph.nodeColor": { - "type": "string", - "default": "white", - "scope": "resource", - "description": "%jsonFlow.graph.nodeColor%" - }, - "jsonFlow.graph.edgeColor": { - "type": "string", - "default": "white", - "scope": "resource", - "description": "%jsonFlow.graph.edgeColor%" - }, - "jsonFlow.graph.layoutDirection": { - "type": "string", - "default": "TB", - "enum": [ - "TB", - "LR" - ], - "scope": "resource", - "description": "%jsonFlow.graph.layoutDirection%" - }, - "jsonFlow.image.folder": { - "type": "string", - "default": "json-flow/images", - "scope": "resource", - "description": "%jsonFlow.image.folder%" - } - } - }, - "commands": [ - { - "command": "jsonFlow.files.refreshList", - "title": "%jsonFlow.files.refreshList%", - "category": "JSON Flow", - "icon": "$(refresh)" - }, - { - "command": "jsonFlow.files.openFile", - "title": "%jsonFlow.files.openFile%", - "category": "JSON Flow" - }, - { - "command": "jsonFlow.files.convertToJson", - "title": "%jsonFlow.files.convertToJson%", - "category": "JSON Flow" - }, - { - "command": "jsonFlow.files.convertPartialToJson", - "title": "%jsonFlow.files.convertPartialToJson%", - "category": "JSON Flow" - }, - { - "command": "jsonFlow.files.copyContent", - "title": "%jsonFlow.files.copyContent%", - "category": "JSON Flow" - }, - { - "command": "jsonFlow.files.copyContentAsJson", - "title": "%jsonFlow.files.copyContentAsJson%", - "category": "JSON Flow" - }, - { - "command": "jsonFlow.files.copyContentPartialAsJson", - "title": "%jsonFlow.files.copyContentPartialAsJson%", - "category": "JSON Flow" - }, - { - "command": "jsonFlow.files.getFileProperties", - "title": "%jsonFlow.files.getFileProperties%", - "category": "JSON Flow" - }, - { - "command": "jsonFlow.json.showPartialPreview", - "title": "%jsonFlow.json.showPartialPreview%", - "category": "JSON Flow" - }, - { - "command": "jsonFlow.json.showPreview", - "title": "%jsonFlow.json.showPreview%", - "category": "JSON Flow" - } - ], - "submenus": [ - { - "id": "jsonFlow.explorer.submenu", - "label": "JSON Flow" - }, - { - "id": "jsonFlow.editor.submenu", - "label": "JSON Flow" - } - ], - "menus": { - "view/title": [ - { - "command": "jsonFlow.files.refreshList", - "when": "view == jsonFlow.filesView", - "group": "navigation" - } - ], - "view/item/context": [ - { - "command": "jsonFlow.files.openFile", - "when": "view == jsonFlow.filesView && viewItem == file", - "group": "1_navigation" - }, - { - "command": "jsonFlow.files.convertToJson", - "when": "view == jsonFlow.filesView && viewItem == file", - "group": "2_modification" - }, - { - "command": "jsonFlow.files.copyContent", - "when": "view == jsonFlow.filesView && viewItem == file", - "group": "3_cutcopypaste@1" - }, - { - "command": "jsonFlow.files.copyContentAsJson", - "when": "view == jsonFlow.filesView && viewItem == file", - "group": "3_cutcopypaste@2" - }, - { - "command": "jsonFlow.files.getFileProperties", - "when": "view == jsonFlow.filesView && viewItem == file", - "group": "4_properties" - } - ], - "explorer/context": [ - { - "submenu": "jsonFlow.explorer.submenu", - "group": "2_workspace", - "when": "resourceExtname =~ /json|jsonc|json5|cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml/" - } - ], - "editor/context": [ - { - "submenu": "jsonFlow.editor.submenu", - "group": "1_modification", - "when": "editorHasSelection" - } - ], - "jsonFlow.explorer.submenu": [ - { - "command": "jsonFlow.json.showPreview", - "title": "%jsonFlow.json.showPreview%", - "group": "1_navigation" - }, - { - "command": "jsonFlow.files.convertToJson", - "title": "%jsonFlow.files.convertToJson%", - "group": "2_modification" - }, - { - "command": "jsonFlow.files.copyContentAsJson", - "title": "%jsonFlow.files.copyContentAsJson%", - "group": "3_cutcopypaste" - } - ], - "jsonFlow.editor.submenu": [ - { - "command": "jsonFlow.json.showPartialPreview", - "title": "%jsonFlow.json.showPartialPreview%", - "group": "1_view" - }, - { - "command": "jsonFlow.files.convertPartialToJson", - "title": "%jsonFlow.files.convertPartialToJson%", - "group": "2_modification" - }, - { - "command": "jsonFlow.files.copyContentPartialAsJson", - "title": "%jsonFlow.files.copyContentPartialAsJson%", - "group": "3_cutcopypaste" - } - ] - }, - "viewsWelcome": [ - { - "view": "jsonFlow.filesView", - "contents": "%viewsWelcome.jsonFlow.filesView%" - } - ], - "viewsContainers": { - "activitybar": [ - { - "id": "json-explorer", - "title": "JSON Flow", - "icon": "./assets/logo.svg" - } - ] - }, - "views": { - "json-explorer": [ - { - "id": "jsonFlow.filesView", - "name": "%jsonFlow.filesView%", - "visibility": "visible" - }, - { - "id": "jsonFlow.feedbackView", - "name": "%jsonFlow.feedbackView%", - "visibility": "visible" - } - ] - }, - "jsonValidation": [ - { - "fileMatch": ".vscode/settings.json", - "url": "./schemas/config.schema.json" - } - ] - }, - "scripts": { - "vscode:prepublish": "npm run build && npm run compile", - "compile": "rimraf out && tsc -p ./ && cpy dist/* out/webview", - "watch": "tsc -watch -p ./", - "pretest": "npm run compile && npm run lint", - "dev": "vite", - "build": "tsc --p ./tsconfig.web.json && vite build", - "preview": "vite preview", - "format": "biome format --write", - "lint": "biome lint --write", - "lint:check": "biome check --write", - "test": "vscode-test", - "compodoc": "npx compodoc -p tsconfig.doc.json -d compodoc --theme readthedocs -s", - "prepare": "husky", - "release": "release-it" - }, - "dependencies": { - "@vscode/webview-ui-toolkit": "^1.4.0", - "@xyflow/react": "^12.3.4", - "dotenv": "^16.4.5", - "entitree-flex": "^0.4.1", - "fast-glob": "^3.3.2", - "fast-xml-parser": "^4.5.0", - "hcl-parser": "^0.1.1", - "html-to-image": "^1.11.11", - "ini": "^5.0.0", - "json5": "^2.2.3", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "toml": "^3.0.0", - "yaml": "^2.6.0" - }, - "devDependencies": { - "@biomejs/biome": "1.9.4", - "@commitlint/cli": "^19.5.0", - "@commitlint/config-conventional": "^19.5.0", - "@compodoc/compodoc": "^1.1.26", - "@types/mocha": "^10.0.10", - "@types/node": "^22.10.5", - "@types/react": "^18.3.12", - "@types/react-dom": "^18.3.1", - "@types/vscode": "^1.88.0", - "@typescript-eslint/eslint-plugin": "^8.17.0", - "@typescript-eslint/parser": "^8.17.0", - "@vitejs/plugin-react": "^4.3.3", - "@vscode/l10n-dev": "^0.0.35", - "@vscode/test-cli": "^0.0.10", - "@vscode/test-electron": "^2.4.1", - "autoprefixer": "^10.4.20", - "cpy-cli": "^5.0.0", - "eslint": "^9.16.0", - "husky": "^9.1.6", - "lint-staged": "^15.2.10", - "postcss": "^8.4.47", - "release-it": "^18.1.1", - "rimraf": "^6.0.1", - "tailwindcss": "^3.4.14", - "typescript": "^5.7.2", - "vite": "^5.4.10", - "vscode-test": "^1.6.1" - } + "name": "vscode-json-flow", + "displayName": "JSON Flow", + "description": "Transform JSON into interactive graphs in VSCode - Free & Open Source", + "version": "1.11.0", + "icon": "icon.png", + "license": "MIT", + "publisher": "imgildev", + "author": { + "name": "Manuel Gil", + "email": "support@imgil.dev", + "url": "https://imgil.dev/" + }, + "sponsor": { + "url": "https://github.com/sponsors/manuelgil" + }, + "engines": { + "vscode": "^1.88.0" + }, + "categories": [ + "Other" + ], + "keywords": [ + "cfg", + "csv", + "data", + "dotenv", + "env", + "explorer", + "fileview", + "flow view", + "flow", + "flowview", + "graph view", + "graph", + "graphview", + "hcl", + "ini", + "json flow", + "json schema", + "json view", + "json-flow", + "json-schema", + "json-xml", + "json", + "json5", + "jsonc", + "jsonflow", + "jsonschema", + "jsonview", + "live preview", + "manager", + "node", + "nodes", + "preview", + "properties", + "schema", + "toml", + "tree", + "treeview", + "tsv", + "view", + "visualizer", + "vscode-extension", + "vscode-json-flow", + "vscode", + "xml", + "yaml", + "yml" + ], + "homepage": "https://github.com/ManuelGil/vscode-json-flow", + "repository": { + "type": "git", + "url": "https://github.com/ManuelGil/vscode-json-flow" + }, + "bugs": { + "url": "https://github.com/ManuelGil/vscode-json-flow/issues" + }, + "activationEvents": [], + "main": "./out/extension.js", + "l10n": "./l10n", + "contributes": { + "configuration": { + "title": "JSON Flow", + "properties": { + "jsonFlow.enable": { + "type": "boolean", + "default": true, + "scope": "resource", + "description": "%jsonFlow.enable%" + }, + "jsonFlow.files.include": { + "type": "array", + "default": [ + "json", + "jsonc", + "json5", + "cfg", + "csv", + "env", + "hcl", + "ini", + "properties", + "toml", + "tsv", + "xml", + "yaml", + "yml" + ], + "scope": "resource", + "description": "%jsonFlow.files.include%" + }, + "jsonFlow.files.exclude": { + "type": "array", + "default": [ + "**/node_modules/**", + "**/dist/**", + "**/out/**", + "**/build/**", + "**/vendor/**" + ], + "scope": "resource", + "description": "%jsonFlow.files.exclude%" + }, + "jsonFlow.files.showPath": { + "type": "boolean", + "default": true, + "scope": "resource", + "description": "%jsonFlow.files.showPath%" + }, + "jsonFlow.graph.showValues": { + "type": "boolean", + "default": true, + "scope": "resource", + "description": "%jsonFlow.graph.showValues%" + }, + "jsonFlow.graph.nodeWidth": { + "type": "number", + "default": 200, + "scope": "resource", + "description": "%jsonFlow.graph.nodeWidth%" + }, + "jsonFlow.graph.nodeHeight": { + "type": "number", + "default": 50, + "scope": "resource", + "description": "%jsonFlow.graph.nodeHeight%" + }, + "jsonFlow.graph.nodeBorderColor": { + "type": "string", + "default": "white", + "scope": "resource", + "description": "%jsonFlow.graph.nodeBorderColor%" + }, + "jsonFlow.graph.nodeColor": { + "type": "string", + "default": "white", + "scope": "resource", + "description": "%jsonFlow.graph.nodeColor%" + }, + "jsonFlow.graph.edgeColor": { + "type": "string", + "default": "white", + "scope": "resource", + "description": "%jsonFlow.graph.edgeColor%" + }, + "jsonFlow.graph.layoutDirection": { + "type": "string", + "default": "TB", + "enum": [ + "TB", + "LR" + ], + "scope": "resource", + "description": "%jsonFlow.graph.layoutDirection%" + }, + "jsonFlow.image.folder": { + "type": "string", + "default": "json-flow/images", + "scope": "resource", + "description": "%jsonFlow.image.folder%" + } + } + }, + "commands": [ + { + "command": "jsonFlow.files.refreshList", + "title": "%jsonFlow.files.refreshList%", + "category": "JSON Flow", + "icon": "$(refresh)" + }, + { + "command": "jsonFlow.files.openFile", + "title": "%jsonFlow.files.openFile%", + "category": "JSON Flow" + }, + { + "command": "jsonFlow.files.copyContent", + "title": "%jsonFlow.files.copyContent%", + "category": "JSON Flow" + }, + { + "command": "jsonFlow.files.copyContentAsJson", + "title": "%jsonFlow.files.copyContentAsJson%", + "category": "JSON Flow" + }, + { + "command": "jsonFlow.files.copyContentPartialAsJson", + "title": "%jsonFlow.files.copyContentPartialAsJson%", + "category": "JSON Flow" + }, + { + "command": "jsonFlow.files.getFileProperties", + "title": "%jsonFlow.files.getFileProperties%", + "category": "JSON Flow" + }, + { + "command": "jsonFlow.json.showPartialPreview", + "title": "%jsonFlow.json.showPartialPreview%", + "category": "JSON Flow" + }, + { + "command": "jsonFlow.json.showPreview", + "title": "%jsonFlow.json.showPreview%", + "category": "JSON Flow" + }, + { + "command": "jsonFlow.files.convertToJson", + "title": "%jsonFlow.files.convertToJson%", + "category": "JSON Flow" + }, + { + "command": "jsonFlow.files.convertPartialToJson", + "title": "%jsonFlow.files.convertPartialToJson%", + "category": "JSON Flow" + }, + { + "command": "jsonFlow.files.convertToType", + "title": "%jsonFlow.files.convertToType%", + "category": "JSON Flow" + }, + { + "command": "jsonFlow.files.convertPartialToType", + "title": "%jsonFlow.files.convertPartialToType%", + "category": "JSON Flow" + } + ], + "submenus": [ + { + "id": "jsonFlow.explorer.submenu", + "label": "JSON Flow" + }, + { + "id": "jsonFlow.editor.submenu", + "label": "JSON Flow" + } + ], + "menus": { + "view/title": [ + { + "command": "jsonFlow.files.refreshList", + "when": "view == jsonFlow.filesView", + "group": "navigation" + } + ], + "view/item/context": [ + { + "command": "jsonFlow.files.openFile", + "when": "view == jsonFlow.filesView && viewItem =~ /.(json|jsonc|json5|cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml)/", + "group": "1_navigation" + }, + { + "command": "jsonFlow.files.convertToJson", + "when": "view == jsonFlow.filesView && viewItem =~ /.(cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml)/", + "group": "2_modification" + }, + { + "command": "jsonFlow.files.convertToType", + "when": "view == jsonFlow.filesView && viewItem =~ /.(json|jsonc|json5|cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml)/", + "group": "2_modification" + }, + { + "command": "jsonFlow.files.copyContent", + "when": "view == jsonFlow.filesView && viewItem =~ /.(json|jsonc|json5|cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml)/", + "group": "3_cutcopypaste@1" + }, + { + "command": "jsonFlow.files.copyContentAsJson", + "when": "view == jsonFlow.filesView && viewItem =~ /.(cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml)/", + "group": "3_cutcopypaste@2" + }, + { + "command": "jsonFlow.files.getFileProperties", + "when": "view == jsonFlow.filesView && viewItem =~ /.(json|jsonc|json5|cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml)/", + "group": "4_properties" + } + ], + "explorer/context": [ + { + "submenu": "jsonFlow.explorer.submenu", + "group": "2_workspace", + "when": "resourceExtname =~ /json|jsonc|json5|cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml/" + } + ], + "editor/context": [ + { + "submenu": "jsonFlow.editor.submenu", + "group": "1_modification", + "when": "editorHasSelection" + } + ], + "jsonFlow.explorer.submenu": [ + { + "command": "jsonFlow.json.showPreview", + "title": "%jsonFlow.json.showPreview%", + "group": "1_navigation" + }, + { + "command": "jsonFlow.files.convertToJson", + "title": "%jsonFlow.files.convertToJson%", + "when": "resourceExtname =~ /cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml/", + "group": "2_modification" + }, + { + "command": "jsonFlow.files.convertToType", + "title": "%jsonFlow.files.convertToType%", + "when": "resourceExtname =~ /json|jsonc|json5|cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml/", + "group": "2_modification" + }, + { + "command": "jsonFlow.files.copyContent", + "title": "%jsonFlow.files.copyContent%", + "when": "resourceExtname =~ /json|jsonc|json5|cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml/", + "group": "3_cutcopypaste" + }, + { + "command": "jsonFlow.files.copyContentAsJson", + "title": "%jsonFlow.files.copyContentAsJson%", + "when": "resourceExtname =~ /cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml/", + "group": "3_cutcopypaste" + } + ], + "jsonFlow.editor.submenu": [ + { + "command": "jsonFlow.json.showPartialPreview", + "title": "%jsonFlow.json.showPartialPreview%", + "group": "1_view" + }, + { + "command": "jsonFlow.files.convertPartialToJson", + "title": "%jsonFlow.files.convertPartialToJson%", + "when": "resourceExtname =~ /cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml/", + "group": "2_modification" + }, + { + "command": "jsonFlow.files.convertPartialToType", + "title": "%jsonFlow.files.convertPartialToType%", + "when": "resourceExtname =~ /json|jsonc|json5|cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml/", + "group": "2_modification" + }, + { + "command": "jsonFlow.files.copyContentPartialAsJson", + "title": "%jsonFlow.files.copyContentPartialAsJson%", + "when": "resourceExtname =~ /cfg|csv|env|hcl|ini|properties|toml|tsv|xml|yaml|yml/", + "group": "3_cutcopypaste" + } + ] + }, + "viewsWelcome": [ + { + "view": "jsonFlow.filesView", + "contents": "%viewsWelcome.jsonFlow.filesView%" + } + ], + "viewsContainers": { + "activitybar": [ + { + "id": "json-explorer", + "title": "JSON Flow", + "icon": "./assets/logo.svg" + } + ] + }, + "views": { + "json-explorer": [ + { + "id": "jsonFlow.filesView", + "name": "%jsonFlow.filesView%", + "visibility": "visible" + }, + { + "id": "jsonFlow.feedbackView", + "name": "%jsonFlow.feedbackView%", + "visibility": "visible" + } + ] + }, + "jsonValidation": [ + { + "fileMatch": ".vscode/settings.json", + "url": "./schemas/config.schema.json" + } + ] + }, + "scripts": { + "vscode:prepublish": "npm run build && npm run compile", + "compile": "rimraf out && tsc -p ./ && cpy dist/* out/webview", + "watch": "tsc -watch -p ./", + "pretest": "npm run compile && npm run lint", + "dev": "vite", + "build": "tsc --p ./tsconfig.web.json && vite build", + "preview": "vite preview", + "format": "biome format --write", + "lint": "biome lint --write", + "lint:check": "biome check --write", + "test": "vscode-test", + "compodoc": "npx compodoc -p tsconfig.doc.json -d compodoc --theme readthedocs -s", + "prepare": "husky", + "release": "release-it" + }, + "dependencies": { + "@vscode/webview-ui-toolkit": "^1.4.0", + "@xyflow/react": "^12.3.4", + "dotenv": "^16.4.5", + "entitree-flex": "^0.4.1", + "fast-glob": "^3.3.2", + "fast-xml-parser": "^4.5.0", + "hcl-parser": "^0.1.1", + "html-to-image": "^1.11.11", + "ini": "^5.0.0", + "json5": "^2.2.3", + "quicktype-core": "^23.0.170", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "toml": "^3.0.0", + "yaml": "^2.6.0" + }, + "devDependencies": { + "@biomejs/biome": "1.9.4", + "@commitlint/cli": "^19.5.0", + "@commitlint/config-conventional": "^19.5.0", + "@compodoc/compodoc": "^1.1.26", + "@types/mocha": "^10.0.10", + "@types/node": "^22.10.5", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@types/vscode": "^1.88.0", + "@typescript-eslint/eslint-plugin": "^8.17.0", + "@typescript-eslint/parser": "^8.17.0", + "@vitejs/plugin-react": "^4.3.3", + "@vscode/l10n-dev": "^0.0.35", + "@vscode/test-cli": "^0.0.10", + "@vscode/test-electron": "^2.4.1", + "autoprefixer": "^10.4.20", + "cpy-cli": "^5.0.0", + "eslint": "^9.16.0", + "husky": "^9.1.6", + "lint-staged": "^15.2.10", + "postcss": "^8.4.47", + "release-it": "^18.1.1", + "rimraf": "^6.0.1", + "tailwindcss": "^3.4.14", + "typescript": "^5.7.2", + "vite": "^5.4.10", + "vscode-test": "^1.6.1" + } } diff --git a/package.nls.de.json b/package.nls.de.json index 488ac2d..b09c16f 100644 --- a/package.nls.de.json +++ b/package.nls.de.json @@ -15,6 +15,8 @@ "jsonFlow.files.openFile": "Datei öffnen", "jsonFlow.files.convertToJson": "In JSON konvertieren", "jsonFlow.files.convertPartialToJson": "Auswahl in JSON konvertieren", + "jsonFlow.files.convertToType": "In Typ oder Struktur umwandeln", + "jsonFlow.files.convertPartialToType": "Auswahl in Typ oder Struktur umwandeln", "jsonFlow.files.copyContent": "Inhalt in Zwischenablage kopieren", "jsonFlow.files.copyContentAsJson": "Inhalt als JSON kopieren", "jsonFlow.files.copyContentPartialAsJson": "Auswahl als JSON kopieren", diff --git a/package.nls.es.json b/package.nls.es.json index e84ead0..3943786 100644 --- a/package.nls.es.json +++ b/package.nls.es.json @@ -15,6 +15,8 @@ "jsonFlow.files.openFile": "Abrir Archivo", "jsonFlow.files.convertToJson": "Convertir a JSON", "jsonFlow.files.convertPartialToJson": "Convertir Selección a JSON", + "jsonFlow.files.convertToType": "Convertir a Tipo o Estructura", + "jsonFlow.files.convertPartialToType": "Convertir Selección a Tipo o Estructura", "jsonFlow.files.copyContent": "Copiar Contenido al Portapapeles", "jsonFlow.files.copyContentAsJson": "Copiar Contenido como JSON", "jsonFlow.files.copyContentPartialAsJson": "Copiar Selección como JSON", diff --git a/package.nls.fr.json b/package.nls.fr.json index 11ea443..e7e8d30 100644 --- a/package.nls.fr.json +++ b/package.nls.fr.json @@ -15,6 +15,8 @@ "jsonFlow.files.openFile": "Ouvrir le fichier", "jsonFlow.files.convertToJson": "Convertir en JSON", "jsonFlow.files.convertPartialToJson": "Convertir la sélection en JSON", + "jsonFlow.files.convertToType": "Convertir en type ou structure", + "jsonFlow.files.convertPartialToType": "Convertir la sélection en type ou structure", "jsonFlow.files.copyContent": "Copier le contenu dans le presse-papiers", "jsonFlow.files.copyContentAsJson": "Copier le contenu en tant que JSON", "jsonFlow.files.copyContentPartialAsJson": "Copier la sélection en tant que JSON", diff --git a/package.nls.it.json b/package.nls.it.json index 0715d93..2b5cc04 100644 --- a/package.nls.it.json +++ b/package.nls.it.json @@ -15,6 +15,8 @@ "jsonFlow.files.openFile": "Apri File", "jsonFlow.files.convertToJson": "Converti in JSON", "jsonFlow.files.convertPartialToJson": "Converti Selezione in JSON", + "jsonFlow.files.convertToType": "Converti in Tipo o Struttura", + "jsonFlow.files.convertPartialToType": "Converti Selezione in Tipo o Struttura", "jsonFlow.files.copyContent": "Copia Contenuto negli Appunti", "jsonFlow.files.copyContentAsJson": "Copia Contenuto come JSON", "jsonFlow.files.copyContentPartialAsJson": "Copia Selezione come JSON", diff --git a/package.nls.json b/package.nls.json index 8e3342c..e355fe7 100644 --- a/package.nls.json +++ b/package.nls.json @@ -15,6 +15,8 @@ "jsonFlow.files.openFile": "Open File", "jsonFlow.files.convertToJson": "Convert to JSON", "jsonFlow.files.convertPartialToJson": "Convert Selection to JSON", + "jsonFlow.files.convertToType": "Convert to Type or Structure", + "jsonFlow.files.convertPartialToType": "Convert Selection to Type or Structure", "jsonFlow.files.copyContent": "Copy Content to Clipboard", "jsonFlow.files.copyContentAsJson": "Copy Content as JSON", "jsonFlow.files.copyContentPartialAsJson": "Copy Selection as JSON", diff --git a/package.nls.pt-br.json b/package.nls.pt-br.json index 7c38e1c..fbe93eb 100644 --- a/package.nls.pt-br.json +++ b/package.nls.pt-br.json @@ -15,6 +15,8 @@ "jsonFlow.files.openFile": "Abrir Arquivo", "jsonFlow.files.convertToJson": "Converter para JSON", "jsonFlow.files.convertPartialToJson": "Converter Seleção para JSON", + "jsonFlow.files.convertToType": "Converter para Tipo ou Estrutura", + "jsonFlow.files.convertPartialToType": "Converter Seleção para Tipo ou Estrutura", "jsonFlow.files.copyContent": "Copiar Conteúdo para a Área de Transferência", "jsonFlow.files.copyContentAsJson": "Copiar Conteúdo como JSON", "jsonFlow.files.copyContentPartialAsJson": "Copiar Seleção como JSON", diff --git a/src/app/controllers/files.controller.ts b/src/app/controllers/files.controller.ts index 825c2b9..4cb0092 100644 --- a/src/app/controllers/files.controller.ts +++ b/src/app/controllers/files.controller.ts @@ -101,7 +101,7 @@ export class FilesController { arguments: [document.uri], }, document.uri, - 'file', + document.fileName, ), ); } @@ -132,153 +132,6 @@ export class FilesController { } } - /** - * The convertToJson method. - * - * @function convertToJson - * @param {NodeModel | Uri} node - The node model - * @public - * @memberof FilesController - * @example - * controller.convertToJson('file:///path/to/file'); - * - * @returns {void} - The promise - */ - convertToJson(node: NodeModel | Uri) { - if (node) { - // Get the resource URI - const resourceUri = node instanceof NodeModel ? node.resourceUri : node; - - // Check if the resource URI is valid - if (!resourceUri) { - return; - } - - // Open the text document - workspace.openTextDocument(resourceUri).then(async (document) => { - // Get the language ID and file name - const { languageId, fileName } = document; - - // Determine the file type, defaulting to 'json' if unsupported - let fileType = languageId; - - if (!isFileTypeSupported(fileType)) { - const fileExtension = fileName.split('.').pop(); - - fileType = fileExtension; - } - - // Parse JSON content - const jsonContent = parseJSONContent( - document.getText(), - fileType as FileType, - ); - - // Check if the content is null - if (jsonContent === null) { - return; - } - - // Open the JSON document - const jsonDocument = await workspace.openTextDocument({ - language: 'json', - content: JSON.stringify(jsonContent, null, 2), - }); - - // Show the JSON document - window.showTextDocument(jsonDocument); - }); - } - } - - /** - * The convertPartialToJson method. - * - * @function convertPartialToJson - * @public - * @memberof FilesController - * @example - * controller.convertPartialToJson(); - * - * @returns {void} - The promise - */ - async convertPartialToJson() { - // Get the active text editor - const editor = window.activeTextEditor; - - // Check if there is an active editor - if (!editor) { - const message = l10n.t('No active editor!'); - window.showErrorMessage(message); - return; - } - - // Check if there is a selection - const selection = editor.selection; - - if (selection.isEmpty) { - const message = l10n.t('No selection!'); - window.showErrorMessage(message); - return; - } - - // Get the selection range - const selectionRange = new Range( - selection.start.line, - selection.start.character, - selection.end.line, - selection.end.character, - ); - - // Get the language ID and file name - const { languageId, fileName } = editor.document; - - let fileType = languageId; - - let text = editor.document.getText(selectionRange); - - if ( - [ - 'javascript', - 'javascriptreact', - 'typescript', - 'typescriptreact', - ].includes(fileType) - ) { - fileType = 'jsonc'; - - text = text - .replace(/'([^']+)'/g, '"$1"') - .replace(/(['"])?([a-zA-Z0-9_]+)(['"])?:/g, '"$2":') - .replace(/,*\s*\n*\]/g, ']') - .replace(/{\s*\n*/g, '{') - .replace(/,*\s*\n*};*/g, '}'); - } - - if (!isFileTypeSupported(fileType)) { - const fileExtension = fileName.split('.').pop(); - - fileType = isFileTypeSupported(fileExtension) ? fileExtension : 'jsonc'; - } - - // Parse JSON content - const jsonContent = parseJSONContent(text, fileType as FileType); - - // Check if the JSON content is null - if (jsonContent === null) { - return; - } - - // Open the JSON document - const jsonDocument = await workspace.openTextDocument({ - language: 'json', - content: JSON.stringify(jsonContent, null, 2), - }); - - // Show the JSON document - window.showTextDocument(jsonDocument); - } - /** * The copyContent method. * diff --git a/src/app/controllers/index.ts b/src/app/controllers/index.ts index 010da89..343776a 100644 --- a/src/app/controllers/index.ts +++ b/src/app/controllers/index.ts @@ -1,3 +1,4 @@ export * from './feedback.controller'; export * from './files.controller'; export * from './json.controller'; +export * from './transform.controller'; diff --git a/src/app/controllers/transform.controller.ts b/src/app/controllers/transform.controller.ts new file mode 100644 index 0000000..ac957b5 --- /dev/null +++ b/src/app/controllers/transform.controller.ts @@ -0,0 +1,462 @@ +import { + InputData, + jsonInputForTargetLanguage, + quicktype, +} from 'quicktype-core'; +import { Range, Uri, l10n, window, workspace } from 'vscode'; +import { FileType, isFileTypeSupported, parseJSONContent } from '../helpers'; +import { NodeModel } from '../models'; + +/** + * The TransformController class. + * + * @class + * @classdesc The class that represents the example controller. + * @export + * @public + * @example + * const controller = new TransformController(); + */ +export class TransformController { + // ----------------------------------------------------------------- + // Methods + // ----------------------------------------------------------------- + + // Public methods + + /** + * The convertToJson method. + * + * @function convertToJson + * @param {NodeModel | Uri} node - The node model + * @public + * @memberof FilesController + * @example + * controller.convertToJson('file:///path/to/file'); + * + * @returns {void} - The promise + */ + convertToJson(node: NodeModel | Uri) { + if (node) { + // Get the resource URI + const resourceUri = node instanceof NodeModel ? node.resourceUri : node; + + // Check if the resource URI is valid + if (!resourceUri) { + return; + } + + // Open the text document + workspace.openTextDocument(resourceUri).then(async (document) => { + // Get the language ID and file name + const { languageId, fileName } = document; + + // Determine the file type, defaulting to 'json' if unsupported + let fileType = languageId; + + if (!isFileTypeSupported(fileType)) { + const fileExtension = fileName.split('.').pop(); + + fileType = fileExtension; + } + + // Parse JSON content + const jsonContent = parseJSONContent( + document.getText(), + fileType as FileType, + ); + + // Check if the content is null + if (jsonContent === null) { + return; + } + + // Open the JSON document + const jsonDocument = await workspace.openTextDocument({ + language: 'json', + content: JSON.stringify(jsonContent, null, 2), + }); + + // Show the JSON document + window.showTextDocument(jsonDocument); + }); + } + } + + /** + * The convertPartialToJson method. + * + * @function convertPartialToJson + * @public + * @memberof FilesController + * @example + * controller.convertPartialToJson(); + * + * @returns {void} - The promise + */ + async convertPartialToJson() { + // Get the active text editor + const editor = window.activeTextEditor; + + // Check if there is an active editor + if (!editor) { + const message = l10n.t('No active editor!'); + window.showErrorMessage(message); + return; + } + + // Check if there is a selection + const selection = editor.selection; + + if (selection.isEmpty) { + const message = l10n.t('No selection!'); + window.showErrorMessage(message); + return; + } + + // Get the selection range + const selectionRange = new Range( + selection.start.line, + selection.start.character, + selection.end.line, + selection.end.character, + ); + + // Get the language ID and file name + const { languageId, fileName } = editor.document; + + let fileType = languageId; + + let text = editor.document.getText(selectionRange); + + if ( + [ + 'javascript', + 'javascriptreact', + 'typescript', + 'typescriptreact', + ].includes(fileType) + ) { + fileType = 'jsonc'; + + text = text + .replace(/'([^']+)'/g, '"$1"') + .replace(/(['"])?([a-zA-Z0-9_]+)(['"])?:/g, '"$2":') + .replace(/,*\s*\n*\]/g, ']') + .replace(/{\s*\n*/g, '{') + .replace(/,*\s*\n*};*/g, '}'); + } + + if (!isFileTypeSupported(fileType)) { + const fileExtension = fileName.split('.').pop(); + + fileType = isFileTypeSupported(fileExtension) ? fileExtension : 'jsonc'; + } + + // Parse JSON content + const jsonContent = parseJSONContent(text, fileType as FileType); + + // Check if the JSON content is null + if (jsonContent === null) { + return; + } + + // Open the JSON document + const jsonDocument = await workspace.openTextDocument({ + language: 'json', + content: JSON.stringify(jsonContent, null, 2), + }); + + // Show the JSON document + window.showTextDocument(jsonDocument); + } + + /** + * The convertToType method. + * + * @function convertToType + * @param {NodeModel | Uri} node - The node model + * @param {string} targetLanguage - The target language + * @public + * @memberof FilesController + * @example + * controller.convertToType('file:///path/to/file', 'typescript'); + * + * @returns {void} - The promise + */ + async convertToType(node: NodeModel | Uri, targetLanguage: string) { + if (node) { + // Get the resource URI + const resourceUri = node instanceof NodeModel ? node.resourceUri : node; + + // Check if the resource URI is valid + if (!resourceUri) { + return; + } + + // Open the text document + workspace.openTextDocument(resourceUri).then(async (document) => { + // Get the language ID and file name + const { languageId, fileName } = document; + + // Determine the file type, defaulting to 'json' if unsupported + let fileType = languageId; + + if (!isFileTypeSupported(fileType)) { + const fileExtension = fileName.split('.').pop(); + + fileType = fileExtension; + } + + // Parse JSON content + const jsonContent = parseJSONContent( + document.getText(), + fileType as FileType, + ); + + // Check if the content is null + if (jsonContent === null) { + return; + } + + // Get the name of the type or structure generated + const typeName = await window.showInputBox({ + prompt: l10n.t('Enter the name of the type or structure generated'), + placeHolder: l10n.t( + 'Enter the name of the type or structure, e.g., User, Post, etc.', + ), + value: undefined, + validateInput: (value) => { + if (!value) { + return l10n.t('The name of the type or structure is required!'); + } + + return; + }, + }); + + if (!typeName) { + return; + } + + // Create an instance of JSONInput + const jsonInput = jsonInputForTargetLanguage(targetLanguage); + + // Add the JSON content to the JSONInput instance + await jsonInput.addSource({ + name: typeName, + samples: [JSON.stringify(jsonContent)], + }); + + // Create an instance of InputData + const inputData = new InputData(); + inputData.addInput(jsonInput); + + // Generate the target language + const { lines } = await quicktype({ + inputData, + lang: targetLanguage, + }); + + // Open the JSON document + const jsonDocument = await workspace.openTextDocument({ + language: this.mapLanguageId(targetLanguage), + content: lines.join('\n'), + }); + + // Show the JSON document + window.showTextDocument(jsonDocument); + }); + } + } + + /** + * The convertPartialToType method. + * + * @function convertPartialToType + * @param {string} targetLanguage - The target language + * @public + * @memberof FilesController + * @example + * controller.convertPartialToType('typescript'); + * + * @returns {void} - The promise + */ + async convertPartialToType(targetLanguage: string) { + // Get the active text editor + const editor = window.activeTextEditor; + + // Check if there is an active editor + if (!editor) { + const message = l10n.t('No active editor!'); + window.showErrorMessage(message); + return; + } + + // Check if there is a selection + const selection = editor.selection; + + if (selection.isEmpty) { + const message = l10n.t('No selection!'); + window.showErrorMessage(message); + return; + } + + // Get the selection range + const selectionRange = new Range( + selection.start.line, + selection.start.character, + selection.end.line, + selection.end.character, + ); + + // Get the language ID and file name + const { languageId, fileName } = editor.document; + + let fileType = languageId; + + let text = editor.document.getText(selectionRange); + + if ( + [ + 'javascript', + 'javascriptreact', + 'typescript', + 'typescriptreact', + ].includes(fileType) + ) { + fileType = 'jsonc'; + + text = text + .replace(/'([^']+)'/g, '"$1"') + .replace(/(['"])?([a-zA-Z0-9_]+)(['"])?:/g, '"$2":') + .replace(/,*\s*\n*\]/g, ']') + .replace(/{\s*\n*/g, '{') + .replace(/,*\s*\n*};*/g, '}'); + } + + if (!isFileTypeSupported(fileType)) { + const fileExtension = fileName.split('.').pop(); + + fileType = isFileTypeSupported(fileExtension) ? fileExtension : 'jsonc'; + } + + // Parse JSON content + const jsonContent = parseJSONContent(text, fileType as FileType); + + // Check if the JSON content is null + if (jsonContent === null) { + return; + } + + // Get the name of the type or structure generated + const typeName = await window.showInputBox({ + prompt: l10n.t('Enter the name of the type or structure generated'), + placeHolder: l10n.t( + 'Enter the name of the type or structure, e.g., User, Post, etc.', + ), + value: undefined, + validateInput: (value) => { + if (!value) { + return l10n.t('The name of the type or structure is required!'); + } + + return; + }, + }); + + if (!typeName) { + return; + } + + // Create an instance of JSONInput + const jsonInput = jsonInputForTargetLanguage(targetLanguage); + + // Add the JSON content to the JSONInput instance + await jsonInput.addSource({ + name: typeName, + samples: [JSON.stringify(jsonContent)], + }); + + // Create an instance of InputData + const inputData = new InputData(); + inputData.addInput(jsonInput); + + // Generate the target language + const { lines } = await quicktype({ + inputData, + lang: targetLanguage, + }); + + // Open the JSON document + const jsonDocument = await workspace.openTextDocument({ + language: this.mapLanguageId(targetLanguage), + content: lines.join('\n'), + }); + + // Show the JSON document + window.showTextDocument(jsonDocument); + } + + // Private methods + /** + * The mapLanguageId method. + * + * @function mapLanguageId + * @param {string} targetLanguage - The target language + * @private + * @memberof TransformController + * @example + * const languageId = mapLanguageId('typescript'); + * + * @returns {string} - The language ID + */ + mapLanguageId(targetLanguage: string): string { + switch (targetLanguage) { + case 'ruby': + return 'ruby'; + case 'javascript': + return 'javascript'; + case 'flow': + return 'javascript'; // Flow es un tipo de JavaScript + case 'rust': + return 'rust'; + case 'kotlin': + return 'kotlin'; + case 'dart': + return 'dart'; + case 'python': + return 'python'; + case 'csharp': + return 'csharp'; + case 'go': + return 'go'; + case 'cpp': + return 'cpp'; + case 'java': + return 'java'; + case 'scala': + return 'scala'; + case 'typescript': + return 'typescript'; + case 'swift': + return 'swift'; + case 'objective-c': + return 'objective-c'; + case 'elm': + return 'elm'; + case 'json-schema': + return 'json'; // JSON Schema se representa como JSON + case 'pike': + return 'pike'; + case 'prop-types': + return 'javascript'; // Prop-Types se utiliza con JavaScript + case 'haskell': + return 'haskell'; + case 'php': + return 'php'; + default: + return 'plaintext'; // Lenguaje por defecto + } + } +} diff --git a/src/app/helpers/json.helper.ts b/src/app/helpers/json.helper.ts index 2a0817c..464fd0e 100644 --- a/src/app/helpers/json.helper.ts +++ b/src/app/helpers/json.helper.ts @@ -70,8 +70,6 @@ export const parseJSONContent = ( try { switch (type) { case 'json': - return JSON.parse(content); - case 'jsonc': case 'json5': return json5.parse(content); diff --git a/src/extension.ts b/src/extension.ts index d792893..dbbfc16 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -13,6 +13,7 @@ import { FeedbackController, FilesController, JsonController, + TransformController, } from './app/controllers'; import { FeedbackProvider, FilesProvider, JSONProvider } from './app/providers'; @@ -169,40 +170,6 @@ export async function activate(context: vscode.ExtensionContext) { }, ); - const disposableConvertToJson = vscode.commands.registerCommand( - `${EXTENSION_ID}.files.convertToJson`, - (uri) => { - // Check if the extension is enabled - if (!config.enable) { - const message = vscode.l10n.t( - '{0} is disabled in settings. Enable it to use its features', - [EXTENSION_NAME], - ); - vscode.window.showErrorMessage(message); - return; - } - - filesController.convertToJson(uri); - }, - ); - - const disposableConvertPartialToJson = vscode.commands.registerCommand( - `${EXTENSION_ID}.files.convertPartialToJson`, - () => { - // Check if the extension is enabled - if (!config.enable) { - const message = vscode.l10n.t( - '{0} is disabled in settings. Enable it to use its features', - [EXTENSION_NAME], - ); - vscode.window.showErrorMessage(message); - return; - } - - filesController.convertPartialToJson(); - }, - ); - const disponsableCopyContent = vscode.commands.registerCommand( `${EXTENSION_ID}.files.copyContent`, (uri) => { @@ -273,8 +240,6 @@ export async function activate(context: vscode.ExtensionContext) { context.subscriptions.push( disposableOpenFile, - disposableConvertToJson, - disposableConvertPartialToJson, disponsableCopyContent, disponsableCopyContentAsJson, disponsableCopyContentPartialAsJson, @@ -329,6 +294,150 @@ export async function activate(context: vscode.ExtensionContext) { disposableShowPartialPreview, ); + // ----------------------------------------------------------------- + // Register TransformController + // ----------------------------------------------------------------- + + // Create a new TransformController + const transformController = new TransformController(); + + const disposableConvertToJson = vscode.commands.registerCommand( + `${EXTENSION_ID}.files.convertToJson`, + (uri) => { + // Check if the extension is enabled + if (!config.enable) { + const message = vscode.l10n.t( + '{0} is disabled in settings. Enable it to use its features', + [EXTENSION_NAME], + ); + vscode.window.showErrorMessage(message); + return; + } + + transformController.convertToJson(uri); + }, + ); + + const disposableConvertPartialToJson = vscode.commands.registerCommand( + `${EXTENSION_ID}.files.convertPartialToJson`, + () => { + // Check if the extension is enabled + if (!config.enable) { + const message = vscode.l10n.t( + '{0} is disabled in settings. Enable it to use its features', + [EXTENSION_NAME], + ); + vscode.window.showErrorMessage(message); + return; + } + + transformController.convertPartialToJson(); + }, + ); + + const disposableConvertToType = vscode.commands.registerCommand( + `${EXTENSION_ID}.files.convertToType`, + async (uri) => { + // Check if the extension is enabled + if (!config.enable) { + const message = vscode.l10n.t( + '{0} is disabled in settings. Enable it to use its features', + [EXTENSION_NAME], + ); + vscode.window.showErrorMessage(message); + return; + } + + const targetLanguage = await vscode.window.showQuickPick( + [ + 'cpp', + 'csharp', + 'dart', + 'elm', + 'flow', + 'go', + 'haskell', + 'java', + 'javascript', + 'json-schema', + 'kotlin', + 'objective-c', + 'php', + 'pike', + 'prop-types', + 'python', + 'ruby', + 'rust', + 'scala', + 'swift', + 'typescript', + ], + { placeHolder: vscode.l10n.t('Select the target language') }, + ); + + if (!targetLanguage) { + return; + } + + transformController.convertToType(uri, targetLanguage); + }, + ); + + const disposableConvertPartialToType = vscode.commands.registerCommand( + `${EXTENSION_ID}.files.convertPartialToType`, + async () => { + // Check if the extension is enabled + if (!config.enable) { + const message = vscode.l10n.t( + '{0} is disabled in settings. Enable it to use its features', + [EXTENSION_NAME], + ); + vscode.window.showErrorMessage(message); + return; + } + + const targetLanguage = await vscode.window.showQuickPick( + [ + 'cpp', + 'csharp', + 'dart', + 'elm', + 'flow', + 'go', + 'haskell', + 'java', + 'javascript', + 'json-schema', + 'kotlin', + 'objective-c', + 'php', + 'pike', + 'prop-types', + 'python', + 'ruby', + 'rust', + 'scala', + 'swift', + 'typescript', + ], + { placeHolder: vscode.l10n.t('Select the target language') }, + ); + + if (!targetLanguage) { + return; + } + + transformController.convertPartialToType(targetLanguage); + }, + ); + + context.subscriptions.push( + disposableConvertToJson, + disposableConvertPartialToJson, + disposableConvertToType, + disposableConvertPartialToType, + ); + // ----------------------------------------------------------------- // Register FeedbackProvider and Feedback commands // -----------------------------------------------------------------