@morscherlab/mint-sdk 1.0.0-rc.4 → 1.0.0-rc.5

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.
Files changed (304) hide show
  1. package/dist/__tests__/components/AppTopBar.navigation.test.d.ts +1 -0
  2. package/dist/__tests__/components/DoseCalculatorVolumeField.test.d.ts +1 -0
  3. package/dist/__tests__/components/PlateMapEditorToolbarInternal.test.d.ts +1 -0
  4. package/dist/__tests__/components/PluginWorkspaceView.controls.test.d.ts +1 -0
  5. package/dist/__tests__/components/PluginWorkspaceView.navigation.test.d.ts +1 -0
  6. package/dist/__tests__/components/PluginWorkspaceView.shell.test.d.ts +1 -0
  7. package/dist/__tests__/components/ProtocolStep.presentation.test.d.ts +1 -0
  8. package/dist/__tests__/components/ProtocolStepEditor.state.test.d.ts +1 -0
  9. package/dist/__tests__/components/ProtocolStepParameterField.test.d.ts +1 -0
  10. package/dist/__tests__/components/ReagentList.presentation.test.d.ts +1 -0
  11. package/dist/__tests__/components/SampleSelector.colors.test.d.ts +1 -0
  12. package/dist/__tests__/components/SampleSelector.drag.test.d.ts +1 -0
  13. package/dist/__tests__/components/SampleSelector.groups.test.d.ts +1 -0
  14. package/dist/__tests__/components/SampleSelector.selection.test.d.ts +1 -0
  15. package/dist/__tests__/components/SampleSelectorSampleRow.test.d.ts +1 -0
  16. package/dist/__tests__/components/ScheduleCalendar.test.d.ts +1 -0
  17. package/dist/__tests__/components/SettingsModal.schema.test.d.ts +1 -0
  18. package/dist/__tests__/components/WellPlate.colors.test.d.ts +1 -0
  19. package/dist/__tests__/components/WellPlate.conditions.test.d.ts +1 -0
  20. package/dist/__tests__/components/WellPlate.geometry.test.d.ts +1 -0
  21. package/dist/__tests__/components/WellPlate.interaction.test.d.ts +1 -0
  22. package/dist/__tests__/components/WellPlate.legend.test.d.ts +1 -0
  23. package/dist/__tests__/components/WellPlate.rendering.test.d.ts +1 -0
  24. package/dist/__tests__/components/WellPlate.sampleDrop.test.d.ts +1 -0
  25. package/dist/__tests__/composables/autoGroup/classify.test.d.ts +1 -0
  26. package/dist/__tests__/composables/autoGroup/columns.test.d.ts +1 -0
  27. package/dist/__tests__/composables/autoGroup/compose.test.d.ts +1 -0
  28. package/dist/__tests__/composables/autoGroup/cooccurrence.test.d.ts +1 -0
  29. package/dist/__tests__/composables/autoGroup/fingerprint.test.d.ts +1 -0
  30. package/dist/__tests__/composables/autoGroup/integration.test.d.ts +1 -0
  31. package/dist/__tests__/composables/autoGroup/template.test.d.ts +1 -0
  32. package/dist/__tests__/composables/autoGroup/tokenize.test.d.ts +1 -0
  33. package/dist/__tests__/composables/useAutoGroupInputSources.test.d.ts +1 -0
  34. package/dist/__tests__/composables/useScheduleCalendarLayout.test.d.ts +1 -0
  35. package/dist/__tests__/docs/extractDocsComponents.test.d.ts +1 -0
  36. package/dist/__tests__/docs/extractDocsExports.test.d.ts +1 -0
  37. package/dist/__tests__/docs/extractDocsParsing.test.d.ts +1 -0
  38. package/dist/__tests__/docs/extractDocsTemplates.test.d.ts +1 -0
  39. package/dist/__tests__/docs/extractDocsTheme.test.d.ts +1 -0
  40. package/dist/components/AppSidebar.vue.d.ts +3 -3
  41. package/dist/components/AppTopBar.navigation.d.ts +11 -0
  42. package/dist/components/BaseButton.vue.d.ts +1 -1
  43. package/dist/components/BaseCheckbox.vue.d.ts +1 -1
  44. package/dist/components/BaseInput.vue.d.ts +2 -2
  45. package/dist/components/BasePill.vue.d.ts +1 -1
  46. package/dist/components/BaseRadioGroup.vue.d.ts +1 -1
  47. package/dist/components/BaseSelect.vue.d.ts +1 -1
  48. package/dist/components/BaseSlider.vue.d.ts +2 -2
  49. package/dist/components/BaseTextarea.vue.d.ts +2 -2
  50. package/dist/components/BaseToggle.vue.d.ts +1 -1
  51. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +2 -2
  52. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +1 -1
  53. package/dist/components/ColorSlider.vue.d.ts +2 -2
  54. package/dist/components/ConcentrationInput.vue.d.ts +2 -2
  55. package/dist/components/ControlWorkspaceView.vue.d.ts +3 -3
  56. package/dist/components/DatePicker.vue.d.ts +1 -1
  57. package/dist/components/DateTimePicker.vue.d.ts +2 -2
  58. package/dist/components/DoseCalculatorVolumeField.vue.d.ts +15 -0
  59. package/dist/components/DoseDesignWorkspaceView.vue.d.ts +1 -1
  60. package/dist/components/DropdownButton.vue.d.ts +1 -1
  61. package/dist/components/FileUploader.vue.d.ts +2 -2
  62. package/dist/components/FormulaInput.vue.d.ts +2 -2
  63. package/dist/components/IconButton.vue.d.ts +1 -1
  64. package/dist/components/LoadingSpinner.vue.d.ts +1 -1
  65. package/dist/components/MoleculeInput.vue.d.ts +2 -2
  66. package/dist/components/MultiSelect.vue.d.ts +1 -1
  67. package/dist/components/NumberInput.vue.d.ts +1 -1
  68. package/dist/components/PlateMapEditor.vue.d.ts +6 -6
  69. package/dist/components/PluginWorkspaceView.controls.d.ts +28 -0
  70. package/dist/components/PluginWorkspaceView.navigation.d.ts +29 -0
  71. package/dist/components/PluginWorkspaceView.props.d.ts +151 -0
  72. package/dist/components/PluginWorkspaceView.shell.d.ts +19 -0
  73. package/dist/components/PluginWorkspaceView.vue.d.ts +46 -195
  74. package/dist/components/ProgressBar.vue.d.ts +1 -1
  75. package/dist/components/ProtocolStep.presentation.d.ts +4 -0
  76. package/dist/components/ProtocolStepEditor.state.d.ts +18 -0
  77. package/dist/components/ProtocolStepParameterField.vue.d.ts +12 -0
  78. package/dist/components/ReagentList.presentation.d.ts +16 -0
  79. package/dist/components/ResourceCard.vue.d.ts +1 -1
  80. package/dist/components/SampleSelector.colors.d.ts +13 -0
  81. package/dist/components/SampleSelector.drag.d.ts +24 -0
  82. package/dist/components/SampleSelector.groups.d.ts +15 -0
  83. package/dist/components/SampleSelector.selection.d.ts +26 -0
  84. package/dist/components/SampleSelector.vue.d.ts +4 -1
  85. package/dist/components/SampleSelectorSampleRow.vue.d.ts +21 -0
  86. package/dist/components/SegmentedControl.vue.d.ts +1 -1
  87. package/dist/components/SequenceInput.vue.d.ts +2 -2
  88. package/dist/components/SequenceProgressBar.vue.d.ts +1 -1
  89. package/dist/components/SettingsModal.schema.d.ts +9 -0
  90. package/dist/components/StatusIndicator.vue.d.ts +1 -1
  91. package/dist/components/TagsInput.vue.d.ts +2 -2
  92. package/dist/components/TimePicker.vue.d.ts +2 -2
  93. package/dist/components/TimeRangeInput.vue.d.ts +1 -1
  94. package/dist/components/UnitInput.vue.d.ts +2 -2
  95. package/dist/components/WellPlate.colors.d.ts +9 -0
  96. package/dist/components/WellPlate.conditions.d.ts +26 -0
  97. package/dist/components/WellPlate.geometry.d.ts +23 -0
  98. package/dist/components/WellPlate.interaction.d.ts +71 -0
  99. package/dist/components/WellPlate.legend.d.ts +2 -0
  100. package/dist/components/WellPlate.rendering.d.ts +24 -0
  101. package/dist/components/WellPlate.sampleDrop.d.ts +8 -0
  102. package/dist/components/WellPlate.vue.d.ts +1 -1
  103. package/dist/components/index.js +2 -2
  104. package/dist/components/internal/ActionItemInternal.vue.d.ts +1 -1
  105. package/dist/components/internal/PlateMapEditorToolbarInternal.vue.d.ts +28 -0
  106. package/dist/{components-DafPc4rM.js → components-DtHA2bgp.js} +3754 -2991
  107. package/dist/components-DtHA2bgp.js.map +1 -0
  108. package/dist/composables/autoGroup/classKey.d.ts +4 -0
  109. package/dist/composables/autoGroup/classify.d.ts +28 -0
  110. package/dist/composables/autoGroup/colors.d.ts +2 -0
  111. package/dist/composables/autoGroup/columns.d.ts +10 -0
  112. package/dist/composables/autoGroup/compose.d.ts +8 -0
  113. package/dist/composables/autoGroup/cooccurrence.d.ts +2 -0
  114. package/dist/composables/autoGroup/csv-shim.d.ts +2 -0
  115. package/dist/composables/autoGroup/fingerprint.d.ts +3 -0
  116. package/dist/composables/autoGroup/index.d.ts +16 -0
  117. package/dist/composables/autoGroup/replicatePreGroup.d.ts +38 -0
  118. package/dist/composables/autoGroup/template.d.ts +15 -0
  119. package/dist/composables/autoGroup/tokenize.d.ts +8 -0
  120. package/dist/composables/autoGroupConstants.d.ts +1 -0
  121. package/dist/composables/autoGroupGrouping.d.ts +3 -0
  122. package/dist/composables/controlComponentBindings.d.ts +1 -1
  123. package/dist/composables/controlSchemaAdapters.d.ts +1 -1
  124. package/dist/composables/controlSchemaDoseDesign.d.ts +11 -0
  125. package/dist/composables/controlSchemaLayout.d.ts +1 -1
  126. package/dist/composables/controlSchemaModel.d.ts +5 -0
  127. package/dist/composables/controlSchemaNormalize.d.ts +1 -1
  128. package/dist/composables/controlSchemaTypes.d.ts +305 -0
  129. package/dist/composables/controlWorkspaceOptions.d.ts +1 -1
  130. package/dist/composables/formBuilderSchema.d.ts +18 -0
  131. package/dist/composables/index.js +3 -3
  132. package/dist/composables/pluginEndpointBuilder.d.ts +13 -0
  133. package/dist/composables/protocolTemplateCatalog.d.ts +26 -0
  134. package/dist/composables/useAutoGroup.d.ts +61 -74
  135. package/dist/composables/useAutoGroupInputSources.d.ts +32 -0
  136. package/dist/composables/useBioTemplateControls.d.ts +1 -1
  137. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +1 -1
  138. package/dist/composables/useBioTemplateWorkspace.d.ts +1 -1
  139. package/dist/composables/useControlSchema.d.ts +4 -316
  140. package/dist/composables/useControlWorkspace.d.ts +1 -1
  141. package/dist/composables/useForm.d.ts +2 -33
  142. package/dist/composables/useFormBuilder.d.ts +2 -9
  143. package/dist/composables/useFormValidation.d.ts +34 -0
  144. package/dist/composables/usePluginClient.d.ts +1 -4
  145. package/dist/composables/useProtocolTemplates.d.ts +2 -24
  146. package/dist/composables/useScheduleCalendarLayout.d.ts +49 -0
  147. package/dist/{composables-BMkPQhVK.js → composables-Dlg8jenH.js} +33 -31
  148. package/dist/composables-Dlg8jenH.js.map +1 -0
  149. package/dist/index.js +4 -4
  150. package/dist/install.js +2 -2
  151. package/dist/styles.css +547 -516
  152. package/dist/templates/controlSchemaTypes.d.ts +1 -1
  153. package/dist/templates/index.js +1 -1
  154. package/dist/templates/templateAdapterTypes.d.ts +48 -0
  155. package/dist/templates/templateCreateOptions.d.ts +165 -0
  156. package/dist/templates/templateQpcrTypes.d.ts +42 -0
  157. package/dist/templates/types.d.ts +5 -250
  158. package/dist/{templates-bUAWMn5L.js → templates-DtdUvJ4c.js} +144 -136
  159. package/dist/templates-DtdUvJ4c.js.map +1 -0
  160. package/dist/types/auto-group.d.ts +79 -9
  161. package/dist/types/componentLabTypes.d.ts +161 -0
  162. package/dist/types/componentWorkflowTypes.d.ts +150 -0
  163. package/dist/types/components.d.ts +2 -311
  164. package/dist/{useProtocolTemplates-QZtHFFH2.js → useProtocolTemplates-Bm5vyH4_.js} +1220 -454
  165. package/dist/useProtocolTemplates-Bm5vyH4_.js.map +1 -0
  166. package/package.json +1 -1
  167. package/src/__tests__/components/AppTopBar.navigation.test.ts +70 -0
  168. package/src/__tests__/components/DoseCalculatorVolumeField.test.ts +53 -0
  169. package/src/__tests__/components/PlateMapEditorToolbarInternal.test.ts +54 -0
  170. package/src/__tests__/components/PluginWorkspaceView.controls.test.ts +156 -0
  171. package/src/__tests__/components/PluginWorkspaceView.navigation.test.ts +102 -0
  172. package/src/__tests__/components/PluginWorkspaceView.shell.test.ts +41 -0
  173. package/src/__tests__/components/ProtocolStep.presentation.test.ts +31 -0
  174. package/src/__tests__/components/ProtocolStepEditor.state.test.ts +165 -0
  175. package/src/__tests__/components/ProtocolStepParameterField.test.ts +44 -0
  176. package/src/__tests__/components/ReagentList.presentation.test.ts +68 -0
  177. package/src/__tests__/components/SampleSelector.colors.test.ts +49 -0
  178. package/src/__tests__/components/SampleSelector.drag.test.ts +100 -0
  179. package/src/__tests__/components/SampleSelector.groups.test.ts +81 -0
  180. package/src/__tests__/components/SampleSelector.selection.test.ts +70 -0
  181. package/src/__tests__/components/SampleSelector.test.ts +32 -0
  182. package/src/__tests__/components/SampleSelectorSampleRow.test.ts +37 -0
  183. package/src/__tests__/components/ScheduleCalendar.test.ts +44 -0
  184. package/src/__tests__/components/SettingsModal.schema.test.ts +97 -0
  185. package/src/__tests__/components/WellPlate.colors.test.ts +28 -0
  186. package/src/__tests__/components/WellPlate.conditions.test.ts +68 -0
  187. package/src/__tests__/components/WellPlate.geometry.test.ts +54 -0
  188. package/src/__tests__/components/WellPlate.interaction.test.ts +171 -0
  189. package/src/__tests__/components/WellPlate.legend.test.ts +13 -0
  190. package/src/__tests__/components/WellPlate.rendering.test.ts +122 -0
  191. package/src/__tests__/components/WellPlate.sampleDrop.test.ts +70 -0
  192. package/src/__tests__/composables/autoGroup/classify.test.ts +107 -0
  193. package/src/__tests__/composables/autoGroup/columns.test.ts +135 -0
  194. package/src/__tests__/composables/autoGroup/compose.test.ts +227 -0
  195. package/src/__tests__/composables/autoGroup/cooccurrence.test.ts +91 -0
  196. package/src/__tests__/composables/autoGroup/fingerprint.test.ts +50 -0
  197. package/src/__tests__/composables/autoGroup/integration.test.ts +79 -0
  198. package/src/__tests__/composables/autoGroup/template.test.ts +70 -0
  199. package/src/__tests__/composables/autoGroup/tokenize.test.ts +33 -0
  200. package/src/__tests__/composables/useAutoGroup.test.ts +129 -625
  201. package/src/__tests__/composables/useAutoGroupInputSources.test.ts +107 -0
  202. package/src/__tests__/composables/useControlSchema.test.ts +23 -0
  203. package/src/__tests__/composables/useScheduleCalendarLayout.test.ts +89 -0
  204. package/src/__tests__/docs/extractDocsComponents.test.ts +142 -0
  205. package/src/__tests__/docs/extractDocsExports.test.ts +77 -0
  206. package/src/__tests__/docs/extractDocsParsing.test.ts +69 -0
  207. package/src/__tests__/docs/extractDocsTemplates.test.ts +54 -0
  208. package/src/__tests__/docs/extractDocsTheme.test.ts +89 -0
  209. package/src/__tests__/docs/frontendDocsCatalog.test.ts +1 -1
  210. package/src/__tests__/fixtures/auto-group/mixed-lc-ms-batch.txt +187 -0
  211. package/src/components/AppSidebar.vue +2 -6
  212. package/src/components/AppTopBar.navigation.ts +62 -0
  213. package/src/components/AppTopBar.vue +17 -44
  214. package/src/components/AutoGroupModal.story.vue +50 -0
  215. package/src/components/AutoGroupModal.vue +441 -158
  216. package/src/components/ControlWorkspaceView.vue +2 -6
  217. package/src/components/DoseCalculator.vue +13 -73
  218. package/src/components/DoseCalculatorVolumeField.vue +61 -0
  219. package/src/components/ExperimentTimeline.vue +6 -31
  220. package/src/components/FormBuilder.vue +2 -7
  221. package/src/components/PlateMapEditor.vue +32 -106
  222. package/src/components/PluginWorkspaceView.controls.ts +182 -0
  223. package/src/components/PluginWorkspaceView.navigation.ts +106 -0
  224. package/src/components/PluginWorkspaceView.props.ts +174 -0
  225. package/src/components/PluginWorkspaceView.shell.ts +66 -0
  226. package/src/components/PluginWorkspaceView.vue +85 -404
  227. package/src/components/ProtocolStep.presentation.ts +31 -0
  228. package/src/components/ProtocolStepEditor.state.ts +104 -0
  229. package/src/components/ProtocolStepEditor.vue +48 -179
  230. package/src/components/ProtocolStepParameterField.vue +134 -0
  231. package/src/components/ReagentList.presentation.ts +105 -0
  232. package/src/components/ReagentList.vue +16 -79
  233. package/src/components/SampleSelector.colors.ts +43 -0
  234. package/src/components/SampleSelector.drag.ts +164 -0
  235. package/src/components/SampleSelector.groups.ts +109 -0
  236. package/src/components/SampleSelector.selection.ts +103 -0
  237. package/src/components/SampleSelector.vue +82 -349
  238. package/src/components/SampleSelectorSampleRow.vue +64 -0
  239. package/src/components/ScheduleCalendar.vue +44 -199
  240. package/src/components/SettingsModal.schema.ts +71 -0
  241. package/src/components/SettingsModal.vue +16 -46
  242. package/src/components/WellPlate.colors.ts +56 -0
  243. package/src/components/WellPlate.conditions.ts +100 -0
  244. package/src/components/WellPlate.geometry.ts +91 -0
  245. package/src/components/WellPlate.interaction.ts +272 -0
  246. package/src/components/WellPlate.legend.ts +8 -0
  247. package/src/components/WellPlate.rendering.ts +105 -0
  248. package/src/components/WellPlate.sampleDrop.ts +73 -0
  249. package/src/components/WellPlate.vue +102 -550
  250. package/src/components/internal/PlateMapEditorToolbarInternal.vue +128 -0
  251. package/src/composables/autoGroup/classKey.ts +5 -0
  252. package/src/composables/autoGroup/classify.ts +205 -0
  253. package/src/composables/autoGroup/colors.ts +6 -0
  254. package/src/composables/autoGroup/columns.ts +226 -0
  255. package/src/composables/autoGroup/compose.ts +156 -0
  256. package/src/composables/autoGroup/cooccurrence.ts +46 -0
  257. package/src/composables/autoGroup/csv-shim.ts +44 -0
  258. package/src/composables/autoGroup/fingerprint.ts +49 -0
  259. package/src/composables/autoGroup/index.ts +20 -0
  260. package/src/composables/autoGroup/replicatePreGroup.ts +90 -0
  261. package/src/composables/autoGroup/template.ts +126 -0
  262. package/src/composables/autoGroup/tokenize.ts +41 -0
  263. package/src/composables/autoGroup/vocab.json +67 -0
  264. package/src/composables/autoGroupConstants.ts +4 -0
  265. package/src/composables/autoGroupGrouping.ts +148 -0
  266. package/src/composables/controlComponentBindings.ts +1 -1
  267. package/src/composables/controlSchemaAdapters.ts +1 -1
  268. package/src/composables/controlSchemaDoseDesign.ts +215 -0
  269. package/src/composables/controlSchemaFormFields.ts +1 -1
  270. package/src/composables/controlSchemaLayout.ts +1 -1
  271. package/src/composables/controlSchemaModel.ts +163 -0
  272. package/src/composables/controlSchemaNormalize.ts +1 -1
  273. package/src/composables/controlSchemaTypes.ts +364 -0
  274. package/src/composables/controlWorkspaceOptions.ts +1 -1
  275. package/src/composables/formBuilderSchema.ts +153 -0
  276. package/src/composables/pluginEndpointBuilder.ts +203 -0
  277. package/src/composables/protocolTemplateCatalog.ts +325 -0
  278. package/src/composables/useAutoGroup.ts +395 -549
  279. package/src/composables/useAutoGroupInputSources.ts +147 -0
  280. package/src/composables/useBioTemplateControls.ts +1 -1
  281. package/src/composables/useBioTemplatePresetWorkspace.ts +1 -1
  282. package/src/composables/useBioTemplateWorkspace.ts +1 -1
  283. package/src/composables/useControlSchema.ts +21 -692
  284. package/src/composables/useControlWorkspace.ts +7 -13
  285. package/src/composables/useForm.ts +5 -187
  286. package/src/composables/useFormBuilder.ts +11 -153
  287. package/src/composables/useFormValidation.ts +154 -0
  288. package/src/composables/usePluginClient.ts +10 -193
  289. package/src/composables/useProtocolTemplates.ts +10 -328
  290. package/src/composables/useScheduleCalendarLayout.ts +287 -0
  291. package/src/styles/components/auto-group-modal.css +248 -310
  292. package/src/templates/controlSchemaTypes.ts +1 -1
  293. package/src/templates/templateAdapterTypes.ts +58 -0
  294. package/src/templates/templateCreateOptions.ts +208 -0
  295. package/src/templates/templateQpcrTypes.ts +48 -0
  296. package/src/templates/types.ts +79 -275
  297. package/src/types/auto-group.ts +107 -9
  298. package/src/types/componentLabTypes.ts +235 -0
  299. package/src/types/componentWorkflowTypes.ts +190 -0
  300. package/src/types/components.ts +74 -424
  301. package/dist/components-DafPc4rM.js.map +0 -1
  302. package/dist/composables-BMkPQhVK.js.map +0 -1
  303. package/dist/templates-bUAWMn5L.js.map +0 -1
  304. package/dist/useProtocolTemplates-QZtHFFH2.js.map +0 -1
