@opentrons/shared-data 0.1.2-alpha.0 → 0.1.2-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/js/__tests__/__snapshots__/pipettes.test.ts.snap +5969 -0
- package/js/__tests__/deckSchemas.test.ts +87 -0
- package/js/__tests__/errors.test.js +21 -0
- package/js/__tests__/getAreSlotsAdjacent.test.ts +128 -0
- package/js/__tests__/getWellNamePerMultiTip.test.ts +162 -0
- package/js/__tests__/labwareDefQuirks.test.ts +38 -0
- package/js/__tests__/labwareDefSchemaV1.test.ts +82 -0
- package/js/__tests__/labwareDefSchemaV2.test.ts +298 -0
- package/js/__tests__/moduleAccessors.test.ts +50 -0
- package/js/__tests__/moduleSpecsSchema.test.ts +77 -0
- package/js/__tests__/pipetteSchemaV2.test.ts +107 -0
- package/js/__tests__/pipetteSpecSchemas.test.ts +48 -0
- package/js/__tests__/pipettes.test.ts +58 -0
- package/js/__tests__/protocolSchemaV4.test.ts +137 -0
- package/js/__tests__/protocolSchemaV5.test.ts +137 -0
- package/js/__tests__/protocolSchemaV6.test.ts +132 -0
- package/js/__tests__/protocolSchemaV7.test.ts +64 -0
- package/js/__tests__/protocolValidation.test.ts +83 -0
- package/js/__tests__/sortWells.test.ts +40 -0
- package/js/__tests__/splitWellsOnColumn.test.ts +21 -0
- package/js/__tests__/validateErrors.test.js +34 -0
- package/js/constants.ts +405 -0
- package/js/cypressUtils.ts +35 -0
- package/js/errors.ts +33 -0
- package/js/fixtures.ts +156 -0
- package/js/getLabware.ts +145 -0
- package/js/gripper.ts +29 -0
- package/js/helpers/__tests__/getAdapterName.test.ts +31 -0
- package/js/helpers/__tests__/getDeckDefFromLoadedLabware.test.ts +12 -0
- package/js/helpers/__tests__/getSimplestFlexDeckConfig.test.ts +176 -0
- package/js/helpers/__tests__/getVectorDifference.test.ts +25 -0
- package/js/helpers/__tests__/getVectorSum.test.ts +21 -0
- package/js/helpers/__tests__/labwareInference.test.ts +84 -0
- package/js/helpers/__tests__/orderWells.test.ts +87 -0
- package/js/helpers/__tests__/parseProtocolData.test.ts +165 -0
- package/js/helpers/__tests__/volume.test.ts +108 -0
- package/js/helpers/__tests__/wellSets.test.ts +352 -0
- package/js/helpers/get96Channel384WellPlateWells.ts +44 -0
- package/js/helpers/getAddressableAreasInProtocol.ts +98 -0
- package/js/helpers/getLoadedLabwareDefinitionsByUri.ts +30 -0
- package/js/helpers/getModuleVizDims.ts +118 -0
- package/js/helpers/getOccludedSlotCountForModule.ts +13 -0
- package/js/helpers/getSimplestFlexDeckConfig.ts +183 -0
- package/js/helpers/getVectorDifference.ts +12 -0
- package/js/helpers/getVectorSum.ts +12 -0
- package/js/helpers/getWellNamePerMultiTip.ts +86 -0
- package/js/helpers/getWellTotalVolume.ts +16 -0
- package/js/helpers/index.ts +348 -0
- package/js/helpers/labwareInference.ts +92 -0
- package/js/helpers/orderWells.ts +69 -0
- package/js/helpers/parseProtocolData.ts +141 -0
- package/js/helpers/volume.ts +35 -0
- package/js/helpers/wellIsRect.ts +6 -0
- package/js/helpers/wellSets.ts +155 -0
- package/js/index.ts +14 -0
- package/js/labwareTools/__tests__/__snapshots__/createIrregularLabware.test.ts.snap +3 -0
- package/js/labwareTools/__tests__/__snapshots__/createLabware.test.ts.snap +3 -0
- package/js/labwareTools/__tests__/createDefaultDisplayName.test.ts +111 -0
- package/js/labwareTools/__tests__/createIrregularLabware.test.ts +226 -0
- package/js/labwareTools/__tests__/createLabware.test.ts +147 -0
- package/js/labwareTools/index.ts +452 -0
- package/js/modules.ts +97 -0
- package/js/pipettes.ts +89 -0
- package/js/protocols.ts +290 -0
- package/js/schema.ts +80 -0
- package/js/scripts/generateDeckLayersFromSVG.js +46 -0
- package/js/titleCase.ts +30 -0
- package/js/types.ts +561 -0
- package/lib/js/__tests__/deckSchemas.test.d.ts +1 -0
- package/lib/js/__tests__/getAreSlotsAdjacent.test.d.ts +1 -0
- package/lib/js/__tests__/getWellNamePerMultiTip.test.d.ts +1 -0
- package/lib/js/__tests__/labwareDefQuirks.test.d.ts +1 -0
- package/lib/js/__tests__/labwareDefSchemaV1.test.d.ts +1 -0
- package/lib/js/__tests__/labwareDefSchemaV2.test.d.ts +1 -0
- package/lib/js/__tests__/moduleAccessors.test.d.ts +1 -0
- package/lib/js/__tests__/moduleSpecsSchema.test.d.ts +1 -0
- package/lib/js/__tests__/pipetteSchemaV2.test.d.ts +1 -0
- package/lib/js/__tests__/pipetteSpecSchemas.test.d.ts +1 -0
- package/lib/js/__tests__/pipettes.test.d.ts +1 -0
- package/lib/js/__tests__/protocolSchemaV4.test.d.ts +1 -0
- package/lib/js/__tests__/protocolSchemaV5.test.d.ts +1 -0
- package/lib/js/__tests__/protocolSchemaV6.test.d.ts +1 -0
- package/lib/js/__tests__/protocolSchemaV7.test.d.ts +1 -0
- package/lib/js/__tests__/protocolValidation.test.d.ts +1 -0
- package/lib/js/__tests__/sortWells.test.d.ts +1 -0
- package/lib/js/__tests__/splitWellsOnColumn.test.d.ts +1 -0
- package/lib/js/constants.d.ts +156 -0
- package/lib/js/cypressUtils.d.ts +1 -0
- package/lib/js/errors.d.ts +13 -0
- package/lib/js/fixtures.d.ts +13 -0
- package/lib/js/getLabware.d.ts +8 -0
- package/lib/js/gripper.d.ts +3 -0
- package/lib/js/helpers/__tests__/getAdapterName.test.d.ts +1 -0
- package/lib/js/helpers/__tests__/getDeckDefFromLoadedLabware.test.d.ts +1 -0
- package/lib/js/helpers/__tests__/getSimplestFlexDeckConfig.test.d.ts +1 -0
- package/lib/js/helpers/__tests__/getVectorDifference.test.d.ts +1 -0
- package/lib/js/helpers/__tests__/getVectorSum.test.d.ts +1 -0
- package/lib/js/helpers/__tests__/labwareInference.test.d.ts +1 -0
- package/lib/js/helpers/__tests__/orderWells.test.d.ts +1 -0
- package/lib/js/helpers/__tests__/parseProtocolData.test.d.ts +1 -0
- package/lib/js/helpers/__tests__/volume.test.d.ts +1 -0
- package/lib/js/helpers/__tests__/wellSets.test.d.ts +1 -0
- package/lib/js/helpers/get96Channel384WellPlateWells.d.ts +1 -0
- package/lib/js/helpers/getAddressableAreasInProtocol.d.ts +4 -0
- package/lib/js/helpers/getLoadedLabwareDefinitionsByUri.d.ts +5 -0
- package/lib/js/helpers/getModuleVizDims.d.ts +16 -0
- package/lib/js/helpers/getOccludedSlotCountForModule.d.ts +2 -0
- package/lib/js/helpers/getSimplestFlexDeckConfig.d.ts +14 -0
- package/lib/js/helpers/getVectorDifference.d.ts +2 -0
- package/lib/js/helpers/getVectorSum.d.ts +2 -0
- package/lib/js/helpers/getWellNamePerMultiTip.d.ts +3 -0
- package/lib/js/helpers/getWellTotalVolume.d.ts +2 -0
- package/lib/js/helpers/index.d.ts +44 -0
- package/lib/js/helpers/labwareInference.d.ts +16 -0
- package/lib/js/helpers/orderWells.d.ts +2 -0
- package/lib/js/helpers/parseProtocolData.d.ts +23 -0
- package/lib/js/helpers/volume.d.ts +4 -0
- package/lib/js/helpers/wellIsRect.d.ts +3 -0
- package/lib/js/helpers/wellSets.d.ts +9 -0
- package/lib/js/index.d.ts +14 -0
- package/lib/js/labwareTools/__tests__/createDefaultDisplayName.test.d.ts +1 -0
- package/lib/js/labwareTools/__tests__/createIrregularLabware.test.d.ts +1 -0
- package/lib/js/labwareTools/__tests__/createLabware.test.d.ts +1 -0
- package/lib/js/labwareTools/index.d.ts +65 -0
- package/lib/js/modules.d.ts +6 -0
- package/lib/js/pipettes.d.ts +13 -0
- package/lib/js/protocols.d.ts +3 -0
- package/lib/js/schema.d.ts +90 -0
- package/lib/js/titleCase.d.ts +1 -0
- package/lib/js/types.d.ts +398 -0
- package/package.json +1 -1
package/js/protocols.ts
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
// Helper functions for validating protocols. Used only in tests right now but
|
|
2
|
+
// intended for use as the thing that turns something from a json document into
|
|
3
|
+
// a protocol inside the js ecosystem.
|
|
4
|
+
|
|
5
|
+
import Ajv from 'ajv'
|
|
6
|
+
|
|
7
|
+
import commandSchema8 from '../command/schemas/8.json'
|
|
8
|
+
import commandSchema7 from '../command/schemas/7.json'
|
|
9
|
+
import commandAnnotationSchema1 from '../commandAnnotation/schemas/1.json'
|
|
10
|
+
import liquidSchema1 from '../liquid/schemas/1.json'
|
|
11
|
+
import labwareSchema2 from '../labware/schemas/2.json'
|
|
12
|
+
|
|
13
|
+
import protocolSchema8 from '../protocol/schemas/8.json'
|
|
14
|
+
import protocolSchema7 from '../protocol/schemas/7.json'
|
|
15
|
+
import protocolSchema6 from '../protocol/schemas/6.json'
|
|
16
|
+
import protocolSchema5 from '../protocol/schemas/5.json'
|
|
17
|
+
import protocolSchema4 from '../protocol/schemas/4.json'
|
|
18
|
+
import protocolSchema3 from '../protocol/schemas/3.json'
|
|
19
|
+
import protocolSchema1 from '../protocol/schemas/1.json'
|
|
20
|
+
|
|
21
|
+
import type * as ProtocolSchemas from '../protocol'
|
|
22
|
+
import type { CreateCommand } from '../command/types'
|
|
23
|
+
import type { CommandAnnotation } from '../commandAnnotation/types'
|
|
24
|
+
|
|
25
|
+
export type { ProtocolSchemas }
|
|
26
|
+
|
|
27
|
+
const validateCommands8 = (
|
|
28
|
+
toValidate: ProtocolSchemas.ProtocolStructureV8
|
|
29
|
+
): Promise<CreateCommand[]> =>
|
|
30
|
+
new Promise((resolve, reject) => {
|
|
31
|
+
const requestedSchema = toValidate.commandSchemaId
|
|
32
|
+
switch (requestedSchema) {
|
|
33
|
+
case 'opentronsCommandSchemaV8':
|
|
34
|
+
resolve(commandSchema8)
|
|
35
|
+
break
|
|
36
|
+
default:
|
|
37
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
38
|
+
reject([
|
|
39
|
+
{
|
|
40
|
+
keyword: 'Invalid command schema requested',
|
|
41
|
+
dataPath: requestedSchema,
|
|
42
|
+
schemaPath: '#/properties/commandSchemaId',
|
|
43
|
+
params: { allowedValues: ['opentronsCommandSchemaV8'] },
|
|
44
|
+
},
|
|
45
|
+
])
|
|
46
|
+
break
|
|
47
|
+
}
|
|
48
|
+
}).then(
|
|
49
|
+
schema =>
|
|
50
|
+
new Promise((resolve, reject) => {
|
|
51
|
+
const generatedSchema = { type: 'array', items: schema }
|
|
52
|
+
const commandAjv = new Ajv({ allErrors: true, jsonPointers: true })
|
|
53
|
+
const validateCommands = commandAjv.compile(generatedSchema)
|
|
54
|
+
const ok = validateCommands(toValidate.commands)
|
|
55
|
+
if (!ok) {
|
|
56
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
57
|
+
reject(validateCommands.errors)
|
|
58
|
+
}
|
|
59
|
+
resolve(toValidate.commands)
|
|
60
|
+
})
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
const validateCommandAnnotations8 = (
|
|
64
|
+
toValidate: ProtocolSchemas.ProtocolStructureV8
|
|
65
|
+
): Promise<CommandAnnotation[]> =>
|
|
66
|
+
new Promise((resolve, reject) => {
|
|
67
|
+
const requestedSchema = toValidate.commandAnnotationSchemaId
|
|
68
|
+
switch (requestedSchema) {
|
|
69
|
+
case 'opentronsCommandAnnotationSchemaV1':
|
|
70
|
+
resolve(commandAnnotationSchema1)
|
|
71
|
+
break
|
|
72
|
+
default:
|
|
73
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
74
|
+
reject([
|
|
75
|
+
{
|
|
76
|
+
keyword: 'Invalid command annotation schema requested',
|
|
77
|
+
dataPath: requestedSchema,
|
|
78
|
+
schemaPath: '#/properties/commandAnnotationSchemaId',
|
|
79
|
+
params: { allowedValues: ['opentronsCommandAnnotationSchemaV1'] },
|
|
80
|
+
},
|
|
81
|
+
])
|
|
82
|
+
}
|
|
83
|
+
}).then(
|
|
84
|
+
(schema: any) =>
|
|
85
|
+
new Promise((resolve, reject) => {
|
|
86
|
+
const generatedSchema = {
|
|
87
|
+
type: 'array',
|
|
88
|
+
items: { $ref: 'opentronsCommandAnnotationSchemaV1' },
|
|
89
|
+
}
|
|
90
|
+
const annotationAjv = new Ajv({ allErrors: true, jsonPointers: true })
|
|
91
|
+
annotationAjv.addSchema(schema)
|
|
92
|
+
const validateAnnotations = annotationAjv.compile(generatedSchema)
|
|
93
|
+
const ok = validateAnnotations(toValidate.commandAnnotations)
|
|
94
|
+
if (!ok) {
|
|
95
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
96
|
+
reject(validateAnnotations.errors)
|
|
97
|
+
}
|
|
98
|
+
resolve(toValidate.commandAnnotations)
|
|
99
|
+
})
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
const validateLiquids8 = (
|
|
103
|
+
toValidate: ProtocolSchemas.ProtocolStructureV8
|
|
104
|
+
): Promise<ProtocolSchemas.ProtocolFileV8['liquids']> =>
|
|
105
|
+
new Promise((resolve, reject) => {
|
|
106
|
+
const requestedSchema = toValidate.liquidSchemaId
|
|
107
|
+
switch (requestedSchema) {
|
|
108
|
+
case 'opentronsLiquidSchemaV1':
|
|
109
|
+
resolve(liquidSchema1)
|
|
110
|
+
break
|
|
111
|
+
default:
|
|
112
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
113
|
+
reject([
|
|
114
|
+
{
|
|
115
|
+
keyword: 'Invalid liquid schema requested',
|
|
116
|
+
dataPath: requestedSchema,
|
|
117
|
+
schemaPath: '#/properties/liquidSchemaId',
|
|
118
|
+
params: { allowedValues: ['opentronsLiquidSchemaV1'] },
|
|
119
|
+
},
|
|
120
|
+
])
|
|
121
|
+
}
|
|
122
|
+
}).then(
|
|
123
|
+
schema =>
|
|
124
|
+
new Promise((resolve, reject) => {
|
|
125
|
+
const generatedSchema = {
|
|
126
|
+
type: 'object',
|
|
127
|
+
patternProperties: { '.+': schema },
|
|
128
|
+
}
|
|
129
|
+
const liquidAjv = new Ajv({ allErrors: true, jsonPointers: true })
|
|
130
|
+
const validateLiquids = liquidAjv.compile(generatedSchema)
|
|
131
|
+
const ok = validateLiquids(toValidate.liquids)
|
|
132
|
+
if (!ok) {
|
|
133
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
134
|
+
reject(validateLiquids.errors)
|
|
135
|
+
}
|
|
136
|
+
resolve(toValidate.liquids)
|
|
137
|
+
})
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
const validateLabware8 = (
|
|
141
|
+
toValidate: ProtocolSchemas.ProtocolStructureV8
|
|
142
|
+
): Promise<ProtocolSchemas.ProtocolFileV8['labwareDefinitions']> =>
|
|
143
|
+
new Promise((resolve, reject) => {
|
|
144
|
+
const requestedSchema = toValidate.labwareDefinitionSchemaId
|
|
145
|
+
switch (requestedSchema) {
|
|
146
|
+
case 'opentronsLabwareSchemaV2':
|
|
147
|
+
resolve(labwareSchema2)
|
|
148
|
+
break
|
|
149
|
+
default:
|
|
150
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
151
|
+
reject([
|
|
152
|
+
{
|
|
153
|
+
keyword: 'Invalid labware schema requested',
|
|
154
|
+
dataPath: requestedSchema,
|
|
155
|
+
schemaPath: '#/properties/labwareSchemaId',
|
|
156
|
+
params: { allowedValues: ['opentronsLabwareSchemaV2'] },
|
|
157
|
+
},
|
|
158
|
+
])
|
|
159
|
+
}
|
|
160
|
+
}).then(
|
|
161
|
+
schema =>
|
|
162
|
+
new Promise((resolve, reject) => {
|
|
163
|
+
const generatedSchema = {
|
|
164
|
+
type: 'object',
|
|
165
|
+
patternProperties: { '.+': schema },
|
|
166
|
+
}
|
|
167
|
+
const labwareAjv = new Ajv({ allErrors: true, jsonPointers: true })
|
|
168
|
+
const validateLabware = labwareAjv.compile(generatedSchema)
|
|
169
|
+
const ok = validateLabware(toValidate.labwareDefinitions)
|
|
170
|
+
if (!ok) {
|
|
171
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
172
|
+
reject(validateLabware.errors)
|
|
173
|
+
}
|
|
174
|
+
resolve(toValidate.labwareDefinitions)
|
|
175
|
+
})
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
const validate8 = (toValidate: any): Promise<ProtocolSchemas.ProtocolFileV8> =>
|
|
179
|
+
new Promise<ProtocolSchemas.ProtocolStructureV8>((resolve, reject) => {
|
|
180
|
+
const protoAjv = new Ajv({ allErrors: true, jsonPointers: true })
|
|
181
|
+
const validateProtocol = protoAjv.compile(protocolSchema8)
|
|
182
|
+
const valid = validateProtocol(toValidate)
|
|
183
|
+
if (!valid) {
|
|
184
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
185
|
+
reject(validateProtocol.errors)
|
|
186
|
+
}
|
|
187
|
+
const validatedProtocol = toValidate as ProtocolSchemas.ProtocolStructureV8
|
|
188
|
+
resolve(validatedProtocol)
|
|
189
|
+
})
|
|
190
|
+
.then(protocol =>
|
|
191
|
+
Promise.all([
|
|
192
|
+
validateCommands8(protocol),
|
|
193
|
+
validateCommandAnnotations8(protocol),
|
|
194
|
+
validateLiquids8(protocol),
|
|
195
|
+
validateLabware8(protocol),
|
|
196
|
+
])
|
|
197
|
+
)
|
|
198
|
+
.then(() => Promise.resolve(toValidate as ProtocolSchemas.ProtocolFileV8))
|
|
199
|
+
|
|
200
|
+
const fakeAjvErrorForBadOTSharedSchema = (
|
|
201
|
+
requestedValue: any
|
|
202
|
+
): Ajv.ErrorObject => ({
|
|
203
|
+
keyword: 'Invalid protocol schema requested',
|
|
204
|
+
dataPath: requestedValue,
|
|
205
|
+
schemaPath: '#/properties/$otSharedSchema',
|
|
206
|
+
params: {
|
|
207
|
+
allowedValues: [
|
|
208
|
+
'#/protocol/schemas/8',
|
|
209
|
+
'#/protocol/schemas/7',
|
|
210
|
+
'#/protocol/schemas/6',
|
|
211
|
+
'#/protocol/schemas/5',
|
|
212
|
+
'#/protocol/schemas/4',
|
|
213
|
+
'#/protocol/schemas/3',
|
|
214
|
+
'#/protocol/schemas/2',
|
|
215
|
+
'#/protocol/schemas/1',
|
|
216
|
+
],
|
|
217
|
+
},
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
type ProtocolFileSub7 =
|
|
221
|
+
| ProtocolSchemas.ProtocolFileV6
|
|
222
|
+
| ProtocolSchemas.ProtocolFileV5<{}>
|
|
223
|
+
| ProtocolSchemas.ProtocolFileV4<{}>
|
|
224
|
+
| ProtocolSchemas.ProtocolFileV3<{}>
|
|
225
|
+
| ProtocolSchemas.ProtocolFileV1<{}>
|
|
226
|
+
|
|
227
|
+
const validateSub7 = (
|
|
228
|
+
toValidate: any,
|
|
229
|
+
schemaObj: any
|
|
230
|
+
): Promise<ProtocolFileSub7> =>
|
|
231
|
+
new Promise((resolve, reject) => {
|
|
232
|
+
const ajv = new Ajv({ allErrors: true, jsonPointers: true })
|
|
233
|
+
ajv.addSchema(labwareSchema2)
|
|
234
|
+
const validateProtocol = ajv.compile(schemaObj)
|
|
235
|
+
const ok = validateProtocol(toValidate)
|
|
236
|
+
if (!ok) {
|
|
237
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
238
|
+
reject(validateProtocol.errors)
|
|
239
|
+
}
|
|
240
|
+
resolve(toValidate as ProtocolFileSub7)
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
const validate7 = (toValidate: any): Promise<ProtocolSchemas.ProtocolFileV7> =>
|
|
244
|
+
new Promise((resolve, reject) => {
|
|
245
|
+
const ajv = new Ajv({ allErrors: true, jsonPointers: true })
|
|
246
|
+
ajv.addSchema([commandSchema7, labwareSchema2])
|
|
247
|
+
const validateProtocol = ajv.compile(protocolSchema7)
|
|
248
|
+
const ok = validateProtocol(toValidate)
|
|
249
|
+
if (!ok) {
|
|
250
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
251
|
+
reject(validateProtocol.errors)
|
|
252
|
+
}
|
|
253
|
+
resolve(toValidate as ProtocolSchemas.ProtocolFileV7)
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
// note: rejects with an array of ajv errors
|
|
257
|
+
export function validate(
|
|
258
|
+
toValidate: any
|
|
259
|
+
): Promise<ProtocolSchemas.JsonProtocolFile> {
|
|
260
|
+
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
261
|
+
const requestedProtocolSchema = toValidate['$otSharedSchema']
|
|
262
|
+
switch (requestedProtocolSchema) {
|
|
263
|
+
case '#/protocol/schemas/8':
|
|
264
|
+
return validate8(toValidate)
|
|
265
|
+
case '#/protocol/schemas/7':
|
|
266
|
+
return validate7(toValidate)
|
|
267
|
+
case '#/protocol/schemas/6':
|
|
268
|
+
return validateSub7(toValidate, protocolSchema6)
|
|
269
|
+
case '#/protocol/schemas/5':
|
|
270
|
+
return validateSub7(toValidate, protocolSchema5)
|
|
271
|
+
case '#/protocol/schemas/4':
|
|
272
|
+
return validateSub7(toValidate, protocolSchema4)
|
|
273
|
+
default:
|
|
274
|
+
if (!Object.keys(toValidate).includes('$otSharedSchema')) {
|
|
275
|
+
const v3SchemaVersion = toValidate.schemaVersion
|
|
276
|
+
if (v3SchemaVersion === '3.0.0') {
|
|
277
|
+
return validateSub7(toValidate, protocolSchema3)
|
|
278
|
+
}
|
|
279
|
+
const v1SchemaVersion = toValidate['protocol-schema']
|
|
280
|
+
if (v1SchemaVersion === '1.0.0') {
|
|
281
|
+
return validateSub7(toValidate, protocolSchema1)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return new Promise((resolve, reject) => {
|
|
286
|
+
// eslint-disable-next-line prefer-promise-reject-errors
|
|
287
|
+
reject([fakeAjvErrorForBadOTSharedSchema(requestedProtocolSchema)])
|
|
288
|
+
})
|
|
289
|
+
}
|
|
290
|
+
}
|
package/js/schema.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const NumberType = {
|
|
2
|
+
type: 'number',
|
|
3
|
+
}
|
|
4
|
+
const PositiveNumber = {
|
|
5
|
+
type: 'number',
|
|
6
|
+
minimum: 0,
|
|
7
|
+
}
|
|
8
|
+
const LabwareFormats = ['96-standard', '384-standard', 'trough', 'irregular']
|
|
9
|
+
// TODO IMMEDIATELY move to labware/flowTypes/
|
|
10
|
+
// TODO(mc, 2020-02-21) move to labware/schemas/1.json? delete?
|
|
11
|
+
// this only appears to be used in a single test file
|
|
12
|
+
// shared-data/js/__tests__/labwareDefSchemaV1.test.js
|
|
13
|
+
export const labwareSchemaV1 = {
|
|
14
|
+
type: 'object',
|
|
15
|
+
required: ['metadata', 'ordering', 'wells'],
|
|
16
|
+
additionalProperties: false,
|
|
17
|
+
properties: {
|
|
18
|
+
metadata: {
|
|
19
|
+
type: 'object',
|
|
20
|
+
required: ['name', 'format'],
|
|
21
|
+
properties: {
|
|
22
|
+
name: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
},
|
|
25
|
+
format: {
|
|
26
|
+
enum: LabwareFormats,
|
|
27
|
+
},
|
|
28
|
+
deprecated: {
|
|
29
|
+
enum: [true],
|
|
30
|
+
},
|
|
31
|
+
displayName: {
|
|
32
|
+
type: 'string',
|
|
33
|
+
},
|
|
34
|
+
displayCategory: {
|
|
35
|
+
type: 'string',
|
|
36
|
+
},
|
|
37
|
+
isValidSource: {
|
|
38
|
+
enum: [false],
|
|
39
|
+
},
|
|
40
|
+
isTiprack: {
|
|
41
|
+
enum: [true],
|
|
42
|
+
},
|
|
43
|
+
tipVolume: PositiveNumber,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
ordering: {
|
|
47
|
+
type: 'array',
|
|
48
|
+
items: {
|
|
49
|
+
type: 'array',
|
|
50
|
+
items: {
|
|
51
|
+
type: 'string',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
wells: {
|
|
56
|
+
type: 'object',
|
|
57
|
+
patternProperties: {
|
|
58
|
+
'.*': {
|
|
59
|
+
// TODO: use ^[A-Z]+[1-9]+[0-9]*$ (eg A1, AB16, not A03) -- but make sure invalid well keys fail instead of slip past
|
|
60
|
+
type: 'object',
|
|
61
|
+
required: ['height', 'length', 'width', 'x', 'y', 'z'],
|
|
62
|
+
properties: {
|
|
63
|
+
height: NumberType,
|
|
64
|
+
length: PositiveNumber,
|
|
65
|
+
width: PositiveNumber,
|
|
66
|
+
x: NumberType,
|
|
67
|
+
y: NumberType,
|
|
68
|
+
z: NumberType,
|
|
69
|
+
// Optional
|
|
70
|
+
diameter: PositiveNumber,
|
|
71
|
+
// NOTE: presence of diameter indicates a circular well
|
|
72
|
+
depth: PositiveNumber,
|
|
73
|
+
// TODO Ian 2018-03-12: depth should be required, but is missing in MALDI-plate
|
|
74
|
+
'total-liquid-volume': PositiveNumber,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const assert = require('assert')
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
const path = require('path')
|
|
4
|
+
const camelCase = require('lodash/camelCase')
|
|
5
|
+
const JSDOM = require('jsdom').JSDOM
|
|
6
|
+
const { promisify } = require('util')
|
|
7
|
+
const readFile = promisify(fs.readFile)
|
|
8
|
+
const writeFile = promisify(fs.writeFile)
|
|
9
|
+
|
|
10
|
+
// NOTE: the expected source SVG is an output SVG from Adobe Illustrator
|
|
11
|
+
// when using `Save as` or `Save as a Copy` and not `Export`
|
|
12
|
+
// Furthermore, the .ai file should contain no groups and all layers
|
|
13
|
+
// will be directly translated to layer groups in the JSON output
|
|
14
|
+
|
|
15
|
+
const svgPath = process.argv[2]
|
|
16
|
+
const buildDir = process.argv[3]
|
|
17
|
+
|
|
18
|
+
const USAGE =
|
|
19
|
+
'Expected Params Not Present: (e.g. node ./scripts/generateDeckLayersFromSVG ./path/to/source/svg ./path/to/output/dir)'
|
|
20
|
+
assert(svgPath && buildDir, USAGE)
|
|
21
|
+
|
|
22
|
+
readFile(svgPath, 'utf8')
|
|
23
|
+
.then(data => {
|
|
24
|
+
const doc = new JSDOM(data, 'text/xml')
|
|
25
|
+
const groups = Array.from(doc.window.document.querySelectorAll('g'))
|
|
26
|
+
|
|
27
|
+
let layers = {}
|
|
28
|
+
groups.forEach(g => {
|
|
29
|
+
const groupId = g.getAttribute('id')
|
|
30
|
+
if (groupId && g.hasChildNodes()) {
|
|
31
|
+
const features = Array.from(g.querySelectorAll('path'))
|
|
32
|
+
const paths = features.map(f => ({
|
|
33
|
+
footprint: f.getAttribute('d').replace(/\s| {2}|\r\n|\n|\r/gm, ''), // clean up whitespaces and newlines
|
|
34
|
+
}))
|
|
35
|
+
layers = { ...layers, [camelCase(groupId)]: paths }
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const jsonOutput = JSON.stringify(layers)
|
|
40
|
+
return writeFile(path.join(buildDir, 'deckLayers.json'), jsonOutput)
|
|
41
|
+
})
|
|
42
|
+
.then(() => process.exit(0))
|
|
43
|
+
.catch(error => {
|
|
44
|
+
console.error(error)
|
|
45
|
+
process.exit(1)
|
|
46
|
+
})
|
package/js/titleCase.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const SMALL_WORDS = /\b(?:an?d?|a[st]|because|but|by|en|for|i[fn]|neither|nor|o[fnr]|only|over|per|μL|so|some|tha[tn]|the|to|up|upon|vs?\.?|versus|via|when|with|without|yet)\b/i
|
|
2
|
+
const TOKENS = /[^\s:–—-]+|./g
|
|
3
|
+
const WHITESPACE = /\s/
|
|
4
|
+
const IS_MANUAL_CASE = /.(?=[A-Z]|\..)/
|
|
5
|
+
const ALPHANUMERIC_PATTERN = /[A-Za-z0-9\u00C0-\u00FF]/
|
|
6
|
+
|
|
7
|
+
export function titleCase(input: string): string {
|
|
8
|
+
let result = ''
|
|
9
|
+
let m: RegExpExecArray | null
|
|
10
|
+
|
|
11
|
+
while ((m = TOKENS.exec(input)) !== null) {
|
|
12
|
+
const { 0: token, index } = m
|
|
13
|
+
|
|
14
|
+
if (
|
|
15
|
+
!IS_MANUAL_CASE.test(token) &&
|
|
16
|
+
(!SMALL_WORDS.test(token) ||
|
|
17
|
+
index === 0 ||
|
|
18
|
+
index + token.length === input.length) &&
|
|
19
|
+
(input.charAt(index + token.length) !== ':' ||
|
|
20
|
+
WHITESPACE.test(input.charAt(index + token.length + 1)))
|
|
21
|
+
) {
|
|
22
|
+
result += token.replace(ALPHANUMERIC_PATTERN, m => m.toUpperCase())
|
|
23
|
+
continue
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
result += token
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return result
|
|
30
|
+
}
|