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

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 (178) hide show
  1. package/dist/components/AppSidebar.vue.d.ts +3 -3
  2. package/dist/components/ControlWorkspaceView.vue.d.ts +3 -3
  3. package/dist/components/DoseDesignWorkspaceView.vue.d.ts +1 -1
  4. package/dist/components/PluginWorkspaceView.vue.d.ts +3 -3
  5. package/dist/components/index.js +2 -2
  6. package/dist/{components-BhK-dW99.js → components-DafPc4rM.js} +3 -3
  7. package/dist/{components-BhK-dW99.js.map → components-DafPc4rM.js.map} +1 -1
  8. package/dist/composables/controlComponentBindings.d.ts +7 -0
  9. package/dist/composables/controlSchemaAdapters.d.ts +20 -0
  10. package/dist/composables/controlSchemaFormFields.d.ts +3 -0
  11. package/dist/composables/controlSchemaLayout.d.ts +7 -0
  12. package/dist/composables/controlSchemaNormalize.d.ts +15 -0
  13. package/dist/composables/controlSchemaUtils.d.ts +9 -0
  14. package/dist/composables/controlWorkspaceOptions.d.ts +2 -0
  15. package/dist/composables/index.js +3 -3
  16. package/dist/composables/useControlSchema.d.ts +4 -30
  17. package/dist/composables/useControlWorkspace.d.ts +5 -0
  18. package/dist/{composables-Bg7CFuNz.js → composables-BMkPQhVK.js} +2 -2
  19. package/dist/{composables-Bg7CFuNz.js.map → composables-BMkPQhVK.js.map} +1 -1
  20. package/dist/index.js +4 -4
  21. package/dist/install.js +2 -2
  22. package/dist/templates/adapters.d.ts +14 -47
  23. package/dist/templates/assayLookups.d.ts +3 -0
  24. package/dist/templates/assayMatrixAdapters.d.ts +6 -0
  25. package/dist/templates/assayMatrixBuilder.d.ts +2 -0
  26. package/dist/templates/assayNormalizers.d.ts +4 -0
  27. package/dist/templates/builderDefaults.d.ts +1 -0
  28. package/dist/templates/builderIdUtils.d.ts +4 -0
  29. package/dist/templates/builderPresetControls.d.ts +10 -0
  30. package/dist/templates/builderReadUtils.d.ts +8 -0
  31. package/dist/templates/builders.d.ts +26 -67
  32. package/dist/templates/calibrationCurveAdapters.d.ts +4 -0
  33. package/dist/templates/calibrationCurveBuilder.d.ts +2 -0
  34. package/dist/templates/calibrationNormalizers.d.ts +5 -0
  35. package/dist/templates/componentBindingCatalog.d.ts +25 -0
  36. package/dist/templates/componentBindingHelpers.d.ts +17 -0
  37. package/dist/templates/componentDoseResponseProps.d.ts +3 -0
  38. package/dist/templates/componentGenericProps.d.ts +8 -0
  39. package/dist/templates/componentPlateHelpers.d.ts +5 -0
  40. package/dist/templates/componentPlateMapProps.d.ts +3 -0
  41. package/dist/templates/componentPropsFactory.d.ts +3 -0
  42. package/dist/templates/componentQpcrPlateProps.d.ts +3 -0
  43. package/dist/templates/componentTargetResolvers.d.ts +5 -0
  44. package/dist/templates/componentTemplateProps.d.ts +3 -0
  45. package/dist/templates/controlSchemaClone.d.ts +4 -0
  46. package/dist/templates/controlSchemaConstants.d.ts +10 -0
  47. package/dist/templates/controlSchemaMerge.d.ts +3 -0
  48. package/dist/templates/controlSchemaTargets.d.ts +17 -0
  49. package/dist/templates/controlSchemaTypes.d.ts +4 -0
  50. package/dist/templates/controlSchemas.d.ts +4 -4
  51. package/dist/templates/defaultBioTemplateBuilder.d.ts +2 -0
  52. package/dist/templates/doseResponseAdapters.d.ts +4 -0
  53. package/dist/templates/doseResponseBuilder.d.ts +2 -0
  54. package/dist/templates/elisaAssayCollectionBuilder.d.ts +2 -0
  55. package/dist/templates/flowCytometryAssayCollectionBuilder.d.ts +2 -0
  56. package/dist/templates/flowCytometryPanelBuilder.d.ts +2 -0
  57. package/dist/templates/flowNormalizers.d.ts +8 -0
  58. package/dist/templates/flowPanelAdapters.d.ts +4 -0
  59. package/dist/templates/index.js +1 -1
  60. package/dist/templates/instrumentRunAdapterHelpers.d.ts +8 -0
  61. package/dist/templates/instrumentRunAdapters.d.ts +8 -0
  62. package/dist/templates/instrumentRunBuilder.d.ts +2 -0
  63. package/dist/templates/lcmsBatchCollectionBuilder.d.ts +2 -0
  64. package/dist/templates/plateGeometry.d.ts +4 -0
  65. package/dist/templates/plateMapAdapters.d.ts +3 -0
  66. package/dist/templates/plateMapBuilder.d.ts +2 -0
  67. package/dist/templates/presetControlSchemas.d.ts +534 -0
  68. package/dist/templates/protocolAdapters.d.ts +5 -0
  69. package/dist/templates/protocolNormalizers.d.ts +6 -0
  70. package/dist/templates/protocolStepsBuilder.d.ts +2 -0
  71. package/dist/templates/qpcrAdapters.d.ts +5 -0
  72. package/dist/templates/qpcrExpressionCollectionBuilder.d.ts +2 -0
  73. package/dist/templates/qpcrPlateBuilder.d.ts +2 -0
  74. package/dist/templates/reagentAdapters.d.ts +5 -0
  75. package/dist/templates/reagentListBuilder.d.ts +2 -0
  76. package/dist/templates/runNormalizers.d.ts +10 -0
  77. package/dist/templates/sampleNormalizers.d.ts +4 -0
  78. package/dist/templates/samplePrepAdapters.d.ts +4 -0
  79. package/dist/templates/samplePrepBuilder.d.ts +2 -0
  80. package/dist/templates/sampleSheetAdapters.d.ts +5 -0
  81. package/dist/templates/sampleSheetBuilder.d.ts +2 -0
  82. package/dist/templates/targetedMetabolomicsCollectionBuilder.d.ts +2 -0
  83. package/dist/templates/targetedMetabolomicsHelpers.d.ts +5 -0
  84. package/dist/templates/templateControlSchemas.d.ts +400 -0
  85. package/dist/templates/templateEnvelopes.d.ts +9 -0
  86. package/dist/templates/templatePackCollectionBuilder.d.ts +2 -0
  87. package/dist/templates/templatePresetCollectionBuilder.d.ts +18 -0
  88. package/dist/templates/templateValidators.d.ts +13 -0
  89. package/dist/templates/timeCourseAdapters.d.ts +5 -0
  90. package/dist/templates/timeCourseBuilder.d.ts +2 -0
  91. package/dist/templates/wellPlateScreenCollectionBuilder.d.ts +2 -0
  92. package/dist/templates/westernBlotAssayCollectionBuilder.d.ts +2 -0
  93. package/dist/{templates-BorLR_7p.js → templates-bUAWMn5L.js} +3574 -3428
  94. package/dist/templates-bUAWMn5L.js.map +1 -0
  95. package/dist/{useProtocolTemplates-n6AJqSqv.js → useProtocolTemplates-QZtHFFH2.js} +2 -2
  96. package/dist/{useProtocolTemplates-n6AJqSqv.js.map → useProtocolTemplates-QZtHFFH2.js.map} +1 -1
  97. package/package.json +1 -1
  98. package/src/composables/controlComponentBindings.ts +80 -0
  99. package/src/composables/controlSchemaAdapters.ts +196 -0
  100. package/src/composables/controlSchemaFormFields.ts +61 -0
  101. package/src/composables/controlSchemaLayout.ts +59 -0
  102. package/src/composables/controlSchemaNormalize.ts +101 -0
  103. package/src/composables/controlSchemaUtils.ts +36 -0
  104. package/src/composables/controlWorkspaceOptions.ts +21 -0
  105. package/src/composables/useControlSchema.ts +51 -628
  106. package/src/composables/useControlWorkspace.ts +207 -0
  107. package/src/templates/adapters.ts +89 -930
  108. package/src/templates/assayLookups.ts +33 -0
  109. package/src/templates/assayMatrixAdapters.ts +78 -0
  110. package/src/templates/assayMatrixBuilder.ts +59 -0
  111. package/src/templates/assayNormalizers.ts +34 -0
  112. package/src/templates/builderDefaults.ts +11 -0
  113. package/src/templates/builderIdUtils.ts +20 -0
  114. package/src/templates/builderPresetControls.ts +165 -0
  115. package/src/templates/builderReadUtils.ts +57 -0
  116. package/src/templates/builders.ts +122 -2350
  117. package/src/templates/calibrationCurveAdapters.ts +59 -0
  118. package/src/templates/calibrationCurveBuilder.ts +99 -0
  119. package/src/templates/calibrationNormalizers.ts +60 -0
  120. package/src/templates/componentBindingCatalog.ts +90 -0
  121. package/src/templates/componentBindingHelpers.ts +93 -0
  122. package/src/templates/componentBindings.ts +12 -461
  123. package/src/templates/componentDoseResponseProps.ts +42 -0
  124. package/src/templates/componentGenericProps.ts +77 -0
  125. package/src/templates/componentPlateHelpers.ts +29 -0
  126. package/src/templates/componentPlateMapProps.ts +32 -0
  127. package/src/templates/componentPropsFactory.ts +21 -0
  128. package/src/templates/componentQpcrPlateProps.ts +28 -0
  129. package/src/templates/componentTargetResolvers.ts +69 -0
  130. package/src/templates/componentTemplateProps.ts +78 -0
  131. package/src/templates/controlSchemaClone.ts +32 -0
  132. package/src/templates/controlSchemaConstants.ts +11 -0
  133. package/src/templates/controlSchemaMerge.ts +40 -0
  134. package/src/templates/controlSchemaTargets.ts +87 -0
  135. package/src/templates/controlSchemaTypes.ts +20 -0
  136. package/src/templates/controlSchemas.ts +22 -704
  137. package/src/templates/defaultBioTemplateBuilder.ts +124 -0
  138. package/src/templates/doseResponseAdapters.ts +45 -0
  139. package/src/templates/doseResponseBuilder.ts +44 -0
  140. package/src/templates/elisaAssayCollectionBuilder.ts +62 -0
  141. package/src/templates/flowCytometryAssayCollectionBuilder.ts +41 -0
  142. package/src/templates/flowCytometryPanelBuilder.ts +53 -0
  143. package/src/templates/flowNormalizers.ts +58 -0
  144. package/src/templates/flowPanelAdapters.ts +58 -0
  145. package/src/templates/instrumentRunAdapterHelpers.ts +94 -0
  146. package/src/templates/instrumentRunAdapters.ts +163 -0
  147. package/src/templates/instrumentRunBuilder.ts +97 -0
  148. package/src/templates/lcmsBatchCollectionBuilder.ts +38 -0
  149. package/src/templates/plateGeometry.ts +62 -0
  150. package/src/templates/plateMapAdapters.ts +36 -0
  151. package/src/templates/plateMapBuilder.ts +43 -0
  152. package/src/templates/presetControlSchemas.ts +258 -0
  153. package/src/templates/protocolAdapters.ts +69 -0
  154. package/src/templates/protocolNormalizers.ts +37 -0
  155. package/src/templates/protocolStepsBuilder.ts +36 -0
  156. package/src/templates/qpcrAdapters.ts +104 -0
  157. package/src/templates/qpcrExpressionCollectionBuilder.ts +33 -0
  158. package/src/templates/qpcrPlateBuilder.ts +96 -0
  159. package/src/templates/reagentAdapters.ts +77 -0
  160. package/src/templates/reagentListBuilder.ts +30 -0
  161. package/src/templates/runNormalizers.ts +63 -0
  162. package/src/templates/sampleNormalizers.ts +58 -0
  163. package/src/templates/samplePrepAdapters.ts +63 -0
  164. package/src/templates/samplePrepBuilder.ts +51 -0
  165. package/src/templates/sampleSheetAdapters.ts +75 -0
  166. package/src/templates/sampleSheetBuilder.ts +23 -0
  167. package/src/templates/targetedMetabolomicsCollectionBuilder.ts +79 -0
  168. package/src/templates/targetedMetabolomicsHelpers.ts +102 -0
  169. package/src/templates/templateControlSchemas.ts +320 -0
  170. package/src/templates/templateEnvelopes.ts +137 -0
  171. package/src/templates/templatePackCollectionBuilder.ts +23 -0
  172. package/src/templates/templatePresetCollectionBuilder.ts +139 -0
  173. package/src/templates/templateValidators.ts +414 -0
  174. package/src/templates/timeCourseAdapters.ts +73 -0
  175. package/src/templates/timeCourseBuilder.ts +64 -0
  176. package/src/templates/wellPlateScreenCollectionBuilder.ts +36 -0
  177. package/src/templates/westernBlotAssayCollectionBuilder.ts +68 -0
  178. package/dist/templates-BorLR_7p.js.map +0 -1