@@ -0,0 +1,203 @@
1
+ import {
2
+ getInjectedPlatformContext,
3
+ resolveCurrentExperimentId,
4
+ } from './platformContextHelpers'
5
+ import type {
6
+ BuildPluginEndpointUrlOptions,
7
+ PluginContract,
8
+ PluginEndpointDefinition,
9
+ PluginEndpointParamDefinition,
10
+ } from './usePluginClient'
11
+
12
+ function normalizeApiBaseUrl(baseUrl: string | undefined): string | undefined {
13
+ if (!baseUrl) return undefined
14
+ return baseUrl.length > 1 ? baseUrl.replace(/\/+$/, '') : baseUrl
15
+ }
16
+
17
+ function normalizeApiPrefix(prefix: string | undefined): string | undefined {
18
+ if (!prefix) return undefined
19
+ if (prefix.startsWith('/api/')) return normalizeApiBaseUrl(prefix)
20
+ if (prefix === '/api') return prefix
21
+ if (prefix.startsWith('/')) return normalizeApiBaseUrl(`/api${prefix}`)
22
+ return normalizeApiBaseUrl(`/api/${prefix}`)
23
+ }
24
+
25
+ /** Resolve the runtime plugin API base URL from env, explicit options, platform injection, or contract metadata. */
26
+ export function resolvePluginBaseUrl(contract: PluginContract, explicitBaseUrl?: string): string {
27
+ const envPrefix = (import.meta.env?.VITE_API_PREFIX as string | undefined) || undefined
28
+ if (envPrefix) return normalizeApiBaseUrl(envPrefix) ?? envPrefix
29
+ if (explicitBaseUrl) return normalizeApiBaseUrl(explicitBaseUrl) ?? explicitBaseUrl
30
+
31
+ const injected = getInjectedPlatformContext()
32
+ const platformPrefix =
33
+ normalizeApiBaseUrl(injected?.plugin?.api_prefix) ||
34
+ normalizeApiPrefix(injected?.plugin?.route_prefix)
35
+ if (platformPrefix) return platformPrefix
36
+
37
+ return normalizeApiBaseUrl(contract.plugin.apiPrefix) || '/api'
38
+ }
39
+
40
+ function encodePath(path: string, payload: Record<string, unknown>, pathParams: string[]): string {
41
+ let nextPath = path
42
+ for (const param of pathParams) {
43
+ const value = payload[param]
44
+ if (value === undefined || value === null) {
45
+ throw new Error(`[MINT SDK] Missing path parameter '${param}' for plugin endpoint ${path}`)
46
+ }
47
+ nextPath = nextPath.replace(`{${param}}`, encodeURIComponent(String(value)))
48
+ nextPath = nextPath.replace(`:${param}`, encodeURIComponent(String(value)))
49
+ }
50
+ return nextPath
51
+ }
52
+
53
+ function withDefaultPathParams(
54
+ payload: Record<string, unknown>,
55
+ pathParams: string[],
56
+ ): Record<string, unknown> {
57
+ if (!pathParams.length) return payload
58
+ const nextPayload = { ...payload }
59
+ for (const param of pathParams) {
60
+ if (nextPayload[param] !== undefined && nextPayload[param] !== null) continue
61
+ if (isExperimentPathParam(param)) {
62
+ const experimentId = resolveCurrentExperimentId()
63
+ if (experimentId !== undefined) {
64
+ nextPayload[param] = experimentId
65
+ }
66
+ }
67
+ }
68
+ return nextPayload
69
+ }
70
+
71
+ function isExperimentPathParam(param: string): boolean {
72
+ return param === 'experimentId' || param === 'experiment_id'
73
+ }
74
+
75
+ function withoutPathParams(payload: Record<string, unknown>, pathParams: string[]) {
76
+ const copy = { ...payload }
77
+ for (const param of pathParams) {
78
+ delete copy[param]
79
+ }
80
+ return copy
81
+ }
82
+
83
+ function queryParamsFromPayload(
84
+ payload: Record<string, unknown>,
85
+ pathParams: string[],
86
+ queryParams?: PluginEndpointParamDefinition[],
87
+ endpointPath?: string,
88
+ includeUnspecifiedParams = false,
89
+ ) {
90
+ if (!queryParams?.length) {
91
+ return includeUnspecifiedParams ? withoutPathParams(payload, pathParams) : {}
92
+ }
93
+
94
+ const query: Record<string, unknown> = {}
95
+ for (const param of queryParams) {
96
+ const name = typeof param === 'string' ? param : param.name
97
+ const fieldName = typeof param === 'string' ? param : param.fieldName ?? param.name
98
+ const required = typeof param !== 'string' && param.required === true
99
+ const value = payload[fieldName]
100
+ if (value === undefined || value === null) {
101
+ if (required) {
102
+ throw new Error(
103
+ `[MINT SDK] Missing query parameter '${fieldName}' for plugin endpoint ${endpointPath ?? ''}`,
104
+ )
105
+ }
106
+ continue
107
+ }
108
+ query[name] = value
109
+ }
110
+ return query
111
+ }
112
+
113
+ export function hasKeys(value: Record<string, unknown>): boolean {
114
+ return Object.keys(value).length > 0
115
+ }
116
+
117
+ export function requestBodyFromPayload(
118
+ payload: unknown,
119
+ requestPayload: Record<string, unknown>,
120
+ endpoint: PluginEndpointDefinition,
121
+ ): unknown {
122
+ if (!endpoint.hasBody) return undefined
123
+ const body = endpoint.pathParams?.length || endpoint.queryParams?.length
124
+ ? requestPayload.body
125
+ : payload
126
+ if (body === undefined || body === null) {
127
+ throw new Error(`[MINT SDK] Missing request body for plugin endpoint ${endpoint.path}`)
128
+ }
129
+ return body
130
+ }
131
+
132
+ export function pluginEndpointRequestParts(
133
+ contract: PluginContract,
134
+ endpoint: PluginEndpointDefinition,
135
+ payload?: unknown,
136
+ explicitBaseUrl?: string,
137
+ ) {
138
+ const payloadObject =
139
+ payload && typeof payload === 'object' && !Array.isArray(payload)
140
+ ? payload as Record<string, unknown>
141
+ : {}
142
+ const pathParams = endpoint.pathParams ?? []
143
+ const requestPayload = withDefaultPathParams(payloadObject, pathParams)
144
+ const path = encodePath(endpoint.path, requestPayload, pathParams)
145
+ const query = queryParamsFromPayload(
146
+ requestPayload,
147
+ pathParams,
148
+ endpoint.queryParams,
149
+ endpoint.path,
150
+ endpoint.method === 'get',
151
+ )
152
+
153
+ return {
154
+ baseUrl: resolvePluginBaseUrl(contract, explicitBaseUrl),
155
+ path,
156
+ query,
157
+ requestPayload,
158
+ }
159
+ }
160
+
161
+ function appendQueryValue(params: URLSearchParams, key: string, value: unknown): void {
162
+ if (value === undefined || value === null) return
163
+ if (Array.isArray(value)) {
164
+ for (const item of value) {
165
+ appendQueryValue(params, key, item)
166
+ }
167
+ return
168
+ }
169
+ if (typeof value === 'object') {
170
+ params.append(key, JSON.stringify(value))
171
+ return
172
+ }
173
+ params.append(key, String(value))
174
+ }
175
+
176
+ function queryString(query: Record<string, unknown>): string {
177
+ const params = new URLSearchParams()
178
+ for (const [key, value] of Object.entries(query)) {
179
+ appendQueryValue(params, key, value)
180
+ }
181
+ const serialized = params.toString()
182
+ return serialized ? `?${serialized}` : ''
183
+ }
184
+
185
+ function joinBaseUrl(baseUrl: string, path: string): string {
186
+ if (!baseUrl) return path
187
+ const normalizedBase = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl
188
+ const normalizedPath = path.startsWith('/') ? path : `/${path}`
189
+ return `${normalizedBase}${normalizedPath}`
190
+ }
191
+
192
+ /** Build the concrete URL for a generated plugin endpoint without making a request. */
193
+ export function buildPluginEndpointUrl(
194
+ contract: PluginContract,
195
+ endpoint: PluginEndpointDefinition,
196
+ payload?: unknown,
197
+ options: BuildPluginEndpointUrlOptions = {},
198
+ ): string {
199
+ const parts = pluginEndpointRequestParts(contract, endpoint, payload, options.baseUrl)
200
+ const pathWithQuery = `${parts.path}${queryString(parts.query)}`
201
+ if (options.includeBaseUrl === false) return pathWithQuery
202
+ return joinBaseUrl(parts.baseUrl, pathWithQuery)
203
+ }
@@ -0,0 +1,325 @@
1
+ import type { ProtocolStepType } from '../types'
2
+
3
+ // Parameter definition for step templates
4
+ export interface ParameterDefinition {
5
+ key: string
6
+ label: string
7
+ type: 'number' | 'text' | 'select' | 'concentration' | 'temperature' | 'duration' | 'reagent'
8
+ unit?: string
9
+ options?: Array<{ value: string; label: string }>
10
+ required?: boolean
11
+ default?: unknown
12
+ min?: number
13
+ max?: number
14
+ placeholder?: string
15
+ }
16
+
17
+ // Step template definition
18
+ export interface StepTemplate {
19
+ id: string
20
+ type: ProtocolStepType
21
+ name: string
22
+ description?: string
23
+ defaultDuration?: number
24
+ parameters: ParameterDefinition[]
25
+ isBuiltIn?: boolean
26
+ }
27
+
28
+ export const BUILT_IN_PROTOCOL_TEMPLATES: StepTemplate[] = [
29
+ {
30
+ id: 'builtin-incubation',
31
+ type: 'incubation',
32
+ name: 'Incubation',
33
+ description: 'Incubate samples at specified conditions',
34
+ defaultDuration: 60,
35
+ isBuiltIn: true,
36
+ parameters: [
37
+ {
38
+ key: 'temperature',
39
+ label: 'Temperature',
40
+ type: 'temperature',
41
+ unit: '°C',
42
+ required: true,
43
+ default: 37,
44
+ min: -80,
45
+ max: 100,
46
+ },
47
+ {
48
+ key: 'duration',
49
+ label: 'Duration',
50
+ type: 'duration',
51
+ unit: 'hours',
52
+ required: true,
53
+ default: 24,
54
+ min: 0,
55
+ },
56
+ {
57
+ key: 'co2',
58
+ label: 'CO2',
59
+ type: 'number',
60
+ unit: '%',
61
+ required: false,
62
+ default: 5,
63
+ min: 0,
64
+ max: 100,
65
+ },
66
+ {
67
+ key: 'humidity',
68
+ label: 'Humidity',
69
+ type: 'number',
70
+ unit: '%',
71
+ required: false,
72
+ default: 95,
73
+ min: 0,
74
+ max: 100,
75
+ },
76
+ ],
77
+ },
78
+ {
79
+ id: 'builtin-wash',
80
+ type: 'wash',
81
+ name: 'Wash',
82
+ description: 'Wash samples with buffer',
83
+ defaultDuration: 5,
84
+ isBuiltIn: true,
85
+ parameters: [
86
+ {
87
+ key: 'buffer',
88
+ label: 'Buffer',
89
+ type: 'select',
90
+ required: true,
91
+ default: 'PBS',
92
+ options: [
93
+ { value: 'PBS', label: 'PBS' },
94
+ { value: 'PBST', label: 'PBST' },
95
+ { value: 'TBS', label: 'TBS' },
96
+ { value: 'TBST', label: 'TBST' },
97
+ { value: 'Water', label: 'Water' },
98
+ { value: 'Other', label: 'Other' },
99
+ ],
100
+ },
101
+ {
102
+ key: 'volume',
103
+ label: 'Volume',
104
+ type: 'number',
105
+ unit: 'µL',
106
+ required: true,
107
+ default: 200,
108
+ min: 0,
109
+ },
110
+ {
111
+ key: 'cycles',
112
+ label: 'Wash Cycles',
113
+ type: 'number',
114
+ required: true,
115
+ default: 3,
116
+ min: 1,
117
+ max: 10,
118
+ },
119
+ ],
120
+ },
121
+ {
122
+ id: 'builtin-addition',
123
+ type: 'addition',
124
+ name: 'Addition',
125
+ description: 'Add reagent or compound to samples',
126
+ defaultDuration: 5,
127
+ isBuiltIn: true,
128
+ parameters: [
129
+ {
130
+ key: 'reagent',
131
+ label: 'Reagent',
132
+ type: 'text',
133
+ required: true,
134
+ placeholder: 'Enter reagent name',
135
+ },
136
+ {
137
+ key: 'volume',
138
+ label: 'Volume',
139
+ type: 'number',
140
+ unit: 'µL',
141
+ required: true,
142
+ default: 100,
143
+ min: 0,
144
+ },
145
+ {
146
+ key: 'concentration',
147
+ label: 'Concentration',
148
+ type: 'concentration',
149
+ required: false,
150
+ },
151
+ ],
152
+ },
153
+ {
154
+ id: 'builtin-measurement',
155
+ type: 'measurement',
156
+ name: 'Measurement',
157
+ description: 'Take measurements using specified instrument',
158
+ defaultDuration: 15,
159
+ isBuiltIn: true,
160
+ parameters: [
161
+ {
162
+ key: 'instrument',
163
+ label: 'Instrument',
164
+ type: 'select',
165
+ required: true,
166
+ options: [
167
+ { value: 'plate_reader', label: 'Plate Reader' },
168
+ { value: 'microscope', label: 'Microscope' },
169
+ { value: 'flow_cytometer', label: 'Flow Cytometer' },
170
+ { value: 'spectrophotometer', label: 'Spectrophotometer' },
171
+ { value: 'other', label: 'Other' },
172
+ ],
173
+ },
174
+ {
175
+ key: 'readout',
176
+ label: 'Readout Type',
177
+ type: 'text',
178
+ required: false,
179
+ placeholder: 'e.g., Absorbance 450nm',
180
+ },
181
+ {
182
+ key: 'notes',
183
+ label: 'Parameters',
184
+ type: 'text',
185
+ required: false,
186
+ placeholder: 'Additional parameters',
187
+ },
188
+ ],
189
+ },
190
+ {
191
+ id: 'builtin-centrifuge',
192
+ type: 'centrifuge',
193
+ name: 'Centrifuge',
194
+ description: 'Centrifuge samples',
195
+ defaultDuration: 10,
196
+ isBuiltIn: true,
197
+ parameters: [
198
+ {
199
+ key: 'speed',
200
+ label: 'Speed',
201
+ type: 'number',
202
+ unit: 'RPM',
203
+ required: true,
204
+ default: 1000,
205
+ min: 100,
206
+ max: 20000,
207
+ },
208
+ {
209
+ key: 'duration',
210
+ label: 'Duration',
211
+ type: 'number',
212
+ unit: 'min',
213
+ required: true,
214
+ default: 5,
215
+ min: 1,
216
+ },
217
+ {
218
+ key: 'temperature',
219
+ label: 'Temperature',
220
+ type: 'temperature',
221
+ unit: '°C',
222
+ required: false,
223
+ default: 4,
224
+ min: -10,
225
+ max: 40,
226
+ },
227
+ ],
228
+ },
229
+ {
230
+ id: 'builtin-transfer',
231
+ type: 'transfer',
232
+ name: 'Transfer',
233
+ description: 'Transfer samples between containers',
234
+ defaultDuration: 10,
235
+ isBuiltIn: true,
236
+ parameters: [
237
+ {
238
+ key: 'source',
239
+ label: 'Source',
240
+ type: 'text',
241
+ required: true,
242
+ placeholder: 'Source container',
243
+ },
244
+ {
245
+ key: 'destination',
246
+ label: 'Destination',
247
+ type: 'text',
248
+ required: true,
249
+ placeholder: 'Destination container',
250
+ },
251
+ {
252
+ key: 'volume',
253
+ label: 'Volume',
254
+ type: 'number',
255
+ unit: 'µL',
256
+ required: true,
257
+ default: 100,
258
+ min: 0,
259
+ },
260
+ ],
261
+ },
262
+ {
263
+ id: 'builtin-mix',
264
+ type: 'mix',
265
+ name: 'Mix',
266
+ description: 'Mix samples',
267
+ defaultDuration: 5,
268
+ isBuiltIn: true,
269
+ parameters: [
270
+ {
271
+ key: 'method',
272
+ label: 'Method',
273
+ type: 'select',
274
+ required: true,
275
+ default: 'pipette',
276
+ options: [
277
+ { value: 'pipette', label: 'Pipette mixing' },
278
+ { value: 'vortex', label: 'Vortex' },
279
+ { value: 'shaker', label: 'Orbital shaker' },
280
+ { value: 'inversion', label: 'Inversion' },
281
+ ],
282
+ },
283
+ {
284
+ key: 'duration',
285
+ label: 'Duration',
286
+ type: 'number',
287
+ unit: 'sec',
288
+ required: false,
289
+ default: 30,
290
+ min: 1,
291
+ },
292
+ {
293
+ key: 'speed',
294
+ label: 'Speed/Intensity',
295
+ type: 'text',
296
+ required: false,
297
+ placeholder: 'e.g., 300 RPM',
298
+ },
299
+ ],
300
+ },
301
+ {
302
+ id: 'builtin-custom',
303
+ type: 'custom',
304
+ name: 'Custom Step',
305
+ description: 'Custom protocol step',
306
+ defaultDuration: 15,
307
+ isBuiltIn: true,
308
+ parameters: [
309
+ {
310
+ key: 'description',
311
+ label: 'Description',
312
+ type: 'text',
313
+ required: true,
314
+ placeholder: 'Describe the step',
315
+ },
316
+ {
317
+ key: 'notes',
318
+ label: 'Notes',
319
+ type: 'text',
320
+ required: false,
321
+ placeholder: 'Additional notes',
322
+ },
323
+ ],
324
+ },
325
+ ]