@vessel-dsp/core 0.6.3 → 0.6.5
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 +11 -3
- 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 +483 -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 +59 -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 +72 -37
- 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 +763 -315
- 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 +376 -216
- package/dist/panel/extract.js.map +1 -1
- package/dist/panel/index.d.ts +7 -5
- package/dist/panel/index.d.ts.map +1 -1
- package/dist/panel/index.js +5 -4
- 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 +27 -0
- package/dist/panel/placement.d.ts.map +1 -0
- package/dist/panel/placement.js +91 -0
- package/dist/panel/placement.js.map +1 -0
- 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 +26 -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,10 +657,11 @@ 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`);
|
|
664
|
+
const members = parseControlGroupMembers(group.members, `${path}.members`);
|
|
526
665
|
const description = parseOptionalString(group.description, `${path}.description`);
|
|
527
666
|
return {
|
|
528
667
|
id: expectString(group.id, `${path}.id`),
|
|
@@ -530,6 +669,25 @@ function parseControlGroups(value) {
|
|
|
530
669
|
role: expectString(group.role, `${path}.role`),
|
|
531
670
|
...(contextIds === undefined ? {} : { contextIds }),
|
|
532
671
|
...(description === undefined ? {} : { description }),
|
|
672
|
+
...(members === undefined ? {} : { members }),
|
|
673
|
+
};
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
function parseControlGroupMembers(value, path) {
|
|
677
|
+
if (value === undefined) {
|
|
678
|
+
return undefined;
|
|
679
|
+
}
|
|
680
|
+
return optionalArray(value, path).map((item, index) => {
|
|
681
|
+
const memberPath = `${path}[${index}]`;
|
|
682
|
+
const member = expectObject(item, memberPath);
|
|
683
|
+
const order = parseOptionalNumber(member.order, `${memberPath}.order`);
|
|
684
|
+
const appliesWhen = parseOptionalApplicabilityPredicate(member.appliesWhen, `${memberPath}.appliesWhen`);
|
|
685
|
+
const description = parseOptionalString(member.description, `${memberPath}.description`);
|
|
686
|
+
return {
|
|
687
|
+
controlId: expectString(member.controlId, `${memberPath}.controlId`),
|
|
688
|
+
...(order === undefined ? {} : { order }),
|
|
689
|
+
...(appliesWhen === undefined ? {} : { appliesWhen }),
|
|
690
|
+
...(description === undefined ? {} : { description }),
|
|
533
691
|
};
|
|
534
692
|
});
|
|
535
693
|
}
|
|
@@ -537,7 +695,7 @@ function parseControlContexts(value) {
|
|
|
537
695
|
if (value === undefined) {
|
|
538
696
|
return undefined;
|
|
539
697
|
}
|
|
540
|
-
return optionalArray(value,
|
|
698
|
+
return optionalArray(value, "controlContexts").map((item, index) => {
|
|
541
699
|
const path = `controlContexts[${index}]`;
|
|
542
700
|
const context = expectObject(item, path);
|
|
543
701
|
const description = parseOptionalString(context.description, `${path}.description`);
|
|
@@ -553,9 +711,9 @@ function parseDeviceInterface(value) {
|
|
|
553
711
|
if (value === undefined) {
|
|
554
712
|
return undefined;
|
|
555
713
|
}
|
|
556
|
-
const deviceInterface = expectObject(value,
|
|
714
|
+
const deviceInterface = expectObject(value, "deviceInterface");
|
|
557
715
|
return {
|
|
558
|
-
controls: optionalArray(deviceInterface.controls,
|
|
716
|
+
controls: optionalArray(deviceInterface.controls, "deviceInterface.controls").map((item, index) => {
|
|
559
717
|
const path = `deviceInterface.controls[${index}]`;
|
|
560
718
|
const control = expectObject(item, path);
|
|
561
719
|
const groupId = parseOptionalString(control.groupId, `${path}.groupId`);
|
|
@@ -580,13 +738,13 @@ function parseDeviceInterface(value) {
|
|
|
580
738
|
function parseDeviceInterfaceControlKind(value, path) {
|
|
581
739
|
const kind = expectString(value, path);
|
|
582
740
|
switch (kind) {
|
|
583
|
-
case
|
|
584
|
-
case
|
|
585
|
-
case
|
|
586
|
-
case
|
|
587
|
-
case
|
|
588
|
-
case
|
|
589
|
-
case
|
|
741
|
+
case "knob":
|
|
742
|
+
case "slider":
|
|
743
|
+
case "switch":
|
|
744
|
+
case "selector":
|
|
745
|
+
case "footswitch":
|
|
746
|
+
case "led":
|
|
747
|
+
case "jack":
|
|
590
748
|
return kind;
|
|
591
749
|
default:
|
|
592
750
|
throw new Error(`${path}: expected knob, slider, switch, selector, footswitch, led, or jack`);
|
|
@@ -625,16 +783,16 @@ function parseDevice(value) {
|
|
|
625
783
|
if (value === undefined) {
|
|
626
784
|
return undefined;
|
|
627
785
|
}
|
|
628
|
-
const device = expectObject(value,
|
|
629
|
-
const id = parseOptionalString(device.id,
|
|
630
|
-
const version = parseOptionalPositiveInteger(device.version,
|
|
631
|
-
const family = parseOptionalString(device.family,
|
|
632
|
-
const model = parseOptionalString(device.model,
|
|
633
|
-
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");
|
|
634
792
|
return {
|
|
635
793
|
...(id === undefined ? {} : { id }),
|
|
636
794
|
...(version === undefined ? {} : { version }),
|
|
637
|
-
kind: parseCircuitDocumentDeviceKind(device.kind,
|
|
795
|
+
kind: parseCircuitDocumentDeviceKind(device.kind, "device.kind"),
|
|
638
796
|
...(family === undefined ? {} : { family }),
|
|
639
797
|
...(model === undefined ? {} : { model }),
|
|
640
798
|
...(audioProcessing === undefined ? {} : { audioProcessing }),
|
|
@@ -643,10 +801,10 @@ function parseDevice(value) {
|
|
|
643
801
|
function parseCircuitDocumentDeviceKind(value, path) {
|
|
644
802
|
const kind = expectString(value, path);
|
|
645
803
|
switch (kind) {
|
|
646
|
-
case
|
|
647
|
-
case
|
|
648
|
-
case
|
|
649
|
-
case
|
|
804
|
+
case "audio-pedal":
|
|
805
|
+
case "control-accessory":
|
|
806
|
+
case "utility":
|
|
807
|
+
case "unknown":
|
|
650
808
|
return kind;
|
|
651
809
|
default:
|
|
652
810
|
throw new Error(`${path}: expected audio-pedal, control-accessory, utility, or unknown`);
|
|
@@ -656,7 +814,7 @@ function parseControlOutputs(value) {
|
|
|
656
814
|
if (value === undefined) {
|
|
657
815
|
return undefined;
|
|
658
816
|
}
|
|
659
|
-
return optionalArray(value,
|
|
817
|
+
return optionalArray(value, "controlOutputs").map((item, index) => {
|
|
660
818
|
const path = `controlOutputs[${index}]`;
|
|
661
819
|
const controlOutput = expectObject(item, path);
|
|
662
820
|
const connector = parseOptionalControlInterfaceConnector(controlOutput.connector, `${path}.connector`);
|
|
@@ -686,8 +844,8 @@ function parseOptionalControlOutputSwitchMode(value, path) {
|
|
|
686
844
|
}
|
|
687
845
|
const switchMode = expectString(value, path);
|
|
688
846
|
switch (switchMode) {
|
|
689
|
-
case
|
|
690
|
-
case
|
|
847
|
+
case "momentary":
|
|
848
|
+
case "latching":
|
|
691
849
|
return switchMode;
|
|
692
850
|
default:
|
|
693
851
|
throw new Error(`${path}: expected momentary or latching`);
|
|
@@ -697,7 +855,7 @@ function parseControlInterfaces(value) {
|
|
|
697
855
|
if (value === undefined) {
|
|
698
856
|
return undefined;
|
|
699
857
|
}
|
|
700
|
-
return optionalArray(value,
|
|
858
|
+
return optionalArray(value, "controlInterfaces").map((item, index) => {
|
|
701
859
|
const path = `controlInterfaces[${index}]`;
|
|
702
860
|
const controlInterface = expectObject(item, path);
|
|
703
861
|
const componentId = parseOptionalString(controlInterface.componentId, `${path}.componentId`);
|
|
@@ -742,13 +900,13 @@ function parseOptionalControlInterfaceBinding(value, path) {
|
|
|
742
900
|
function parseControlInterfaceRole(value, path) {
|
|
743
901
|
const role = expectString(value, path);
|
|
744
902
|
switch (role) {
|
|
745
|
-
case
|
|
746
|
-
case
|
|
747
|
-
case
|
|
748
|
-
case
|
|
749
|
-
case
|
|
750
|
-
case
|
|
751
|
-
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":
|
|
752
910
|
return role;
|
|
753
911
|
default:
|
|
754
912
|
throw new Error(`${path}: expected external-control, tempo-tap, trigger, reset, sampler-trigger, expression, or unknown`);
|
|
@@ -760,12 +918,12 @@ function parseOptionalControlInterfaceConnector(value, path) {
|
|
|
760
918
|
}
|
|
761
919
|
const connector = expectString(value, path);
|
|
762
920
|
switch (connector) {
|
|
763
|
-
case
|
|
764
|
-
case
|
|
765
|
-
case
|
|
766
|
-
case
|
|
767
|
-
case
|
|
768
|
-
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":
|
|
769
927
|
return connector;
|
|
770
928
|
default:
|
|
771
929
|
throw new Error(`${path}: expected a supported connector kind`);
|
|
@@ -777,10 +935,10 @@ function parseOptionalControlInterfaceAssignmentHint(value, path) {
|
|
|
777
935
|
}
|
|
778
936
|
const hint = expectString(value, path);
|
|
779
937
|
switch (hint) {
|
|
780
|
-
case
|
|
781
|
-
case
|
|
782
|
-
case
|
|
783
|
-
case
|
|
938
|
+
case "momentary":
|
|
939
|
+
case "latching":
|
|
940
|
+
case "momentary-or-latching":
|
|
941
|
+
case "continuous":
|
|
784
942
|
return hint;
|
|
785
943
|
default:
|
|
786
944
|
throw new Error(`${path}: expected momentary, latching, momentary-or-latching, or continuous`);
|
|
@@ -792,10 +950,10 @@ function parseOptionalControlInterfacePolarity(value, path) {
|
|
|
792
950
|
}
|
|
793
951
|
const polarity = expectString(value, path);
|
|
794
952
|
switch (polarity) {
|
|
795
|
-
case
|
|
796
|
-
case
|
|
797
|
-
case
|
|
798
|
-
case
|
|
953
|
+
case "normally-open":
|
|
954
|
+
case "normally-closed":
|
|
955
|
+
case "expression":
|
|
956
|
+
case "unknown":
|
|
799
957
|
return polarity;
|
|
800
958
|
default:
|
|
801
959
|
throw new Error(`${path}: expected normally-open, normally-closed, expression, or unknown`);
|
|
@@ -804,12 +962,12 @@ function parseOptionalControlInterfacePolarity(value, path) {
|
|
|
804
962
|
function parseYamlSubset(source) {
|
|
805
963
|
const lines = tokenize(source);
|
|
806
964
|
if (lines.length === 0) {
|
|
807
|
-
throw new Error(
|
|
965
|
+
throw new Error("interchange YAML is empty");
|
|
808
966
|
}
|
|
809
967
|
const cursor = { index: 0 };
|
|
810
968
|
const first = lines[0];
|
|
811
969
|
if (first === undefined) {
|
|
812
|
-
throw new Error(
|
|
970
|
+
throw new Error("interchange YAML is empty");
|
|
813
971
|
}
|
|
814
972
|
const value = parseBlock(lines, cursor, first.indent);
|
|
815
973
|
if (cursor.index < lines.length) {
|
|
@@ -820,13 +978,13 @@ function parseYamlSubset(source) {
|
|
|
820
978
|
}
|
|
821
979
|
function tokenize(source) {
|
|
822
980
|
const lines = [];
|
|
823
|
-
const rawLines = source.replace(/^/,
|
|
981
|
+
const rawLines = source.replace(/^/, "").split(/\r?\n/);
|
|
824
982
|
rawLines.forEach((rawLine, index) => {
|
|
825
983
|
if (rawLine.trim().length === 0) {
|
|
826
984
|
return;
|
|
827
985
|
}
|
|
828
|
-
const indentText = rawLine.match(/^\s*/)?.[0] ??
|
|
829
|
-
if (indentText.includes(
|
|
986
|
+
const indentText = rawLine.match(/^\s*/)?.[0] ?? "";
|
|
987
|
+
if (indentText.includes("\t")) {
|
|
830
988
|
throw new Error(`line ${index + 1}: tabs are not supported in interchange YAML`);
|
|
831
989
|
}
|
|
832
990
|
lines.push({
|
|
@@ -845,7 +1003,7 @@ function parseBlock(lines, cursor, indent) {
|
|
|
845
1003
|
if (line.indent !== indent) {
|
|
846
1004
|
throw new Error(`line ${line.lineNumber}: expected indentation ${indent}, got ${line.indent}`);
|
|
847
1005
|
}
|
|
848
|
-
if (line.text ===
|
|
1006
|
+
if (line.text === "-" || line.text.startsWith("- ")) {
|
|
849
1007
|
return parseArray(lines, cursor, indent);
|
|
850
1008
|
}
|
|
851
1009
|
return parseObject(lines, cursor, indent);
|
|
@@ -860,14 +1018,15 @@ function parseObject(lines, cursor, indent) {
|
|
|
860
1018
|
if (line.indent > indent) {
|
|
861
1019
|
throw new Error(`line ${line.lineNumber}: unexpected indentation ${line.indent}`);
|
|
862
1020
|
}
|
|
863
|
-
if (line.text ===
|
|
1021
|
+
if (line.text === "-" || line.text.startsWith("- ")) {
|
|
864
1022
|
break;
|
|
865
1023
|
}
|
|
866
1024
|
const pair = parsePair(line.text, line.lineNumber);
|
|
867
1025
|
cursor.index += 1;
|
|
868
|
-
out[pair.key] =
|
|
869
|
-
|
|
870
|
-
|
|
1026
|
+
out[pair.key] =
|
|
1027
|
+
pair.rest.length > 0
|
|
1028
|
+
? parseInlineValue(pair.rest, line.lineNumber)
|
|
1029
|
+
: parseNestedValue(lines, cursor, indent, line.lineNumber);
|
|
871
1030
|
}
|
|
872
1031
|
return out;
|
|
873
1032
|
}
|
|
@@ -881,10 +1040,10 @@ function parseArray(lines, cursor, indent) {
|
|
|
881
1040
|
if (line.indent > indent) {
|
|
882
1041
|
throw new Error(`line ${line.lineNumber}: unexpected indentation ${line.indent}`);
|
|
883
1042
|
}
|
|
884
|
-
if (line.text !==
|
|
1043
|
+
if (line.text !== "-" && !line.text.startsWith("- ")) {
|
|
885
1044
|
break;
|
|
886
1045
|
}
|
|
887
|
-
const rest = line.text ===
|
|
1046
|
+
const rest = line.text === "-" ? "" : line.text.slice(2);
|
|
888
1047
|
cursor.index += 1;
|
|
889
1048
|
if (rest.length === 0) {
|
|
890
1049
|
out.push(parseNestedValue(lines, cursor, indent, line.lineNumber));
|
|
@@ -901,9 +1060,10 @@ function parseArray(lines, cursor, indent) {
|
|
|
901
1060
|
function parseObjectItem(firstPairText, lines, cursor, indent, lineNumber) {
|
|
902
1061
|
const out = {};
|
|
903
1062
|
const firstPair = parsePair(firstPairText, lineNumber);
|
|
904
|
-
out[firstPair.key] =
|
|
905
|
-
|
|
906
|
-
|
|
1063
|
+
out[firstPair.key] =
|
|
1064
|
+
firstPair.rest.length > 0
|
|
1065
|
+
? parseInlineValue(firstPair.rest, lineNumber)
|
|
1066
|
+
: parseNestedValue(lines, cursor, indent, lineNumber);
|
|
907
1067
|
while (cursor.index < lines.length) {
|
|
908
1068
|
const line = lines[cursor.index];
|
|
909
1069
|
if (line === undefined || line.indent < indent) {
|
|
@@ -912,14 +1072,15 @@ function parseObjectItem(firstPairText, lines, cursor, indent, lineNumber) {
|
|
|
912
1072
|
if (line.indent > indent) {
|
|
913
1073
|
throw new Error(`line ${line.lineNumber}: unexpected indentation ${line.indent}`);
|
|
914
1074
|
}
|
|
915
|
-
if (line.text ===
|
|
1075
|
+
if (line.text === "-" || line.text.startsWith("- ")) {
|
|
916
1076
|
break;
|
|
917
1077
|
}
|
|
918
1078
|
const pair = parsePair(line.text, line.lineNumber);
|
|
919
1079
|
cursor.index += 1;
|
|
920
|
-
out[pair.key] =
|
|
921
|
-
|
|
922
|
-
|
|
1080
|
+
out[pair.key] =
|
|
1081
|
+
pair.rest.length > 0
|
|
1082
|
+
? parseInlineValue(pair.rest, line.lineNumber)
|
|
1083
|
+
: parseNestedValue(lines, cursor, indent, line.lineNumber);
|
|
923
1084
|
}
|
|
924
1085
|
return out;
|
|
925
1086
|
}
|
|
@@ -942,7 +1103,7 @@ function parsePair(text, lineNumber) {
|
|
|
942
1103
|
const restText = text.slice(colonIndex + 1);
|
|
943
1104
|
return {
|
|
944
1105
|
key: parseKey(keyText, lineNumber),
|
|
945
|
-
rest: restText.startsWith(
|
|
1106
|
+
rest: restText.startsWith(" ") ? restText.slice(1) : restText,
|
|
946
1107
|
};
|
|
947
1108
|
}
|
|
948
1109
|
function looksLikePair(text) {
|
|
@@ -951,9 +1112,9 @@ function looksLikePair(text) {
|
|
|
951
1112
|
function findPairColon(text) {
|
|
952
1113
|
if (text.startsWith('"')) {
|
|
953
1114
|
const end = findJsonStringEnd(text);
|
|
954
|
-
return end >= 0 && text[end + 1] ===
|
|
1115
|
+
return end >= 0 && text[end + 1] === ":" ? end + 1 : -1;
|
|
955
1116
|
}
|
|
956
|
-
return text.indexOf(
|
|
1117
|
+
return text.indexOf(":");
|
|
957
1118
|
}
|
|
958
1119
|
function findJsonStringEnd(text) {
|
|
959
1120
|
let escaped = false;
|
|
@@ -963,7 +1124,7 @@ function findJsonStringEnd(text) {
|
|
|
963
1124
|
escaped = false;
|
|
964
1125
|
continue;
|
|
965
1126
|
}
|
|
966
|
-
if (char ===
|
|
1127
|
+
if (char === "\\") {
|
|
967
1128
|
escaped = true;
|
|
968
1129
|
continue;
|
|
969
1130
|
}
|
|
@@ -979,7 +1140,7 @@ function parseKey(text, lineNumber) {
|
|
|
979
1140
|
}
|
|
980
1141
|
try {
|
|
981
1142
|
const parsed = JSON.parse(text);
|
|
982
|
-
if (typeof parsed ===
|
|
1143
|
+
if (typeof parsed === "string") {
|
|
983
1144
|
return parsed;
|
|
984
1145
|
}
|
|
985
1146
|
}
|
|
@@ -989,25 +1150,25 @@ function parseKey(text, lineNumber) {
|
|
|
989
1150
|
throw new Error(`line ${lineNumber}: invalid quoted key`);
|
|
990
1151
|
}
|
|
991
1152
|
function parseInlineValue(text, lineNumber) {
|
|
992
|
-
if (text ===
|
|
1153
|
+
if (text === "[]") {
|
|
993
1154
|
return [];
|
|
994
1155
|
}
|
|
995
|
-
if (text ===
|
|
1156
|
+
if (text === "{}") {
|
|
996
1157
|
return {};
|
|
997
1158
|
}
|
|
998
|
-
if (text ===
|
|
1159
|
+
if (text === "null") {
|
|
999
1160
|
return null;
|
|
1000
1161
|
}
|
|
1001
|
-
if (text ===
|
|
1162
|
+
if (text === "true") {
|
|
1002
1163
|
return true;
|
|
1003
1164
|
}
|
|
1004
|
-
if (text ===
|
|
1165
|
+
if (text === "false") {
|
|
1005
1166
|
return false;
|
|
1006
1167
|
}
|
|
1007
1168
|
if (text.startsWith('"')) {
|
|
1008
1169
|
try {
|
|
1009
1170
|
const parsed = JSON.parse(text);
|
|
1010
|
-
if (typeof parsed ===
|
|
1171
|
+
if (typeof parsed === "string") {
|
|
1011
1172
|
return parsed;
|
|
1012
1173
|
}
|
|
1013
1174
|
}
|
|
@@ -1022,7 +1183,7 @@ function parseInlineValue(text, lineNumber) {
|
|
|
1022
1183
|
return text;
|
|
1023
1184
|
}
|
|
1024
1185
|
function parseMetadata(value) {
|
|
1025
|
-
const metadata = optionalObject(value,
|
|
1186
|
+
const metadata = optionalObject(value, "metadata");
|
|
1026
1187
|
return {
|
|
1027
1188
|
name: scalarText(metadata.name),
|
|
1028
1189
|
description: scalarText(metadata.description),
|
|
@@ -1030,30 +1191,32 @@ function parseMetadata(value) {
|
|
|
1030
1191
|
};
|
|
1031
1192
|
}
|
|
1032
1193
|
function parseSource(value) {
|
|
1033
|
-
return parseStringRecord(value,
|
|
1194
|
+
return parseStringRecord(value, "source");
|
|
1034
1195
|
}
|
|
1035
1196
|
function parsePanel(value, allowV3PhysicalFields) {
|
|
1036
1197
|
if (value === undefined) {
|
|
1037
1198
|
return undefined;
|
|
1038
1199
|
}
|
|
1039
|
-
const panel = expectObject(value,
|
|
1200
|
+
const panel = expectObject(value, "panel");
|
|
1040
1201
|
if (panel.faces !== undefined) {
|
|
1041
1202
|
return {
|
|
1042
|
-
faces: optionalArray(panel.faces,
|
|
1203
|
+
faces: optionalArray(panel.faces, "panel.faces").map((item, index) => parsePanelFace(item, index, allowV3PhysicalFields)),
|
|
1043
1204
|
};
|
|
1044
1205
|
}
|
|
1045
1206
|
if (panel.layout === undefined) {
|
|
1046
1207
|
return undefined;
|
|
1047
1208
|
}
|
|
1048
|
-
const layout = parsePanelLayout(panel.layout,
|
|
1209
|
+
const layout = parsePanelLayout(panel.layout, "panel.layout");
|
|
1049
1210
|
const elementsValue = panel.controls ?? panel.elements;
|
|
1050
|
-
const elementsPath = panel.controls === undefined ?
|
|
1211
|
+
const elementsPath = panel.controls === undefined ? "panel.elements" : "panel.controls";
|
|
1051
1212
|
return {
|
|
1052
|
-
faces: [
|
|
1053
|
-
|
|
1213
|
+
faces: [
|
|
1214
|
+
{
|
|
1215
|
+
id: "top",
|
|
1054
1216
|
layout,
|
|
1055
1217
|
elements: parsePanelElements(elementsValue, layout, elementsPath, allowV3PhysicalFields),
|
|
1056
|
-
}
|
|
1218
|
+
},
|
|
1219
|
+
],
|
|
1057
1220
|
};
|
|
1058
1221
|
}
|
|
1059
1222
|
function parsePanelFace(value, index, allowV3PhysicalFields) {
|
|
@@ -1064,7 +1227,9 @@ function parsePanelFace(value, index, allowV3PhysicalFields) {
|
|
|
1064
1227
|
if (!allowV3PhysicalFields && face.geometry !== undefined) {
|
|
1065
1228
|
throw new Error(`${path}.geometry: requires schema ${INTERCHANGE_SCHEMA_V3}`);
|
|
1066
1229
|
}
|
|
1067
|
-
const geometry = allowV3PhysicalFields
|
|
1230
|
+
const geometry = allowV3PhysicalFields
|
|
1231
|
+
? parseOptionalPanelFaceGeometry(face.geometry, `${path}.geometry`)
|
|
1232
|
+
: undefined;
|
|
1068
1233
|
return {
|
|
1069
1234
|
id: expectString(face.id, `${path}.id`),
|
|
1070
1235
|
...(label === undefined ? {} : { label }),
|
|
@@ -1098,7 +1263,9 @@ function parsePanelElements(value, layout, path, allowV3PhysicalFields) {
|
|
|
1098
1263
|
if (!allowV3PhysicalFields && element.physical !== undefined) {
|
|
1099
1264
|
throw new Error(`${elementPath}.physical: requires schema ${INTERCHANGE_SCHEMA_V3}`);
|
|
1100
1265
|
}
|
|
1101
|
-
const id = allowV3PhysicalFields
|
|
1266
|
+
const id = allowV3PhysicalFields
|
|
1267
|
+
? parseOptionalString(element.id, `${elementPath}.id`)
|
|
1268
|
+
: undefined;
|
|
1102
1269
|
const physical = allowV3PhysicalFields
|
|
1103
1270
|
? parseOptionalPanelElementPhysical(element.physical, `${elementPath}.physical`)
|
|
1104
1271
|
: undefined;
|
|
@@ -1122,11 +1289,17 @@ function parseOptionalPanelFaceGeometry(value, path) {
|
|
|
1122
1289
|
const geometry = expectObject(value, path);
|
|
1123
1290
|
return {
|
|
1124
1291
|
...parseBuildDataObject(geometry, path),
|
|
1125
|
-
...(geometry.units === undefined
|
|
1126
|
-
|
|
1292
|
+
...(geometry.units === undefined
|
|
1293
|
+
? {}
|
|
1294
|
+
: { units: expectString(geometry.units, `${path}.units`) }),
|
|
1295
|
+
...(geometry.surface === undefined
|
|
1296
|
+
? {}
|
|
1297
|
+
: { surface: expectString(geometry.surface, `${path}.surface`) }),
|
|
1127
1298
|
...(geometry.usableRectMm === undefined
|
|
1128
1299
|
? {}
|
|
1129
|
-
: {
|
|
1300
|
+
: {
|
|
1301
|
+
usableRectMm: parseMillimeterRect(geometry.usableRectMm, `${path}.usableRectMm`),
|
|
1302
|
+
}),
|
|
1130
1303
|
};
|
|
1131
1304
|
}
|
|
1132
1305
|
function parseOptionalPanelElementPhysical(value, path) {
|
|
@@ -1136,15 +1309,31 @@ function parseOptionalPanelElementPhysical(value, path) {
|
|
|
1136
1309
|
const physical = expectObject(value, path);
|
|
1137
1310
|
return {
|
|
1138
1311
|
...parseBuildDataObject(physical, path),
|
|
1139
|
-
...(physical.units === undefined
|
|
1140
|
-
|
|
1312
|
+
...(physical.units === undefined
|
|
1313
|
+
? {}
|
|
1314
|
+
: { units: expectString(physical.units, `${path}.units`) }),
|
|
1315
|
+
...(physical.centerMm === undefined
|
|
1316
|
+
? {}
|
|
1317
|
+
: { centerMm: parsePoint(physical.centerMm, `${path}.centerMm`) }),
|
|
1141
1318
|
...(physical.drillDiameterMm === undefined
|
|
1142
1319
|
? {}
|
|
1143
|
-
: {
|
|
1320
|
+
: {
|
|
1321
|
+
drillDiameterMm: expectNumber(physical.drillDiameterMm, `${path}.drillDiameterMm`),
|
|
1322
|
+
}),
|
|
1144
1323
|
...(physical.partProfileId === undefined
|
|
1145
1324
|
? {}
|
|
1146
|
-
: {
|
|
1147
|
-
|
|
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`) }),
|
|
1148
1337
|
};
|
|
1149
1338
|
}
|
|
1150
1339
|
function parseMillimeterRect(value, path) {
|
|
@@ -1179,8 +1368,8 @@ function parsePanelGridPosition(value, path, layout) {
|
|
|
1179
1368
|
const columnSpan = parseOptionalPositiveInteger(grid.columnSpan, `${path}.columnSpan`);
|
|
1180
1369
|
const row = expectNonNegativeInteger(grid.row, `${path}.row`);
|
|
1181
1370
|
const column = expectNonNegativeInteger(grid.column, `${path}.column`);
|
|
1182
|
-
validateGridAxis(row, rowSpan ?? 1, layout.rows, layout.indexing, `${path}.row`,
|
|
1183
|
-
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");
|
|
1184
1373
|
return {
|
|
1185
1374
|
row,
|
|
1186
1375
|
column,
|
|
@@ -1189,23 +1378,23 @@ function parsePanelGridPosition(value, path, layout) {
|
|
|
1189
1378
|
};
|
|
1190
1379
|
}
|
|
1191
1380
|
function validateGridAxis(value, span, size, indexing, path, axisName) {
|
|
1192
|
-
const min = indexing ===
|
|
1193
|
-
const occupiedEnd = indexing ===
|
|
1381
|
+
const min = indexing === "one-based" ? 1 : 0;
|
|
1382
|
+
const occupiedEnd = indexing === "one-based" ? value + span - 1 : value + span;
|
|
1194
1383
|
if (value < min || occupiedEnd > size) {
|
|
1195
|
-
const maxLabel = indexing ===
|
|
1384
|
+
const maxLabel = indexing === "one-based" ? String(size) : String(size - 1);
|
|
1196
1385
|
throw new Error(`${path}: expected ${indexing} ${axisName} coordinate within ${min}..${maxLabel}`);
|
|
1197
1386
|
}
|
|
1198
1387
|
}
|
|
1199
1388
|
function parsePanelLayoutKind(value, path) {
|
|
1200
1389
|
const kind = expectString(value, path);
|
|
1201
|
-
if (kind ===
|
|
1390
|
+
if (kind === "stompbox-grid") {
|
|
1202
1391
|
return kind;
|
|
1203
1392
|
}
|
|
1204
1393
|
throw new Error(`${path}: expected stompbox-grid`);
|
|
1205
1394
|
}
|
|
1206
1395
|
function parsePanelGridIndexing(value, path) {
|
|
1207
1396
|
const indexing = expectString(value, path);
|
|
1208
|
-
if (indexing ===
|
|
1397
|
+
if (indexing === "one-based" || indexing === "zero-based") {
|
|
1209
1398
|
return indexing;
|
|
1210
1399
|
}
|
|
1211
1400
|
throw new Error(`${path}: expected one-based or zero-based`);
|
|
@@ -1215,7 +1404,7 @@ function parseOptionalPanelRowOrder(value, path) {
|
|
|
1215
1404
|
return undefined;
|
|
1216
1405
|
}
|
|
1217
1406
|
const order = expectString(value, path);
|
|
1218
|
-
if (order ===
|
|
1407
|
+
if (order === "top-to-bottom" || order === "bottom-to-top") {
|
|
1219
1408
|
return order;
|
|
1220
1409
|
}
|
|
1221
1410
|
throw new Error(`${path}: expected top-to-bottom or bottom-to-top`);
|
|
@@ -1225,7 +1414,7 @@ function parseOptionalPanelColumnOrder(value, path) {
|
|
|
1225
1414
|
return undefined;
|
|
1226
1415
|
}
|
|
1227
1416
|
const order = expectString(value, path);
|
|
1228
|
-
if (order ===
|
|
1417
|
+
if (order === "left-to-right" || order === "right-to-left") {
|
|
1229
1418
|
return order;
|
|
1230
1419
|
}
|
|
1231
1420
|
throw new Error(`${path}: expected left-to-right or right-to-left`);
|
|
@@ -1233,20 +1422,20 @@ function parseOptionalPanelColumnOrder(value, path) {
|
|
|
1233
1422
|
function parsePanelControlKind(value, path) {
|
|
1234
1423
|
const kind = expectString(value, path);
|
|
1235
1424
|
switch (kind) {
|
|
1236
|
-
case
|
|
1237
|
-
case
|
|
1238
|
-
case
|
|
1239
|
-
case
|
|
1240
|
-
case
|
|
1241
|
-
case
|
|
1242
|
-
case
|
|
1425
|
+
case "knob":
|
|
1426
|
+
case "slider":
|
|
1427
|
+
case "switch":
|
|
1428
|
+
case "selector":
|
|
1429
|
+
case "footswitch":
|
|
1430
|
+
case "led":
|
|
1431
|
+
case "jack":
|
|
1243
1432
|
return kind;
|
|
1244
1433
|
default:
|
|
1245
1434
|
throw new Error(`${path}: expected knob, slider, switch, selector, footswitch, led, or jack`);
|
|
1246
1435
|
}
|
|
1247
1436
|
}
|
|
1248
1437
|
function parseComponents(value) {
|
|
1249
|
-
return optionalArray(value,
|
|
1438
|
+
return optionalArray(value, "components").map((item, index) => {
|
|
1250
1439
|
const path = `components[${index}]`;
|
|
1251
1440
|
const component = expectObject(item, path);
|
|
1252
1441
|
return {
|
|
@@ -1307,7 +1496,7 @@ function isParsedQuantityValue(value) {
|
|
|
1307
1496
|
return isParsedQuantity(value);
|
|
1308
1497
|
}
|
|
1309
1498
|
function parseWires(value) {
|
|
1310
|
-
return optionalArray(value,
|
|
1499
|
+
return optionalArray(value, "wires").map((item, index) => {
|
|
1311
1500
|
const path = `wires[${index}]`;
|
|
1312
1501
|
const wire = expectObject(item, path);
|
|
1313
1502
|
const points = expectArray(wire.points, `${path}.points`);
|
|
@@ -1323,7 +1512,7 @@ function parseWires(value) {
|
|
|
1323
1512
|
});
|
|
1324
1513
|
}
|
|
1325
1514
|
function parseWarnings(value) {
|
|
1326
|
-
return optionalArray(value,
|
|
1515
|
+
return optionalArray(value, "diagnostics").map((item, index) => {
|
|
1327
1516
|
const path = `diagnostics[${index}]`;
|
|
1328
1517
|
const warning = expectObject(item, path);
|
|
1329
1518
|
const out = {
|
|
@@ -1331,7 +1520,9 @@ function parseWarnings(value) {
|
|
|
1331
1520
|
message: expectString(warning.message, `${path}.message`),
|
|
1332
1521
|
...(warning.componentId === undefined
|
|
1333
1522
|
? {}
|
|
1334
|
-
: {
|
|
1523
|
+
: {
|
|
1524
|
+
componentId: expectString(warning.componentId, `${path}.componentId`),
|
|
1525
|
+
}),
|
|
1335
1526
|
...(warning.wireId === undefined
|
|
1336
1527
|
? {}
|
|
1337
1528
|
: { wireId: expectString(warning.wireId, `${path}.wireId`) }),
|
|
@@ -1373,41 +1564,41 @@ function parseNullableString(value, path) {
|
|
|
1373
1564
|
function parseComponentKind(value, path) {
|
|
1374
1565
|
const kind = expectString(value, path);
|
|
1375
1566
|
switch (kind) {
|
|
1376
|
-
case
|
|
1377
|
-
case
|
|
1378
|
-
case
|
|
1379
|
-
case
|
|
1380
|
-
case
|
|
1381
|
-
case
|
|
1382
|
-
case
|
|
1383
|
-
case
|
|
1384
|
-
case
|
|
1385
|
-
case
|
|
1386
|
-
case
|
|
1387
|
-
case
|
|
1388
|
-
case
|
|
1389
|
-
case
|
|
1390
|
-
case
|
|
1391
|
-
case
|
|
1392
|
-
case
|
|
1393
|
-
case
|
|
1394
|
-
case
|
|
1395
|
-
case
|
|
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
|
|
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":
|
|
1411
1602
|
return kind;
|
|
1412
1603
|
default:
|
|
1413
1604
|
throw new Error(`${path}: unsupported component kind "${kind}"`);
|
|
@@ -1438,13 +1629,13 @@ function expectArray(value, path) {
|
|
|
1438
1629
|
throw new Error(`${path}: expected array`);
|
|
1439
1630
|
}
|
|
1440
1631
|
function expectString(value, path) {
|
|
1441
|
-
if (typeof value ===
|
|
1632
|
+
if (typeof value === "string") {
|
|
1442
1633
|
return value;
|
|
1443
1634
|
}
|
|
1444
1635
|
throw new Error(`${path}: expected string`);
|
|
1445
1636
|
}
|
|
1446
1637
|
function expectNumber(value, path) {
|
|
1447
|
-
if (typeof value ===
|
|
1638
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
1448
1639
|
return value;
|
|
1449
1640
|
}
|
|
1450
1641
|
throw new Error(`${path}: expected number`);
|
|
@@ -1494,14 +1685,14 @@ function parseOptionalBoolean(value, path) {
|
|
|
1494
1685
|
return expectBoolean(value, path);
|
|
1495
1686
|
}
|
|
1496
1687
|
function expectBoolean(value, path) {
|
|
1497
|
-
if (typeof value ===
|
|
1688
|
+
if (typeof value === "boolean") {
|
|
1498
1689
|
return value;
|
|
1499
1690
|
}
|
|
1500
1691
|
throw new Error(`${path}: expected boolean`);
|
|
1501
1692
|
}
|
|
1502
|
-
function scalarText(value, path =
|
|
1693
|
+
function scalarText(value, path = "value") {
|
|
1503
1694
|
if (value === undefined || value === null) {
|
|
1504
|
-
return
|
|
1695
|
+
return "";
|
|
1505
1696
|
}
|
|
1506
1697
|
if (isScalar(value)) {
|
|
1507
1698
|
return String(value);
|
|
@@ -1509,9 +1700,15 @@ function scalarText(value, path = 'value') {
|
|
|
1509
1700
|
throw new Error(`${path}: expected scalar`);
|
|
1510
1701
|
}
|
|
1511
1702
|
function isScalar(value) {
|
|
1512
|
-
return value === null ||
|
|
1703
|
+
return (value === null ||
|
|
1704
|
+
typeof value === "string" ||
|
|
1705
|
+
typeof value === "number" ||
|
|
1706
|
+
typeof value === "boolean");
|
|
1513
1707
|
}
|
|
1514
1708
|
function isYamlObject(value) {
|
|
1515
|
-
return value !== undefined &&
|
|
1709
|
+
return (value !== undefined &&
|
|
1710
|
+
value !== null &&
|
|
1711
|
+
typeof value === "object" &&
|
|
1712
|
+
!Array.isArray(value));
|
|
1516
1713
|
}
|
|
1517
1714
|
//# sourceMappingURL=parser.js.map
|