fluidcad 0.0.34 → 0.0.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/README.md +69 -0
  2. package/bin/commands/login.js +148 -0
  3. package/bin/commands/mcp.js +3 -2
  4. package/bin/commands/pack.js +49 -0
  5. package/bin/commands/publish.js +231 -0
  6. package/bin/fluidcad.js +6 -0
  7. package/bin/lib/api-client.js +48 -0
  8. package/bin/lib/browser.js +16 -0
  9. package/bin/lib/config.js +39 -0
  10. package/bin/lib/model-config.js +61 -0
  11. package/bin/lib/prompt.js +97 -0
  12. package/bin/lib/workspace.js +57 -0
  13. package/lib/dist/common/shape-factory.d.ts +2 -1
  14. package/lib/dist/common/shape-factory.js +4 -0
  15. package/lib/dist/common/transformable-primitive.d.ts +6 -5
  16. package/lib/dist/common/transformable-primitive.js +8 -7
  17. package/lib/dist/common/vertex.js +0 -1
  18. package/lib/dist/core/2d/aline.d.ts +4 -3
  19. package/lib/dist/core/2d/aline.js +3 -2
  20. package/lib/dist/core/2d/arc.d.ts +3 -2
  21. package/lib/dist/core/2d/arc.js +4 -3
  22. package/lib/dist/core/2d/bezier.d.ts +8 -6
  23. package/lib/dist/core/2d/circle.d.ts +4 -3
  24. package/lib/dist/core/2d/circle.js +3 -2
  25. package/lib/dist/core/2d/ellipse.d.ts +5 -4
  26. package/lib/dist/core/2d/ellipse.js +5 -4
  27. package/lib/dist/core/2d/hline.d.ts +4 -3
  28. package/lib/dist/core/2d/hline.js +5 -3
  29. package/lib/dist/core/2d/line.js +1 -0
  30. package/lib/dist/core/2d/offset.d.ts +3 -2
  31. package/lib/dist/core/2d/offset.js +6 -5
  32. package/lib/dist/core/2d/polygon.d.ts +5 -4
  33. package/lib/dist/core/2d/polygon.js +10 -9
  34. package/lib/dist/core/2d/rect.d.ts +4 -3
  35. package/lib/dist/core/2d/rect.js +10 -9
  36. package/lib/dist/core/2d/slot.d.ts +14 -6
  37. package/lib/dist/core/2d/slot.js +19 -8
  38. package/lib/dist/core/2d/vline.d.ts +4 -3
  39. package/lib/dist/core/2d/vline.js +5 -3
  40. package/lib/dist/core/chamfer.d.ts +5 -4
  41. package/lib/dist/core/chamfer.js +7 -6
  42. package/lib/dist/core/color.d.ts +3 -2
  43. package/lib/dist/core/color.js +2 -1
  44. package/lib/dist/core/cut.d.ts +4 -3
  45. package/lib/dist/core/cut.js +5 -4
  46. package/lib/dist/core/cylinder.d.ts +2 -1
  47. package/lib/dist/core/cylinder.js +2 -1
  48. package/lib/dist/core/draft.d.ts +3 -2
  49. package/lib/dist/core/draft.js +3 -2
  50. package/lib/dist/core/extrude.d.ts +4 -3
  51. package/lib/dist/core/extrude.js +5 -4
  52. package/lib/dist/core/fillet.d.ts +5 -4
  53. package/lib/dist/core/fillet.js +6 -5
  54. package/lib/dist/core/index.d.ts +1 -0
  55. package/lib/dist/core/index.js +1 -0
  56. package/lib/dist/core/interfaces.d.ts +25 -24
  57. package/lib/dist/core/param.d.ts +74 -0
  58. package/lib/dist/core/param.js +147 -0
  59. package/lib/dist/core/repeat.d.ts +2 -1
  60. package/lib/dist/core/repeat.js +10 -8
  61. package/lib/dist/core/revolve.d.ts +2 -1
  62. package/lib/dist/core/revolve.js +3 -2
  63. package/lib/dist/core/rib.d.ts +3 -2
  64. package/lib/dist/core/rib.js +6 -2
  65. package/lib/dist/core/rotate.d.ts +5 -4
  66. package/lib/dist/core/rotate.js +4 -3
  67. package/lib/dist/core/shell.d.ts +3 -2
  68. package/lib/dist/core/shell.js +3 -2
  69. package/lib/dist/core/sphere.d.ts +3 -2
  70. package/lib/dist/core/sphere.js +2 -1
  71. package/lib/dist/core/translate.d.ts +7 -6
  72. package/lib/dist/core/translate.js +6 -5
  73. package/lib/dist/features/2d/arc.js +5 -5
  74. package/lib/dist/features/2d/bezier.js +16 -16
  75. package/lib/dist/features/2d/circle.js +4 -0
  76. package/lib/dist/features/2d/ellipse.js +4 -0
  77. package/lib/dist/features/2d/hline.d.ts +3 -0
  78. package/lib/dist/features/2d/hline.js +9 -2
  79. package/lib/dist/features/2d/line.d.ts +3 -0
  80. package/lib/dist/features/2d/line.js +11 -3
  81. package/lib/dist/features/2d/sketch.js +5 -1
  82. package/lib/dist/features/2d/slot.d.ts +5 -0
  83. package/lib/dist/features/2d/slot.js +52 -7
  84. package/lib/dist/features/2d/tarc-to-point-tangent.js +3 -0
  85. package/lib/dist/features/2d/tarc-to-point.js +3 -0
  86. package/lib/dist/features/2d/tarc-with-tangent.js +3 -0
  87. package/lib/dist/features/2d/tarc.js +3 -0
  88. package/lib/dist/features/2d/vline.d.ts +3 -0
  89. package/lib/dist/features/2d/vline.js +9 -2
  90. package/lib/dist/features/copy-circular.d.ts +4 -3
  91. package/lib/dist/features/copy-circular.js +16 -9
  92. package/lib/dist/features/copy-circular2d.js +16 -9
  93. package/lib/dist/features/copy-linear.d.ts +4 -3
  94. package/lib/dist/features/copy-linear.js +18 -12
  95. package/lib/dist/features/copy-linear2d.js +18 -12
  96. package/lib/dist/features/extrude-base.d.ts +4 -3
  97. package/lib/dist/features/extrude-base.js +10 -3
  98. package/lib/dist/features/mirror-shape2d.js +2 -2
  99. package/lib/dist/features/repeat-base.d.ts +13 -0
  100. package/lib/dist/features/repeat-base.js +21 -0
  101. package/lib/dist/features/repeat-circular.d.ts +6 -5
  102. package/lib/dist/features/repeat-circular.js +3 -6
  103. package/lib/dist/features/repeat-linear.d.ts +7 -7
  104. package/lib/dist/features/repeat-linear.js +3 -6
  105. package/lib/dist/index.d.ts +5 -0
  106. package/lib/dist/index.js +8 -1
  107. package/lib/dist/io/file-import.d.ts +7 -0
  108. package/lib/dist/io/file-import.js +30 -10
  109. package/lib/dist/math/lazy-matrix.d.ts +5 -0
  110. package/lib/dist/math/lazy-matrix.js +78 -10
  111. package/lib/dist/oc/boolean-ops.d.ts +2 -2
  112. package/lib/dist/param-registry.d.ts +34 -0
  113. package/lib/dist/param-registry.js +60 -0
  114. package/lib/dist/rendering/mesh-builder.js +2 -1
  115. package/lib/dist/tests/features/copy-circular.test.js +1 -1
  116. package/lib/dist/tests/features/copy-linear.test.js +10 -10
  117. package/lib/dist/tests/features/repeat-user-repro-cache.test.d.ts +1 -0
  118. package/lib/dist/tests/features/repeat-user-repro-cache.test.js +97 -0
  119. package/lib/dist/tsconfig.tsbuildinfo +1 -1
  120. package/llm-docs/api/bezier.md +10 -11
  121. package/llm-docs/api/index.json +1 -1
  122. package/llm-docs/api/types/arc-points.md +2 -2
  123. package/llm-docs/api/types/cut.md +10 -10
  124. package/llm-docs/api/types/extrude.md +10 -10
  125. package/llm-docs/api/types/loft.md +6 -6
  126. package/llm-docs/api/types/revolve.md +6 -6
  127. package/llm-docs/api/types/rib.md +2 -2
  128. package/llm-docs/api/types/slot.md +2 -2
  129. package/llm-docs/api/types/sweep.md +10 -10
  130. package/llm-docs/api/types/transformable.md +14 -14
  131. package/llm-docs/index.json +12 -12
  132. package/mcp/dist/client.d.ts +1 -0
  133. package/mcp/dist/client.js +8 -1
  134. package/mcp/dist/server.js +14 -1
  135. package/mcp/dist/tools/engine.d.ts +16 -0
  136. package/mcp/dist/tools/engine.js +45 -0
  137. package/package.json +9 -3
  138. package/server/dist/api.d.ts +37 -0
  139. package/server/dist/api.js +44 -0
  140. package/server/dist/code-editor.d.ts +64 -0
  141. package/server/dist/code-editor.js +520 -2
  142. package/server/dist/fluidcad-server.d.ts +87 -1
  143. package/server/dist/fluidcad-server.js +254 -88
  144. package/server/dist/host/blocked-imports.d.ts +8 -0
  145. package/server/dist/host/blocked-imports.js +30 -0
  146. package/server/dist/{vite-manager.d.ts → host/local-scene-host.d.ts} +3 -1
  147. package/server/dist/{vite-manager.js → host/local-scene-host.js} +6 -26
  148. package/server/dist/host/scene-host.d.ts +19 -0
  149. package/server/dist/host/scene-host.js +1 -0
  150. package/server/dist/index.js +24 -117
  151. package/server/dist/model-package/capture-params.d.ts +19 -0
  152. package/server/dist/model-package/capture-params.js +42 -0
  153. package/server/dist/model-package/pack.d.ts +23 -0
  154. package/server/dist/model-package/pack.js +230 -0
  155. package/server/dist/model-package/types.d.ts +79 -0
  156. package/server/dist/model-package/types.js +17 -0
  157. package/server/dist/routes/hit-test.d.ts +3 -0
  158. package/server/dist/routes/hit-test.js +17 -0
  159. package/server/dist/routes/pack.d.ts +10 -0
  160. package/server/dist/routes/pack.js +47 -0
  161. package/server/dist/routes/params.d.ts +3 -0
  162. package/server/dist/routes/params.js +75 -0
  163. package/server/dist/routes/sketch-edits.d.ts +3 -0
  164. package/server/dist/routes/sketch-edits.js +542 -0
  165. package/server/dist/routes/timeline.d.ts +3 -0
  166. package/server/dist/routes/timeline.js +49 -0
  167. package/server/dist/server-core.d.ts +53 -0
  168. package/server/dist/server-core.js +147 -0
  169. package/server/dist/ws-protocol.d.ts +101 -2
  170. package/ui/dist/assets/index-CDJmUpFI.css +2 -0
  171. package/ui/dist/assets/index-MRqwG9Vh.js +5417 -0
  172. package/ui/dist/index.html +2 -2
  173. package/server/dist/routes/actions.d.ts +0 -3
  174. package/server/dist/routes/actions.js +0 -309
  175. package/ui/dist/assets/index-BdqrMDRu.js +0 -4946
  176. package/ui/dist/assets/index-DR7c2Qk9.css +0 -2
