@morscherlab/mint-sdk 1.0.0 → 1.0.1

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 (68) hide show
  1. package/dist/BaseModal-B9UA8Y_I.js +165 -0
  2. package/dist/BaseModal-B9UA8Y_I.js.map +1 -0
  3. package/dist/BaseSelect-DksaKYq_.js +176 -0
  4. package/dist/BaseSelect-DksaKYq_.js.map +1 -0
  5. package/dist/ExperimentPopover-CCYB1oWp.js +361 -0
  6. package/dist/ExperimentPopover-CCYB1oWp.js.map +1 -0
  7. package/dist/ExperimentPopover-D0bg_fqM.js +3 -0
  8. package/dist/ExperimentSelectorModal-B_kPbXcg.js +4 -0
  9. package/dist/ExperimentSelectorModal-wm7yUdAr.js +720 -0
  10. package/dist/ExperimentSelectorModal-wm7yUdAr.js.map +1 -0
  11. package/dist/SettingsModal-L7Ejny45.js +5 -0
  12. package/dist/SettingsModal-LEKI6Ebl.js +521 -0
  13. package/dist/SettingsModal-LEKI6Ebl.js.map +1 -0
  14. package/dist/{auth-BulIv_km.js → auth-D9q2GIcv.js} +3 -80
  15. package/dist/auth-D9q2GIcv.js.map +1 -0
  16. package/dist/components/DataFrame.vue.d.ts +3 -0
  17. package/dist/components/ExperimentDataViewer.vue.d.ts +2 -0
  18. package/dist/components/PluginWorkspaceView.vue.d.ts +2 -2
  19. package/dist/components/index.js +7 -2
  20. package/dist/{components-DtX3LDLq.js → components-CdjRzHI2.js} +533 -2025
  21. package/dist/components-CdjRzHI2.js.map +1 -0
  22. package/dist/composables/index.js +9 -3
  23. package/dist/composables/usePluginClient.d.ts +2 -1
  24. package/dist/{composables-wNt7VtkF.js → composables-DJgqPrlR.js} +7 -12
  25. package/dist/{composables-wNt7VtkF.js.map → composables-DJgqPrlR.js.map} +1 -1
  26. package/dist/experiment-utils-hGXMHlAc.js +109 -0
  27. package/dist/experiment-utils-hGXMHlAc.js.map +1 -0
  28. package/dist/index.js +16 -5
  29. package/dist/index.js.map +1 -1
  30. package/dist/install.js +7 -2
  31. package/dist/install.js.map +1 -1
  32. package/dist/permissions.js +81 -0
  33. package/dist/permissions.js.map +1 -0
  34. package/dist/stores/index.js +1 -1
  35. package/dist/styles.css +3233 -3185
  36. package/dist/templates/index.js +3 -1
  37. package/dist/templates-Do43ZIMb.js +5065 -0
  38. package/dist/templates-Do43ZIMb.js.map +1 -0
  39. package/dist/{templates-DSbHJC4v.js → useControlSchema-0n8Bcftq.js} +10 -5335
  40. package/dist/useControlSchema-0n8Bcftq.js.map +1 -0
  41. package/dist/useDropdownState-Ben4DnjJ.js +47 -0
  42. package/dist/useDropdownState-Ben4DnjJ.js.map +1 -0
  43. package/dist/useEventListener-CfVkP9Xz.js +57 -0
  44. package/dist/useEventListener-CfVkP9Xz.js.map +1 -0
  45. package/dist/useExperimentSelector-BpZklTbV.js +469 -0
  46. package/dist/useExperimentSelector-BpZklTbV.js.map +1 -0
  47. package/dist/useFormBuilder-COfYWDuC.js +729 -0
  48. package/dist/useFormBuilder-COfYWDuC.js.map +1 -0
  49. package/dist/{useProtocolTemplates-DwBhEPPU.js → useProtocolTemplates-TUQO_F3n.js} +8 -1298
  50. package/dist/useProtocolTemplates-TUQO_F3n.js.map +1 -0
  51. package/dist/utils/pluginIcon.d.ts +29 -2
  52. package/package.json +5 -1
  53. package/src/__tests__/components/DataFrame.test.ts +37 -0
  54. package/src/__tests__/components/PluginIcon.test.ts +77 -0
  55. package/src/__tests__/composables/usePluginClient.test.ts +11 -10
  56. package/src/components/AppTopBar.vue +7 -6
  57. package/src/components/DataFrame.vue +27 -2
  58. package/src/components/ExperimentDataViewer.vue +5 -1
  59. package/src/components/PluginIcon.story.vue +31 -1
  60. package/src/components/PluginIcon.vue +94 -4
  61. package/src/composables/usePluginClient.ts +3 -12
  62. package/src/styles/components/dataframe.css +26 -0
  63. package/src/styles/components/plugin-icon.css +5 -0
  64. package/src/utils/pluginIcon.ts +159 -2
  65. package/dist/auth-BulIv_km.js.map +0 -1
  66. package/dist/components-DtX3LDLq.js.map +0 -1
  67. package/dist/templates-DSbHJC4v.js.map +0 -1
  68. package/dist/useProtocolTemplates-DwBhEPPU.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,9 +1,20 @@
