@vessel-dsp/core 0.5.0 → 0.6.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.
- package/README.md +10 -0
- package/dist/editor/commands.d.ts +48 -0
- package/dist/editor/commands.d.ts.map +1 -0
- package/{src/editor/commands.ts → dist/editor/commands.js} +44 -91
- package/dist/editor/commands.js.map +1 -0
- package/dist/editor/factory.d.ts +10 -0
- package/dist/editor/factory.d.ts.map +1 -0
- package/{src/editor/factory.ts → dist/editor/factory.js} +11 -27
- package/dist/editor/factory.js.map +1 -0
- package/dist/editor/history.d.ts +29 -0
- package/dist/editor/history.d.ts.map +1 -0
- package/{src/editor/history.ts → dist/editor/history.js} +12 -42
- package/dist/editor/history.js.map +1 -0
- package/{src/editor/index.ts → dist/editor/index.d.ts} +1 -3
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/editor/index.js +5 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/editor/layout.d.ts +8 -0
- package/dist/editor/layout.d.ts.map +1 -0
- package/{src/editor/layout.ts → dist/editor/layout.js} +36 -90
- package/dist/editor/layout.js.map +1 -0
- package/dist/formats/circuit-json/serializer.d.ts +86 -0
- package/dist/formats/circuit-json/serializer.d.ts.map +1 -0
- package/{src/formats/circuit-json/serializer.ts → dist/formats/circuit-json/serializer.js} +114 -414
- package/dist/formats/circuit-json/serializer.js.map +1 -0
- package/dist/formats/document.d.ts +64 -0
- package/dist/formats/document.d.ts.map +1 -0
- package/dist/formats/document.js +300 -0
- package/dist/formats/document.js.map +1 -0
- package/dist/formats/interchange/parser.d.ts +3 -0
- package/dist/formats/interchange/parser.d.ts.map +1 -0
- package/{src/formats/interchange/parser.ts → dist/formats/interchange/parser.js} +651 -299
- package/dist/formats/interchange/parser.js.map +1 -0
- package/dist/formats/interchange/serializer.d.ts +9 -0
- package/dist/formats/interchange/serializer.d.ts.map +1 -0
- package/{src/formats/interchange/serializer.ts → dist/formats/interchange/serializer.js} +151 -158
- package/dist/formats/interchange/serializer.js.map +1 -0
- package/dist/formats/ltspice/catalog.d.ts +19 -0
- package/dist/formats/ltspice/catalog.d.ts.map +1 -0
- package/{src/formats/ltspice/catalog.ts → dist/formats/ltspice/catalog.js} +18 -52
- package/dist/formats/ltspice/catalog.js.map +1 -0
- package/dist/formats/ltspice/encoding.d.ts +2 -0
- package/dist/formats/ltspice/encoding.d.ts.map +1 -0
- package/{src/formats/ltspice/encoding.ts → dist/formats/ltspice/encoding.js} +17 -41
- package/dist/formats/ltspice/encoding.js.map +1 -0
- package/dist/formats/ltspice/parser.d.ts +3 -0
- package/dist/formats/ltspice/parser.d.ts.map +1 -0
- package/{src/formats/ltspice/parser.ts → dist/formats/ltspice/parser.js} +39 -141
- package/dist/formats/ltspice/parser.js.map +1 -0
- package/dist/formats/ltspice/serializer.d.ts +7 -0
- package/dist/formats/ltspice/serializer.d.ts.map +1 -0
- package/{src/formats/ltspice/serializer.ts → dist/formats/ltspice/serializer.js} +18 -45
- package/dist/formats/ltspice/serializer.js.map +1 -0
- package/dist/formats/schx/catalog.d.ts +19 -0
- package/dist/formats/schx/catalog.d.ts.map +1 -0
- package/{src/formats/schx/catalog.ts → dist/formats/schx/catalog.js} +48 -101
- package/dist/formats/schx/catalog.js.map +1 -0
- package/dist/formats/schx/parser.d.ts +3 -0
- package/dist/formats/schx/parser.d.ts.map +1 -0
- package/{src/formats/schx/parser.ts → dist/formats/schx/parser.js} +31 -86
- package/dist/formats/schx/parser.js.map +1 -0
- package/dist/formats/schx/runtime-descriptors.d.ts +3 -0
- package/dist/formats/schx/runtime-descriptors.d.ts.map +1 -0
- package/{src/formats/schx/runtime-descriptors.ts → dist/formats/schx/runtime-descriptors.js} +36 -123
- package/dist/formats/schx/runtime-descriptors.js.map +1 -0
- package/dist/formats/schx/serializer.d.ts +5 -0
- package/dist/formats/schx/serializer.d.ts.map +1 -0
- package/{src/formats/schx/serializer.ts → dist/formats/schx/serializer.js} +17 -42
- package/dist/formats/schx/serializer.js.map +1 -0
- package/dist/formats/schx/transforms.d.ts +4 -0
- package/dist/formats/schx/transforms.d.ts.map +1 -0
- package/{src/formats/schx/transforms.ts → dist/formats/schx/transforms.js} +6 -10
- package/dist/formats/schx/transforms.js.map +1 -0
- package/dist/formats/spice/parser.d.ts +3 -0
- package/dist/formats/spice/parser.d.ts.map +1 -0
- package/{src/formats/spice/parser.ts → dist/formats/spice/parser.js} +50 -96
- package/dist/formats/spice/parser.js.map +1 -0
- package/dist/formats/spice/serializer.d.ts +3 -0
- package/dist/formats/spice/serializer.d.ts.map +1 -0
- package/{src/formats/spice/serializer.ts → dist/formats/spice/serializer.js} +8 -13
- package/dist/formats/spice/serializer.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/model/connectivity.d.ts +16 -0
- package/dist/model/connectivity.d.ts.map +1 -0
- package/{src/model/connectivity.ts → dist/model/connectivity.js} +28 -63
- package/dist/model/connectivity.js.map +1 -0
- package/dist/model/netlist.d.ts +24 -0
- package/dist/model/netlist.d.ts.map +1 -0
- package/{src/model/netlist.ts → dist/model/netlist.js} +42 -110
- package/dist/model/netlist.js.map +1 -0
- package/dist/model/properties.d.ts +9 -0
- package/dist/model/properties.d.ts.map +1 -0
- package/{src/model/properties.ts → dist/model/properties.js} +10 -18
- package/dist/model/properties.js.map +1 -0
- package/dist/model/quantity.d.ts +3 -0
- package/dist/model/quantity.d.ts.map +1 -0
- package/{src/model/quantity.ts → dist/model/quantity.js} +7 -30
- package/dist/model/quantity.js.map +1 -0
- package/dist/model/types.d.ts +431 -0
- package/dist/model/types.d.ts.map +1 -0
- package/dist/model/types.js +10 -0
- package/dist/model/types.js.map +1 -0
- package/dist/model/validation.d.ts +32 -0
- package/dist/model/validation.d.ts.map +1 -0
- package/{src/model/validation.ts → dist/model/validation.js} +420 -323
- package/dist/model/validation.js.map +1 -0
- package/dist/model/wires.d.ts +3 -0
- package/dist/model/wires.d.ts.map +1 -0
- package/{src/model/wires.ts → dist/model/wires.js} +10 -16
- package/dist/model/wires.js.map +1 -0
- package/dist/panel/extract.d.ts +5 -0
- package/dist/panel/extract.d.ts.map +1 -0
- package/{src/panel/extract.ts → dist/panel/extract.js} +146 -235
- package/dist/panel/extract.js.map +1 -0
- package/dist/panel/index.d.ts +6 -0
- package/dist/panel/index.d.ts.map +1 -0
- package/dist/panel/index.js +5 -0
- package/dist/panel/index.js.map +1 -0
- package/dist/panel/knobs.d.ts +7 -0
- package/dist/panel/knobs.d.ts.map +1 -0
- package/{src/panel/knobs.ts → dist/panel/knobs.js} +7 -18
- package/dist/panel/knobs.js.map +1 -0
- package/dist/panel/protocol.d.ts +9 -0
- package/dist/panel/protocol.d.ts.map +1 -0
- package/{src/panel/protocol.ts → dist/panel/protocol.js} +10 -26
- package/dist/panel/protocol.js.map +1 -0
- package/{src/panel/types.ts → dist/panel/types.d.ts} +50 -89
- package/dist/panel/types.d.ts.map +1 -0
- package/dist/panel/types.js +2 -0
- package/dist/panel/types.js.map +1 -0
- package/dist/preview/bounds.d.ts +12 -0
- package/dist/preview/bounds.d.ts.map +1 -0
- package/{src/preview/bounds.ts → dist/preview/bounds.js} +15 -29
- package/dist/preview/bounds.js.map +1 -0
- package/dist/preview/box-layout.d.ts +4 -0
- package/dist/preview/box-layout.d.ts.map +1 -0
- package/{src/preview/box-layout.ts → dist/preview/box-layout.js} +2 -6
- package/dist/preview/box-layout.js.map +1 -0
- package/dist/preview/colors.d.ts +3 -0
- package/dist/preview/colors.d.ts.map +1 -0
- package/{src/preview/colors.ts → dist/preview/colors.js} +3 -5
- package/dist/preview/colors.js.map +1 -0
- package/dist/preview/hanging.d.ts +8 -0
- package/dist/preview/hanging.d.ts.map +1 -0
- package/{src/preview/hanging.ts → dist/preview/hanging.js} +9 -28
- package/dist/preview/hanging.js.map +1 -0
- package/dist/preview/junctions.d.ts +3 -0
- package/dist/preview/junctions.d.ts.map +1 -0
- package/{src/preview/junctions.ts → dist/preview/junctions.js} +9 -24
- package/dist/preview/junctions.js.map +1 -0
- package/dist/preview/label-layout.d.ts +12 -0
- package/dist/preview/label-layout.d.ts.map +1 -0
- package/{src/preview/label-layout.ts → dist/preview/label-layout.js} +15 -36
- package/dist/preview/label-layout.js.map +1 -0
- package/dist/preview/ports.d.ts +17 -0
- package/dist/preview/ports.d.ts.map +1 -0
- package/{src/preview/ports.ts → dist/preview/ports.js} +10 -37
- package/dist/preview/ports.js.map +1 -0
- package/dist/preview/renderable-wires.d.ts +3 -0
- package/dist/preview/renderable-wires.d.ts.map +1 -0
- package/{src/preview/renderable-wires.ts → dist/preview/renderable-wires.js} +12 -29
- package/dist/preview/renderable-wires.js.map +1 -0
- package/dist/preview/routing.d.ts +4 -0
- package/dist/preview/routing.d.ts.map +1 -0
- package/dist/preview/routing.js +13 -0
- package/dist/preview/routing.js.map +1 -0
- package/dist/preview/snap.d.ts +9 -0
- package/dist/preview/snap.d.ts.map +1 -0
- package/{src/preview/snap.ts → dist/preview/snap.js} +9 -31
- package/dist/preview/snap.js.map +1 -0
- package/dist/preview/symbols/svg-content.d.ts +7 -0
- package/dist/preview/symbols/svg-content.d.ts.map +1 -0
- package/{src/preview/symbols/svg-content.ts → dist/preview/symbols/svg-content.js} +3 -6
- package/dist/preview/symbols/svg-content.js.map +1 -0
- package/dist/preview/symbols.d.ts +7 -0
- package/dist/preview/symbols.d.ts.map +1 -0
- package/{src/preview/symbols.ts → dist/preview/symbols.js} +18 -43
- package/dist/preview/symbols.js.map +1 -0
- package/dist/preview/wire-chains.d.ts +4 -0
- package/dist/preview/wire-chains.d.ts.map +1 -0
- package/{src/preview/wire-chains.ts → dist/preview/wire-chains.js} +37 -37
- package/dist/preview/wire-chains.js.map +1 -0
- package/package.json +3 -3
- package/src/formats/document.ts +0 -274
- package/src/index.ts +0 -205
- package/src/model/types.ts +0 -309
- package/src/panel/index.ts +0 -39
- package/src/preview/routing.ts +0 -15
- package/src/preview/symbols/analog-switch.svg +0 -17
- package/src/preview/symbols/battery.svg +0 -16
- package/src/preview/symbols/bbd.svg +0 -21
- package/src/preview/symbols/bjt-npn.svg +0 -16
- package/src/preview/symbols/bjt-pnp.svg +0 -17
- package/src/preview/symbols/capacitor-electrolytic.svg +0 -13
- package/src/preview/symbols/capacitor.svg +0 -12
- package/src/preview/symbols/current-source.svg +0 -14
- package/src/preview/symbols/delay-ic.svg +0 -22
- package/src/preview/symbols/diode-schottky.svg +0 -12
- package/src/preview/symbols/diode-zener.svg +0 -12
- package/src/preview/symbols/diode.svg +0 -13
- package/src/preview/symbols/flipflop.svg +0 -20
- package/src/preview/symbols/ground.svg +0 -12
- package/src/preview/symbols/ic-block.svg +0 -20
- package/src/preview/symbols/ic.svg +0 -19
- package/src/preview/symbols/inductor.svg +0 -11
- package/src/preview/symbols/jack-input.svg +0 -16
- package/src/preview/symbols/jack-output.svg +0 -16
- package/src/preview/symbols/jfet-junction-n.svg +0 -17
- package/src/preview/symbols/jfet-n.svg +0 -17
- package/src/preview/symbols/jfet-p.svg +0 -17
- package/src/preview/symbols/label.svg +0 -8
- package/src/preview/symbols/led.svg +0 -18
- package/src/preview/symbols/mosfet-n.svg +0 -21
- package/src/preview/symbols/mosfet-p.svg +0 -21
- package/src/preview/symbols/named-wire.svg +0 -11
- package/src/preview/symbols/opamp.svg +0 -21
- package/src/preview/symbols/optocoupler.svg +0 -30
- package/src/preview/symbols/ota.svg +0 -20
- package/src/preview/symbols/pentode.svg +0 -25
- package/src/preview/symbols/photoresistor.svg +0 -19
- package/src/preview/symbols/port.svg +0 -8
- package/src/preview/symbols/potentiometer.svg +0 -15
- package/src/preview/symbols/power-amp.svg +0 -20
- package/src/preview/symbols/rail.svg +0 -11
- package/src/preview/symbols/regulator.svg +0 -13
- package/src/preview/symbols/relay.svg +0 -20
- package/src/preview/symbols/resistor.svg +0 -11
- package/src/preview/symbols/switch-3pdt.svg +0 -32
- package/src/preview/symbols/switch-rotary.svg +0 -23
- package/src/preview/symbols/switch-spdt.svg +0 -16
- package/src/preview/symbols/switch-spst.svg +0 -14
- package/src/preview/symbols/switch-toggle.svg +0 -14
- package/src/preview/symbols/transformer.svg +0 -17
- package/src/preview/symbols/triode.svg +0 -17
- package/src/preview/symbols/tube-diode.svg +0 -13
- package/src/preview/symbols/unsupported.svg +0 -8
- package/src/preview/symbols/variable-resistor.svg +0 -13
- package/src/preview/symbols/voltage-source.svg +0 -15
|
@@ -1,84 +1,53 @@
|
|
|
1
|
-
import { isParsedQuantity } from '../../model/properties';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
ControlInterface,
|
|
15
|
-
ControlInterfaceAssignmentHint,
|
|
16
|
-
ControlInterfaceConnector,
|
|
17
|
-
ControlInterfacePolarity,
|
|
18
|
-
ControlInterfaceRole,
|
|
19
|
-
ControlOutput,
|
|
20
|
-
ControlOutputSwitchMode,
|
|
21
|
-
DocumentSource,
|
|
22
|
-
PanelColumnOrder,
|
|
23
|
-
PanelControlKind,
|
|
24
|
-
PanelElementBinding,
|
|
25
|
-
PanelGridLayout,
|
|
26
|
-
PanelGridIndexing,
|
|
27
|
-
PanelGridPosition,
|
|
28
|
-
PanelPlacementMetadata,
|
|
29
|
-
PanelRowOrder,
|
|
30
|
-
ParsedQuantity,
|
|
31
|
-
Point,
|
|
32
|
-
PropertyValue,
|
|
33
|
-
Rotation,
|
|
34
|
-
Terminal,
|
|
35
|
-
Warning,
|
|
36
|
-
Wire,
|
|
37
|
-
} from '../../model/types';
|
|
38
|
-
|
|
39
|
-
type YamlScalar = string | number | boolean | null;
|
|
40
|
-
type YamlValue = YamlScalar | readonly YamlValue[] | YamlObject;
|
|
41
|
-
type YamlObject = { [key: string]: YamlValue };
|
|
42
|
-
|
|
43
|
-
type YamlLine = Readonly<{
|
|
44
|
-
indent: number;
|
|
45
|
-
text: string;
|
|
46
|
-
lineNumber: number;
|
|
47
|
-
}>;
|
|
48
|
-
|
|
49
|
-
type Cursor = {
|
|
50
|
-
index: number;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
type ParsedPair = Readonly<{
|
|
54
|
-
key: string;
|
|
55
|
-
rest: string;
|
|
56
|
-
}>;
|
|
57
|
-
|
|
58
|
-
const INTERCHANGE_SCHEMA = 'circuit-interchange/v2';
|
|
59
|
-
|
|
60
|
-
export function parseInterchangeYaml(source: string): CircuitDocument {
|
|
1
|
+
import { isParsedQuantity } from '../../model/properties.js';
|
|
2
|
+
const INTERCHANGE_SCHEMA_V2 = 'circuit-interchange/v2';
|
|
3
|
+
const INTERCHANGE_SCHEMA_V3 = 'circuit-interchange/v3';
|
|
4
|
+
const V3_ONLY_TOP_LEVEL_FIELDS = [
|
|
5
|
+
'mechanical',
|
|
6
|
+
'build',
|
|
7
|
+
'bom',
|
|
8
|
+
'partProfiles',
|
|
9
|
+
'footprints',
|
|
10
|
+
'offBoardWiring',
|
|
11
|
+
'boards',
|
|
12
|
+
];
|
|
13
|
+
export function parseInterchangeYaml(source) {
|
|
61
14
|
const value = parseYamlSubset(source);
|
|
62
15
|
const root = expectObject(value, 'root');
|
|
63
16
|
const schema = expectString(root.schema, 'schema');
|
|
64
|
-
if (schema !==
|
|
17
|
+
if (schema !== INTERCHANGE_SCHEMA_V2 && schema !== INTERCHANGE_SCHEMA_V3) {
|
|
65
18
|
throw new Error(`unsupported interchange schema: ${schema}`);
|
|
66
19
|
}
|
|
67
|
-
|
|
68
|
-
|
|
20
|
+
const isV3 = schema === INTERCHANGE_SCHEMA_V3;
|
|
21
|
+
if (!isV3) {
|
|
22
|
+
rejectV3OnlyTopLevelFields(root);
|
|
23
|
+
}
|
|
24
|
+
const panel = parsePanel(root.panel, isV3);
|
|
69
25
|
const controlInterfaces = parseControlInterfaces(root.controlInterfaces);
|
|
70
26
|
const device = parseDevice(root.device);
|
|
71
27
|
const controlOutputs = parseControlOutputs(root.controlOutputs);
|
|
72
28
|
const controlGroups = parseControlGroups(root.controlGroups);
|
|
73
29
|
const controlContexts = parseControlContexts(root.controlContexts);
|
|
74
30
|
const deviceInterface = parseDeviceInterface(root.deviceInterface);
|
|
75
|
-
|
|
31
|
+
const mechanical = isV3 ? parseMechanical(root.mechanical) : undefined;
|
|
32
|
+
const build = isV3 ? parseBuild(root.build) : undefined;
|
|
33
|
+
const bom = isV3 ? parseBom(root.bom) : undefined;
|
|
34
|
+
const partProfiles = isV3 ? parsePartProfiles(root.partProfiles) : undefined;
|
|
35
|
+
const footprints = isV3 ? parseFootprints(root.footprints) : undefined;
|
|
36
|
+
const offBoardWiring = isV3 ? parseOffBoardWiring(root.offBoardWiring) : undefined;
|
|
37
|
+
const boards = isV3 ? parseBoards(root.boards) : undefined;
|
|
76
38
|
return {
|
|
77
39
|
metadata: parseMetadata(root.metadata),
|
|
78
40
|
source: parseSource(root.source),
|
|
79
41
|
...(device === undefined ? {} : { device }),
|
|
80
42
|
...(controlGroups === undefined ? {} : { controlGroups }),
|
|
81
43
|
...(controlContexts === undefined ? {} : { controlContexts }),
|
|
44
|
+
...(mechanical === undefined ? {} : { mechanical }),
|
|
45
|
+
...(build === undefined ? {} : { build }),
|
|
46
|
+
...(bom === undefined ? {} : { bom }),
|
|
47
|
+
...(partProfiles === undefined ? {} : { partProfiles }),
|
|
48
|
+
...(footprints === undefined ? {} : { footprints }),
|
|
49
|
+
...(offBoardWiring === undefined ? {} : { offBoardWiring }),
|
|
50
|
+
...(boards === undefined ? {} : { boards }),
|
|
82
51
|
...(deviceInterface === undefined ? {} : { deviceInterface }),
|
|
83
52
|
...(panel === undefined ? {} : { panel }),
|
|
84
53
|
...(controlInterfaces === undefined ? {} : { controlInterfaces }),
|
|
@@ -90,8 +59,463 @@ export function parseInterchangeYaml(source: string): CircuitDocument {
|
|
|
90
59
|
rawAttributes: parseStringRecord(root.rawAttributes, 'rawAttributes'),
|
|
91
60
|
};
|
|
92
61
|
}
|
|
93
|
-
|
|
94
|
-
|
|
62
|
+
function rejectV3OnlyTopLevelFields(root) {
|
|
63
|
+
for (const field of V3_ONLY_TOP_LEVEL_FIELDS) {
|
|
64
|
+
if (root[field] !== undefined) {
|
|
65
|
+
throw new Error(`${field}: requires schema ${INTERCHANGE_SCHEMA_V3}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function parseMechanical(value) {
|
|
70
|
+
if (value === undefined) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
const mechanical = expectObject(value, 'mechanical');
|
|
74
|
+
return {
|
|
75
|
+
...parseBuildDataObject(mechanical, 'mechanical'),
|
|
76
|
+
...(mechanical.schema === undefined ? {} : { schema: expectString(mechanical.schema, 'mechanical.schema') }),
|
|
77
|
+
...(mechanical.units === undefined ? {} : { units: expectString(mechanical.units, 'mechanical.units') }),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function parseBuild(value) {
|
|
81
|
+
if (value === undefined) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
const build = expectObject(value, 'build');
|
|
85
|
+
return {
|
|
86
|
+
...parseBuildDataObject(build, 'build'),
|
|
87
|
+
schema: parseLiteralString(build.schema, 'build.schema', 'build-scope/v1'),
|
|
88
|
+
...(build.intent === undefined ? {} : { intent: parseBuildIntent(build.intent, 'build.intent') }),
|
|
89
|
+
...(build.completeness === undefined
|
|
90
|
+
? {}
|
|
91
|
+
: { completeness: parseBuildCompleteness(build.completeness, 'build.completeness') }),
|
|
92
|
+
...(build.selectedBoardId === undefined
|
|
93
|
+
? {}
|
|
94
|
+
: { selectedBoardId: expectString(build.selectedBoardId, 'build.selectedBoardId') }),
|
|
95
|
+
...(build.selectedOffBoardWiringHarnessIds === undefined
|
|
96
|
+
? {}
|
|
97
|
+
: {
|
|
98
|
+
selectedOffBoardWiringHarnessIds: parseOptionalStringArray(build.selectedOffBoardWiringHarnessIds, 'build.selectedOffBoardWiringHarnessIds') ?? [],
|
|
99
|
+
}),
|
|
100
|
+
...(build.alternateBoardIds === undefined
|
|
101
|
+
? {}
|
|
102
|
+
: { alternateBoardIds: parseOptionalStringArray(build.alternateBoardIds, 'build.alternateBoardIds') ?? [] }),
|
|
103
|
+
...(build.bomScope === undefined ? {} : { bomScope: expectString(build.bomScope, 'build.bomScope') }),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function parseBuildIntent(value, path) {
|
|
107
|
+
const intent = expectString(value, path);
|
|
108
|
+
if (intent === 'diy-build-artifact' || intent === 'schema-review-sample') {
|
|
109
|
+
return intent;
|
|
110
|
+
}
|
|
111
|
+
throw new Error(`${path}: expected diy-build-artifact or schema-review-sample`);
|
|
112
|
+
}
|
|
113
|
+
function parseBuildCompleteness(value, path) {
|
|
114
|
+
const completeness = expectString(value, path);
|
|
115
|
+
if (completeness === 'complete-selected-build' || completeness === 'partial-offboard-wiring') {
|
|
116
|
+
return completeness;
|
|
117
|
+
}
|
|
118
|
+
throw new Error(`${path}: expected complete-selected-build or partial-offboard-wiring`);
|
|
119
|
+
}
|
|
120
|
+
function parseBom(value) {
|
|
121
|
+
if (value === undefined) {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
const bom = expectObject(value, 'bom');
|
|
125
|
+
return {
|
|
126
|
+
...parseBuildDataObject(bom, 'bom'),
|
|
127
|
+
schema: parseLiteralString(bom.schema, 'bom.schema', 'build-bom/v1'),
|
|
128
|
+
items: optionalArray(bom.items, 'bom.items').map(parseBomItem),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function parseBomItem(value, index) {
|
|
132
|
+
const path = `bom.items[${index}]`;
|
|
133
|
+
const item = expectObject(value, path);
|
|
134
|
+
return {
|
|
135
|
+
...parseBuildDataObject(item, path),
|
|
136
|
+
id: expectString(item.id, `${path}.id`),
|
|
137
|
+
refs: optionalArray(item.refs, `${path}.refs`).map((ref, refIndex) => parseBomRef(ref, `${path}.refs[${refIndex}]`)),
|
|
138
|
+
quantity: expectNumber(item.quantity, `${path}.quantity`),
|
|
139
|
+
...(item.value === undefined ? {} : { value: expectString(item.value, `${path}.value`) }),
|
|
140
|
+
...(item.partProfileId === undefined
|
|
141
|
+
? {}
|
|
142
|
+
: { partProfileId: expectString(item.partProfileId, `${path}.partProfileId`) }),
|
|
143
|
+
...(item.category === undefined ? {} : { category: expectString(item.category, `${path}.category`) }),
|
|
144
|
+
...(item.sku === undefined ? {} : { sku: expectString(item.sku, `${path}.sku`) }),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function parseBomRef(value, path) {
|
|
148
|
+
const ref = expectObject(value, path);
|
|
149
|
+
const kind = expectString(ref.kind, `${path}.kind`);
|
|
150
|
+
switch (kind) {
|
|
151
|
+
case 'component':
|
|
152
|
+
case 'device-interface-control':
|
|
153
|
+
case 'panel-element':
|
|
154
|
+
case 'board':
|
|
155
|
+
case 'freeform-build-item':
|
|
156
|
+
return {
|
|
157
|
+
...parseBuildDataObject(ref, path),
|
|
158
|
+
kind,
|
|
159
|
+
...(ref.componentId === undefined ? {} : { componentId: expectString(ref.componentId, `${path}.componentId`) }),
|
|
160
|
+
...(ref.controlId === undefined ? {} : { controlId: expectString(ref.controlId, `${path}.controlId`) }),
|
|
161
|
+
...(ref.panelElementId === undefined
|
|
162
|
+
? {}
|
|
163
|
+
: { panelElementId: expectString(ref.panelElementId, `${path}.panelElementId`) }),
|
|
164
|
+
...(ref.boardId === undefined ? {} : { boardId: expectString(ref.boardId, `${path}.boardId`) }),
|
|
165
|
+
...(ref.label === undefined ? {} : { label: expectString(ref.label, `${path}.label`) }),
|
|
166
|
+
};
|
|
167
|
+
default:
|
|
168
|
+
throw new Error(`${path}.kind: expected component, device-interface-control, panel-element, board, or freeform-build-item`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function parsePartProfiles(value) {
|
|
172
|
+
if (value === undefined) {
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
const catalog = expectObject(value, 'partProfiles');
|
|
176
|
+
return {
|
|
177
|
+
...parseBuildDataObject(catalog, 'partProfiles'),
|
|
178
|
+
schema: parseLiteralString(catalog.schema, 'partProfiles.schema', 'part-profile-catalog/v1'),
|
|
179
|
+
...(catalog.resolution === undefined
|
|
180
|
+
? {}
|
|
181
|
+
: { resolution: expectString(catalog.resolution, 'partProfiles.resolution') }),
|
|
182
|
+
...(catalog.units === undefined ? {} : { units: expectString(catalog.units, 'partProfiles.units') }),
|
|
183
|
+
profiles: optionalArray(catalog.profiles, 'partProfiles.profiles').map((profile, index) => parsePartProfile(profile, index)),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function parsePartProfile(value, index) {
|
|
187
|
+
const path = `partProfiles.profiles[${index}]`;
|
|
188
|
+
const profile = expectObject(value, path);
|
|
189
|
+
return {
|
|
190
|
+
...parseBuildDataObject(profile, path),
|
|
191
|
+
id: expectString(profile.id, `${path}.id`),
|
|
192
|
+
...(profile.kind === undefined ? {} : { kind: expectString(profile.kind, `${path}.kind`) }),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function parseFootprints(value) {
|
|
196
|
+
if (value === undefined) {
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
const catalog = expectObject(value, 'footprints');
|
|
200
|
+
return {
|
|
201
|
+
...parseBuildDataObject(catalog, 'footprints'),
|
|
202
|
+
schema: parseLiteralString(catalog.schema, 'footprints.schema', 'board-footprint-catalog/v1'),
|
|
203
|
+
...(catalog.resolution === undefined ? {} : { resolution: expectString(catalog.resolution, 'footprints.resolution') }),
|
|
204
|
+
...(catalog.units === undefined ? {} : { units: expectString(catalog.units, 'footprints.units') }),
|
|
205
|
+
footprints: optionalArray(catalog.footprints, 'footprints.footprints').map((footprint, index) => parseFootprint(footprint, index)),
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function parseFootprint(value, index) {
|
|
209
|
+
const path = `footprints.footprints[${index}]`;
|
|
210
|
+
const footprint = expectObject(value, path);
|
|
211
|
+
return {
|
|
212
|
+
...parseBuildDataObject(footprint, path),
|
|
213
|
+
id: expectString(footprint.id, `${path}.id`),
|
|
214
|
+
...(footprint.boardApplicability === undefined
|
|
215
|
+
? {}
|
|
216
|
+
: { boardApplicability: parseBoardApplicability(footprint.boardApplicability, `${path}.boardApplicability`) }),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
function parseBoardApplicability(value, path) {
|
|
220
|
+
const applicability = expectObject(value, path);
|
|
221
|
+
return {
|
|
222
|
+
...parseBuildDataObject(applicability, path),
|
|
223
|
+
family: parseBoardFamily(applicability.family, `${path}.family`),
|
|
224
|
+
kind: parseBoardKind(applicability.kind, `${path}.kind`),
|
|
225
|
+
...(applicability.subtype === undefined
|
|
226
|
+
? {}
|
|
227
|
+
: { subtype: parseBoardSubtype(applicability.subtype, `${path}.subtype`) }),
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
function parseOffBoardWiring(value) {
|
|
231
|
+
if (value === undefined) {
|
|
232
|
+
return undefined;
|
|
233
|
+
}
|
|
234
|
+
const plan = expectObject(value, 'offBoardWiring');
|
|
235
|
+
return {
|
|
236
|
+
...parseBuildDataObject(plan, 'offBoardWiring'),
|
|
237
|
+
schema: parseLiteralString(plan.schema, 'offBoardWiring.schema', 'offboard-wiring/v1'),
|
|
238
|
+
...(plan.source === undefined ? {} : { source: expectString(plan.source, 'offBoardWiring.source') }),
|
|
239
|
+
...(plan.coverage === undefined
|
|
240
|
+
? {}
|
|
241
|
+
: { coverage: parseOffBoardWiringCoverage(plan.coverage, 'offBoardWiring.coverage') }),
|
|
242
|
+
harnesses: optionalArray(plan.harnesses, 'offBoardWiring.harnesses').map(parseOffBoardWiringHarness),
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function parseOffBoardWiringCoverage(value, path) {
|
|
246
|
+
const coverage = expectString(value, path);
|
|
247
|
+
if (coverage === 'selected-build-complete' || coverage === 'representative-selected-build-endpoints') {
|
|
248
|
+
return coverage;
|
|
249
|
+
}
|
|
250
|
+
throw new Error(`${path}: expected selected-build-complete or representative-selected-build-endpoints`);
|
|
251
|
+
}
|
|
252
|
+
function parseOffBoardWiringHarness(value, index) {
|
|
253
|
+
const path = `offBoardWiring.harnesses[${index}]`;
|
|
254
|
+
const harness = expectObject(value, path);
|
|
255
|
+
return {
|
|
256
|
+
...parseBuildDataObject(harness, path),
|
|
257
|
+
id: expectString(harness.id, `${path}.id`),
|
|
258
|
+
...(harness.status === undefined
|
|
259
|
+
? {}
|
|
260
|
+
: { status: parseOffBoardWiringHarnessStatus(harness.status, `${path}.status`) }),
|
|
261
|
+
...(harness.notes === undefined ? {} : { notes: expectString(harness.notes, `${path}.notes`) }),
|
|
262
|
+
endpoints: optionalArray(harness.endpoints, `${path}.endpoints`).map((endpoint, endpointIndex) => parseOffBoardWiringEndpoint(endpoint, `${path}.endpoints[${endpointIndex}]`)),
|
|
263
|
+
connections: optionalArray(harness.connections, `${path}.connections`).map((connection, connectionIndex) => parseOffBoardWiringConnection(connection, `${path}.connections[${connectionIndex}]`)),
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function parseOffBoardWiringHarnessStatus(value, path) {
|
|
267
|
+
const status = expectString(value, path);
|
|
268
|
+
if (status === 'complete' || status === 'partial' || status === 'candidate') {
|
|
269
|
+
return status;
|
|
270
|
+
}
|
|
271
|
+
throw new Error(`${path}: expected complete, partial, or candidate`);
|
|
272
|
+
}
|
|
273
|
+
function parseOffBoardWiringEndpoint(value, path) {
|
|
274
|
+
const endpoint = expectObject(value, path);
|
|
275
|
+
const kind = expectString(endpoint.kind, `${path}.kind`);
|
|
276
|
+
switch (kind) {
|
|
277
|
+
case 'panel-component-terminal':
|
|
278
|
+
case 'board-terminal':
|
|
279
|
+
case 'power-terminal':
|
|
280
|
+
case 'footswitch-terminal':
|
|
281
|
+
case 'free-wire-label':
|
|
282
|
+
return {
|
|
283
|
+
...parseBuildDataObject(endpoint, path),
|
|
284
|
+
id: expectString(endpoint.id, `${path}.id`),
|
|
285
|
+
kind,
|
|
286
|
+
...(endpoint.componentId === undefined
|
|
287
|
+
? {}
|
|
288
|
+
: { componentId: expectString(endpoint.componentId, `${path}.componentId`) }),
|
|
289
|
+
...(endpoint.terminalName === undefined
|
|
290
|
+
? {}
|
|
291
|
+
: { terminalName: expectString(endpoint.terminalName, `${path}.terminalName`) }),
|
|
292
|
+
...(endpoint.panelElementId === undefined
|
|
293
|
+
? {}
|
|
294
|
+
: { panelElementId: expectString(endpoint.panelElementId, `${path}.panelElementId`) }),
|
|
295
|
+
...(endpoint.boardId === undefined ? {} : { boardId: expectString(endpoint.boardId, `${path}.boardId`) }),
|
|
296
|
+
...(endpoint.terminalId === undefined
|
|
297
|
+
? {}
|
|
298
|
+
: { terminalId: expectString(endpoint.terminalId, `${path}.terminalId`) }),
|
|
299
|
+
...(endpoint.label === undefined ? {} : { label: expectString(endpoint.label, `${path}.label`) }),
|
|
300
|
+
};
|
|
301
|
+
default:
|
|
302
|
+
throw new Error(`${path}.kind: expected a supported off-board wiring endpoint kind`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function parseOffBoardWiringConnection(value, path) {
|
|
306
|
+
const connection = expectObject(value, path);
|
|
307
|
+
return {
|
|
308
|
+
...parseBuildDataObject(connection, path),
|
|
309
|
+
id: expectString(connection.id, `${path}.id`),
|
|
310
|
+
fromEndpointId: expectString(connection.fromEndpointId, `${path}.fromEndpointId`),
|
|
311
|
+
toEndpointId: expectString(connection.toEndpointId, `${path}.toEndpointId`),
|
|
312
|
+
...(connection.signalRef === undefined
|
|
313
|
+
? {}
|
|
314
|
+
: { signalRef: parseBuildDataObject(connection.signalRef, `${path}.signalRef`) }),
|
|
315
|
+
...(connection.wire === undefined ? {} : { wire: parseBuildDataObject(connection.wire, `${path}.wire`) }),
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
function parseBoards(value) {
|
|
319
|
+
if (value === undefined) {
|
|
320
|
+
return undefined;
|
|
321
|
+
}
|
|
322
|
+
return optionalArray(value, 'boards').map(parseBoard);
|
|
323
|
+
}
|
|
324
|
+
function parseBoard(value, index) {
|
|
325
|
+
const path = `boards[${index}]`;
|
|
326
|
+
const board = expectObject(value, path);
|
|
327
|
+
const sourceCircuit = board.sourceCircuit === undefined
|
|
328
|
+
? undefined
|
|
329
|
+
: parseBoardSourceCircuit(board.sourceCircuit, `${path}.sourceCircuit`);
|
|
330
|
+
return {
|
|
331
|
+
...parseBuildDataObject(board, path),
|
|
332
|
+
id: expectString(board.id, `${path}.id`),
|
|
333
|
+
schema: parseLiteralString(board.schema, `${path}.schema`, 'circuit-board/v1'),
|
|
334
|
+
family: parseBoardFamily(board.family, `${path}.family`),
|
|
335
|
+
kind: parseBoardKind(board.kind, `${path}.kind`),
|
|
336
|
+
...(board.subtype === undefined ? {} : { subtype: parseBoardSubtype(board.subtype, `${path}.subtype`) }),
|
|
337
|
+
...(board.source === undefined ? {} : { source: expectString(board.source, `${path}.source`) }),
|
|
338
|
+
...(board.units === undefined ? {} : { units: expectString(board.units, `${path}.units`) }),
|
|
339
|
+
...(board.locked === undefined ? {} : { locked: expectBoolean(board.locked, `${path}.locked`) }),
|
|
340
|
+
...(sourceCircuit === undefined ? {} : { sourceCircuit }),
|
|
341
|
+
edgeTerminals: optionalArray(board.edgeTerminals, `${path}.edgeTerminals`).map((terminal, terminalIndex) => parseBoardEdgeTerminal(terminal, `${path}.edgeTerminals[${terminalIndex}]`)),
|
|
342
|
+
footprintPlacements: optionalArray(board.footprintPlacements, `${path}.footprintPlacements`).map((placement, placementIndex) => parseBoardFootprintPlacement(placement, `${path}.footprintPlacements[${placementIndex}]`)),
|
|
343
|
+
...(board.netlist === undefined ? {} : { netlist: parseBoardNetlist(board.netlist, `${path}.netlist`) }),
|
|
344
|
+
routes: optionalArray(board.routes, `${path}.routes`).map((route, routeIndex) => parseBoardRoute(route, `${path}.routes[${routeIndex}]`)),
|
|
345
|
+
...(board.zones === undefined ? {} : { zones: parseBuildDataObjectArray(board.zones, `${path}.zones`) }),
|
|
346
|
+
...(board.drills === undefined ? {} : { drills: parseBuildDataObjectArray(board.drills, `${path}.drills`) }),
|
|
347
|
+
...(board.review === undefined ? {} : { review: parseBuildDataObject(board.review, `${path}.review`) }),
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
function parseBoardSourceCircuit(value, path) {
|
|
351
|
+
const sourceCircuit = expectObject(value, path);
|
|
352
|
+
const hash = expectString(sourceCircuit.hash, `${path}.hash`);
|
|
353
|
+
if (!/^sha256:[0-9a-f]{64}$/.test(hash)) {
|
|
354
|
+
throw new Error(`${path}.hash: expected sha256:<64 lowercase hex characters>`);
|
|
355
|
+
}
|
|
356
|
+
return {
|
|
357
|
+
...parseBuildDataObject(sourceCircuit, path),
|
|
358
|
+
schema: parseLiteralString(sourceCircuit.schema, `${path}.schema`, 'canonical-circuit-facts-hash/v1'),
|
|
359
|
+
hashAlgorithm: parseLiteralString(sourceCircuit.hashAlgorithm, `${path}.hashAlgorithm`, 'sha256'),
|
|
360
|
+
hash,
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
function parseBoardEdgeTerminal(value, path) {
|
|
364
|
+
const terminal = expectObject(value, path);
|
|
365
|
+
return {
|
|
366
|
+
...parseBuildDataObject(terminal, path),
|
|
367
|
+
id: expectString(terminal.id, `${path}.id`),
|
|
368
|
+
...(terminal.role === undefined ? {} : { role: expectString(terminal.role, `${path}.role`) }),
|
|
369
|
+
...(terminal.terminalRef === undefined
|
|
370
|
+
? {}
|
|
371
|
+
: { terminalRef: parseComponentTerminalRef(terminal.terminalRef, `${path}.terminalRef`) }),
|
|
372
|
+
...(terminal.hole === undefined ? {} : { hole: parseBoardHole(terminal.hole, `${path}.hole`) }),
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
function parseBoardFootprintPlacement(value, path) {
|
|
376
|
+
const placement = expectObject(value, path);
|
|
377
|
+
return {
|
|
378
|
+
...parseBuildDataObject(placement, path),
|
|
379
|
+
componentId: expectString(placement.componentId, `${path}.componentId`),
|
|
380
|
+
footprintId: expectString(placement.footprintId, `${path}.footprintId`),
|
|
381
|
+
...(placement.atGrid === undefined ? {} : { atGrid: parseBoardHole(placement.atGrid, `${path}.atGrid`) }),
|
|
382
|
+
...(placement.atMm === undefined ? {} : { atMm: parsePoint(placement.atMm, `${path}.atMm`) }),
|
|
383
|
+
...(placement.rotationDeg === undefined ? {} : { rotationDeg: expectNumber(placement.rotationDeg, `${path}.rotationDeg`) }),
|
|
384
|
+
pads: optionalArray(placement.pads, `${path}.pads`).map((pad, padIndex) => parseBoardPlacedPad(pad, `${path}.pads[${padIndex}]`)),
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
function parseBoardPlacedPad(value, path) {
|
|
388
|
+
const pad = expectObject(value, path);
|
|
389
|
+
return {
|
|
390
|
+
...parseBuildDataObject(pad, path),
|
|
391
|
+
padId: expectString(pad.padId, `${path}.padId`),
|
|
392
|
+
...(pad.terminalName === undefined ? {} : { terminalName: expectString(pad.terminalName, `${path}.terminalName`) }),
|
|
393
|
+
...(pad.hole === undefined ? {} : { hole: parseBoardHole(pad.hole, `${path}.hole`) }),
|
|
394
|
+
...(pad.positionMm === undefined ? {} : { positionMm: parsePoint(pad.positionMm, `${path}.positionMm`) }),
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
function parseBoardNetlist(value, path) {
|
|
398
|
+
const netlist = expectObject(value, path);
|
|
399
|
+
return {
|
|
400
|
+
...parseBuildDataObject(netlist, path),
|
|
401
|
+
...(netlist.source === undefined ? {} : { source: expectString(netlist.source, `${path}.source`) }),
|
|
402
|
+
nets: optionalArray(netlist.nets, `${path}.nets`).map((net, netIndex) => parseBoardNet(net, `${path}.nets[${netIndex}]`)),
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
function parseBoardNet(value, path) {
|
|
406
|
+
const net = expectObject(value, path);
|
|
407
|
+
return {
|
|
408
|
+
...parseBuildDataObject(net, path),
|
|
409
|
+
id: expectString(net.id, `${path}.id`),
|
|
410
|
+
...(net.name === undefined ? {} : { name: expectString(net.name, `${path}.name`) }),
|
|
411
|
+
members: optionalArray(net.members, `${path}.members`).map((member, memberIndex) => parseBoardNetMember(member, `${path}.members[${memberIndex}]`)),
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
function parseBoardNetMember(value, path) {
|
|
415
|
+
const member = expectObject(value, path);
|
|
416
|
+
return {
|
|
417
|
+
...parseBuildDataObject(member, path),
|
|
418
|
+
componentId: expectString(member.componentId, `${path}.componentId`),
|
|
419
|
+
terminalName: expectString(member.terminalName, `${path}.terminalName`),
|
|
420
|
+
...(member.padId === undefined ? {} : { padId: expectString(member.padId, `${path}.padId`) }),
|
|
421
|
+
...(member.terminalId === undefined ? {} : { terminalId: expectString(member.terminalId, `${path}.terminalId`) }),
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
function parseBoardRoute(value, path) {
|
|
425
|
+
const route = expectObject(value, path);
|
|
426
|
+
return {
|
|
427
|
+
...parseBuildDataObject(route, path),
|
|
428
|
+
id: expectString(route.id, `${path}.id`),
|
|
429
|
+
...(route.netRef === undefined ? {} : { netRef: parseBuildDataObject(route.netRef, `${path}.netRef`) }),
|
|
430
|
+
...(route.locked === undefined ? {} : { locked: expectBoolean(route.locked, `${path}.locked`) }),
|
|
431
|
+
...(route.conductors === undefined
|
|
432
|
+
? {}
|
|
433
|
+
: { conductors: parseBuildDataObjectArray(route.conductors, `${path}.conductors`) }),
|
|
434
|
+
...(route.copper === undefined ? {} : { copper: parseBuildDataObjectArray(route.copper, `${path}.copper`) }),
|
|
435
|
+
...(route.vias === undefined ? {} : { vias: parseBuildDataObjectArray(route.vias, `${path}.vias`) }),
|
|
436
|
+
...(route.zones === undefined ? {} : { zones: parseBuildDataObjectArray(route.zones, `${path}.zones`) }),
|
|
437
|
+
...(route.drills === undefined ? {} : { drills: parseBuildDataObjectArray(route.drills, `${path}.drills`) }),
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function parseComponentTerminalRef(value, path) {
|
|
441
|
+
const ref = expectObject(value, path);
|
|
442
|
+
return {
|
|
443
|
+
...parseBuildDataObject(ref, path),
|
|
444
|
+
componentId: expectString(ref.componentId, `${path}.componentId`),
|
|
445
|
+
terminalName: expectString(ref.terminalName, `${path}.terminalName`),
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
function parseBoardHole(value, path) {
|
|
449
|
+
const hole = expectObject(value, path);
|
|
450
|
+
return {
|
|
451
|
+
...parseBuildDataObject(hole, path),
|
|
452
|
+
row: expectPositiveInteger(hole.row, `${path}.row`),
|
|
453
|
+
column: expectPositiveInteger(hole.column, `${path}.column`),
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
function parseBoardFamily(value, path) {
|
|
457
|
+
const family = expectString(value, path);
|
|
458
|
+
if (family === 'prototype-board' || family === 'fabricated-board') {
|
|
459
|
+
return family;
|
|
460
|
+
}
|
|
461
|
+
throw new Error(`${path}: expected prototype-board or fabricated-board`);
|
|
462
|
+
}
|
|
463
|
+
function parseBoardKind(value, path) {
|
|
464
|
+
const kind = expectString(value, path);
|
|
465
|
+
switch (kind) {
|
|
466
|
+
case 'stripboard':
|
|
467
|
+
case 'perfboard':
|
|
468
|
+
case 'breadboard-pattern':
|
|
469
|
+
case 'pcb':
|
|
470
|
+
return kind;
|
|
471
|
+
default:
|
|
472
|
+
throw new Error(`${path}: expected stripboard, perfboard, breadboard-pattern, or pcb`);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
function parseBoardSubtype(value, path) {
|
|
476
|
+
const subtype = expectString(value, path);
|
|
477
|
+
switch (subtype) {
|
|
478
|
+
case 'veroboard':
|
|
479
|
+
case 'isolated-pad':
|
|
480
|
+
case 'solderable-half-breadboard':
|
|
481
|
+
case 'single-sided-through-hole':
|
|
482
|
+
case 'two-layer-through-hole':
|
|
483
|
+
return subtype;
|
|
484
|
+
default:
|
|
485
|
+
throw new Error(`${path}: expected a supported board subtype`);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
function parseLiteralString(value, path, expected) {
|
|
489
|
+
const actual = expectString(value, path);
|
|
490
|
+
if (actual === expected) {
|
|
491
|
+
return expected;
|
|
492
|
+
}
|
|
493
|
+
throw new Error(`${path}: expected ${expected}`);
|
|
494
|
+
}
|
|
495
|
+
function parseBuildDataObjectArray(value, path) {
|
|
496
|
+
return optionalArray(value, path).map((item, index) => parseBuildDataObject(item, `${path}[${index}]`));
|
|
497
|
+
}
|
|
498
|
+
function parseBuildDataObject(value, path) {
|
|
499
|
+
const object = expectObject(value, path);
|
|
500
|
+
const out = {};
|
|
501
|
+
for (const [key, child] of Object.entries(object)) {
|
|
502
|
+
out[key] = parseBuildDataValue(child, `${path}.${key}`);
|
|
503
|
+
}
|
|
504
|
+
return out;
|
|
505
|
+
}
|
|
506
|
+
function parseBuildDataValue(value, path) {
|
|
507
|
+
if (isScalar(value)) {
|
|
508
|
+
return value;
|
|
509
|
+
}
|
|
510
|
+
if (Array.isArray(value)) {
|
|
511
|
+
return value.map((item, index) => parseBuildDataValue(item, `${path}[${index}]`));
|
|
512
|
+
}
|
|
513
|
+
if (isYamlObject(value)) {
|
|
514
|
+
return parseBuildDataObject(value, path);
|
|
515
|
+
}
|
|
516
|
+
throw new Error(`${path}: expected v3 build data value`);
|
|
517
|
+
}
|
|
518
|
+
function parseControlGroups(value) {
|
|
95
519
|
if (value === undefined) {
|
|
96
520
|
return undefined;
|
|
97
521
|
}
|
|
@@ -109,8 +533,7 @@ function parseControlGroups(value: YamlValue | undefined): readonly ControlGroup
|
|
|
109
533
|
};
|
|
110
534
|
});
|
|
111
535
|
}
|
|
112
|
-
|
|
113
|
-
function parseControlContexts(value: YamlValue | undefined): readonly ControlContext[] | undefined {
|
|
536
|
+
function parseControlContexts(value) {
|
|
114
537
|
if (value === undefined) {
|
|
115
538
|
return undefined;
|
|
116
539
|
}
|
|
@@ -126,8 +549,7 @@ function parseControlContexts(value: YamlValue | undefined): readonly ControlCon
|
|
|
126
549
|
};
|
|
127
550
|
});
|
|
128
551
|
}
|
|
129
|
-
|
|
130
|
-
function parseDeviceInterface(value: YamlValue | undefined): DeviceInterface | undefined {
|
|
552
|
+
function parseDeviceInterface(value) {
|
|
131
553
|
if (value === undefined) {
|
|
132
554
|
return undefined;
|
|
133
555
|
}
|
|
@@ -155,11 +577,7 @@ function parseDeviceInterface(value: YamlValue | undefined): DeviceInterface | u
|
|
|
155
577
|
}),
|
|
156
578
|
};
|
|
157
579
|
}
|
|
158
|
-
|
|
159
|
-
function parseDeviceInterfaceControlKind(
|
|
160
|
-
value: YamlValue | undefined,
|
|
161
|
-
path: string,
|
|
162
|
-
): DeviceInterfaceControlKind {
|
|
580
|
+
function parseDeviceInterfaceControlKind(value, path) {
|
|
163
581
|
const kind = expectString(value, path);
|
|
164
582
|
switch (kind) {
|
|
165
583
|
case 'knob':
|
|
@@ -174,11 +592,7 @@ function parseDeviceInterfaceControlKind(
|
|
|
174
592
|
throw new Error(`${path}: expected knob, slider, switch, selector, footswitch, led, or jack`);
|
|
175
593
|
}
|
|
176
594
|
}
|
|
177
|
-
|
|
178
|
-
function parseOptionalDeviceInterfaceBinding(
|
|
179
|
-
value: YamlValue | undefined,
|
|
180
|
-
path: string,
|
|
181
|
-
): DeviceInterfaceBinding | undefined {
|
|
595
|
+
function parseOptionalDeviceInterfaceBinding(value, path) {
|
|
182
596
|
if (value === undefined) {
|
|
183
597
|
return undefined;
|
|
184
598
|
}
|
|
@@ -195,11 +609,7 @@ function parseOptionalDeviceInterfaceBinding(
|
|
|
195
609
|
...(externalInterfaceId === undefined ? {} : { externalInterfaceId }),
|
|
196
610
|
};
|
|
197
611
|
}
|
|
198
|
-
|
|
199
|
-
function parseOptionalApplicabilityPredicate(
|
|
200
|
-
value: YamlValue | undefined,
|
|
201
|
-
path: string,
|
|
202
|
-
): ControlApplicabilityPredicate | undefined {
|
|
612
|
+
function parseOptionalApplicabilityPredicate(value, path) {
|
|
203
613
|
if (value === undefined) {
|
|
204
614
|
return undefined;
|
|
205
615
|
}
|
|
@@ -211,8 +621,7 @@ function parseOptionalApplicabilityPredicate(
|
|
|
211
621
|
...(anyOf === undefined ? {} : { anyOf }),
|
|
212
622
|
};
|
|
213
623
|
}
|
|
214
|
-
|
|
215
|
-
function parseDevice(value: YamlValue | undefined): CircuitDocumentDevice | undefined {
|
|
624
|
+
function parseDevice(value) {
|
|
216
625
|
if (value === undefined) {
|
|
217
626
|
return undefined;
|
|
218
627
|
}
|
|
@@ -231,8 +640,7 @@ function parseDevice(value: YamlValue | undefined): CircuitDocumentDevice | unde
|
|
|
231
640
|
...(audioProcessing === undefined ? {} : { audioProcessing }),
|
|
232
641
|
};
|
|
233
642
|
}
|
|
234
|
-
|
|
235
|
-
function parseCircuitDocumentDeviceKind(value: YamlValue | undefined, path: string): CircuitDocumentDeviceKind {
|
|
643
|
+
function parseCircuitDocumentDeviceKind(value, path) {
|
|
236
644
|
const kind = expectString(value, path);
|
|
237
645
|
switch (kind) {
|
|
238
646
|
case 'audio-pedal':
|
|
@@ -244,8 +652,7 @@ function parseCircuitDocumentDeviceKind(value: YamlValue | undefined, path: stri
|
|
|
244
652
|
throw new Error(`${path}: expected audio-pedal, control-accessory, utility, or unknown`);
|
|
245
653
|
}
|
|
246
654
|
}
|
|
247
|
-
|
|
248
|
-
function parseControlOutputs(value: YamlValue | undefined): readonly ControlOutput[] | undefined {
|
|
655
|
+
function parseControlOutputs(value) {
|
|
249
656
|
if (value === undefined) {
|
|
250
657
|
return undefined;
|
|
251
658
|
}
|
|
@@ -273,11 +680,7 @@ function parseControlOutputs(value: YamlValue | undefined): readonly ControlOutp
|
|
|
273
680
|
};
|
|
274
681
|
});
|
|
275
682
|
}
|
|
276
|
-
|
|
277
|
-
function parseOptionalControlOutputSwitchMode(
|
|
278
|
-
value: YamlValue | undefined,
|
|
279
|
-
path: string,
|
|
280
|
-
): ControlOutputSwitchMode | undefined {
|
|
683
|
+
function parseOptionalControlOutputSwitchMode(value, path) {
|
|
281
684
|
if (value === undefined) {
|
|
282
685
|
return undefined;
|
|
283
686
|
}
|
|
@@ -290,8 +693,7 @@ function parseOptionalControlOutputSwitchMode(
|
|
|
290
693
|
throw new Error(`${path}: expected momentary or latching`);
|
|
291
694
|
}
|
|
292
695
|
}
|
|
293
|
-
|
|
294
|
-
function parseControlInterfaces(value: YamlValue | undefined): readonly ControlInterface[] | undefined {
|
|
696
|
+
function parseControlInterfaces(value) {
|
|
295
697
|
if (value === undefined) {
|
|
296
698
|
return undefined;
|
|
297
699
|
}
|
|
@@ -302,10 +704,7 @@ function parseControlInterfaces(value: YamlValue | undefined): readonly ControlI
|
|
|
302
704
|
const controlRole = parseOptionalString(controlInterface.controlRole, `${path}.controlRole`);
|
|
303
705
|
const interfaceName = parseOptionalString(controlInterface.interface, `${path}.interface`);
|
|
304
706
|
const connector = parseOptionalControlInterfaceConnector(controlInterface.connector, `${path}.connector`);
|
|
305
|
-
const assignmentHint = parseOptionalControlInterfaceAssignmentHint(
|
|
306
|
-
controlInterface.assignmentHint,
|
|
307
|
-
`${path}.assignmentHint`,
|
|
308
|
-
);
|
|
707
|
+
const assignmentHint = parseOptionalControlInterfaceAssignmentHint(controlInterface.assignmentHint, `${path}.assignmentHint`);
|
|
309
708
|
const polarity = parseOptionalControlInterfacePolarity(controlInterface.polarity, `${path}.polarity`);
|
|
310
709
|
const binding = parseOptionalControlInterfaceBinding(controlInterface.binding, `${path}.binding`);
|
|
311
710
|
const description = parseOptionalString(controlInterface.description, `${path}.description`);
|
|
@@ -324,11 +723,7 @@ function parseControlInterfaces(value: YamlValue | undefined): readonly ControlI
|
|
|
324
723
|
};
|
|
325
724
|
});
|
|
326
725
|
}
|
|
327
|
-
|
|
328
|
-
function parseOptionalControlInterfaceBinding(
|
|
329
|
-
value: YamlValue | undefined,
|
|
330
|
-
path: string,
|
|
331
|
-
): ControlInterface['binding'] | undefined {
|
|
726
|
+
function parseOptionalControlInterfaceBinding(value, path) {
|
|
332
727
|
if (value === undefined) {
|
|
333
728
|
return undefined;
|
|
334
729
|
}
|
|
@@ -344,8 +739,7 @@ function parseOptionalControlInterfaceBinding(
|
|
|
344
739
|
...(property === undefined ? {} : { property }),
|
|
345
740
|
};
|
|
346
741
|
}
|
|
347
|
-
|
|
348
|
-
function parseControlInterfaceRole(value: YamlValue | undefined, path: string): ControlInterfaceRole {
|
|
742
|
+
function parseControlInterfaceRole(value, path) {
|
|
349
743
|
const role = expectString(value, path);
|
|
350
744
|
switch (role) {
|
|
351
745
|
case 'external-control':
|
|
@@ -360,11 +754,7 @@ function parseControlInterfaceRole(value: YamlValue | undefined, path: string):
|
|
|
360
754
|
throw new Error(`${path}: expected external-control, tempo-tap, trigger, reset, sampler-trigger, expression, or unknown`);
|
|
361
755
|
}
|
|
362
756
|
}
|
|
363
|
-
|
|
364
|
-
function parseOptionalControlInterfaceConnector(
|
|
365
|
-
value: YamlValue | undefined,
|
|
366
|
-
path: string,
|
|
367
|
-
): ControlInterfaceConnector | undefined {
|
|
757
|
+
function parseOptionalControlInterfaceConnector(value, path) {
|
|
368
758
|
if (value === undefined) {
|
|
369
759
|
return undefined;
|
|
370
760
|
}
|
|
@@ -381,11 +771,7 @@ function parseOptionalControlInterfaceConnector(
|
|
|
381
771
|
throw new Error(`${path}: expected a supported connector kind`);
|
|
382
772
|
}
|
|
383
773
|
}
|
|
384
|
-
|
|
385
|
-
function parseOptionalControlInterfaceAssignmentHint(
|
|
386
|
-
value: YamlValue | undefined,
|
|
387
|
-
path: string,
|
|
388
|
-
): ControlInterfaceAssignmentHint | undefined {
|
|
774
|
+
function parseOptionalControlInterfaceAssignmentHint(value, path) {
|
|
389
775
|
if (value === undefined) {
|
|
390
776
|
return undefined;
|
|
391
777
|
}
|
|
@@ -400,11 +786,7 @@ function parseOptionalControlInterfaceAssignmentHint(
|
|
|
400
786
|
throw new Error(`${path}: expected momentary, latching, momentary-or-latching, or continuous`);
|
|
401
787
|
}
|
|
402
788
|
}
|
|
403
|
-
|
|
404
|
-
function parseOptionalControlInterfacePolarity(
|
|
405
|
-
value: YamlValue | undefined,
|
|
406
|
-
path: string,
|
|
407
|
-
): ControlInterfacePolarity | undefined {
|
|
789
|
+
function parseOptionalControlInterfacePolarity(value, path) {
|
|
408
790
|
if (value === undefined) {
|
|
409
791
|
return undefined;
|
|
410
792
|
}
|
|
@@ -419,13 +801,12 @@ function parseOptionalControlInterfacePolarity(
|
|
|
419
801
|
throw new Error(`${path}: expected normally-open, normally-closed, expression, or unknown`);
|
|
420
802
|
}
|
|
421
803
|
}
|
|
422
|
-
|
|
423
|
-
function parseYamlSubset(source: string): YamlValue {
|
|
804
|
+
function parseYamlSubset(source) {
|
|
424
805
|
const lines = tokenize(source);
|
|
425
806
|
if (lines.length === 0) {
|
|
426
807
|
throw new Error('interchange YAML is empty');
|
|
427
808
|
}
|
|
428
|
-
const cursor
|
|
809
|
+
const cursor = { index: 0 };
|
|
429
810
|
const first = lines[0];
|
|
430
811
|
if (first === undefined) {
|
|
431
812
|
throw new Error('interchange YAML is empty');
|
|
@@ -437,9 +818,8 @@ function parseYamlSubset(source: string): YamlValue {
|
|
|
437
818
|
}
|
|
438
819
|
return value;
|
|
439
820
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
const lines: YamlLine[] = [];
|
|
821
|
+
function tokenize(source) {
|
|
822
|
+
const lines = [];
|
|
443
823
|
const rawLines = source.replace(/^/, '').split(/\r?\n/);
|
|
444
824
|
rawLines.forEach((rawLine, index) => {
|
|
445
825
|
if (rawLine.trim().length === 0) {
|
|
@@ -457,8 +837,7 @@ function tokenize(source: string): readonly YamlLine[] {
|
|
|
457
837
|
});
|
|
458
838
|
return lines;
|
|
459
839
|
}
|
|
460
|
-
|
|
461
|
-
function parseBlock(lines: readonly YamlLine[], cursor: Cursor, indent: number): YamlValue {
|
|
840
|
+
function parseBlock(lines, cursor, indent) {
|
|
462
841
|
const line = lines[cursor.index];
|
|
463
842
|
if (line === undefined) {
|
|
464
843
|
return {};
|
|
@@ -471,9 +850,8 @@ function parseBlock(lines: readonly YamlLine[], cursor: Cursor, indent: number):
|
|
|
471
850
|
}
|
|
472
851
|
return parseObject(lines, cursor, indent);
|
|
473
852
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
const out: YamlObject = {};
|
|
853
|
+
function parseObject(lines, cursor, indent) {
|
|
854
|
+
const out = {};
|
|
477
855
|
while (cursor.index < lines.length) {
|
|
478
856
|
const line = lines[cursor.index];
|
|
479
857
|
if (line === undefined || line.indent < indent) {
|
|
@@ -485,7 +863,6 @@ function parseObject(lines: readonly YamlLine[], cursor: Cursor, indent: number)
|
|
|
485
863
|
if (line.text === '-' || line.text.startsWith('- ')) {
|
|
486
864
|
break;
|
|
487
865
|
}
|
|
488
|
-
|
|
489
866
|
const pair = parsePair(line.text, line.lineNumber);
|
|
490
867
|
cursor.index += 1;
|
|
491
868
|
out[pair.key] = pair.rest.length > 0
|
|
@@ -494,9 +871,8 @@ function parseObject(lines: readonly YamlLine[], cursor: Cursor, indent: number)
|
|
|
494
871
|
}
|
|
495
872
|
return out;
|
|
496
873
|
}
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
const out: YamlValue[] = [];
|
|
874
|
+
function parseArray(lines, cursor, indent) {
|
|
875
|
+
const out = [];
|
|
500
876
|
while (cursor.index < lines.length) {
|
|
501
877
|
const line = lines[cursor.index];
|
|
502
878
|
if (line === undefined || line.indent < indent) {
|
|
@@ -508,33 +884,26 @@ function parseArray(lines: readonly YamlLine[], cursor: Cursor, indent: number):
|
|
|
508
884
|
if (line.text !== '-' && !line.text.startsWith('- ')) {
|
|
509
885
|
break;
|
|
510
886
|
}
|
|
511
|
-
|
|
512
887
|
const rest = line.text === '-' ? '' : line.text.slice(2);
|
|
513
888
|
cursor.index += 1;
|
|
514
889
|
if (rest.length === 0) {
|
|
515
890
|
out.push(parseNestedValue(lines, cursor, indent, line.lineNumber));
|
|
516
|
-
}
|
|
891
|
+
}
|
|
892
|
+
else if (looksLikePair(rest)) {
|
|
517
893
|
out.push(parseObjectItem(rest, lines, cursor, indent + 2, line.lineNumber));
|
|
518
|
-
}
|
|
894
|
+
}
|
|
895
|
+
else {
|
|
519
896
|
out.push(parseInlineValue(rest, line.lineNumber));
|
|
520
897
|
}
|
|
521
898
|
}
|
|
522
899
|
return out;
|
|
523
900
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
firstPairText: string,
|
|
527
|
-
lines: readonly YamlLine[],
|
|
528
|
-
cursor: Cursor,
|
|
529
|
-
indent: number,
|
|
530
|
-
lineNumber: number,
|
|
531
|
-
): YamlObject {
|
|
532
|
-
const out: YamlObject = {};
|
|
901
|
+
function parseObjectItem(firstPairText, lines, cursor, indent, lineNumber) {
|
|
902
|
+
const out = {};
|
|
533
903
|
const firstPair = parsePair(firstPairText, lineNumber);
|
|
534
904
|
out[firstPair.key] = firstPair.rest.length > 0
|
|
535
905
|
? parseInlineValue(firstPair.rest, lineNumber)
|
|
536
906
|
: parseNestedValue(lines, cursor, indent, lineNumber);
|
|
537
|
-
|
|
538
907
|
while (cursor.index < lines.length) {
|
|
539
908
|
const line = lines[cursor.index];
|
|
540
909
|
if (line === undefined || line.indent < indent) {
|
|
@@ -546,23 +915,15 @@ function parseObjectItem(
|
|
|
546
915
|
if (line.text === '-' || line.text.startsWith('- ')) {
|
|
547
916
|
break;
|
|
548
917
|
}
|
|
549
|
-
|
|
550
918
|
const pair = parsePair(line.text, line.lineNumber);
|
|
551
919
|
cursor.index += 1;
|
|
552
920
|
out[pair.key] = pair.rest.length > 0
|
|
553
921
|
? parseInlineValue(pair.rest, line.lineNumber)
|
|
554
922
|
: parseNestedValue(lines, cursor, indent, line.lineNumber);
|
|
555
923
|
}
|
|
556
|
-
|
|
557
924
|
return out;
|
|
558
925
|
}
|
|
559
|
-
|
|
560
|
-
function parseNestedValue(
|
|
561
|
-
lines: readonly YamlLine[],
|
|
562
|
-
cursor: Cursor,
|
|
563
|
-
parentIndent: number,
|
|
564
|
-
lineNumber: number,
|
|
565
|
-
): YamlValue {
|
|
926
|
+
function parseNestedValue(lines, cursor, parentIndent, lineNumber) {
|
|
566
927
|
const next = lines[cursor.index];
|
|
567
928
|
if (next === undefined || next.indent <= parentIndent) {
|
|
568
929
|
return {};
|
|
@@ -572,8 +933,7 @@ function parseNestedValue(
|
|
|
572
933
|
}
|
|
573
934
|
return parseBlock(lines, cursor, next.indent);
|
|
574
935
|
}
|
|
575
|
-
|
|
576
|
-
function parsePair(text: string, lineNumber: number): ParsedPair {
|
|
936
|
+
function parsePair(text, lineNumber) {
|
|
577
937
|
const colonIndex = findPairColon(text);
|
|
578
938
|
if (colonIndex <= 0) {
|
|
579
939
|
throw new Error(`line ${lineNumber}: expected key/value pair`);
|
|
@@ -585,20 +945,17 @@ function parsePair(text: string, lineNumber: number): ParsedPair {
|
|
|
585
945
|
rest: restText.startsWith(' ') ? restText.slice(1) : restText,
|
|
586
946
|
};
|
|
587
947
|
}
|
|
588
|
-
|
|
589
|
-
function looksLikePair(text: string): boolean {
|
|
948
|
+
function looksLikePair(text) {
|
|
590
949
|
return findPairColon(text) > 0;
|
|
591
950
|
}
|
|
592
|
-
|
|
593
|
-
function findPairColon(text: string): number {
|
|
951
|
+
function findPairColon(text) {
|
|
594
952
|
if (text.startsWith('"')) {
|
|
595
953
|
const end = findJsonStringEnd(text);
|
|
596
954
|
return end >= 0 && text[end + 1] === ':' ? end + 1 : -1;
|
|
597
955
|
}
|
|
598
956
|
return text.indexOf(':');
|
|
599
957
|
}
|
|
600
|
-
|
|
601
|
-
function findJsonStringEnd(text: string): number {
|
|
958
|
+
function findJsonStringEnd(text) {
|
|
602
959
|
let escaped = false;
|
|
603
960
|
for (let index = 1; index < text.length; index += 1) {
|
|
604
961
|
const char = text[index];
|
|
@@ -616,8 +973,7 @@ function findJsonStringEnd(text: string): number {
|
|
|
616
973
|
}
|
|
617
974
|
return -1;
|
|
618
975
|
}
|
|
619
|
-
|
|
620
|
-
function parseKey(text: string, lineNumber: number): string {
|
|
976
|
+
function parseKey(text, lineNumber) {
|
|
621
977
|
if (!text.startsWith('"')) {
|
|
622
978
|
return text;
|
|
623
979
|
}
|
|
@@ -626,13 +982,13 @@ function parseKey(text: string, lineNumber: number): string {
|
|
|
626
982
|
if (typeof parsed === 'string') {
|
|
627
983
|
return parsed;
|
|
628
984
|
}
|
|
629
|
-
}
|
|
985
|
+
}
|
|
986
|
+
catch {
|
|
630
987
|
// Fall through to the consistent parser error below.
|
|
631
988
|
}
|
|
632
989
|
throw new Error(`line ${lineNumber}: invalid quoted key`);
|
|
633
990
|
}
|
|
634
|
-
|
|
635
|
-
function parseInlineValue(text: string, lineNumber: number): YamlValue {
|
|
991
|
+
function parseInlineValue(text, lineNumber) {
|
|
636
992
|
if (text === '[]') {
|
|
637
993
|
return [];
|
|
638
994
|
}
|
|
@@ -654,7 +1010,8 @@ function parseInlineValue(text: string, lineNumber: number): YamlValue {
|
|
|
654
1010
|
if (typeof parsed === 'string') {
|
|
655
1011
|
return parsed;
|
|
656
1012
|
}
|
|
657
|
-
}
|
|
1013
|
+
}
|
|
1014
|
+
catch {
|
|
658
1015
|
// Fall through to the consistent parser error below.
|
|
659
1016
|
}
|
|
660
1017
|
throw new Error(`line ${lineNumber}: invalid quoted scalar`);
|
|
@@ -664,8 +1021,7 @@ function parseInlineValue(text: string, lineNumber: number): YamlValue {
|
|
|
664
1021
|
}
|
|
665
1022
|
return text;
|
|
666
1023
|
}
|
|
667
|
-
|
|
668
|
-
function parseMetadata(value: YamlValue | undefined): CircuitDocument['metadata'] {
|
|
1024
|
+
function parseMetadata(value) {
|
|
669
1025
|
const metadata = optionalObject(value, 'metadata');
|
|
670
1026
|
return {
|
|
671
1027
|
name: scalarText(metadata.name),
|
|
@@ -673,53 +1029,51 @@ function parseMetadata(value: YamlValue | undefined): CircuitDocument['metadata'
|
|
|
673
1029
|
partNumber: scalarText(metadata.partNumber),
|
|
674
1030
|
};
|
|
675
1031
|
}
|
|
676
|
-
|
|
677
|
-
function parseSource(value: YamlValue | undefined): DocumentSource {
|
|
1032
|
+
function parseSource(value) {
|
|
678
1033
|
return parseStringRecord(value, 'source');
|
|
679
1034
|
}
|
|
680
|
-
|
|
681
|
-
function parsePanel(value: YamlValue | undefined): PanelPlacementMetadata | undefined {
|
|
1035
|
+
function parsePanel(value, allowV3PhysicalFields) {
|
|
682
1036
|
if (value === undefined) {
|
|
683
1037
|
return undefined;
|
|
684
1038
|
}
|
|
685
1039
|
const panel = expectObject(value, 'panel');
|
|
686
|
-
|
|
687
1040
|
if (panel.faces !== undefined) {
|
|
688
1041
|
return {
|
|
689
|
-
faces: optionalArray(panel.faces, 'panel.faces').map((item, index) => parsePanelFace(item, index)),
|
|
1042
|
+
faces: optionalArray(panel.faces, 'panel.faces').map((item, index) => parsePanelFace(item, index, allowV3PhysicalFields)),
|
|
690
1043
|
};
|
|
691
1044
|
}
|
|
692
|
-
|
|
693
1045
|
if (panel.layout === undefined) {
|
|
694
1046
|
return undefined;
|
|
695
1047
|
}
|
|
696
|
-
|
|
697
1048
|
const layout = parsePanelLayout(panel.layout, 'panel.layout');
|
|
698
1049
|
const elementsValue = panel.controls ?? panel.elements;
|
|
699
1050
|
const elementsPath = panel.controls === undefined ? 'panel.elements' : 'panel.controls';
|
|
700
1051
|
return {
|
|
701
1052
|
faces: [{
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
1053
|
+
id: 'top',
|
|
1054
|
+
layout,
|
|
1055
|
+
elements: parsePanelElements(elementsValue, layout, elementsPath, allowV3PhysicalFields),
|
|
1056
|
+
}],
|
|
706
1057
|
};
|
|
707
1058
|
}
|
|
708
|
-
|
|
709
|
-
function parsePanelFace(value: YamlValue, index: number): PanelPlacementMetadata['faces'][number] {
|
|
1059
|
+
function parsePanelFace(value, index, allowV3PhysicalFields) {
|
|
710
1060
|
const path = `panel.faces[${index}]`;
|
|
711
1061
|
const face = expectObject(value, path);
|
|
712
1062
|
const label = parseOptionalString(face.label, `${path}.label`);
|
|
713
1063
|
const layout = parsePanelLayout(face.layout, `${path}.layout`);
|
|
1064
|
+
if (!allowV3PhysicalFields && face.geometry !== undefined) {
|
|
1065
|
+
throw new Error(`${path}.geometry: requires schema ${INTERCHANGE_SCHEMA_V3}`);
|
|
1066
|
+
}
|
|
1067
|
+
const geometry = allowV3PhysicalFields ? parseOptionalPanelFaceGeometry(face.geometry, `${path}.geometry`) : undefined;
|
|
714
1068
|
return {
|
|
715
1069
|
id: expectString(face.id, `${path}.id`),
|
|
716
1070
|
...(label === undefined ? {} : { label }),
|
|
717
1071
|
layout,
|
|
718
|
-
|
|
1072
|
+
...(geometry === undefined ? {} : { geometry }),
|
|
1073
|
+
elements: parsePanelElements(face.elements, layout, `${path}.elements`, allowV3PhysicalFields),
|
|
719
1074
|
};
|
|
720
1075
|
}
|
|
721
|
-
|
|
722
|
-
function parsePanelLayout(value: YamlValue | undefined, path: string): PanelGridLayout {
|
|
1076
|
+
function parsePanelLayout(value, path) {
|
|
723
1077
|
const layout = expectObject(value, path);
|
|
724
1078
|
const rowOrder = parseOptionalPanelRowOrder(layout.rowOrder, `${path}.rowOrder`);
|
|
725
1079
|
const columnOrder = parseOptionalPanelColumnOrder(layout.columnOrder, `${path}.columnOrder`);
|
|
@@ -732,33 +1086,77 @@ function parsePanelLayout(value: YamlValue | undefined, path: string): PanelGrid
|
|
|
732
1086
|
...(columnOrder === undefined ? {} : { columnOrder }),
|
|
733
1087
|
};
|
|
734
1088
|
}
|
|
735
|
-
|
|
736
|
-
function parsePanelElements(
|
|
737
|
-
value: YamlValue | undefined,
|
|
738
|
-
layout: PanelGridLayout,
|
|
739
|
-
path: string,
|
|
740
|
-
): PanelPlacementMetadata['faces'][number]['elements'] {
|
|
1089
|
+
function parsePanelElements(value, layout, path, allowV3PhysicalFields) {
|
|
741
1090
|
return optionalArray(value, path).map((item, index) => {
|
|
742
1091
|
const elementPath = `${path}[${index}]`;
|
|
743
1092
|
const element = expectObject(item, elementPath);
|
|
744
1093
|
const label = parseOptionalString(element.label, `${elementPath}.label`);
|
|
745
1094
|
const interfaceControlId = parseOptionalString(element.interfaceControlId, `${elementPath}.interfaceControlId`);
|
|
1095
|
+
if (!allowV3PhysicalFields && element.id !== undefined) {
|
|
1096
|
+
throw new Error(`${elementPath}.id: requires schema ${INTERCHANGE_SCHEMA_V3}`);
|
|
1097
|
+
}
|
|
1098
|
+
if (!allowV3PhysicalFields && element.physical !== undefined) {
|
|
1099
|
+
throw new Error(`${elementPath}.physical: requires schema ${INTERCHANGE_SCHEMA_V3}`);
|
|
1100
|
+
}
|
|
1101
|
+
const id = allowV3PhysicalFields ? parseOptionalString(element.id, `${elementPath}.id`) : undefined;
|
|
1102
|
+
const physical = allowV3PhysicalFields
|
|
1103
|
+
? parseOptionalPanelElementPhysical(element.physical, `${elementPath}.physical`)
|
|
1104
|
+
: undefined;
|
|
746
1105
|
return {
|
|
1106
|
+
...(id === undefined ? {} : { id }),
|
|
747
1107
|
bind: parsePanelElementBinding(element, elementPath),
|
|
748
|
-
kind: parsePanelControlKind(
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
? `${elementPath}.controlKind`
|
|
752
|
-
: `${elementPath}.kind`,
|
|
753
|
-
),
|
|
1108
|
+
kind: parsePanelControlKind(element.kind ?? element.controlKind, element.kind === undefined && element.controlKind !== undefined
|
|
1109
|
+
? `${elementPath}.controlKind`
|
|
1110
|
+
: `${elementPath}.kind`),
|
|
754
1111
|
grid: parsePanelGridPosition(element.grid, `${elementPath}.grid`, layout),
|
|
755
1112
|
...(label === undefined ? {} : { label }),
|
|
756
1113
|
...(interfaceControlId === undefined ? {} : { interfaceControlId }),
|
|
1114
|
+
...(physical === undefined ? {} : { physical }),
|
|
757
1115
|
};
|
|
758
1116
|
});
|
|
759
1117
|
}
|
|
760
|
-
|
|
761
|
-
|
|
1118
|
+
function parseOptionalPanelFaceGeometry(value, path) {
|
|
1119
|
+
if (value === undefined) {
|
|
1120
|
+
return undefined;
|
|
1121
|
+
}
|
|
1122
|
+
const geometry = expectObject(value, path);
|
|
1123
|
+
return {
|
|
1124
|
+
...parseBuildDataObject(geometry, path),
|
|
1125
|
+
...(geometry.units === undefined ? {} : { units: expectString(geometry.units, `${path}.units`) }),
|
|
1126
|
+
...(geometry.surface === undefined ? {} : { surface: expectString(geometry.surface, `${path}.surface`) }),
|
|
1127
|
+
...(geometry.usableRectMm === undefined
|
|
1128
|
+
? {}
|
|
1129
|
+
: { usableRectMm: parseMillimeterRect(geometry.usableRectMm, `${path}.usableRectMm`) }),
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
function parseOptionalPanelElementPhysical(value, path) {
|
|
1133
|
+
if (value === undefined) {
|
|
1134
|
+
return undefined;
|
|
1135
|
+
}
|
|
1136
|
+
const physical = expectObject(value, path);
|
|
1137
|
+
return {
|
|
1138
|
+
...parseBuildDataObject(physical, path),
|
|
1139
|
+
...(physical.units === undefined ? {} : { units: expectString(physical.units, `${path}.units`) }),
|
|
1140
|
+
...(physical.centerMm === undefined ? {} : { centerMm: parsePoint(physical.centerMm, `${path}.centerMm`) }),
|
|
1141
|
+
...(physical.drillDiameterMm === undefined
|
|
1142
|
+
? {}
|
|
1143
|
+
: { drillDiameterMm: expectNumber(physical.drillDiameterMm, `${path}.drillDiameterMm`) }),
|
|
1144
|
+
...(physical.partProfileId === undefined
|
|
1145
|
+
? {}
|
|
1146
|
+
: { partProfileId: expectString(physical.partProfileId, `${path}.partProfileId`) }),
|
|
1147
|
+
...(physical.locked === undefined ? {} : { locked: expectBoolean(physical.locked, `${path}.locked`) }),
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
1150
|
+
function parseMillimeterRect(value, path) {
|
|
1151
|
+
const rect = expectObject(value, path);
|
|
1152
|
+
return {
|
|
1153
|
+
x: expectNumber(rect.x, `${path}.x`),
|
|
1154
|
+
y: expectNumber(rect.y, `${path}.y`),
|
|
1155
|
+
width: expectNumber(rect.width, `${path}.width`),
|
|
1156
|
+
height: expectNumber(rect.height, `${path}.height`),
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
function parsePanelElementBinding(element, path) {
|
|
762
1160
|
if (element.bind !== undefined) {
|
|
763
1161
|
const bind = expectObject(element.bind, `${path}.bind`);
|
|
764
1162
|
const controlId = parseOptionalString(bind.controlId, `${path}.bind.controlId`);
|
|
@@ -771,17 +1169,11 @@ function parsePanelElementBinding(element: YamlObject, path: string): PanelEleme
|
|
|
771
1169
|
...(property === undefined ? {} : { property }),
|
|
772
1170
|
};
|
|
773
1171
|
}
|
|
774
|
-
|
|
775
1172
|
return {
|
|
776
1173
|
componentId: expectString(element.componentId, `${path}.componentId`),
|
|
777
1174
|
};
|
|
778
1175
|
}
|
|
779
|
-
|
|
780
|
-
function parsePanelGridPosition(
|
|
781
|
-
value: YamlValue | undefined,
|
|
782
|
-
path: string,
|
|
783
|
-
layout: PanelGridLayout,
|
|
784
|
-
): PanelGridPosition {
|
|
1176
|
+
function parsePanelGridPosition(value, path, layout) {
|
|
785
1177
|
const grid = expectObject(value, path);
|
|
786
1178
|
const rowSpan = parseOptionalPositiveInteger(grid.rowSpan, `${path}.rowSpan`);
|
|
787
1179
|
const columnSpan = parseOptionalPositiveInteger(grid.columnSpan, `${path}.columnSpan`);
|
|
@@ -796,15 +1188,7 @@ function parsePanelGridPosition(
|
|
|
796
1188
|
...(columnSpan === undefined ? {} : { columnSpan }),
|
|
797
1189
|
};
|
|
798
1190
|
}
|
|
799
|
-
|
|
800
|
-
function validateGridAxis(
|
|
801
|
-
value: number,
|
|
802
|
-
span: number,
|
|
803
|
-
size: number,
|
|
804
|
-
indexing: PanelGridIndexing,
|
|
805
|
-
path: string,
|
|
806
|
-
axisName: 'row' | 'column',
|
|
807
|
-
): void {
|
|
1191
|
+
function validateGridAxis(value, span, size, indexing, path, axisName) {
|
|
808
1192
|
const min = indexing === 'one-based' ? 1 : 0;
|
|
809
1193
|
const occupiedEnd = indexing === 'one-based' ? value + span - 1 : value + span;
|
|
810
1194
|
if (value < min || occupiedEnd > size) {
|
|
@@ -812,24 +1196,21 @@ function validateGridAxis(
|
|
|
812
1196
|
throw new Error(`${path}: expected ${indexing} ${axisName} coordinate within ${min}..${maxLabel}`);
|
|
813
1197
|
}
|
|
814
1198
|
}
|
|
815
|
-
|
|
816
|
-
function parsePanelLayoutKind(value: YamlValue | undefined, path: string): 'stompbox-grid' {
|
|
1199
|
+
function parsePanelLayoutKind(value, path) {
|
|
817
1200
|
const kind = expectString(value, path);
|
|
818
1201
|
if (kind === 'stompbox-grid') {
|
|
819
1202
|
return kind;
|
|
820
1203
|
}
|
|
821
1204
|
throw new Error(`${path}: expected stompbox-grid`);
|
|
822
1205
|
}
|
|
823
|
-
|
|
824
|
-
function parsePanelGridIndexing(value: YamlValue | undefined, path: string): PanelGridIndexing {
|
|
1206
|
+
function parsePanelGridIndexing(value, path) {
|
|
825
1207
|
const indexing = expectString(value, path);
|
|
826
1208
|
if (indexing === 'one-based' || indexing === 'zero-based') {
|
|
827
1209
|
return indexing;
|
|
828
1210
|
}
|
|
829
1211
|
throw new Error(`${path}: expected one-based or zero-based`);
|
|
830
1212
|
}
|
|
831
|
-
|
|
832
|
-
function parseOptionalPanelRowOrder(value: YamlValue | undefined, path: string): PanelRowOrder | undefined {
|
|
1213
|
+
function parseOptionalPanelRowOrder(value, path) {
|
|
833
1214
|
if (value === undefined) {
|
|
834
1215
|
return undefined;
|
|
835
1216
|
}
|
|
@@ -839,8 +1220,7 @@ function parseOptionalPanelRowOrder(value: YamlValue | undefined, path: string):
|
|
|
839
1220
|
}
|
|
840
1221
|
throw new Error(`${path}: expected top-to-bottom or bottom-to-top`);
|
|
841
1222
|
}
|
|
842
|
-
|
|
843
|
-
function parseOptionalPanelColumnOrder(value: YamlValue | undefined, path: string): PanelColumnOrder | undefined {
|
|
1223
|
+
function parseOptionalPanelColumnOrder(value, path) {
|
|
844
1224
|
if (value === undefined) {
|
|
845
1225
|
return undefined;
|
|
846
1226
|
}
|
|
@@ -850,22 +1230,22 @@ function parseOptionalPanelColumnOrder(value: YamlValue | undefined, path: strin
|
|
|
850
1230
|
}
|
|
851
1231
|
throw new Error(`${path}: expected left-to-right or right-to-left`);
|
|
852
1232
|
}
|
|
853
|
-
|
|
854
|
-
function parsePanelControlKind(value: YamlValue | undefined, path: string): PanelControlKind {
|
|
1233
|
+
function parsePanelControlKind(value, path) {
|
|
855
1234
|
const kind = expectString(value, path);
|
|
856
1235
|
switch (kind) {
|
|
857
1236
|
case 'knob':
|
|
858
1237
|
case 'slider':
|
|
859
1238
|
case 'switch':
|
|
1239
|
+
case 'selector':
|
|
1240
|
+
case 'footswitch':
|
|
860
1241
|
case 'led':
|
|
861
1242
|
case 'jack':
|
|
862
1243
|
return kind;
|
|
863
1244
|
default:
|
|
864
|
-
throw new Error(`${path}: expected knob, slider, switch, led, or jack`);
|
|
1245
|
+
throw new Error(`${path}: expected knob, slider, switch, selector, footswitch, led, or jack`);
|
|
865
1246
|
}
|
|
866
1247
|
}
|
|
867
|
-
|
|
868
|
-
function parseComponents(value: YamlValue | undefined): readonly Component[] {
|
|
1248
|
+
function parseComponents(value) {
|
|
869
1249
|
return optionalArray(value, 'components').map((item, index) => {
|
|
870
1250
|
const path = `components[${index}]`;
|
|
871
1251
|
const component = expectObject(item, path);
|
|
@@ -882,8 +1262,7 @@ function parseComponents(value: YamlValue | undefined): readonly Component[] {
|
|
|
882
1262
|
};
|
|
883
1263
|
});
|
|
884
1264
|
}
|
|
885
|
-
|
|
886
|
-
function parseTerminals(value: YamlValue | undefined, path: string): readonly Terminal[] {
|
|
1265
|
+
function parseTerminals(value, path) {
|
|
887
1266
|
return optionalArray(value, path).map((item, index) => {
|
|
888
1267
|
const terminalPath = `${path}[${index}]`;
|
|
889
1268
|
const terminal = expectObject(item, terminalPath);
|
|
@@ -893,17 +1272,15 @@ function parseTerminals(value: YamlValue | undefined, path: string): readonly Te
|
|
|
893
1272
|
};
|
|
894
1273
|
});
|
|
895
1274
|
}
|
|
896
|
-
|
|
897
|
-
function parseProperties(value: YamlValue | undefined, path: string): Readonly<Record<string, PropertyValue>> {
|
|
1275
|
+
function parseProperties(value, path) {
|
|
898
1276
|
const properties = optionalObject(value, path);
|
|
899
|
-
const out
|
|
1277
|
+
const out = {};
|
|
900
1278
|
for (const [key, child] of Object.entries(properties)) {
|
|
901
1279
|
out[key] = parsePropertyValue(child, `${path}.${key}`);
|
|
902
1280
|
}
|
|
903
1281
|
return out;
|
|
904
1282
|
}
|
|
905
|
-
|
|
906
|
-
function parsePropertyValue(value: YamlValue, path: string): PropertyValue {
|
|
1283
|
+
function parsePropertyValue(value, path) {
|
|
907
1284
|
if (isParsedQuantityValue(value)) {
|
|
908
1285
|
return {
|
|
909
1286
|
raw: expectString(value.raw, `${path}.raw`),
|
|
@@ -915,7 +1292,7 @@ function parsePropertyValue(value: YamlValue, path: string): PropertyValue {
|
|
|
915
1292
|
return value.map((item, index) => parsePropertyValue(item, `${path}[${index}]`));
|
|
916
1293
|
}
|
|
917
1294
|
if (isYamlObject(value)) {
|
|
918
|
-
const out
|
|
1295
|
+
const out = {};
|
|
919
1296
|
for (const [key, child] of Object.entries(value)) {
|
|
920
1297
|
out[key] = parsePropertyValue(child, `${path}.${key}`);
|
|
921
1298
|
}
|
|
@@ -926,12 +1303,10 @@ function parsePropertyValue(value: YamlValue, path: string): PropertyValue {
|
|
|
926
1303
|
}
|
|
927
1304
|
throw new Error(`${path}: expected scalar property value or parsed quantity`);
|
|
928
1305
|
}
|
|
929
|
-
|
|
930
|
-
function isParsedQuantityValue(value: YamlValue): value is ParsedQuantity {
|
|
1306
|
+
function isParsedQuantityValue(value) {
|
|
931
1307
|
return isParsedQuantity(value);
|
|
932
1308
|
}
|
|
933
|
-
|
|
934
|
-
function parseWires(value: YamlValue | undefined): readonly Wire[] {
|
|
1309
|
+
function parseWires(value) {
|
|
935
1310
|
return optionalArray(value, 'wires').map((item, index) => {
|
|
936
1311
|
const path = `wires[${index}]`;
|
|
937
1312
|
const wire = expectObject(item, path);
|
|
@@ -947,12 +1322,11 @@ function parseWires(value: YamlValue | undefined): readonly Wire[] {
|
|
|
947
1322
|
};
|
|
948
1323
|
});
|
|
949
1324
|
}
|
|
950
|
-
|
|
951
|
-
function parseWarnings(value: YamlValue | undefined): readonly Warning[] {
|
|
1325
|
+
function parseWarnings(value) {
|
|
952
1326
|
return optionalArray(value, 'diagnostics').map((item, index) => {
|
|
953
1327
|
const path = `diagnostics[${index}]`;
|
|
954
1328
|
const warning = expectObject(item, path);
|
|
955
|
-
const out
|
|
1329
|
+
const out = {
|
|
956
1330
|
code: expectString(warning.code, `${path}.code`),
|
|
957
1331
|
message: expectString(warning.message, `${path}.message`),
|
|
958
1332
|
...(warning.componentId === undefined
|
|
@@ -965,44 +1339,38 @@ function parseWarnings(value: YamlValue | undefined): readonly Warning[] {
|
|
|
965
1339
|
return out;
|
|
966
1340
|
});
|
|
967
1341
|
}
|
|
968
|
-
|
|
969
|
-
function parseStringArray(value: YamlValue | undefined, path: string): readonly string[] {
|
|
1342
|
+
function parseStringArray(value, path) {
|
|
970
1343
|
return optionalArray(value, path).map((item, index) => scalarText(item, `${path}[${index}]`));
|
|
971
1344
|
}
|
|
972
|
-
|
|
973
|
-
function parseStringRecord(value: YamlValue | undefined, path: string): Readonly<Record<string, string>> {
|
|
1345
|
+
function parseStringRecord(value, path) {
|
|
974
1346
|
const record = optionalObject(value, path);
|
|
975
|
-
const out
|
|
1347
|
+
const out = {};
|
|
976
1348
|
for (const [key, child] of Object.entries(record)) {
|
|
977
1349
|
out[key] = scalarText(child, `${path}.${key}`);
|
|
978
1350
|
}
|
|
979
1351
|
return out;
|
|
980
1352
|
}
|
|
981
|
-
|
|
982
|
-
function parsePoint(value: YamlValue | undefined, path: string): Point {
|
|
1353
|
+
function parsePoint(value, path) {
|
|
983
1354
|
const point = expectObject(value, path);
|
|
984
1355
|
return {
|
|
985
1356
|
x: expectNumber(point.x, `${path}.x`),
|
|
986
1357
|
y: expectNumber(point.y, `${path}.y`),
|
|
987
1358
|
};
|
|
988
1359
|
}
|
|
989
|
-
|
|
990
|
-
function parseRotation(value: YamlValue | undefined, path: string): Rotation {
|
|
1360
|
+
function parseRotation(value, path) {
|
|
991
1361
|
const rotation = expectNumber(value, path);
|
|
992
1362
|
if (rotation === 0 || rotation === 1 || rotation === 2 || rotation === 3) {
|
|
993
1363
|
return rotation;
|
|
994
1364
|
}
|
|
995
1365
|
throw new Error(`${path}: expected rotation 0, 1, 2, or 3`);
|
|
996
1366
|
}
|
|
997
|
-
|
|
998
|
-
function parseNullableString(value: YamlValue | undefined, path: string): string | null {
|
|
1367
|
+
function parseNullableString(value, path) {
|
|
999
1368
|
if (value === null || value === undefined) {
|
|
1000
1369
|
return null;
|
|
1001
1370
|
}
|
|
1002
1371
|
return expectString(value, path);
|
|
1003
1372
|
}
|
|
1004
|
-
|
|
1005
|
-
function parseComponentKind(value: YamlValue | undefined, path: string): ComponentKind {
|
|
1373
|
+
function parseComponentKind(value, path) {
|
|
1006
1374
|
const kind = expectString(value, path);
|
|
1007
1375
|
switch (kind) {
|
|
1008
1376
|
case 'resistor':
|
|
@@ -1045,108 +1413,93 @@ function parseComponentKind(value: YamlValue | undefined, path: string): Compone
|
|
|
1045
1413
|
throw new Error(`${path}: unsupported component kind "${kind}"`);
|
|
1046
1414
|
}
|
|
1047
1415
|
}
|
|
1048
|
-
|
|
1049
|
-
function optionalObject(value: YamlValue | undefined, path: string): YamlObject {
|
|
1416
|
+
function optionalObject(value, path) {
|
|
1050
1417
|
if (value === undefined) {
|
|
1051
1418
|
return {};
|
|
1052
1419
|
}
|
|
1053
1420
|
return expectObject(value, path);
|
|
1054
1421
|
}
|
|
1055
|
-
|
|
1056
|
-
function optionalArray(value: YamlValue | undefined, path: string): readonly YamlValue[] {
|
|
1422
|
+
function optionalArray(value, path) {
|
|
1057
1423
|
if (value === undefined) {
|
|
1058
1424
|
return [];
|
|
1059
1425
|
}
|
|
1060
1426
|
return expectArray(value, path);
|
|
1061
1427
|
}
|
|
1062
|
-
|
|
1063
|
-
function expectObject(value: YamlValue | undefined, path: string): YamlObject {
|
|
1428
|
+
function expectObject(value, path) {
|
|
1064
1429
|
if (isYamlObject(value)) {
|
|
1065
1430
|
return value;
|
|
1066
1431
|
}
|
|
1067
1432
|
throw new Error(`${path}: expected object`);
|
|
1068
1433
|
}
|
|
1069
|
-
|
|
1070
|
-
function expectArray(value: YamlValue | undefined, path: string): readonly YamlValue[] {
|
|
1434
|
+
function expectArray(value, path) {
|
|
1071
1435
|
if (Array.isArray(value)) {
|
|
1072
1436
|
return value;
|
|
1073
1437
|
}
|
|
1074
1438
|
throw new Error(`${path}: expected array`);
|
|
1075
1439
|
}
|
|
1076
|
-
|
|
1077
|
-
function expectString(value: YamlValue | undefined, path: string): string {
|
|
1440
|
+
function expectString(value, path) {
|
|
1078
1441
|
if (typeof value === 'string') {
|
|
1079
1442
|
return value;
|
|
1080
1443
|
}
|
|
1081
1444
|
throw new Error(`${path}: expected string`);
|
|
1082
1445
|
}
|
|
1083
|
-
|
|
1084
|
-
function expectNumber(value: YamlValue | undefined, path: string): number {
|
|
1446
|
+
function expectNumber(value, path) {
|
|
1085
1447
|
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
1086
1448
|
return value;
|
|
1087
1449
|
}
|
|
1088
1450
|
throw new Error(`${path}: expected number`);
|
|
1089
1451
|
}
|
|
1090
|
-
|
|
1091
|
-
function expectPositiveInteger(value: YamlValue | undefined, path: string): number {
|
|
1452
|
+
function expectPositiveInteger(value, path) {
|
|
1092
1453
|
const number = expectNumber(value, path);
|
|
1093
1454
|
if (Number.isInteger(number) && number > 0) {
|
|
1094
1455
|
return number;
|
|
1095
1456
|
}
|
|
1096
1457
|
throw new Error(`${path}: expected positive integer`);
|
|
1097
1458
|
}
|
|
1098
|
-
|
|
1099
|
-
function expectNonNegativeInteger(value: YamlValue | undefined, path: string): number {
|
|
1459
|
+
function expectNonNegativeInteger(value, path) {
|
|
1100
1460
|
const number = expectNumber(value, path);
|
|
1101
1461
|
if (Number.isInteger(number) && number >= 0) {
|
|
1102
1462
|
return number;
|
|
1103
1463
|
}
|
|
1104
1464
|
throw new Error(`${path}: expected non-negative integer`);
|
|
1105
1465
|
}
|
|
1106
|
-
|
|
1107
|
-
function parseOptionalPositiveInteger(value: YamlValue | undefined, path: string): number | undefined {
|
|
1466
|
+
function parseOptionalPositiveInteger(value, path) {
|
|
1108
1467
|
if (value === undefined) {
|
|
1109
1468
|
return undefined;
|
|
1110
1469
|
}
|
|
1111
1470
|
return expectPositiveInteger(value, path);
|
|
1112
1471
|
}
|
|
1113
|
-
|
|
1114
|
-
function parseOptionalNumber(value: YamlValue | undefined, path: string): number | undefined {
|
|
1472
|
+
function parseOptionalNumber(value, path) {
|
|
1115
1473
|
if (value === undefined) {
|
|
1116
1474
|
return undefined;
|
|
1117
1475
|
}
|
|
1118
1476
|
return expectNumber(value, path);
|
|
1119
1477
|
}
|
|
1120
|
-
|
|
1121
|
-
function parseOptionalString(value: YamlValue | undefined, path: string): string | undefined {
|
|
1478
|
+
function parseOptionalString(value, path) {
|
|
1122
1479
|
if (value === undefined) {
|
|
1123
1480
|
return undefined;
|
|
1124
1481
|
}
|
|
1125
1482
|
return expectString(value, path);
|
|
1126
1483
|
}
|
|
1127
|
-
|
|
1128
|
-
function parseOptionalStringArray(value: YamlValue | undefined, path: string): readonly string[] | undefined {
|
|
1484
|
+
function parseOptionalStringArray(value, path) {
|
|
1129
1485
|
if (value === undefined) {
|
|
1130
1486
|
return undefined;
|
|
1131
1487
|
}
|
|
1132
1488
|
return expectArray(value, path).map((item, index) => expectString(item, `${path}[${index}]`));
|
|
1133
1489
|
}
|
|
1134
|
-
|
|
1135
|
-
function parseOptionalBoolean(value: YamlValue | undefined, path: string): boolean | undefined {
|
|
1490
|
+
function parseOptionalBoolean(value, path) {
|
|
1136
1491
|
if (value === undefined) {
|
|
1137
1492
|
return undefined;
|
|
1138
1493
|
}
|
|
1139
1494
|
return expectBoolean(value, path);
|
|
1140
1495
|
}
|
|
1141
|
-
|
|
1142
|
-
function expectBoolean(value: YamlValue | undefined, path: string): boolean {
|
|
1496
|
+
function expectBoolean(value, path) {
|
|
1143
1497
|
if (typeof value === 'boolean') {
|
|
1144
1498
|
return value;
|
|
1145
1499
|
}
|
|
1146
1500
|
throw new Error(`${path}: expected boolean`);
|
|
1147
1501
|
}
|
|
1148
|
-
|
|
1149
|
-
function scalarText(value: YamlValue | undefined, path = 'value'): string {
|
|
1502
|
+
function scalarText(value, path = 'value') {
|
|
1150
1503
|
if (value === undefined || value === null) {
|
|
1151
1504
|
return '';
|
|
1152
1505
|
}
|
|
@@ -1155,11 +1508,10 @@ function scalarText(value: YamlValue | undefined, path = 'value'): string {
|
|
|
1155
1508
|
}
|
|
1156
1509
|
throw new Error(`${path}: expected scalar`);
|
|
1157
1510
|
}
|
|
1158
|
-
|
|
1159
|
-
function isScalar(value: YamlValue): value is YamlScalar {
|
|
1511
|
+
function isScalar(value) {
|
|
1160
1512
|
return value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean';
|
|
1161
1513
|
}
|
|
1162
|
-
|
|
1163
|
-
function isYamlObject(value: YamlValue | undefined): value is YamlObject {
|
|
1514
|
+
function isYamlObject(value) {
|
|
1164
1515
|
return value !== undefined && value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
1165
1516
|
}
|
|
1517
|
+
//# sourceMappingURL=parser.js.map
|