@@ -1,13 +1,14 @@
1
1
  import { PlaneLike } from "../../math/plane.js";
2
2
  import { IOffset, ISceneObject } from "../interfaces.js";
3
3
  import { Extrudable } from "../../helpers/types.js";
4
+ import { type NumberParam, type BooleanParam } from "../param.js";
4
5
  interface OffsetFunction {
5
6
  /**
6
7
  * Offsets the current sketch geometry by the given distance.
7
8
  * @param distance - The offset distance (defaults to 1)
8
9
  * @param removeOriginal - Whether to remove the original geometry
9
10
  */
10
- (distance?: number, removeOriginal?: boolean): IOffset;
11
+ (distance?: NumberParam, removeOriginal?: BooleanParam): IOffset;
11
12
  /**
12
13
  * Offsets source geometries onto a target plane.
13
14
  * @param targetPlane - The plane to offset onto
@@ -15,7 +16,7 @@ interface OffsetFunction {
15
16
  * @param removeOriginal - Whether to remove the original geometry
16
17
  * @param sourceGeometries - The geometries to offset
17
18
  */
18
- (targetPlane: PlaneLike | ISceneObject, distance: number, removeOriginal: boolean, ...sourceGeometries: Extrudable[]): IOffset;
19
+ (targetPlane: PlaneLike | ISceneObject, distance: NumberParam, removeOriginal: BooleanParam, ...sourceGeometries: Extrudable[]): IOffset;
19
20
  }