@@ -0,0 +1,21 @@
1
+ import { cloneBinding } from './componentBindingHelpers'
2
+ import { templateComponentBindings } from './componentBindingCatalog'
3
+ import type {
4
+ BioTemplateComponentPropsBinding,
5
+ } from './componentBindings'
6
+ import type { TemplateId } from './types'
7
+
8
+ export function propsBinding(
9
+ templateId: TemplateId,
10
+ component: string,
11
+ propsObject: Record<string, unknown>
12
+ ): BioTemplateComponentPropsBinding {
13
+ const matched = templateComponentBindings[templateId].find(binding => binding.component === component)
14
+ if (!matched) {
15
+ throw new Error(`No component binding registered for '${templateId}' and '${component}'.`)
16
+ }
17
+ return {
18
+ ...cloneBinding(matched),
19
+ propsObject,
20
+ }
21
+ }
@@ -0,0 +1,28 @@
1
+ import type { WellLegendItem } from '../types'
2
+ import { toQpcrWellPlateWells } from './adapters'
3
+ import { colorForIndex } from './componentPlateHelpers'
4
+ import { getTemplateData } from './templateEnvelopes'
5
+ import { dataFrameProps } from './componentGenericProps'
6
+ import { propsBinding } from './componentPropsFactory'
7
+ import type { BioTemplateComponentPropsBinding } from './componentBindings'
8
+ import type { QpcrPlateTemplate } from './types'
9
+
10
+ export function qpcrPlateProps(template: QpcrPlateTemplate): BioTemplateComponentPropsBinding[] {
11
+ const data = getTemplateData(template, 'qpcr-plate')
12
+ const frame = dataFrameProps(template)
13
+ return [
14
+ propsBinding('qpcr-plate', 'WellPlate', {
15
+ format: data.format,
16
+ wells: toQpcrWellPlateWells(template),
17
+ sampleColors: Object.fromEntries(data.samples.map((sample, index) => [sample.sampleId, colorForIndex(index)])),
18
+ legendItems: data.samples.map((sample, index): WellLegendItem => ({
19
+ type: sample.sampleId,
20
+ label: sample.name ?? sample.sampleId,
21
+ color: colorForIndex(index),
22
+ })),
23
+ showLegend: true,
24
+ showSampleTypeIndicator: true,
25
+ }),
26
+ frame,
27
+ ]
28
+ }
@@ -0,0 +1,69 @@
1
+ import { extractTemplateCollection } from './templateEnvelopes'
2
+ import { getBioTemplateInfo } from './catalog'
3
+ import { getBioTemplatePackInfo } from './packs'
4
+ import { getBioTemplatePresetInfo } from './presets'
5
+ import type {
6
+ BioTemplateEnvelope,
7
+ TemplateCollectionEnvelope,
8
+ TemplateId,
9
+ TemplatePackId,
10
+ TemplatePresetId,
11
+ } from './types'
12
+
13
+ type BioTemplateComponentTarget =
14
+ | TemplateId
15
+ | TemplatePackId
16
+ | TemplatePresetId
17
+ | string
18
+ | BioTemplateEnvelope<unknown>
19
+ | TemplateCollectionEnvelope
20
+
21
+ export function resolveComponentTemplateIds(target: BioTemplateComponentTarget): TemplateId[] {
22
+ if (typeof target === 'string') {
23
+ const preset = getBioTemplatePresetInfo(target)
24
+ if (preset) return [...preset.templates]
25
+ const pack = getBioTemplatePackInfo(target)
26
+ if (pack) return [...pack.templates]
27
+ const template = getBioTemplateInfo(target)
28
+ return template ? [template.template_id] : []
29
+ }
30
+
31
+ if (isTemplateEnvelope(target)) {
32
+ const template = getBioTemplateInfo(target.template_id)
33
+ return template ? [template.template_id] : []
34
+ }
35
+
36
+ const presetName = collectionPresetName(target)
37
+ if (presetName) {
38
+ const preset = getBioTemplatePresetInfo(presetName)
39
+ if (preset) return [...preset.templates]
40
+ }
41
+
42
+ const packName = collectionPackName(target)
43
+ if (packName) {
44
+ const pack = getBioTemplatePackInfo(packName)
45
+ if (pack) return [...pack.templates]
46
+ }
47
+
48
+ return Object.keys(extractTemplateCollection(target))
49
+ .map(templateId => getBioTemplateInfo(templateId)?.template_id)
50
+ .filter((templateId): templateId is TemplateId => templateId !== undefined)
51
+ }
52
+
53
+ export function isTemplateEnvelope(value: unknown): value is BioTemplateEnvelope<unknown> {
54
+ return isRecord(value) && typeof value.template_id === 'string' && 'data' in value
55
+ }
56
+
57
+ function collectionPresetName(value: unknown): string | undefined {
58
+ if (!isRecord(value) || !isRecord(value.metadata)) return undefined
59
+ return typeof value.metadata.preset === 'string' ? value.metadata.preset : undefined
60
+ }
61
+
62
+ function collectionPackName(value: unknown): string | undefined {
63
+ if (!isRecord(value) || !isRecord(value.metadata)) return undefined
64
+ return typeof value.metadata.pack === 'string' ? value.metadata.pack : undefined
65
+ }
66
+
67
+ function isRecord(value: unknown): value is Record<string, unknown> {
68
+ return typeof value === 'object' && value !== null
69
+ }
@@ -0,0 +1,78 @@
1
+ import {
2
+ toInstrumentRunSteps,
3
+ toProtocolSteps,
4
+ toTimeCourseSteps,
5
+ } from './adapters'
6
+ import { doseResponseProps } from './componentDoseResponseProps'
7
+ import {
8
+ assayMatrixSampleSelectorProps,
9
+ dataFrameProps,
10
+ reagentListProps,
11
+ sampleSelectorProps,
12
+ scheduleCalendarProps,
13
+ timelineProps,
14
+ } from './componentGenericProps'
15
+ import { plateMapProps } from './componentPlateMapProps'
16
+ import { qpcrPlateProps } from './componentQpcrPlateProps'
17
+ import type { BioTemplateComponentPropsBinding } from './componentBindings'
18
+ import type {
19
+ AssayMatrixTemplate,
20
+ BioTemplateEnvelope,
21
+ DataFrameTemplate,
22
+ DoseResponseTemplate,
23
+ InstrumentRunTemplate,
24
+ PlateMapTemplate,
25
+ ProtocolStepsTemplate,
26
+ QpcrPlateTemplate,
27
+ ReagentListTemplate,
28
+ SampleSheetTemplate,
29
+ TimeCourseTemplate,
30
+ } from './types'
31
+
32
+ export function propsForTemplate(template: BioTemplateEnvelope<unknown>): BioTemplateComponentPropsBinding[] {
33
+ switch (template.template_id) {
34
+ case 'plate-map':
35
+ return plateMapProps(template as PlateMapTemplate)
36
+ case 'sample-sheet':
37
+ return [
38
+ dataFrameProps(template as DataFrameTemplate),
39
+ sampleSelectorProps(template as SampleSheetTemplate),
40
+ ]
41
+ case 'sample-prep':
42
+ case 'calibration-curve':
43
+ case 'flow-cytometry-panel':
44
+ return [dataFrameProps(template as DataFrameTemplate)]
45
+ case 'assay-matrix':
46
+ return [
47
+ dataFrameProps(template as DataFrameTemplate),
48
+ assayMatrixSampleSelectorProps(template as AssayMatrixTemplate),
49
+ ]
50
+ case 'instrument-run':
51
+ return [
52
+ dataFrameProps(template as DataFrameTemplate),
53
+ scheduleCalendarProps(template as InstrumentRunTemplate),
54
+ timelineProps(template as InstrumentRunTemplate, toInstrumentRunSteps(template as InstrumentRunTemplate)),
55
+ ]
56
+ case 'dose-response':
57
+ return doseResponseProps(template as DoseResponseTemplate)
58
+ case 'time-course':
59
+ return [
60
+ timelineProps(template as TimeCourseTemplate, toTimeCourseSteps(template as TimeCourseTemplate)),
61
+ dataFrameProps(template as DataFrameTemplate),
62
+ ]
63
+ case 'protocol-steps':
64
+ return [
65
+ timelineProps(template as ProtocolStepsTemplate, toProtocolSteps(template as ProtocolStepsTemplate), true),
66
+ dataFrameProps(template as DataFrameTemplate),
67
+ ]
68
+ case 'reagent-list':
69
+ return [
70
+ reagentListProps(template as ReagentListTemplate),
71
+ dataFrameProps(template as DataFrameTemplate),
72
+ ]
73
+ case 'qpcr-plate':
74
+ return qpcrPlateProps(template as QpcrPlateTemplate)
75
+ default:
76
+ return []
77
+ }
78
+ }
@@ -0,0 +1,32 @@
1
+ import type {
2
+ BioTemplateControlSchema,
3
+ } from './controlSchemaTypes'
4
+
5
+ export function cloneSchemaMap<TName extends string>(
6
+ schemas: Record<TName, BioTemplateControlSchema>
7
+ ): Record<TName, BioTemplateControlSchema> {
8
+ const result = {} as Record<TName, BioTemplateControlSchema>
9
+ for (const name of Object.keys(schemas) as TName[]) {
10
+ result[name] = cloneControlSchema(schemas[name])
11
+ }
12
+ return result
13
+ }
14
+
15
+ export function cloneControlSchema(schema: BioTemplateControlSchema): BioTemplateControlSchema {
16
+ return Object.fromEntries(
17
+ Object.entries(schema).map(([name, definition]) => [name, cloneControlDefinition(definition)])
18
+ )
19
+ }
20
+
21
+ export function cloneControlDefinition(
22
+ definition: BioTemplateControlSchema[string]
23
+ ): BioTemplateControlSchema[string] {
24
+ return {
25
+ ...definition,
26
+ options: definition.options ? [...definition.options] : undefined,
27
+ props: definition.props ? { ...definition.props } : undefined,
28
+ sidebar: typeof definition.sidebar === 'object' && definition.sidebar !== null
29
+ ? { ...definition.sidebar }
30
+ : definition.sidebar,
31
+ }
32
+ }
@@ -0,0 +1,11 @@
1
+ export const ICONS = {
2
+ plate: ['M4 4h16v16H4z', 'M8 4v16', 'M12 4v16', 'M16 4v16', 'M4 8h16', 'M4 12h16', 'M4 16h16'],
3
+ samples: ['M16 21v-2a4 4 0 0 0-8 0v2', 'M12 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8'],
4
+ dose: ['M10 2v8L4 20h16l-6-10V2', 'M8 2h8', 'M7 14h10'],
5
+ table: ['M3 5h18', 'M3 12h18', 'M3 19h18', 'M8 5v14', 'M16 5v14'],
6
+ run: ['M4 17l6-6 4 4 6-8', 'M4 21h16'],
7
+ settings: ['M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8', 'M4 12h2', 'M18 12h2', 'M12 4v2', 'M12 18v2'],
8
+ }
9
+
10
+ export const PLATE_FORMAT_OPTIONS = [6, 12, 24, 48, 96, 384] as const
11
+ export const CONCENTRATION_UNITS = ['nM', 'uM', 'mM', 'ug/mL', 'mg/mL'] as const
@@ -0,0 +1,40 @@
1
+ import {
2
+ getBioTemplateInfo,
3
+ } from './catalog'
4
+ import {
5
+ cloneControlDefinition,
6
+ } from './controlSchemaClone'
7
+ import type {
8
+ BioTemplateControlSchema,
9
+ } from './controlSchemaTypes'
10
+ import type {
11
+ TemplateId,
12
+ } from './types'
13
+
14
+ export function mergeTemplateControlSchemas(
15
+ templateIds: TemplateId[],
16
+ templateSchemas: Record<TemplateId, BioTemplateControlSchema>
17
+ ): BioTemplateControlSchema {
18
+ const merged: BioTemplateControlSchema = {}
19
+ for (const templateId of templateIds) {
20
+ const schema = templateSchemas[templateId]
21
+ const template = getBioTemplateInfo(templateId)
22
+ for (const [name, definition] of Object.entries(schema)) {
23
+ const key = `${camelize(templateId)}${capitalize(name)}`
24
+ merged[key] = {
25
+ ...cloneControlDefinition(definition),
26
+ section: definition.section ?? templateId,
27
+ sectionLabel: definition.sectionLabel ?? template?.label ?? templateId,
28
+ }
29
+ }
30
+ }
31
+ return merged
32
+ }
33
+
34
+ function camelize(value: string): string {
35
+ return value.replace(/-([a-z0-9])/g, (_, char: string) => char.toUpperCase())
36
+ }
37
+
38
+ function capitalize(value: string): string {
39
+ return value.charAt(0).toUpperCase() + value.slice(1)
40
+ }
@@ -0,0 +1,87 @@
1
+ import {
2
+ getBioTemplateInfo,
3
+ } from './catalog'
4
+ import {
5
+ getBioTemplatePackInfo,
6
+ } from './packs'
7
+ import {
8
+ getBioTemplatePresetInfo,
9
+ } from './presets'
10
+ import {
11
+ extractTemplateCollection,
12
+ } from './templateEnvelopes'
13
+ import type {
14
+ BioTemplateEnvelope,
15
+ TemplateId,
16
+ TemplatePresetId,
17
+ } from './types'
18
+ import type {
19
+ BioTemplateControlTarget,
20
+ } from './controlSchemaTypes'
21
+
22
+ export type ControlSchemaResolvedTarget =
23
+ | { kind: 'template'; name: TemplateId }
24
+ | { kind: 'pack'; templates: TemplateId[] }
25
+ | { kind: 'preset'; name: TemplatePresetId }
26
+ | { kind: 'collection'; templates: TemplateId[] }
27
+
28
+ export function resolveControlSchemaTarget(
29
+ target: BioTemplateControlTarget
30
+ ): ControlSchemaResolvedTarget | undefined {
31
+ if (typeof target === 'string') {
32
+ const preset = getBioTemplatePresetInfo(target)
33
+ if (preset) return { kind: 'preset', name: preset.name }
34
+ const pack = getBioTemplatePackInfo(target)
35
+ if (pack) return { kind: 'pack', templates: [...pack.templates] }
36
+ const template = getBioTemplateInfo(target)
37
+ if (template) return { kind: 'template', name: template.template_id }
38
+ return undefined
39
+ }
40
+
41
+ if (isTemplateEnvelope(target)) {
42
+ const template = getBioTemplateInfo(target.template_id)
43
+ return template ? { kind: 'template', name: template.template_id } : undefined
44
+ }
45
+
46
+ const presetName = collectionPresetName(target)
47
+ if (presetName) {
48
+ const preset = getBioTemplatePresetInfo(presetName)
49
+ if (preset) return { kind: 'preset', name: preset.name }
50
+ }
51
+
52
+ const packName = collectionPackName(target)
53
+ if (packName) {
54
+ const pack = getBioTemplatePackInfo(packName)
55
+ if (pack) return { kind: 'pack', templates: [...pack.templates] }
56
+ }
57
+
58
+ const collection = extractTemplateCollection(target)
59
+ const templateIds = Object.keys(collection)
60
+ .map(id => getBioTemplateInfo(id)?.template_id)
61
+ .filter((id): id is TemplateId => id !== undefined)
62
+ return templateIds.length > 0 ? { kind: 'collection', templates: templateIds } : undefined
63
+ }
64
+
65
+ export function describeControlTarget(target: BioTemplateControlTarget): string {
66
+ if (typeof target === 'string') return target
67
+ if (isTemplateEnvelope(target)) return target.template_id
68
+ return collectionPresetName(target) ?? collectionPackName(target) ?? 'template collection'
69
+ }
70
+
71
+ function isTemplateEnvelope(value: unknown): value is BioTemplateEnvelope<unknown> {
72
+ return isRecord(value) && typeof value.template_id === 'string' && 'data' in value
73
+ }
74
+
75
+ function collectionPresetName(value: unknown): string | undefined {
76
+ if (!isRecord(value) || !isRecord(value.metadata)) return undefined
77
+ return typeof value.metadata.preset === 'string' ? value.metadata.preset : undefined
78
+ }
79
+
80
+ function collectionPackName(value: unknown): string | undefined {
81
+ if (!isRecord(value) || !isRecord(value.metadata)) return undefined
82
+ return typeof value.metadata.pack === 'string' ? value.metadata.pack : undefined
83
+ }
84
+
85
+ function isRecord(value: unknown): value is Record<string, unknown> {
86
+ return typeof value === 'object' && value !== null
87
+ }
@@ -0,0 +1,20 @@
1
+ import type {
2
+ ControlDefinition,
3
+ } from '../composables/useControlSchema'
4
+ import type {
5
+ BioTemplateEnvelope,
6
+ TemplateCollectionEnvelope,
7
+ TemplateId,
8
+ TemplatePackId,
9
+ TemplatePresetId,
10
+ } from './types'
11
+
12
+ export type BioTemplateControlSchema = Record<string, ControlDefinition>
13
+
14
+ export type BioTemplateControlTarget =
15
+ | TemplateId
16
+ | TemplatePackId
17
+ | TemplatePresetId
18
+ | string
19
+ | BioTemplateEnvelope<unknown>
20
+ | TemplateCollectionEnvelope