1
- import { $ as SampleLegend_default, A as ReagentEditor_default, At as SegmentedControl_default, B as ProgressBar_default, C as formatSequenceRemaining, Ct as AppToastContainer_default, D as ScientificNumber_default, Dt as Calendar_default, E as ChemicalFormula_default, Et as DataFrame_default, F as BioTemplateExperimentWorkspaceView_default, G as ControlWorkspaceView_default, H as Divider_default, I as BioTemplateRenderer_default, J as SampleSelector_default, K as ComponentBindingRenderer_default, L as ChartContainer_default, M as RackEditor_default, Mt as BaseTabs_default, N as BioTemplatePresetWorkspaceView_default, Nt as ColorSlider_default, O as ProtocolStepEditor_default, Ot as DropdownButton_default, P as BioTemplatePackWorkspaceView_default, Pt as BaseButton_default, Q as PlateMapEditor_default, R as Breadcrumb_default, S as formatSequenceEta, St as IconButton_default, T as sequenceSamplesRemaining, Tt as FormField_default, U as AppContainer_default, V as StatusIndicator_default, W as DoseDesignWorkspaceView_default, X as LoadingSpinner_default, Y as AutoGroupModal_default, Z as ReagentList_default, _ as InstrumentStateBadge_default, _t as ExperimentPopover_default, a as ExperimentDataViewer_default, at as AppSidebar_default, b as estimateSequenceFinishDate, bt as CollapsibleCard_default, c as LcmsSequenceTable_default, ct as StepWizard_default, d as extractLcmsCommonPrefix, dt as AppAvatarMenu_default, et as WellPlate_default, f as extractLcmsSampleName, ft as PluginIcon_default, g as InstrumentStatusCard_default, gt as Skeleton_default, h as reconstructLcmsPlateCellsFromSequenceItems, ht as EmptyState_default, i as TimeRangeInput_default, it as AppLayout_default, j as GroupAssigner_default, jt as BaseModal_default, k as SampleHierarchyTree_default, kt as BasePill_default, l as DEFAULT_LCMS_SEQUENCE_COLUMNS, lt as AppTopBar_default, m as lcmsWellIdFromPosition, mt as ExperimentCodeBadge_default, n as FitPanel_default, nt as DoseCalculator_default, o as BatchProgressList_default, ot as FormBuilder_default, p as inferLcmsPlateTypeFromWellIds, pt as ExperimentSelectorModal_default, q as ScheduleCalendar_default, r as ResourceCard_default, rt as PluginWorkspaceView_default, s as AuditTrail_default, st as FormActions_default, tt as ExperimentTimeline_default, u as basenameFromWindowsPath, ut as AppPluginSwitcher_default, v as InstrumentAlertLog_default, vt as ConfirmDialog_default, w as sequenceProgressPercent, wt as AlertBox_default, x as estimateSequenceRemainingSeconds, xt as ThemeToggle_default, y as SequenceProgressBar_default, yt as SettingsModal_default, z as Avatar_default } from "./components-DtX3LDLq.js";
2
- import { $ as toTimeCourseRows, $n as TimePicker_default, $t as listBioTemplatePacks, A as createSamplePrepTemplate, An as controlsToSectionFormSchema, Ar as BaseInput_default, At as toCalibrationCurveRows, B as toBioTemplateComponentProps, Bn as ConcentrationInput_default, Bt as validatePlateMapData, C as createFlowCytometryPanelTemplate, Cn as defineControlModel, Cr as BaseToggle_default, Ct as toInstrumentRunScheduleEvents, D as createTimeCourseTemplate, Dn as controlValuesToComponentProps, Dr as BaseSelect_default, Dt as toFlowPanelRows, E as createProtocolStepsTemplate, En as controlValuesToComponentBindingsById, Er as useEventListener, Et as toFlowPanelDataFrame, Fn as controlsToViewIds, Ft as validateAssayMatrixData, G as toTemplateDataFrame, Gn as useSequenceUtils, Gt as validateSampleSheetData, H as toBioTemplateComponentPropsById, Hn as useConcentrationUnits, Ht as validateQpcrPlateData, I as listBioTemplateComponentBindings, In as controlsToViewItems, It as validateCalibrationCurveData, J as toDoseLayoutState, Jn as useChemicalFormula, Jt as getBioTemplatePresetInfo, K as toWellMapArray, Kn as FormulaInput_default, Kt as validateTimeCourseData, L as toBioTemplateComponentBindings, Ln as getDefaultControlView, Lt as validateDoseResponseData, M as createPlateMapTemplate, Mn as controlsToSettingsSchema, Mt as toAssayMatrixDataFrame, N as bioTemplatePresetControlValuesToOptions, Nn as controlsToSidebarPanels, Nt as toAssayMatrixRows, O as createCalibrationCurveTemplate, Ot as toCalibrationCurveColumns, P as getBioTemplateComponentBindings, Pn as controlsToTopBarSettingsConfig, Pt as toAssayMatrixSampleOptions, Q as toTimeCourseDataFrame, Qn as TagsInput_default, Qt as getBioTemplatePackInfo, R as toBioTemplateComponentBindingsById, Rn as getFieldRegistryEntry, Rt as validateFlowCytometryPanelData, S as createInstrumentRunTemplate, Sn as useControlWorkspace, Sr as BaseRadioGroup_default, St as toInstrumentRunRows, T as createAssayMatrixTemplate, Tn as controlValuesToComponentBindings, Tr as Tooltip_default, Tt as toFlowPanelColumns, U as toBioTemplateComponentSnippets, Un as MoleculeInput_default, Ut as validateReagentListData, Vn as UnitInput_default, Vt as validateProtocolStepsData, W as toBioTemplateComponentUsage, Wn as SequenceInput_default, Wt as validateSamplePrepData, X as toWellPlateWells, Xn as FileUploader_default, Xt as searchBioTemplatePresets, Y as toPlateMapEditorState, Yn as DateTimePicker_default, Yt as listBioTemplatePresets, Z as toTimeCourseColumns, Zn as NumberInput_default, Zt as bioTemplatePacks, _ as createElisaAssayCollection, _n as defineDoseCalculatorControlProps, _t as toProtocolDataFrame, a as getBioTemplateControlDefaults, an as TEMPLATE_COLLECTION_KEY, ar as formatDuration, at as toSamplePrepColumns, b as createQpcrExpressionCollection, bn as defineWellPlateDoseComponentBindings, br as useSelectionLimit, bt as toInstrumentRunColumns, c as listBioTemplatePresetControlSchemas, cn as createTemplateEnvelope, cr as fromMinutes, ct as toReagentColumns, d as createBioTemplatePresetCollectionFromControls, dn as extractTemplateCollection, dr as parseTime, dt as toReagentRows, en as searchBioTemplatePacks, er as addMinutes, et as toTimeCourseSteps, f as createWellPlateScreenCollection, fn as getTemplateData, fr as rangesOverlap, ft as toQpcrColumns, g as createFlowCytometryAssayCollection, gn as useControlSchema, gr as DatePicker_default, gt as toProtocolColumns, h as createWesternBlotAssayCollection, hn as getControlDefaults, hr as useTimeUtils, ht as toQpcrWellPlateWells, i as createBioTemplateControlToolkit, in as searchBioTemplateCatalog, ir as findNearestTimeSlotIndex, it as toSampleRows, j as createSampleSheetTemplate, jn as controlsToSectionFormSchemas, jt as toAssayMatrixColumns, k as createDoseResponseTemplate, kn as controlsToFormSchema, kr as BaseTextarea_default, kt as toCalibrationCurveDataFrame, l as requireBioTemplateControlSchema, ln as ensureTemplateEnvelope, lr as generateTimeSlots, lt as toReagentDataFrame, m as createDefaultBioTemplate, mn as defineControls, mr as toMinutes, mt as toQpcrRows, n as bioTemplateControlsToSectionFormSchemas, nn as getBioTemplateInfo, nr as durationMinutes, nt as toSampleDataFrame, o as getBioTemplateControlSchema, on as assertTemplateEnvelope, or as formatTime, ot as toSamplePrepDataFrame, p as createBioTemplatePackCollection, pn as defineControlComponentBindings, pr as snapToSlot, pt as toQpcrDataFrame, q as toDoseConditions, qn as ATOMIC_WEIGHTS, qt as bioTemplatePresets, r as bioTemplateControlsToSidebarPanels, rn as listBioTemplateCatalog, rr as findAvailableSlots, rt as toSampleOptions, s as listBioTemplateControlSchemas, sn as createTemplateCollection, sr as formatTimeSlot, st as toSamplePrepRows, t as bioTemplateControlsToFormSchema, tn as bioTemplateCatalog, tr as compareTime, tt as toSampleColumns, u as createBioTemplatePresetCollection, un as ensureTemplateFromCollection, ur as isTimeInRange, ut as toReagentListItems, v as createTargetedMetabolomicsCollection, vn as defineDoseDesignControlModel, vr as MultiSelect_default, vt as toProtocolRows, w as createReagentListTemplate, wr as BaseCheckbox_default, wt as toInstrumentRunSteps, x as createQpcrPlateTemplate, xn as defineWellPlateDoseControlProps, xr as BaseSlider_default, xt as toInstrumentRunDataFrame, y as createLcmsBatchCollection, yn as defineWellPlateControlProps, yr as useListSelection, yt as toProtocolSteps, z as toBioTemplateComponentImports, zn as getTypeDefault, zt as validateInstrumentRunData } from "./templates-DSbHJC4v.js";
3
- import { $ as resolveExperimentCode, B as useExperimentSelector, C as useExpansionSet, D as hslToHex, E as hexToHsl, G as EXPERIMENT_STATUS_LABELS, H as useDebouncedWatch, I as useWellPlateEditor, J as SORT_OPTIONS, K as EXPERIMENT_STATUS_OPTIONS, L as useDoseCalculator, M as extractSampleOptionsFromDesignData, N as unwrapExperimentDesignData, O as extractSamplesFromDesignData, P as DEFAULT_COLORS, Q as getExperimentStatusVariant, R as APP_EXPERIMENT_KEY, T as deriveShade, U as useApi, V as useRequestSyncState, W as DATE_PRESET_OPTIONS, X as formatExperimentDate, Y as datePresetToISO, Z as formatExperimentStatus, _ as useScheduleDrag, a as useReagentSeries, at as useToast, c as useBioTemplatePresetWorkspace, ct as useTextSearch, d as getBioTemplateComponentProps, et as usePlatformContext, f as toBioTemplateComponentPropsByComponent, g as useExperimentSave, h as useTemplateCollection, i as generateDilutionSeries, it as useTheme, j as extractSampleNamesFromDesignData, k as useAutoGroup, l as useBioTemplatePackWorkspace, lt as compareSortValues, m as useBioTemplateControls, n as DEFAULT_PRESETS, nt as evaluateCondition, o as useGroupAssignment, ot as candidateMatchesSearch, p as useBioTemplateComponents, q as EXPERIMENT_STATUS_VARIANT_MAP, r as DEFAULT_UNITS, rt as useForm, s as useRackEditor, st as normalizeSearchQuery, t as useProtocolTemplates, tt as useFormBuilder, u as useBioTemplateWorkspace, ut as useSortedItems, v as useExperimentSamples, w as useSampleGroups, y as useExperimentData, z as useAppExperiment } from "./useProtocolTemplates-DwBhEPPU.js";
4
- import { a as canAccessByPolicy, c as getRoleInfo, d as hasAnyPermission, f as isAdminRole, g as useSettingsStore, h as colorPalettes, i as canAccessAdmin, l as getUserPermissions, m as normalizeAccessPolicy, n as ADMIN_PANEL_PERMISSIONS, o as canAccessPlugin, p as isAdminUser, r as ADMIN_ROLE, s as getAccessAudience, t as useAuthStore, u as hasAllPermissions } from "./auth-BulIv_km.js";
1
+ import { $ as SampleLegend_default, A as ReagentEditor_default, B as ProgressBar_default, C as formatSequenceRemaining, Ct as ColorSlider_default, D as ScientificNumber_default, E as ChemicalFormula_default, F as BioTemplateExperimentWorkspaceView_default, G as ControlWorkspaceView_default, H as Divider_default, I as BioTemplateRenderer_default, J as SampleSelector_default, K as ComponentBindingRenderer_default, L as ChartContainer_default, M as RackEditor_default, N as BioTemplatePresetWorkspaceView_default, O as ProtocolStepEditor_default, P as BioTemplatePackWorkspaceView_default, Q as PlateMapEditor_default, R as Breadcrumb_default, S as formatSequenceEta, St as BaseTabs_default, T as sequenceSamplesRemaining, U as AppContainer_default, V as StatusIndicator_default, W as DoseDesignWorkspaceView_default, X as LoadingSpinner_default, Y as AutoGroupModal_default, Z as ReagentList_default, _ as InstrumentStateBadge_default, _t as AlertBox_default, a as ExperimentDataViewer_default, at as AppSidebar_default, b as estimateSequenceFinishDate, bt as DropdownButton_default, c as LcmsSequenceTable_default, ct as StepWizard_default, d as extractLcmsCommonPrefix, dt as AppAvatarMenu_default, et as WellPlate_default, f as extractLcmsSampleName, ft as PluginIcon_default, g as InstrumentStatusCard_default, gt as AppToastContainer_default, h as reconstructLcmsPlateCellsFromSequenceItems, ht as IconButton_default, i as TimeRangeInput_default, it as AppLayout_default, j as GroupAssigner_default, k as SampleHierarchyTree_default, l as DEFAULT_LCMS_SEQUENCE_COLUMNS, lt as AppTopBar_default, m as lcmsWellIdFromPosition, mt as ThemeToggle_default, n as FitPanel_default, nt as DoseCalculator_default, o as BatchProgressList_default, ot as FormBuilder_default, p as inferLcmsPlateTypeFromWellIds, pt as CollapsibleCard_default, q as ScheduleCalendar_default, r as ResourceCard_default, rt as PluginWorkspaceView_default, s as AuditTrail_default, st as FormActions_default, tt as ExperimentTimeline_default, u as basenameFromWindowsPath, ut as AppPluginSwitcher_default, v as InstrumentAlertLog_default, vt as DataFrame_default, w as sequenceProgressPercent, x as estimateSequenceRemainingSeconds, xt as SegmentedControl_default, y as SequenceProgressBar_default, yt as Calendar_default, z as Avatar_default } from "./components-CdjRzHI2.js";
2
+ import { a as BasePill_default, i as Skeleton_default, n as ExperimentCodeBadge_default, o as BaseButton_default, r as EmptyState_default, t as ExperimentSelectorModal_default } from "./ExperimentSelectorModal-wm7yUdAr.js";
3
+ import { r as BaseInput_default, t as BaseSelect_default } from "./BaseSelect-DksaKYq_.js";
4
+ import { $ as parseTime, A as useConcentrationUnits, B as TagsInput_default, 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, L as DateTimePicker_default, M as SequenceInput_default, N as useSequenceUtils, O as ConcentrationInput_default, P as FormulaInput_default, Q as isTimeInRange, R as FileUploader_default, S as controlsToTopBarSettingsConfig, T as getDefaultControlView, U as compareTime, V as TimePicker_default, W as durationMinutes, X as fromMinutes, Y as formatTimeSlot, Z as generateTimeSlots, _ as controlsToFormSchema, a as defineDoseCalculatorControlProps, at as MultiSelect_default, b as controlsToSettingsSchema, c as defineWellPlateDoseComponentBindings, ct as BaseSlider_default, d as defineControlModel, dt as BaseCheckbox_default, et as rangesOverlap, ft as Tooltip_default, h as controlValuesToComponentProps, i as useControlSchema, it as DatePicker_default, j as MoleculeInput_default, k as UnitInput_default, l as defineWellPlateDoseControlProps, lt as BaseRadioGroup_default, m as controlValuesToComponentBindingsById, n as defineControls, nt as toMinutes, o as defineDoseDesignControlModel, ot as useListSelection, p as controlValuesToComponentBindings, pt as BaseTextarea_default, q as formatDuration, r as getControlDefaults, rt as useTimeUtils, s as defineWellPlateControlProps, st as useSelectionLimit, t as defineControlComponentBindings, tt as snapToSlot, u as useControlWorkspace, ut as BaseToggle_default, v as controlsToSectionFormSchema, w as controlsToViewItems, x as controlsToSidebarPanels, y as controlsToSectionFormSchemas, z as NumberInput_default } from "./useControlSchema-0n8Bcftq.js";
5
+ import { t as useEventListener } from "./useEventListener-CfVkP9Xz.js";
6
+ import { o as FormField_default, t as SettingsModal_default } from "./SettingsModal-LEKI6Ebl.js";
7
+ import { t as BaseModal_default } from "./BaseModal-B9UA8Y_I.js";
8
+ import { B as useTheme, C as useExpansionSet, D as hslToHex, E as hexToHsl, G as compareSortValues, H as candidateMatchesSearch, I as useWellPlateEditor, K as useSortedItems, L as useDoseCalculator, M as extractSampleOptionsFromDesignData, N as unwrapExperimentDesignData, O as extractSamplesFromDesignData, P as DEFAULT_COLORS, R as APP_EXPERIMENT_KEY, T as deriveShade, U as normalizeSearchQuery, V as useToast, W as useTextSearch, _ as useScheduleDrag, a as useReagentSeries, c as useBioTemplatePresetWorkspace, d as getBioTemplateComponentProps, f as toBioTemplateComponentPropsByComponent, g as useExperimentSave, h as useTemplateCollection, i as generateDilutionSeries, j as extractSampleNamesFromDesignData, k as useAutoGroup, l as useBioTemplatePackWorkspace, m as useBioTemplateControls, n as DEFAULT_PRESETS, o as useGroupAssignment, p as useBioTemplateComponents, r as DEFAULT_UNITS, s as useRackEditor, t as useProtocolTemplates, u as useBioTemplateWorkspace, v as useExperimentSamples, w as useSampleGroups, y as useExperimentData, z as useAppExperiment } from "./useProtocolTemplates-TUQO_F3n.js";
9
+ import { n as colorPalettes, r as useSettingsStore, t as useAuthStore } from "./auth-D9q2GIcv.js";
10
+ import { i as usePlatformContext, n as evaluateCondition, r as useForm, t as useFormBuilder } from "./useFormBuilder-COfYWDuC.js";
11
+ 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-hGXMHlAc.js";
12
+ import { ADMIN_PANEL_PERMISSIONS, ADMIN_ROLE, canAccessAdmin, canAccessByPolicy, canAccessPlugin, getAccessAudience, getRoleInfo, getUserPermissions, hasAllPermissions, hasAnyPermission, isAdminRole, isAdminUser, normalizeAccessPolicy } from "./permissions.js";
13
+ import { i as useApi, n as useDebouncedWatch, r as useRequestSyncState, t as useExperimentSelector } from "./useExperimentSelector-BpZklTbV.js";
14
+ import { n as ConfirmDialog_default, t as ExperimentPopover_default } from "./ExperimentPopover-CCYB1oWp.js";
15
+ import { $ as toTimeCourseRows, $t as listBioTemplatePacks, A as createSamplePrepTemplate, At as toCalibrationCurveRows, B as toBioTemplateComponentProps, Bt as validatePlateMapData, C as createFlowCytometryPanelTemplate, Ct as toInstrumentRunScheduleEvents, D as createTimeCourseTemplate, Dt as toFlowPanelRows, E as createProtocolStepsTemplate, Et as toFlowPanelDataFrame, Ft as validateAssayMatrixData, G as toTemplateDataFrame, Gt as validateSampleSheetData, H as toBioTemplateComponentPropsById, Ht as validateQpcrPlateData, I as listBioTemplateComponentBindings, It as validateCalibrationCurveData, J as toDoseLayoutState, Jt as getBioTemplatePresetInfo, K as toWellMapArray, Kt as validateTimeCourseData, L as toBioTemplateComponentBindings, Lt as validateDoseResponseData, M as createPlateMapTemplate, Mt as toAssayMatrixDataFrame, N as bioTemplatePresetControlValuesToOptions, Nt as toAssayMatrixRows, O as createCalibrationCurveTemplate, Ot as toCalibrationCurveColumns, P as getBioTemplateComponentBindings, Pt as toAssayMatrixSampleOptions, Q as toTimeCourseDataFrame, Qt as getBioTemplatePackInfo, R as toBioTemplateComponentBindingsById, Rt as validateFlowCytometryPanelData, S as createInstrumentRunTemplate, St as toInstrumentRunRows, T as createAssayMatrixTemplate, Tt as toFlowPanelColumns, U as toBioTemplateComponentSnippets, Ut as validateReagentListData, Vt as validateProtocolStepsData, W as toBioTemplateComponentUsage, Wt as validateSamplePrepData, X as toWellPlateWells, Xt as searchBioTemplatePresets, Y as toPlateMapEditorState, Yt as listBioTemplatePresets, Z as toTimeCourseColumns, Zt as bioTemplatePacks, _ as createElisaAssayCollection, _t as toProtocolDataFrame, a as getBioTemplateControlDefaults, an as TEMPLATE_COLLECTION_KEY, at as toSamplePrepColumns, b as createQpcrExpressionCollection, bt as toInstrumentRunColumns, c as listBioTemplatePresetControlSchemas, cn as createTemplateEnvelope, ct as toReagentColumns, d as createBioTemplatePresetCollectionFromControls, dn as extractTemplateCollection, dt as toReagentRows, en as searchBioTemplatePacks, et as toTimeCourseSteps, f as createWellPlateScreenCollection, fn as getTemplateData, ft as toQpcrColumns, g as createFlowCytometryAssayCollection, gt as toProtocolColumns, h as createWesternBlotAssayCollection, ht as toQpcrWellPlateWells, i as createBioTemplateControlToolkit, in as searchBioTemplateCatalog, it as toSampleRows, j as createSampleSheetTemplate, jt as toAssayMatrixColumns, k as createDoseResponseTemplate, kt as toCalibrationCurveDataFrame, l as requireBioTemplateControlSchema, ln as ensureTemplateEnvelope, lt as toReagentDataFrame, m as createDefaultBioTemplate, mt as toQpcrRows, n as bioTemplateControlsToSectionFormSchemas, nn as getBioTemplateInfo, nt as toSampleDataFrame, o as getBioTemplateControlSchema, on as assertTemplateEnvelope, ot as toSamplePrepDataFrame, p as createBioTemplatePackCollection, pt as toQpcrDataFrame, q as toDoseConditions, qt as bioTemplatePresets, r as bioTemplateControlsToSidebarPanels, rn as listBioTemplateCatalog, rt as toSampleOptions, s as listBioTemplateControlSchemas, sn as createTemplateCollection, st as toSamplePrepRows, t as bioTemplateControlsToFormSchema, tn as bioTemplateCatalog, tt as toSampleColumns, u as createBioTemplatePresetCollection, un as ensureTemplateFromCollection, ut as toReagentListItems, v as createTargetedMetabolomicsCollection, vt as toProtocolRows, w as createReagentListTemplate, wt as toInstrumentRunSteps, x as createQpcrPlateTemplate, xt as toInstrumentRunDataFrame, y as createLcmsBatchCollection, yt as toProtocolSteps, z as toBioTemplateComponentImports, zt as validateInstrumentRunData } from "./templates-Do43ZIMb.js";
5
16
  import { MINTSdk } from "./install.js";
