@morscherlab/mint-sdk 1.0.53 → 1.0.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -0
- package/dist/{ExperimentSelectorModal-BwPbQN1g.js → ExperimentSelectorModal-Cg4-LXBD.js} +1 -1
- package/dist/{ExperimentSelectorModal-B2qek_YG.js → ExperimentSelectorModal-DZeSd-yr.js} +2 -2
- package/dist/{ExperimentSelectorModal-B2qek_YG.js.map → ExperimentSelectorModal-DZeSd-yr.js.map} +1 -1
- package/dist/__tests__/composables/resolvePluginFrontendBase.test.d.ts +1 -0
- package/dist/components/index.js +2 -2
- package/dist/{components-Lk_h_rON.js → components-BQwOeyiy.js} +5 -5
- package/dist/{components-Lk_h_rON.js.map → components-BQwOeyiy.js.map} +1 -1
- package/dist/composables/index.d.ts +3 -2
- package/dist/composables/index.js +4 -4
- package/dist/composables/pluginFrontendBase.d.ts +7 -0
- package/dist/composables/useApi.d.ts +9 -0
- package/dist/composables/usePluginClient.d.ts +12 -2
- package/dist/{composables-DyfGpYZw.js → composables-TpXyhRZZ.js} +97 -30
- package/dist/composables-TpXyhRZZ.js.map +1 -0
- package/dist/index.js +6 -6
- package/dist/install.js +2 -2
- package/dist/{useExperimentSelector-DdCy5VNv.js → useExperimentSelector-DRbj6vse.js} +33 -3
- package/dist/useExperimentSelector-DRbj6vse.js.map +1 -0
- package/dist/{useJobsStatusTray-DAH999_N.js → useJobsStatusTray-CVecN6Ao.js} +2 -2
- package/dist/{useJobsStatusTray-DAH999_N.js.map → useJobsStatusTray-CVecN6Ao.js.map} +1 -1
- package/package.json +1 -1
- package/src/__tests__/composables/resolvePluginFrontendBase.test.ts +65 -0
- package/src/__tests__/composables/useApi.test.ts +76 -2
- package/src/__tests__/composables/usePluginClient.test.ts +158 -0
- package/src/composables/index.ts +8 -1
- package/src/composables/pluginEndpointBuilder.ts +13 -4
- package/src/composables/pluginFrontendBase.ts +22 -0
- package/src/composables/useApi.ts +48 -1
- package/src/composables/usePluginClient.ts +125 -21
- package/dist/composables-DyfGpYZw.js.map +0 -1
- package/dist/useExperimentSelector-DdCy5VNv.js.map +0 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export { useApi, type ApiClientOptions } from './useApi';
|
|
1
|
+
export { AuthenticationRequiredError, useApi, type ApiClientOptions, type UseApiReturn, } from './useApi';
|
|
2
2
|
export { useAuth } from './useAuth';
|
|
3
3
|
export { usePasskey } from './usePasskey';
|
|
4
4
|
export { useTheme } from './useTheme';
|
|
5
5
|
export { useToast } from './useToast';
|
|
6
6
|
export { usePlatformContext } from './usePlatformContext';
|
|
7
|
+
export { resolvePluginFrontendBase } from './pluginFrontendBase';
|
|
7
8
|
export { useForm, type ValidationRule, type FieldRules, type FieldState, type UseFormReturn, } from './useForm';
|
|
8
9
|
export { useAsync, useAsyncBatch, type AsyncError, type AsyncState, type UseAsyncReturn, type UseAsyncOptions, } from './useAsync';
|
|
9
10
|
export { useWellPlateEditor, type UseWellPlateEditorOptions, type UseWellPlateEditorReturn, } from './useWellPlateEditor';
|
|
@@ -52,5 +53,5 @@ export { getBioTemplateComponentProps, getBioTemplateComponentBindings, toBioTem
|
|
|
52
53
|
export { useBioTemplateWorkspace, type BioTemplateRendererBinding, type BioTemplateWorkspaceBindings, type BioTemplateWorkspaceTarget, type UseBioTemplateWorkspaceReturn, } from './useBioTemplateWorkspace';
|
|
53
54
|
export { useBioTemplatePresetWorkspace, type BioTemplatePresetWorkspaceBindings, type UseBioTemplatePresetWorkspaceOptions, type UseBioTemplatePresetWorkspaceReturn, } from './useBioTemplatePresetWorkspace';
|
|
54
55
|
export { useBioTemplatePackWorkspace, type UseBioTemplatePackWorkspaceOptions, type UseBioTemplatePackWorkspaceReturn, } from './useBioTemplatePackWorkspace';
|
|
55
|
-
export { buildPluginEndpointUrl, createPluginClient, downloadBlob, downloadPluginEndpoint, getPluginPageSelectorItems, pluginFormDataFromPayload, resolvePluginBaseUrl, uploadPluginEndpoint, usePluginClient, usePluginEventStream, usePluginSettings, useCurrentExperiment, type BuildPluginEndpointUrlOptions, type DownloadBlobOptions, type DownloadPluginEndpointOptions, type PluginContract, type PluginEndpointContract, type PluginEndpointDefinition, type PluginHttpMethod, type PluginNavItemContract, type PluginEndpointRequestOptions, type PluginEventStreamMessage, type PluginEventStreamOptions, type PluginFormDataPayload, type PluginFormDataValue, type CreatePluginClientOptions, type UseCurrentExperimentOptions, type UseCurrentExperimentReturn, type UsePluginEventStreamReturn, type UsePluginSettingsOptions, type UsePluginSettingsReturn, } from './usePluginClient';
|
|
56
|
+
export { buildPluginEndpointUrl, createPluginClient, downloadBlob, downloadPluginEndpoint, getPluginPageSelectorItems, pluginFormDataFromPayload, resolvePluginBaseUrl, uploadPluginEndpoint, usePluginClient, usePluginEventStream, usePluginSettings, useCurrentExperiment, type BuildPluginEndpointUrlOptions, type DownloadBlobOptions, type DownloadPluginEndpointOptions, type PluginContract, type PluginClientRequestOptions, type PluginEndpointContract, type PluginEndpointDefinition, type PluginHttpMethod, type PluginNavItemContract, type PluginEndpointRequestOptions, type PluginEventStreamMessage, type PluginEventStreamOptions, type PluginFormDataPayload, type PluginFormDataValue, type CreatePluginClientOptions, type UseCurrentExperimentOptions, type UseCurrentExperimentReturn, type UsePluginEventStreamReturn, type UsePluginSettingsOptions, type UsePluginSettingsReturn, } from './usePluginClient';
|
|
56
57
|
export { useJobsStatusTray, type JobsStatusTrayAdapter, type JobsStatusTrayTab, type JobStreamMessage, type UseJobsStatusTrayOptions, type UseJobsStatusTrayReturn, } from './useJobsStatusTray';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "../BaseSelect-ekgr9fDo.js";
|
|
2
2
|
import { $ as parseTime, A as useConcentrationUnits, C as controlsToViewIds, D as getTypeDefault, E as getFieldRegistryEntry, F as ATOMIC_WEIGHTS, G as findAvailableSlots, H as addMinutes, I as useChemicalFormula, J as formatTime, K as findNearestTimeSlotIndex, N as useSequenceUtils, Q as isTimeInRange, S as controlsToTopBarSettingsConfig, T as getDefaultControlView, U as compareTime, W as durationMinutes, X as fromMinutes, Y as formatTimeSlot, Z as generateTimeSlots, _ as controlsToFormSchema, a as defineDoseCalculatorControlProps, b as controlsToSettingsSchema, c as defineWellPlateDoseComponentBindings, d as defineControlModel, et as rangesOverlap, h as controlValuesToComponentProps, i as useControlSchema, l as defineWellPlateDoseControlProps, m as controlValuesToComponentBindingsById, n as defineControls, nt as toMinutes, o as defineDoseDesignControlModel, ot as useListSelection, p as controlValuesToComponentBindings, q as formatDuration, r as getControlDefaults, rt as useTimeUtils, s as defineWellPlateControlProps, st as useSelectionLimit, t as defineControlComponentBindings, tt as snapToSlot, u as useControlWorkspace, v as controlsToSectionFormSchema, w as controlsToViewItems, x as controlsToSidebarPanels, y as controlsToSectionFormSchemas } from "../useControlSchema-BZNdalmL.js";
|
|
3
3
|
import { t as useEventListener } from "../useEventListener-CfVkP9Xz.js";
|
|
4
|
-
import { $ as useTheme, A as useExpansionSet, B as extractSamplesFromDesignData, C as useExperimentSave, E as useExperimentData, F as detectDelimiter, G as unwrapExperimentDesignData, I as parseDelimitedText, J as useDoseCalculator, K as DEFAULT_COLORS, L as readFileAsText, Q as useAppExperiment, R as useFileImport, S as useTemplateCollection, T as useExperimentSamples, U as extractSampleNamesFromDesignData, V as useAutoGroup, W as extractSampleOptionsFromDesignData, X as useMobileSupportGate, Y as DEFAULT_MOBILE_VIEWPORT_QUERY, Z as APP_EXPERIMENT_KEY, _ as useBioTemplateWorkspace, at as useSortedItems, b as useBioTemplateComponents, c as useProtocolTemplates, d as generateDilutionSeries, et as useToast, f as useReagentSeries, g as useBioTemplatePackWorkspace, h as useBioTemplatePresetWorkspace, it as compareSortValues, j as useSampleGroups, l as DEFAULT_PRESETS, m as useRackEditor, nt as normalizeSearchQuery, p as useGroupAssignment, q as useWellPlateEditor, rt as useTextSearch, t as useJobsStatusTray, tt as candidateMatchesSearch, u as DEFAULT_UNITS, v as getBioTemplateComponentProps, w as useScheduleDrag, x as useBioTemplateControls, y as toBioTemplateComponentPropsByComponent, z as validateImportFile } from "../useJobsStatusTray-
|
|
4
|
+
import { $ as useTheme, A as useExpansionSet, B as extractSamplesFromDesignData, C as useExperimentSave, E as useExperimentData, F as detectDelimiter, G as unwrapExperimentDesignData, I as parseDelimitedText, J as useDoseCalculator, K as DEFAULT_COLORS, L as readFileAsText, Q as useAppExperiment, R as useFileImport, S as useTemplateCollection, T as useExperimentSamples, U as extractSampleNamesFromDesignData, V as useAutoGroup, W as extractSampleOptionsFromDesignData, X as useMobileSupportGate, Y as DEFAULT_MOBILE_VIEWPORT_QUERY, Z as APP_EXPERIMENT_KEY, _ as useBioTemplateWorkspace, at as useSortedItems, b as useBioTemplateComponents, c as useProtocolTemplates, d as generateDilutionSeries, et as useToast, f as useReagentSeries, g as useBioTemplatePackWorkspace, h as useBioTemplatePresetWorkspace, it as compareSortValues, j as useSampleGroups, l as DEFAULT_PRESETS, m as useRackEditor, nt as normalizeSearchQuery, p as useGroupAssignment, q as useWellPlateEditor, rt as useTextSearch, t as useJobsStatusTray, tt as candidateMatchesSearch, u as DEFAULT_UNITS, v as getBioTemplateComponentProps, w as useScheduleDrag, x as useBioTemplateControls, y as toBioTemplateComponentPropsByComponent, z as validateImportFile } from "../useJobsStatusTray-CVecN6Ao.js";
|
|
5
5
|
import { i as usePlatformContext, n as evaluateCondition, r as useForm, t as useFormBuilder } from "../useFormBuilder-DKekvXRs.js";
|
|
6
6
|
import { a as SORT_OPTIONS, c as formatExperimentStatus, i as EXPERIMENT_STATUS_VARIANT_MAP, l as getExperimentStatusVariant, n as EXPERIMENT_STATUS_LABELS, o as datePresetToISO, r as EXPERIMENT_STATUS_OPTIONS, s as formatExperimentDate, t as DATE_PRESET_OPTIONS, u as resolveExperimentCode } from "../experiment-utils-Bfa7CwPU.js";
|
|
7
|
-
import { i as
|
|
7
|
+
import { i as AuthenticationRequiredError, n as useDebouncedWatch, o as useApi, r as useRequestSyncState, t as useExperimentSelector } from "../useExperimentSelector-DRbj6vse.js";
|
|
8
8
|
import { B as toBioTemplateComponentProps, H as toBioTemplateComponentPropsById, L as toBioTemplateComponentBindings, P as getBioTemplateComponentBindings, R as toBioTemplateComponentBindingsById, l as requireBioTemplateControlSchema, o as getBioTemplateControlSchema } from "../templates-CNbPQNID.js";
|
|
9
|
-
import { A as
|
|
10
|
-
export { APP_EXPERIMENT_KEY, ATOMIC_WEIGHTS, DATE_PRESET_OPTIONS, DEFAULT_COLORS, DEFAULT_MOBILE_VIEWPORT_QUERY, DEFAULT_PRESETS, DEFAULT_UNITS, EXPERIMENT_STATUS_LABELS, EXPERIMENT_STATUS_OPTIONS, EXPERIMENT_STATUS_VARIANT_MAP, SORT_OPTIONS, addMinutes, buildPluginEndpointUrl, candidateMatchesSearch, compareSortValues, compareTime, controlValuesToComponentBindings, controlValuesToComponentBindingsById, controlValuesToComponentProps, controlsToFormSchema, controlsToSectionFormSchema, controlsToSectionFormSchemas, controlsToSettingsSchema, controlsToSidebarPanels, controlsToTopBarSettingsConfig, controlsToViewIds, controlsToViewItems, coordinateToWellId, createColumnConditions, createPluginClient, createPluginResourceClient, createRowConditions, createWellPlateWells, datePresetToISO, defineControlComponentBindings, defineControlModel, defineControls, defineDoseCalculatorControlProps, defineDoseDesignControlModel, defineWellPlateControlProps, defineWellPlateDoseComponentBindings, defineWellPlateDoseControlProps, detectDelimiter, downloadBlob, downloadPluginEndpoint, durationMinutes, evaluateCondition, extractSampleNamesFromDesignData, extractSampleOptionsFromDesignData, extractSamplesFromDesignData, findAvailableSlots, findNearestTimeSlotIndex, formatDuration, formatExperimentDate, formatExperimentStatus, formatTime, formatTimeSlot, fromMinutes, generateDilutionSeries, generateTimeSlots, getBioTemplateComponentBindings, getBioTemplateComponentProps, getBioTemplateControlSchema, getControlDefaults, getDefaultControlView, getExperimentStatusVariant, getFieldRegistryEntry, getPluginPageSelectorItems, getTypeDefault, isTimeInRange, normalizeSearchQuery, parseDelimitedText, parseTime, pluginFormDataFromPayload, rangesOverlap, readFileAsText, requireBioTemplateControlSchema, resolveExperimentCode, resolvePluginBaseUrl, runWellPlateValidation, snapToSlot, toBioTemplateComponentBindings, toBioTemplateComponentBindingsById, toBioTemplateComponentProps, toBioTemplateComponentPropsByComponent, toBioTemplateComponentPropsById, toMinutes, unwrapExperimentDesignData, uploadPluginEndpoint, useApi, useAppExperiment, useAsync, useAsyncBatch, useAuth, useAutoGroup, useBioTemplateComponents, useBioTemplateControls, useBioTemplatePackWorkspace, useBioTemplatePresetWorkspace, useBioTemplateWorkspace, useChemicalFormula, useCommandHistory, useConcentrationUnits, useControlSchema, useControlWorkspace, useCurrentExperiment, useDebouncedWatch, useDoseCalculator, useEventListener, useExpansionSet, useExperimentData, useExperimentSamples, useExperimentSave, useExperimentSelector, useFileImport, useForm, useFormBuilder, useGroupAssignment, useJobsStatusTray, useListSelection, useMobileSupportGate, useOptimisticMutation, usePasskey, usePlatformContext, usePluginClient, usePluginConfig, usePluginEventStream, usePluginSettings, useProtocolTemplates, useRackEditor, useReagentSeries, useRequestSyncState, useResourceCrud, useSampleGroups, useScheduleDrag, useSelectionLimit, useSequenceUtils, useSortedItems, useTemplateCollection, useTextSearch, useTheme, useTimeUtils, useToast, useWellPainting, useWellPlateAdapter, useWellPlateEditor, useWellPlateValidation, validateImportFile, wellIdToCoordinate, wellIdsInRectangle };
|
|
9
|
+
import { A as resolvePluginFrontendBase, C as createPluginResourceClient, D as usePluginConfig, E as useCommandHistory, M as useAuth, O as useAsync, S as wellIdsInRectangle, T as useOptimisticMutation, _ as createWellPlateWells, a as pluginFormDataFromPayload, b as useWellPainting, c as usePluginClient, d as buildPluginEndpointUrl, f as resolvePluginBaseUrl, g as createRowConditions, h as createColumnConditions, i as getPluginPageSelectorItems, j as usePasskey, k as useAsyncBatch, l as usePluginEventStream, m as useWellPlateValidation, n as downloadBlob, o as uploadPluginEndpoint, p as runWellPlateValidation, r as downloadPluginEndpoint, s as useCurrentExperiment, t as createPluginClient, u as usePluginSettings, v as useWellPlateAdapter, w as useResourceCrud, x as wellIdToCoordinate, y as coordinateToWellId } from "../composables-TpXyhRZZ.js";
|
|
10
|
+
export { APP_EXPERIMENT_KEY, ATOMIC_WEIGHTS, AuthenticationRequiredError, DATE_PRESET_OPTIONS, DEFAULT_COLORS, DEFAULT_MOBILE_VIEWPORT_QUERY, DEFAULT_PRESETS, DEFAULT_UNITS, EXPERIMENT_STATUS_LABELS, EXPERIMENT_STATUS_OPTIONS, EXPERIMENT_STATUS_VARIANT_MAP, SORT_OPTIONS, addMinutes, buildPluginEndpointUrl, candidateMatchesSearch, compareSortValues, compareTime, controlValuesToComponentBindings, controlValuesToComponentBindingsById, controlValuesToComponentProps, controlsToFormSchema, controlsToSectionFormSchema, controlsToSectionFormSchemas, controlsToSettingsSchema, controlsToSidebarPanels, controlsToTopBarSettingsConfig, controlsToViewIds, controlsToViewItems, coordinateToWellId, createColumnConditions, createPluginClient, createPluginResourceClient, createRowConditions, createWellPlateWells, datePresetToISO, defineControlComponentBindings, defineControlModel, defineControls, defineDoseCalculatorControlProps, defineDoseDesignControlModel, defineWellPlateControlProps, defineWellPlateDoseComponentBindings, defineWellPlateDoseControlProps, detectDelimiter, downloadBlob, downloadPluginEndpoint, durationMinutes, evaluateCondition, extractSampleNamesFromDesignData, extractSampleOptionsFromDesignData, extractSamplesFromDesignData, findAvailableSlots, findNearestTimeSlotIndex, formatDuration, formatExperimentDate, formatExperimentStatus, formatTime, formatTimeSlot, fromMinutes, generateDilutionSeries, generateTimeSlots, getBioTemplateComponentBindings, getBioTemplateComponentProps, getBioTemplateControlSchema, getControlDefaults, getDefaultControlView, getExperimentStatusVariant, getFieldRegistryEntry, getPluginPageSelectorItems, getTypeDefault, isTimeInRange, normalizeSearchQuery, parseDelimitedText, parseTime, pluginFormDataFromPayload, rangesOverlap, readFileAsText, requireBioTemplateControlSchema, resolveExperimentCode, resolvePluginBaseUrl, resolvePluginFrontendBase, runWellPlateValidation, snapToSlot, toBioTemplateComponentBindings, toBioTemplateComponentBindingsById, toBioTemplateComponentProps, toBioTemplateComponentPropsByComponent, toBioTemplateComponentPropsById, toMinutes, unwrapExperimentDesignData, uploadPluginEndpoint, useApi, useAppExperiment, useAsync, useAsyncBatch, useAuth, useAutoGroup, useBioTemplateComponents, useBioTemplateControls, useBioTemplatePackWorkspace, useBioTemplatePresetWorkspace, useBioTemplateWorkspace, useChemicalFormula, useCommandHistory, useConcentrationUnits, useControlSchema, useControlWorkspace, useCurrentExperiment, useDebouncedWatch, useDoseCalculator, useEventListener, useExpansionSet, useExperimentData, useExperimentSamples, useExperimentSave, useExperimentSelector, useFileImport, useForm, useFormBuilder, useGroupAssignment, useJobsStatusTray, useListSelection, useMobileSupportGate, useOptimisticMutation, usePasskey, usePlatformContext, usePluginClient, usePluginConfig, usePluginEventStream, usePluginSettings, useProtocolTemplates, useRackEditor, useReagentSeries, useRequestSyncState, useResourceCrud, useSampleGroups, useScheduleDrag, useSelectionLimit, useSequenceUtils, useSortedItems, useTemplateCollection, useTextSearch, useTheme, useTimeUtils, useToast, useWellPainting, useWellPlateAdapter, useWellPlateEditor, useWellPlateValidation, validateImportFile, wellIdToCoordinate, wellIdsInRectangle };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the Vue Router base for a plugin frontend.
|
|
3
|
+
*
|
|
4
|
+
* Integrated plugins use the platform-injected mount prefix. Standalone and
|
|
5
|
+
* development builds retain the caller's Vite base unchanged.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolvePluginFrontendBase(fallbackBase?: string): string;
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { AxiosInstance, AxiosRequestConfig } from 'axios';
|
|
2
|
+
/** Raised when an authenticated SDK request is rejected because the login is no longer valid. */
|
|
3
|
+
export declare class AuthenticationRequiredError extends Error {
|
|
4
|
+
readonly cause?: unknown | undefined;
|
|
5
|
+
readonly code = "AUTHENTICATION_REQUIRED";
|
|
6
|
+
readonly status = 401;
|
|
7
|
+
constructor(cause?: unknown | undefined);
|
|
8
|
+
}
|
|
9
|
+
/** @internal Convert a rejected authenticated request into the SDK's public auth error. */
|
|
10
|
+
export declare function authenticationRequiredError(cause: unknown, rejectedToken?: string): AuthenticationRequiredError;
|
|
2
11
|
export interface ApiClientOptions {
|
|
3
12
|
baseUrl?: string;
|
|
4
13
|
timeout?: number;
|
|
@@ -9,7 +9,9 @@ export interface PluginEndpointContract {
|
|
|
9
9
|
pathParams?: PluginEndpointParamContract[];
|
|
10
10
|
queryParams?: PluginEndpointParamContract[];
|
|
11
11
|
requestType?: string | null;
|
|
12
|
+
requestContentType?: string | null;
|
|
12
13
|
responseType?: string | null;
|
|
14
|
+
responseContentType?: string | null;
|
|
13
15
|
eventStream?: boolean;
|
|
14
16
|
}
|
|
15
17
|
export interface PluginEndpointParamContract {
|
|
@@ -58,8 +60,10 @@ export interface PluginEndpointDefinition {
|
|
|
58
60
|
pathParams?: PluginEndpointParamDefinition[];
|
|
59
61
|
queryParams?: PluginEndpointParamDefinition[];
|
|
60
62
|
hasBody?: boolean;
|
|
63
|
+
requestContentType?: string | null;
|
|
61
64
|
eventStream?: boolean;
|
|
62
65
|
responseType?: string | null;
|
|
66
|
+
responseContentType?: string | null;
|
|
63
67
|
}
|
|
64
68
|
export type PluginEndpointParamDefinition = string | {
|
|
65
69
|
name: string;
|
|
@@ -80,6 +84,12 @@ export interface BuildPluginEndpointUrlOptions {
|
|
|
80
84
|
export interface PluginEndpointRequestOptions {
|
|
81
85
|
/** Override the generated or platform-injected API base URL. */
|
|
82
86
|
baseUrl?: string;
|
|
87
|
+
/** Cancel the request without changing its endpoint or authentication behavior. */
|
|
88
|
+
signal?: AbortSignal;
|
|
89
|
+
}
|
|
90
|
+
export interface PluginClientRequestOptions {
|
|
91
|
+
/** Cancel the generated endpoint request. */
|
|
92
|
+
signal?: AbortSignal;
|
|
83
93
|
}
|
|
84
94
|
export interface DownloadPluginEndpointOptions extends PluginEndpointRequestOptions {
|
|
85
95
|
/** Browser download filename. When omitted, the blob is returned without triggering a download. */
|
|
@@ -189,7 +199,7 @@ export interface UseCurrentExperimentReturn<TExperiment = ExperimentSummary> {
|
|
|
189
199
|
/** Refetch the currently resolved experiment id. */
|
|
190
200
|
refresh: () => Promise<TExperiment | undefined>;
|
|
191
201
|
}
|
|
192
|
-
export type PluginEndpointCaller = (
|
|
202
|
+
export type PluginEndpointCaller = (payloadOrOptions?: unknown, options?: PluginClientRequestOptions) => Promise<unknown>;
|
|
193
203
|
export type GeneratedPluginClient = Record<string, (...args: any[]) => Promise<any>>;
|
|
194
204
|
/** Convert plain upload payloads into FormData using the same encoding across generated plugin clients. */
|
|
195
205
|
export declare function pluginFormDataFromPayload(payload: unknown): FormData;
|
|
@@ -199,7 +209,7 @@ export declare function downloadBlob(blob: Blob, filename: string, options?: Dow
|
|
|
199
209
|
export declare function getPluginPageSelectorItems(contract: PluginContract): PageSelectorItem[];
|
|
200
210
|
/** Create a typed plugin API client from a generated MINT plugin contract. */
|
|
201
211
|
export declare function createPluginClient<TClient extends object = GeneratedPluginClient>(contract: PluginContract, options: CreatePluginClientOptions): TClient;
|
|
202
|
-
/** Send multipart
|
|
212
|
+
/** Send multipart or raw binary data to a generated endpoint with contract URL, cancellation, and auth handling. */
|
|
203
213
|
export declare function uploadPluginEndpoint<TResponse = unknown>(contract: PluginContract, endpoint: PluginEndpointDefinition, payload?: unknown, options?: PluginEndpointRequestOptions): Promise<TResponse>;
|
|
204
214
|
/** Fetch a generated plugin endpoint as a Blob and optionally trigger a browser download. */
|
|
205
215
|
export declare function downloadPluginEndpoint(contract: PluginContract, endpoint: PluginEndpointDefinition, payload?: unknown, options?: DownloadPluginEndpointOptions): Promise<Blob>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { D as currentExperimentFromContext, O as getInjectedPlatformContext, k as resolveCurrentExperimentId } from "./useJobsStatusTray-
|
|
1
|
+
import { D as currentExperimentFromContext, O as getInjectedPlatformContext, k as resolveCurrentExperimentId } from "./useJobsStatusTray-CVecN6Ao.js";
|
|
2
2
|
import { r as useSettingsStore, t as useAuthStore } from "./auth-DZAwEeis.js";
|
|
3
3
|
import { i as usePlatformContext } from "./useFormBuilder-DKekvXRs.js";
|
|
4
|
-
import { i as useApi, r as useRequestSyncState } from "./useExperimentSelector-
|
|
4
|
+
import { a as authenticationRequiredError, i as AuthenticationRequiredError, o as useApi, r as useRequestSyncState } from "./useExperimentSelector-DRbj6vse.js";
|
|
5
5
|
import { computed, getCurrentInstance, onMounted, onUnmounted, ref, shallowRef, toValue, watch } from "vue";
|
|
6
6
|
import axios from "axios";
|
|
7
7
|
//#region src/composables/useAuth.ts
|
|
@@ -394,6 +394,25 @@ function usePasskey() {
|
|
|
394
394
|
};
|
|
395
395
|
}
|
|
396
396
|
//#endregion
|
|
397
|
+
//#region src/composables/pluginFrontendBase.ts
|
|
398
|
+
function normalizePluginRoutePrefix(prefix) {
|
|
399
|
+
const candidate = prefix?.trim();
|
|
400
|
+
if (!candidate) return void 0;
|
|
401
|
+
const path = candidate.split("/").filter(Boolean).join("/");
|
|
402
|
+
return path ? `/${path}/` : "/";
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Resolve the Vue Router base for a plugin frontend.
|
|
406
|
+
*
|
|
407
|
+
* Integrated plugins use the platform-injected mount prefix. Standalone and
|
|
408
|
+
* development builds retain the caller's Vite base unchanged.
|
|
409
|
+
*/
|
|
410
|
+
function resolvePluginFrontendBase(fallbackBase = "/") {
|
|
411
|
+
const context = getInjectedPlatformContext();
|
|
412
|
+
if (!context?.isIntegrated) return fallbackBase;
|
|
413
|
+
return normalizePluginRoutePrefix(context.plugin?.route_prefix) ?? fallbackBase;
|
|
414
|
+
}
|
|
415
|
+
//#endregion
|
|
397
416
|
//#region src/composables/useAsync.ts
|
|
398
417
|
/**
|
|
399
418
|
* Default error transformer.
|
|
@@ -1206,6 +1225,13 @@ function endpointParamName(param) {
|
|
|
1206
1225
|
function endpointParamFieldName(param) {
|
|
1207
1226
|
return typeof param === "string" ? param : param.fieldName ?? param.name;
|
|
1208
1227
|
}
|
|
1228
|
+
function escapeRegExp(value) {
|
|
1229
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1230
|
+
}
|
|
1231
|
+
function replacePathParam(path, name, encoded) {
|
|
1232
|
+
const escapedName = escapeRegExp(name);
|
|
1233
|
+
return path.replace(new RegExp(`\\{${escapedName}(?::[^{}]+)?\\}`, "g"), () => encoded).replace(new RegExp(`:${escapedName}(?=/|$)`, "g"), () => encoded);
|
|
1234
|
+
}
|
|
1209
1235
|
/** Resolve the runtime plugin API base URL from env, explicit options, platform injection, or contract metadata. */
|
|
1210
1236
|
function resolvePluginBaseUrl(contract, explicitBaseUrl) {
|
|
1211
1237
|
if (explicitBaseUrl) return normalizeApiBaseUrl(explicitBaseUrl) ?? explicitBaseUrl;
|
|
@@ -1222,12 +1248,8 @@ function encodePath(path, payload, pathParams) {
|
|
|
1222
1248
|
const value = payload[fieldName] ?? payload[name];
|
|
1223
1249
|
if (value === void 0 || value === null) throw new Error(`[MINT SDK] Missing path parameter '${fieldName}' for plugin endpoint ${path}`);
|
|
1224
1250
|
const encoded = encodeURIComponent(String(value));
|
|
1225
|
-
nextPath = nextPath
|
|
1226
|
-
nextPath = nextPath
|
|
1227
|
-
if (fieldName !== name) {
|
|
1228
|
-
nextPath = nextPath.replace(`{${fieldName}}`, encoded);
|
|
1229
|
-
nextPath = nextPath.replace(`:${fieldName}`, encoded);
|
|
1230
|
-
}
|
|
1251
|
+
nextPath = replacePathParam(nextPath, name, encoded);
|
|
1252
|
+
if (fieldName !== name) nextPath = replacePathParam(nextPath, fieldName, encoded);
|
|
1231
1253
|
}
|
|
1232
1254
|
return nextPath;
|
|
1233
1255
|
}
|
|
@@ -1347,9 +1369,26 @@ function buildPluginEndpointUrl(contract, endpoint, payload, options = {}) {
|
|
|
1347
1369
|
function queryConfig(query) {
|
|
1348
1370
|
return hasKeys(query) ? { params: query } : void 0;
|
|
1349
1371
|
}
|
|
1372
|
+
var OCTET_STREAM = "application/octet-stream";
|
|
1373
|
+
var MULTIPART_FORM_DATA = "multipart/form-data";
|
|
1374
|
+
function endpointRequestConfig(endpoint, query, options) {
|
|
1375
|
+
const config = {};
|
|
1376
|
+
if (hasKeys(query)) config.params = query;
|
|
1377
|
+
if (endpoint.requestContentType === OCTET_STREAM) config.headers = { "Content-Type": OCTET_STREAM };
|
|
1378
|
+
if (endpoint.requestContentType === MULTIPART_FORM_DATA) config.headers = { "Content-Type": void 0 };
|
|
1379
|
+
if (endpoint.responseContentType === OCTET_STREAM) config.responseType = "blob";
|
|
1380
|
+
if (options?.signal) config.signal = options.signal;
|
|
1381
|
+
return hasKeys(config) ? config : void 0;
|
|
1382
|
+
}
|
|
1350
1383
|
function isFormData(value) {
|
|
1351
1384
|
return typeof FormData !== "undefined" && value instanceof FormData;
|
|
1352
1385
|
}
|
|
1386
|
+
function endpointRequestBody(endpoint, body) {
|
|
1387
|
+
return endpoint.requestContentType === MULTIPART_FORM_DATA ? pluginFormDataFromPayload(body) : body;
|
|
1388
|
+
}
|
|
1389
|
+
function endpointHasPayload(endpoint) {
|
|
1390
|
+
return Boolean(endpoint.hasBody || endpoint.pathParams?.length || endpoint.queryParams?.length);
|
|
1391
|
+
}
|
|
1353
1392
|
function isBlob(value) {
|
|
1354
1393
|
return typeof Blob !== "undefined" && value instanceof Blob;
|
|
1355
1394
|
}
|
|
@@ -1411,28 +1450,32 @@ function getPluginPageSelectorItems(contract) {
|
|
|
1411
1450
|
/** Create a typed plugin API client from a generated MINT plugin contract. */
|
|
1412
1451
|
function createPluginClient(contract, options) {
|
|
1413
1452
|
const client = {};
|
|
1414
|
-
for (const [name, endpoint] of Object.entries(options.endpoints)) client[name] = async (
|
|
1453
|
+
for (const [name, endpoint] of Object.entries(options.endpoints)) client[name] = async (payloadOrOptions, explicitOptions) => {
|
|
1454
|
+
const hasPayload = endpointHasPayload(endpoint);
|
|
1455
|
+
const payload = hasPayload ? payloadOrOptions : void 0;
|
|
1456
|
+
const callOptions = hasPayload ? explicitOptions : payloadOrOptions ?? explicitOptions;
|
|
1415
1457
|
const parts = pluginEndpointRequestParts(contract, endpoint, payload, options.baseUrl);
|
|
1416
1458
|
const api = useApi({ baseUrl: parts.baseUrl });
|
|
1417
|
-
const
|
|
1418
|
-
if (endpoint.method === "get") return api.get(parts.path,
|
|
1459
|
+
const config = endpointRequestConfig(endpoint, parts.query, callOptions);
|
|
1460
|
+
if (endpoint.method === "get") return api.get(parts.path, config);
|
|
1419
1461
|
if (endpoint.method === "delete") {
|
|
1420
|
-
const
|
|
1421
|
-
const
|
|
1422
|
-
|
|
1462
|
+
const rawBody = requestBodyFromPayload(payload, parts.requestPayload, endpoint);
|
|
1463
|
+
const body = rawBody === void 0 ? void 0 : endpointRequestBody(endpoint, rawBody);
|
|
1464
|
+
const config = body === void 0 ? endpointRequestConfig(endpoint, parts.query, callOptions) : {
|
|
1465
|
+
...endpointRequestConfig(endpoint, parts.query, callOptions),
|
|
1423
1466
|
data: body
|
|
1424
1467
|
};
|
|
1425
1468
|
return api.delete(parts.path, config);
|
|
1426
1469
|
}
|
|
1427
|
-
const body = requestBodyFromPayload(payload, parts.requestPayload, endpoint);
|
|
1428
|
-
if (endpoint.method === "post") return api.post(parts.path, body,
|
|
1429
|
-
if (endpoint.method === "put") return api.put(parts.path, body,
|
|
1430
|
-
if (endpoint.method === "patch") return api.patch(parts.path, body,
|
|
1470
|
+
const body = endpointRequestBody(endpoint, requestBodyFromPayload(payload, parts.requestPayload, endpoint));
|
|
1471
|
+
if (endpoint.method === "post") return api.post(parts.path, body, config);
|
|
1472
|
+
if (endpoint.method === "put") return api.put(parts.path, body, config);
|
|
1473
|
+
if (endpoint.method === "patch") return api.patch(parts.path, body, config);
|
|
1431
1474
|
throw new Error(`[MINT SDK] Unsupported plugin endpoint method: ${endpoint.method}`);
|
|
1432
1475
|
};
|
|
1433
1476
|
return client;
|
|
1434
1477
|
}
|
|
1435
|
-
/** Send multipart
|
|
1478
|
+
/** Send multipart or raw binary data to a generated endpoint with contract URL, cancellation, and auth handling. */
|
|
1436
1479
|
async function uploadPluginEndpoint(contract, endpoint, payload, options = {}) {
|
|
1437
1480
|
if (![
|
|
1438
1481
|
"post",
|
|
@@ -1441,9 +1484,17 @@ async function uploadPluginEndpoint(contract, endpoint, payload, options = {}) {
|
|
|
1441
1484
|
].includes(endpoint.method)) throw new Error(`[MINT SDK] Plugin upload endpoints must use POST, PUT, or PATCH; got ${endpoint.method}`);
|
|
1442
1485
|
const parts = pluginEndpointRequestParts(contract, endpoint, payload, options.baseUrl);
|
|
1443
1486
|
const api = useApi({ baseUrl: parts.baseUrl });
|
|
1444
|
-
const
|
|
1487
|
+
const body = endpoint.hasBody ? requestBodyFromPayload(payload, parts.requestPayload, endpoint) : payload;
|
|
1488
|
+
if (endpoint.requestContentType === OCTET_STREAM) {
|
|
1489
|
+
const config = endpointRequestConfig(endpoint, parts.query, { signal: options.signal });
|
|
1490
|
+
if (endpoint.method === "post") return api.post(parts.path, body, config);
|
|
1491
|
+
if (endpoint.method === "put") return api.put(parts.path, body, config);
|
|
1492
|
+
return api.patch(parts.path, body, config);
|
|
1493
|
+
}
|
|
1494
|
+
const formData = pluginFormDataFromPayload(body);
|
|
1445
1495
|
const config = {
|
|
1446
1496
|
...queryConfig(parts.query) ?? {},
|
|
1497
|
+
...options.signal ? { signal: options.signal } : {},
|
|
1447
1498
|
headers: { "Content-Type": void 0 }
|
|
1448
1499
|
};
|
|
1449
1500
|
if (endpoint.method === "post") return api.post(parts.path, formData, config);
|
|
@@ -1455,6 +1506,7 @@ async function downloadPluginEndpoint(contract, endpoint, payload, options = {})
|
|
|
1455
1506
|
const parts = pluginEndpointRequestParts(contract, endpoint, payload, options.baseUrl);
|
|
1456
1507
|
const blob = await useApi({ baseUrl: parts.baseUrl }).get(parts.path, {
|
|
1457
1508
|
...queryConfig(parts.query) ?? {},
|
|
1509
|
+
...options.signal ? { signal: options.signal } : {},
|
|
1458
1510
|
responseType: "blob"
|
|
1459
1511
|
});
|
|
1460
1512
|
if (options.filename) downloadBlob(blob, options.filename, { revokeObjectUrlDelayMs: options.revokeObjectUrlDelayMs });
|
|
@@ -1564,13 +1616,17 @@ function usePluginSettings(options = {}) {
|
|
|
1564
1616
|
reset
|
|
1565
1617
|
};
|
|
1566
1618
|
}
|
|
1567
|
-
function
|
|
1619
|
+
function streamRequestAuth(options) {
|
|
1568
1620
|
const headers = new Headers(options.headers);
|
|
1569
1621
|
const authStore = useAuthStore();
|
|
1570
1622
|
if (!authStore.isInitialized) authStore.initialize();
|
|
1571
1623
|
if (authStore.token && !headers.has("Authorization")) headers.set("Authorization", `Bearer ${authStore.token}`);
|
|
1572
1624
|
headers.set("Accept", "text/event-stream");
|
|
1573
|
-
|
|
1625
|
+
const token = authStore.token;
|
|
1626
|
+
return {
|
|
1627
|
+
headers,
|
|
1628
|
+
token: token && headers.get("Authorization") === `Bearer ${token}` ? token : void 0
|
|
1629
|
+
};
|
|
1574
1630
|
}
|
|
1575
1631
|
function parseSseEvent(block, parseJson) {
|
|
1576
1632
|
let event = "message";
|
|
@@ -1659,16 +1715,24 @@ function usePluginEventStream(contract, endpoint, payloadOrOptions, maybeOptions
|
|
|
1659
1715
|
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
1660
1716
|
error.value = null;
|
|
1661
1717
|
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
1718
|
+
let authenticationFailed = false;
|
|
1662
1719
|
try {
|
|
1663
1720
|
const url = buildPluginEndpointUrl(contract, endpoint, payload, { baseUrl: options.baseUrl });
|
|
1721
|
+
const requestAuth = streamRequestAuth(options);
|
|
1664
1722
|
const response = await fetch(url, {
|
|
1665
1723
|
method: "GET",
|
|
1666
|
-
headers:
|
|
1724
|
+
headers: requestAuth.headers,
|
|
1667
1725
|
credentials: options.credentials ?? "same-origin",
|
|
1668
1726
|
signal: connectionController.signal
|
|
1669
1727
|
});
|
|
1670
1728
|
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
1671
|
-
if (!response.ok)
|
|
1729
|
+
if (!response.ok) {
|
|
1730
|
+
if (response.status === 401) {
|
|
1731
|
+
authenticationFailed = true;
|
|
1732
|
+
throw authenticationRequiredError(response, requestAuth.token);
|
|
1733
|
+
}
|
|
1734
|
+
throw new Error(`Plugin event stream failed with HTTP ${response.status}`);
|
|
1735
|
+
}
|
|
1672
1736
|
if (!response.body) throw new Error("Plugin event stream response did not include a readable body.");
|
|
1673
1737
|
isConnected.value = true;
|
|
1674
1738
|
if (!ownsConnection(connectionGeneration, connectionController)) return;
|
|
@@ -1703,6 +1767,7 @@ function usePluginEventStream(contract, endpoint, payloadOrOptions, maybeOptions
|
|
|
1703
1767
|
}
|
|
1704
1768
|
}
|
|
1705
1769
|
} catch (err) {
|
|
1770
|
+
if (err instanceof AuthenticationRequiredError) authenticationFailed = true;
|
|
1706
1771
|
if (ownsConnection(connectionGeneration, connectionController) && !(err instanceof DOMException && err.name === "AbortError")) {
|
|
1707
1772
|
error.value = err instanceof Error ? err.message : "Plugin event stream failed";
|
|
1708
1773
|
if (ownsConnection(connectionGeneration, connectionController)) options.onError?.(err);
|
|
@@ -1714,7 +1779,8 @@ function usePluginEventStream(contract, endpoint, payloadOrOptions, maybeOptions
|
|
|
1714
1779
|
isConnected.value = false;
|
|
1715
1780
|
if (ownsConnection(connectionGeneration, connectionController)) {
|
|
1716
1781
|
controller = null;
|
|
1717
|
-
|
|
1782
|
+
if (authenticationFailed) stopped = true;
|
|
1783
|
+
else scheduleReconnect(connectionGeneration);
|
|
1718
1784
|
}
|
|
1719
1785
|
}
|
|
1720
1786
|
}
|
|
@@ -1737,9 +1803,10 @@ function usePluginEventStream(contract, endpoint, payloadOrOptions, maybeOptions
|
|
|
1737
1803
|
isConnecting.value = false;
|
|
1738
1804
|
isConnected.value = false;
|
|
1739
1805
|
}
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
if (
|
|
1806
|
+
const currentInstance = getCurrentInstance();
|
|
1807
|
+
if (currentInstance && options.immediate !== false && typeof window === "undefined") onMounted(start);
|
|
1808
|
+
if (currentInstance) onUnmounted(stop);
|
|
1809
|
+
if (options.immediate !== false && (typeof window !== "undefined" || !currentInstance)) start();
|
|
1743
1810
|
return {
|
|
1744
1811
|
isConnected,
|
|
1745
1812
|
isConnecting,
|
|
@@ -1808,6 +1875,6 @@ function useCurrentExperiment(options = {}) {
|
|
|
1808
1875
|
};
|
|
1809
1876
|
}
|
|
1810
1877
|
//#endregion
|
|
1811
|
-
export {
|
|
1878
|
+
export { resolvePluginFrontendBase as A, createPluginResourceClient as C, usePluginConfig as D, useCommandHistory as E, useAuth as M, useAsync as O, wellIdsInRectangle as S, useOptimisticMutation as T, createWellPlateWells as _, pluginFormDataFromPayload as a, useWellPainting as b, usePluginClient as c, buildPluginEndpointUrl as d, resolvePluginBaseUrl as f, createRowConditions as g, createColumnConditions as h, getPluginPageSelectorItems as i, usePasskey as j, useAsyncBatch as k, usePluginEventStream as l, useWellPlateValidation as m, downloadBlob as n, uploadPluginEndpoint as o, runWellPlateValidation as p, downloadPluginEndpoint as r, useCurrentExperiment as s, createPluginClient as t, usePluginSettings as u, useWellPlateAdapter as v, useResourceCrud as w, wellIdToCoordinate as x, coordinateToWellId as y };
|
|
1812
1879
|
|
|
1813
|
-
//# sourceMappingURL=composables-
|
|
1880
|
+
//# sourceMappingURL=composables-TpXyhRZZ.js.map
|