diff --git a/src/App.vue b/src/App.vue index a69b94653a92c7b219570dd03560d4b1c912cdcb..3e6eb4445167b522666cc19a652464d688700dfc 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,4 +1,4 @@ -<script setup> +<script setup lang="ts"> import SetupView from "@/components/SetupView.vue"; import MainView from "@/components/MainView.vue"; import {useMainStore} from "@/services/mainStore"; @@ -6,6 +6,9 @@ import {storeToRefs} from "pinia"; import {useConstantsStore} from "@/services/constantsStore"; import {onMounted, ref} from "vue"; import CookieNag from "@/components/helpers/CookieNag.vue"; +import {useAPIClient, RawCompiled} from "@/services/api-v2"; + +const x : RawCompiled = {typed_query: ""} const store = useMainStore() const constants = useConstantsStore() @@ -36,8 +39,8 @@ onMounted(() => constants.initViaAPI()) }} </v-icon> - <div class="text-h5 pa-2"> - Connecting to backend <a :href="useAPIClient().api.getBaseURL()">{{ useAPIClient().api.getBaseURL() }}</a> failed. + <div class="text-h5 pa-2" v-if="apiStatus === 'disconnected'"> + Connecting to backend <a :href="useAPIClient().getConfig().baseUrl">{{ useAPIClient().getConfig().baseUrl }}</a> failed. </div> <v-btn class="mt-2" prepend-icon="mdi-reload" @click="retestAPI" :loading="apiStatus === 'connecting'"> diff --git a/src/components/ExportView.vue b/src/components/ExportView.vue index 75d42c26101c58abe8c4b87113015c388d286ad9..949782d351858e935a40015abf66a0d6b43f44c9 100644 --- a/src/components/ExportView.vue +++ b/src/components/ExportView.vue @@ -110,7 +110,7 @@ async function pollExport(url: string) { :poll-interval="5 * 1000" :interval-notches="5" stop-on-positive-poll></ReadinessPoller> <v-list-item-action end> <v-btn density="default" variant="text"> - <a target="_blank" :href="item.download_url"> + <a :href="item.download_url"> <v-icon color="primary" size="large">mdi-download</v-icon> </a> </v-btn> diff --git a/src/components/helpers/TableLabel.vue b/src/components/helpers/TableLabel.vue index 37141f8a57f77e0dba41058797a18fd86e574e6d..291af3cdd9bf6c61a7eee79cb458c386bde353eb 100644 --- a/src/components/helpers/TableLabel.vue +++ b/src/components/helpers/TableLabel.vue @@ -2,16 +2,16 @@ import {TableIdentifier} from "@/services/api-v2"; -const {selectedTable} = defineProps<{ 'selectedTable': TableIdentifier }>() +const props = defineProps<{ selectedTable: TableIdentifier | null }>() </script> <template> - <div v-if="selectedTable" class="text-h6"> + <div v-if="props.selectedTable" class="text-h6"> <slot> Preview of </slot> - <span class="text-bold"><small>{{ selectedTable.schema }}.</small>{{ selectedTable.name }}</span> + <span class="text-bold"><small>{{ props.selectedTable.schema }}.</small>{{ props.selectedTable.name }}</span> </div> <div v-else>No table selected.</div> </template> diff --git a/src/components/helpers/TableSelector.vue b/src/components/helpers/TableSelector.vue index d0c40a7ed01a7ac3625f69b7a8bdce6faf2b58b5..9167581f501fb8669e4798b1fcf652d0ba235980 100644 --- a/src/components/helpers/TableSelector.vue +++ b/src/components/helpers/TableSelector.vue @@ -4,7 +4,7 @@ import {SourceDBType, TableIdentifier} from "@/services/api-v2"; import {ref, watchEffect} from "vue"; import {useAllTables, useTablesInDB} from "@/services/convenienceStore"; -const selectedTable = defineModel<TableIdentifier>("selectedTable") +const selectedTable = defineModel<TableIdentifier | null>("selectedTable") const props = defineProps<{ props?: object, sourceDB: SourceDBType | "either" }>() const availableTables = ref([]) diff --git a/src/components/subcomponents/transform/EditColumns.vue b/src/components/subcomponents/transform/EditColumns.vue index a6ac5a5ae84c5f8383bde39b2a87facbd63aa7e2..307cffbb6968ccbfa89526f0c8d9f2ba3faf48f0 100644 --- a/src/components/subcomponents/transform/EditColumns.vue +++ b/src/components/subcomponents/transform/EditColumns.vue @@ -1,12 +1,12 @@ <script setup lang="ts"> -import {Ref, ref, useTemplateRef, watch} from "vue"; +import {Ref, ref, toValue, useTemplateRef, watch} from "vue"; import {useConstantsStore} from "@/services/constantsStore"; import {TableIdentifier, Transform, CastColumn, ReselectColumns, EditColumns} from "@/services/api-v2"; -import {AddColumn} from "@/services/api-v2"; import {useMainStore} from "@/services/mainStore"; import {useColumnsOfTableWithProbe, useMitMTypes} from "@/services/convenienceStore"; import {rules} from "@/services/utils"; import {VueDraggable} from "vue-draggable-plus"; +// import {AddColumn} from "@/services/api-v2" const store = useMainStore(); const constants = useConstantsStore() @@ -89,7 +89,8 @@ function createTransforms(): Transform[] { const selection = [] targetTableItems.value.forEach((item, i) => { - const targetType = item.castedType ? {mitm: item.castedType} : undefined + const targetType = toValue(item.castedType) ? toValue(item.castedType.wrapped) : undefined + const newName = toValue(item.newName) // interpret as mitm type if it starts like this, else it is used verbatim, and thus assumed to be a SQL type //if (targetType.startsWith("mitm.")) @@ -107,9 +108,9 @@ function createTransforms(): Transform[] { } else { if (!!targetType) transforms[item.name] = {target_type: targetType, operation: "cast_column"} as CastColumn - if (!!item.newName) { - renames[item.name] = item.newName - selection.push(item.newName) + if (!!newName) { + renames[item.name] = newName + selection.push(newName) } else selection.push(item.name) } diff --git a/src/services/api-v2.ts b/src/services/api-v2.ts index 88f4a29e97003923692d481b6814cddf05661442..daa2c516a7f34ffed999a7bfeb7fa63de939f127 100644 --- a/src/services/api-v2.ts +++ b/src/services/api-v2.ts @@ -1,5 +1,10 @@ -import {MITM, MITMDataType, SourceDBType, SimpleSQLOperator, FKCreationRequest} from "@/services/api-schema/types.gen" -import * as apiTypes from "@/services/api-schema/types.gen" +import { + MITM as MITMs, + MITMDataType as MITMDataTypes, + SourceDBType as SourceDBTypes, + SimpleSQLOperator as SimpleSQLOperators +} from "@/services/api-schema/types.gen.ts" +import * as apiTypes from "@/services/api-schema/types.gen.ts" /* export { MITM as MITMs, @@ -8,23 +13,22 @@ export { SimpleSQLOperator as SimpleSQLOperators } from "@/services/api-schema/types.gen" */ -export * from "@/services/api-schema/types.gen" +export * from "@/services/api-schema/types.gen.ts" export type Base = apiTypes.ExistingTable | apiTypes.SimpleJoin | apiTypes.RawCompiled export type Transform = apiTypes.EditColumns | apiTypes.ReselectColumns | apiTypes.TableFilter | apiTypes.Limit export type ColumnCreations = apiTypes.AddColumn | apiTypes.ExtractJson - import { - client, - SessionService, - AdminService, - DataService, - ControlService, - DefaultService, - DefinitionsService, - MitmService, - ReflectionService + client, + SessionService, + AdminService, + DataService, + ControlService, + DefaultService, + DefinitionsService, + MitmService, + ReflectionService } from "@/services/api-schema/services.gen"; @@ -32,212 +36,212 @@ const backendUrl = (process.env.VITE_API_HOST ?? window.location.origin) + (proc console.log(`Using following (backend) API_URL: ${backendUrl}`) client.setConfig({ - withCredentials: true, - baseURL: backendUrl + withCredentials: true, + baseURL: backendUrl }) function errorHandler(msg?) { - return err => { - console.log(msg ?? "Request failed:", err); - return null as undefined - } + return err => { + console.log(msg ?? "Request failed:", err); + return null as undefined + } } async function keepAlive() { - return await SessionService.keepAlive().catch(errorHandler('API is unreachable')) + return await SessionService.keepAlive().catch(errorHandler('API is unreachable')) } async function startSession() { - return await SessionService.startSession().catch(errorHandler()) + return await SessionService.startSession().catch(errorHandler()) } async function stopSession() { - return await SessionService.stopSession({}).catch(errorHandler()) + return await SessionService.stopSession({}).catch(errorHandler()) } async function uploadDB(sqliteFile) { - return await SessionService.uploadDb({body: {sqlite: sqliteFile}}).catch(errorHandler('Error uploading file')) - /* - const formData = new FormData(); - formData.append('sqlite', sqliteFile); - return apiConnection.post('/setup/upload-db', formData, { - headers: { - 'Content-Type': 'multipart/form-data', - }, - }) - */ + return await SessionService.uploadDb({body: {sqlite: sqliteFile}}).catch(errorHandler('Error uploading file')) + /* + const formData = new FormData(); + formData.append('sqlite', sqliteFile); + return apiConnection.post('/setup/upload-db', formData, { + headers: { + 'Content-Type': 'multipart/form-data', + }, + }) + */ } async function connectDB(url: string) { - return await SessionService.connectDb({body: {db_url: url}}).catch(errorHandler('Error connecting to DB')) + return await SessionService.connectDb({body: {db_url: url}}).catch(errorHandler('Error connecting to DB')) } async function testDBConn() { - return await SessionService.testDbConn({}).catch(errorHandler()) + return await SessionService.testDbConn({}).catch(errorHandler()) } // async function getMitMs() { - return await DefinitionsService.getMitms().catch(errorHandler()) + return await DefinitionsService.getMitms().catch(errorHandler()) } -async function getMitMDefinition(mitm: MITM) { - return await DefinitionsService.getMitmDefinition({query: {mitm}}).catch(errorHandler()) +async function getMitMDefinition(mitm: apiTypes.MITM) { + return await DefinitionsService.getMitmDefinition({query: {mitm}}).catch(errorHandler()) } async function getMitMDataTypes() { - return await DefinitionsService.getMitmDataTypes().catch(errorHandler()) + return await DefinitionsService.getMitmDataTypes().catch(errorHandler()) } // async function reflectDB() { - return await ControlService.reflectDb({}).catch(errorHandler('Error reflecting DB schema')) + return await ControlService.reflectDb({}).catch(errorHandler('Error reflecting DB schema')) } async function getDBSchema(source?: apiTypes.SourceDBType) { - return await ReflectionService.getDbSchema({query: {source}}).catch(errorHandler('Error retrieving DB schema')) + return await ReflectionService.getDbSchema({query: {source}}).catch(errorHandler('Error retrieving DB schema')) } async function getTableSchema(tid: apiTypes.TableIdentifier) { - return await ReflectionService.getTableSchema({query: {...tid}}).catch(errorHandler('Error retrieving Table schema')) + return await ReflectionService.getTableSchema({query: {...tid}}).catch(errorHandler('Error retrieving Table schema')) } async function queryTable(params: apiTypes.QueryTableData["query"]) { - return await DataService.queryTable({query: {...params}}).catch(errorHandler()) + return await DataService.queryTable({query: {...params}}).catch(errorHandler()) } async function probeTable(tid: apiTypes.TableIdentifier) { - return await ReflectionService.probeTable({query: {...tid}}).catch(errorHandler()) + return await ReflectionService.probeTable({query: {...tid}}).catch(errorHandler()) } async function probeDB(tid: apiTypes.TableIdentifier, body: apiTypes.ProbeDbData["body"]) { - return await ReflectionService.probeDb({ - body, - query: {...tid, override_if_exists: true} - }).catch(errorHandler()) + return await ReflectionService.probeDb({ + body, + query: {...tid, override_if_exists: true} + }).catch(errorHandler()) } -async function searchDB(source: SourceDBType, body: apiTypes.DBSchemaQueryRequest) { - return await ReflectionService.queryDbSchema({body, query: {source}}).catch(errorHandler()) +async function searchDB(source: apiTypes.SourceDBType, body: apiTypes.DBSchemaQueryRequest) { + return await ReflectionService.queryDbSchema({body, query: {source}}).catch(errorHandler()) } -async function makeERD(source?: SourceDBType, body?: apiTypes.DBSchemaSelectionRequest) { - if (!body) - return await DataService.makeErd({query: {source, version: "mermaid"}}).catch(errorHandler()) - else - return await DataService.makeFilteredErd({query: {source, version: "mermaid"}, body}).catch(errorHandler()) +async function makeERD(source?: apiTypes.SourceDBType, body?: apiTypes.DBSchemaSelectionRequest) { + if (!body) + return await DataService.makeErd({query: {source, version: "mermaid"}}).catch(errorHandler()) + else + return await DataService.makeFilteredErd({query: {source, version: "mermaid"}, body}).catch(errorHandler()) } // -async function markForeignKey(source: SourceDBType, body: apiTypes.FKCreationRequest) { - return await ControlService.markForeignKey({ - query: {source}, - body - }).catch(errorHandler('Foreign key constraint could not be created')) +async function markForeignKey(source: apiTypes.SourceDBType, body: apiTypes.FKCreationRequest) { + return await ControlService.markForeignKey({ + query: {source}, + body + }).catch(errorHandler('Foreign key constraint could not be created')) } async function createVirtualView(body: apiTypes.VirtualViewCreationRequest, params?: apiTypes.CreateVirtualViewData["query"]) { - return await ControlService.createVirtualView({ - query: {...params}, - body - }).catch(errorHandler('Error creating virtual view')) + return await ControlService.createVirtualView({ + query: {...params}, + body + }).catch(errorHandler('Error creating virtual view')) } async function createVirtualViewsBatch(body: apiTypes.VirtualViewCreationRequest[], params?: apiTypes.CreateVirtualViewsBatchData["query"]) { - return await ControlService.createVirtualViewsBatch({ - query: {...params}, - body - }).catch(errorHandler('Error creating virtual views')) + return await ControlService.createVirtualViewsBatch({ + query: {...params}, + body + }).catch(errorHandler('Error creating virtual views')) } async function dropVirtualView(params: apiTypes.DropVirtualViewData["query"]) { - return await ControlService.dropVirtualView({query: {...params}}).catch(errorHandler('Error dropping virtual view')) + return await ControlService.dropVirtualView({query: {...params}}).catch(errorHandler('Error dropping virtual view')) } async function getCompiledView(params: apiTypes.GetCompiledVirtualViewData["query"]) { - return await ControlService.getCompiledVirtualView({query: {...params}}).catch(errorHandler('Requested virtual view could not be compiled')) + return await ControlService.getCompiledVirtualView({query: {...params}}).catch(errorHandler('Requested virtual view could not be compiled')) } async function getCompiledViews() { - return await ControlService.getCompiledVirtualViews({}).catch(errorHandler('Virtual views could not be compiled')) + return await ControlService.getCompiledVirtualViews({}).catch(errorHandler('Virtual views could not be compiled')) } async function validateMappings(body: apiTypes.ConceptMappingRequest[]) { - return await MitmService.validateConceptMappings({ - body - }).catch(errorHandler('Error validating MitM concept mappings')) + return await MitmService.validateConceptMappings({ + body + }).catch(errorHandler('Error validating MitM concept mappings')) } // async function exportMitM(body: apiTypes.MappingExportRequest) { - return await MitmService.exportMitm({ - body, - params: {responseType: "blob"} - }).catch(errorHandler('Error exporting MitM mapped dataset')) + return await MitmService.exportMitm({ + body, + params: {responseType: "blob"} + }).catch(errorHandler('Error exporting MitM mapped dataset')) } async function publishMitMExport(body: apiTypes.MappingExportRequest, use_streaming_export: boolean) { - return await MitmService.publishMitmExport({ - query: {use_streaming_export: use_streaming_export}, - body - }).catch(errorHandler('Error publishing MitM mapped dataset export')) + return await MitmService.publishMitmExport({ + query: {use_streaming_export: use_streaming_export}, + body + }).catch(errorHandler('Error publishing MitM mapped dataset export')) } async function deleteMitMExport(exportID: number) { - return await MitmService.deleteMitmExport({ - query: {export_id: exportID} - }).catch(errorHandler('Error deleting MitM dataset export')) + return await MitmService.deleteMitmExport({ + query: {export_id: exportID} + }).catch(errorHandler('Error deleting MitM dataset export')) } async function deleteMitMExports() { - return await MitmService.deleteMitmExports({}).catch(errorHandler('Error deleting MitM dataset exports')) + return await MitmService.deleteMitmExports({}).catch(errorHandler('Error deleting MitM dataset exports')) } export function useAPIClient() { - return client + return client } export function useAPI() { - return { - AdminService, - SessionService, - ControlService, - ReflectionService, - DataService, - MitmService, - DefinitionsService, - keepAlive, - startSession, - stopSession, - getDBSchema, - uploadDB, - connectDB, - getMitMs, - getMitMDefinition, - getMitMDataTypes, - reflectDB, - testDBConn, - queryTable, - probeTable, - probeDB, - searchDB, - makeERD, - getTableSchema, - markForeignKey, - createVirtualView, - createVirtualViewsBatch, - dropVirtualView, - validateMappings, - exportMitM, - publishMitMExport, - deleteMitMExport, - deleteMitMExports, - getCompiledView, - getCompiledViews - } + return { + AdminService, + SessionService, + ControlService, + ReflectionService, + DataService, + MitmService, + DefinitionsService, + keepAlive, + startSession, + stopSession, + getDBSchema, + uploadDB, + connectDB, + getMitMs, + getMitMDefinition, + getMitMDataTypes, + reflectDB, + testDBConn, + queryTable, + probeTable, + probeDB, + searchDB, + makeERD, + getTableSchema, + markForeignKey, + createVirtualView, + createVirtualViewsBatch, + dropVirtualView, + validateMappings, + exportMitM, + publishMitMExport, + deleteMitMExport, + deleteMitMExports, + getCompiledView, + getCompiledViews + } } diff --git a/src/services/constantsStore.ts b/src/services/constantsStore.ts index 2389c54559eafa218a023c5114ea12b4bd2e8fe4..931ba5a630c35146abfb71e7d13dde0bf6061839 100644 --- a/src/services/constantsStore.ts +++ b/src/services/constantsStore.ts @@ -51,7 +51,7 @@ export const useConstantsStore = defineStore('constants', () => { if (r3?.data) { const temp = {} Object.entries(r3.data).forEach(([key, value]) => { - temp[key] = {wrappedIdentifer: {mitm: key}, ...value} + temp[key] = {wrappedIdentifier: {mitm: key}, ...value} }) mitmDataTypes.value = temp } diff --git a/src/services/selectionStore.ts b/src/services/selectionStore.ts index 0599bf1382b8a15c02a24eca33eb67e8f5de2dae..965dfa79e4293688867c9faad37fd5224dde9dcf 100644 --- a/src/services/selectionStore.ts +++ b/src/services/selectionStore.ts @@ -10,7 +10,7 @@ export const useSelectionStore = defineStore('selection', () => { const api = useAPI() const constants = useConstantsStore() - const selectedTable = ref<TableIdentifier>(null as TableIdentifier) + const selectedTable = ref<TableIdentifier | null>(null as TableIdentifier) const favoritedTables = ref<TableIdentifier[]>([] as TableIdentifier[]) const selectedMitM = ref<MITM>("MAED" as MITM) const selectedMitMDef = computed(() => constants.mitmDefs[selectedMitM.value] as MITMDefinition) diff --git a/tsconfig.json b/tsconfig.json index f8e971f0ebeac943363b6f102491e3516a428129..be5d8eb340a4ea5acb0585b354ed6ff9e95a60f9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "resolveJsonModule": true, "allowJs": true, + "allowImportingTsExtensions": true, "target": "es5", "module": "esnext", "baseUrl": "./",