6
- import { a as pluginFormDataFromPayload, c as usePluginClient, d as resolvePluginBaseUrl, f as usePluginConfig, g as useAuth, h as usePasskey, i as getPluginPageSelectorItems, l as usePluginSettings, m as useAsyncBatch, n as downloadBlob, o as uploadPluginEndpoint, p as useAsync, r as downloadPluginEndpoint, s as useCurrentExperiment, t as createPluginClient, u as buildPluginEndpointUrl } from "./composables-wNt7VtkF.js";
17
+ import { a as pluginFormDataFromPayload, c as usePluginClient, d as resolvePluginBaseUrl, f as usePluginConfig, g as useAuth, h as usePasskey, i as getPluginPageSelectorItems, l as usePluginSettings, m as useAsyncBatch, n as downloadBlob, o as uploadPluginEndpoint, p as useAsync, r as downloadPluginEndpoint, s as useCurrentExperiment, t as createPluginClient, u as buildPluginEndpointUrl } from "./composables-DJgqPrlR.js";
7
18
  import "./stores/index.js";
8
19
  //#region src/utils/rack.ts
9
20
  var LCMS_DEFAULT_CONTROL_POSITIONS = {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/utils/rack.ts"],"sourcesContent":["import type { Rack, SlotPosition, Well, WellEditData, WellPlateFormat } from '../types'\n\nexport type LcmsPlateType = '96well' | '54vial'\nexport type LcmsControlSampleType = 'blank' | 'qc' | 'iqc'\n\nexport interface LcmsPlateCell {\n row: string\n column: number\n sample_name: string\n sample_type?: string | null\n injection_volume?: number | null\n injection_count?: number | null\n custom_method?: string | null\n slot?: SlotPosition | null\n}\n\nexport interface LcmsPlateCellsToRackOptions {\n rackId?: string\n rackName?: string\n format?: WellPlateFormat\n plateType?: LcmsPlateType\n slot?: SlotPosition\n injectionVolume?: number\n}\n\nexport interface LcmsPlateCellsToRacksOptions extends Omit<LcmsPlateCellsToRackOptions, 'rackId' | 'rackName' | 'slot'> {\n defaultSlot?: SlotPosition\n rackId?: (slot: SlotPosition, index: number) => string\n rackName?: (slot: SlotPosition, index: number) => string\n}\n\nexport const LCMS_DEFAULT_CONTROL_POSITIONS: Record<LcmsPlateType, Record<LcmsControlSampleType, { row: string; column: number }>> = {\n '96well': {\n blank: { row: 'H', column: 12 },\n qc: { row: 'H', column: 11 },\n iqc: { row: 'H', column: 10 },\n },\n '54vial': {\n blank: { row: 'F', column: 9 },\n qc: { row: 'F', column: 8 },\n iqc: { row: 'F', column: 7 },\n },\n}\n\nconst SLOT_ORDER: SlotPosition[] = ['R', 'G', 'B', 'Y']\n\nexport function lcmsPlateTypeToRackFormat(plateType: LcmsPlateType): WellPlateFormat {\n return plateType === '96well' ? 96 : 54\n}\n\nexport function rackFormatToLcmsPlateType(format: WellPlateFormat): LcmsPlateType {\n if (format === 96) return '96well'\n if (format === 54) return '54vial'\n throw new Error(`LCMS plate cells support only 54-vial racks and 96-well plates; received format ${format}.`)\n}\n\nexport function lcmsWellId(row: string, column: number): string {\n return `${row.toUpperCase()}${column}`\n}\n\nexport function parseLcmsWellId(wellId: string): { row: string; column: number } {\n const match = /^([A-Za-z]+)(\\d+)$/.exec(wellId.trim())\n if (!match) {\n throw new Error(`Invalid well id \"${wellId}\". Expected a row letter followed by a column number, e.g. A1.`)\n }\n\n return {\n row: match[1].toUpperCase(),\n column: Number(match[2]),\n }\n}\n\nexport function lcmsPlateCellsToRack(cells: LcmsPlateCell[], options: LcmsPlateCellsToRackOptions = {}): Rack {\n const format = options.format ?? (options.plateType ? lcmsPlateTypeToRackFormat(options.plateType) : inferRackFormat(cells))\n const slot = options.slot ?? cells.find(cell => cell.slot)?.slot ?? 'R'\n const injectionVolume = options.injectionVolume ?? inferInjectionVolume(cells) ?? 5\n\n return {\n id: options.rackId ?? `rack-${slot}`,\n name: options.rackName ?? `Rack ${slot}`,\n format,\n slot,\n injectionVolume,\n wells: Object.fromEntries(\n cells\n .filter(cell => cell.sample_name.trim())\n .map((cell) => {\n const wellId = lcmsWellId(cell.row, cell.column)\n const well: Partial<Well> = {\n id: wellId,\n row: rowIndex(cell.row),\n col: cell.column - 1,\n state: 'filled',\n sampleType: cell.sample_type ?? 'sample',\n metadata: {\n label: cell.sample_name.trim(),\n injectionVolume: cell.injection_volume ?? injectionVolume,\n injectionCount: cell.injection_count ?? 1,\n customMethod: cell.custom_method ?? null,\n },\n }\n return [wellId, well]\n }),\n ),\n }\n}\n\nexport function lcmsPlateCellsToRacks(cells: LcmsPlateCell[], options: LcmsPlateCellsToRacksOptions = {}): Rack[] {\n const bySlot = new Map<SlotPosition, LcmsPlateCell[]>()\n const defaultSlot = options.defaultSlot ?? 'R'\n\n for (const cell of cells) {\n const slot = cell.slot ?? defaultSlot\n const slotCells = bySlot.get(slot) ?? []\n slotCells.push(cell)\n bySlot.set(slot, slotCells)\n }\n\n return Array.from(bySlot.entries())\n .sort(([a], [b]) => SLOT_ORDER.indexOf(a) - SLOT_ORDER.indexOf(b))\n .map(([slot, slotCells], index) => lcmsPlateCellsToRack(slotCells, {\n ...options,\n slot,\n rackId: options.rackId?.(slot, index) ?? `rack-${slot}`,\n rackName: options.rackName?.(slot, index) ?? `Rack ${slot}`,\n }))\n}\n\nexport function rackToLcmsPlateCells(rack: Rack): LcmsPlateCell[] {\n return Object.entries(rack.wells)\n .map(([wellId, well]) => wellToLcmsPlateCell(rack, wellId, well))\n .filter((cell): cell is LcmsPlateCell => cell !== null)\n .sort(comparePlateCells)\n}\n\nexport function racksToLcmsPlateCells(racks: Rack[]): LcmsPlateCell[] {\n return racks.flatMap(rackToLcmsPlateCells)\n}\n\nexport function getLcmsDefaultControlWellId(plateType: LcmsPlateType, sampleType: LcmsControlSampleType): string {\n const position = LCMS_DEFAULT_CONTROL_POSITIONS[plateType][sampleType]\n return lcmsWellId(position.row, position.column)\n}\n\nexport function createLcmsControlWellEditData(\n sampleType: LcmsControlSampleType,\n options: {\n wellId?: string\n plateType?: LcmsPlateType\n injectionVolume?: number\n } = {},\n): WellEditData {\n const plateType = options.plateType ?? '54vial'\n return {\n wellId: options.wellId ?? getLcmsDefaultControlWellId(plateType, sampleType),\n label: sampleType === 'blank' ? 'Blank' : sampleType.toUpperCase(),\n sampleType,\n injectionVolume: options.injectionVolume ?? 5,\n injectionCount: 1,\n customMethod: '',\n }\n}\n\nfunction wellToLcmsPlateCell(rack: Rack, wellId: string, well: Partial<Well>): LcmsPlateCell | null {\n const metadata = well.metadata ?? {}\n const label = getString(metadata.label)\n if (!label) return null\n\n const parsed = parseLcmsWellId(well.id ?? wellId)\n return {\n row: parsed.row,\n column: parsed.column,\n sample_name: label,\n sample_type: well.sampleType ?? null,\n injection_volume: getNumber(metadata.injectionVolume) ?? rack.injectionVolume,\n injection_count: getNumber(metadata.injectionCount) ?? 1,\n custom_method: getNullableString(metadata.customMethod),\n slot: rack.slot,\n }\n}\n\nfunction inferRackFormat(cells: LcmsPlateCell[]): WellPlateFormat {\n return cells.some(cell => rowIndex(cell.row) > 5 || cell.column > 9) ? 96 : 54\n}\n\nfunction inferInjectionVolume(cells: LcmsPlateCell[]): number | undefined {\n return cells.find(cell => typeof cell.injection_volume === 'number')?.injection_volume ?? undefined\n}\n\nfunction rowIndex(row: string): number {\n return row.toUpperCase().charCodeAt(0) - 65\n}\n\nfunction getString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined\n}\n\nfunction getNullableString(value: unknown): string | null {\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n\nfunction getNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n\nfunction comparePlateCells(a: LcmsPlateCell, b: LcmsPlateCell): number {\n const rowDiff = rowIndex(a.row) - rowIndex(b.row)\n return rowDiff === 0 ? a.column - b.column : rowDiff\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/utils/rack.ts"],"sourcesContent":["import type { Rack, SlotPosition, Well, WellEditData, WellPlateFormat } from '../types'\n\nexport type LcmsPlateType = '96well' | '54vial'\nexport type LcmsControlSampleType = 'blank' | 'qc' | 'iqc'\n\nexport interface LcmsPlateCell {\n row: string\n column: number\n sample_name: string\n sample_type?: string | null\n injection_volume?: number | null\n injection_count?: number | null\n custom_method?: string | null\n slot?: SlotPosition | null\n}\n\nexport interface LcmsPlateCellsToRackOptions {\n rackId?: string\n rackName?: string\n format?: WellPlateFormat\n plateType?: LcmsPlateType\n slot?: SlotPosition\n injectionVolume?: number\n}\n\nexport interface LcmsPlateCellsToRacksOptions extends Omit<LcmsPlateCellsToRackOptions, 'rackId' | 'rackName' | 'slot'> {\n defaultSlot?: SlotPosition\n rackId?: (slot: SlotPosition, index: number) => string\n rackName?: (slot: SlotPosition, index: number) => string\n}\n\nexport const LCMS_DEFAULT_CONTROL_POSITIONS: Record<LcmsPlateType, Record<LcmsControlSampleType, { row: string; column: number }>> = {\n '96well': {\n blank: { row: 'H', column: 12 },\n qc: { row: 'H', column: 11 },\n iqc: { row: 'H', column: 10 },\n },\n '54vial': {\n blank: { row: 'F', column: 9 },\n qc: { row: 'F', column: 8 },\n iqc: { row: 'F', column: 7 },\n },\n}\n\nconst SLOT_ORDER: SlotPosition[] = ['R', 'G', 'B', 'Y']\n\nexport function lcmsPlateTypeToRackFormat(plateType: LcmsPlateType): WellPlateFormat {\n return plateType === '96well' ? 96 : 54\n}\n\nexport function rackFormatToLcmsPlateType(format: WellPlateFormat): LcmsPlateType {\n if (format === 96) return '96well'\n if (format === 54) return '54vial'\n throw new Error(`LCMS plate cells support only 54-vial racks and 96-well plates; received format ${format}.`)\n}\n\nexport function lcmsWellId(row: string, column: number): string {\n return `${row.toUpperCase()}${column}`\n}\n\nexport function parseLcmsWellId(wellId: string): { row: string; column: number } {\n const match = /^([A-Za-z]+)(\\d+)$/.exec(wellId.trim())\n if (!match) {\n throw new Error(`Invalid well id \"${wellId}\". Expected a row letter followed by a column number, e.g. A1.`)\n }\n\n return {\n row: match[1].toUpperCase(),\n column: Number(match[2]),\n }\n}\n\nexport function lcmsPlateCellsToRack(cells: LcmsPlateCell[], options: LcmsPlateCellsToRackOptions = {}): Rack {\n const format = options.format ?? (options.plateType ? lcmsPlateTypeToRackFormat(options.plateType) : inferRackFormat(cells))\n const slot = options.slot ?? cells.find(cell => cell.slot)?.slot ?? 'R'\n const injectionVolume = options.injectionVolume ?? inferInjectionVolume(cells) ?? 5\n\n return {\n id: options.rackId ?? `rack-${slot}`,\n name: options.rackName ?? `Rack ${slot}`,\n format,\n slot,\n injectionVolume,\n wells: Object.fromEntries(\n cells\n .filter(cell => cell.sample_name.trim())\n .map((cell) => {\n const wellId = lcmsWellId(cell.row, cell.column)\n const well: Partial<Well> = {\n id: wellId,\n row: rowIndex(cell.row),\n col: cell.column - 1,\n state: 'filled',\n sampleType: cell.sample_type ?? 'sample',\n metadata: {\n label: cell.sample_name.trim(),\n injectionVolume: cell.injection_volume ?? injectionVolume,\n injectionCount: cell.injection_count ?? 1,\n customMethod: cell.custom_method ?? null,\n },\n }\n return [wellId, well]\n }),\n ),\n }\n}\n\nexport function lcmsPlateCellsToRacks(cells: LcmsPlateCell[], options: LcmsPlateCellsToRacksOptions = {}): Rack[] {\n const bySlot = new Map<SlotPosition, LcmsPlateCell[]>()\n const defaultSlot = options.defaultSlot ?? 'R'\n\n for (const cell of cells) {\n const slot = cell.slot ?? defaultSlot\n const slotCells = bySlot.get(slot) ?? []\n slotCells.push(cell)\n bySlot.set(slot, slotCells)\n }\n\n return Array.from(bySlot.entries())\n .sort(([a], [b]) => SLOT_ORDER.indexOf(a) - SLOT_ORDER.indexOf(b))\n .map(([slot, slotCells], index) => lcmsPlateCellsToRack(slotCells, {\n ...options,\n slot,\n rackId: options.rackId?.(slot, index) ?? `rack-${slot}`,\n rackName: options.rackName?.(slot, index) ?? `Rack ${slot}`,\n }))\n}\n\nexport function rackToLcmsPlateCells(rack: Rack): LcmsPlateCell[] {\n return Object.entries(rack.wells)\n .map(([wellId, well]) => wellToLcmsPlateCell(rack, wellId, well))\n .filter((cell): cell is LcmsPlateCell => cell !== null)\n .sort(comparePlateCells)\n}\n\nexport function racksToLcmsPlateCells(racks: Rack[]): LcmsPlateCell[] {\n return racks.flatMap(rackToLcmsPlateCells)\n}\n\nexport function getLcmsDefaultControlWellId(plateType: LcmsPlateType, sampleType: LcmsControlSampleType): string {\n const position = LCMS_DEFAULT_CONTROL_POSITIONS[plateType][sampleType]\n return lcmsWellId(position.row, position.column)\n}\n\nexport function createLcmsControlWellEditData(\n sampleType: LcmsControlSampleType,\n options: {\n wellId?: string\n plateType?: LcmsPlateType\n injectionVolume?: number\n } = {},\n): WellEditData {\n const plateType = options.plateType ?? '54vial'\n return {\n wellId: options.wellId ?? getLcmsDefaultControlWellId(plateType, sampleType),\n label: sampleType === 'blank' ? 'Blank' : sampleType.toUpperCase(),\n sampleType,\n injectionVolume: options.injectionVolume ?? 5,\n injectionCount: 1,\n customMethod: '',\n }\n}\n\nfunction wellToLcmsPlateCell(rack: Rack, wellId: string, well: Partial<Well>): LcmsPlateCell | null {\n const metadata = well.metadata ?? {}\n const label = getString(metadata.label)\n if (!label) return null\n\n const parsed = parseLcmsWellId(well.id ?? wellId)\n return {\n row: parsed.row,\n column: parsed.column,\n sample_name: label,\n sample_type: well.sampleType ?? null,\n injection_volume: getNumber(metadata.injectionVolume) ?? rack.injectionVolume,\n injection_count: getNumber(metadata.injectionCount) ?? 1,\n custom_method: getNullableString(metadata.customMethod),\n slot: rack.slot,\n }\n}\n\nfunction inferRackFormat(cells: LcmsPlateCell[]): WellPlateFormat {\n return cells.some(cell => rowIndex(cell.row) > 5 || cell.column > 9) ? 96 : 54\n}\n\nfunction inferInjectionVolume(cells: LcmsPlateCell[]): number | undefined {\n return cells.find(cell => typeof cell.injection_volume === 'number')?.injection_volume ?? undefined\n}\n\nfunction rowIndex(row: string): number {\n return row.toUpperCase().charCodeAt(0) - 65\n}\n\nfunction getString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined\n}\n\nfunction getNullableString(value: unknown): string | null {\n return typeof value === 'string' && value.trim() ? value.trim() : null\n}\n\nfunction getNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n\nfunction comparePlateCells(a: LcmsPlateCell, b: LcmsPlateCell): number {\n const rowDiff = rowIndex(a.row) - rowIndex(b.row)\n return rowDiff === 0 ? a.column - b.column : rowDiff\n}\n"],"mappings":"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"}
package/dist/install.js CHANGED
@@ -1,5 +1,10 @@
1
- import { t as components_exports } from "./components-DtX3LDLq.js";
2
- import "./templates-DSbHJC4v.js";
1
+ import { t as components_exports } from "./components-CdjRzHI2.js";
2
+ import "./ExperimentSelectorModal-wm7yUdAr.js";
3
+ import "./BaseSelect-DksaKYq_.js";
4
+ import "./useControlSchema-0n8Bcftq.js";
5
+ import "./SettingsModal-LEKI6Ebl.js";
6
+ import "./BaseModal-B9UA8Y_I.js";
7
+ import "./ExperimentPopover-CCYB1oWp.js";
3
8
  //#region src/install.ts
4
9
  /**
5
10
  * Vue plugin that registers all MINT SDK components globally.
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","names":[],"sources":["../src/install.ts"],"sourcesContent":["import * as components from './components'\n\ntype ComponentRegistryApp = {\n component: (name: string, component: any) => unknown\n}\n\nexport interface MINTSdkPlugin {\n install(app: ComponentRegistryApp): void\n}\n\n/**\n * Vue plugin that registers all MINT SDK components globally.\n *\n * @example\n * ```typescript\n * import { createApp } from 'vue'\n * import { MINTSdk } from '@morscherlab/mint-sdk'\n * import '@morscherlab/mint-sdk/styles'\n *\n * const app = createApp(App)\n * app.use(MINTSdk)\n * ```\n */\nexport const MINTSdk: MINTSdkPlugin = {\n install(app) {\n for (const [name, component] of Object.entries(components)) {\n // Check if it's a valid Vue component (has setup, render, or template)\n if (\n component &&\n typeof component === 'object' &&\n ('setup' in component || 'render' in component || '__name' in component)\n ) {\n app.component(name, component)\n }\n }\n },\n}\n\nexport default MINTSdk\n"],"mappings":";;;;;;;;;;;;;;;;AAuBA,IAAa,UAAyB,EACpC,QAAQ,KAAK;AACX,MAAK,MAAM,CAAC,MAAM,cAAc,OAAO,QAAQ,mBAAW,CAExD,KACE,aACA,OAAO,cAAc,aACpB,WAAW,aAAa,YAAY,aAAa,YAAY,WAE9D,KAAI,UAAU,MAAM,UAAU;GAIrC"}
1
+ {"version":3,"file":"install.js","names":[],"sources":["../src/install.ts"],"sourcesContent":["import * as components from './components'\n\ntype ComponentRegistryApp = {\n component: (name: string, component: any) => unknown\n}\n\nexport interface MINTSdkPlugin {\n install(app: ComponentRegistryApp): void\n}\n\n/**\n * Vue plugin that registers all MINT SDK components globally.\n *\n * @example\n * ```typescript\n * import { createApp } from 'vue'\n * import { MINTSdk } from '@morscherlab/mint-sdk'\n * import '@morscherlab/mint-sdk/styles'\n *\n * const app = createApp(App)\n * app.use(MINTSdk)\n * ```\n */\nexport const MINTSdk: MINTSdkPlugin = {\n install(app) {\n for (const [name, component] of Object.entries(components)) {\n // Check if it's a valid Vue component (has setup, render, or template)\n if (\n component &&\n typeof component === 'object' &&\n ('setup' in component || 'render' in component || '__name' in component)\n ) {\n app.component(name, component)\n }\n }\n },\n}\n\nexport default MINTSdk\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuBA,IAAa,UAAyB,EACpC,QAAQ,KAAK;AACX,MAAK,MAAM,CAAC,MAAM,cAAc,OAAO,QAAQ,mBAAW,CAExD,KACE,aACA,OAAO,cAAc,aACpB,WAAW,aAAa,YAAY,aAAa,YAAY,WAE9D,KAAI,UAAU,MAAM,UAAU;GAIrC"}
@@ -0,0 +1,81 @@
1
+ //#region src/permissions.ts
2
+ var ADMIN_ROLE = "admin";
3
+ var ADMIN_PANEL_PERMISSIONS = [
4
+ "users.view",
5
+ "users.invite",
6
+ "users.manage",
7
+ "platform.configure",
8
+ "platform.view_logs",
9
+ "plugins.configure",
10
+ "plugins.install"
11
+ ];
12
+ function getRoleInfo(user) {
13
+ return user?.roleObj ?? user?.role_obj ?? null;
14
+ }
15
+ function isAdminRole(role) {
16
+ return role === ADMIN_ROLE;
17
+ }
18
+ function isAdminUser(user) {
19
+ return isAdminRole(user?.role) || getRoleInfo(user)?.slug === "admin";
20
+ }
21
+ function getAccessAudience(user) {
22
+ return isAdminUser(user) ? "admin" : "user";
23
+ }
24
+ function getUserPermissions(user) {
25
+ const rolePermissions = getRoleInfo(user)?.permissions;
26
+ if (rolePermissions?.length) return [...rolePermissions];
27
+ return [...user?.permissions ?? []];
28
+ }
29
+ function hasAllPermissions(user, permissions = []) {
30
+ if (permissions.length === 0) return true;
31
+ if (isAdminUser(user)) return true;
32
+ const granted = new Set(getUserPermissions(user));
33
+ return permissions.every((permission) => granted.has(permission));
34
+ }
35
+ function hasAnyPermission(user, permissions = []) {
36
+ if (permissions.length === 0) return true;
37
+ if (isAdminUser(user)) return true;
38
+ const granted = new Set(getUserPermissions(user));
39
+ return permissions.some((permission) => granted.has(permission));
40
+ }
41
+ function canAccessAdmin(user) {
42
+ return isAdminUser(user) || hasAnyPermission(user, ADMIN_PANEL_PERMISSIONS);
43
+ }
44
+ function canAccessPlugin(user, pluginName) {
45
+ if (!pluginName) return true;
46
+ const access = getRoleInfo(user)?.plugin_access;
47
+ if (!access || access === "all") return true;
48
+ return Array.isArray(access) && access.includes(pluginName);
49
+ }
50
+ function normalizeAccessPolicy(rule) {
51
+ if (!rule) return {};
52
+ const { access: nested, ...direct } = rule;
53
+ return {
54
+ ...nested ?? {},
55
+ ...direct,
56
+ ..."visibleFor" in rule && rule.visibleFor !== void 0 ? { visibleFor: rule.visibleFor } : {},
57
+ ..."requiresAdmin" in rule && rule.requiresAdmin !== void 0 ? { requiresAdmin: rule.requiresAdmin } : {},
58
+ ..."permissions" in rule && rule.permissions !== void 0 ? { permissions: rule.permissions } : {},
59
+ ..."anyPermissions" in rule && rule.anyPermissions !== void 0 ? { anyPermissions: rule.anyPermissions } : {}
60
+ };
61
+ }
62
+ function canAccessByPolicy(user, rule, isAuthenticated = user !== null && user !== void 0) {
63
+ const policy = normalizeAccessPolicy(rule);
64
+ if (policy.requiresAuth && !isAuthenticated) return false;
65
+ if (policy.requiresAdmin && !isAdminUser(user)) return false;
66
+ if (!audienceAllowsUser(policy.visibleFor ?? policy.audience, user)) return false;
67
+ if (!hasAllPermissions(user, policy.permissions)) return false;
68
+ if (!hasAnyPermission(user, policy.anyPermissions)) return false;
69
+ if (policy.plugin && !canAccessPlugin(user, policy.plugin)) return false;
70
+ return true;
71
+ }
72
+ function audienceAllowsUser(audience, user) {
73
+ if (audience === void 0) return true;
74
+ const allowed = Array.isArray(audience) ? audience : [audience];
75
+ if (allowed.includes("all")) return true;
76
+ return allowed.includes(getAccessAudience(user));
77
+ }
78
+ //#endregion
79
+ export { ADMIN_PANEL_PERMISSIONS, ADMIN_ROLE, canAccessAdmin, canAccessByPolicy, canAccessPlugin, getAccessAudience, getRoleInfo, getUserPermissions, hasAllPermissions, hasAnyPermission, isAdminRole, isAdminUser, normalizeAccessPolicy };
80
+
81
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","names":[],"sources":["../src/permissions.ts"],"sourcesContent":["export const ADMIN_ROLE = 'admin'\n\nexport const ADMIN_PANEL_PERMISSIONS = [\n 'users.view',\n 'users.invite',\n 'users.manage',\n 'platform.configure',\n 'platform.view_logs',\n 'plugins.configure',\n 'plugins.install',\n] as const\n\nexport type AccessAudience = 'all' | 'admin' | 'user'\nexport type AccessAudienceInput = AccessAudience | readonly AccessAudience[]\n\nexport interface RoleInfo {\n id?: number\n slug: string\n name?: string\n color?: string\n permissions?: readonly string[] | null\n project_scope?: 'all' | 'assigned' | string\n plugin_access?: readonly string[] | 'all' | null\n}\n\nexport interface PermissionUser {\n role?: string | null\n role_obj?: RoleInfo | null\n roleObj?: RoleInfo | null\n permissions?: readonly string[] | null\n}\n\nexport interface AccessPolicy {\n audience?: AccessAudienceInput\n visibleFor?: AccessAudienceInput\n requiresAuth?: boolean\n requiresAdmin?: boolean\n permissions?: readonly string[]\n anyPermissions?: readonly string[]\n plugin?: string\n}\n\nexport interface AccessControlled {\n access?: AccessPolicy\n visibleFor?: AccessAudienceInput\n requiresAdmin?: boolean\n permissions?: readonly string[]\n anyPermissions?: readonly string[]\n}\n\nexport function getRoleInfo(user: PermissionUser | null | undefined): RoleInfo | null {\n return user?.roleObj ?? user?.role_obj ?? null\n}\n\nexport function isAdminRole(role: string | null | undefined): boolean {\n return role === ADMIN_ROLE\n}\n\nexport function isAdminUser(user: PermissionUser | null | undefined): boolean {\n return isAdminRole(user?.role) || getRoleInfo(user)?.slug === ADMIN_ROLE\n}\n\nexport function getAccessAudience(user: PermissionUser | null | undefined): Exclude<AccessAudience, 'all'> {\n return isAdminUser(user) ? 'admin' : 'user'\n}\n\nexport function getUserPermissions(user: PermissionUser | null | undefined): string[] {\n const rolePermissions = getRoleInfo(user)?.permissions\n if (rolePermissions?.length) return [...rolePermissions]\n return [...(user?.permissions ?? [])]\n}\n\nexport function hasAllPermissions(\n user: PermissionUser | null | undefined,\n permissions: readonly string[] = [],\n): boolean {\n if (permissions.length === 0) return true\n if (isAdminUser(user)) return true\n const granted = new Set(getUserPermissions(user))\n return permissions.every(permission => granted.has(permission))\n}\n\nexport function hasAnyPermission(\n user: PermissionUser | null | undefined,\n permissions: readonly string[] = [],\n): boolean {\n if (permissions.length === 0) return true\n if (isAdminUser(user)) return true\n const granted = new Set(getUserPermissions(user))\n return permissions.some(permission => granted.has(permission))\n}\n\nexport function canAccessAdmin(user: PermissionUser | null | undefined): boolean {\n return isAdminUser(user) || hasAnyPermission(user, ADMIN_PANEL_PERMISSIONS)\n}\n\nexport function canAccessPlugin(\n user: PermissionUser | null | undefined,\n pluginName: string | null | undefined,\n): boolean {\n if (!pluginName) return true\n const access = getRoleInfo(user)?.plugin_access\n if (!access || access === 'all') return true\n return Array.isArray(access) && access.includes(pluginName)\n}\n\nexport function normalizeAccessPolicy(rule: AccessControlled | AccessPolicy | undefined): AccessPolicy {\n if (!rule) return {}\n const { access: nested, ...direct } = rule as AccessPolicy & { access?: AccessPolicy }\n return {\n ...(nested ?? {}),\n ...direct,\n ...('visibleFor' in rule && rule.visibleFor !== undefined ? { visibleFor: rule.visibleFor } : {}),\n ...('requiresAdmin' in rule && rule.requiresAdmin !== undefined ? { requiresAdmin: rule.requiresAdmin } : {}),\n ...('permissions' in rule && rule.permissions !== undefined ? { permissions: rule.permissions } : {}),\n ...('anyPermissions' in rule && rule.anyPermissions !== undefined ? { anyPermissions: rule.anyPermissions } : {}),\n }\n}\n\nexport function canAccessByPolicy(\n user: PermissionUser | null | undefined,\n rule: AccessControlled | AccessPolicy | undefined,\n isAuthenticated = user !== null && user !== undefined,\n): boolean {\n const policy = normalizeAccessPolicy(rule)\n if (policy.requiresAuth && !isAuthenticated) return false\n if (policy.requiresAdmin && !isAdminUser(user)) return false\n if (!audienceAllowsUser(policy.visibleFor ?? policy.audience, user)) return false\n if (!hasAllPermissions(user, policy.permissions)) return false\n if (!hasAnyPermission(user, policy.anyPermissions)) return false\n if (policy.plugin && !canAccessPlugin(user, policy.plugin)) return false\n return true\n}\n\nfunction audienceAllowsUser(\n audience: AccessAudienceInput | undefined,\n user: PermissionUser | null | undefined,\n): boolean {\n if (audience === undefined) return true\n const allowed = Array.isArray(audience) ? audience : [audience]\n if (allowed.includes('all')) return true\n return allowed.includes(getAccessAudience(user))\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { g as useSettingsStore, h as colorPalettes, t as useAuthStore } from "../auth-BulIv_km.js";
1
+ import { n as colorPalettes, r as useSettingsStore, t as useAuthStore } from "../auth-D9q2GIcv.js";
2
2
  export { colorPalettes, useAuthStore, useSettingsStore };