@vessel-dsp/core 0.6.4 → 0.6.6
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 -2
- package/dist/editor/commands.d.ts +13 -13
- package/dist/editor/commands.d.ts.map +1 -1
- package/dist/editor/commands.js +44 -29
- package/dist/editor/commands.js.map +1 -1
- package/dist/editor/factory.d.ts +1 -1
- package/dist/editor/factory.d.ts.map +1 -1
- package/dist/editor/factory.js +51 -51
- package/dist/editor/factory.js.map +1 -1
- package/dist/editor/history.d.ts +7 -7
- package/dist/editor/history.d.ts.map +1 -1
- package/dist/editor/history.js +20 -12
- package/dist/editor/history.js.map +1 -1
- package/dist/editor/index.d.ts +8 -8
- package/dist/editor/index.d.ts.map +1 -1
- package/dist/editor/index.js +4 -4
- package/dist/editor/index.js.map +1 -1
- package/dist/editor/layout.d.ts +1 -1
- package/dist/editor/layout.d.ts.map +1 -1
- package/dist/editor/layout.js +11 -6
- package/dist/editor/layout.js.map +1 -1
- package/dist/formats/circuit-json/serializer.d.ts +15 -15
- package/dist/formats/circuit-json/serializer.d.ts.map +1 -1
- package/dist/formats/circuit-json/serializer.js +486 -394
- package/dist/formats/circuit-json/serializer.js.map +1 -1
- package/dist/formats/document.d.ts +6 -6
- package/dist/formats/document.d.ts.map +1 -1
- package/dist/formats/document.js +112 -92
- package/dist/formats/document.js.map +1 -1
- package/dist/formats/interchange/parser.d.ts +1 -1
- package/dist/formats/interchange/parser.d.ts.map +1 -1
- package/dist/formats/interchange/parser.js +463 -286
- package/dist/formats/interchange/parser.js.map +1 -1
- package/dist/formats/interchange/serializer.d.ts +1 -1
- package/dist/formats/interchange/serializer.d.ts.map +1 -1
- package/dist/formats/interchange/serializer.js +41 -28
- package/dist/formats/interchange/serializer.js.map +1 -1
- package/dist/formats/ltspice/catalog.d.ts +1 -1
- package/dist/formats/ltspice/catalog.d.ts.map +1 -1
- package/dist/formats/ltspice/catalog.js +150 -48
- package/dist/formats/ltspice/catalog.js.map +1 -1
- package/dist/formats/ltspice/encoding.js +12 -40
- package/dist/formats/ltspice/encoding.js.map +1 -1
- package/dist/formats/ltspice/parser.d.ts +1 -1
- package/dist/formats/ltspice/parser.d.ts.map +1 -1
- package/dist/formats/ltspice/parser.js +122 -75
- package/dist/formats/ltspice/parser.js.map +1 -1
- package/dist/formats/ltspice/serializer.d.ts +1 -1
- package/dist/formats/ltspice/serializer.d.ts.map +1 -1
- package/dist/formats/ltspice/serializer.js +69 -47
- package/dist/formats/ltspice/serializer.js.map +1 -1
- package/dist/formats/schx/catalog.d.ts +1 -1
- package/dist/formats/schx/catalog.d.ts.map +1 -1
- package/dist/formats/schx/catalog.js +499 -254
- package/dist/formats/schx/catalog.js.map +1 -1
- package/dist/formats/schx/parser.d.ts +1 -1
- package/dist/formats/schx/parser.d.ts.map +1 -1
- package/dist/formats/schx/parser.js +40 -38
- package/dist/formats/schx/parser.js.map +1 -1
- package/dist/formats/schx/runtime-descriptors.d.ts +1 -1
- package/dist/formats/schx/runtime-descriptors.d.ts.map +1 -1
- package/dist/formats/schx/runtime-descriptors.js +239 -201
- package/dist/formats/schx/runtime-descriptors.js.map +1 -1
- package/dist/formats/schx/serializer.d.ts +2 -2
- package/dist/formats/schx/serializer.d.ts.map +1 -1
- package/dist/formats/schx/serializer.js +106 -106
- package/dist/formats/schx/serializer.js.map +1 -1
- package/dist/formats/schx/transforms.d.ts +1 -1
- package/dist/formats/schx/transforms.d.ts.map +1 -1
- package/dist/formats/schx/transforms.js +16 -8
- package/dist/formats/schx/transforms.js.map +1 -1
- package/dist/formats/spice/parser.d.ts +1 -1
- package/dist/formats/spice/parser.d.ts.map +1 -1
- package/dist/formats/spice/parser.js +105 -56
- package/dist/formats/spice/parser.js.map +1 -1
- package/dist/formats/spice/serializer.d.ts +1 -1
- package/dist/formats/spice/serializer.js +14 -12
- package/dist/formats/spice/serializer.js.map +1 -1
- package/dist/index.d.ts +47 -46
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -31
- package/dist/index.js.map +1 -1
- package/dist/model/connectivity.d.ts +1 -1
- package/dist/model/connectivity.d.ts.map +1 -1
- package/dist/model/connectivity.js +22 -7
- package/dist/model/connectivity.js.map +1 -1
- package/dist/model/netlist.d.ts +3 -3
- package/dist/model/netlist.d.ts.map +1 -1
- package/dist/model/netlist.js +117 -100
- package/dist/model/netlist.js.map +1 -1
- package/dist/model/properties.d.ts +1 -1
- package/dist/model/properties.d.ts.map +1 -1
- package/dist/model/properties.js +16 -16
- package/dist/model/properties.js.map +1 -1
- package/dist/model/quantity.d.ts +1 -1
- package/dist/model/quantity.d.ts.map +1 -1
- package/dist/model/quantity.js +35 -35
- package/dist/model/quantity.js.map +1 -1
- package/dist/model/types.d.ts +61 -33
- package/dist/model/types.d.ts.map +1 -1
- package/dist/model/types.js +1 -1
- package/dist/model/types.js.map +1 -1
- package/dist/model/validation.d.ts +5 -5
- package/dist/model/validation.d.ts.map +1 -1
- package/dist/model/validation.js +668 -331
- package/dist/model/validation.js.map +1 -1
- package/dist/model/wires.d.ts +1 -1
- package/dist/model/wires.d.ts.map +1 -1
- package/dist/model/wires.js +4 -1
- package/dist/model/wires.js.map +1 -1
- package/dist/panel/extract.d.ts +2 -2
- package/dist/panel/extract.d.ts.map +1 -1
- package/dist/panel/extract.js +327 -225
- package/dist/panel/extract.js.map +1 -1
- package/dist/panel/index.d.ts +7 -7
- package/dist/panel/index.d.ts.map +1 -1
- package/dist/panel/index.js +5 -5
- package/dist/panel/index.js.map +1 -1
- package/dist/panel/knobs.d.ts +4 -4
- package/dist/panel/knobs.d.ts.map +1 -1
- package/dist/panel/knobs.js +1 -1
- package/dist/panel/knobs.js.map +1 -1
- package/dist/panel/placement.d.ts +1 -1
- package/dist/panel/placement.d.ts.map +1 -1
- package/dist/panel/placement.js +11 -9
- package/dist/panel/placement.js.map +1 -1
- package/dist/panel/protocol.d.ts +1 -1
- package/dist/panel/protocol.d.ts.map +1 -1
- package/dist/panel/protocol.js +32 -23
- package/dist/panel/protocol.js.map +1 -1
- package/dist/panel/types.d.ts +18 -18
- package/dist/panel/types.d.ts.map +1 -1
- package/dist/panel/types.js.map +1 -1
- package/dist/preview/bounds.d.ts +1 -1
- package/dist/preview/bounds.d.ts.map +1 -1
- package/dist/preview/bounds.js +3 -3
- package/dist/preview/bounds.js.map +1 -1
- package/dist/preview/box-layout.d.ts +2 -2
- package/dist/preview/box-layout.js.map +1 -1
- package/dist/preview/colors.d.ts +1 -1
- package/dist/preview/colors.js +35 -35
- package/dist/preview/colors.js.map +1 -1
- package/dist/preview/hanging.d.ts +1 -1
- package/dist/preview/hanging.d.ts.map +1 -1
- package/dist/preview/hanging.js +4 -1
- package/dist/preview/hanging.js.map +1 -1
- package/dist/preview/junctions.d.ts +1 -1
- package/dist/preview/junctions.d.ts.map +1 -1
- package/dist/preview/junctions.js.map +1 -1
- package/dist/preview/label-layout.d.ts.map +1 -1
- package/dist/preview/label-layout.js +4 -4
- package/dist/preview/label-layout.js.map +1 -1
- package/dist/preview/ports.d.ts +1 -1
- package/dist/preview/ports.d.ts.map +1 -1
- package/dist/preview/ports.js +2 -1
- package/dist/preview/ports.js.map +1 -1
- package/dist/preview/renderable-wires.d.ts +1 -1
- package/dist/preview/renderable-wires.d.ts.map +1 -1
- package/dist/preview/renderable-wires.js +3 -1
- package/dist/preview/renderable-wires.js.map +1 -1
- package/dist/preview/routing.d.ts +1 -1
- package/dist/preview/routing.js +1 -1
- package/dist/preview/routing.js.map +1 -1
- package/dist/preview/snap.d.ts +1 -1
- package/dist/preview/snap.d.ts.map +1 -1
- package/dist/preview/snap.js +11 -3
- package/dist/preview/snap.js.map +1 -1
- package/dist/preview/symbols/svg-content.d.ts.map +1 -1
- package/dist/preview/symbols/svg-content.js +200 -50
- package/dist/preview/symbols/svg-content.js.map +1 -1
- package/dist/preview/symbols.d.ts +2 -2
- package/dist/preview/symbols.d.ts.map +1 -1
- package/dist/preview/symbols.js +100 -97
- package/dist/preview/symbols.js.map +1 -1
- package/dist/preview/wire-chains.d.ts +1 -1
- package/dist/preview/wire-chains.d.ts.map +1 -1
- package/dist/preview/wire-chains.js.map +1 -1
- package/dist/profiles.d.ts +600 -0
- package/dist/profiles.d.ts.map +1 -0
- package/dist/profiles.js +118 -0
- package/dist/profiles.js.map +1 -0
- package/package.json +54 -54
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { isParsedQuantity } from
|
|
2
|
-
const INTERCHANGE_SCHEMA_V2 =
|
|
3
|
-
const INTERCHANGE_SCHEMA_V3 =
|
|
1
|
+
import { isParsedQuantity } from "../../model/properties.js";
|
|
2
|
+
const INTERCHANGE_SCHEMA_V2 = "circuit-interchange/v2";
|
|
3
|
+
const INTERCHANGE_SCHEMA_V3 = "circuit-interchange/v3";
|
|
4
4
|
const V3_ONLY_TOP_LEVEL_FIELDS = [
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
"mechanical",
|
|
6
|
+
"build",
|
|
7
|
+
"bom",
|
|
8
|
+
"partProfiles",
|
|
9
|
+
"footprints",
|
|
10
|
+
"offBoardWiring",
|
|
11
|
+
"boards",
|
|
12
12
|
];
|
|
13
13
|
export function parseInterchangeYaml(source) {
|
|
14
14
|
const value = parseYamlSubset(source);
|
|
15
|
-
const root = expectObject(value,
|
|
16
|
-
const schema = expectString(root.schema,
|
|
15
|
+
const root = expectObject(value, "root");
|
|
16
|
+
const schema = expectString(root.schema, "schema");
|
|
17
17
|
if (schema !== INTERCHANGE_SCHEMA_V2 && schema !== INTERCHANGE_SCHEMA_V3) {
|
|
18
18
|
throw new Error(`unsupported interchange schema: ${schema}`);
|
|
19
19
|
}
|
|
@@ -33,7 +33,9 @@ export function parseInterchangeYaml(source) {
|
|
|
33
33
|
const bom = isV3 ? parseBom(root.bom) : undefined;
|
|
34
34
|
const partProfiles = isV3 ? parsePartProfiles(root.partProfiles) : undefined;
|
|
35
35
|
const footprints = isV3 ? parseFootprints(root.footprints) : undefined;
|
|
36
|
-
const offBoardWiring = isV3
|
|
36
|
+
const offBoardWiring = isV3
|
|
37
|
+
? parseOffBoardWiring(root.offBoardWiring)
|
|
38
|
+
: undefined;
|
|
37
39
|
const boards = isV3 ? parseBoards(root.boards) : undefined;
|
|
38
40
|
return {
|
|
39
41
|
metadata: parseMetadata(root.metadata),
|
|
@@ -54,9 +56,9 @@ export function parseInterchangeYaml(source) {
|
|
|
54
56
|
...(controlOutputs === undefined ? {} : { controlOutputs }),
|
|
55
57
|
components: parseComponents(root.components),
|
|
56
58
|
wires: parseWires(root.wires),
|
|
57
|
-
directives: parseStringArray(root.directives,
|
|
59
|
+
directives: parseStringArray(root.directives, "directives"),
|
|
58
60
|
warnings: parseWarnings(root.diagnostics),
|
|
59
|
-
rawAttributes: parseStringRecord(root.rawAttributes,
|
|
61
|
+
rawAttributes: parseStringRecord(root.rawAttributes, "rawAttributes"),
|
|
60
62
|
};
|
|
61
63
|
}
|
|
62
64
|
function rejectV3OnlyTopLevelFields(root) {
|
|
@@ -70,49 +72,64 @@ function parseMechanical(value) {
|
|
|
70
72
|
if (value === undefined) {
|
|
71
73
|
return undefined;
|
|
72
74
|
}
|
|
73
|
-
const mechanical = expectObject(value,
|
|
75
|
+
const mechanical = expectObject(value, "mechanical");
|
|
74
76
|
return {
|
|
75
|
-
...parseBuildDataObject(mechanical,
|
|
76
|
-
...(mechanical.schema === undefined
|
|
77
|
-
|
|
77
|
+
...parseBuildDataObject(mechanical, "mechanical"),
|
|
78
|
+
...(mechanical.schema === undefined
|
|
79
|
+
? {}
|
|
80
|
+
: { schema: expectString(mechanical.schema, "mechanical.schema") }),
|
|
81
|
+
...(mechanical.units === undefined
|
|
82
|
+
? {}
|
|
83
|
+
: { units: expectString(mechanical.units, "mechanical.units") }),
|
|
78
84
|
};
|
|
79
85
|
}
|
|
80
86
|
function parseBuild(value) {
|
|
81
87
|
if (value === undefined) {
|
|
82
88
|
return undefined;
|
|
83
89
|
}
|
|
84
|
-
const build = expectObject(value,
|
|
90
|
+
const build = expectObject(value, "build");
|
|
85
91
|
return {
|
|
86
|
-
...parseBuildDataObject(build,
|
|
87
|
-
schema: parseLiteralString(build.schema,
|
|
88
|
-
...(build.intent === undefined
|
|
92
|
+
...parseBuildDataObject(build, "build"),
|
|
93
|
+
schema: parseLiteralString(build.schema, "build.schema", "build-scope/v1"),
|
|
94
|
+
...(build.intent === undefined
|
|
95
|
+
? {}
|
|
96
|
+
: { intent: parseBuildIntent(build.intent, "build.intent") }),
|
|
89
97
|
...(build.completeness === undefined
|
|
90
98
|
? {}
|
|
91
|
-
: {
|
|
99
|
+
: {
|
|
100
|
+
completeness: parseBuildCompleteness(build.completeness, "build.completeness"),
|
|
101
|
+
}),
|
|
92
102
|
...(build.selectedBoardId === undefined
|
|
93
103
|
? {}
|
|
94
|
-
: {
|
|
104
|
+
: {
|
|
105
|
+
selectedBoardId: expectString(build.selectedBoardId, "build.selectedBoardId"),
|
|
106
|
+
}),
|
|
95
107
|
...(build.selectedOffBoardWiringHarnessIds === undefined
|
|
96
108
|
? {}
|
|
97
109
|
: {
|
|
98
|
-
selectedOffBoardWiringHarnessIds: parseOptionalStringArray(build.selectedOffBoardWiringHarnessIds,
|
|
110
|
+
selectedOffBoardWiringHarnessIds: parseOptionalStringArray(build.selectedOffBoardWiringHarnessIds, "build.selectedOffBoardWiringHarnessIds") ?? [],
|
|
99
111
|
}),
|
|
100
112
|
...(build.alternateBoardIds === undefined
|
|
101
113
|
? {}
|
|
102
|
-
: {
|
|
103
|
-
|
|
114
|
+
: {
|
|
115
|
+
alternateBoardIds: parseOptionalStringArray(build.alternateBoardIds, "build.alternateBoardIds") ?? [],
|
|
116
|
+
}),
|
|
117
|
+
...(build.bomScope === undefined
|
|
118
|
+
? {}
|
|
119
|
+
: { bomScope: expectString(build.bomScope, "build.bomScope") }),
|
|
104
120
|
};
|
|
105
121
|
}
|
|
106
122
|
function parseBuildIntent(value, path) {
|
|
107
123
|
const intent = expectString(value, path);
|
|
108
|
-
if (intent ===
|
|
124
|
+
if (intent === "diy-build-artifact" || intent === "schema-review-sample") {
|
|
109
125
|
return intent;
|
|
110
126
|
}
|
|
111
127
|
throw new Error(`${path}: expected diy-build-artifact or schema-review-sample`);
|
|
112
128
|
}
|
|
113
129
|
function parseBuildCompleteness(value, path) {
|
|
114
130
|
const completeness = expectString(value, path);
|
|
115
|
-
if (completeness ===
|
|
131
|
+
if (completeness === "complete-selected-build" ||
|
|
132
|
+
completeness === "partial-offboard-wiring") {
|
|
116
133
|
return completeness;
|
|
117
134
|
}
|
|
118
135
|
throw new Error(`${path}: expected complete-selected-build or partial-offboard-wiring`);
|
|
@@ -121,11 +138,11 @@ function parseBom(value) {
|
|
|
121
138
|
if (value === undefined) {
|
|
122
139
|
return undefined;
|
|
123
140
|
}
|
|
124
|
-
const bom = expectObject(value,
|
|
141
|
+
const bom = expectObject(value, "bom");
|
|
125
142
|
return {
|
|
126
|
-
...parseBuildDataObject(bom,
|
|
127
|
-
schema: parseLiteralString(bom.schema,
|
|
128
|
-
items: optionalArray(bom.items,
|
|
143
|
+
...parseBuildDataObject(bom, "bom"),
|
|
144
|
+
schema: parseLiteralString(bom.schema, "bom.schema", "build-bom/v1"),
|
|
145
|
+
items: optionalArray(bom.items, "bom.items").map(parseBomItem),
|
|
129
146
|
};
|
|
130
147
|
}
|
|
131
148
|
function parseBomItem(value, index) {
|
|
@@ -136,33 +153,53 @@ function parseBomItem(value, index) {
|
|
|
136
153
|
id: expectString(item.id, `${path}.id`),
|
|
137
154
|
refs: optionalArray(item.refs, `${path}.refs`).map((ref, refIndex) => parseBomRef(ref, `${path}.refs[${refIndex}]`)),
|
|
138
155
|
quantity: expectNumber(item.quantity, `${path}.quantity`),
|
|
139
|
-
...(item.value === undefined
|
|
156
|
+
...(item.value === undefined
|
|
157
|
+
? {}
|
|
158
|
+
: { value: expectString(item.value, `${path}.value`) }),
|
|
140
159
|
...(item.partProfileId === undefined
|
|
141
160
|
? {}
|
|
142
|
-
: {
|
|
143
|
-
|
|
144
|
-
|
|
161
|
+
: {
|
|
162
|
+
partProfileId: expectString(item.partProfileId, `${path}.partProfileId`),
|
|
163
|
+
}),
|
|
164
|
+
...(item.category === undefined
|
|
165
|
+
? {}
|
|
166
|
+
: { category: expectString(item.category, `${path}.category`) }),
|
|
167
|
+
...(item.sku === undefined
|
|
168
|
+
? {}
|
|
169
|
+
: { sku: expectString(item.sku, `${path}.sku`) }),
|
|
145
170
|
};
|
|
146
171
|
}
|
|
147
172
|
function parseBomRef(value, path) {
|
|
148
173
|
const ref = expectObject(value, path);
|
|
149
174
|
const kind = expectString(ref.kind, `${path}.kind`);
|
|
150
175
|
switch (kind) {
|
|
151
|
-
case
|
|
152
|
-
case
|
|
153
|
-
case
|
|
154
|
-
case
|
|
155
|
-
case
|
|
176
|
+
case "component":
|
|
177
|
+
case "device-interface-control":
|
|
178
|
+
case "panel-element":
|
|
179
|
+
case "board":
|
|
180
|
+
case "freeform-build-item":
|
|
156
181
|
return {
|
|
157
182
|
...parseBuildDataObject(ref, path),
|
|
158
183
|
kind,
|
|
159
|
-
...(ref.componentId === undefined
|
|
160
|
-
|
|
184
|
+
...(ref.componentId === undefined
|
|
185
|
+
? {}
|
|
186
|
+
: {
|
|
187
|
+
componentId: expectString(ref.componentId, `${path}.componentId`),
|
|
188
|
+
}),
|
|
189
|
+
...(ref.controlId === undefined
|
|
190
|
+
? {}
|
|
191
|
+
: { controlId: expectString(ref.controlId, `${path}.controlId`) }),
|
|
161
192
|
...(ref.panelElementId === undefined
|
|
162
193
|
? {}
|
|
163
|
-
: {
|
|
164
|
-
|
|
165
|
-
|
|
194
|
+
: {
|
|
195
|
+
panelElementId: expectString(ref.panelElementId, `${path}.panelElementId`),
|
|
196
|
+
}),
|
|
197
|
+
...(ref.boardId === undefined
|
|
198
|
+
? {}
|
|
199
|
+
: { boardId: expectString(ref.boardId, `${path}.boardId`) }),
|
|
200
|
+
...(ref.label === undefined
|
|
201
|
+
? {}
|
|
202
|
+
: { label: expectString(ref.label, `${path}.label`) }),
|
|
166
203
|
};
|
|
167
204
|
default:
|
|
168
205
|
throw new Error(`${path}.kind: expected component, device-interface-control, panel-element, board, or freeform-build-item`);
|
|
@@ -172,15 +209,19 @@ function parsePartProfiles(value) {
|
|
|
172
209
|
if (value === undefined) {
|
|
173
210
|
return undefined;
|
|
174
211
|
}
|
|
175
|
-
const catalog = expectObject(value,
|
|
212
|
+
const catalog = expectObject(value, "partProfiles");
|
|
176
213
|
return {
|
|
177
|
-
...parseBuildDataObject(catalog,
|
|
178
|
-
schema: parseLiteralString(catalog.schema,
|
|
214
|
+
...parseBuildDataObject(catalog, "partProfiles"),
|
|
215
|
+
schema: parseLiteralString(catalog.schema, "partProfiles.schema", "part-profile-catalog/v1"),
|
|
179
216
|
...(catalog.resolution === undefined
|
|
180
217
|
? {}
|
|
181
|
-
: {
|
|
182
|
-
|
|
183
|
-
|
|
218
|
+
: {
|
|
219
|
+
resolution: expectString(catalog.resolution, "partProfiles.resolution"),
|
|
220
|
+
}),
|
|
221
|
+
...(catalog.units === undefined
|
|
222
|
+
? {}
|
|
223
|
+
: { units: expectString(catalog.units, "partProfiles.units") }),
|
|
224
|
+
profiles: optionalArray(catalog.profiles, "partProfiles.profiles").map((profile, index) => parsePartProfile(profile, index)),
|
|
184
225
|
};
|
|
185
226
|
}
|
|
186
227
|
function parsePartProfile(value, index) {
|
|
@@ -189,20 +230,28 @@ function parsePartProfile(value, index) {
|
|
|
189
230
|
return {
|
|
190
231
|
...parseBuildDataObject(profile, path),
|
|
191
232
|
id: expectString(profile.id, `${path}.id`),
|
|
192
|
-
...(profile.kind === undefined
|
|
233
|
+
...(profile.kind === undefined
|
|
234
|
+
? {}
|
|
235
|
+
: { kind: expectString(profile.kind, `${path}.kind`) }),
|
|
193
236
|
};
|
|
194
237
|
}
|
|
195
238
|
function parseFootprints(value) {
|
|
196
239
|
if (value === undefined) {
|
|
197
240
|
return undefined;
|
|
198
241
|
}
|
|
199
|
-
const catalog = expectObject(value,
|
|
242
|
+
const catalog = expectObject(value, "footprints");
|
|
200
243
|
return {
|
|
201
|
-
...parseBuildDataObject(catalog,
|
|
202
|
-
schema: parseLiteralString(catalog.schema,
|
|
203
|
-
...(catalog.resolution === undefined
|
|
204
|
-
|
|
205
|
-
|
|
244
|
+
...parseBuildDataObject(catalog, "footprints"),
|
|
245
|
+
schema: parseLiteralString(catalog.schema, "footprints.schema", "board-footprint-catalog/v1"),
|
|
246
|
+
...(catalog.resolution === undefined
|
|
247
|
+
? {}
|
|
248
|
+
: {
|
|
249
|
+
resolution: expectString(catalog.resolution, "footprints.resolution"),
|
|
250
|
+
}),
|
|
251
|
+
...(catalog.units === undefined
|
|
252
|
+
? {}
|
|
253
|
+
: { units: expectString(catalog.units, "footprints.units") }),
|
|
254
|
+
footprints: optionalArray(catalog.footprints, "footprints.footprints").map((footprint, index) => parseFootprint(footprint, index)),
|
|
206
255
|
};
|
|
207
256
|
}
|
|
208
257
|
function parseFootprint(value, index) {
|
|
@@ -213,7 +262,9 @@ function parseFootprint(value, index) {
|
|
|
213
262
|
id: expectString(footprint.id, `${path}.id`),
|
|
214
263
|
...(footprint.boardApplicability === undefined
|
|
215
264
|
? {}
|
|
216
|
-
: {
|
|
265
|
+
: {
|
|
266
|
+
boardApplicability: parseBoardApplicability(footprint.boardApplicability, `${path}.boardApplicability`),
|
|
267
|
+
}),
|
|
217
268
|
};
|
|
218
269
|
}
|
|
219
270
|
function parseBoardApplicability(value, path) {
|
|
@@ -224,27 +275,34 @@ function parseBoardApplicability(value, path) {
|
|
|
224
275
|
kind: parseBoardKind(applicability.kind, `${path}.kind`),
|
|
225
276
|
...(applicability.subtype === undefined
|
|
226
277
|
? {}
|
|
227
|
-
: {
|
|
278
|
+
: {
|
|
279
|
+
subtype: parseBoardSubtype(applicability.subtype, `${path}.subtype`),
|
|
280
|
+
}),
|
|
228
281
|
};
|
|
229
282
|
}
|
|
230
283
|
function parseOffBoardWiring(value) {
|
|
231
284
|
if (value === undefined) {
|
|
232
285
|
return undefined;
|
|
233
286
|
}
|
|
234
|
-
const plan = expectObject(value,
|
|
287
|
+
const plan = expectObject(value, "offBoardWiring");
|
|
235
288
|
return {
|
|
236
|
-
...parseBuildDataObject(plan,
|
|
237
|
-
schema: parseLiteralString(plan.schema,
|
|
238
|
-
...(plan.source === undefined
|
|
289
|
+
...parseBuildDataObject(plan, "offBoardWiring"),
|
|
290
|
+
schema: parseLiteralString(plan.schema, "offBoardWiring.schema", "offboard-wiring/v1"),
|
|
291
|
+
...(plan.source === undefined
|
|
292
|
+
? {}
|
|
293
|
+
: { source: expectString(plan.source, "offBoardWiring.source") }),
|
|
239
294
|
...(plan.coverage === undefined
|
|
240
295
|
? {}
|
|
241
|
-
: {
|
|
242
|
-
|
|
296
|
+
: {
|
|
297
|
+
coverage: parseOffBoardWiringCoverage(plan.coverage, "offBoardWiring.coverage"),
|
|
298
|
+
}),
|
|
299
|
+
harnesses: optionalArray(plan.harnesses, "offBoardWiring.harnesses").map(parseOffBoardWiringHarness),
|
|
243
300
|
};
|
|
244
301
|
}
|
|
245
302
|
function parseOffBoardWiringCoverage(value, path) {
|
|
246
303
|
const coverage = expectString(value, path);
|
|
247
|
-
if (coverage ===
|
|
304
|
+
if (coverage === "selected-build-complete" ||
|
|
305
|
+
coverage === "representative-selected-build-endpoints") {
|
|
248
306
|
return coverage;
|
|
249
307
|
}
|
|
250
308
|
throw new Error(`${path}: expected selected-build-complete or representative-selected-build-endpoints`);
|
|
@@ -257,15 +315,19 @@ function parseOffBoardWiringHarness(value, index) {
|
|
|
257
315
|
id: expectString(harness.id, `${path}.id`),
|
|
258
316
|
...(harness.status === undefined
|
|
259
317
|
? {}
|
|
260
|
-
: {
|
|
261
|
-
|
|
318
|
+
: {
|
|
319
|
+
status: parseOffBoardWiringHarnessStatus(harness.status, `${path}.status`),
|
|
320
|
+
}),
|
|
321
|
+
...(harness.notes === undefined
|
|
322
|
+
? {}
|
|
323
|
+
: { notes: expectString(harness.notes, `${path}.notes`) }),
|
|
262
324
|
endpoints: optionalArray(harness.endpoints, `${path}.endpoints`).map((endpoint, endpointIndex) => parseOffBoardWiringEndpoint(endpoint, `${path}.endpoints[${endpointIndex}]`)),
|
|
263
325
|
connections: optionalArray(harness.connections, `${path}.connections`).map((connection, connectionIndex) => parseOffBoardWiringConnection(connection, `${path}.connections[${connectionIndex}]`)),
|
|
264
326
|
};
|
|
265
327
|
}
|
|
266
328
|
function parseOffBoardWiringHarnessStatus(value, path) {
|
|
267
329
|
const status = expectString(value, path);
|
|
268
|
-
if (status ===
|
|
330
|
+
if (status === "complete" || status === "partial" || status === "candidate") {
|
|
269
331
|
return status;
|
|
270
332
|
}
|
|
271
333
|
throw new Error(`${path}: expected complete, partial, or candidate`);
|
|
@@ -274,29 +336,41 @@ function parseOffBoardWiringEndpoint(value, path) {
|
|
|
274
336
|
const endpoint = expectObject(value, path);
|
|
275
337
|
const kind = expectString(endpoint.kind, `${path}.kind`);
|
|
276
338
|
switch (kind) {
|
|
277
|
-
case
|
|
278
|
-
case
|
|
279
|
-
case
|
|
280
|
-
case
|
|
281
|
-
case
|
|
339
|
+
case "panel-component-terminal":
|
|
340
|
+
case "board-terminal":
|
|
341
|
+
case "power-terminal":
|
|
342
|
+
case "footswitch-terminal":
|
|
343
|
+
case "free-wire-label":
|
|
282
344
|
return {
|
|
283
345
|
...parseBuildDataObject(endpoint, path),
|
|
284
346
|
id: expectString(endpoint.id, `${path}.id`),
|
|
285
347
|
kind,
|
|
286
348
|
...(endpoint.componentId === undefined
|
|
287
349
|
? {}
|
|
288
|
-
: {
|
|
350
|
+
: {
|
|
351
|
+
componentId: expectString(endpoint.componentId, `${path}.componentId`),
|
|
352
|
+
}),
|
|
289
353
|
...(endpoint.terminalName === undefined
|
|
290
354
|
? {}
|
|
291
|
-
: {
|
|
355
|
+
: {
|
|
356
|
+
terminalName: expectString(endpoint.terminalName, `${path}.terminalName`),
|
|
357
|
+
}),
|
|
292
358
|
...(endpoint.panelElementId === undefined
|
|
293
359
|
? {}
|
|
294
|
-
: {
|
|
295
|
-
|
|
360
|
+
: {
|
|
361
|
+
panelElementId: expectString(endpoint.panelElementId, `${path}.panelElementId`),
|
|
362
|
+
}),
|
|
363
|
+
...(endpoint.boardId === undefined
|
|
364
|
+
? {}
|
|
365
|
+
: { boardId: expectString(endpoint.boardId, `${path}.boardId`) }),
|
|
296
366
|
...(endpoint.terminalId === undefined
|
|
297
367
|
? {}
|
|
298
|
-
: {
|
|
299
|
-
|
|
368
|
+
: {
|
|
369
|
+
terminalId: expectString(endpoint.terminalId, `${path}.terminalId`),
|
|
370
|
+
}),
|
|
371
|
+
...(endpoint.label === undefined
|
|
372
|
+
? {}
|
|
373
|
+
: { label: expectString(endpoint.label, `${path}.label`) }),
|
|
300
374
|
};
|
|
301
375
|
default:
|
|
302
376
|
throw new Error(`${path}.kind: expected a supported off-board wiring endpoint kind`);
|
|
@@ -311,15 +385,19 @@ function parseOffBoardWiringConnection(value, path) {
|
|
|
311
385
|
toEndpointId: expectString(connection.toEndpointId, `${path}.toEndpointId`),
|
|
312
386
|
...(connection.signalRef === undefined
|
|
313
387
|
? {}
|
|
314
|
-
: {
|
|
315
|
-
|
|
388
|
+
: {
|
|
389
|
+
signalRef: parseBuildDataObject(connection.signalRef, `${path}.signalRef`),
|
|
390
|
+
}),
|
|
391
|
+
...(connection.wire === undefined
|
|
392
|
+
? {}
|
|
393
|
+
: { wire: parseBuildDataObject(connection.wire, `${path}.wire`) }),
|
|
316
394
|
};
|
|
317
395
|
}
|
|
318
396
|
function parseBoards(value) {
|
|
319
397
|
if (value === undefined) {
|
|
320
398
|
return undefined;
|
|
321
399
|
}
|
|
322
|
-
return optionalArray(value,
|
|
400
|
+
return optionalArray(value, "boards").map(parseBoard);
|
|
323
401
|
}
|
|
324
402
|
function parseBoard(value, index) {
|
|
325
403
|
const path = `boards[${index}]`;
|
|
@@ -330,21 +408,37 @@ function parseBoard(value, index) {
|
|
|
330
408
|
return {
|
|
331
409
|
...parseBuildDataObject(board, path),
|
|
332
410
|
id: expectString(board.id, `${path}.id`),
|
|
333
|
-
schema: parseLiteralString(board.schema, `${path}.schema`,
|
|
411
|
+
schema: parseLiteralString(board.schema, `${path}.schema`, "circuit-board/v1"),
|
|
334
412
|
family: parseBoardFamily(board.family, `${path}.family`),
|
|
335
413
|
kind: parseBoardKind(board.kind, `${path}.kind`),
|
|
336
|
-
...(board.subtype === undefined
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
...(board.
|
|
414
|
+
...(board.subtype === undefined
|
|
415
|
+
? {}
|
|
416
|
+
: { subtype: parseBoardSubtype(board.subtype, `${path}.subtype`) }),
|
|
417
|
+
...(board.source === undefined
|
|
418
|
+
? {}
|
|
419
|
+
: { source: expectString(board.source, `${path}.source`) }),
|
|
420
|
+
...(board.units === undefined
|
|
421
|
+
? {}
|
|
422
|
+
: { units: expectString(board.units, `${path}.units`) }),
|
|
423
|
+
...(board.locked === undefined
|
|
424
|
+
? {}
|
|
425
|
+
: { locked: expectBoolean(board.locked, `${path}.locked`) }),
|
|
340
426
|
...(sourceCircuit === undefined ? {} : { sourceCircuit }),
|
|
341
427
|
edgeTerminals: optionalArray(board.edgeTerminals, `${path}.edgeTerminals`).map((terminal, terminalIndex) => parseBoardEdgeTerminal(terminal, `${path}.edgeTerminals[${terminalIndex}]`)),
|
|
342
428
|
footprintPlacements: optionalArray(board.footprintPlacements, `${path}.footprintPlacements`).map((placement, placementIndex) => parseBoardFootprintPlacement(placement, `${path}.footprintPlacements[${placementIndex}]`)),
|
|
343
|
-
...(board.netlist === undefined
|
|
429
|
+
...(board.netlist === undefined
|
|
430
|
+
? {}
|
|
431
|
+
: { netlist: parseBoardNetlist(board.netlist, `${path}.netlist`) }),
|
|
344
432
|
routes: optionalArray(board.routes, `${path}.routes`).map((route, routeIndex) => parseBoardRoute(route, `${path}.routes[${routeIndex}]`)),
|
|
345
|
-
...(board.zones === undefined
|
|
346
|
-
|
|
347
|
-
|
|
433
|
+
...(board.zones === undefined
|
|
434
|
+
? {}
|
|
435
|
+
: { zones: parseBuildDataObjectArray(board.zones, `${path}.zones`) }),
|
|
436
|
+
...(board.drills === undefined
|
|
437
|
+
? {}
|
|
438
|
+
: { drills: parseBuildDataObjectArray(board.drills, `${path}.drills`) }),
|
|
439
|
+
...(board.review === undefined
|
|
440
|
+
? {}
|
|
441
|
+
: { review: parseBuildDataObject(board.review, `${path}.review`) }),
|
|
348
442
|
};
|
|
349
443
|
}
|
|
350
444
|
function parseBoardSourceCircuit(value, path) {
|
|
@@ -355,8 +449,8 @@ function parseBoardSourceCircuit(value, path) {
|
|
|
355
449
|
}
|
|
356
450
|
return {
|
|
357
451
|
...parseBuildDataObject(sourceCircuit, path),
|
|
358
|
-
schema: parseLiteralString(sourceCircuit.schema, `${path}.schema`,
|
|
359
|
-
hashAlgorithm: parseLiteralString(sourceCircuit.hashAlgorithm, `${path}.hashAlgorithm`,
|
|
452
|
+
schema: parseLiteralString(sourceCircuit.schema, `${path}.schema`, "canonical-circuit-facts-hash/v1"),
|
|
453
|
+
hashAlgorithm: parseLiteralString(sourceCircuit.hashAlgorithm, `${path}.hashAlgorithm`, "sha256"),
|
|
360
454
|
hash,
|
|
361
455
|
};
|
|
362
456
|
}
|
|
@@ -365,11 +459,17 @@ function parseBoardEdgeTerminal(value, path) {
|
|
|
365
459
|
return {
|
|
366
460
|
...parseBuildDataObject(terminal, path),
|
|
367
461
|
id: expectString(terminal.id, `${path}.id`),
|
|
368
|
-
...(terminal.role === undefined
|
|
462
|
+
...(terminal.role === undefined
|
|
463
|
+
? {}
|
|
464
|
+
: { role: expectString(terminal.role, `${path}.role`) }),
|
|
369
465
|
...(terminal.terminalRef === undefined
|
|
370
466
|
? {}
|
|
371
|
-
: {
|
|
372
|
-
|
|
467
|
+
: {
|
|
468
|
+
terminalRef: parseComponentTerminalRef(terminal.terminalRef, `${path}.terminalRef`),
|
|
469
|
+
}),
|
|
470
|
+
...(terminal.hole === undefined
|
|
471
|
+
? {}
|
|
472
|
+
: { hole: parseBoardHole(terminal.hole, `${path}.hole`) }),
|
|
373
473
|
};
|
|
374
474
|
}
|
|
375
475
|
function parseBoardFootprintPlacement(value, path) {
|
|
@@ -378,9 +478,17 @@ function parseBoardFootprintPlacement(value, path) {
|
|
|
378
478
|
...parseBuildDataObject(placement, path),
|
|
379
479
|
componentId: expectString(placement.componentId, `${path}.componentId`),
|
|
380
480
|
footprintId: expectString(placement.footprintId, `${path}.footprintId`),
|
|
381
|
-
...(placement.atGrid === undefined
|
|
382
|
-
|
|
383
|
-
|
|
481
|
+
...(placement.atGrid === undefined
|
|
482
|
+
? {}
|
|
483
|
+
: { atGrid: parseBoardHole(placement.atGrid, `${path}.atGrid`) }),
|
|
484
|
+
...(placement.atMm === undefined
|
|
485
|
+
? {}
|
|
486
|
+
: { atMm: parsePoint(placement.atMm, `${path}.atMm`) }),
|
|
487
|
+
...(placement.rotationDeg === undefined
|
|
488
|
+
? {}
|
|
489
|
+
: {
|
|
490
|
+
rotationDeg: expectNumber(placement.rotationDeg, `${path}.rotationDeg`),
|
|
491
|
+
}),
|
|
384
492
|
pads: optionalArray(placement.pads, `${path}.pads`).map((pad, padIndex) => parseBoardPlacedPad(pad, `${path}.pads[${padIndex}]`)),
|
|
385
493
|
};
|
|
386
494
|
}
|
|
@@ -389,16 +497,26 @@ function parseBoardPlacedPad(value, path) {
|
|
|
389
497
|
return {
|
|
390
498
|
...parseBuildDataObject(pad, path),
|
|
391
499
|
padId: expectString(pad.padId, `${path}.padId`),
|
|
392
|
-
...(pad.terminalName === undefined
|
|
393
|
-
|
|
394
|
-
|
|
500
|
+
...(pad.terminalName === undefined
|
|
501
|
+
? {}
|
|
502
|
+
: {
|
|
503
|
+
terminalName: expectString(pad.terminalName, `${path}.terminalName`),
|
|
504
|
+
}),
|
|
505
|
+
...(pad.hole === undefined
|
|
506
|
+
? {}
|
|
507
|
+
: { hole: parseBoardHole(pad.hole, `${path}.hole`) }),
|
|
508
|
+
...(pad.positionMm === undefined
|
|
509
|
+
? {}
|
|
510
|
+
: { positionMm: parsePoint(pad.positionMm, `${path}.positionMm`) }),
|
|
395
511
|
};
|
|
396
512
|
}
|
|
397
513
|
function parseBoardNetlist(value, path) {
|
|
398
514
|
const netlist = expectObject(value, path);
|
|
399
515
|
return {
|
|
400
516
|
...parseBuildDataObject(netlist, path),
|
|
401
|
-
...(netlist.source === undefined
|
|
517
|
+
...(netlist.source === undefined
|
|
518
|
+
? {}
|
|
519
|
+
: { source: expectString(netlist.source, `${path}.source`) }),
|
|
402
520
|
nets: optionalArray(netlist.nets, `${path}.nets`).map((net, netIndex) => parseBoardNet(net, `${path}.nets[${netIndex}]`)),
|
|
403
521
|
};
|
|
404
522
|
}
|
|
@@ -407,7 +525,9 @@ function parseBoardNet(value, path) {
|
|
|
407
525
|
return {
|
|
408
526
|
...parseBuildDataObject(net, path),
|
|
409
527
|
id: expectString(net.id, `${path}.id`),
|
|
410
|
-
...(net.name === undefined
|
|
528
|
+
...(net.name === undefined
|
|
529
|
+
? {}
|
|
530
|
+
: { name: expectString(net.name, `${path}.name`) }),
|
|
411
531
|
members: optionalArray(net.members, `${path}.members`).map((member, memberIndex) => parseBoardNetMember(member, `${path}.members[${memberIndex}]`)),
|
|
412
532
|
};
|
|
413
533
|
}
|
|
@@ -417,8 +537,12 @@ function parseBoardNetMember(value, path) {
|
|
|
417
537
|
...parseBuildDataObject(member, path),
|
|
418
538
|
componentId: expectString(member.componentId, `${path}.componentId`),
|
|
419
539
|
terminalName: expectString(member.terminalName, `${path}.terminalName`),
|
|
420
|
-
...(member.padId === undefined
|
|
421
|
-
|
|
540
|
+
...(member.padId === undefined
|
|
541
|
+
? {}
|
|
542
|
+
: { padId: expectString(member.padId, `${path}.padId`) }),
|
|
543
|
+
...(member.terminalId === undefined
|
|
544
|
+
? {}
|
|
545
|
+
: { terminalId: expectString(member.terminalId, `${path}.terminalId`) }),
|
|
422
546
|
};
|
|
423
547
|
}
|
|
424
548
|
function parseBoardRoute(value, path) {
|
|
@@ -426,15 +550,29 @@ function parseBoardRoute(value, path) {
|
|
|
426
550
|
return {
|
|
427
551
|
...parseBuildDataObject(route, path),
|
|
428
552
|
id: expectString(route.id, `${path}.id`),
|
|
429
|
-
...(route.netRef === undefined
|
|
430
|
-
|
|
553
|
+
...(route.netRef === undefined
|
|
554
|
+
? {}
|
|
555
|
+
: { netRef: parseBuildDataObject(route.netRef, `${path}.netRef`) }),
|
|
556
|
+
...(route.locked === undefined
|
|
557
|
+
? {}
|
|
558
|
+
: { locked: expectBoolean(route.locked, `${path}.locked`) }),
|
|
431
559
|
...(route.conductors === undefined
|
|
432
560
|
? {}
|
|
433
|
-
: {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
...(route.
|
|
437
|
-
|
|
561
|
+
: {
|
|
562
|
+
conductors: parseBuildDataObjectArray(route.conductors, `${path}.conductors`),
|
|
563
|
+
}),
|
|
564
|
+
...(route.copper === undefined
|
|
565
|
+
? {}
|
|
566
|
+
: { copper: parseBuildDataObjectArray(route.copper, `${path}.copper`) }),
|
|
567
|
+
...(route.vias === undefined
|
|
568
|
+
? {}
|
|
569
|
+
: { vias: parseBuildDataObjectArray(route.vias, `${path}.vias`) }),
|
|
570
|
+
...(route.zones === undefined
|
|
571
|
+
? {}
|
|
572
|
+
: { zones: parseBuildDataObjectArray(route.zones, `${path}.zones`) }),
|
|
573
|
+
...(route.drills === undefined
|
|
574
|
+
? {}
|
|
575
|
+
: { drills: parseBuildDataObjectArray(route.drills, `${path}.drills`) }),
|
|
438
576
|
};
|
|
439
577
|
}
|
|
440
578
|
function parseComponentTerminalRef(value, path) {
|
|
@@ -455,7 +593,7 @@ function parseBoardHole(value, path) {
|
|
|
455
593
|
}
|
|
456
594
|
function parseBoardFamily(value, path) {
|
|
457
595
|
const family = expectString(value, path);
|
|
458
|
-
if (family ===
|
|
596
|
+
if (family === "prototype-board" || family === "fabricated-board") {
|
|
459
597
|
return family;
|
|
460
598
|
}
|
|
461
599
|
throw new Error(`${path}: expected prototype-board or fabricated-board`);
|
|
@@ -463,10 +601,10 @@ function parseBoardFamily(value, path) {
|
|
|
463
601
|
function parseBoardKind(value, path) {
|
|
464
602
|
const kind = expectString(value, path);
|
|
465
603
|
switch (kind) {
|
|
466
|
-
case
|
|
467
|
-
case
|
|
468
|
-
case
|
|
469
|
-
case
|
|
604
|
+
case "stripboard":
|
|
605
|
+
case "perfboard":
|
|
606
|
+
case "breadboard-pattern":
|
|
607
|
+
case "pcb":
|
|
470
608
|
return kind;
|
|
471
609
|
default:
|
|
472
610
|
throw new Error(`${path}: expected stripboard, perfboard, breadboard-pattern, or pcb`);
|
|
@@ -475,11 +613,11 @@ function parseBoardKind(value, path) {
|
|
|
475
613
|
function parseBoardSubtype(value, path) {
|
|
476
614
|
const subtype = expectString(value, path);
|
|
477
615
|
switch (subtype) {
|
|
478
|
-
case
|
|
479
|
-
case
|
|
480
|
-
case
|
|
481
|
-
case
|
|
482
|
-
case
|
|
616
|
+
case "veroboard":
|
|
617
|
+
case "isolated-pad":
|
|
618
|
+
case "solderable-half-breadboard":
|
|
619
|
+
case "single-sided-through-hole":
|
|
620
|
+
case "two-layer-through-hole":
|
|
483
621
|
return subtype;
|
|
484
622
|
default:
|
|
485
623
|
throw new Error(`${path}: expected a supported board subtype`);
|
|
@@ -519,7 +657,7 @@ function parseControlGroups(value) {
|
|
|
519
657
|
if (value === undefined) {
|
|
520
658
|
return undefined;
|
|
521
659
|
}
|
|
522
|
-
return optionalArray(value,
|
|
660
|
+
return optionalArray(value, "controlGroups").map((item, index) => {
|
|
523
661
|
const path = `controlGroups[${index}]`;
|
|
524
662
|
const group = expectObject(item, path);
|
|
525
663
|
const contextIds = parseOptionalStringArray(group.contextIds, `${path}.contextIds`);
|
|
@@ -557,7 +695,7 @@ function parseControlContexts(value) {
|
|
|
557
695
|
if (value === undefined) {
|
|
558
696
|
return undefined;
|
|
559
697
|
}
|
|
560
|
-
return optionalArray(value,
|
|
698
|
+
return optionalArray(value, "controlContexts").map((item, index) => {
|
|
561
699
|
const path = `controlContexts[${index}]`;
|
|
562
700
|
const context = expectObject(item, path);
|
|
563
701
|
const description = parseOptionalString(context.description, `${path}.description`);
|
|
@@ -573,9 +711,9 @@ function parseDeviceInterface(value) {
|
|
|
573
711
|
if (value === undefined) {
|
|
574
712
|
return undefined;
|
|
575
713
|
}
|
|
576
|
-
const deviceInterface = expectObject(value,
|
|
714
|
+
const deviceInterface = expectObject(value, "deviceInterface");
|
|
577
715
|
return {
|
|
578
|
-
controls: optionalArray(deviceInterface.controls,
|
|
716
|
+
controls: optionalArray(deviceInterface.controls, "deviceInterface.controls").map((item, index) => {
|
|
579
717
|
const path = `deviceInterface.controls[${index}]`;
|
|
580
718
|
const control = expectObject(item, path);
|
|
581
719
|
const groupId = parseOptionalString(control.groupId, `${path}.groupId`);
|
|
@@ -600,13 +738,13 @@ function parseDeviceInterface(value) {
|
|
|
600
738
|
function parseDeviceInterfaceControlKind(value, path) {
|
|
601
739
|
const kind = expectString(value, path);
|
|
602
740
|
switch (kind) {
|
|
603
|
-
case
|
|
604
|
-
case
|
|
605
|
-
case
|
|
606
|
-
case
|
|
607
|
-
case
|
|
608
|
-
case
|
|
609
|
-
case
|
|
741
|
+
case "knob":
|
|
742
|
+
case "slider":
|
|
743
|
+
case "switch":
|
|
744
|
+
case "selector":
|
|
745
|
+
case "footswitch":
|
|
746
|
+
case "led":
|
|
747
|
+
case "jack":
|
|
610
748
|
return kind;
|
|
611
749
|
default:
|
|
612
750
|
throw new Error(`${path}: expected knob, slider, switch, selector, footswitch, led, or jack`);
|
|
@@ -645,16 +783,16 @@ function parseDevice(value) {
|
|
|
645
783
|
if (value === undefined) {
|
|
646
784
|
return undefined;
|
|
647
785
|
}
|
|
648
|
-
const device = expectObject(value,
|
|
649
|
-
const id = parseOptionalString(device.id,
|
|
650
|
-
const version = parseOptionalPositiveInteger(device.version,
|
|
651
|
-
const family = parseOptionalString(device.family,
|
|
652
|
-
const model = parseOptionalString(device.model,
|
|
653
|
-
const audioProcessing = parseOptionalBoolean(device.audioProcessing,
|
|
786
|
+
const device = expectObject(value, "device");
|
|
787
|
+
const id = parseOptionalString(device.id, "device.id");
|
|
788
|
+
const version = parseOptionalPositiveInteger(device.version, "device.version");
|
|
789
|
+
const family = parseOptionalString(device.family, "device.family");
|
|
790
|
+
const model = parseOptionalString(device.model, "device.model");
|
|
791
|
+
const audioProcessing = parseOptionalBoolean(device.audioProcessing, "device.audioProcessing");
|
|
654
792
|
return {
|
|
655
793
|
...(id === undefined ? {} : { id }),
|
|
656
794
|
...(version === undefined ? {} : { version }),
|
|
657
|
-
kind: parseCircuitDocumentDeviceKind(device.kind,
|
|
795
|
+
kind: parseCircuitDocumentDeviceKind(device.kind, "device.kind"),
|
|
658
796
|
...(family === undefined ? {} : { family }),
|
|
659
797
|
...(model === undefined ? {} : { model }),
|
|
660
798
|
...(audioProcessing === undefined ? {} : { audioProcessing }),
|
|
@@ -663,10 +801,10 @@ function parseDevice(value) {
|
|
|
663
801
|
function parseCircuitDocumentDeviceKind(value, path) {
|
|
664
802
|
const kind = expectString(value, path);
|
|
665
803
|
switch (kind) {
|
|
666
|
-
case
|
|
667
|
-
case
|
|
668
|
-
case
|
|
669
|
-
case
|
|
804
|
+
case "audio-pedal":
|
|
805
|
+
case "control-accessory":
|
|
806
|
+
case "utility":
|
|
807
|
+
case "unknown":
|
|
670
808
|
return kind;
|
|
671
809
|
default:
|
|
672
810
|
throw new Error(`${path}: expected audio-pedal, control-accessory, utility, or unknown`);
|
|
@@ -676,7 +814,7 @@ function parseControlOutputs(value) {
|
|
|
676
814
|
if (value === undefined) {
|
|
677
815
|
return undefined;
|
|
678
816
|
}
|
|
679
|
-
return optionalArray(value,
|
|
817
|
+
return optionalArray(value, "controlOutputs").map((item, index) => {
|
|
680
818
|
const path = `controlOutputs[${index}]`;
|
|
681
819
|
const controlOutput = expectObject(item, path);
|
|
682
820
|
const connector = parseOptionalControlInterfaceConnector(controlOutput.connector, `${path}.connector`);
|
|
@@ -706,8 +844,8 @@ function parseOptionalControlOutputSwitchMode(value, path) {
|
|
|
706
844
|
}
|
|
707
845
|
const switchMode = expectString(value, path);
|
|
708
846
|
switch (switchMode) {
|
|
709
|
-
case
|
|
710
|
-
case
|
|
847
|
+
case "momentary":
|
|
848
|
+
case "latching":
|
|
711
849
|
return switchMode;
|
|
712
850
|
default:
|
|
713
851
|
throw new Error(`${path}: expected momentary or latching`);
|
|
@@ -717,7 +855,7 @@ function parseControlInterfaces(value) {
|
|
|
717
855
|
if (value === undefined) {
|
|
718
856
|
return undefined;
|
|
719
857
|
}
|
|
720
|
-
return optionalArray(value,
|
|
858
|
+
return optionalArray(value, "controlInterfaces").map((item, index) => {
|
|
721
859
|
const path = `controlInterfaces[${index}]`;
|
|
722
860
|
const controlInterface = expectObject(item, path);
|
|
723
861
|
const componentId = parseOptionalString(controlInterface.componentId, `${path}.componentId`);
|
|
@@ -762,13 +900,13 @@ function parseOptionalControlInterfaceBinding(value, path) {
|
|
|
762
900
|
function parseControlInterfaceRole(value, path) {
|
|
763
901
|
const role = expectString(value, path);
|
|
764
902
|
switch (role) {
|
|
765
|
-
case
|
|
766
|
-
case
|
|
767
|
-
case
|
|
768
|
-
case
|
|
769
|
-
case
|
|
770
|
-
case
|
|
771
|
-
case
|
|
903
|
+
case "external-control":
|
|
904
|
+
case "tempo-tap":
|
|
905
|
+
case "trigger":
|
|
906
|
+
case "reset":
|
|
907
|
+
case "sampler-trigger":
|
|
908
|
+
case "expression":
|
|
909
|
+
case "unknown":
|
|
772
910
|
return role;
|
|
773
911
|
default:
|
|
774
912
|
throw new Error(`${path}: expected external-control, tempo-tap, trigger, reset, sampler-trigger, expression, or unknown`);
|
|
@@ -780,12 +918,12 @@ function parseOptionalControlInterfaceConnector(value, path) {
|
|
|
780
918
|
}
|
|
781
919
|
const connector = expectString(value, path);
|
|
782
920
|
switch (connector) {
|
|
783
|
-
case
|
|
784
|
-
case
|
|
785
|
-
case
|
|
786
|
-
case
|
|
787
|
-
case
|
|
788
|
-
case
|
|
921
|
+
case "1/4-inch-mono-ts":
|
|
922
|
+
case "1/4-inch-trs":
|
|
923
|
+
case "3.5mm-mono-ts":
|
|
924
|
+
case "3.5mm-trs":
|
|
925
|
+
case "proprietary":
|
|
926
|
+
case "unknown":
|
|
789
927
|
return connector;
|
|
790
928
|
default:
|
|
791
929
|
throw new Error(`${path}: expected a supported connector kind`);
|
|
@@ -797,10 +935,10 @@ function parseOptionalControlInterfaceAssignmentHint(value, path) {
|
|
|
797
935
|
}
|
|
798
936
|
const hint = expectString(value, path);
|
|
799
937
|
switch (hint) {
|
|
800
|
-
case
|
|
801
|
-
case
|
|
802
|
-
case
|
|
803
|
-
case
|
|
938
|
+
case "momentary":
|
|
939
|
+
case "latching":
|
|
940
|
+
case "momentary-or-latching":
|
|
941
|
+
case "continuous":
|
|
804
942
|
return hint;
|
|
805
943
|
default:
|
|
806
944
|
throw new Error(`${path}: expected momentary, latching, momentary-or-latching, or continuous`);
|
|
@@ -812,10 +950,10 @@ function parseOptionalControlInterfacePolarity(value, path) {
|
|
|
812
950
|
}
|
|
813
951
|
const polarity = expectString(value, path);
|
|
814
952
|
switch (polarity) {
|
|
815
|
-
case
|
|
816
|
-
case
|
|
817
|
-
case
|
|
818
|
-
case
|
|
953
|
+
case "normally-open":
|
|
954
|
+
case "normally-closed":
|
|
955
|
+
case "expression":
|
|
956
|
+
case "unknown":
|
|
819
957
|
return polarity;
|
|
820
958
|
default:
|
|
821
959
|
throw new Error(`${path}: expected normally-open, normally-closed, expression, or unknown`);
|
|
@@ -824,12 +962,12 @@ function parseOptionalControlInterfacePolarity(value, path) {
|
|
|
824
962
|
function parseYamlSubset(source) {
|
|
825
963
|
const lines = tokenize(source);
|
|
826
964
|
if (lines.length === 0) {
|
|
827
|
-
throw new Error(
|
|
965
|
+
throw new Error("interchange YAML is empty");
|
|
828
966
|
}
|
|
829
967
|
const cursor = { index: 0 };
|
|
830
968
|
const first = lines[0];
|
|
831
969
|
if (first === undefined) {
|
|
832
|
-
throw new Error(
|
|
970
|
+
throw new Error("interchange YAML is empty");
|
|
833
971
|
}
|
|
834
972
|
const value = parseBlock(lines, cursor, first.indent);
|
|
835
973
|
if (cursor.index < lines.length) {
|
|
@@ -840,13 +978,13 @@ function parseYamlSubset(source) {
|
|
|
840
978
|
}
|
|
841
979
|
function tokenize(source) {
|
|
842
980
|
const lines = [];
|
|
843
|
-
const rawLines = source.replace(/^/,
|
|
981
|
+
const rawLines = source.replace(/^/, "").split(/\r?\n/);
|
|
844
982
|
rawLines.forEach((rawLine, index) => {
|
|
845
983
|
if (rawLine.trim().length === 0) {
|
|
846
984
|
return;
|
|
847
985
|
}
|
|
848
|
-
const indentText = rawLine.match(/^\s*/)?.[0] ??
|
|
849
|
-
if (indentText.includes(
|
|
986
|
+
const indentText = rawLine.match(/^\s*/)?.[0] ?? "";
|
|
987
|
+
if (indentText.includes("\t")) {
|
|
850
988
|
throw new Error(`line ${index + 1}: tabs are not supported in interchange YAML`);
|
|
851
989
|
}
|
|
852
990
|
lines.push({
|
|
@@ -865,7 +1003,7 @@ function parseBlock(lines, cursor, indent) {
|
|
|
865
1003
|
if (line.indent !== indent) {
|
|
866
1004
|
throw new Error(`line ${line.lineNumber}: expected indentation ${indent}, got ${line.indent}`);
|
|
867
1005
|
}
|
|
868
|
-
if (line.text ===
|
|
1006
|
+
if (line.text === "-" || line.text.startsWith("- ")) {
|
|
869
1007
|
return parseArray(lines, cursor, indent);
|
|
870
1008
|
}
|
|
871
1009
|
return parseObject(lines, cursor, indent);
|
|
@@ -880,14 +1018,15 @@ function parseObject(lines, cursor, indent) {
|
|
|
880
1018
|
if (line.indent > indent) {
|
|
881
1019
|
throw new Error(`line ${line.lineNumber}: unexpected indentation ${line.indent}`);
|
|
882
1020
|
}
|
|
883
|
-
if (line.text ===
|
|
1021
|
+
if (line.text === "-" || line.text.startsWith("- ")) {
|
|
884
1022
|
break;
|
|
885
1023
|
}
|
|
886
1024
|
const pair = parsePair(line.text, line.lineNumber);
|
|
887
1025
|
cursor.index += 1;
|
|
888
|
-
out[pair.key] =
|
|
889
|
-
|
|
890
|
-
|
|
1026
|
+
out[pair.key] =
|
|
1027
|
+
pair.rest.length > 0
|
|
1028
|
+
? parseInlineValue(pair.rest, line.lineNumber)
|
|
1029
|
+
: parseNestedValue(lines, cursor, indent, line.lineNumber);
|
|
891
1030
|
}
|
|
892
1031
|
return out;
|
|
893
1032
|
}
|
|
@@ -901,10 +1040,10 @@ function parseArray(lines, cursor, indent) {
|
|
|
901
1040
|
if (line.indent > indent) {
|
|
902
1041
|
throw new Error(`line ${line.lineNumber}: unexpected indentation ${line.indent}`);
|
|
903
1042
|
}
|
|
904
|
-
if (line.text !==
|
|
1043
|
+
if (line.text !== "-" && !line.text.startsWith("- ")) {
|
|
905
1044
|
break;
|
|
906
1045
|
}
|
|
907
|
-
const rest = line.text ===
|
|
1046
|
+
const rest = line.text === "-" ? "" : line.text.slice(2);
|
|
908
1047
|
cursor.index += 1;
|
|
909
1048
|
if (rest.length === 0) {
|
|
910
1049
|
out.push(parseNestedValue(lines, cursor, indent, line.lineNumber));
|
|
@@ -921,9 +1060,10 @@ function parseArray(lines, cursor, indent) {
|
|
|
921
1060
|
function parseObjectItem(firstPairText, lines, cursor, indent, lineNumber) {
|
|
922
1061
|
const out = {};
|
|
923
1062
|
const firstPair = parsePair(firstPairText, lineNumber);
|
|
924
|
-
out[firstPair.key] =
|
|
925
|
-
|
|
926
|
-
|
|
1063
|
+
out[firstPair.key] =
|
|
1064
|
+
firstPair.rest.length > 0
|
|
1065
|
+
? parseInlineValue(firstPair.rest, lineNumber)
|
|
1066
|
+
: parseNestedValue(lines, cursor, indent, lineNumber);
|
|
927
1067
|
while (cursor.index < lines.length) {
|
|
928
1068
|
const line = lines[cursor.index];
|
|
929
1069
|
if (line === undefined || line.indent < indent) {
|
|
@@ -932,14 +1072,15 @@ function parseObjectItem(firstPairText, lines, cursor, indent, lineNumber) {
|
|
|
932
1072
|
if (line.indent > indent) {
|
|
933
1073
|
throw new Error(`line ${line.lineNumber}: unexpected indentation ${line.indent}`);
|
|
934
1074
|
}
|
|
935
|
-
if (line.text ===
|
|
1075
|
+
if (line.text === "-" || line.text.startsWith("- ")) {
|
|
936
1076
|
break;
|
|
937
1077
|
}
|
|
938
1078
|
const pair = parsePair(line.text, line.lineNumber);
|
|
939
1079
|
cursor.index += 1;
|
|
940
|
-
out[pair.key] =
|
|
941
|
-
|
|
942
|
-
|
|
1080
|
+
out[pair.key] =
|
|
1081
|
+
pair.rest.length > 0
|
|
1082
|
+
? parseInlineValue(pair.rest, line.lineNumber)
|
|
1083
|
+
: parseNestedValue(lines, cursor, indent, line.lineNumber);
|
|
943
1084
|
}
|
|
944
1085
|
return out;
|
|
945
1086
|
}
|
|
@@ -962,7 +1103,7 @@ function parsePair(text, lineNumber) {
|
|
|
962
1103
|
const restText = text.slice(colonIndex + 1);
|
|
963
1104
|
return {
|
|
964
1105
|
key: parseKey(keyText, lineNumber),
|
|
965
|
-
rest: restText.startsWith(
|
|
1106
|
+
rest: restText.startsWith(" ") ? restText.slice(1) : restText,
|
|
966
1107
|
};
|
|
967
1108
|
}
|
|
968
1109
|
function looksLikePair(text) {
|
|
@@ -971,9 +1112,9 @@ function looksLikePair(text) {
|
|
|
971
1112
|
function findPairColon(text) {
|
|
972
1113
|
if (text.startsWith('"')) {
|
|
973
1114
|
const end = findJsonStringEnd(text);
|
|
974
|
-
return end >= 0 && text[end + 1] ===
|
|
1115
|
+
return end >= 0 && text[end + 1] === ":" ? end + 1 : -1;
|
|
975
1116
|
}
|
|
976
|
-
return text.indexOf(
|
|
1117
|
+
return text.indexOf(":");
|
|
977
1118
|
}
|
|
978
1119
|
function findJsonStringEnd(text) {
|
|
979
1120
|
let escaped = false;
|
|
@@ -983,7 +1124,7 @@ function findJsonStringEnd(text) {
|
|
|
983
1124
|
escaped = false;
|
|
984
1125
|
continue;
|
|
985
1126
|
}
|
|
986
|
-
if (char ===
|
|
1127
|
+
if (char === "\\") {
|
|
987
1128
|
escaped = true;
|
|
988
1129
|
continue;
|
|
989
1130
|
}
|
|
@@ -999,7 +1140,7 @@ function parseKey(text, lineNumber) {
|
|
|
999
1140
|
}
|
|
1000
1141
|
try {
|
|
1001
1142
|
const parsed = JSON.parse(text);
|
|
1002
|
-
if (typeof parsed ===
|
|
1143
|
+
if (typeof parsed === "string") {
|
|
1003
1144
|
return parsed;
|
|
1004
1145
|
}
|
|
1005
1146
|
}
|
|
@@ -1009,25 +1150,25 @@ function parseKey(text, lineNumber) {
|
|
|
1009
1150
|
throw new Error(`line ${lineNumber}: invalid quoted key`);
|
|
1010
1151
|
}
|
|
1011
1152
|
function parseInlineValue(text, lineNumber) {
|
|
1012
|
-
if (text ===
|
|
1153
|
+
if (text === "[]") {
|
|
1013
1154
|
return [];
|
|
1014
1155
|
}
|
|
1015
|
-
if (text ===
|
|
1156
|
+
if (text === "{}") {
|
|
1016
1157
|
return {};
|
|
1017
1158
|
}
|
|
1018
|
-
if (text ===
|
|
1159
|
+
if (text === "null") {
|
|
1019
1160
|
return null;
|
|
1020
1161
|
}
|
|
1021
|
-
if (text ===
|
|
1162
|
+
if (text === "true") {
|
|
1022
1163
|
return true;
|
|
1023
1164
|
}
|
|
1024
|
-
if (text ===
|
|
1165
|
+
if (text === "false") {
|
|
1025
1166
|
return false;
|
|
1026
1167
|
}
|
|
1027
1168
|
if (text.startsWith('"')) {
|
|
1028
1169
|
try {
|
|
1029
1170
|
const parsed = JSON.parse(text);
|
|
1030
|
-
if (typeof parsed ===
|
|
1171
|
+
if (typeof parsed === "string") {
|
|
1031
1172
|
return parsed;
|
|
1032
1173
|
}
|
|
1033
1174
|
}
|
|
@@ -1042,7 +1183,7 @@ function parseInlineValue(text, lineNumber) {
|
|
|
1042
1183
|
return text;
|
|
1043
1184
|
}
|
|
1044
1185
|
function parseMetadata(value) {
|
|
1045
|
-
const metadata = optionalObject(value,
|
|
1186
|
+
const metadata = optionalObject(value, "metadata");
|
|
1046
1187
|
return {
|
|
1047
1188
|
name: scalarText(metadata.name),
|
|
1048
1189
|
description: scalarText(metadata.description),
|
|
@@ -1050,30 +1191,32 @@ function parseMetadata(value) {
|
|
|
1050
1191
|
};
|
|
1051
1192
|
}
|
|
1052
1193
|
function parseSource(value) {
|
|
1053
|
-
return parseStringRecord(value,
|
|
1194
|
+
return parseStringRecord(value, "source");
|
|
1054
1195
|
}
|
|
1055
1196
|
function parsePanel(value, allowV3PhysicalFields) {
|
|
1056
1197
|
if (value === undefined) {
|
|
1057
1198
|
return undefined;
|
|
1058
1199
|
}
|
|
1059
|
-
const panel = expectObject(value,
|
|
1200
|
+
const panel = expectObject(value, "panel");
|
|
1060
1201
|
if (panel.faces !== undefined) {
|
|
1061
1202
|
return {
|
|
1062
|
-
faces: optionalArray(panel.faces,
|
|
1203
|
+
faces: optionalArray(panel.faces, "panel.faces").map((item, index) => parsePanelFace(item, index, allowV3PhysicalFields)),
|
|
1063
1204
|
};
|
|
1064
1205
|
}
|
|
1065
1206
|
if (panel.layout === undefined) {
|
|
1066
1207
|
return undefined;
|
|
1067
1208
|
}
|
|
1068
|
-
const layout = parsePanelLayout(panel.layout,
|
|
1209
|
+
const layout = parsePanelLayout(panel.layout, "panel.layout");
|
|
1069
1210
|
const elementsValue = panel.controls ?? panel.elements;
|
|
1070
|
-
const elementsPath = panel.controls === undefined ?
|
|
1211
|
+
const elementsPath = panel.controls === undefined ? "panel.elements" : "panel.controls";
|
|
1071
1212
|
return {
|
|
1072
|
-
faces: [
|
|
1073
|
-
|
|
1213
|
+
faces: [
|
|
1214
|
+
{
|
|
1215
|
+
id: "top",
|
|
1074
1216
|
layout,
|
|
1075
1217
|
elements: parsePanelElements(elementsValue, layout, elementsPath, allowV3PhysicalFields),
|
|
1076
|
-
}
|
|
1218
|
+
},
|
|
1219
|
+
],
|
|
1077
1220
|
};
|
|
1078
1221
|
}
|
|
1079
1222
|
function parsePanelFace(value, index, allowV3PhysicalFields) {
|
|
@@ -1084,7 +1227,9 @@ function parsePanelFace(value, index, allowV3PhysicalFields) {
|
|
|
1084
1227
|
if (!allowV3PhysicalFields && face.geometry !== undefined) {
|
|
1085
1228
|
throw new Error(`${path}.geometry: requires schema ${INTERCHANGE_SCHEMA_V3}`);
|
|
1086
1229
|
}
|
|
1087
|
-
const geometry = allowV3PhysicalFields
|
|
1230
|
+
const geometry = allowV3PhysicalFields
|
|
1231
|
+
? parseOptionalPanelFaceGeometry(face.geometry, `${path}.geometry`)
|
|
1232
|
+
: undefined;
|
|
1088
1233
|
return {
|
|
1089
1234
|
id: expectString(face.id, `${path}.id`),
|
|
1090
1235
|
...(label === undefined ? {} : { label }),
|
|
@@ -1118,7 +1263,9 @@ function parsePanelElements(value, layout, path, allowV3PhysicalFields) {
|
|
|
1118
1263
|
if (!allowV3PhysicalFields && element.physical !== undefined) {
|
|
1119
1264
|
throw new Error(`${elementPath}.physical: requires schema ${INTERCHANGE_SCHEMA_V3}`);
|
|
1120
1265
|
}
|
|
1121
|
-
const id = allowV3PhysicalFields
|
|
1266
|
+
const id = allowV3PhysicalFields
|
|
1267
|
+
? parseOptionalString(element.id, `${elementPath}.id`)
|
|
1268
|
+
: undefined;
|
|
1122
1269
|
const physical = allowV3PhysicalFields
|
|
1123
1270
|
? parseOptionalPanelElementPhysical(element.physical, `${elementPath}.physical`)
|
|
1124
1271
|
: undefined;
|
|
@@ -1142,11 +1289,17 @@ function parseOptionalPanelFaceGeometry(value, path) {
|
|
|
1142
1289
|
const geometry = expectObject(value, path);
|
|
1143
1290
|
return {
|
|
1144
1291
|
...parseBuildDataObject(geometry, path),
|
|
1145
|
-
...(geometry.units === undefined
|
|
1146
|
-
|
|
1292
|
+
...(geometry.units === undefined
|
|
1293
|
+
? {}
|
|
1294
|
+
: { units: expectString(geometry.units, `${path}.units`) }),
|
|
1295
|
+
...(geometry.surface === undefined
|
|
1296
|
+
? {}
|
|
1297
|
+
: { surface: expectString(geometry.surface, `${path}.surface`) }),
|
|
1147
1298
|
...(geometry.usableRectMm === undefined
|
|
1148
1299
|
? {}
|
|
1149
|
-
: {
|
|
1300
|
+
: {
|
|
1301
|
+
usableRectMm: parseMillimeterRect(geometry.usableRectMm, `${path}.usableRectMm`),
|
|
1302
|
+
}),
|
|
1150
1303
|
};
|
|
1151
1304
|
}
|
|
1152
1305
|
function parseOptionalPanelElementPhysical(value, path) {
|
|
@@ -1156,15 +1309,31 @@ function parseOptionalPanelElementPhysical(value, path) {
|
|
|
1156
1309
|
const physical = expectObject(value, path);
|
|
1157
1310
|
return {
|
|
1158
1311
|
...parseBuildDataObject(physical, path),
|
|
1159
|
-
...(physical.units === undefined
|
|
1160
|
-
|
|
1312
|
+
...(physical.units === undefined
|
|
1313
|
+
? {}
|
|
1314
|
+
: { units: expectString(physical.units, `${path}.units`) }),
|
|
1315
|
+
...(physical.centerMm === undefined
|
|
1316
|
+
? {}
|
|
1317
|
+
: { centerMm: parsePoint(physical.centerMm, `${path}.centerMm`) }),
|
|
1161
1318
|
...(physical.drillDiameterMm === undefined
|
|
1162
1319
|
? {}
|
|
1163
|
-
: {
|
|
1320
|
+
: {
|
|
1321
|
+
drillDiameterMm: expectNumber(physical.drillDiameterMm, `${path}.drillDiameterMm`),
|
|
1322
|
+
}),
|
|
1164
1323
|
...(physical.partProfileId === undefined
|
|
1165
1324
|
? {}
|
|
1166
|
-
: {
|
|
1167
|
-
|
|
1325
|
+
: {
|
|
1326
|
+
partProfileId: expectString(physical.partProfileId, `${path}.partProfileId`),
|
|
1327
|
+
}),
|
|
1328
|
+
...(physical.locked === undefined
|
|
1329
|
+
? {}
|
|
1330
|
+
: { locked: expectBoolean(physical.locked, `${path}.locked`) }),
|
|
1331
|
+
...(physical.mountId === undefined
|
|
1332
|
+
? {}
|
|
1333
|
+
: { mountId: expectString(physical.mountId, `${path}.mountId`) }),
|
|
1334
|
+
...(physical.surface === undefined
|
|
1335
|
+
? {}
|
|
1336
|
+
: { surface: expectString(physical.surface, `${path}.surface`) }),
|
|
1168
1337
|
};
|
|
1169
1338
|
}
|
|
1170
1339
|
function parseMillimeterRect(value, path) {
|
|
@@ -1199,8 +1368,8 @@ function parsePanelGridPosition(value, path, layout) {
|
|
|
1199
1368
|
const columnSpan = parseOptionalPositiveInteger(grid.columnSpan, `${path}.columnSpan`);
|
|
1200
1369
|
const row = expectNonNegativeInteger(grid.row, `${path}.row`);
|
|
1201
1370
|
const column = expectNonNegativeInteger(grid.column, `${path}.column`);
|
|
1202
|
-
validateGridAxis(row, rowSpan ?? 1, layout.rows, layout.indexing, `${path}.row`,
|
|
1203
|
-
validateGridAxis(column, columnSpan ?? 1, layout.columns, layout.indexing, `${path}.column`,
|
|
1371
|
+
validateGridAxis(row, rowSpan ?? 1, layout.rows, layout.indexing, `${path}.row`, "row");
|
|
1372
|
+
validateGridAxis(column, columnSpan ?? 1, layout.columns, layout.indexing, `${path}.column`, "column");
|
|
1204
1373
|
return {
|
|
1205
1374
|
row,
|
|
1206
1375
|
column,
|
|
@@ -1209,23 +1378,23 @@ function parsePanelGridPosition(value, path, layout) {
|
|
|
1209
1378
|
};
|
|
1210
1379
|
}
|
|
1211
1380
|
function validateGridAxis(value, span, size, indexing, path, axisName) {
|
|
1212
|
-
const min = indexing ===
|
|
1213
|
-
const occupiedEnd = indexing ===
|
|
1381
|
+
const min = indexing === "one-based" ? 1 : 0;
|
|
1382
|
+
const occupiedEnd = indexing === "one-based" ? value + span - 1 : value + span;
|
|
1214
1383
|
if (value < min || occupiedEnd > size) {
|
|
1215
|
-
const maxLabel = indexing ===
|
|
1384
|
+
const maxLabel = indexing === "one-based" ? String(size) : String(size - 1);
|
|
1216
1385
|
throw new Error(`${path}: expected ${indexing} ${axisName} coordinate within ${min}..${maxLabel}`);
|
|
1217
1386
|
}
|
|
1218
1387
|
}
|
|
1219
1388
|
function parsePanelLayoutKind(value, path) {
|
|
1220
1389
|
const kind = expectString(value, path);
|
|
1221
|
-
if (kind ===
|
|
1390
|
+
if (kind === "stompbox-grid") {
|
|
1222
1391
|
return kind;
|
|
1223
1392
|
}
|
|
1224
1393
|
throw new Error(`${path}: expected stompbox-grid`);
|
|
1225
1394
|
}
|
|
1226
1395
|
function parsePanelGridIndexing(value, path) {
|
|
1227
1396
|
const indexing = expectString(value, path);
|
|
1228
|
-
if (indexing ===
|
|
1397
|
+
if (indexing === "one-based" || indexing === "zero-based") {
|
|
1229
1398
|
return indexing;
|
|
1230
1399
|
}
|
|
1231
1400
|
throw new Error(`${path}: expected one-based or zero-based`);
|
|
@@ -1235,7 +1404,7 @@ function parseOptionalPanelRowOrder(value, path) {
|
|
|
1235
1404
|
return undefined;
|
|
1236
1405
|
}
|
|
1237
1406
|
const order = expectString(value, path);
|
|
1238
|
-
if (order ===
|
|
1407
|
+
if (order === "top-to-bottom" || order === "bottom-to-top") {
|
|
1239
1408
|
return order;
|
|
1240
1409
|
}
|
|
1241
1410
|
throw new Error(`${path}: expected top-to-bottom or bottom-to-top`);
|
|
@@ -1245,7 +1414,7 @@ function parseOptionalPanelColumnOrder(value, path) {
|
|
|
1245
1414
|
return undefined;
|
|
1246
1415
|
}
|
|
1247
1416
|
const order = expectString(value, path);
|
|
1248
|
-
if (order ===
|
|
1417
|
+
if (order === "left-to-right" || order === "right-to-left") {
|
|
1249
1418
|
return order;
|
|
1250
1419
|
}
|
|
1251
1420
|
throw new Error(`${path}: expected left-to-right or right-to-left`);
|
|
@@ -1253,20 +1422,20 @@ function parseOptionalPanelColumnOrder(value, path) {
|
|
|
1253
1422
|
function parsePanelControlKind(value, path) {
|
|
1254
1423
|
const kind = expectString(value, path);
|
|
1255
1424
|
switch (kind) {
|
|
1256
|
-
case
|
|
1257
|
-
case
|
|
1258
|
-
case
|
|
1259
|
-
case
|
|
1260
|
-
case
|
|
1261
|
-
case
|
|
1262
|
-
case
|
|
1425
|
+
case "knob":
|
|
1426
|
+
case "slider":
|
|
1427
|
+
case "switch":
|
|
1428
|
+
case "selector":
|
|
1429
|
+
case "footswitch":
|
|
1430
|
+
case "led":
|
|
1431
|
+
case "jack":
|
|
1263
1432
|
return kind;
|
|
1264
1433
|
default:
|
|
1265
1434
|
throw new Error(`${path}: expected knob, slider, switch, selector, footswitch, led, or jack`);
|
|
1266
1435
|
}
|
|
1267
1436
|
}
|
|
1268
1437
|
function parseComponents(value) {
|
|
1269
|
-
return optionalArray(value,
|
|
1438
|
+
return optionalArray(value, "components").map((item, index) => {
|
|
1270
1439
|
const path = `components[${index}]`;
|
|
1271
1440
|
const component = expectObject(item, path);
|
|
1272
1441
|
return {
|
|
@@ -1327,7 +1496,7 @@ function isParsedQuantityValue(value) {
|
|
|
1327
1496
|
return isParsedQuantity(value);
|
|
1328
1497
|
}
|
|
1329
1498
|
function parseWires(value) {
|
|
1330
|
-
return optionalArray(value,
|
|
1499
|
+
return optionalArray(value, "wires").map((item, index) => {
|
|
1331
1500
|
const path = `wires[${index}]`;
|
|
1332
1501
|
const wire = expectObject(item, path);
|
|
1333
1502
|
const points = expectArray(wire.points, `${path}.points`);
|
|
@@ -1343,7 +1512,7 @@ function parseWires(value) {
|
|
|
1343
1512
|
});
|
|
1344
1513
|
}
|
|
1345
1514
|
function parseWarnings(value) {
|
|
1346
|
-
return optionalArray(value,
|
|
1515
|
+
return optionalArray(value, "diagnostics").map((item, index) => {
|
|
1347
1516
|
const path = `diagnostics[${index}]`;
|
|
1348
1517
|
const warning = expectObject(item, path);
|
|
1349
1518
|
const out = {
|
|
@@ -1351,7 +1520,9 @@ function parseWarnings(value) {
|
|
|
1351
1520
|
message: expectString(warning.message, `${path}.message`),
|
|
1352
1521
|
...(warning.componentId === undefined
|
|
1353
1522
|
? {}
|
|
1354
|
-
: {
|
|
1523
|
+
: {
|
|
1524
|
+
componentId: expectString(warning.componentId, `${path}.componentId`),
|
|
1525
|
+
}),
|
|
1355
1526
|
...(warning.wireId === undefined
|
|
1356
1527
|
? {}
|
|
1357
1528
|
: { wireId: expectString(warning.wireId, `${path}.wireId`) }),
|
|
@@ -1393,41 +1564,41 @@ function parseNullableString(value, path) {
|
|
|
1393
1564
|
function parseComponentKind(value, path) {
|
|
1394
1565
|
const kind = expectString(value, path);
|
|
1395
1566
|
switch (kind) {
|
|
1396
|
-
case
|
|
1397
|
-
case
|
|
1398
|
-
case
|
|
1399
|
-
case
|
|
1400
|
-
case
|
|
1401
|
-
case
|
|
1402
|
-
case
|
|
1403
|
-
case
|
|
1404
|
-
case
|
|
1405
|
-
case
|
|
1406
|
-
case
|
|
1407
|
-
case
|
|
1408
|
-
case
|
|
1409
|
-
case
|
|
1410
|
-
case
|
|
1411
|
-
case
|
|
1412
|
-
case
|
|
1413
|
-
case
|
|
1414
|
-
case
|
|
1415
|
-
case
|
|
1416
|
-
case
|
|
1417
|
-
case
|
|
1418
|
-
case
|
|
1419
|
-
case
|
|
1420
|
-
case
|
|
1421
|
-
case
|
|
1422
|
-
case
|
|
1423
|
-
case
|
|
1424
|
-
case
|
|
1425
|
-
case
|
|
1426
|
-
case
|
|
1427
|
-
case
|
|
1428
|
-
case
|
|
1429
|
-
case
|
|
1430
|
-
case
|
|
1567
|
+
case "resistor":
|
|
1568
|
+
case "capacitor":
|
|
1569
|
+
case "inductor":
|
|
1570
|
+
case "diode":
|
|
1571
|
+
case "led":
|
|
1572
|
+
case "bjt":
|
|
1573
|
+
case "jfet":
|
|
1574
|
+
case "mosfet":
|
|
1575
|
+
case "opamp":
|
|
1576
|
+
case "ota":
|
|
1577
|
+
case "triode":
|
|
1578
|
+
case "pentode":
|
|
1579
|
+
case "tube-diode":
|
|
1580
|
+
case "transformer":
|
|
1581
|
+
case "potentiometer":
|
|
1582
|
+
case "variable-resistor":
|
|
1583
|
+
case "switch":
|
|
1584
|
+
case "optocoupler":
|
|
1585
|
+
case "voltage-source":
|
|
1586
|
+
case "current-source":
|
|
1587
|
+
case "battery":
|
|
1588
|
+
case "ground":
|
|
1589
|
+
case "rail":
|
|
1590
|
+
case "jack":
|
|
1591
|
+
case "bbd":
|
|
1592
|
+
case "delay-ic":
|
|
1593
|
+
case "power-amp":
|
|
1594
|
+
case "regulator":
|
|
1595
|
+
case "analog-switch":
|
|
1596
|
+
case "flipflop":
|
|
1597
|
+
case "ic":
|
|
1598
|
+
case "label":
|
|
1599
|
+
case "named-wire":
|
|
1600
|
+
case "port":
|
|
1601
|
+
case "unsupported":
|
|
1431
1602
|
return kind;
|
|
1432
1603
|
default:
|
|
1433
1604
|
throw new Error(`${path}: unsupported component kind "${kind}"`);
|
|
@@ -1458,13 +1629,13 @@ function expectArray(value, path) {
|
|
|
1458
1629
|
throw new Error(`${path}: expected array`);
|
|
1459
1630
|
}
|
|
1460
1631
|
function expectString(value, path) {
|
|
1461
|
-
if (typeof value ===
|
|
1632
|
+
if (typeof value === "string") {
|
|
1462
1633
|
return value;
|
|
1463
1634
|
}
|
|
1464
1635
|
throw new Error(`${path}: expected string`);
|
|
1465
1636
|
}
|
|
1466
1637
|
function expectNumber(value, path) {
|
|
1467
|
-
if (typeof value ===
|
|
1638
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
1468
1639
|
return value;
|
|
1469
1640
|
}
|
|
1470
1641
|
throw new Error(`${path}: expected number`);
|
|
@@ -1514,14 +1685,14 @@ function parseOptionalBoolean(value, path) {
|
|
|
1514
1685
|
return expectBoolean(value, path);
|
|
1515
1686
|
}
|
|
1516
1687
|
function expectBoolean(value, path) {
|
|
1517
|
-
if (typeof value ===
|
|
1688
|
+
if (typeof value === "boolean") {
|
|
1518
1689
|
return value;
|
|
1519
1690
|
}
|
|
1520
1691
|
throw new Error(`${path}: expected boolean`);
|
|
1521
1692
|
}
|
|
1522
|
-
function scalarText(value, path =
|
|
1693
|
+
function scalarText(value, path = "value") {
|
|
1523
1694
|
if (value === undefined || value === null) {
|
|
1524
|
-
return
|
|
1695
|
+
return "";
|
|
1525
1696
|
}
|
|
1526
1697
|
if (isScalar(value)) {
|
|
1527
1698
|
return String(value);
|
|
@@ -1529,9 +1700,15 @@ function scalarText(value, path = 'value') {
|
|
|
1529
1700
|
throw new Error(`${path}: expected scalar`);
|
|
1530
1701
|
}
|
|
1531
1702
|
function isScalar(value) {
|
|
1532
|
-
return value === null ||
|
|
1703
|
+
return (value === null ||
|
|
1704
|
+
typeof value === "string" ||
|
|
1705
|
+
typeof value === "number" ||
|
|
1706
|
+
typeof value === "boolean");
|
|
1533
1707
|
}
|
|
1534
1708
|
function isYamlObject(value) {
|
|
1535
|
-
return value !== undefined &&
|
|
1709
|
+
return (value !== undefined &&
|
|
1710
|
+
value !== null &&
|
|
1711
|
+
typeof value === "object" &&
|
|
1712
|
+
!Array.isArray(value));
|
|
1536
1713
|
}
|
|
1537
1714
|
//# sourceMappingURL=parser.js.map
|