Compare commits
26 Commits
kcl-test-s
...
nrc-refact
Author | SHA1 | Date | |
---|---|---|---|
7fd9eb3322 | |||
5aef2b72cb | |||
8ccdf2286d | |||
054e235362 | |||
3eebd36a41 | |||
412417411b | |||
a1c9dd99cf | |||
3ed873b6e9 | |||
a172e606b4 | |||
c42967d0e7 | |||
cb8fc33adb | |||
2dc8b429ff | |||
19ffa220e8 | |||
5332ddd88e | |||
11d9a2ee00 | |||
bfebc41a5c | |||
824b4c823e | |||
785002fa4e | |||
f650281855 | |||
9f6999829a | |||
a14bbaa237 | |||
0706624381 | |||
ef0ae5e06e | |||
a010743abb | |||
057ee479c3 | |||
7218efc489 |
@ -1,3 +1,3 @@
|
||||
[codespell]
|
||||
ignore-words-list: crate,everytime,inout,co-ordinate,ot,nwo,absolutey,atleast,ue,afterall
|
||||
skip: **/target,node_modules,build,**/Cargo.lock,./docs/kcl/*.md,.yarn.lock,**/yarn.lock
|
||||
skip: **/target,node_modules,build,**/Cargo.lock,./docs/kcl/*.md,.yarn.lock,**/yarn.lock,./openapi/*.json,./src/lib/machine-api.d.ts
|
||||
|
@ -211,7 +211,7 @@ jobs:
|
||||
out/*-x86_64-linux.*
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||
if: ${{ env.BUILD_RELEASE == 'true' }}
|
||||
with:
|
||||
name: out-yml
|
||||
path: |
|
||||
|
@ -9,7 +9,7 @@ Draw a line segment relative to the current origin using the polar
|
||||
measure of some angle and distance.
|
||||
|
||||
```js
|
||||
angledLine(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
angledLine(data: AngledLineData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ angledLine(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`AngledLineData`](/docs/kcl/types/AngledLineData) | Data to draw an angled line. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Create a line segment from the current 2-dimensional sketch origin
|
||||
along some angle (in degrees) for some relative length in the 'x' dimension.
|
||||
|
||||
```js
|
||||
angledLineOfXLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
angledLineOfXLength(data: AngledLineData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ angledLineOfXLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`AngledLineData`](/docs/kcl/types/AngledLineData) | Data to draw an angled line. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Create a line segment from the current 2-dimensional sketch origin
|
||||
along some angle (in degrees) for some relative length in the 'y' dimension.
|
||||
|
||||
```js
|
||||
angledLineOfYLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
angledLineOfYLength(data: AngledLineData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ angledLineOfYLength(data: AngledLineData, sketch: Sketch, tag?: TagDeclarator) -
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`AngledLineData`](/docs/kcl/types/AngledLineData) | Data to draw an angled line. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Draw an angled line from the current origin, constructing a line segment
|
||||
such that the newly created line intersects the desired target line segment.
|
||||
|
||||
```js
|
||||
angledLineThatIntersects(data: AngledLineThatIntersectsData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
angledLineThatIntersects(data: AngledLineThatIntersectsData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ angledLineThatIntersects(data: AngledLineThatIntersectsData, sketch: Sketch, tag
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`AngledLineThatIntersectsData`](/docs/kcl/types/AngledLineThatIntersectsData) | Data for drawing an angled line that intersects with a given line. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Create a line segment from the current 2-dimensional sketch origin
|
||||
along some angle (in degrees) for some length, ending at the provided value in the 'x' dimension.
|
||||
|
||||
```js
|
||||
angledLineToX(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
angledLineToX(data: AngledLineToData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ angledLineToX(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sk
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`AngledLineToData`](/docs/kcl/types/AngledLineToData) | Data to draw an angled line to a point. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Create a line segment from the current 2-dimensional sketch origin
|
||||
along some angle (in degrees) for some length, ending at the provided value in the 'y' dimension.
|
||||
|
||||
```js
|
||||
angledLineToY(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
angledLineToY(data: AngledLineToData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ angledLineToY(data: AngledLineToData, sketch: Sketch, tag?: TagDeclarator) -> Sk
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`AngledLineToData`](/docs/kcl/types/AngledLineToData) | Data to draw an angled line to a point. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -11,7 +11,7 @@ The arc is constructed such that the current position of the sketch is placed al
|
||||
Unless this makes a lot of sense and feels like what you're looking for to construct your shape, you're likely looking for tangentialArc.
|
||||
|
||||
```js
|
||||
arc(data: ArcData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
arc(data: ArcData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ arc(data: ArcData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`ArcData`](/docs/kcl/types/ArcData) | Data to draw an arc. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Draw a smooth, continuous, curved line segment from the current origin to
|
||||
the desired (x, y), using a number of control points to shape the curve's shape.
|
||||
|
||||
```js
|
||||
bezierCurve(data: BezierData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
bezierCurve(data: BezierData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ bezierCurve(data: BezierData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`BezierData`](/docs/kcl/types/BezierData) | Data to draw a bezier curve. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Cut a straight transitional edge along a tagged path.
|
||||
Chamfer is similar in function and use to a fillet, except a fillet will blend the transition along an edge, rather than cut a sharp, straight transitional edge.
|
||||
|
||||
```js
|
||||
chamfer(data: ChamferData, solid: Solid, tag?: TagDeclarator) -> Solid
|
||||
chamfer(data: ChamferData, solid: Solid, tag?: TagNode) -> Solid
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ chamfer(data: ChamferData, solid: Solid, tag?: TagDeclarator) -> Solid
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`ChamferData`](/docs/kcl/types/ChamferData) | Data for chamfers. | Yes |
|
||||
| `solid` | [`Solid`](/docs/kcl/types/Solid) | An solid is a collection of extrude surfaces. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Construct a 2-dimensional circle, of the specified radius, centered at
|
||||
the provided (x, y) origin point.
|
||||
|
||||
```js
|
||||
circle(data: CircleData, sketch_surface_or_group: SketchOrSurface, tag?: TagDeclarator) -> Sketch
|
||||
circle(data: CircleData, sketch_surface_or_group: SketchOrSurface, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ circle(data: CircleData, sketch_surface_or_group: SketchOrSurface, tag?: TagDecl
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`CircleData`](/docs/kcl/types/CircleData) | Data for drawing an circle | Yes |
|
||||
| `sketch_surface_or_group` | [`SketchOrSurface`](/docs/kcl/types/SketchOrSurface) | A sketch surface or a sketch. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Construct a line segment from the current origin back to the profile's
|
||||
origin, ensuring the resulting 2-dimensional sketch is not open-ended.
|
||||
|
||||
```js
|
||||
close(sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
close(sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ close(sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
| Name | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Blend a transitional edge along a tagged path, smoothing the sharp edge.
|
||||
Fillet is similar in function and use to a chamfer, except a chamfer will cut a sharp transition along an edge while fillet will smoothly blend the transition.
|
||||
|
||||
```js
|
||||
fillet(data: FilletData, solid: Solid, tag?: TagDeclarator) -> Solid
|
||||
fillet(data: FilletData, solid: Solid, tag?: TagNode) -> Solid
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ fillet(data: FilletData, solid: Solid, tag?: TagDeclarator) -> Solid
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`FilletData`](/docs/kcl/types/FilletData) | Data for fillets. | Yes |
|
||||
| `solid` | [`Solid`](/docs/kcl/types/Solid) | An solid is a collection of extrude surfaces. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Draw a line relative to the current origin to a specified (x, y) away
|
||||
from the current position.
|
||||
|
||||
```js
|
||||
line(delta: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
line(delta: [number], sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ line(delta: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `delta` | `[number]` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Draw a line from the current origin to some absolute (x, y) point.
|
||||
|
||||
|
||||
```js
|
||||
lineTo(to: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
lineTo(to: [number], sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ lineTo(to: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `to` | `[number]` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Start a new profile at a given point.
|
||||
|
||||
|
||||
```js
|
||||
startProfileAt(to: [number], sketch_surface: SketchSurface, tag?: TagDeclarator) -> Sketch
|
||||
startProfileAt(to: [number], sketch_surface: SketchSurface, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ startProfileAt(to: [number], sketch_surface: SketchSurface, tag?: TagDeclarator)
|
||||
|----------|------|-------------|----------|
|
||||
| `to` | `[number]` | | Yes |
|
||||
| `sketch_surface` | [`SketchSurface`](/docs/kcl/types/SketchSurface) | A sketch type. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
17373
docs/kcl/std.json
@ -9,7 +9,7 @@ Draw a curved line segment along part of an imaginary circle.
|
||||
The arc is constructed such that the last line segment is placed tangent to the imaginary circle of the specified radius. The resulting arc is the segment of the imaginary circle from that tangent point for 'offset' degrees along the imaginary circle.
|
||||
|
||||
```js
|
||||
tangentialArc(data: TangentialArcData, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
tangentialArc(data: TangentialArcData, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ tangentialArc(data: TangentialArcData, sketch: Sketch, tag?: TagDeclarator) -> S
|
||||
|----------|------|-------------|----------|
|
||||
| `data` | [`TangentialArcData`](/docs/kcl/types/TangentialArcData) | Data to draw a tangential arc. | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Starting at the current sketch's origin, draw a curved line segment along
|
||||
some part of an imaginary circle until it reaches the desired (x, y) coordinates.
|
||||
|
||||
```js
|
||||
tangentialArcTo(to: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
tangentialArcTo(to: [number], sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ tangentialArcTo(to: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `to` | `[number]` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Starting at the current sketch's origin, draw a curved line segment along
|
||||
some part of an imaginary circle until it reaches a point the given (x, y) distance away.
|
||||
|
||||
```js
|
||||
tangentialArcToRelative(delta: [number], sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
tangentialArcToRelative(delta: [number], sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ tangentialArcToRelative(delta: [number], sketch: Sketch, tag?: TagDeclarator) ->
|
||||
|----------|------|-------------|----------|
|
||||
| `delta` | `[number]` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -18,7 +18,7 @@ A base path.
|
||||
|----------|------|-------------|----------|
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
|
@ -22,12 +22,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Literal`| | No |
|
||||
| `type` |enum: [`Literal`](/docs/kcl/types/Literal)| | No |
|
||||
| `kind` |[`Literal`](/docs/kcl/types/Literal)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `value` |[`LiteralValue`](/docs/kcl/types/LiteralValue)| | No |
|
||||
| `raw` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -43,10 +41,9 @@ layout: manual
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `kind` |[`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -61,13 +58,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `BinaryExpression`| | No |
|
||||
| `type` |enum: [`BinaryExpression`](/docs/kcl/types/BinaryExpression)| | No |
|
||||
| `kind` |[`BinaryExpression`](/docs/kcl/types/BinaryExpression)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `operator` |[`BinaryOperator`](/docs/kcl/types/BinaryOperator)| | No |
|
||||
| `left` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| | No |
|
||||
| `right` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -82,13 +76,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `CallExpression`| | No |
|
||||
| `type` |enum: [`CallExpression`](/docs/kcl/types/CallExpression)| | No |
|
||||
| `kind` |[`CallExpression`](/docs/kcl/types/CallExpression)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `callee` |[`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `arguments` |`[` [`Expr`](/docs/kcl/types/Expr) `]`| | No |
|
||||
| `optional` |`boolean`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -103,12 +94,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `UnaryExpression`| | No |
|
||||
| `type` |enum: [`UnaryExpression`](/docs/kcl/types/UnaryExpression)| | No |
|
||||
| `kind` |[`UnaryExpression`](/docs/kcl/types/UnaryExpression)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `operator` |[`UnaryOperator`](/docs/kcl/types/UnaryOperator)| | No |
|
||||
| `argument` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -123,13 +112,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `MemberExpression`| | No |
|
||||
| `type` |enum: [`MemberExpression`](/docs/kcl/types/MemberExpression)| | No |
|
||||
| `kind` |[`MemberExpression`](/docs/kcl/types/MemberExpression)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `object` |[`MemberObject`](/docs/kcl/types/MemberObject)| | No |
|
||||
| `property` |[`LiteralIdentifier`](/docs/kcl/types/LiteralIdentifier)| | No |
|
||||
| `computed` |`boolean`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -144,14 +130,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `IfExpression`| | No |
|
||||
| `type` |enum: [`IfExpression`](/docs/kcl/types/IfExpression)| | No |
|
||||
| `kind` |[`IfExpression`](/docs/kcl/types/IfExpression)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `cond` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `then_val` |[`Program`](/docs/kcl/types/Program)| | No |
|
||||
| `else_ifs` |`[` [`ElseIf`](/docs/kcl/types/ElseIf) `]`| | No |
|
||||
| `final_else` |[`Program`](/docs/kcl/types/Program)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
@ -22,13 +22,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `ImportStatement`| | No |
|
||||
| `type` |enum: [`ImportStatement`](/docs/kcl/types/ImportStatement)| | No |
|
||||
| `kind` |[`ImportStatement`](/docs/kcl/types/ImportStatement)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `items` |`[` [`ImportItem`](/docs/kcl/types/ImportItem) `]`| | No |
|
||||
| `path` |`string`| | No |
|
||||
| `raw_path` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -43,11 +40,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `ExpressionStatement`| | No |
|
||||
| `type` |enum: [`ExpressionStatement`](/docs/kcl/types/ExpressionStatement)| | No |
|
||||
| `kind` |[`ExpressionStatement`](/docs/kcl/types/ExpressionStatement)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `expression` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -62,13 +58,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `VariableDeclaration`| | No |
|
||||
| `type` |enum: [`VariableDeclaration`](/docs/kcl/types/VariableDeclaration)| | No |
|
||||
| `kind` |[`VariableDeclaration`](/docs/kcl/types/VariableDeclaration)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `declarations` |`[` [`VariableDeclarator`](/docs/kcl/types/VariableDeclarator) `]`| | No |
|
||||
| `visibility` |[`ItemVisibility`](/docs/kcl/types/ItemVisibility)| | No |
|
||||
| `kind` |[`VariableKind`](/docs/kcl/types/VariableKind)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -83,11 +76,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `ReturnStatement`| | No |
|
||||
| `type` |enum: [`ReturnStatement`](/docs/kcl/types/ReturnStatement)| | No |
|
||||
| `kind` |[`ReturnStatement`](/docs/kcl/types/ReturnStatement)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `argument` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
@ -28,7 +28,7 @@ A fillet.
|
||||
| `id` |`string`| The id of the engine command that called this fillet. | No |
|
||||
| `radius` |`number`| | No |
|
||||
| `edgeId` |`string`| The engine id of the edge to fillet. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -48,7 +48,7 @@ A chamfer.
|
||||
| `id` |`string`| The id of the engine command that called this chamfer. | No |
|
||||
| `length` |`number`| | No |
|
||||
| `edgeId` |`string`| The engine id of the edge to chamfer. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| | No |
|
||||
|
||||
|
||||
----
|
||||
|
@ -15,10 +15,8 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `cond` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `then_val` |[`Program`](/docs/kcl/types/Program)| | No |
|
||||
| `then_val` |[`UnboxedNode_for_Program`](/docs/kcl/types/UnboxedNode_for_Program)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
|
@ -23,12 +23,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Literal`| | No |
|
||||
| `type` |enum: [`Literal`](/docs/kcl/types/Literal)| | No |
|
||||
| `kind` |[`Literal`](/docs/kcl/types/Literal)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `value` |[`LiteralValue`](/docs/kcl/types/LiteralValue)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `raw` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -44,10 +42,9 @@ An expression can be evaluated to yield a single KCL value.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `kind` |[`Identifier`](/docs/kcl/types/Identifier)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -63,10 +60,9 @@ An expression can be evaluated to yield a single KCL value.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`TagDeclarator`](/docs/kcl/types#tag-declaration)| | No |
|
||||
| `kind` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `value` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -81,13 +77,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `BinaryExpression`| | No |
|
||||
| `type` |enum: [`BinaryExpression`](/docs/kcl/types/BinaryExpression)| | No |
|
||||
| `kind` |[`BinaryExpression`](/docs/kcl/types/BinaryExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `operator` |[`BinaryOperator`](/docs/kcl/types/BinaryOperator)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `left` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `right` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -103,11 +96,9 @@ An expression can be evaluated to yield a single KCL value.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`FunctionExpression`](/docs/kcl/types/FunctionExpression)| | No |
|
||||
| `kind` |[`FunctionExpression`](/docs/kcl/types/FunctionExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `params` |`[` [`Parameter`](/docs/kcl/types/Parameter) `]`| | No |
|
||||
| `body` |[`Program`](/docs/kcl/types/Program)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -122,13 +113,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `CallExpression`| | No |
|
||||
| `type` |enum: [`CallExpression`](/docs/kcl/types/CallExpression)| | No |
|
||||
| `kind` |[`CallExpression`](/docs/kcl/types/CallExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `callee` |[`Identifier`](/docs/kcl/types/Identifier)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `arguments` |`[` [`Expr`](/docs/kcl/types/Expr) `]`| | No |
|
||||
| `optional` |`boolean`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -143,12 +131,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `PipeExpression`| | No |
|
||||
| `type` |enum: [`PipeExpression`](/docs/kcl/types/PipeExpression)| | No |
|
||||
| `kind` |[`PipeExpression`](/docs/kcl/types/PipeExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `body` |`[` [`Expr`](/docs/kcl/types/Expr) `]`| | No |
|
||||
| `nonCodeMeta` |[`NonCodeMeta`](/docs/kcl/types/NonCodeMeta)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -163,10 +149,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `PipeSubstitution`| | No |
|
||||
| `type` |enum: [`PipeSubstitution`](/docs/kcl/types/PipeSubstitution)| | No |
|
||||
| `kind` |[`PipeSubstitution`](/docs/kcl/types/PipeSubstitution)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -181,12 +167,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `ArrayExpression`| | No |
|
||||
| `type` |enum: [`ArrayExpression`](/docs/kcl/types/ArrayExpression)| | No |
|
||||
| `kind` |[`ArrayExpression`](/docs/kcl/types/ArrayExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `elements` |`[` [`Expr`](/docs/kcl/types/Expr) `]`| | No |
|
||||
| `nonCodeMeta` |[`NonCodeMeta`](/docs/kcl/types/NonCodeMeta)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -201,13 +185,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `ArrayRangeExpression`| | No |
|
||||
| `type` |enum: [`ArrayRangeExpression`](/docs/kcl/types/ArrayRangeExpression)| | No |
|
||||
| `kind` |[`ArrayRangeExpression`](/docs/kcl/types/ArrayRangeExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `startElement` |[`Expr`](/docs/kcl/types/Expr)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `endElement` |[`Expr`](/docs/kcl/types/Expr)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `endInclusive` |`boolean`| Is the `end_element` included in the range? | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -222,12 +203,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `ObjectExpression`| | No |
|
||||
| `type` |enum: [`ObjectExpression`](/docs/kcl/types/ObjectExpression)| | No |
|
||||
| `kind` |[`ObjectExpression`](/docs/kcl/types/ObjectExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `properties` |`[` [`ObjectProperty`](/docs/kcl/types/ObjectProperty) `]`| | No |
|
||||
| `nonCodeMeta` |[`NonCodeMeta`](/docs/kcl/types/NonCodeMeta)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -242,13 +221,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `MemberExpression`| | No |
|
||||
| `type` |enum: [`MemberExpression`](/docs/kcl/types/MemberExpression)| | No |
|
||||
| `kind` |[`MemberExpression`](/docs/kcl/types/MemberExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `object` |[`MemberObject`](/docs/kcl/types/MemberObject)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `property` |[`LiteralIdentifier`](/docs/kcl/types/LiteralIdentifier)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `computed` |`boolean`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -263,12 +239,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `UnaryExpression`| | No |
|
||||
| `type` |enum: [`UnaryExpression`](/docs/kcl/types/UnaryExpression)| | No |
|
||||
| `kind` |[`UnaryExpression`](/docs/kcl/types/UnaryExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `operator` |[`UnaryOperator`](/docs/kcl/types/UnaryOperator)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `argument` |[`BinaryPart`](/docs/kcl/types/BinaryPart)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -283,14 +257,10 @@ An expression can be evaluated to yield a single KCL value.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `IfExpression`| | No |
|
||||
| `type` |enum: [`IfExpression`](/docs/kcl/types/IfExpression)| | No |
|
||||
| `kind` |[`IfExpression`](/docs/kcl/types/IfExpression)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `cond` |[`Expr`](/docs/kcl/types/Expr)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `then_val` |[`Program`](/docs/kcl/types/Program)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `else_ifs` |`[` [`ElseIf`](/docs/kcl/types/ElseIf) `]`| | No |
|
||||
| `final_else` |[`Program`](/docs/kcl/types/Program)| An expression can be evaluated to yield a single KCL value. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
@ -26,7 +26,7 @@ An extrude plane.
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `extrudePlane`| | No |
|
||||
| `faceId` |`string`| The face id for the extrude plane. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag. | No |
|
||||
| `id` |`string`| The id of the geometry. | No |
|
||||
| `sourceRange` |`SourceRange`| The source range. | No |
|
||||
|
||||
@ -46,7 +46,7 @@ An extruded arc.
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `extrudeArc`| | No |
|
||||
| `faceId` |`string`| The face id for the extrude plane. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag. | No |
|
||||
| `id` |`string`| The id of the geometry. | No |
|
||||
| `sourceRange` |`SourceRange`| The source range. | No |
|
||||
|
||||
@ -66,7 +66,7 @@ Geometry metadata.
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `chamfer`| | No |
|
||||
| `faceId` |`string`| The id for the chamfer surface. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag. | No |
|
||||
| `id` |`string`| The id of the geometry. | No |
|
||||
| `sourceRange` |`SourceRange`| The source range. | No |
|
||||
|
||||
@ -86,7 +86,7 @@ Geometry metadata.
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `fillet`| | No |
|
||||
| `faceId` |`string`| The id for the fillet surface. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag. | No |
|
||||
| `id` |`string`| The id of the geometry. | No |
|
||||
| `sourceRange` |`SourceRange`| The source range. | No |
|
||||
|
||||
|
@ -15,10 +15,8 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `params` |`[` [`Parameter`](/docs/kcl/types/Parameter) `]`| | No |
|
||||
| `body` |[`Program`](/docs/kcl/types/Program)| | No |
|
||||
| `body` |[`UnboxedNode_for_Program`](/docs/kcl/types/UnboxedNode_for_Program)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
|
@ -15,8 +15,6 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
@ -15,10 +15,8 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `name` |[`Identifier`](/docs/kcl/types/Identifier)| Name of the item to import. | No |
|
||||
| `alias` |[`Identifier`](/docs/kcl/types/Identifier)| Rename the item using an identifier after "as". | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `name` |[`UnboxedNode_for_Identifier`](/docs/kcl/types/UnboxedNode_for_Identifier)| Name of the item to import. | No |
|
||||
| `alias` |[`UnboxedNode_for_Identifier`](/docs/kcl/types/UnboxedNode_for_Identifier)| Rename the item using an identifier after "as". | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
|
@ -59,10 +59,9 @@ Any KCL value.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`TagDeclarator`](/docs/kcl/types#tag-declaration)| | No |
|
||||
| `kind` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| Any KCL value. | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `value` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -183,7 +182,7 @@ Data for an imported geometry.
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Function`| | No |
|
||||
| `expression` |[`FunctionExpression`](/docs/kcl/types/FunctionExpression)| Any KCL value. | No |
|
||||
| `expression` |[`UnboxedNode_for_FunctionExpression`](/docs/kcl/types/UnboxedNode_for_FunctionExpression)| Any KCL value. | No |
|
||||
| `memory` |[`ProgramMemory`](/docs/kcl/types/ProgramMemory)| Any KCL value. | No |
|
||||
| `__meta` |`[` [`Metadata`](/docs/kcl/types/Metadata) `]`| | No |
|
||||
|
||||
|
@ -23,10 +23,9 @@ layout: manual
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `kind` |[`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -41,12 +40,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `Literal`| | No |
|
||||
| `type` |enum: [`Literal`](/docs/kcl/types/Literal)| | No |
|
||||
| `kind` |[`Literal`](/docs/kcl/types/Literal)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `value` |[`LiteralValue`](/docs/kcl/types/LiteralValue)| | No |
|
||||
| `raw` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
@ -22,13 +22,10 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: `MemberExpression`| | No |
|
||||
| `type` |enum: [`MemberExpression`](/docs/kcl/types/MemberExpression)| | No |
|
||||
| `kind` |[`MemberExpression`](/docs/kcl/types/MemberExpression)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `object` |[`MemberObject`](/docs/kcl/types/MemberObject)| | No |
|
||||
| `property` |[`LiteralIdentifier`](/docs/kcl/types/LiteralIdentifier)| | No |
|
||||
| `computed` |`boolean`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
@ -44,10 +41,9 @@ layout: manual
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `type` |enum: [`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `kind` |[`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `name` |`string`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
----
|
||||
|
@ -16,7 +16,7 @@ layout: manual
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `nonCodeNodes` |`object`| | No |
|
||||
| `start` |`[` [`NonCodeNode`](/docs/kcl/types/NonCodeNode) `]`| | No |
|
||||
| `start` |`[` [`UnboxedNode_for_NonCodeNode`](/docs/kcl/types/UnboxedNode_for_NonCodeNode) `]`| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
|
@ -15,8 +15,6 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `value` |[`NonCodeValue`](/docs/kcl/types/NonCodeValue)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
@ -15,9 +15,7 @@ layout: manual
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `key` |[`Identifier`](/docs/kcl/types/Identifier)| | No |
|
||||
| `key` |[`UnboxedNode_for_Identifier`](/docs/kcl/types/UnboxedNode_for_Identifier)| | No |
|
||||
| `value` |[`Expr`](/docs/kcl/types/Expr)| | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
@ -16,7 +16,7 @@ Parameter of a KCL function.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `identifier` |[`Identifier`](/docs/kcl/types/Identifier)| The parameter's label or name. | No |
|
||||
| `identifier` |[`UnboxedNode_for_Identifier`](/docs/kcl/types/UnboxedNode_for_Identifier)| The parameter's label or name. | No |
|
||||
| `optional` |`boolean`| Is the parameter optional? | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
@ -27,7 +27,7 @@ A path that goes to a point.
|
||||
| `type` |enum: `ToPoint`| | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ A arc that is tangential to the last path segment that goes to a point
|
||||
| `ccw` |`boolean`| arc's direction | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
@ -71,7 +71,7 @@ A arc that is tangential to the last path segment
|
||||
| `ccw` |`boolean`| arc's direction | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ a complete arc
|
||||
| `ccw` |`boolean`| arc's direction | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
@ -115,7 +115,7 @@ A path that is horizontal.
|
||||
| `x` |`number`| The x coordinate. | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
@ -137,7 +137,7 @@ An angled line to.
|
||||
| `y` |`number`| The y coordinate. | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
@ -157,7 +157,7 @@ A base path.
|
||||
| `type` |enum: `Base`| | No |
|
||||
| `from` |`[number, number]`| The from point. | No |
|
||||
| `to` |`[number, number]`| The to point. | No |
|
||||
| `tag` |[`TagDeclarator`](/docs/kcl/types#tag-declaration)| The tag of the path. | No |
|
||||
| `tag` |[`TagNode`](/docs/kcl/types/TagNode)| The tag of the path. | No |
|
||||
| `__geoMeta` |[`GeoMeta`](/docs/kcl/types/GeoMeta)| Metadata. | No |
|
||||
|
||||
|
||||
|
@ -16,10 +16,8 @@ A KCL program top level, or function body.
|
||||
|
||||
| Property | Type | Description | Required |
|
||||
|----------|------|-------------|----------|
|
||||
| `start` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `end` |[`EnvironmentRef`](/docs/kcl/types/EnvironmentRef)| | No |
|
||||
| `body` |`[` [`BodyItem`](/docs/kcl/types/BodyItem) `]`| | No |
|
||||
| `nonCodeMeta` |[`NonCodeMeta`](/docs/kcl/types/NonCodeMeta)| A KCL program top level, or function body. | No |
|
||||
| `nonCodeMeta` |[`UnboxedNode_for_NonCodeMeta`](/docs/kcl/types/UnboxedNode_for_NonCodeMeta)| A KCL program top level, or function body. | No |
|
||||
| `digest` |`[, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`, `integer`]`| | No |
|
||||
|
||||
|
||||
|
@ -9,7 +9,7 @@ Draw a line relative to the current origin to a specified distance away
|
||||
from the current position along the 'x' axis.
|
||||
|
||||
```js
|
||||
xLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
xLine(length: number, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ xLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `length` | `number` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Draw a line parallel to the X axis, that ends at the given X.
|
||||
E.g. if the previous line ended at (1, 1), then xLineTo(4) draws a line from (1, 1) to (4, 1)
|
||||
|
||||
```js
|
||||
xLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
xLineTo(to: number, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ xLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `to` | `number` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Draw a line relative to the current origin to a specified distance away
|
||||
from the current position along the 'y' axis.
|
||||
|
||||
```js
|
||||
yLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
yLine(length: number, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ yLine(length: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `length` | `number` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -9,7 +9,7 @@ Draw a line parallel to the Y axis, that ends at the given Y.
|
||||
E.g. if the previous line ended at (1, 1), then yLineTo(4) draws a line from (1, 1) to (1, 4)
|
||||
|
||||
```js
|
||||
yLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
yLineTo(to: number, sketch: Sketch, tag?: TagNode) -> Sketch
|
||||
```
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ yLineTo(to: number, sketch: Sketch, tag?: TagDeclarator) -> Sketch
|
||||
|----------|------|-------------|----------|
|
||||
| `to` | `number` | | Yes |
|
||||
| `sketch` | [`Sketch`](/docs/kcl/types/Sketch) | A sketch is a collection of paths. | Yes |
|
||||
| `tag` | [`TagDeclarator`](/docs/kcl/types#tag-declaration) | | No |
|
||||
| `tag` | [`TagNode`](/docs/kcl/types/TagNode) | | No |
|
||||
|
||||
### Returns
|
||||
|
||||
|
@ -313,3 +313,45 @@ test(
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
'external change of file contents are reflected in editor',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const PROJECT_DIR_NAME = 'lee-was-here'
|
||||
const {
|
||||
electronApp,
|
||||
page,
|
||||
dir: projectsDir,
|
||||
} = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
const aProjectDir = join(dir, PROJECT_DIR_NAME)
|
||||
await fsp.mkdir(aProjectDir, { recursive: true })
|
||||
},
|
||||
})
|
||||
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
await test.step('Open the project', async () => {
|
||||
await expect(page.getByText(PROJECT_DIR_NAME)).toBeVisible()
|
||||
await page.getByText(PROJECT_DIR_NAME).click()
|
||||
await u.waitForPageLoad()
|
||||
})
|
||||
|
||||
await u.openFilePanel()
|
||||
await u.openKclCodePanel()
|
||||
|
||||
await test.step('Write to file externally and check for changed content', async () => {
|
||||
const content = 'ha he ho ho ha blap scap be dap'
|
||||
await fsp.writeFile(
|
||||
join(projectsDir, PROJECT_DIR_NAME, 'main.kcl'),
|
||||
content
|
||||
)
|
||||
await u.editorTextMatches(content)
|
||||
})
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
|
@ -104,7 +104,7 @@ test(
|
||||
},
|
||||
{ timeout: 15_000 }
|
||||
)
|
||||
.toBe(431341)
|
||||
.toBeGreaterThan(300_000)
|
||||
|
||||
// clean up output.gltf
|
||||
await fsp.rm('output.gltf')
|
||||
@ -179,7 +179,7 @@ test(
|
||||
},
|
||||
{ timeout: 15_000 }
|
||||
)
|
||||
.toBe(102040)
|
||||
.toBeGreaterThan(100_000)
|
||||
|
||||
// clean up output.gltf
|
||||
await fsp.rm('output.gltf')
|
||||
|
@ -1,6 +1,16 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import fsp from 'fs/promises'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
import { getUtils, setup, tearDown } from './test-utils'
|
||||
import {
|
||||
darkModeBgColor,
|
||||
darkModePlaneColorXZ,
|
||||
executorInputPath,
|
||||
getUtils,
|
||||
setup,
|
||||
setupElectron,
|
||||
tearDown,
|
||||
} from './test-utils'
|
||||
import { join } from 'path'
|
||||
|
||||
test.beforeEach(async ({ context, page }, testInfo) => {
|
||||
await setup(context, page, testInfo)
|
||||
@ -974,4 +984,84 @@ test.describe('Editor tests', () => {
|
||||
|> close(%)
|
||||
|> extrude(5, %)`)
|
||||
})
|
||||
|
||||
test(
|
||||
`Can use the import stdlib function on a local OBJ file`,
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const { electronApp, page } = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
const bracketDir = join(dir, 'cube')
|
||||
await fsp.mkdir(bracketDir, { recursive: true })
|
||||
await fsp.copyFile(
|
||||
executorInputPath('cube.obj'),
|
||||
join(bracketDir, 'cube.obj')
|
||||
)
|
||||
await fsp.writeFile(join(bracketDir, 'main.kcl'), '')
|
||||
},
|
||||
})
|
||||
const viewportSize = { width: 1200, height: 500 }
|
||||
await page.setViewportSize(viewportSize)
|
||||
|
||||
// Locators and constants
|
||||
const u = await getUtils(page)
|
||||
const projectLink = page.getByRole('link', { name: 'cube' })
|
||||
const gizmo = page.locator('[aria-label*=gizmo]')
|
||||
const resetCameraButton = page.getByRole('button', { name: 'Reset view' })
|
||||
const locationToHavColor = async (
|
||||
position: { x: number; y: number },
|
||||
color: [number, number, number]
|
||||
) => {
|
||||
return u.getGreatestPixDiff(position, color)
|
||||
}
|
||||
const notTheOrigin = {
|
||||
x: viewportSize.width * 0.55,
|
||||
y: viewportSize.height * 0.3,
|
||||
}
|
||||
const origin = { x: viewportSize.width / 2, y: viewportSize.height / 2 }
|
||||
const errorIndicators = page.locator('.cm-lint-marker-error')
|
||||
|
||||
await test.step(`Open the empty file, see the default planes`, async () => {
|
||||
await projectLink.click()
|
||||
await u.waitForPageLoad()
|
||||
await expect
|
||||
.poll(
|
||||
async () => locationToHavColor(notTheOrigin, darkModePlaneColorXZ),
|
||||
{
|
||||
timeout: 5000,
|
||||
message: 'XZ plane color is visible',
|
||||
}
|
||||
)
|
||||
.toBeLessThan(15)
|
||||
})
|
||||
await test.step(`Write the import function line`, async () => {
|
||||
await u.codeLocator.fill(`import('cube.obj')`)
|
||||
await page.waitForTimeout(800)
|
||||
})
|
||||
await test.step(`Reset the camera before checking`, async () => {
|
||||
await u.doAndWaitForCmd(async () => {
|
||||
await gizmo.click({ button: 'right' })
|
||||
await resetCameraButton.click()
|
||||
}, 'zoom_to_fit')
|
||||
})
|
||||
await test.step(`Verify that we see the imported geometry and no errors`, async () => {
|
||||
await expect(errorIndicators).toHaveCount(0)
|
||||
await expect
|
||||
.poll(async () => locationToHavColor(origin, darkModePlaneColorXZ), {
|
||||
timeout: 3000,
|
||||
message: 'Plane color should not be visible',
|
||||
})
|
||||
.toBeGreaterThan(15)
|
||||
await expect
|
||||
.poll(async () => locationToHavColor(origin, darkModeBgColor), {
|
||||
timeout: 3000,
|
||||
message: 'Background color should not be visible',
|
||||
})
|
||||
.toBeGreaterThan(15)
|
||||
})
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -960,4 +960,171 @@ _test.describe('Deleting items from the file pane', () => {
|
||||
'TODO - delete folder we are in, with no main.kcl',
|
||||
async () => {}
|
||||
)
|
||||
|
||||
// Copied from tests above.
|
||||
_test(
|
||||
`external deletion of project navigates back home`,
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const TEST_PROJECT_NAME = 'Test Project'
|
||||
const {
|
||||
electronApp,
|
||||
page,
|
||||
dir: projectsDirName,
|
||||
} = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
await fsp.mkdir(join(dir, TEST_PROJECT_NAME), { recursive: true })
|
||||
await fsp.mkdir(join(dir, TEST_PROJECT_NAME, 'folderToDelete'), {
|
||||
recursive: true,
|
||||
})
|
||||
await fsp.copyFile(
|
||||
executorInputPath('basic_fillet_cube_end.kcl'),
|
||||
join(dir, TEST_PROJECT_NAME, 'main.kcl')
|
||||
)
|
||||
await fsp.copyFile(
|
||||
executorInputPath('cylinder.kcl'),
|
||||
join(dir, TEST_PROJECT_NAME, 'folderToDelete', 'someFileWithin.kcl')
|
||||
)
|
||||
},
|
||||
})
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
// Constants and locators
|
||||
const projectCard = page.getByText(TEST_PROJECT_NAME)
|
||||
const projectMenuButton = page.getByTestId('project-sidebar-toggle')
|
||||
const folderToDelete = page.getByRole('button', {
|
||||
name: 'folderToDelete',
|
||||
})
|
||||
const fileWithinFolder = page.getByRole('listitem').filter({
|
||||
has: page.getByRole('button', { name: 'someFileWithin.kcl' }),
|
||||
})
|
||||
|
||||
await _test.step(
|
||||
'Open project and navigate into folderToDelete',
|
||||
async () => {
|
||||
await projectCard.click()
|
||||
await u.waitForPageLoad()
|
||||
await _expect(projectMenuButton).toContainText('main.kcl')
|
||||
await u.closeKclCodePanel()
|
||||
await u.openFilePanel()
|
||||
|
||||
await folderToDelete.click()
|
||||
await _expect(fileWithinFolder).toBeVisible()
|
||||
await fileWithinFolder.click()
|
||||
await _expect(projectMenuButton).toContainText('someFileWithin.kcl')
|
||||
}
|
||||
)
|
||||
|
||||
// Point of divergence. Delete the project folder and see if it goes back
|
||||
// to the home view.
|
||||
await _test.step(
|
||||
'Delete projectsDirName/<project-name> externally',
|
||||
async () => {
|
||||
await fsp.rm(join(projectsDirName, TEST_PROJECT_NAME), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
await _test.step('Check the app is back on the home view', async () => {
|
||||
const projectsDirLink = page.getByText('Loaded from')
|
||||
await _expect(projectsDirLink).toBeVisible()
|
||||
})
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
|
||||
// Similar to the above
|
||||
_test(
|
||||
`external deletion of file in sub-directory updates the file tree and recreates it on code editor typing`,
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const TEST_PROJECT_NAME = 'Test Project'
|
||||
const {
|
||||
electronApp,
|
||||
page,
|
||||
dir: projectsDirName,
|
||||
} = await setupElectron({
|
||||
testInfo,
|
||||
folderSetupFn: async (dir) => {
|
||||
await fsp.mkdir(join(dir, TEST_PROJECT_NAME), { recursive: true })
|
||||
await fsp.mkdir(join(dir, TEST_PROJECT_NAME, 'folderToDelete'), {
|
||||
recursive: true,
|
||||
})
|
||||
await fsp.copyFile(
|
||||
executorInputPath('basic_fillet_cube_end.kcl'),
|
||||
join(dir, TEST_PROJECT_NAME, 'main.kcl')
|
||||
)
|
||||
await fsp.copyFile(
|
||||
executorInputPath('cylinder.kcl'),
|
||||
join(dir, TEST_PROJECT_NAME, 'folderToDelete', 'someFileWithin.kcl')
|
||||
)
|
||||
},
|
||||
})
|
||||
const u = await getUtils(page)
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
// Constants and locators
|
||||
const projectCard = page.getByText(TEST_PROJECT_NAME)
|
||||
const projectMenuButton = page.getByTestId('project-sidebar-toggle')
|
||||
const folderToDelete = page.getByRole('button', {
|
||||
name: 'folderToDelete',
|
||||
})
|
||||
const fileWithinFolder = page.getByRole('listitem').filter({
|
||||
has: page.getByRole('button', { name: 'someFileWithin.kcl' }),
|
||||
})
|
||||
|
||||
await _test.step(
|
||||
'Open project and navigate into folderToDelete',
|
||||
async () => {
|
||||
await projectCard.click()
|
||||
await u.waitForPageLoad()
|
||||
await _expect(projectMenuButton).toContainText('main.kcl')
|
||||
|
||||
await u.openFilePanel()
|
||||
|
||||
await folderToDelete.click()
|
||||
await _expect(fileWithinFolder).toBeVisible()
|
||||
await fileWithinFolder.click()
|
||||
await _expect(projectMenuButton).toContainText('someFileWithin.kcl')
|
||||
}
|
||||
)
|
||||
|
||||
await _test.step(
|
||||
'Delete projectsDirName/<project-name> externally',
|
||||
async () => {
|
||||
await fsp.rm(
|
||||
join(
|
||||
projectsDirName,
|
||||
TEST_PROJECT_NAME,
|
||||
'folderToDelete',
|
||||
'someFileWithin.kcl'
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
await _test.step('Check the file is gone in the file tree', async () => {
|
||||
await _expect(
|
||||
page.getByTestId('file-pane-scroll-container')
|
||||
).not.toContainText('someFileWithin.kcl')
|
||||
})
|
||||
|
||||
await _test.step(
|
||||
'Check the file is back in the file tree after typing in code editor',
|
||||
async () => {
|
||||
await u.pasteCodeInEditor('hello = 1')
|
||||
await _expect(
|
||||
page.getByTestId('file-pane-scroll-container')
|
||||
).toContainText('someFileWithin.kcl')
|
||||
}
|
||||
)
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
})
|
||||
|
@ -255,7 +255,7 @@ test.describe('Can export from electron app', () => {
|
||||
},
|
||||
{ timeout: 15_000 }
|
||||
)
|
||||
.toBe(431341)
|
||||
.toBeGreaterThan(300_000)
|
||||
|
||||
// clean up output.gltf
|
||||
await fsp.rm('output.gltf')
|
||||
@ -851,7 +851,7 @@ test(
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
test.fixme(
|
||||
'When the project folder is empty, user can create new project and open it.',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
@ -861,6 +861,12 @@ test(
|
||||
|
||||
page.on('console', console.log)
|
||||
|
||||
// Locators and constants
|
||||
const gizmo = page.locator('[aria-label*=gizmo]')
|
||||
const resetCameraButton = page.getByRole('button', { name: 'Reset view' })
|
||||
const pointOnModel = { x: 660, y: 250 }
|
||||
const expectedStartCamZPosition = 15633.47
|
||||
|
||||
// expect to see text "No Projects found"
|
||||
await expect(page.getByText('No Projects found')).toBeVisible()
|
||||
|
||||
@ -873,16 +879,7 @@ test(
|
||||
|
||||
await page.getByText('project-000').click()
|
||||
|
||||
await expect(page.getByTestId('loading')).toBeAttached()
|
||||
await expect(page.getByTestId('loading')).not.toBeAttached({
|
||||
timeout: 20_000,
|
||||
})
|
||||
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).toBeEnabled({
|
||||
timeout: 20_000,
|
||||
})
|
||||
await u.waitForPageLoad()
|
||||
|
||||
await page.locator('.cm-content').fill(`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([-87.4, 282.92], %)
|
||||
@ -892,8 +889,28 @@ test(
|
||||
|> lineTo([profileStartX(%), profileStartY(%)], %)
|
||||
|> close(%)
|
||||
extrude001 = extrude(200, sketch001)`)
|
||||
await page.waitForTimeout(800)
|
||||
|
||||
const pointOnModel = { x: 660, y: 250 }
|
||||
async function getCameraZValue() {
|
||||
return page
|
||||
.getByTestId('cam-z-position')
|
||||
.inputValue()
|
||||
.then((value) => parseFloat(value))
|
||||
}
|
||||
|
||||
await test.step(`Reset camera`, async () => {
|
||||
await u.openDebugPanel()
|
||||
await u.clearCommandLogs()
|
||||
await u.doAndWaitForCmd(async () => {
|
||||
await gizmo.click({ button: 'right' })
|
||||
await resetCameraButton.click()
|
||||
}, 'zoom_to_fit')
|
||||
await expect
|
||||
.poll(getCameraZValue, {
|
||||
message: 'Camera Z should be at expected position after reset',
|
||||
})
|
||||
.toEqual(expectedStartCamZPosition)
|
||||
})
|
||||
|
||||
// gray at this pixel means the stream has loaded in the most
|
||||
// user way we can verify it (pixel color)
|
||||
@ -901,7 +918,7 @@ extrude001 = extrude(200, sketch001)`)
|
||||
.poll(() => u.getGreatestPixDiff(pointOnModel, [143, 143, 143]), {
|
||||
timeout: 10_000,
|
||||
})
|
||||
.toBeLessThan(15)
|
||||
.toBeLessThan(30)
|
||||
|
||||
await expect(async () => {
|
||||
await page.mouse.move(0, 0, { steps: 5 })
|
||||
|
@ -471,7 +471,7 @@ test(
|
||||
|
||||
await page.mouse.move(startXPx + PUR * 30, 500 - PUR * 20, { steps: 10 })
|
||||
|
||||
await page.waitForTimeout(300)
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
@ -528,6 +528,7 @@ test(
|
||||
// Draw the rectangle
|
||||
await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 30)
|
||||
await page.mouse.move(startXPx + PUR * 10, 500 - PUR * 10, { steps: 5 })
|
||||
await page.waitForTimeout(800)
|
||||
|
||||
// Ensure the draft rectangle looks the same as it usually does
|
||||
await expect(page).toHaveScreenshot({
|
||||
@ -895,7 +896,7 @@ test(
|
||||
// Wait for the second extrusion to appear
|
||||
// TODO: Find a way to truly know that the objects have finished
|
||||
// rendering, because an execution-done message is not sufficient.
|
||||
await page.waitForTimeout(1000)
|
||||
await page.waitForTimeout(2000)
|
||||
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
@ -939,7 +940,7 @@ test(
|
||||
// Wait for the second extrusion to appear
|
||||
// TODO: Find a way to truly know that the objects have finished
|
||||
// rendering, because an execution-done message is not sufficient.
|
||||
await page.waitForTimeout(1000)
|
||||
await page.waitForTimeout(2000)
|
||||
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
@ -47,6 +47,14 @@ export const commonPoints = {
|
||||
num2: 14.44,
|
||||
}
|
||||
|
||||
/** A semi-reliable color to check the default XZ plane on
|
||||
* in dark mode in the default camera position
|
||||
*/
|
||||
export const darkModePlaneColorXZ: [number, number, number] = [50, 50, 99]
|
||||
|
||||
/** A semi-reliable color to check the default dark mode bg color against */
|
||||
export const darkModeBgColor: [number, number, number] = [27, 27, 27]
|
||||
|
||||
export const editorSelector = '[role="textbox"][data-language="kcl"]'
|
||||
type PaneId = 'variables' | 'code' | 'files' | 'logs'
|
||||
|
||||
@ -463,6 +471,9 @@ export async function getUtils(page: Page, test_?: typeof test) {
|
||||
return test_?.step(
|
||||
`Create and select project with text "${hasText}"`,
|
||||
async () => {
|
||||
// Without this, we get unreliable project creation. It's probably
|
||||
// due to a race between the FS being read and clicking doing something.
|
||||
await page.waitForTimeout(100)
|
||||
await page.getByTestId('home-new-file').click()
|
||||
const projectLinksPost = page.getByTestId('project-link')
|
||||
await projectLinksPost.filter({ hasText }).click()
|
||||
@ -492,6 +503,11 @@ export async function getUtils(page: Page, test_?: typeof test) {
|
||||
|
||||
createNewFile: async (name: string) => {
|
||||
return test?.step(`Create a file named ${name}`, async () => {
|
||||
// If the application is in the middle of connecting a stream
|
||||
// then creating a new file won't work in the end.
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Start Sketch' })
|
||||
).not.toBeDisabled()
|
||||
await page.getByTestId('create-file-button').click()
|
||||
await page.getByTestId('file-rename-field').fill(name)
|
||||
await page.keyboard.press('Enter')
|
||||
@ -874,8 +890,8 @@ export async function setupElectron({
|
||||
appSettings
|
||||
? { settings: appSettings }
|
||||
: {
|
||||
...TEST_SETTINGS,
|
||||
settings: {
|
||||
...TEST_SETTINGS,
|
||||
app: {
|
||||
...TEST_SETTINGS.app,
|
||||
projectDirectory: projectDirName,
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
executorInputPath,
|
||||
} from './test-utils'
|
||||
import { SaveSettingsPayload, SettingsLevel } from 'lib/settings/settingsTypes'
|
||||
import { SETTINGS_FILE_NAME } from 'lib/constants'
|
||||
import { SETTINGS_FILE_NAME, PROJECT_SETTINGS_FILE_NAME } from 'lib/constants'
|
||||
import {
|
||||
TEST_SETTINGS_KEY,
|
||||
TEST_SETTINGS_CORRUPTED,
|
||||
@ -445,6 +445,58 @@ test.describe('Testing settings', () => {
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
'project settings reload on external change',
|
||||
{ tag: '@electron' },
|
||||
async ({ browserName }, testInfo) => {
|
||||
const {
|
||||
electronApp,
|
||||
page,
|
||||
dir: projectDirName,
|
||||
} = await setupElectron({
|
||||
testInfo,
|
||||
})
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
|
||||
const logoLink = page.getByTestId('app-logo')
|
||||
const projectDirLink = page.getByText('Loaded from')
|
||||
|
||||
await test.step('Wait for project view', async () => {
|
||||
await expect(projectDirLink).toBeVisible()
|
||||
})
|
||||
|
||||
const projectLinks = page.getByTestId('project-link')
|
||||
const oldCount = await projectLinks.count()
|
||||
await page.getByRole('button', { name: 'New project' }).click()
|
||||
await expect(projectLinks).toHaveCount(oldCount + 1)
|
||||
await projectLinks.filter({ hasText: 'project-000' }).first().click()
|
||||
|
||||
const changeColorFs = async (color: string) => {
|
||||
const tempSettingsFilePath = join(
|
||||
projectDirName,
|
||||
'project-000',
|
||||
PROJECT_SETTINGS_FILE_NAME
|
||||
)
|
||||
await fsp.writeFile(
|
||||
tempSettingsFilePath,
|
||||
`[settings.app]\nthemeColor = "${color}"`
|
||||
)
|
||||
}
|
||||
|
||||
await test.step('Check the color is first starting as we expect', async () => {
|
||||
await expect(logoLink).toHaveCSS('--primary-hue', '264.5')
|
||||
})
|
||||
|
||||
await test.step('Check color of logo changed', async () => {
|
||||
await changeColorFs('99')
|
||||
await expect(logoLink).toHaveCSS('--primary-hue', '99')
|
||||
})
|
||||
|
||||
await electronApp.close()
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
`Closing settings modal should go back to the original file being viewed`,
|
||||
{ tag: '@electron' },
|
||||
|
7
interface.d.ts
vendored
@ -20,10 +20,11 @@ export interface IElectronAPI {
|
||||
version: typeof process.env.version
|
||||
watchFileOn: (
|
||||
path: string,
|
||||
key: string,
|
||||
callback: (eventType: string, path: string) => void
|
||||
) => void
|
||||
watchFileOff: (path: string) => void
|
||||
readFile: (path: string) => ReturnType<fs.readFile>
|
||||
readFile: typeof fs.readFile
|
||||
watchFileOff: (path: string, key: string) => void
|
||||
writeFile: (
|
||||
path: string,
|
||||
data: string | Uint8Array
|
||||
@ -67,7 +68,7 @@ export interface IElectronAPI {
|
||||
}
|
||||
}
|
||||
kittycad: (access: string, args: any) => any
|
||||
listMachines: () => Promise<MachinesListing>
|
||||
listMachines: (machineApiIp: string) => Promise<MachinesListing>
|
||||
getMachineApiIp: () => Promise<string | null>
|
||||
onUpdateDownloadStart: (
|
||||
callback: (value: { version: string }) => void
|
||||
|
@ -70,7 +70,7 @@ echo ""
|
||||
echo "Suggested changelog:"
|
||||
echo "\`\`\`"
|
||||
echo "## What's Changed"
|
||||
git log $(git describe --tags --abbrev=0)..HEAD --oneline --pretty=format:%s | grep -v Bump | grep -v 'Cut release v' | awk '{print "* "toupper(substr($0,0,1))substr($0,2)}'
|
||||
git log $(git describe --tags --match="v[0-9]*" --abbrev=0)..HEAD --oneline --pretty=format:%s | grep -v Bump | grep -v 'Cut release v' | awk '{print "* "toupper(substr($0,0,1))substr($0,2)}'
|
||||
echo ""
|
||||
echo "**Full Changelog**: https://github.com/KittyCAD/modeling-app/compare/${latest_tag}...${new_version}"
|
||||
echo "\`\`\`"
|
||||
|
@ -36,38 +36,297 @@
|
||||
"description": "Extra machine-specific information regarding a connected machine.",
|
||||
"oneOf": [
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"Moonraker": {
|
||||
"type": "object"
|
||||
"type": {
|
||||
"enum": [
|
||||
"moonraker"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Moonraker"
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"Usb": {
|
||||
"type": "object"
|
||||
"type": {
|
||||
"enum": [
|
||||
"usb"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Usb"
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"Bambu": {
|
||||
"type": "object"
|
||||
"current_stage": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Stage"
|
||||
}
|
||||
],
|
||||
"description": "The current stage of the machine as defined by Bambu which can include errors, etc.",
|
||||
"nullable": true
|
||||
},
|
||||
"nozzle_diameter": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/NozzleDiameter"
|
||||
}
|
||||
],
|
||||
"description": "The nozzle diameter of the machine."
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"bambu"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Bambu"
|
||||
"nozzle_diameter",
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"FdmHardwareConfiguration": {
|
||||
"description": "Configuration for a FDM-based printer.",
|
||||
"properties": {
|
||||
"filaments": {
|
||||
"description": "The filaments the printer has access to.",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Filament"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"nozzle_diameter": {
|
||||
"description": "Diameter of the extrusion nozzle, in mm.",
|
||||
"format": "double",
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"filaments",
|
||||
"nozzle_diameter"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"Filament": {
|
||||
"description": "Information about the filament being used in a FDM printer.",
|
||||
"properties": {
|
||||
"color": {
|
||||
"description": "The color (as hex without the `#`) of the filament, this is likely specific to the manufacturer.",
|
||||
"maxLength": 6,
|
||||
"minLength": 6,
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
},
|
||||
"material": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/FilamentMaterial"
|
||||
}
|
||||
],
|
||||
"description": "The material that the filament is made of."
|
||||
},
|
||||
"name": {
|
||||
"description": "The name of the filament, this is likely specfic to the manufacturer.",
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"material"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"FilamentMaterial": {
|
||||
"description": "The material that the filament is made of.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Polylactic acid based plastics",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"pla"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Pla support",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"pla_support"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "acrylonitrile butadiene styrene based plastics",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"abs"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "polyethylene terephthalate glycol based plastics",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"petg"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "unsuprisingly, nylon based",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"nylon"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "thermoplastic polyurethane based urethane material",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"tpu"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "polyvinyl alcohol based material",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"pva"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "high impact polystyrene based material",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"hips"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "composite material with stuff in other stuff, something like PLA mixed with carbon fiber, kevlar, or fiberglass",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"composite"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"HardwareConfiguration": {
|
||||
"description": "The hardware configuration of a machine.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "No configuration is possible. This isn't the same conceptually as an `Option<HardwareConfiguration>`, because this indicates we positively know there is no possible configuration changes that are possible with this method of manufcture.",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"none"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Hardware configuration specific to FDM based printers",
|
||||
"properties": {
|
||||
"config": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/FdmHardwareConfiguration"
|
||||
}
|
||||
],
|
||||
"description": "The configuration for the FDM printer."
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"fdm"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"config",
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
@ -85,6 +344,14 @@
|
||||
"description": "Additional, per-machine information which is specific to the underlying machine type.",
|
||||
"nullable": true
|
||||
},
|
||||
"hardware_configuration": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/HardwareConfiguration"
|
||||
}
|
||||
],
|
||||
"description": "Information about how the Machine is currently configured."
|
||||
},
|
||||
"id": {
|
||||
"description": "Machine Identifier (ID) for the specific Machine.",
|
||||
"type": "string"
|
||||
@ -114,6 +381,12 @@
|
||||
"description": "Maximum part size that can be manufactured by this device. This may be some sort of theoretical upper bound, getting close to this limit seems like maybe a bad idea.\n\nThis may be `None` if the maximum size is not knowable by the Machine API.\n\nWhat \"close\" means is up to you!",
|
||||
"nullable": true
|
||||
},
|
||||
"progress": {
|
||||
"description": "Progress of the current print, if printing.",
|
||||
"format": "double",
|
||||
"nullable": true,
|
||||
"type": "number"
|
||||
},
|
||||
"state": {
|
||||
"allOf": [
|
||||
{
|
||||
@ -124,6 +397,7 @@
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"hardware_configuration",
|
||||
"id",
|
||||
"machine_type",
|
||||
"make_model",
|
||||
@ -157,57 +431,111 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "If a print state can not be resolved at this time, an Unknown may be returned.",
|
||||
"enum": [
|
||||
"Unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Idle, and ready for another job.",
|
||||
"enum": [
|
||||
"Idle"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Running a job -- 3D printing or CNC-ing a part.",
|
||||
"enum": [
|
||||
"Running"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Machine is currently offline or unreachable.",
|
||||
"enum": [
|
||||
"Offline"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Job is underway but halted, waiting for some action to take place.",
|
||||
"enum": [
|
||||
"Paused"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Job is finished, but waiting manual action to move back to Idle.",
|
||||
"enum": [
|
||||
"Complete"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"description": "The printer has failed and is in an unknown state that may require manual attention to resolve. The inner value is a human readable description of what specifically has failed.",
|
||||
"properties": {
|
||||
"Failed": {
|
||||
"nullable": true,
|
||||
"state": {
|
||||
"enum": [
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"Failed"
|
||||
"state"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Idle, and ready for another job.",
|
||||
"properties": {
|
||||
"state": {
|
||||
"enum": [
|
||||
"idle"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"state"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Running a job -- 3D printing or CNC-ing a part.",
|
||||
"properties": {
|
||||
"state": {
|
||||
"enum": [
|
||||
"running"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"state"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Machine is currently offline or unreachable.",
|
||||
"properties": {
|
||||
"state": {
|
||||
"enum": [
|
||||
"offline"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"state"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Job is underway but halted, waiting for some action to take place.",
|
||||
"properties": {
|
||||
"state": {
|
||||
"enum": [
|
||||
"paused"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"state"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Job is finished, but waiting manual action to move back to Idle.",
|
||||
"properties": {
|
||||
"state": {
|
||||
"enum": [
|
||||
"complete"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"state"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "The printer has failed and is in an unknown state that may require manual attention to resolve. The inner value is a human readable description of what specifically has failed.",
|
||||
"properties": {
|
||||
"message": {
|
||||
"description": "A human-readable message describing the failure.",
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"enum": [
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"state"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
@ -219,21 +547,54 @@
|
||||
{
|
||||
"description": "Use light to cure a resin to build up layers.",
|
||||
"enum": [
|
||||
"Stereolithography"
|
||||
"stereolithography"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Fused Deposition Modeling, layers of melted plastic.",
|
||||
"enum": [
|
||||
"FusedDeposition"
|
||||
"fused_deposition"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "\"Computer numerical control\" - machine that grinds away material from a hunk of material to construct a part.",
|
||||
"enum": [
|
||||
"Cnc"
|
||||
"cnc"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"NozzleDiameter": {
|
||||
"description": "A nozzle diameter.",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "0.2mm.",
|
||||
"enum": [
|
||||
"0.2"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "0.4mm.",
|
||||
"enum": [
|
||||
"0.4"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "0.6mm.",
|
||||
"enum": [
|
||||
"0.6"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "0.8mm.",
|
||||
"enum": [
|
||||
"0.8"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
@ -284,6 +645,15 @@
|
||||
"machine_id": {
|
||||
"description": "The machine id to print to.",
|
||||
"type": "string"
|
||||
},
|
||||
"slicer_configuration": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/SlicerConfiguration"
|
||||
}
|
||||
],
|
||||
"description": "Requested design-specific slicer configurations.",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@ -292,6 +662,283 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SlicerConfiguration": {
|
||||
"description": "The slicer configuration is a set of parameters that are passed to the slicer to control how the gcode is generated.",
|
||||
"properties": {
|
||||
"filament_idx": {
|
||||
"description": "The filament to use for the print.",
|
||||
"format": "uint",
|
||||
"minimum": 0,
|
||||
"nullable": true,
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"Stage": {
|
||||
"description": "The print stage. These come from: https://github.com/SoftFever/OrcaSlicer/blob/431978baf17961df90f0d01871b0ad1d839d7f5d/src/slic3r/GUI/DeviceManager.cpp#L78",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Nothing.",
|
||||
"enum": [
|
||||
"nothing"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Empty.",
|
||||
"enum": [
|
||||
"empty"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Auto bed leveling.",
|
||||
"enum": [
|
||||
"auto_bed_leveling"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Heatbed preheating.",
|
||||
"enum": [
|
||||
"heatbed_preheating"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Sweeping XY mech mode.",
|
||||
"enum": [
|
||||
"sweeping_xy_mech_mode"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Changing filament.",
|
||||
"enum": [
|
||||
"changing_filament"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "M400 pause.",
|
||||
"enum": [
|
||||
"m400_pause"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused due to filament runout.",
|
||||
"enum": [
|
||||
"paused_due_to_filament_runout"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Heating hotend.",
|
||||
"enum": [
|
||||
"heating_hotend"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Calibrating extrusion.",
|
||||
"enum": [
|
||||
"calibrating_extrusion"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Scanning bed surface.",
|
||||
"enum": [
|
||||
"scanning_bed_surface"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Inspecting first layer.",
|
||||
"enum": [
|
||||
"inspecting_first_layer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Identifying build plate type.",
|
||||
"enum": [
|
||||
"identifying_build_plate_type"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Calibrating micro lidar.",
|
||||
"enum": [
|
||||
"calibrating_micro_lidar"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Homing toolhead.",
|
||||
"enum": [
|
||||
"homing_toolhead"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Cleaning nozzle tip.",
|
||||
"enum": [
|
||||
"cleaning_nozzle_tip"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Checking extruder temperature.",
|
||||
"enum": [
|
||||
"checking_extruder_temperature"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Printing was paused by the user.",
|
||||
"enum": [
|
||||
"printing_was_paused_by_the_user"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Pause of front cover falling.",
|
||||
"enum": [
|
||||
"pause_of_front_cover_falling"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Calibrating micro lidar.",
|
||||
"enum": [
|
||||
"calibrating_micro_lidar2"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Calibrating extrusion flow.",
|
||||
"enum": [
|
||||
"calibrating_extrusion_flow"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused due to nozzle temperature malfunction.",
|
||||
"enum": [
|
||||
"paused_due_to_nozzle_temperature_malfunction"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused due to heat bed temperature malfunction.",
|
||||
"enum": [
|
||||
"paused_due_to_heat_bed_temperature_malfunction"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Filament unloading.",
|
||||
"enum": [
|
||||
"filament_unloading"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Skip step pause.",
|
||||
"enum": [
|
||||
"skip_step_pause"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Filament loading.",
|
||||
"enum": [
|
||||
"filament_loading"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Motor noise calibration.",
|
||||
"enum": [
|
||||
"motor_noise_calibration"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused due to AMS lost.",
|
||||
"enum": [
|
||||
"paused_due_to_ams_lost"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused due to low speed of the heat break fan.",
|
||||
"enum": [
|
||||
"paused_due_to_low_speed_of_the_heat_break_fan"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused due to chamber temperature control error.",
|
||||
"enum": [
|
||||
"paused_due_to_chamber_temperature_control_error"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Cooling chamber.",
|
||||
"enum": [
|
||||
"cooling_chamber"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Paused by the Gcode inserted by the user.",
|
||||
"enum": [
|
||||
"paused_by_the_gcode_inserted_by_the_user"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Motor noise showoff.",
|
||||
"enum": [
|
||||
"motor_noise_showoff"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Nozzle filament covered detected pause.",
|
||||
"enum": [
|
||||
"nozzle_filament_covered_detected_pause"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Cutter error pause.",
|
||||
"enum": [
|
||||
"cutter_error_pause"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "First layer error pause.",
|
||||
"enum": [
|
||||
"first_layer_error_pause"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Nozzle clog pause.",
|
||||
"enum": [
|
||||
"nozzle_clog_pause"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Volume": {
|
||||
"description": "Set of three values to represent the extent of a 3-D Volume. This contains the width, depth, and height values, generally used to represent some maximum or minimum.\n\nAll measurements are in millimeters.",
|
||||
"properties": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zoo-modeling-app",
|
||||
"version": "0.25.6",
|
||||
"version": "0.26.0",
|
||||
"private": true,
|
||||
"productName": "Zoo Modeling App",
|
||||
"author": {
|
||||
|
@ -44,6 +44,7 @@ import {
|
||||
import { ActionButton } from 'components/ActionButton'
|
||||
import { err, reportRejection, trap } from 'lib/trap'
|
||||
import { useCommandsContext } from 'hooks/useCommandsContext'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
function useShouldHideScene(): { hideClient: boolean; hideServer: boolean } {
|
||||
const [isCamMoving, setIsCamMoving] = useState(false)
|
||||
@ -201,7 +202,7 @@ const Overlay = ({
|
||||
let xAlignment = overlay.angle < 0 ? '0%' : '-100%'
|
||||
let yAlignment = overlay.angle < -90 || overlay.angle >= 90 ? '0%' : '-100%'
|
||||
|
||||
const _node1 = getNodeFromPath<CallExpression>(
|
||||
const _node1 = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
kclManager.ast,
|
||||
overlay.pathToNode,
|
||||
'CallExpression'
|
||||
@ -381,7 +382,7 @@ export async function deleteSegment({
|
||||
pathToNode: PathToNode
|
||||
sketchDetails: SketchDetails | null
|
||||
}) {
|
||||
let modifiedAst: Program | Error = kclManager.ast
|
||||
let modifiedAst: UnboxedNode<Program> | Error = kclManager.ast
|
||||
const dependentRanges = findUsesOfTagInPipe(modifiedAst, pathToNode)
|
||||
|
||||
const shouldContinueSegDelete = dependentRanges.length
|
||||
|
@ -92,6 +92,7 @@ import { err, reportRejection, trap } from 'lib/trap'
|
||||
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
|
||||
import { Point3d } from 'wasm-lib/kcl/bindings/Point3d'
|
||||
import { SegmentInputs } from 'lang/std/stdTypes'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
type DraftSegment = 'line' | 'tangentialArcTo'
|
||||
|
||||
@ -369,14 +370,14 @@ export class SceneEntities {
|
||||
selectionRanges,
|
||||
}: {
|
||||
sketchPathToNode: PathToNode
|
||||
maybeModdedAst: Program
|
||||
maybeModdedAst: UnboxedNode<Program>
|
||||
draftExpressionsIndices?: { start: number; end: number }
|
||||
forward: [number, number, number]
|
||||
up: [number, number, number]
|
||||
position?: [number, number, number]
|
||||
selectionRanges?: Selections
|
||||
}): Promise<{
|
||||
truncatedAst: Program
|
||||
truncatedAst: UnboxedNode<Program>
|
||||
programMemoryOverride: ProgramMemory
|
||||
sketch: Sketch
|
||||
variableDeclarationName: string
|
||||
@ -561,7 +562,7 @@ export class SceneEntities {
|
||||
}
|
||||
updateAstAndRejigSketch = async (
|
||||
sketchPathToNode: PathToNode,
|
||||
modifiedAst: Program | Error,
|
||||
modifiedAst: UnboxedNode<Program> | Error,
|
||||
forward: [number, number, number],
|
||||
up: [number, number, number],
|
||||
origin: [number, number, number]
|
||||
@ -1177,7 +1178,7 @@ export class SceneEntities {
|
||||
}
|
||||
prepareTruncatedMemoryAndAst = (
|
||||
sketchPathToNode: PathToNode,
|
||||
ast?: Program,
|
||||
ast?: UnboxedNode<Program>,
|
||||
draftSegment?: DraftSegment
|
||||
) =>
|
||||
prepareTruncatedMemoryAndAst(
|
||||
@ -1198,7 +1199,7 @@ export class SceneEntities {
|
||||
sketchPathToNode: PathToNode
|
||||
intersects: Intersection<Object3D<Object3DEventMap>>[]
|
||||
draftInfo?: {
|
||||
truncatedAst: Program
|
||||
truncatedAst: UnboxedNode<Program>
|
||||
programMemoryOverride: ProgramMemory
|
||||
variableDeclarationName: string
|
||||
}
|
||||
@ -1234,7 +1235,7 @@ export class SceneEntities {
|
||||
const dragTo: [number, number] = [intersection2d.x, intersection2d.y]
|
||||
let modifiedAst = draftInfo ? draftInfo.truncatedAst : { ...kclManager.ast }
|
||||
|
||||
const _node = getNodeFromPath<CallExpression>(
|
||||
const _node = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
modifiedAst,
|
||||
pathToNode,
|
||||
'CallExpression'
|
||||
@ -1246,7 +1247,7 @@ export class SceneEntities {
|
||||
|
||||
let modded:
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToNode: PathToNode
|
||||
}
|
||||
| Error
|
||||
@ -1541,7 +1542,7 @@ export class SceneEntities {
|
||||
if (parent?.userData?.pathToNode) {
|
||||
const updatedAst = parse(recast(kclManager.ast))
|
||||
if (trap(updatedAst)) return
|
||||
const _node = getNodeFromPath<CallExpression>(
|
||||
const _node = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
updatedAst,
|
||||
parent.userData.pathToNode,
|
||||
'CallExpression'
|
||||
@ -1676,12 +1677,12 @@ export type DefaultPlaneStr = 'XY' | 'XZ' | 'YZ' | '-XY' | '-XZ' | '-YZ'
|
||||
|
||||
function prepareTruncatedMemoryAndAst(
|
||||
sketchPathToNode: PathToNode,
|
||||
ast: Program,
|
||||
ast: UnboxedNode<Program>,
|
||||
programMemory: ProgramMemory,
|
||||
draftSegment?: DraftSegment
|
||||
):
|
||||
| {
|
||||
truncatedAst: Program
|
||||
truncatedAst: UnboxedNode<Program>
|
||||
programMemoryOverride: ProgramMemory
|
||||
variableDeclarationName: string
|
||||
}
|
||||
@ -1689,7 +1690,7 @@ function prepareTruncatedMemoryAndAst(
|
||||
const bodyIndex = Number(sketchPathToNode?.[1]?.[0]) || 0
|
||||
const _ast = structuredClone(ast)
|
||||
|
||||
const _node = getNodeFromPath<VariableDeclaration>(
|
||||
const _node = getNodeFromPath<UnboxedNode<VariableDeclaration>>(
|
||||
_ast,
|
||||
sketchPathToNode || [],
|
||||
'VariableDeclaration'
|
||||
@ -1739,15 +1740,15 @@ function prepareTruncatedMemoryAndAst(
|
||||
).body.slice(-1)[0].start = lastPipeItem.start
|
||||
|
||||
_ast.end = lastPipeItem.end
|
||||
const varDec = _ast.body[bodyIndex] as VariableDeclaration
|
||||
const varDec = _ast.body[bodyIndex] as UnboxedNode<VariableDeclaration>
|
||||
varDec.end = lastPipeItem.end
|
||||
const declarator = varDec.declarations[0]
|
||||
declarator.end = lastPipeItem.end
|
||||
const init = declarator.init as PipeExpression
|
||||
const init = declarator.init as UnboxedNode<PipeExpression>
|
||||
init.end = lastPipeItem.end
|
||||
init.body.slice(-1)[0].end = lastPipeItem.end
|
||||
}
|
||||
const truncatedAst: Program = {
|
||||
const truncatedAst: UnboxedNode<Program> = {
|
||||
..._ast,
|
||||
body: [structuredClone(_ast.body[bodyIndex])],
|
||||
}
|
||||
|
@ -135,7 +135,9 @@ function CommandArgOptionInput({
|
||||
<Combobox.Input
|
||||
id="option-input"
|
||||
ref={inputRef}
|
||||
onChange={(event) => setQuery(event.target.value)}
|
||||
onChange={(event) =>
|
||||
!event.target.disabled && setQuery(event.target.value)
|
||||
}
|
||||
className="flex-grow px-2 py-1 border-b border-b-chalkboard-100 dark:border-b-chalkboard-80 !bg-transparent focus:outline-none"
|
||||
onKeyDown={(event) => {
|
||||
if (event.metaKey && event.key === 'k')
|
||||
@ -175,9 +177,18 @@ function CommandArgOptionInput({
|
||||
<Combobox.Option
|
||||
key={option.name}
|
||||
value={option}
|
||||
disabled={option.disabled}
|
||||
className="flex items-center gap-2 px-4 py-1 first:mt-2 last:mb-2 ui-active:bg-primary/10 dark:ui-active:bg-chalkboard-90"
|
||||
>
|
||||
<p className="flex-grow">{option.name} </p>
|
||||
<p
|
||||
className={`flex-grow ${
|
||||
(option.disabled &&
|
||||
'text-chalkboard-70 dark:text-chalkboard-50 cursor-not-allowed') ||
|
||||
''
|
||||
}`}
|
||||
>
|
||||
{option.name}
|
||||
</p>
|
||||
{option.value === currentOption?.value && (
|
||||
<small className="text-chalkboard-70 dark:text-chalkboard-50">
|
||||
current
|
||||
|
@ -2,7 +2,7 @@ import type { IndexLoaderData } from 'lib/types'
|
||||
import { PATHS } from 'lib/paths'
|
||||
import { ActionButton } from './ActionButton'
|
||||
import Tooltip from './Tooltip'
|
||||
import { Dispatch, useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { Dispatch, useCallback, useRef, useState } from 'react'
|
||||
import { useNavigate, useRouteLoaderData } from 'react-router-dom'
|
||||
import { Disclosure } from '@headlessui/react'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
@ -13,7 +13,6 @@ import { sortProject } from 'lib/desktopFS'
|
||||
import { FILE_EXT } from 'lib/constants'
|
||||
import { CustomIcon } from './CustomIcon'
|
||||
import { codeManager, kclManager } from 'lib/singletons'
|
||||
import { useDocumentHasFocus } from 'hooks/useDocumentHasFocus'
|
||||
import { useLspContext } from './LspProvider'
|
||||
import useHotkeyWrapper from 'lib/hotkeyWrapper'
|
||||
import { useModelingContext } from 'hooks/useModelingContext'
|
||||
@ -21,6 +20,8 @@ import { DeleteConfirmationDialog } from './ProjectCard/DeleteProjectDialog'
|
||||
import { ContextMenu, ContextMenuItem } from './ContextMenu'
|
||||
import usePlatform from 'hooks/usePlatform'
|
||||
import { FileEntry } from 'lib/project'
|
||||
import { useFileSystemWatcher } from 'hooks/useFileSystemWatcher'
|
||||
import { normalizeLineEndings } from 'lib/codeEditor'
|
||||
|
||||
function getIndentationCSS(level: number) {
|
||||
return `calc(1rem * ${level + 1})`
|
||||
@ -131,6 +132,23 @@ const FileTreeItem = ({
|
||||
const isCurrentFile = fileOrDir.path === currentFile?.path
|
||||
const itemRef = useRef(null)
|
||||
|
||||
// Since every file or directory gets its own FileTreeItem, we can do this.
|
||||
// Because subtrees only render when they are opened, that means this
|
||||
// only listens when they open. Because this acts like a useEffect, when
|
||||
// the ReactNodes are destroyed, so is this listener :)
|
||||
useFileSystemWatcher(
|
||||
async (eventType, path) => {
|
||||
// Don't try to read a file that was removed.
|
||||
if (isCurrentFile && eventType !== 'unlink') {
|
||||
let code = await window.electron.readFile(path, { encoding: 'utf-8' })
|
||||
code = normalizeLineEndings(code)
|
||||
codeManager.updateCodeStateEditor(code)
|
||||
}
|
||||
fileSend({ type: 'Refresh' })
|
||||
},
|
||||
[fileOrDir.path]
|
||||
)
|
||||
|
||||
const isRenaming = fileContext.itemsBeingRenamed.includes(fileOrDir.path)
|
||||
const removeCurrentItemFromRenaming = useCallback(
|
||||
() =>
|
||||
@ -154,6 +172,13 @@ const FileTreeItem = ({
|
||||
})
|
||||
}, [fileContext.itemsBeingRenamed, fileOrDir.path, fileSend])
|
||||
|
||||
const clickDirectory = () => {
|
||||
fileSend({
|
||||
type: 'Set selected directory',
|
||||
directory: fileOrDir,
|
||||
})
|
||||
}
|
||||
|
||||
function handleKeyUp(e: React.KeyboardEvent<HTMLButtonElement>) {
|
||||
if (e.metaKey && e.key === 'Backspace') {
|
||||
// Open confirmation dialog
|
||||
@ -242,18 +267,8 @@ const FileTreeItem = ({
|
||||
}
|
||||
style={{ paddingInlineStart: getIndentationCSS(level) }}
|
||||
onClick={(e) => e.currentTarget.focus()}
|
||||
onClickCapture={(e) =>
|
||||
fileSend({
|
||||
type: 'Set selected directory',
|
||||
directory: fileOrDir,
|
||||
})
|
||||
}
|
||||
onFocusCapture={(e) =>
|
||||
fileSend({
|
||||
type: 'Set selected directory',
|
||||
directory: fileOrDir,
|
||||
})
|
||||
}
|
||||
onClickCapture={clickDirectory}
|
||||
onFocusCapture={clickDirectory}
|
||||
onKeyDown={(e) => e.key === 'Enter' && e.preventDefault()}
|
||||
onKeyUp={handleKeyUp}
|
||||
>
|
||||
@ -469,27 +484,30 @@ export const FileTreeInner = ({
|
||||
const loaderData = useRouteLoaderData(PATHS.FILE) as IndexLoaderData
|
||||
const { send: fileSend, context: fileContext } = useFileContext()
|
||||
const { send: modelingSend } = useModelingContext()
|
||||
const documentHasFocus = useDocumentHasFocus()
|
||||
|
||||
// Refresh the file tree when the document gets focus
|
||||
useEffect(() => {
|
||||
fileSend({ type: 'Refresh' })
|
||||
}, [documentHasFocus])
|
||||
// Refresh the file tree when there are changes.
|
||||
useFileSystemWatcher(
|
||||
async (eventType, path) => {
|
||||
fileSend({ type: 'Refresh' })
|
||||
},
|
||||
[loaderData?.project?.path, fileContext.selectedDirectory.path].filter(
|
||||
(x: string | undefined) => x !== undefined
|
||||
)
|
||||
)
|
||||
|
||||
const clickDirectory = () => {
|
||||
fileSend({
|
||||
type: 'Set selected directory',
|
||||
directory: fileContext.project,
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="overflow-auto pb-12 absolute inset-0"
|
||||
data-testid="file-pane-scroll-container"
|
||||
>
|
||||
<ul
|
||||
className="m-0 p-0 text-sm"
|
||||
onClickCapture={(e) => {
|
||||
fileSend({
|
||||
type: 'Set selected directory',
|
||||
directory: fileContext.project,
|
||||
})
|
||||
}}
|
||||
>
|
||||
<ul className="m-0 p-0 text-sm" onClickCapture={clickDirectory}>
|
||||
{sortProject(fileContext.project?.children || []).map((fileOrDir) => (
|
||||
<FileTreeItem
|
||||
project={fileContext.project}
|
||||
|
@ -84,6 +84,7 @@ import {
|
||||
import { submitAndAwaitTextToKcl } from 'lib/textToCad'
|
||||
import { useFileContext } from 'hooks/useFileContext'
|
||||
import { uuidv4 } from 'lib/utils'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
type MachineContext<T extends AnyStateMachine> = {
|
||||
state: StateFrom<T>
|
||||
@ -939,7 +940,7 @@ export const ModelingMachineProvider = ({
|
||||
})
|
||||
let parsed = parse(recast(kclManager.ast))
|
||||
if (trap(parsed)) return Promise.reject(parsed)
|
||||
parsed = parsed as Program
|
||||
parsed = parsed as UnboxedNode<Program>
|
||||
|
||||
const { modifiedAst: _modifiedAst, pathToReplacedNode } =
|
||||
moveValueIntoNewVariablePath(
|
||||
@ -950,7 +951,7 @@ export const ModelingMachineProvider = ({
|
||||
)
|
||||
parsed = parse(recast(_modifiedAst))
|
||||
if (trap(parsed)) return Promise.reject(parsed)
|
||||
parsed = parsed as Program
|
||||
parsed = parsed as UnboxedNode<Program>
|
||||
if (!pathToReplacedNode)
|
||||
return Promise.reject(new Error('No path to replaced node'))
|
||||
|
||||
|
@ -11,6 +11,7 @@ export const NetworkMachineIndicator = ({
|
||||
}) => {
|
||||
const machineCount = machineManager.machineCount()
|
||||
const reason = machineManager.noMachinesReason()
|
||||
const machines = machineManager.machines
|
||||
|
||||
return isDesktop() ? (
|
||||
<Popover className="relative">
|
||||
@ -46,20 +47,34 @@ export const NetworkMachineIndicator = ({
|
||||
</div>
|
||||
{machineCount > 0 && (
|
||||
<ul className="divide-y divide-chalkboard-20 dark:divide-chalkboard-80">
|
||||
{Object.entries(machineManager.machines).map(
|
||||
([hostname, machine]) => (
|
||||
<li key={hostname} className={'px-2 py-4 gap-1 last:mb-0 '}>
|
||||
<p className="">
|
||||
{machine.make_model.model ||
|
||||
machine.make_model.manufacturer ||
|
||||
'Unknown Machine'}
|
||||
</p>
|
||||
{machines.map((machine) => {
|
||||
return (
|
||||
<li key={machine.id} className={'px-2 py-4 gap-1 last:mb-0 '}>
|
||||
<p className="">{machine.id.toUpperCase()}</p>
|
||||
<p className="text-chalkboard-60 dark:text-chalkboard-50 text-xs">
|
||||
Hostname {hostname}
|
||||
{machine.make_model.model}
|
||||
</p>
|
||||
{machine.extra &&
|
||||
machine.extra.type === 'bambu' &&
|
||||
machine.extra.nozzle_diameter && (
|
||||
<p className="text-chalkboard-60 dark:text-chalkboard-50 text-xs">
|
||||
Nozzle Diameter: {machine.extra.nozzle_diameter}
|
||||
</p>
|
||||
)}
|
||||
<p className="text-chalkboard-60 dark:text-chalkboard-50 text-xs">
|
||||
{`Status: ${machine.state.state
|
||||
.charAt(0)
|
||||
.toUpperCase()}${machine.state.state.slice(1)}`}
|
||||
{machine.state.state === 'failed' && machine.state.message
|
||||
? ` (${machine.state.message})`
|
||||
: ''}
|
||||
{machine.state.state === 'running' && machine.progress
|
||||
? ` (${Math.round(machine.progress)}%)`
|
||||
: ''}
|
||||
</p>
|
||||
</li>
|
||||
)
|
||||
)}
|
||||
})}
|
||||
</ul>
|
||||
)}
|
||||
</Popover.Panel>
|
||||
|
@ -221,6 +221,19 @@ export const SettingsAuthProviderBase = ({
|
||||
|
||||
useFileSystemWatcher(
|
||||
async () => {
|
||||
// If there is a projectPath but it no longer exists it means
|
||||
// it was exterally removed. If we let the code past this condition
|
||||
// execute it will recreate the directory due to code in
|
||||
// loadAndValidateSettings trying to recreate files. I do not
|
||||
// wish to change the behavior in case anything else uses it.
|
||||
// Go home.
|
||||
if (loadedProject?.project?.path) {
|
||||
if (!window.electron.exists(loadedProject?.project?.path)) {
|
||||
navigate(PATHS.HOME)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const data = await loadAndValidateSettings(loadedProject?.project?.path)
|
||||
settingsSend({
|
||||
type: 'Set all settings',
|
||||
@ -228,7 +241,9 @@ export const SettingsAuthProviderBase = ({
|
||||
doNotPersist: true,
|
||||
})
|
||||
},
|
||||
settingsPath ? [settingsPath] : []
|
||||
[settingsPath, loadedProject?.project?.path].filter(
|
||||
(x: string | undefined) => x !== undefined
|
||||
)
|
||||
)
|
||||
|
||||
// Add settings commands to the command bar
|
||||
|
@ -14,6 +14,7 @@ import {
|
||||
import { TransformInfo } from 'lang/std/stdTypes'
|
||||
import { kclManager } from 'lib/singletons'
|
||||
import { err } from 'lib/trap'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
export function setEqualLengthInfo({
|
||||
selectionRanges,
|
||||
@ -86,7 +87,7 @@ export function applyConstraintEqualLength({
|
||||
selectionRanges: Selections
|
||||
}):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToNodeMap: PathToNodeMap
|
||||
}
|
||||
| Error {
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
import { TransformInfo } from 'lang/std/stdTypes'
|
||||
import { kclManager } from 'lib/singletons'
|
||||
import { err } from 'lib/trap'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
export function horzVertInfo(
|
||||
selectionRanges: Selections,
|
||||
@ -55,11 +56,11 @@ export function horzVertInfo(
|
||||
export function applyConstraintHorzVert(
|
||||
selectionRanges: Selections,
|
||||
horOrVert: 'vertical' | 'horizontal',
|
||||
ast: Program,
|
||||
ast: UnboxedNode<Program>,
|
||||
programMemory: ProgramMemory
|
||||
):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToNodeMap: PathToNodeMap
|
||||
}
|
||||
| Error {
|
||||
|
@ -19,6 +19,7 @@ import { createVariableDeclaration } from '../../lang/modifyAst'
|
||||
import { removeDoubleNegatives } from '../AvailableVarsHelpers'
|
||||
import { kclManager } from 'lib/singletons'
|
||||
import { err } from 'lib/trap'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
const getModalInfo = createInfoModal(GetInfoModal)
|
||||
|
||||
@ -136,7 +137,7 @@ export async function applyConstraintIntersect({
|
||||
}: {
|
||||
selectionRanges: Selections
|
||||
}): Promise<{
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToNodeMap: PathToNodeMap
|
||||
}> {
|
||||
const info = intersectInfo({
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
import { TransformInfo } from 'lang/std/stdTypes'
|
||||
import { kclManager } from 'lib/singletons'
|
||||
import { err } from 'lib/trap'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
export function removeConstrainingValuesInfo({
|
||||
selectionRanges,
|
||||
@ -77,7 +78,7 @@ export function applyRemoveConstrainingValues({
|
||||
pathToNodes?: Array<PathToNode>
|
||||
}):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToNodeMap: PathToNodeMap
|
||||
}
|
||||
| Error {
|
||||
|
@ -23,6 +23,7 @@ import {
|
||||
import { removeDoubleNegatives } from '../AvailableVarsHelpers'
|
||||
import { kclManager } from 'lib/singletons'
|
||||
import { err } from 'lib/trap'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
const getModalInfo = createSetAngleLengthModal(SetAngleLengthModal)
|
||||
|
||||
@ -161,7 +162,7 @@ export function applyConstraintAxisAlign({
|
||||
constraint: 'snapToYAxis' | 'snapToXAxis'
|
||||
}):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToNodeMap: PathToNodeMap
|
||||
}
|
||||
| Error {
|
||||
|
@ -18,6 +18,7 @@ import { removeDoubleNegatives } from '../AvailableVarsHelpers'
|
||||
import { kclManager } from 'lib/singletons'
|
||||
import { Selections } from 'lib/selections'
|
||||
import { cleanErrs, err } from 'lib/trap'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
const getModalInfo = createInfoModal(GetInfoModal)
|
||||
|
||||
@ -185,7 +186,7 @@ export function applyConstraintHorzVertAlign({
|
||||
constraint: 'setHorzDistance' | 'setVertDistance'
|
||||
}):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToNodeMap: PathToNodeMap
|
||||
}
|
||||
| Error {
|
||||
|
@ -11,7 +11,7 @@ export const kclHighlight = styleTags({
|
||||
nil: t.null,
|
||||
'AddOp MultOp ExpOp': t.arithmeticOperator,
|
||||
BangOp: t.logicOperator,
|
||||
CompOp: t.logicOperator,
|
||||
CompOp: t.compareOperator,
|
||||
'Equals Arrow': t.definitionOperator,
|
||||
PipeOperator: t.controlOperator,
|
||||
String: t.string,
|
||||
|
@ -90,7 +90,7 @@ commaSep1NoTrailingComma<term> { term ("," term)* }
|
||||
MultOp { "/" | "*" | "\\" }
|
||||
ExpOp { "^" }
|
||||
BangOp { "!" }
|
||||
CompOp { $[<>] "="? | "!=" | "==" }
|
||||
CompOp { "==" | "!=" | "<=" | ">=" | "<" | ">" }
|
||||
Equals { "=" }
|
||||
Arrow { "=>" }
|
||||
PipeOperator { "|>" }
|
||||
|
@ -12,35 +12,51 @@ type Path = string
|
||||
// watcher.addListener(() => { ... }).
|
||||
|
||||
export const useFileSystemWatcher = (
|
||||
callback: (path: Path) => Promise<void>,
|
||||
dependencyArray: Path[]
|
||||
callback: (eventType: string, path: Path) => Promise<void>,
|
||||
paths: Path[]
|
||||
): void => {
|
||||
// Track a ref to the callback. This is how we get the callback updated
|
||||
// across the NodeJS<->Browser boundary.
|
||||
const callbackRef = useRef<{ fn: (path: Path) => Promise<void> }>({
|
||||
fn: async (_path) => {},
|
||||
})
|
||||
// Used to track this instance of useFileSystemWatcher.
|
||||
// Assign to ref so it doesn't change between renders.
|
||||
const key = useRef(Math.random().toString())
|
||||
|
||||
const [output, setOutput] = useState<
|
||||
{ eventType: string; path: string } | undefined
|
||||
>(undefined)
|
||||
|
||||
// Used to track if paths list changes.
|
||||
const [pathsTracked, setPathsTracked] = useState<Path[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
callbackRef.current.fn = callback
|
||||
}, [callback])
|
||||
|
||||
// Used to track if dependencyArrray changes.
|
||||
const [dependencyArrayTracked, setDependencyArrayTracked] = useState<Path[]>(
|
||||
[]
|
||||
)
|
||||
if (!output) return
|
||||
callback(output.eventType, output.path).catch(reportRejection)
|
||||
}, [output])
|
||||
|
||||
// On component teardown obliterate all watchers.
|
||||
useEffect(() => {
|
||||
// The hook is useless on web.
|
||||
if (!isDesktop()) return
|
||||
|
||||
const cbWatcher = (eventType: string, path: string) => {
|
||||
setOutput({ eventType, path })
|
||||
}
|
||||
|
||||
for (let path of pathsTracked) {
|
||||
// Because functions don't retain refs between NodeJS-Browser I need to
|
||||
// pass an identifying key so we can later remove it.
|
||||
// A way to think of the function call is:
|
||||
// "For this path, add a new handler with this key"
|
||||
// "There can be many keys (functions) per path"
|
||||
// Again if refs were preserved, we wouldn't need to do this. Keys
|
||||
// gives us uniqueness.
|
||||
window.electron.watchFileOn(path, key.current, cbWatcher)
|
||||
}
|
||||
|
||||
return () => {
|
||||
for (let path of dependencyArray) {
|
||||
window.electron.watchFileOff(path)
|
||||
for (let path of pathsTracked) {
|
||||
window.electron.watchFileOff(path, key.current)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
}, [pathsTracked])
|
||||
|
||||
function difference<T>(l1: T[], l2: T[]): [T[], T[]] {
|
||||
return [
|
||||
@ -49,8 +65,7 @@ export const useFileSystemWatcher = (
|
||||
]
|
||||
}
|
||||
|
||||
const hasDiff =
|
||||
difference(dependencyArray, dependencyArrayTracked)[0].length !== 0
|
||||
const hasDiff = difference(paths, pathsTracked)[0].length !== 0
|
||||
|
||||
// Removing 1 watcher at a time is only possible because in a filesystem,
|
||||
// a path is unique (there can never be two paths with the same name).
|
||||
@ -61,19 +76,8 @@ export const useFileSystemWatcher = (
|
||||
|
||||
if (!hasDiff) return
|
||||
|
||||
const [pathsRemoved, pathsRemaining] = difference(
|
||||
dependencyArrayTracked,
|
||||
dependencyArray
|
||||
)
|
||||
for (let path of pathsRemoved) {
|
||||
window.electron.watchFileOff(path)
|
||||
}
|
||||
const [pathsAdded] = difference(dependencyArray, dependencyArrayTracked)
|
||||
for (let path of pathsAdded) {
|
||||
window.electron.watchFileOn(path, (_eventType: string, path: Path) => {
|
||||
callbackRef.current.fn(path).catch(reportRejection)
|
||||
})
|
||||
}
|
||||
setDependencyArrayTracked(pathsRemaining.concat(pathsAdded))
|
||||
const [, pathsRemaining] = difference(pathsTracked, paths)
|
||||
const [pathsAdded] = difference(paths, pathsTracked)
|
||||
setPathsTracked(pathsRemaining.concat(pathsAdded))
|
||||
}, [hasDiff])
|
||||
}
|
||||
|
@ -21,9 +21,10 @@ import {
|
||||
import { getNodeFromPath } from './queryAst'
|
||||
import { codeManager, editorManager, sceneInfra } from 'lib/singletons'
|
||||
import { Diagnostic } from '@codemirror/lint'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
interface ExecuteArgs {
|
||||
ast?: Program
|
||||
ast?: UnboxedNode<Program>
|
||||
zoomToFit?: boolean
|
||||
executionId?: number
|
||||
zoomOnRangeAndType?: {
|
||||
@ -33,16 +34,14 @@ interface ExecuteArgs {
|
||||
}
|
||||
|
||||
export class KclManager {
|
||||
private _ast: Program = {
|
||||
private _ast: UnboxedNode<Program> = {
|
||||
body: [],
|
||||
start: 0,
|
||||
end: 0,
|
||||
nonCodeMeta: {
|
||||
nonCodeNodes: {},
|
||||
start: [],
|
||||
digest: null,
|
||||
startNodes: [],
|
||||
},
|
||||
digest: null,
|
||||
}
|
||||
private _execState: ExecState = emptyExecState()
|
||||
private _programMemory: ProgramMemory = ProgramMemory.empty()
|
||||
@ -57,7 +56,7 @@ export class KclManager {
|
||||
engineCommandManager: EngineCommandManager
|
||||
|
||||
private _isExecutingCallback: (arg: boolean) => void = () => {}
|
||||
private _astCallBack: (arg: Program) => void = () => {}
|
||||
private _astCallBack: (arg: UnboxedNode<Program>) => void = () => {}
|
||||
private _programMemoryCallBack: (arg: ProgramMemory) => void = () => {}
|
||||
private _logsCallBack: (arg: string[]) => void = () => {}
|
||||
private _kclErrorsCallBack: (arg: KCLError[]) => void = () => {}
|
||||
@ -183,7 +182,7 @@ export class KclManager {
|
||||
setWasmInitFailed,
|
||||
}: {
|
||||
setProgramMemory: (arg: ProgramMemory) => void
|
||||
setAst: (arg: Program) => void
|
||||
setAst: (arg: UnboxedNode<Program>) => void
|
||||
setLogs: (arg: string[]) => void
|
||||
setKclErrors: (arg: KCLError[]) => void
|
||||
setIsExecuting: (arg: boolean) => void
|
||||
@ -207,14 +206,12 @@ export class KclManager {
|
||||
end: 0,
|
||||
nonCodeMeta: {
|
||||
nonCodeNodes: {},
|
||||
start: [],
|
||||
digest: null,
|
||||
startNodes: [],
|
||||
},
|
||||
digest: null,
|
||||
}
|
||||
}
|
||||
|
||||
safeParse(code: string): Program | null {
|
||||
safeParse(code: string): UnboxedNode<Program> | null {
|
||||
const ast = parse(code)
|
||||
this.lints = []
|
||||
this.kclErrors = []
|
||||
@ -381,7 +378,7 @@ export class KclManager {
|
||||
Array.from(this.engineCommandManager.artifactGraph).forEach(
|
||||
([commandId, artifact]) => {
|
||||
if (!('codeRef' in artifact)) return
|
||||
const _node1 = getNodeFromPath<CallExpression>(
|
||||
const _node1 = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
this.ast,
|
||||
artifact.codeRef.pathToNode,
|
||||
'CallExpression'
|
||||
@ -445,7 +442,7 @@ export class KclManager {
|
||||
// but should probably have think about which of the function to keep
|
||||
// This always updates the code state and editor and writes to the file system.
|
||||
async updateAst(
|
||||
ast: Program,
|
||||
ast: UnboxedNode<Program>,
|
||||
execute: boolean,
|
||||
optionalParams?: {
|
||||
focusPath?: Array<PathToNode>
|
||||
@ -456,7 +453,7 @@ export class KclManager {
|
||||
}
|
||||
}
|
||||
): Promise<{
|
||||
newAst: Program
|
||||
newAst: UnboxedNode<Program>
|
||||
selections?: Selections
|
||||
}> {
|
||||
const newCode = recast(ast)
|
||||
@ -592,7 +589,7 @@ export class KclManager {
|
||||
}
|
||||
|
||||
// Determines if there is no KCL code which means it is executing a blank KCL file
|
||||
_isAstEmpty(ast: Program) {
|
||||
_isAstEmpty(ast: UnboxedNode<Program>) {
|
||||
return ast.start === 0 && ast.end === 0 && ast.body.length === 0
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +172,6 @@ const sk2 = startSketchOn('XY')
|
||||
start: 114,
|
||||
type: 'TagDeclarator',
|
||||
value: 'p',
|
||||
digest: null,
|
||||
},
|
||||
id: expect.any(String),
|
||||
sourceRange: [95, 117],
|
||||
@ -223,7 +222,6 @@ const sk2 = startSketchOn('XY')
|
||||
start: 114,
|
||||
type: 'TagDeclarator',
|
||||
value: 'p',
|
||||
digest: null,
|
||||
},
|
||||
__geoMeta: {
|
||||
id: expect.any(String),
|
||||
@ -266,7 +264,6 @@ const sk2 = startSketchOn('XY')
|
||||
start: 417,
|
||||
type: 'TagDeclarator',
|
||||
value: 'o',
|
||||
digest: null,
|
||||
},
|
||||
id: expect.any(String),
|
||||
sourceRange: [399, 420],
|
||||
@ -317,7 +314,6 @@ const sk2 = startSketchOn('XY')
|
||||
start: 417,
|
||||
type: 'TagDeclarator',
|
||||
value: 'o',
|
||||
digest: null,
|
||||
},
|
||||
__geoMeta: {
|
||||
id: expect.any(String),
|
||||
|
@ -73,7 +73,6 @@ const newVar = myVar + 1`
|
||||
start: 89,
|
||||
type: 'TagDeclarator',
|
||||
value: 'myPath',
|
||||
digest: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -99,7 +98,6 @@ const newVar = myVar + 1`
|
||||
start: 143,
|
||||
type: 'TagDeclarator',
|
||||
value: 'rightPath',
|
||||
digest: null,
|
||||
},
|
||||
},
|
||||
])
|
||||
@ -201,7 +199,6 @@ const newVar = myVar + 1`
|
||||
start: 109,
|
||||
type: 'TagDeclarator',
|
||||
value: 'myPath',
|
||||
digest: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -12,6 +12,7 @@ import { EngineCommandManager } from 'lang/std/engineConnection'
|
||||
import { KCLError } from 'lang/errors'
|
||||
import { Diagnostic } from '@codemirror/lint'
|
||||
import { IdGenerator } from 'wasm-lib/kcl/bindings/IdGenerator'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
export type ToolTip =
|
||||
| 'lineTo'
|
||||
@ -52,7 +53,7 @@ export async function executeAst({
|
||||
programMemoryOverride,
|
||||
idGenerator,
|
||||
}: {
|
||||
ast: Program
|
||||
ast: UnboxedNode<Program>
|
||||
engineCommandManager: EngineCommandManager
|
||||
useFakeExecutor?: boolean
|
||||
programMemoryOverride?: ProgramMemory
|
||||
|
@ -21,6 +21,7 @@ import { enginelessExecutor } from '../lib/testHelpers'
|
||||
import { findUsesOfTagInPipe, getNodePathFromSourceRange } from './queryAst'
|
||||
import { err } from 'lib/trap'
|
||||
import { SimplifiedArgDetails } from './std/stdTypes'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
beforeAll(async () => {
|
||||
await initPromise
|
||||
@ -100,16 +101,16 @@ describe('Testing findUniqueName', () => {
|
||||
it('should find a unique name', () => {
|
||||
const result = findUniqueName(
|
||||
JSON.stringify([
|
||||
{ type: 'Identifier', name: 'yo01', start: 0, end: 0, digest: null },
|
||||
{ type: 'Identifier', name: 'yo02', start: 0, end: 0, digest: null },
|
||||
{ type: 'Identifier', name: 'yo03', start: 0, end: 0, digest: null },
|
||||
{ type: 'Identifier', name: 'yo04', start: 0, end: 0, digest: null },
|
||||
{ type: 'Identifier', name: 'yo05', start: 0, end: 0, digest: null },
|
||||
{ type: 'Identifier', name: 'yo06', start: 0, end: 0, digest: null },
|
||||
{ type: 'Identifier', name: 'yo07', start: 0, end: 0, digest: null },
|
||||
{ type: 'Identifier', name: 'yo08', start: 0, end: 0, digest: null },
|
||||
{ type: 'Identifier', name: 'yo09', start: 0, end: 0, digest: null },
|
||||
] satisfies Identifier[]),
|
||||
{ type: 'Identifier', name: 'yo01', start: 0, end: 0 },
|
||||
{ type: 'Identifier', name: 'yo02', start: 0, end: 0 },
|
||||
{ type: 'Identifier', name: 'yo03', start: 0, end: 0 },
|
||||
{ type: 'Identifier', name: 'yo04', start: 0, end: 0 },
|
||||
{ type: 'Identifier', name: 'yo05', start: 0, end: 0 },
|
||||
{ type: 'Identifier', name: 'yo06', start: 0, end: 0 },
|
||||
{ type: 'Identifier', name: 'yo07', start: 0, end: 0 },
|
||||
{ type: 'Identifier', name: 'yo08', start: 0, end: 0 },
|
||||
{ type: 'Identifier', name: 'yo09', start: 0, end: 0 },
|
||||
] satisfies UnboxedNode<Identifier>[]),
|
||||
'yo',
|
||||
2
|
||||
)
|
||||
@ -123,8 +124,7 @@ describe('Testing addSketchTo', () => {
|
||||
body: [],
|
||||
start: 0,
|
||||
end: 0,
|
||||
nonCodeMeta: { nonCodeNodes: {}, start: [], digest: null },
|
||||
digest: null,
|
||||
nonCodeMeta: { nonCodeNodes: {}, startNodes: [] },
|
||||
},
|
||||
'yz'
|
||||
)
|
||||
|
@ -42,12 +42,13 @@ import { SimplifiedArgDetails } from './std/stdTypes'
|
||||
import { TagDeclarator } from 'wasm-lib/kcl/bindings/TagDeclarator'
|
||||
import { Models } from '@kittycad/lib'
|
||||
import { ExtrudeFacePlane } from 'machines/modelingMachine'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
export function startSketchOnDefault(
|
||||
node: Program,
|
||||
node: UnboxedNode<Program>,
|
||||
axis: DefaultPlaneStr,
|
||||
name = ''
|
||||
): { modifiedAst: Program; id: string; pathToNode: PathToNode } {
|
||||
): { modifiedAst: UnboxedNode<Program>; id: string; pathToNode: PathToNode } {
|
||||
const _node = { ...node }
|
||||
const _name =
|
||||
name || findUniqueName(node, KCL_DEFAULT_CONSTANT_PREFIXES.SKETCH)
|
||||
@ -76,10 +77,10 @@ export function startSketchOnDefault(
|
||||
}
|
||||
|
||||
export function addStartProfileAt(
|
||||
node: Program,
|
||||
node: UnboxedNode<Program>,
|
||||
pathToNode: PathToNode,
|
||||
at: [number, number]
|
||||
): { modifiedAst: Program; pathToNode: PathToNode } | Error {
|
||||
): { modifiedAst: UnboxedNode<Program>; pathToNode: PathToNode } | Error {
|
||||
const _node1 = getNodeFromPath<VariableDeclaration>(
|
||||
node,
|
||||
pathToNode,
|
||||
@ -114,7 +115,7 @@ export function addStartProfileAt(
|
||||
}
|
||||
|
||||
export function addSketchTo(
|
||||
node: Program,
|
||||
node: UnboxedNode<Program>,
|
||||
axis: 'xy' | 'xz' | 'yz',
|
||||
name = ''
|
||||
): { modifiedAst: Program; id: string; pathToNode: PathToNode } {
|
||||
@ -210,7 +211,7 @@ export function mutateArrExp(node: Expr, updateWith: ArrayExpression): boolean {
|
||||
|
||||
export function mutateObjExpProp(
|
||||
node: Expr,
|
||||
updateWith: Literal | ArrayExpression,
|
||||
updateWith: UnboxedNode<Literal> | UnboxedNode<ArrayExpression>,
|
||||
key: string
|
||||
): boolean {
|
||||
if (node.type === 'ObjectExpression') {
|
||||
@ -241,7 +242,6 @@ export function mutateObjExpProp(
|
||||
value: updateWith,
|
||||
start: 0,
|
||||
end: 0,
|
||||
digest: null,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -249,13 +249,13 @@ export function mutateObjExpProp(
|
||||
}
|
||||
|
||||
export function extrudeSketch(
|
||||
node: Program,
|
||||
node: UnboxedNode<Program>,
|
||||
pathToNode: PathToNode,
|
||||
shouldPipe = false,
|
||||
distance: Expr = createLiteral(4)
|
||||
):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToNode: PathToNode
|
||||
pathToExtrudeArg: PathToNode
|
||||
}
|
||||
@ -344,13 +344,13 @@ export function extrudeSketch(
|
||||
}
|
||||
|
||||
export function revolveSketch(
|
||||
node: Program,
|
||||
node: UnboxedNode<Program>,
|
||||
pathToNode: PathToNode,
|
||||
shouldPipe = false,
|
||||
angle: Expr = createLiteral(4)
|
||||
):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToNode: PathToNode
|
||||
pathToRevolveArg: PathToNode
|
||||
}
|
||||
@ -440,7 +440,7 @@ export function revolveSketch(
|
||||
}
|
||||
|
||||
export function sketchOnExtrudedFace(
|
||||
node: Program,
|
||||
node: UnboxedNode<Program>,
|
||||
sketchPathToNode: PathToNode,
|
||||
extrudePathToNode: PathToNode,
|
||||
info: ExtrudeFacePlane['faceInfo'] = { type: 'wall' }
|
||||
@ -572,50 +572,48 @@ export function splitPathAtPipeExpression(pathToNode: PathToNode): {
|
||||
return splitPathAtPipeExpression(pathToNode.slice(0, -1))
|
||||
}
|
||||
|
||||
export function createLiteral(value: string | number): Literal {
|
||||
export function createLiteral(value: string | number): UnboxedNode<Literal> {
|
||||
return {
|
||||
type: 'Literal',
|
||||
start: 0,
|
||||
end: 0,
|
||||
value,
|
||||
raw: `${value}`,
|
||||
digest: null,
|
||||
}
|
||||
}
|
||||
|
||||
export function createTagDeclarator(value: string): TagDeclarator {
|
||||
export function createTagDeclarator(value: string): UnboxedNode<TagDeclarator> {
|
||||
return {
|
||||
type: 'TagDeclarator',
|
||||
start: 0,
|
||||
end: 0,
|
||||
digest: null,
|
||||
|
||||
value,
|
||||
}
|
||||
}
|
||||
|
||||
export function createIdentifier(name: string): Identifier {
|
||||
export function createIdentifier(name: string): UnboxedNode<Identifier> {
|
||||
return {
|
||||
type: 'Identifier',
|
||||
start: 0,
|
||||
end: 0,
|
||||
digest: null,
|
||||
|
||||
name,
|
||||
}
|
||||
}
|
||||
|
||||
export function createPipeSubstitution(): PipeSubstitution {
|
||||
export function createPipeSubstitution(): UnboxedNode<PipeSubstitution> {
|
||||
return {
|
||||
type: 'PipeSubstitution',
|
||||
start: 0,
|
||||
end: 0,
|
||||
digest: null,
|
||||
}
|
||||
}
|
||||
|
||||
export function createCallExpressionStdLib(
|
||||
name: string,
|
||||
args: CallExpression['arguments']
|
||||
): CallExpression {
|
||||
): UnboxedNode<CallExpression> {
|
||||
return {
|
||||
type: 'CallExpression',
|
||||
start: 0,
|
||||
@ -624,19 +622,18 @@ export function createCallExpressionStdLib(
|
||||
type: 'Identifier',
|
||||
start: 0,
|
||||
end: 0,
|
||||
digest: null,
|
||||
|
||||
name,
|
||||
},
|
||||
optional: false,
|
||||
arguments: args,
|
||||
digest: null,
|
||||
}
|
||||
}
|
||||
|
||||
export function createCallExpression(
|
||||
name: string,
|
||||
args: CallExpression['arguments']
|
||||
): CallExpression {
|
||||
): UnboxedNode<CallExpression> {
|
||||
return {
|
||||
type: 'CallExpression',
|
||||
start: 0,
|
||||
@ -645,23 +642,22 @@ export function createCallExpression(
|
||||
type: 'Identifier',
|
||||
start: 0,
|
||||
end: 0,
|
||||
digest: null,
|
||||
|
||||
name,
|
||||
},
|
||||
optional: false,
|
||||
arguments: args,
|
||||
digest: null,
|
||||
}
|
||||
}
|
||||
|
||||
export function createArrayExpression(
|
||||
elements: ArrayExpression['elements']
|
||||
): ArrayExpression {
|
||||
): UnboxedNode<ArrayExpression> {
|
||||
return {
|
||||
type: 'ArrayExpression',
|
||||
start: 0,
|
||||
end: 0,
|
||||
digest: null,
|
||||
|
||||
nonCodeMeta: nonCodeMetaEmpty(),
|
||||
elements,
|
||||
}
|
||||
@ -669,12 +665,12 @@ export function createArrayExpression(
|
||||
|
||||
export function createPipeExpression(
|
||||
body: PipeExpression['body']
|
||||
): PipeExpression {
|
||||
): UnboxedNode<PipeExpression> {
|
||||
return {
|
||||
type: 'PipeExpression',
|
||||
start: 0,
|
||||
end: 0,
|
||||
digest: null,
|
||||
|
||||
body,
|
||||
nonCodeMeta: nonCodeMetaEmpty(),
|
||||
}
|
||||
@ -685,18 +681,18 @@ export function createVariableDeclaration(
|
||||
init: VariableDeclarator['init'],
|
||||
visibility: VariableDeclaration['visibility'] = 'default',
|
||||
kind: VariableDeclaration['kind'] = 'const'
|
||||
): VariableDeclaration {
|
||||
): UnboxedNode<VariableDeclaration> {
|
||||
return {
|
||||
type: 'VariableDeclaration',
|
||||
start: 0,
|
||||
end: 0,
|
||||
digest: null,
|
||||
|
||||
declarations: [
|
||||
{
|
||||
type: 'VariableDeclarator',
|
||||
start: 0,
|
||||
end: 0,
|
||||
digest: null,
|
||||
|
||||
id: createIdentifier(varName),
|
||||
init,
|
||||
},
|
||||
@ -708,19 +704,19 @@ export function createVariableDeclaration(
|
||||
|
||||
export function createObjectExpression(properties: {
|
||||
[key: string]: Expr
|
||||
}): ObjectExpression {
|
||||
}): UnboxedNode<ObjectExpression> {
|
||||
return {
|
||||
type: 'ObjectExpression',
|
||||
start: 0,
|
||||
end: 0,
|
||||
digest: null,
|
||||
|
||||
nonCodeMeta: nonCodeMetaEmpty(),
|
||||
properties: Object.entries(properties).map(([key, value]) => ({
|
||||
type: 'ObjectProperty',
|
||||
start: 0,
|
||||
end: 0,
|
||||
key: createIdentifier(key),
|
||||
digest: null,
|
||||
|
||||
value,
|
||||
})),
|
||||
}
|
||||
@ -729,12 +725,12 @@ export function createObjectExpression(properties: {
|
||||
export function createUnaryExpression(
|
||||
argument: UnaryExpression['argument'],
|
||||
operator: UnaryExpression['operator'] = '-'
|
||||
): UnaryExpression {
|
||||
): UnboxedNode<UnaryExpression> {
|
||||
return {
|
||||
type: 'UnaryExpression',
|
||||
start: 0,
|
||||
end: 0,
|
||||
digest: null,
|
||||
|
||||
operator,
|
||||
argument,
|
||||
}
|
||||
@ -744,12 +740,12 @@ export function createBinaryExpression([left, operator, right]: [
|
||||
BinaryExpression['left'],
|
||||
BinaryExpression['operator'],
|
||||
BinaryExpression['right']
|
||||
]): BinaryExpression {
|
||||
]): UnboxedNode<BinaryExpression> {
|
||||
return {
|
||||
type: 'BinaryExpression',
|
||||
start: 0,
|
||||
end: 0,
|
||||
digest: null,
|
||||
|
||||
operator,
|
||||
left,
|
||||
right,
|
||||
@ -759,19 +755,19 @@ export function createBinaryExpression([left, operator, right]: [
|
||||
export function createBinaryExpressionWithUnary([left, right]: [
|
||||
BinaryExpression['left'],
|
||||
BinaryExpression['right']
|
||||
]): BinaryExpression {
|
||||
]): UnboxedNode<BinaryExpression> {
|
||||
if (right.type === 'UnaryExpression' && right.operator === '-')
|
||||
return createBinaryExpression([left, '-', right.argument])
|
||||
return createBinaryExpression([left, '+', right])
|
||||
}
|
||||
|
||||
export function giveSketchFnCallTag(
|
||||
ast: Program,
|
||||
ast: UnboxedNode<Program>,
|
||||
range: Selection['range'],
|
||||
tag?: string
|
||||
):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
tag: string
|
||||
isTagExisting: boolean
|
||||
pathToNode: PathToNode
|
||||
@ -806,7 +802,7 @@ export function giveSketchFnCallTag(
|
||||
}
|
||||
|
||||
export function moveValueIntoNewVariablePath(
|
||||
ast: Program,
|
||||
ast: UnboxedNode<Program>,
|
||||
programMemory: ProgramMemory,
|
||||
pathToNode: PathToNode,
|
||||
variableName: string
|
||||
@ -839,12 +835,12 @@ export function moveValueIntoNewVariablePath(
|
||||
}
|
||||
|
||||
export function moveValueIntoNewVariable(
|
||||
ast: Program,
|
||||
ast: UnboxedNode<Program>,
|
||||
programMemory: ProgramMemory,
|
||||
sourceRange: Selection['range'],
|
||||
variableName: string
|
||||
): {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToReplacedNode?: PathToNode
|
||||
} {
|
||||
const meta = isNodeSafeToReplace(ast, sourceRange)
|
||||
@ -877,17 +873,17 @@ export function moveValueIntoNewVariable(
|
||||
*/
|
||||
export function deleteSegmentFromPipeExpression(
|
||||
dependentRanges: SourceRange[],
|
||||
modifiedAst: Program,
|
||||
modifiedAst: UnboxedNode<Program>,
|
||||
programMemory: ProgramMemory,
|
||||
code: string,
|
||||
pathToNode: PathToNode
|
||||
): Program | Error {
|
||||
): UnboxedNode<Program> | Error {
|
||||
let _modifiedAst = structuredClone(modifiedAst)
|
||||
|
||||
dependentRanges.forEach((range) => {
|
||||
const path = getNodePathFromSourceRange(_modifiedAst, range)
|
||||
|
||||
const callExp = getNodeFromPath<CallExpression>(
|
||||
const callExp = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
_modifiedAst,
|
||||
path,
|
||||
'CallExpression',
|
||||
@ -933,11 +929,11 @@ export function deleteSegmentFromPipeExpression(
|
||||
export function removeSingleConstraintInfo(
|
||||
pathToCallExp: PathToNode,
|
||||
argDetails: SimplifiedArgDetails,
|
||||
ast: Program,
|
||||
ast: UnboxedNode<Program>,
|
||||
programMemory: ProgramMemory
|
||||
):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToNodeMap: PathToNodeMap
|
||||
}
|
||||
| false {
|
||||
@ -959,12 +955,12 @@ export function removeSingleConstraintInfo(
|
||||
}
|
||||
|
||||
export async function deleteFromSelection(
|
||||
ast: Program,
|
||||
ast: UnboxedNode<Program>,
|
||||
selection: Selection,
|
||||
programMemory: ProgramMemory,
|
||||
getFaceDetails: (id: string) => Promise<Models['FaceIsPlanar_type']> = () =>
|
||||
({} as any)
|
||||
): Promise<Program | Error> {
|
||||
): Promise<UnboxedNode<Program> | Error> {
|
||||
const astClone = structuredClone(ast)
|
||||
const range = selection.range
|
||||
const path = getNodePathFromSourceRange(ast, range)
|
||||
@ -1139,5 +1135,5 @@ export async function deleteFromSelection(
|
||||
}
|
||||
|
||||
const nonCodeMetaEmpty = () => {
|
||||
return { nonCodeNodes: {}, start: [], digest: null }
|
||||
return { nonCodeNodes: {}, startNodes: [], start: 0, end: 0 }
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ beforeAll(async () => {
|
||||
},
|
||||
})
|
||||
})
|
||||
}, 20_000)
|
||||
}, 30_000)
|
||||
|
||||
afterAll(() => {
|
||||
engineCommandManager.tearDown()
|
||||
|
@ -36,11 +36,12 @@ import {
|
||||
getSweepFromSuspectedPath,
|
||||
} from 'lang/std/artifactGraph'
|
||||
import { kclManager, engineCommandManager, editorManager } from 'lib/singletons'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
// Apply Fillet To Selection
|
||||
|
||||
export function applyFilletToSelection(
|
||||
ast: Program,
|
||||
ast: UnboxedNode<Program>,
|
||||
selection: Selections,
|
||||
radius: KclCommandValue
|
||||
): void | Error {
|
||||
@ -55,10 +56,12 @@ export function applyFilletToSelection(
|
||||
}
|
||||
|
||||
export function modifyAstCloneWithFilletAndTag(
|
||||
ast: Program,
|
||||
ast: UnboxedNode<Program>,
|
||||
selection: Selections,
|
||||
radius: KclCommandValue
|
||||
): { modifiedAst: Program; pathToFilletNode: Array<PathToNode> } | Error {
|
||||
):
|
||||
| { modifiedAst: UnboxedNode<Program>; pathToFilletNode: Array<PathToNode> }
|
||||
| Error {
|
||||
let clonedAst = structuredClone(ast)
|
||||
const clonedAstForGetExtrude = structuredClone(ast)
|
||||
|
||||
@ -246,7 +249,7 @@ export function getPathToExtrudeForSegmentSelection(
|
||||
}
|
||||
|
||||
async function updateAstAndFocus(
|
||||
modifiedAst: Program,
|
||||
modifiedAst: UnboxedNode<Program>,
|
||||
pathToFilletNode: Array<PathToNode>
|
||||
) {
|
||||
const updatedAst = await kclManager.updateAst(modifiedAst, true, {
|
||||
@ -258,7 +261,7 @@ async function updateAstAndFocus(
|
||||
}
|
||||
|
||||
function mutateAstWithTagForSketchSegment(
|
||||
astClone: Program,
|
||||
astClone: UnboxedNode<Program>,
|
||||
pathToSegmentNode: PathToNode
|
||||
): { modifiedAst: Program; tag: string } | Error {
|
||||
const segmentNode = getNodeFromPath<CallExpression>(
|
||||
@ -292,7 +295,7 @@ function mutateAstWithTagForSketchSegment(
|
||||
function getEdgeTagCall(
|
||||
tag: string,
|
||||
selectionType: string
|
||||
): Identifier | CallExpression {
|
||||
): UnboxedNode<Identifier | CallExpression> {
|
||||
let tagCall: Expr = createIdentifier(tag)
|
||||
|
||||
// Modify the tag based on selectionType
|
||||
@ -426,7 +429,7 @@ export const hasValidFilletSelection = ({
|
||||
code,
|
||||
}: {
|
||||
selectionRanges: Selections
|
||||
ast: Program
|
||||
ast: UnboxedNode<Program>
|
||||
code: string
|
||||
}) => {
|
||||
// check if there is anything filletable in the scene
|
||||
@ -454,7 +457,7 @@ export const hasValidFilletSelection = ({
|
||||
for (const selection of selectionRanges.codeBasedSelections) {
|
||||
// check if all selections are in sketchLineHelperMap
|
||||
const path = getNodePathFromSourceRange(ast, selection.range)
|
||||
const segmentNode = getNodeFromPath<CallExpression>(
|
||||
const segmentNode = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
ast,
|
||||
path,
|
||||
'CallExpression'
|
||||
@ -534,7 +537,7 @@ export const isTagUsedInFillet = ({
|
||||
ast,
|
||||
callExp,
|
||||
}: {
|
||||
ast: Program
|
||||
ast: UnboxedNode<Program>
|
||||
callExp: CallExpression
|
||||
}): Array<EdgeTypes> => {
|
||||
const tag = getTagFromCallExpression(callExp)
|
||||
|
@ -29,6 +29,7 @@ import {
|
||||
} from './std/sketchcombos'
|
||||
import { err } from 'lib/trap'
|
||||
import { ImportStatement } from 'wasm-lib/kcl/bindings/ImportStatement'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
/**
|
||||
* Retrieves a node from a given path within a Program node structure, optionally stopping at a specified node type.
|
||||
@ -121,12 +122,13 @@ export function getNodeFromPathCurry(
|
||||
}
|
||||
|
||||
function moreNodePathFromSourceRange(
|
||||
node:
|
||||
node: UnboxedNode<
|
||||
| Expr
|
||||
| ImportStatement
|
||||
| ExpressionStatement
|
||||
| VariableDeclaration
|
||||
| ReturnStatement,
|
||||
| ReturnStatement
|
||||
>,
|
||||
sourceRange: Selection['range'],
|
||||
previousPath: PathToNode = [['body', '']]
|
||||
): PathToNode {
|
||||
@ -344,15 +346,16 @@ export function getNodePathFromSourceRange(
|
||||
return path
|
||||
}
|
||||
|
||||
type KCLNode =
|
||||
type KCLNode = UnboxedNode<
|
||||
| Expr
|
||||
| ExpressionStatement
|
||||
| VariableDeclaration
|
||||
| VariableDeclarator
|
||||
| ReturnStatement
|
||||
>
|
||||
|
||||
export function traverse(
|
||||
node: KCLNode | Program,
|
||||
node: KCLNode | UnboxedNode<Program>,
|
||||
option: {
|
||||
enter?: (node: KCLNode, pathToNode: PathToNode) => void
|
||||
leave?: (node: KCLNode) => void
|
||||
@ -512,9 +515,9 @@ export function findAllPreviousVariables(
|
||||
}
|
||||
|
||||
type ReplacerFn = (
|
||||
_ast: Program,
|
||||
_ast: UnboxedNode<Program>,
|
||||
varName: string
|
||||
) => { modifiedAst: Program; pathToReplaced: PathToNode } | Error
|
||||
) => { modifiedAst: UnboxedNode<Program>; pathToReplaced: PathToNode } | Error
|
||||
|
||||
export function isNodeSafeToReplacePath(
|
||||
ast: Program,
|
||||
@ -583,12 +586,12 @@ export function isNodeSafeToReplacePath(
|
||||
}
|
||||
|
||||
export function isNodeSafeToReplace(
|
||||
ast: Program,
|
||||
ast: UnboxedNode<Program>,
|
||||
sourceRange: [number, number]
|
||||
):
|
||||
| {
|
||||
isSafe: boolean
|
||||
value: Expr
|
||||
value: UnboxedNode<Expr>
|
||||
replacer: ReplacerFn
|
||||
}
|
||||
| Error {
|
||||
@ -837,7 +840,7 @@ export function findUsesOfTagInPipe(
|
||||
? String(thirdParam.value)
|
||||
: thirdParam.name
|
||||
|
||||
const varDec = getNodeFromPath<VariableDeclaration>(
|
||||
const varDec = getNodeFromPath<UnboxedNode<VariableDeclaration>>(
|
||||
ast,
|
||||
pathToNode,
|
||||
'VariableDeclaration'
|
||||
|
@ -18,7 +18,7 @@ class FileSystemManager {
|
||||
return Promise.resolve(window.electron.path.join(dir, path))
|
||||
}
|
||||
|
||||
async readFile(path: string): Promise<Uint8Array | void> {
|
||||
async readFile(path: string): Promise<Uint8Array> {
|
||||
// Using local file system only works from desktop.
|
||||
if (!isDesktop()) {
|
||||
return Promise.reject(
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
import { getNodeFromPath, getNodePathFromSourceRange } from '../queryAst'
|
||||
import { enginelessExecutor } from '../../lib/testHelpers'
|
||||
import { err } from 'lib/trap'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
const eachQuad: [number, [number, number]][] = [
|
||||
[-315, [1, 1]],
|
||||
@ -687,7 +688,7 @@ describe('testing getConstraintInfo', () => {
|
||||
]
|
||||
if (err(ast)) return ast
|
||||
const pathToNode = getNodePathFromSourceRange(ast, sourceRange)
|
||||
const callExp = getNodeFromPath<CallExpression>(
|
||||
const callExp = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
ast,
|
||||
pathToNode,
|
||||
'CallExpression'
|
||||
@ -841,7 +842,7 @@ describe('testing getConstraintInfo', () => {
|
||||
]
|
||||
if (err(ast)) return ast
|
||||
const pathToNode = getNodePathFromSourceRange(ast, sourceRange)
|
||||
const callExp = getNodeFromPath<CallExpression>(
|
||||
const callExp = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
ast,
|
||||
pathToNode,
|
||||
'CallExpression'
|
||||
@ -1197,7 +1198,7 @@ describe('testing getConstraintInfo', () => {
|
||||
]
|
||||
if (err(ast)) return ast
|
||||
const pathToNode = getNodePathFromSourceRange(ast, sourceRange)
|
||||
const callExp = getNodeFromPath<CallExpression>(
|
||||
const callExp = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
ast,
|
||||
pathToNode,
|
||||
'CallExpression'
|
||||
|
@ -55,6 +55,7 @@ import { err } from 'lib/trap'
|
||||
import { perpendicularDistance } from 'sketch-helpers'
|
||||
import { TagDeclarator } from 'wasm-lib/kcl/bindings/TagDeclarator'
|
||||
import { EdgeCutInfo } from 'machines/modelingMachine'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
const STRAIGHT_SEGMENT_ERR = new Error(
|
||||
'Invalid input, expected "straight-segment"'
|
||||
@ -1785,7 +1786,8 @@ export const angledLineThatIntersects: SketchLineHelper = {
|
||||
)
|
||||
}
|
||||
if (intersectTag !== -1) {
|
||||
const tag = firstArg.properties[intersectTag]?.value as Identifier
|
||||
const tag = firstArg.properties[intersectTag]
|
||||
?.value as UnboxedNode<Identifier>
|
||||
const pathToTagProp: PathToNode = [
|
||||
...pathToObjectExp,
|
||||
[intersectTag, 'index'],
|
||||
@ -1823,11 +1825,12 @@ export const updateStartProfileAtArgs: SketchLineHelper['updateArgs'] = ({
|
||||
start: 0,
|
||||
end: 0,
|
||||
body: [],
|
||||
digest: null,
|
||||
|
||||
nonCodeMeta: {
|
||||
start: [],
|
||||
start: 0,
|
||||
end: 0,
|
||||
startNodes: [],
|
||||
nonCodeNodes: [],
|
||||
digest: null,
|
||||
},
|
||||
},
|
||||
pathToNode,
|
||||
@ -1866,7 +1869,7 @@ export const sketchLineHelperMap: { [key: string]: SketchLineHelper } = {
|
||||
} as const
|
||||
|
||||
export function changeSketchArguments(
|
||||
node: Program,
|
||||
node: UnboxedNode<Program>,
|
||||
programMemory: ProgramMemory,
|
||||
sourceRangeOrPath:
|
||||
| {
|
||||
@ -1878,7 +1881,7 @@ export function changeSketchArguments(
|
||||
pathToNode: PathToNode
|
||||
},
|
||||
input: SegmentInputs
|
||||
): { modifiedAst: Program; pathToNode: PathToNode } | Error {
|
||||
): { modifiedAst: UnboxedNode<Program>; pathToNode: PathToNode } | Error {
|
||||
const _node = { ...node }
|
||||
const thePath =
|
||||
sourceRangeOrPath.type === 'sourceRange'
|
||||
@ -1907,7 +1910,7 @@ export function changeSketchArguments(
|
||||
}
|
||||
|
||||
export function getConstraintInfo(
|
||||
callExpression: CallExpression,
|
||||
callExpression: UnboxedNode<CallExpression>,
|
||||
code: string,
|
||||
pathToNode: PathToNode
|
||||
): ConstrainInfo[] {
|
||||
@ -1945,7 +1948,7 @@ export function compareVec2Epsilon2(
|
||||
}
|
||||
|
||||
interface CreateLineFnCallArgs {
|
||||
node: Program
|
||||
node: UnboxedNode<Program>
|
||||
programMemory: ProgramMemory
|
||||
input: SegmentInputs
|
||||
fnName: ToolTip
|
||||
@ -1962,7 +1965,7 @@ export function addNewSketchLn({
|
||||
spliceBetween = false,
|
||||
}: CreateLineFnCallArgs):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToNode: PathToNode
|
||||
}
|
||||
| Error {
|
||||
@ -1972,8 +1975,12 @@ export function addNewSketchLn({
|
||||
return new Error('not a sketch line helper')
|
||||
}
|
||||
|
||||
getNodeFromPath<VariableDeclarator>(node, pathToNode, 'VariableDeclarator')
|
||||
getNodeFromPath<PipeExpression | CallExpression>(
|
||||
getNodeFromPath<UnboxedNode<VariableDeclarator>>(
|
||||
node,
|
||||
pathToNode,
|
||||
'VariableDeclarator'
|
||||
)
|
||||
getNodeFromPath<UnboxedNode<PipeExpression | CallExpression>>(
|
||||
node,
|
||||
pathToNode,
|
||||
'PipeExpression'
|
||||
@ -1992,13 +1999,13 @@ export function addCallExpressionsToPipe({
|
||||
pathToNode,
|
||||
expressions,
|
||||
}: {
|
||||
node: Program
|
||||
node: UnboxedNode<Program>
|
||||
programMemory: ProgramMemory
|
||||
pathToNode: PathToNode
|
||||
expressions: CallExpression[]
|
||||
expressions: UnboxedNode<CallExpression>[]
|
||||
}) {
|
||||
const _node = { ...node }
|
||||
const pipeExpression = getNodeFromPath<PipeExpression>(
|
||||
const pipeExpression = getNodeFromPath<UnboxedNode<PipeExpression>>(
|
||||
_node,
|
||||
pathToNode,
|
||||
'PipeExpression'
|
||||
@ -2047,7 +2054,7 @@ export function replaceSketchLine({
|
||||
replaceExistingCallback,
|
||||
referencedSegment,
|
||||
}: {
|
||||
node: Program
|
||||
node: UnboxedNode<Program>
|
||||
programMemory: ProgramMemory
|
||||
pathToNode: PathToNode
|
||||
fnName: ToolTip
|
||||
@ -2056,7 +2063,7 @@ export function replaceSketchLine({
|
||||
referencedSegment?: Path
|
||||
}):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
valueUsedInTransform?: number
|
||||
pathToNode: PathToNode
|
||||
}
|
||||
@ -2108,7 +2115,7 @@ function addTagToChamfer(
|
||||
edgeCutMeta: EdgeCutInfo | null
|
||||
):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
tag: string
|
||||
}
|
||||
| Error {
|
||||
@ -2235,7 +2242,7 @@ export function addTagForSketchOnFace(
|
||||
edgeCutMeta: EdgeCutInfo | null
|
||||
):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
tag: string
|
||||
}
|
||||
| Error {
|
||||
@ -2273,12 +2280,14 @@ function isAngleLiteral(lineArugement: Expr): boolean {
|
||||
: false
|
||||
}
|
||||
|
||||
type addTagFn = (a: AddTagInfo) => { modifiedAst: Program; tag: string } | Error
|
||||
type addTagFn = (
|
||||
a: AddTagInfo
|
||||
) => { modifiedAst: UnboxedNode<Program>; tag: string } | Error
|
||||
|
||||
function addTag(tagIndex = 2): addTagFn {
|
||||
return ({ node, pathToNode }) => {
|
||||
const _node = { ...node }
|
||||
const callExpr = getNodeFromPath<CallExpression>(
|
||||
const callExpr = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
_node,
|
||||
pathToNode,
|
||||
'CallExpression'
|
||||
|
@ -49,6 +49,7 @@ import {
|
||||
getSketchSegmentFromSourceRange,
|
||||
} from './sketchConstraints'
|
||||
import { getAngle, roundOff, normaliseAngle } from '../../lib/utils'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
export type LineInputsType =
|
||||
| 'xAbsolute'
|
||||
@ -325,7 +326,7 @@ const setHorzVertDistanceCreateNode =
|
||||
if (isUndef(refNum) || err(literalArg)) return REF_NUM_ERR
|
||||
|
||||
const valueUsedInTransform = roundOff(literalArg - refNum, 2)
|
||||
let finalValue: Expr = createBinaryExpressionWithUnary([
|
||||
let finalValue: UnboxedNode<Expr> = createBinaryExpressionWithUnary([
|
||||
createSegEnd(referenceSegName, !index),
|
||||
forceValueUsedInTransform || createLiteral(valueUsedInTransform),
|
||||
])
|
||||
@ -1541,7 +1542,7 @@ export function transformSecondarySketchLinesTagFirst({
|
||||
forceSegName,
|
||||
forceValueUsedInTransform,
|
||||
}: {
|
||||
ast: Program
|
||||
ast: UnboxedNode<Program>
|
||||
selectionRanges: Selections
|
||||
transformInfos: TransformInfo[]
|
||||
programMemory: ProgramMemory
|
||||
@ -1549,7 +1550,7 @@ export function transformSecondarySketchLinesTagFirst({
|
||||
forceValueUsedInTransform?: BinaryPart
|
||||
}):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
valueUsedInTransform?: number
|
||||
pathToNodeMap: PathToNodeMap
|
||||
tagInfo: {
|
||||
@ -1620,7 +1621,7 @@ export function transformAstSketchLines({
|
||||
forceValueUsedInTransform,
|
||||
referencedSegmentRange,
|
||||
}: {
|
||||
ast: Program
|
||||
ast: UnboxedNode<Program>
|
||||
selectionRanges: Selections | PathToNode[]
|
||||
transformInfos: TransformInfo[]
|
||||
programMemory: ProgramMemory
|
||||
@ -1629,7 +1630,7 @@ export function transformAstSketchLines({
|
||||
referencedSegmentRange?: Selection['range']
|
||||
}):
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
valueUsedInTransform?: number
|
||||
pathToNodeMap: PathToNodeMap
|
||||
}
|
||||
@ -1647,7 +1648,7 @@ export function transformAstSketchLines({
|
||||
|
||||
const getNode = getNodeFromPathCurry(node, _pathToNode)
|
||||
|
||||
const callExp = getNode<CallExpression>('CallExpression')
|
||||
const callExp = getNode<UnboxedNode<CallExpression>>('CallExpression')
|
||||
if (err(callExp)) return callExp
|
||||
const varDec = getNode<VariableDeclarator>('VariableDeclarator')
|
||||
if (err(varDec)) return varDec
|
||||
@ -1806,13 +1807,16 @@ function createSegAngle(referenceSegName: string): BinaryPart {
|
||||
return createCallExpression('segAng', [createIdentifier(referenceSegName)])
|
||||
}
|
||||
|
||||
function createSegEnd(referenceSegName: string, isX: boolean): CallExpression {
|
||||
function createSegEnd(
|
||||
referenceSegName: string,
|
||||
isX: boolean
|
||||
): UnboxedNode<CallExpression> {
|
||||
return createCallExpression(isX ? 'segEndX' : 'segEndY', [
|
||||
createIdentifier(referenceSegName),
|
||||
])
|
||||
}
|
||||
|
||||
function createLastSeg(isX: boolean): CallExpression {
|
||||
function createLastSeg(isX: boolean): UnboxedNode<CallExpression> {
|
||||
return createCallExpression(isX ? 'lastSegX' : 'lastSegY', [
|
||||
createPipeSubstitution(),
|
||||
])
|
||||
@ -1830,7 +1834,7 @@ export function getConstraintLevelFromSourceRange(
|
||||
ast: Program | Error
|
||||
): Error | { range: [number, number]; level: ConstraintLevel } {
|
||||
if (err(ast)) return ast
|
||||
const nodeMeta = getNodeFromPath<CallExpression>(
|
||||
const nodeMeta = getNodeFromPath<UnboxedNode<CallExpression>>(
|
||||
ast,
|
||||
getNodePathFromSourceRange(ast, cursorRange),
|
||||
'CallExpression'
|
||||
|
@ -11,16 +11,17 @@ import {
|
||||
BinaryPart,
|
||||
} from '../wasm'
|
||||
import { LineInputsType } from './sketchcombos'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
export interface ModifyAstBase {
|
||||
node: Program
|
||||
node: UnboxedNode<Program>
|
||||
// TODO #896: Remove ProgramMemory from this interface
|
||||
previousProgramMemory: ProgramMemory
|
||||
pathToNode: PathToNode
|
||||
}
|
||||
|
||||
export interface AddTagInfo {
|
||||
node: Program
|
||||
node: UnboxedNode<Program>
|
||||
pathToNode: PathToNode
|
||||
}
|
||||
|
||||
@ -134,7 +135,7 @@ type _InputArg<T> =
|
||||
* Which is why a union type is used that can be type narrowed using the {@link RawArg.type} property
|
||||
* {@link RawArg.expr} is common to all of these types
|
||||
*/
|
||||
export type InputArg = _InputArg<Expr>
|
||||
export type InputArg = _InputArg<UnboxedNode<Expr>>
|
||||
|
||||
/**
|
||||
* {@link RawArg.expr} is the literal equivalent of whatever current expression is
|
||||
@ -142,7 +143,7 @@ export type InputArg = _InputArg<Expr>
|
||||
* but of course works for expressions like myVar + someFn() etc too
|
||||
* This is useful in cases where we want to "un-constrain" inputs to segments
|
||||
*/
|
||||
type RawArg = _InputArg<Literal>
|
||||
type RawArg = _InputArg<UnboxedNode<Literal>>
|
||||
|
||||
export type InputArgs = Array<InputArg>
|
||||
|
||||
@ -186,7 +187,7 @@ export type CreateStdLibSketchCallExpr = (args: {
|
||||
inputs: InputArgs
|
||||
rawArgs: RawArgs
|
||||
referenceSegName: string
|
||||
tag?: Expr
|
||||
tag?: UnboxedNode<Expr>
|
||||
forceValueUsedInTransform?: BinaryPart
|
||||
referencedSegment?: Path
|
||||
}) => CreatedSketchExprResult | Error
|
||||
@ -215,26 +216,26 @@ export interface ConstrainInfo {
|
||||
export interface SketchLineHelper {
|
||||
add: (a: addCall) =>
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToNode: PathToNode
|
||||
valueUsedInTransform?: number
|
||||
}
|
||||
| Error
|
||||
updateArgs: (a: updateArgs) =>
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
pathToNode: PathToNode
|
||||
}
|
||||
| Error
|
||||
getTag: (a: CallExpression) => string | Error
|
||||
addTag: (a: AddTagInfo) =>
|
||||
| {
|
||||
modifiedAst: Program
|
||||
modifiedAst: UnboxedNode<Program>
|
||||
tag: string
|
||||
}
|
||||
| Error
|
||||
getConstraintInfo: (
|
||||
callExp: CallExpression,
|
||||
callExp: UnboxedNode<CallExpression>,
|
||||
code: string,
|
||||
pathToNode: PathToNode
|
||||
) => ConstrainInfo[]
|
||||
|
13
src/lang/wasm.test.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { err } from 'lib/trap'
|
||||
import { parse } from './wasm'
|
||||
import { enginelessExecutor } from 'lib/testHelpers'
|
||||
|
||||
it('can execute parsed AST', async () => {
|
||||
const code = `x = 1
|
||||
// A comment.`
|
||||
const ast = parse(code)
|
||||
expect(err(ast)).toEqual(false)
|
||||
const execState = await enginelessExecutor(ast)
|
||||
expect(err(ast)).toEqual(false)
|
||||
expect(execState.memory.get('x')).toEqual(1)
|
||||
})
|
@ -42,6 +42,7 @@ import { ExecState as RawExecState } from '../wasm-lib/kcl/bindings/ExecState'
|
||||
import { ProgramMemory as RawProgramMemory } from '../wasm-lib/kcl/bindings/ProgramMemory'
|
||||
import { EnvironmentRef } from '../wasm-lib/kcl/bindings/EnvironmentRef'
|
||||
import { Environment } from '../wasm-lib/kcl/bindings/Environment'
|
||||
import { UnboxedNode } from 'wasm-lib/kcl/bindings/UnboxedNode'
|
||||
|
||||
export type { Program } from '../wasm-lib/kcl/bindings/Program'
|
||||
export type { Expr } from '../wasm-lib/kcl/bindings/Expr'
|
||||
@ -122,11 +123,11 @@ export const initPromise = initialise()
|
||||
export const rangeTypeFix = (ranges: number[][]): [number, number][] =>
|
||||
ranges.map(([start, end]) => [start, end])
|
||||
|
||||
export const parse = (code: string | Error): Program | Error => {
|
||||
export const parse = (code: string | Error): UnboxedNode<Program> | Error => {
|
||||
if (err(code)) return code
|
||||
|
||||
try {
|
||||
const program: Program = parse_wasm(code)
|
||||
const program: UnboxedNode<Program> = parse_wasm(code)
|
||||
return program
|
||||
} catch (e: any) {
|
||||
// throw e
|
||||
@ -378,7 +379,7 @@ export function sketchFromKclValue(
|
||||
}
|
||||
|
||||
export const executor = async (
|
||||
node: Program,
|
||||
node: UnboxedNode<Program>,
|
||||
programMemory: ProgramMemory | Error = ProgramMemory.empty(),
|
||||
idGenerator: IdGenerator = defaultIdGenerator(),
|
||||
engineCommandManager: EngineCommandManager,
|
||||
@ -402,7 +403,7 @@ export const executor = async (
|
||||
}
|
||||
|
||||
export const _executor = async (
|
||||
node: Program,
|
||||
node: UnboxedNode<Program>,
|
||||
programMemory: ProgramMemory | Error = ProgramMemory.empty(),
|
||||
idGenerator: IdGenerator = defaultIdGenerator(),
|
||||
engineCommandManager: EngineCommandManager,
|
||||
@ -493,13 +494,13 @@ export function lexer(str: string): Token[] | Error {
|
||||
|
||||
export const modifyAstForSketch = async (
|
||||
engineCommandManager: EngineCommandManager,
|
||||
ast: Program,
|
||||
ast: UnboxedNode<Program>,
|
||||
variableName: string,
|
||||
currentPlane: string,
|
||||
engineId: string
|
||||
): Promise<Program> => {
|
||||
): Promise<UnboxedNode<Program>> => {
|
||||
try {
|
||||
const updatedAst: Program = await modify_ast_for_sketch_wasm(
|
||||
const updatedAst: UnboxedNode<Program> = await modify_ast_for_sketch_wasm(
|
||||
engineCommandManager,
|
||||
JSON.stringify(ast),
|
||||
variableName,
|
||||
|
3
src/lib/codeEditor.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export const normalizeLineEndings = (str: string, normalized = '\n') => {
|
||||
return str.replace(/\r?\n/g, normalized)
|
||||
}
|
@ -190,10 +190,31 @@ export const modelingMachineCommandConfig: StateMachineCommandSetConfig<
|
||||
options: () => {
|
||||
return Object.entries(machineManager.machines).map(
|
||||
([_, machine]) => ({
|
||||
name: `${machine.id} (${
|
||||
machine.make_model.model || machine.make_model.manufacturer
|
||||
}) via ${machineManager.machineApiIp || 'the local network'}`,
|
||||
name:
|
||||
`${machine.id} (${
|
||||
machine.make_model.model || machine.make_model.manufacturer
|
||||
}) (${machine.state.state})` +
|
||||
(machine.hardware_configuration &&
|
||||
machine.hardware_configuration.type !== 'none' &&
|
||||
machine.hardware_configuration.config.nozzle_diameter
|
||||
? ` - Nozzle Diameter: ${machine.hardware_configuration.config.nozzle_diameter}`
|
||||
: '') +
|
||||
(machine.hardware_configuration &&
|
||||
machine.hardware_configuration.type !== 'none' &&
|
||||
machine.hardware_configuration.config.filaments &&
|
||||
machine.hardware_configuration.config.filaments[0]
|
||||
? ` - ${
|
||||
machine.hardware_configuration.config.filaments[0].name
|
||||
} #${
|
||||
machine.hardware_configuration.config &&
|
||||
machine.hardware_configuration.config.filaments[0].color?.slice(
|
||||
0,
|
||||
6
|
||||
)
|
||||
}`
|
||||
: ''),
|
||||
isCurrent: false,
|
||||
disabled: machine.state.state !== 'idle',
|
||||
value: machine as components['schemas']['MachineInfoResponse'],
|
||||
})
|
||||
)
|
||||
|