diff --git a/client/src/components/AvailableDatatypes/AvailableDatatypes.vue b/client/src/components/AvailableDatatypes/AvailableDatatypes.vue
index 079f9795680..96b6d6b286a 100644
--- a/client/src/components/AvailableDatatypes/AvailableDatatypes.vue
+++ b/client/src/components/AvailableDatatypes/AvailableDatatypes.vue
@@ -1,11 +1,11 @@
-
-
diff --git a/client/src/components/Form/parameterTypes.d.ts b/client/src/components/Form/parameterTypes.d.ts
new file mode 100644
index 00000000000..e3c7ca53574
--- /dev/null
+++ b/client/src/components/Form/parameterTypes.d.ts
@@ -0,0 +1,30 @@
+// TODO: stricter types
+export type FormParameterValue = any;
+export type FormParameterAttributes = {
+ [attribute: string]: any;
+};
+
+export type FormParameterTypes =
+ | "boolean"
+ | "hidden"
+ | "hidden_data"
+ | "baseurl"
+ | "integer"
+ | "float"
+ | "radio"
+ | "color"
+ | "directory_uri"
+ | "text"
+ | "password"
+ | "select"
+ | "data_column"
+ | "genomebuild"
+ | "data"
+ | "data_collection"
+ | "drill_down"
+ | "group_tag"
+ | "library_data"
+ | "ftpfile"
+ | "upload"
+ | "rules"
+ | "data_dialog";
diff --git a/client/src/composables/datatypes.js b/client/src/composables/datatypes.js
deleted file mode 100644
index 15aa61ce8cd..00000000000
--- a/client/src/composables/datatypes.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import { ref } from "vue";
-import axios from "axios";
-import { getAppRoot } from "onload/loadConfig";
-
-/**
- * Fetches a detailed array of datatypes available on this galaxy instance.
- * Does not cache the result or use a store.
- */
-export function useDetailedDatatypes() {
- const datatypesLoading = ref(true);
- const datatypes = ref([]);
-
- async function getDatatypes() {
- try {
- const datatypesPromise = axios.get(`${getAppRoot()}api/datatypes?extension_only=false`);
- const datatypeEDAMFormatsPromise = axios.get(`${getAppRoot()}api/datatypes/edam_formats/detailed`);
- const datatypeEDAMDataPromise = axios.get(`${getAppRoot()}api/datatypes/edam_data/detailed`);
-
- const [baseTypes, datatypeEDAMFormats, datatypeEDAMData] = await Promise.all([
- datatypesPromise,
- datatypeEDAMFormatsPromise,
- datatypeEDAMDataPromise,
- ]);
-
- datatypes.value = baseTypes.data.map((type, i) => {
- const typeEDAMFormat = datatypeEDAMFormats.data[type.extension] ?? null;
- const typeEDAMData = datatypeEDAMData.data[type.extension] ?? null;
-
- return {
- extension: type.extension,
- description: type.description,
- descriptionUrl: type.description_url,
- edamFormat: typeEDAMFormat.prefix_IRI,
- edamFormatLabel: typeEDAMFormat.label,
- edamFormatDefinition: typeEDAMFormat.definition,
- edamData: typeEDAMData.prefix_IRI,
- edamDataLabel: typeEDAMData.label,
- edamDataDefinition: typeEDAMData.definition,
- };
- });
- } catch (e) {
- console.error("unable to fetch available datatypes\n", e);
- } finally {
- datatypesLoading.value = false;
- }
- }
-
- getDatatypes();
-
- return { datatypes, datatypesLoading };
-}
diff --git a/client/src/composables/datatypes.ts b/client/src/composables/datatypes.ts
new file mode 100644
index 00000000000..6140f55c12e
--- /dev/null
+++ b/client/src/composables/datatypes.ts
@@ -0,0 +1,70 @@
+import { ref } from "vue";
+import { fetcher } from "schema";
+
+import type { Ref } from "vue";
+
+const datatypesFetcher = fetcher.path("/api/datatypes").method("get").create();
+const edamFormatsFetcher = fetcher.path("/api/datatypes/edam_formats/detailed").method("get").create();
+const edamDataFetcher = fetcher.path("/api/datatypes/edam_data/detailed").method("get").create();
+
+export interface DetailedDatatypes {
+ extension: string;
+ description?: string;
+ descriptionUrl?: string;
+ edamFormat?: string;
+ edamFormatLabel?: string;
+ edamFormatDefinition?: string;
+ edamData?: string;
+ edamDataLabel?: string;
+ edamDataDefinition?: string;
+}
+
+/**
+ * Fetches a detailed array of datatypes available on this galaxy instance.
+ * Does not cache the result or use a store.
+ */
+export function useDetailedDatatypes() {
+ const datatypesLoading = ref(true);
+ const datatypes: Ref = ref([]);
+
+ async function getDatatypes() {
+ try {
+ const datatypesPromise = datatypesFetcher({ extension_only: true });
+ const datatypeEDAMFormatsPromise = edamFormatsFetcher({});
+ const datatypeEDAMDataPromise = edamDataFetcher({});
+
+ const [baseTypes, datatypeEDAMFormats, datatypeEDAMData] = await Promise.all([
+ datatypesPromise,
+ datatypeEDAMFormatsPromise,
+ datatypeEDAMDataPromise,
+ ]);
+
+ type BaseTypes = Exclude;
+
+ datatypes.value = (baseTypes.data as BaseTypes).map((type) => {
+ const typeEDAMFormat = datatypeEDAMFormats.data[type.extension] ?? null;
+ const typeEDAMData = datatypeEDAMData.data[type.extension] ?? null;
+
+ return {
+ extension: type.extension,
+ description: type.description,
+ descriptionUrl: type.description_url,
+ edamFormat: typeEDAMFormat?.prefix_IRI,
+ edamFormatLabel: typeEDAMFormat?.label,
+ edamFormatDefinition: typeEDAMFormat?.definition,
+ edamData: typeEDAMData?.prefix_IRI,
+ edamDataLabel: typeEDAMData?.label,
+ edamDataDefinition: typeEDAMData?.definition,
+ };
+ });
+ } catch (e) {
+ console.error("unable to fetch available datatypes\n", e);
+ } finally {
+ datatypesLoading.value = false;
+ }
+ }
+
+ getDatatypes();
+
+ return { datatypes, datatypesLoading };
+}
diff --git a/client/src/composables/toast.js b/client/src/composables/toast.js
deleted file mode 100644
index 0f19ef6a240..00000000000
--- a/client/src/composables/toast.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import { ref } from "vue";
-
-let toastRef = ref(null);
-
-export const setToastComponentRef = (newRef) => {
- // eslint-disable-next-line vue/no-ref-as-operand
- toastRef = newRef;
-};
-
-/**
- * Direct export to simplify usage in Options Api component.
- * Use 'useToast' for the Composition Api instead.
- */
-export const Toast = {
- success(message, title = "Success") {
- toastRef.value.showToast(message, title, "success");
- },
-
- info(message, title = "Info") {
- toastRef.value.showToast(message, title, "info");
- },
-
- warning(message, title = "Warning") {
- toastRef.value.showToast(message, title, "warning");
- },
-
- error(message, title = "Error") {
- toastRef.value.showToast(message, title, "error");
- },
-};
-
-export function useToast() {
- return { ...Toast };
-}
diff --git a/client/src/composables/toast.ts b/client/src/composables/toast.ts
new file mode 100644
index 00000000000..7ebb50cd8fc
--- /dev/null
+++ b/client/src/composables/toast.ts
@@ -0,0 +1,39 @@
+import { ref, type Ref } from "vue";
+
+import type Vue from "vue";
+import type ToastComponentFile from "components/Toast";
+
+export type ToastComponent = Vue & typeof ToastComponentFile.methods;
+
+let toastRef: Ref = ref(null);
+
+export const setToastComponentRef = (newRef: typeof toastRef) => {
+ // eslint-disable-next-line vue/no-ref-as-operand
+ toastRef = newRef;
+};
+
+/**
+ * Direct export to simplify usage in Options Api component.
+ * Use 'useToast' for the Composition Api instead.
+ */
+export const Toast = {
+ success(message: string, title = "Success") {
+ toastRef.value?.showToast(message, title, "success");
+ },
+
+ info(message: string, title = "Info") {
+ toastRef.value?.showToast(message, title, "info");
+ },
+
+ warning(message: string, title = "Warning") {
+ toastRef.value?.showToast(message, title, "warning");
+ },
+
+ error(message: string, title = "Error") {
+ toastRef.value?.showToast(message, title, "error");
+ },
+};
+
+export function useToast() {
+ return { ...Toast };
+}
diff --git a/tsconfig.js b/tsconfig.json
similarity index 100%
rename from tsconfig.js
rename to tsconfig.json