20
21
  declare const _default: OffsetFunction;
21
22
  export default _default;
@@ -1,25 +1,26 @@
1
1
  import { Offset } from "../../features/2d/offset.js";
2
2
  import { registerBuilder } from "../../index.js";
3
3
  import { resolvePlane } from "../../helpers/resolve.js";
4
+ import { isNumberParam, isBooleanParam, resolveParam } from "../param.js";
4
5
  function build(context) {
5
6
  return function offset(...args) {
6
7
  // Plane-first mode: offset(plane, distance, removeOriginal, ...sourceGeometries)
7
8
  // Detected when first arg is not a number/undefined.
8
- if (args.length > 0 && args[0] !== undefined && typeof args[0] !== 'number' && typeof args[0] !== 'boolean') {
9
+ if (args.length > 0 && args[0] !== undefined && !isNumberParam(args[0]) && !isBooleanParam(args[0])) {
9
10
  if (context.getActiveSketch() !== null) {
10
11
  throw new Error("offset(plane, ...) cannot be used inside a sketch. Use offset(...) instead.");
11
12
  }
12
13
  const planeObj = resolvePlane(args[0], context);
13
- const distance = args[1] ?? 1;
14
- const removeOriginal = args[2] ?? false;
14
+ const distance = resolveParam(args[1]) ?? 1;
15
+ const removeOriginal = resolveParam(args[2]) ?? false;
15
16
  const sourceObjects = args.slice(3);
16
17
  const off = new Offset(distance, removeOriginal, sourceObjects, planeObj);
17
18
  context.addSceneObject(off);
18
19
  return off;
19
20
  }
20
21
  // In-sketch mode: offset(distance, removeOriginal)
21
- const distance = args[0] ?? 1;
22
- const removeOriginal = args[1] ?? false;
22
+ const distance = isNumberParam(args[0]) ? resolveParam(args[0]) : 1;
23
+ const removeOriginal = isBooleanParam(args[1]) ? resolveParam(args[1]) : false;
23
24
  const off = new Offset(distance, removeOriginal);
24
25
  context.addSceneObject(off);
25
26
  return off;
@@ -2,6 +2,7 @@ import { Point2DLike } from "../../math/point.js";
2
2
  import { PolygonMode } from "../../features/2d/polygon.js";
3
3
  import { PlaneLike } from "../../math/plane.js";
4
4
  import { IPolygon, ISceneObject } from "../interfaces.js";
5
+ import { type NumberParam } from "../param.js";
5
6
  interface PolygonFunction {
6
7
  /**
7
8
  * Draws a regular polygon with the given number of sides and diameter.
@@ -9,7 +10,7 @@ interface PolygonFunction {
9
10
  * @param diameter - The circumscribed or inscribed diameter
10
11
  * @param mode - `'inscribed'` or `'circumscribed'` (defaults to `'inscribed'`)
11
12
  */
12
- (numberOfSides: number, diameter: number, mode?: PolygonMode): IPolygon;
13
+ (numberOfSides: NumberParam, diameter: NumberParam, mode?: PolygonMode): IPolygon;
13
14
  /**
14
15
  * Draws a regular polygon at a given center point.
15
16
  * @param center - The center point
@@ -17,14 +18,14 @@ interface PolygonFunction {
17
18
  * @param diameter - The circumscribed or inscribed diameter
18
19
  * @param mode - `'inscribed'` or `'circumscribed'` (defaults to `'inscribed'`)
19
20
  */
20
- (center: Point2DLike, numberOfSides: number, diameter: number, mode?: PolygonMode): IPolygon;
21
+ (center: Point2DLike, numberOfSides: NumberParam, diameter: NumberParam, mode?: PolygonMode): IPolygon;
21
22
  /**
22
23
  * Draws a regular polygon on a specific plane.
23
24
  * @param targetPlane - The plane to draw on
24
25
  * @param numberOfSides - The number of sides
25
26
  * @param diameter - The circumscribed or inscribed diameter
26
27
  */
27
- (targetPlane: PlaneLike | ISceneObject, numberOfSides: number, diameter: number): IPolygon;
28
+ (targetPlane: PlaneLike | ISceneObject, numberOfSides: NumberParam, diameter: NumberParam): IPolygon;
28
29
  /**
29
30
  * Draws a regular polygon with a given mode on a specific plane.
30
31
  * @param targetPlane - The plane to draw on
@@ -32,7 +33,7 @@ interface PolygonFunction {
32
33
  * @param diameter - The circumscribed or inscribed diameter
33
34
  * @param mode - `'inscribed'` or `'circumscribed'`
34
35
  */
35
- (targetPlane: PlaneLike | ISceneObject, numberOfSides: number, diameter: number, mode: PolygonMode): IPolygon;
36
+ (targetPlane: PlaneLike | ISceneObject, numberOfSides: NumberParam, diameter: NumberParam, mode: PolygonMode): IPolygon;
36
37
  }
37
38
  declare const _default: PolygonFunction;
38
39
  export default _default;
@@ -6,6 +6,7 @@ import { registerBuilder } from "../../index.js";
6
6
  import { isPlaneLike } from "../../math/plane.js";
7
7
  import { SceneObject } from "../../common/scene-object.js";
8
8
  import { resolvePlane } from "../../helpers/resolve.js";
9
+ import { isNumberParam, resolveParam } from "../param.js";
9
10
  function build(context) {
10
11
  return function polygon() {
11
12
  let numberOfSides;
@@ -30,24 +31,24 @@ function build(context) {
30
31
  }
31
32
  const argCount = arguments.length - argOffset;
32
33
  if (argCount === 2) {
33
- numberOfSides = arguments[argOffset];
34
- diameter = arguments[argOffset + 1];
34
+ numberOfSides = resolveParam(arguments[argOffset]);
35
+ diameter = resolveParam(arguments[argOffset + 1]);
35
36
  mode = 'inscribed';
36
37
  poly = new Polygon(numberOfSides, diameter, mode, planeObj);
37
38
  context.addSceneObject(poly);
38
39
  }
39
40
  else if (argCount === 3) {
40
- if (typeof arguments[argOffset] === 'number') {
41
- numberOfSides = arguments[argOffset];
42
- diameter = arguments[argOffset + 1];
41
+ if (isNumberParam(arguments[argOffset])) {
42
+ numberOfSides = resolveParam(arguments[argOffset]);
43
+ diameter = resolveParam(arguments[argOffset + 1]);
43
44
  mode = arguments[argOffset + 2];
44
45
  poly = new Polygon(numberOfSides, diameter, mode, planeObj);
45
46
  context.addSceneObject(poly);
46
47
  }
47
48
  else {
48
49
  center = normalizePoint2D(arguments[argOffset]);
49
- numberOfSides = arguments[argOffset + 1];
50
- diameter = arguments[argOffset + 2];
50
+ numberOfSides = resolveParam(arguments[argOffset + 1]);
51
+ diameter = resolveParam(arguments[argOffset + 2]);
51
52
  mode = 'inscribed';
52
53
  poly = new Polygon(numberOfSides, diameter, mode, planeObj);
53
54
  context.addSceneObjects([new Move(center), poly]);
@@ -55,8 +56,8 @@ function build(context) {
55
56
  }
56
57
  else if (argCount === 4) {
57
58
  center = normalizePoint2D(arguments[argOffset]);
58
- numberOfSides = arguments[argOffset + 1];
59
- diameter = arguments[argOffset + 2];
59
+ numberOfSides = resolveParam(arguments[argOffset + 1]);
60
+ diameter = resolveParam(arguments[argOffset + 2]);
60
61
  mode = arguments[argOffset + 3];
61
62
  poly = new Polygon(numberOfSides, diameter, mode, planeObj);
62
63
  context.addSceneObjects([new Move(center), poly]);
@@ -1,27 +1,28 @@
1
1
  import { Point2DLike } from "../../math/point.js";
2
2
  import { PlaneLike } from "../../math/plane.js";
3
3
  import { IRect, ISceneObject } from "../interfaces.js";
4
+ import { type NumberParam } from "../param.js";
4
5
  interface RectFunction {
5
6
  /**
6
7
  * Draws a rectangle with the given width and optional height.
7
8
  * @param width - The rectangle width
8
9
  * @param height - The rectangle height (defaults to width)
9
10
  */
10
- (width: number, height?: number): IRect;
11
+ (width: NumberParam, height?: NumberParam): IRect;
11
12
  /**
12
13
  * Draws a rectangle at a given start point.
13
14
  * @param start - The start point (bottom-left corner)
14
15
  * @param width - The rectangle width
15
16
  * @param height - The rectangle height (defaults to width)
16
17
  */
17
- (start: Point2DLike, width: number, height?: number): IRect;
18
+ (start: Point2DLike, width: NumberParam, height?: NumberParam): IRect;
18
19
  /**
19
20
  * Draws a rectangle with given dimensions on a specific plane.
20
21
  * @param targetPlane - The plane to draw on
21
22
  * @param width - The rectangle width
22
23
  * @param height - The rectangle height
23
24
  */
24
- (targetPlane: PlaneLike | ISceneObject, width: number, height: number): IRect;
25
+ (targetPlane: PlaneLike | ISceneObject, width: NumberParam, height: NumberParam): IRect;
25
26
  }
26
27
  declare const _default: RectFunction;
27
28
  export default _default;
@@ -6,6 +6,7 @@ import { registerBuilder } from "../../index.js";
6
6
  import { isPlaneLike } from "../../math/plane.js";
7
7
  import { SceneObject } from "../../common/scene-object.js";
8
8
  import { resolvePlane } from "../../helpers/resolve.js";
9
+ import { isNumberParam, resolveParam } from "../param.js";
9
10
  function build(context) {
10
11
  return function cRect() {
11
12
  // Detect plane as first argument (only valid outside a sketch)
@@ -16,8 +17,8 @@ function build(context) {
16
17
  throw new Error("rect(plane, ...) cannot be used inside a sketch. Use rect(...) instead.");
17
18
  }
18
19
  const planeObj = resolvePlane(firstArg, context);
19
- const width = arguments[1];
20
- const height = arguments[2];
20
+ const width = resolveParam(arguments[1]);
21
+ const height = resolveParam(arguments[2]);
21
22
  const rect = new Rect(width, height, planeObj);
22
23
  context.addSceneObject(rect);
23
24
  return rect;
@@ -25,22 +26,22 @@ function build(context) {
25
26
  }
26
27
  const argCount = arguments.length;
27
28
  if (argCount === 1) {
28
- const width = arguments[0];
29
+ const width = resolveParam(arguments[0]);
29
30
  const rect = new Rect(width, width);
30
31
  context.addSceneObject(rect);
31
32
  return rect;
32
33
  }
33
34
  else if (argCount === 2) {
34
- if (typeof arguments[0] === 'number') {
35
- const width = arguments[0];
36
- const height = arguments[1];
35
+ if (isNumberParam(arguments[0])) {
36
+ const width = resolveParam(arguments[0]);
37
+ const height = resolveParam(arguments[1]);
37
38
  const rect = new Rect(width, height);
38
39
  context.addSceneObject(rect);
39
40
  return rect;
40
41
  }
41
42
  else {
42
43
  const start = normalizePoint2D(arguments[0]);
43
- const width = arguments[1];
44
+ const width = resolveParam(arguments[1]);
44
45
  const rect = new Rect(width, width);
45
46
  context.addSceneObjects([new Move(start), rect]);
46
47
  return rect;
@@ -48,8 +49,8 @@ function build(context) {
48
49
  }
49
50
  else if (argCount === 3) {
50
51
  const start = normalizePoint2D(arguments[0]);
51
- const width = arguments[1];
52
- const height = arguments[2];
52
+ const width = resolveParam(arguments[1]);
53
+ const height = resolveParam(arguments[2]);
53
54
  const rect = new Rect(width, height);
54
55
  context.addSceneObjects([new Move(start), rect]);
55
56
  return rect;
@@ -1,41 +1,49 @@
1
1
  import { Point2DLike } from "../../math/point.js";
2
2
  import { PlaneLike } from "../../math/plane.js";
3
3
  import { ISlot, ISceneObject } from "../interfaces.js";
4
+ import { type NumberParam, type BooleanParam } from "../param.js";
4
5
  interface SlotFunction {
5
6
  /**
6
7
  * Draws a slot with the given length and end radius.
7
8
  * @param distance - The slot length
8
9
  * @param radius - The end cap radius
9
10
  */
10
- (distance: number, radius: number): ISlot;
11
+ (distance: NumberParam, radius: NumberParam): ISlot;
11
12
  /**
12
13
  * Draws a slot on a specific plane.
13
14
  * @param targetPlane - The plane to draw on
14
15
  * @param distance - The slot length
15
16
  * @param radius - The end cap radius
16
17
  */
17
- (targetPlane: PlaneLike | ISceneObject, distance: number, radius: number): ISlot;
18
+ (targetPlane: PlaneLike | ISceneObject, distance: NumberParam, radius: NumberParam): ISlot;
18
19
  /**
19
20
  * Draws a slot from a start point with the given length and end radius.
20
21
  * @param start - The start point
21
22
  * @param distance - The slot length
22
23
  * @param radius - The end cap radius
23
24
  */
24
- (start: Point2DLike, distance: number, radius: number): ISlot;
25
+ (start: Point2DLike, distance: NumberParam, radius: NumberParam): ISlot;
26
+ /**
27
+ * Draws a slot between two cap-center points with the given radius.
28
+ * @param start - Center of the first cap
29
+ * @param end - Center of the second cap
30
+ * @param radius - The end cap radius
31
+ */
32
+ (start: Point2DLike, end: Point2DLike, radius: number): ISlot;
25
33
  /**
26
34
  * Creates a slot from a geometry edge with the given radius.
27
35
  * @param geometry - The source geometry edge
28
36
  * @param radius - The end cap radius
29
37
  * @param deleteSource - Whether to delete the source geometry (defaults to true)
30
38
  */
31
- (geometry: ISceneObject, radius: number, deleteSource?: boolean): ISlot;
39
+ (geometry: ISceneObject, radius: NumberParam, deleteSource?: BooleanParam): ISlot;
32
40
  /**
33
41
  * Creates a slot from a geometry edge on a specific plane.
34
42
  * @param targetPlane - The plane to draw on
35
43
  * @param geometry - The source geometry edge
36
44
  * @param radius - The end cap radius
37
45
  */
38
- (targetPlane: PlaneLike | ISceneObject, geometry: ISceneObject, radius: number): ISlot;
46
+ (targetPlane: PlaneLike | ISceneObject, geometry: ISceneObject, radius: NumberParam): ISlot;
39
47
  /**
40
48
  * Creates a slot from a geometry edge, optionally keeping the source, on a specific plane.
41
49
  * @param targetPlane - The plane to draw on
@@ -43,7 +51,7 @@ interface SlotFunction {
43
51
  * @param radius - The end cap radius
44
52
  * @param deleteSource - Whether to delete the source geometry
45
53
  */
46
- (targetPlane: PlaneLike | ISceneObject, geometry: ISceneObject, radius: number, deleteSource: boolean): ISlot;
54
+ (targetPlane: PlaneLike | ISceneObject, geometry: ISceneObject, radius: NumberParam, deleteSource: BooleanParam): ISlot;
47
55
  }
48
56
  declare const _default: SlotFunction;
49
57
  export default _default;
@@ -7,6 +7,7 @@ import { registerBuilder } from "../../index.js";
7
7
  import { SceneObject } from "../../common/scene-object.js";
8
8
  import { isPlaneLike } from "../../math/plane.js";
9
9
  import { resolvePlane } from "../../helpers/resolve.js";
10
+ import { isNumberParam, isBooleanParam, resolveParam } from "../param.js";
10
11
  function build(context) {
11
12
  return function slot() {
12
13
  const inSketch = context.getActiveSketch() !== null;
@@ -29,10 +30,10 @@ function build(context) {
29
30
  // SlotFromEdge path: first non-plane arg is a SceneObject (geometry)
30
31
  if (arguments[argOffset] instanceof SceneObject && !isPoint2DLike(arguments[argOffset])) {
31
32
  const geometry = arguments[argOffset];
32
- const radius = arguments[argOffset + 1];
33
+ const radius = resolveParam(arguments[argOffset + 1]);
33
34
  let deleteSource = true;
34
- if (arguments.length > argOffset + 2 && typeof arguments[argOffset + 2] === 'boolean') {
35
- deleteSource = arguments[argOffset + 2];
35
+ if (arguments.length > argOffset + 2 && isBooleanParam(arguments[argOffset + 2])) {
36
+ deleteSource = resolveParam(arguments[argOffset + 2]);
36
37
  }
37
38
  const slotFromEdge = new SlotFromEdge(geometry, radius, deleteSource, planeObj);
38
39
  context.addSceneObject(slotFromEdge);
@@ -40,18 +41,28 @@ function build(context) {
40
41
  }
41
42
  const argCount = arguments.length - argOffset;
42
43
  // slot(distance, radius)
43
- if (argCount === 2 && typeof arguments[argOffset] === 'number') {
44
- const distance = arguments[argOffset];
45
- const radius = arguments[argOffset + 1];
44
+ if (argCount === 2 && isNumberParam(arguments[argOffset])) {
45
+ const distance = resolveParam(arguments[argOffset]);
46
+ const radius = resolveParam(arguments[argOffset + 1]);
46
47
  const s = new Slot(distance, radius, planeObj);
47
48
  context.addSceneObject(s);
48
49
  return s;
49
50
  }
51
+ // slot(start, end, radius) — in-sketch only
52
+ if (argCount === 3 && argOffset === 0
53
+ && isPoint2DLike(arguments[0]) && isPoint2DLike(arguments[1])) {
54
+ const start = normalizePoint2D(arguments[0]);
55
+ const end = normalizePoint2D(arguments[1]);
56
+ const radius = arguments[2];
57
+ const s = Slot.fromTwoPoints(start, end, radius, planeObj);
58
+ context.addSceneObjects([new Move(start), s]);
59
+ return s;
60
+ }
50
61
  // slot(start, distance, radius) — in-sketch only
51
62
  if (argCount === 3 && argOffset === 0) {
52
63
  const start = normalizePoint2D(arguments[0]);
53
- const distance = arguments[1];
54
- const radius = arguments[2];
64
+ const distance = resolveParam(arguments[1]);
65
+ const radius = resolveParam(arguments[2]);
55
66
  const s = new Slot(distance, radius, planeObj);
56
67
  context.addSceneObjects([new Move(start), s]);
57
68
  return s;
@@ -1,13 +1,14 @@
1
1
  import { Point2DLike } from "../../math/point.js";
2
2
  import { PlaneLike } from "../../math/plane.js";
3
3
  import { IVLine, ISceneObject } from "../interfaces.js";
4
+ import { type NumberParam } from "../param.js";
4
5
  interface VLineFunction {
5
6
  /**
6
7
  * Draws a vertical line of the given distance.
7
8
  * Chain `.centered()` to center the line on the current position.
8
9
  * @param distance - The line length
9
10
  */
10
- (distance: number): IVLine;
11
+ (distance: NumberParam): IVLine;
11
12
  /**
12
13
  * Draws a vertical line that ends where it intersects the target geometry.
13
14
  * The nearest intersection (in either direction along the Y axis) is used.
@@ -20,7 +21,7 @@ interface VLineFunction {
20
21
  * @param start - The start point
21
22
  * @param distance - The line length
22
23
  */
23
- (start: Point2DLike, distance: number): IVLine;
24
+ (start: Point2DLike, distance: NumberParam): IVLine;
24
25
  /**
25
26
  * Draws a vertical line from a start point that ends where it intersects
26
27
  * the target geometry. The nearest intersection (in either direction along
@@ -34,7 +35,7 @@ interface VLineFunction {
34
35
  * @param targetPlane - The plane to draw on
35
36
  * @param distance - The line length
36
37
  */
37
- (targetPlane: PlaneLike | ISceneObject, distance: number): IVLine;
38
+ (targetPlane: PlaneLike | ISceneObject, distance: NumberParam): IVLine;
38
39
  }
39
40
  declare const _default: VLineFunction;
40
41
  export default _default;
@@ -6,6 +6,7 @@ import { registerBuilder } from "../../index.js";
6
6
  import { isPlaneLike } from "../../math/plane.js";
7
7
  import { SceneObject } from "../../common/scene-object.js";
8
8
  import { resolvePlane } from "../../helpers/resolve.js";
9
+ import { isNumberParam, resolveParam } from "../param.js";
9
10
  function build(context) {
10
11
  return function line() {
11
12
  let planeObj = null;
@@ -31,18 +32,19 @@ function build(context) {
31
32
  context.addSceneObject(vline);
32
33
  return vline;
33
34
  }
34
- if (argOffset === 0 && typeof arguments[0] !== 'number') {
35
+ if (argOffset === 0 && !isNumberParam(arguments[0])) {
35
36
  // vLine(start, distance) or vLine(start, target)
36
37
  const start = normalizePoint2D(arguments[0]);
37
38
  const second = arguments[1];
38
39
  const distanceOrTarget = second instanceof SceneObject
39
40
  ? second
40
- : second;
41
+ : resolveParam(second);
41
42
  const vline = new VerticalLine(distanceOrTarget, planeObj);
43
+ vline.setHasExplicitStart();
42
44
  context.addSceneObjects([new Move(start), vline]);
43
45
  return vline;
44
46
  }
45
- const distance = arguments[argOffset];
47
+ const distance = resolveParam(arguments[argOffset]);
46
48
  const vline = new VerticalLine(distance, planeObj);
47
49
  context.addSceneObject(vline);
48
50
  return vline;
@@ -1,23 +1,24 @@
1
1
  import { ISceneObject } from "./interfaces.js";
2
+ import { type NumberParam, type BooleanParam } from "./param.js";
2
3
  interface ChamferFunction {
3
4
  /**
4
5
  * Chamfers selected edges with the given distance.
5
6
  * @param distance - The chamfer distance (defaults to 1)
6
7
  */
7
- (distance?: number): ISceneObject;
8
+ (distance?: NumberParam): ISceneObject;
8
9
  /**
9
10
  * Chamfers the given edge selections with the given distance.
10
11
  * @param distance - The chamfer distance
11
12
  * @param sceneObjects - The edge selections to chamfer
12
13
  */
13
- (distance: number, ...sceneObjects: ISceneObject[]): ISceneObject;
14
+ (distance: NumberParam, ...sceneObjects: ISceneObject[]): ISceneObject;
14
15
  /**
15
16
  * Chamfers selected edges with two distances or a distance and angle.
16
17
  * @param distance - The first chamfer distance
17
18
  * @param distance2 - The second distance, or angle if `isAngle` is true
18
19
  * @param isAngle - Whether `distance2` is an angle
19
20
  */
20
- (distance: number, distance2: number, isAngle?: boolean): ISceneObject;
21
+ (distance: NumberParam, distance2: NumberParam, isAngle?: BooleanParam): ISceneObject;
21
22
  /**
22
23
  * Chamfers the given edge selections with two distances or a distance and angle.
23
24
  * @param distance - The first chamfer distance
@@ -25,7 +26,7 @@ interface ChamferFunction {
25
26
  * @param isAngle - Whether `distance2` is an angle
26
27
  * @param sceneObjects - The edge selections to chamfer
27
28
  */
28
- (distance: number, distance2: number, isAngle: boolean, ...sceneObjects: ISceneObject[]): ISceneObject;
29
+ (distance: NumberParam, distance2: NumberParam, isAngle: BooleanParam, ...sceneObjects: ISceneObject[]): ISceneObject;
29
30
  }
30
31
  declare const _default: ChamferFunction;
31
32
  export default _default;
@@ -1,20 +1,21 @@
1
1
  import { Chamfer } from "../features/chamfer.js";
2
2
  import { SceneObject } from "../common/scene-object.js";
3
3
  import { registerBuilder } from "../index.js";
4
+ import { isNumberParam, isBooleanParam, resolveParam } from "./param.js";
4
5
  function build(context) {
5
6
  return function chamfer() {
6
7
  const args = Array.from(arguments);
7
8
  let distance = 1;
8
9
  let distance2 = undefined;
9
10
  let isAngle = false;
10
- if (args.length >= 1 && typeof args[0] === 'number') {
11
- distance = args[0];
11
+ if (args.length >= 1 && isNumberParam(args[0])) {
12
+ distance = resolveParam(args[0]);
12
13
  }
13
- if (args.length >= 2 && typeof args[1] === 'number') {
14
- distance2 = args[1];
14
+ if (args.length >= 2 && isNumberParam(args[1])) {
15
+ distance2 = resolveParam(args[1]);
15
16
  }
16
- if (args.length >= 3 && typeof args[2] === 'boolean') {
17
- isAngle = args[2];
17
+ if (args.length >= 3 && isBooleanParam(args[2])) {
18
+ isAngle = resolveParam(args[2]);
18
19
  }
19
20
  const selections = args
20
21
  .filter(a => a instanceof SceneObject);
@@ -1,16 +1,17 @@
1
1
  import { ISceneObject } from "./interfaces.js";
2
+ import { type StringParam } from "./param.js";
2
3
  interface ColorFunction {
3
4
  /**
4
5
  * Applies a color to the last selection.
5
6
  * @param color - The color value (CSS color string)
6
7
  */
7
- (color: string): ISceneObject;
8
+ (color: StringParam): ISceneObject;
8
9
  /**
9
10
  * Applies a color to the given selection.
10
11
  * @param color - The color value (CSS color string)
11
12
  * @param selection - The face or edge selection to color
12
13
  */
13
- (color: string, selection: ISceneObject): ISceneObject;
14
+ (color: StringParam, selection: ISceneObject): ISceneObject;
14
15
  }
15
16
  declare const _default: ColorFunction;
16
17
  export default _default;
@@ -1,6 +1,7 @@
1
1
  import { registerBuilder } from "../index.js";
2
2
  import { SceneObject } from "../common/scene-object.js";
3
3
  import { Color } from "../features/color.js";
4
+ import { resolveParam } from "./param.js";
4
5
  function build(context) {
5
6
  return function color() {
6
7
  let selection;
@@ -11,7 +12,7 @@ function build(context) {
11
12
  selection = context.getLastSelection() || undefined;
12
13
  }
13
14
  context.addSceneObject(selection);
14
- const obj = new Color(arguments[0], selection);
15
+ const obj = new Color(resolveParam(arguments[0]), selection);
15
16
  context.addSceneObject(obj);
16
17
  return obj;
17
18
  };
@@ -1,4 +1,5 @@
1
1
  import { ICut, ISceneObject } from "./interfaces.js";
2
+ import { type NumberParam } from "./param.js";
2
3
  interface CutFunction {
3
4
  /**
4
5
  * Cuts through all using the last sketch
@@ -15,20 +16,20 @@ interface CutFunction {
15
16
  * @param distance - The cut depth
16
17
  * @param target - The sketch to cut with
17
18
  */
18
- (distance: number, target?: ISceneObject): ICut;
19
+ (distance: NumberParam, target?: ISceneObject): ICut;
19
20
  /**
20
21
  * Cuts by two distances using the last sketch.
21
22
  * @param distance1 - The first cut distance
22
23
  * @param distance2 - The second cut distance
23
24
  */
24
- (distance1: number, distance2: number): ICut;
25
+ (distance1: NumberParam, distance2: NumberParam): ICut;
25
26
  /**
26
27
  * Cuts by two distances using the given sketch.
27
28
  * @param distance1 - The first cut distance
28
29
  * @param distance2 - The second cut distance
29
30
  * @param target - The sketch to cut with
30
31
  */
31
- (distance1: number, distance2: number, target: ISceneObject): ICut;
32
+ (distance1: NumberParam, distance2: NumberParam, target: ISceneObject): ICut;
32
33
  /**
33
34
  * Cuts up to a specific face using the last sketch.
34
35
  * @param face - A face selection to cut up to
@@ -3,6 +3,7 @@ import { registerBuilder } from "../index.js";
3
3
  import { Extrude } from "../features/extrude.js";
4
4
  import { ExtrudeToFace } from "../features/extrude-to-face.js";
5
5
  import { ExtrudeTwoDistances } from "../features/extrude-two-distances.js";
6
+ import { isNumberParam, resolveParam } from "./param.js";
6
7
  function isExtrudable(obj) {
7
8
  return obj instanceof SceneObject && obj.isExtrudable();
8
9
  }
@@ -12,8 +13,8 @@ function build(context) {
12
13
  return new Extrude(0, extrudable).remove();
13
14
  }
14
15
  else if (params.length === 1) {
15
- if (typeof params[0] === 'number') {
16
- return new Extrude(params[0], extrudable).remove();
16
+ if (isNumberParam(params[0])) {
17
+ return new Extrude(resolveParam(params[0]), extrudable).remove();
17
18
  }
18
19
  else if (params[0] === 'first-face') {
19
20
  return new ExtrudeToFace('first-face', extrudable).remove();
@@ -30,8 +31,8 @@ function build(context) {
30
31
  }
31
32
  }
32
33
  else if (params.length === 2) {
33
- if (typeof params[0] === 'number' && typeof params[1] === 'number') {
34
- return new ExtrudeTwoDistances(params[0], params[1], extrudable).remove();
34
+ if (isNumberParam(params[0]) && isNumberParam(params[1])) {
35
+ return new ExtrudeTwoDistances(resolveParam(params[0]), resolveParam(params[1]), extrudable).remove();
35
36
  }
36
37
  }
37
38
  throw new Error("Invalid parameters for cut function.");
@@ -1,11 +1,12 @@
1
1
  import { ITransformable } from "./interfaces.js";
2
+ import { type NumberParam } from "./param.js";
2
3
  interface CylinderFunction {
3
4
  /**
4
5
  * Creates a cylinder with the given radius and height.
5
6
  * @param radius - The cylinder radius
6
7
  * @param height - The cylinder height
7
8
  */
8
- (radius: number, height: number): ITransformable;
9
+ (radius: NumberParam, height: NumberParam): ITransformable;
9
10
  }
10
11
  declare const _default: CylinderFunction;
11
12
  export default _default;
@@ -1,8 +1,9 @@
1
1
  import { Cylinder } from "../features/cylinder.js";
2
2
  import { registerBuilder } from "../index.js";
3
+ import { resolveParam } from "./param.js";
3
4
  function build(context) {
4
5
  return function cylinder(radius, height) {
5
- const cylinder = new Cylinder(radius, height);
6
+ const cylinder = new Cylinder(resolveParam(radius), resolveParam(height));
6
7
  context.addSceneObject(cylinder);
7
8
  return cylinder;
8
9
  };
@@ -1,16 +1,17 @@
1
1
  import { ISceneObject, IDraft } from "./interfaces.js";
2
+ import { type NumberParam } from "./param.js";
2
3
  interface DraftFunction {
3
4
  /**
4
5
  * Applies a draft angle to the last selected faces.
5
6
  * @param angle - The draft angle in degrees
6
7
  */
7
- (angle: number): IDraft;
8
+ (angle: NumberParam): IDraft;
8
9
  /**
9
10
  * Applies a draft angle to the given face selections.
10
11
  * @param angle - The draft angle in degrees
11
12
  * @param selections - The face selections to draft
12
13
  */
13
- (angle: number, ...selections: ISceneObject[]): IDraft;
14
+ (angle: NumberParam, ...selections: ISceneObject[]): IDraft;
14
15
  }
15
16
  declare const _default: DraftFunction;
16
17
  export default _default;