onshape 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/partstudio.js +31 -0
- package/dist/builders/modeling.js +229 -0
- package/dist/cli.js +101 -5
- package/package.json +1 -1
package/dist/api/partstudio.js
CHANGED
|
@@ -47,6 +47,34 @@ class PartStudioManager {
|
|
|
47
47
|
rollbackIndex: index,
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
+
async validateFeature(documentId, workspaceId, elementId, featureId) {
|
|
51
|
+
const features = await this.getFeatures(documentId, workspaceId, elementId);
|
|
52
|
+
const states = isRecord(features) && isRecord(features.featureStates) ? features.featureStates : {};
|
|
53
|
+
const state = isRecord(states[featureId]) ? states[featureId] : {};
|
|
54
|
+
const status = typeof state.featureStatus === "string" ? state.featureStatus : null;
|
|
55
|
+
if (status === "ERROR") {
|
|
56
|
+
throw new Error(`Feature ${featureId} regenerated with status ERROR.`);
|
|
57
|
+
}
|
|
58
|
+
return { featureId, featureStatus: status };
|
|
59
|
+
}
|
|
60
|
+
async validatePartStudio(documentId, workspaceId, elementId, expectations = {}) {
|
|
61
|
+
const partsRaw = await this.getParts(documentId, workspaceId, elementId);
|
|
62
|
+
const parts = Array.isArray(partsRaw) ? partsRaw : [];
|
|
63
|
+
const massRaw = await this.client.get(`/api/v6/partstudios/d/${documentId}/w/${workspaceId}/e/${elementId}/massproperties`);
|
|
64
|
+
const bodiesRecord = isRecord(massRaw) && isRecord(massRaw.bodies) ? massRaw.bodies : {};
|
|
65
|
+
const bodyCount = Object.keys(bodiesRecord).length;
|
|
66
|
+
if (expectations.parts !== undefined && parts.length !== expectations.parts) {
|
|
67
|
+
throw new Error(`Expected ${expectations.parts} part(s), found ${parts.length}.`);
|
|
68
|
+
}
|
|
69
|
+
if (expectations.bodies !== undefined && bodyCount !== expectations.bodies) {
|
|
70
|
+
throw new Error(`Expected ${expectations.bodies} bod(y/ies), found ${bodyCount}.`);
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
parts: parts.length,
|
|
74
|
+
bodies: bodyCount,
|
|
75
|
+
partIds: parts.map((part) => (isRecord(part) ? part.partId : undefined)).filter(Boolean),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
50
78
|
}
|
|
51
79
|
exports.PartStudioManager = PartStudioManager;
|
|
52
80
|
function loadJson(inline, file) {
|
|
@@ -55,3 +83,6 @@ function loadJson(inline, file) {
|
|
|
55
83
|
throw new Error("Expected JSON via --json or --json-file");
|
|
56
84
|
return JSON.parse(raw);
|
|
57
85
|
}
|
|
86
|
+
function isRecord(value) {
|
|
87
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
88
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.planeId = planeId;
|
|
4
|
+
exports.parsePoint2 = parsePoint2;
|
|
5
|
+
exports.buildCircleSketch = buildCircleSketch;
|
|
6
|
+
exports.buildCircleAxisSketch = buildCircleAxisSketch;
|
|
7
|
+
exports.buildExtrude = buildExtrude;
|
|
8
|
+
exports.buildRevolve = buildRevolve;
|
|
9
|
+
exports.buildBooleanUnion = buildBooleanUnion;
|
|
10
|
+
const INCH_TO_METER = 0.0254;
|
|
11
|
+
const PLANE_IDS = {
|
|
12
|
+
front: "JCC",
|
|
13
|
+
top: "JDC",
|
|
14
|
+
right: "JEC",
|
|
15
|
+
};
|
|
16
|
+
function planeId(name) {
|
|
17
|
+
const value = PLANE_IDS[name.toLowerCase()];
|
|
18
|
+
if (!value)
|
|
19
|
+
throw new Error(`Unknown plane '${name}'. Use Front, Top, or Right.`);
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
function parsePoint2(value) {
|
|
23
|
+
const parts = value.split(",").map((part) => Number(part.trim()));
|
|
24
|
+
if (parts.length !== 2 || parts.some((part) => !Number.isFinite(part))) {
|
|
25
|
+
throw new Error(`Expected a 2D point as x,y; got '${value}'.`);
|
|
26
|
+
}
|
|
27
|
+
return [parts[0], parts[1]];
|
|
28
|
+
}
|
|
29
|
+
function toMeters(value) {
|
|
30
|
+
return value * INCH_TO_METER;
|
|
31
|
+
}
|
|
32
|
+
function circleEntity(id, center, radius) {
|
|
33
|
+
return {
|
|
34
|
+
btType: "BTMSketchCurve-4",
|
|
35
|
+
entityId: id,
|
|
36
|
+
centerId: `${id}.center`,
|
|
37
|
+
geometry: {
|
|
38
|
+
btType: "BTCurveGeometryCircle-115",
|
|
39
|
+
radius: toMeters(radius),
|
|
40
|
+
xCenter: toMeters(center[0]),
|
|
41
|
+
yCenter: toMeters(center[1]),
|
|
42
|
+
xDir: 1,
|
|
43
|
+
yDir: 0,
|
|
44
|
+
clockwise: false,
|
|
45
|
+
},
|
|
46
|
+
isConstruction: false,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function lineEntity(id, start, end, isConstruction = false) {
|
|
50
|
+
const x1 = toMeters(start[0]);
|
|
51
|
+
const y1 = toMeters(start[1]);
|
|
52
|
+
const x2 = toMeters(end[0]);
|
|
53
|
+
const y2 = toMeters(end[1]);
|
|
54
|
+
const dx = x2 - x1;
|
|
55
|
+
const dy = y2 - y1;
|
|
56
|
+
const length = Math.hypot(dx, dy);
|
|
57
|
+
if (length === 0)
|
|
58
|
+
throw new Error("Line start and end must be different.");
|
|
59
|
+
return {
|
|
60
|
+
btType: "BTMSketchCurveSegment-155",
|
|
61
|
+
entityId: id,
|
|
62
|
+
startPointId: `${id}.start`,
|
|
63
|
+
endPointId: `${id}.end`,
|
|
64
|
+
startParam: 0,
|
|
65
|
+
endParam: length,
|
|
66
|
+
geometry: {
|
|
67
|
+
btType: "BTCurveGeometryLine-117",
|
|
68
|
+
pntX: x1,
|
|
69
|
+
pntY: y1,
|
|
70
|
+
dirX: dx / length,
|
|
71
|
+
dirY: dy / length,
|
|
72
|
+
},
|
|
73
|
+
isConstruction,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function sketch(name, sketchPlaneId, entities) {
|
|
77
|
+
return {
|
|
78
|
+
feature: {
|
|
79
|
+
btType: "BTMSketch-151",
|
|
80
|
+
featureType: "newSketch",
|
|
81
|
+
name,
|
|
82
|
+
suppressed: false,
|
|
83
|
+
parameters: [
|
|
84
|
+
{
|
|
85
|
+
btType: "BTMParameterQueryList-148",
|
|
86
|
+
queries: [{ btType: "BTMIndividualQuery-138", deterministicIds: [sketchPlaneId] }],
|
|
87
|
+
parameterId: "sketchPlane",
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
entities,
|
|
91
|
+
constraints: [],
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function pEnum(parameterId, enumName, value) {
|
|
96
|
+
return {
|
|
97
|
+
btType: "BTMParameterEnum-145",
|
|
98
|
+
namespace: "",
|
|
99
|
+
enumName,
|
|
100
|
+
value,
|
|
101
|
+
parameterId,
|
|
102
|
+
parameterName: "",
|
|
103
|
+
libraryRelationType: "NONE",
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function pBool(parameterId, value) {
|
|
107
|
+
return {
|
|
108
|
+
btType: "BTMParameterBoolean-144",
|
|
109
|
+
value,
|
|
110
|
+
parameterId,
|
|
111
|
+
parameterName: "",
|
|
112
|
+
libraryRelationType: "NONE",
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function pQuantity(parameterId, value, units) {
|
|
116
|
+
return {
|
|
117
|
+
btType: "BTMParameterQuantity-147",
|
|
118
|
+
isInteger: false,
|
|
119
|
+
value,
|
|
120
|
+
units: "",
|
|
121
|
+
expression: `${value} ${units}`,
|
|
122
|
+
parameterId,
|
|
123
|
+
parameterName: "",
|
|
124
|
+
libraryRelationType: "NONE",
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function pQuery(parameterId, queryString, featureId) {
|
|
128
|
+
return {
|
|
129
|
+
btType: "BTMParameterQueryList-148",
|
|
130
|
+
queries: [
|
|
131
|
+
{
|
|
132
|
+
btType: "BTMIndividualQuery-138",
|
|
133
|
+
queryStatement: null,
|
|
134
|
+
queryString,
|
|
135
|
+
...(featureId ? { featureId } : {}),
|
|
136
|
+
deterministicIds: [],
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
parameterId,
|
|
140
|
+
parameterName: "",
|
|
141
|
+
libraryRelationType: "NONE",
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function sketchRegion(parameterId, sketchFeatureId) {
|
|
145
|
+
return {
|
|
146
|
+
btType: "BTMParameterQueryList-148",
|
|
147
|
+
queries: [
|
|
148
|
+
{
|
|
149
|
+
btType: "BTMIndividualSketchRegionQuery-140",
|
|
150
|
+
queryStatement: null,
|
|
151
|
+
filterInnerLoops: true,
|
|
152
|
+
queryString: `query = qSketchRegion(id + "${sketchFeatureId}", true);`,
|
|
153
|
+
featureId: sketchFeatureId,
|
|
154
|
+
deterministicIds: [],
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
parameterId,
|
|
158
|
+
parameterName: "",
|
|
159
|
+
libraryRelationType: "NONE",
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function buildCircleSketch(input) {
|
|
163
|
+
return sketch(input.name, planeId(input.plane), [circleEntity("circle.1", input.center, input.radius)]);
|
|
164
|
+
}
|
|
165
|
+
function buildCircleAxisSketch(input) {
|
|
166
|
+
return sketch(input.name, planeId(input.plane), [
|
|
167
|
+
circleEntity("profile.circle", input.center, input.radius),
|
|
168
|
+
lineEntity("axis.1", input.axisStart, input.axisEnd, true),
|
|
169
|
+
]);
|
|
170
|
+
}
|
|
171
|
+
function buildExtrude(input) {
|
|
172
|
+
return {
|
|
173
|
+
btType: "BTFeatureDefinitionCall-1406",
|
|
174
|
+
feature: {
|
|
175
|
+
btType: "BTMFeature-134",
|
|
176
|
+
featureType: "extrude",
|
|
177
|
+
name: input.name,
|
|
178
|
+
suppressed: false,
|
|
179
|
+
namespace: "",
|
|
180
|
+
parameters: [
|
|
181
|
+
sketchRegion("entities", input.sketchFeatureId),
|
|
182
|
+
pEnum("operationType", "NewBodyOperationType", input.operationType),
|
|
183
|
+
pQuantity("depth", input.depth, "in"),
|
|
184
|
+
pBool("oppositeDirection", false),
|
|
185
|
+
pBool("defaultScope", true),
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function buildRevolve(input) {
|
|
191
|
+
return {
|
|
192
|
+
btType: "BTFeatureDefinitionCall-1406",
|
|
193
|
+
feature: {
|
|
194
|
+
btType: "BTMFeature-134",
|
|
195
|
+
featureType: "revolve",
|
|
196
|
+
name: input.name,
|
|
197
|
+
suppressed: false,
|
|
198
|
+
namespace: "",
|
|
199
|
+
parameters: [
|
|
200
|
+
pEnum("bodyType", "ExtendedToolBodyType", "SOLID"),
|
|
201
|
+
pEnum("operationType", "NewBodyOperationType", input.operationType),
|
|
202
|
+
sketchRegion("entities", input.sketchFeatureId),
|
|
203
|
+
pQuery("axis", `query = qConstructionFilter(qCreatedBy(makeId("${input.sketchFeatureId}"), EntityType.EDGE), ConstructionObject.YES);`, input.sketchFeatureId),
|
|
204
|
+
pBool("fullRevolve", false),
|
|
205
|
+
pEnum("endBound", "RevolveBoundingType", "BLIND"),
|
|
206
|
+
pQuantity("angle", input.angle, "deg"),
|
|
207
|
+
pBool("defaultScope", true),
|
|
208
|
+
],
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function buildBooleanUnion() {
|
|
213
|
+
return {
|
|
214
|
+
btType: "BTFeatureDefinitionCall-1406",
|
|
215
|
+
feature: {
|
|
216
|
+
btType: "BTMFeature-134",
|
|
217
|
+
featureType: "booleanBodies",
|
|
218
|
+
name: "Union bodies",
|
|
219
|
+
suppressed: false,
|
|
220
|
+
namespace: "",
|
|
221
|
+
parameters: [
|
|
222
|
+
pEnum("operationType", "BooleanOperationType", "UNION"),
|
|
223
|
+
pBool("defaultScope", false),
|
|
224
|
+
pQuery("tools", "query = qAllModifiableSolidBodies();"),
|
|
225
|
+
pBool("toolsExplicit", true),
|
|
226
|
+
],
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
}
|
package/dist/cli.js
CHANGED
|
@@ -41,6 +41,7 @@ const client_1 = require("./api/client");
|
|
|
41
41
|
const documents_1 = require("./api/documents");
|
|
42
42
|
const edges_1 = require("./api/edges");
|
|
43
43
|
const partstudio_1 = require("./api/partstudio");
|
|
44
|
+
const modeling_1 = require("./builders/modeling");
|
|
44
45
|
const output_1 = require("./output");
|
|
45
46
|
async function main(argv) {
|
|
46
47
|
try {
|
|
@@ -104,6 +105,12 @@ async function run(argv) {
|
|
|
104
105
|
case "add-feature":
|
|
105
106
|
case "update-feature":
|
|
106
107
|
case "rollback":
|
|
108
|
+
case "sketch-circle":
|
|
109
|
+
case "sketch-circle-axis":
|
|
110
|
+
case "extrude":
|
|
111
|
+
case "revolve":
|
|
112
|
+
case "boolean-union":
|
|
113
|
+
case "validate-partstudio":
|
|
107
114
|
case "get-edges":
|
|
108
115
|
case "find-circular-edges":
|
|
109
116
|
case "find-edges-by-feature":
|
|
@@ -127,7 +134,7 @@ function parseArgs(argv) {
|
|
|
127
134
|
if (eq !== -1) {
|
|
128
135
|
options[key] = item.slice(eq + 1);
|
|
129
136
|
}
|
|
130
|
-
else if (argv[index + 1] && !argv[index + 1].startsWith("-")) {
|
|
137
|
+
else if (argv[index + 1] && (!argv[index + 1].startsWith("-") || isNegativeValue(argv[index + 1]))) {
|
|
131
138
|
options[key] = argv[index + 1];
|
|
132
139
|
index += 1;
|
|
133
140
|
}
|
|
@@ -147,6 +154,9 @@ function parseArgs(argv) {
|
|
|
147
154
|
}
|
|
148
155
|
return { command, positionals, options };
|
|
149
156
|
}
|
|
157
|
+
function isNegativeValue(value) {
|
|
158
|
+
return /^-\d/.test(value) || /^-\.\d/.test(value);
|
|
159
|
+
}
|
|
150
160
|
async function handleConfig(parsed) {
|
|
151
161
|
const action = parsed.positionals[0];
|
|
152
162
|
const store = new credentials_1.CredentialStore();
|
|
@@ -324,7 +334,7 @@ async function handleReadCommand(parsed) {
|
|
|
324
334
|
case "add-feature": {
|
|
325
335
|
const { doc, ws, elem } = dwe(parsed.options);
|
|
326
336
|
const feature = requiredJson(parsed.options);
|
|
327
|
-
(0, output_1.emit)(await
|
|
337
|
+
(0, output_1.emit)(await addFeatureResult(partstudios, doc, ws, elem, feature, !parsed.options.noValidate));
|
|
328
338
|
return;
|
|
329
339
|
}
|
|
330
340
|
case "update-feature": {
|
|
@@ -338,6 +348,67 @@ async function handleReadCommand(parsed) {
|
|
|
338
348
|
(0, output_1.emit)(await partstudios.rollback(doc, ws, elem, requiredNumberOption(parsed.options, "index")));
|
|
339
349
|
return;
|
|
340
350
|
}
|
|
351
|
+
case "sketch-circle": {
|
|
352
|
+
const { doc, ws, elem } = dwe(parsed.options);
|
|
353
|
+
(0, output_1.emit)(await addFeatureResult(partstudios, doc, ws, elem, (0, modeling_1.buildCircleSketch)({
|
|
354
|
+
name: stringOption(parsed.options, "name") ?? "Sketch circle",
|
|
355
|
+
plane: stringOption(parsed.options, "plane") ?? "Front",
|
|
356
|
+
center: parsePointOption(parsed.options, "center"),
|
|
357
|
+
radius: requiredNumberOption(parsed.options, "radius"),
|
|
358
|
+
}), !parsed.options.noValidate));
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
case "sketch-circle-axis": {
|
|
362
|
+
const { doc, ws, elem } = dwe(parsed.options);
|
|
363
|
+
(0, output_1.emit)(await addFeatureResult(partstudios, doc, ws, elem, (0, modeling_1.buildCircleAxisSketch)({
|
|
364
|
+
name: stringOption(parsed.options, "name") ?? "Sketch circle and axis",
|
|
365
|
+
plane: stringOption(parsed.options, "plane") ?? "Front",
|
|
366
|
+
center: parsePointOption(parsed.options, "center"),
|
|
367
|
+
radius: requiredNumberOption(parsed.options, "radius"),
|
|
368
|
+
axisStart: parsePointOption(parsed.options, "axisStart"),
|
|
369
|
+
axisEnd: parsePointOption(parsed.options, "axisEnd"),
|
|
370
|
+
}), !parsed.options.noValidate));
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
case "extrude": {
|
|
374
|
+
const { doc, ws, elem } = dwe(parsed.options);
|
|
375
|
+
(0, output_1.emit)(await addFeatureResult(partstudios, doc, ws, elem, (0, modeling_1.buildExtrude)({
|
|
376
|
+
name: stringOption(parsed.options, "name") ?? "Extrude",
|
|
377
|
+
sketchFeatureId: requiredOption(parsed.options, "sketch"),
|
|
378
|
+
depth: requiredNumberOption(parsed.options, "depth"),
|
|
379
|
+
operationType: stringOption(parsed.options, "op") ?? "NEW",
|
|
380
|
+
}), !parsed.options.noValidate));
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
case "revolve": {
|
|
384
|
+
const { doc, ws, elem } = dwe(parsed.options);
|
|
385
|
+
(0, output_1.emit)(await addFeatureResult(partstudios, doc, ws, elem, (0, modeling_1.buildRevolve)({
|
|
386
|
+
name: stringOption(parsed.options, "name") ?? "Revolve",
|
|
387
|
+
sketchFeatureId: requiredOption(parsed.options, "sketch"),
|
|
388
|
+
angle: numberOption(parsed.options, "angle", 360),
|
|
389
|
+
operationType: stringOption(parsed.options, "op") ?? "NEW",
|
|
390
|
+
}), !parsed.options.noValidate));
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
case "boolean-union": {
|
|
394
|
+
const { doc, ws, elem } = dwe(parsed.options);
|
|
395
|
+
(0, output_1.emit)(await addFeatureResult(partstudios, doc, ws, elem, (0, modeling_1.buildBooleanUnion)(), !parsed.options.noValidate));
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
case "validate-partstudio": {
|
|
399
|
+
const { doc, ws, elem } = dwe(parsed.options);
|
|
400
|
+
try {
|
|
401
|
+
(0, output_1.emit)(await partstudios.validatePartStudio(doc, ws, elem, {
|
|
402
|
+
parts: optionalNumberOption(parsed.options, "expectParts"),
|
|
403
|
+
bodies: optionalNumberOption(parsed.options, "expectBodies"),
|
|
404
|
+
}));
|
|
405
|
+
}
|
|
406
|
+
catch (error) {
|
|
407
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
408
|
+
throw new output_1.CliError(message, null, 1);
|
|
409
|
+
}
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
341
412
|
case "get-edges": {
|
|
342
413
|
const { doc, ws, elem } = dwe(parsed.options);
|
|
343
414
|
(0, output_1.emit)(await edges.getEdges(doc, ws, elem));
|
|
@@ -362,10 +433,20 @@ async function handleReadCommand(parsed) {
|
|
|
362
433
|
}
|
|
363
434
|
}
|
|
364
435
|
}
|
|
365
|
-
async function
|
|
366
|
-
const response = await
|
|
436
|
+
async function addFeatureResult(partstudios, doc, ws, elem, feature, validate) {
|
|
437
|
+
const response = await partstudios.addFeature(doc, ws, elem, feature);
|
|
367
438
|
const featureId = isRecord(response) && isRecord(response.feature) ? response.feature.featureId ?? null : null;
|
|
368
|
-
|
|
439
|
+
const result = { featureId, response };
|
|
440
|
+
if (validate && typeof featureId === "string") {
|
|
441
|
+
try {
|
|
442
|
+
result.validation = await partstudios.validateFeature(doc, ws, elem, featureId);
|
|
443
|
+
}
|
|
444
|
+
catch (error) {
|
|
445
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
446
|
+
throw new output_1.CliError(message, { featureId, response }, 1);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
return result;
|
|
369
450
|
}
|
|
370
451
|
function isRecord(value) {
|
|
371
452
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
@@ -419,6 +500,15 @@ function requiredNumberOption(options, key) {
|
|
|
419
500
|
function requiredOption(options, key) {
|
|
420
501
|
return stringOption(options, key) ?? missing(key);
|
|
421
502
|
}
|
|
503
|
+
function parsePointOption(options, key) {
|
|
504
|
+
try {
|
|
505
|
+
return (0, modeling_1.parsePoint2)(requiredOption(options, key));
|
|
506
|
+
}
|
|
507
|
+
catch (error) {
|
|
508
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
509
|
+
throw new output_1.CliError(message, null, 2);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
422
512
|
function requiredJson(options) {
|
|
423
513
|
try {
|
|
424
514
|
return (0, partstudio_1.loadJson)(stringOption(options, "json"), stringOption(options, "jsonFile"));
|
|
@@ -470,6 +560,12 @@ Commands:
|
|
|
470
560
|
add-feature
|
|
471
561
|
update-feature
|
|
472
562
|
rollback
|
|
563
|
+
sketch-circle
|
|
564
|
+
sketch-circle-axis
|
|
565
|
+
extrude
|
|
566
|
+
revolve
|
|
567
|
+
boolean-union
|
|
568
|
+
validate-partstudio
|
|
473
569
|
get-edges
|
|
474
570
|
find-circular-edges
|
|
475
571
|
find-edges-by-feature
|