Merge remote-tracking branch 'origin/main' into paultag/import
This commit is contained in:
		
							
								
								
									
										103
									
								
								.eslintrc
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								.eslintrc
									
									
									
									
									
								
							@ -1,103 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
    "parser": "@typescript-eslint/parser",
 | 
			
		||||
    "parserOptions": {
 | 
			
		||||
      "project": "./tsconfig.json"
 | 
			
		||||
    },
 | 
			
		||||
    "plugins": [
 | 
			
		||||
      "react-perf",
 | 
			
		||||
      "css-modules",
 | 
			
		||||
      "jest",
 | 
			
		||||
      "jsx-a11y",
 | 
			
		||||
      "react",
 | 
			
		||||
      "react-hooks",
 | 
			
		||||
      "suggest-no-throw",
 | 
			
		||||
      "testing-library",
 | 
			
		||||
      "@typescript-eslint"
 | 
			
		||||
    ],
 | 
			
		||||
    "extends": [
 | 
			
		||||
      "plugin:css-modules/recommended",
 | 
			
		||||
      "plugin:jsx-a11y/recommended",
 | 
			
		||||
      "plugin:react-hooks/recommended"
 | 
			
		||||
    ],
 | 
			
		||||
    "rules": {
 | 
			
		||||
      "no-array-constructor": "off", // This is wrong; use the @typescript-eslint one instead.
 | 
			
		||||
      "@typescript-eslint/no-array-constructor": "error",
 | 
			
		||||
      "@typescript-eslint/no-array-delete": "error",
 | 
			
		||||
      "@typescript-eslint/no-duplicate-enum-values": "error",
 | 
			
		||||
      "@typescript-eslint/no-duplicate-type-constituents": "error",
 | 
			
		||||
      "@typescript-eslint/no-empty-object-type": "error",
 | 
			
		||||
      "@typescript-eslint/no-extra-non-null-assertion": "error",
 | 
			
		||||
      "@typescript-eslint/no-floating-promises": "error",
 | 
			
		||||
      "@typescript-eslint/no-for-in-array": "error",
 | 
			
		||||
      "no-implied-eval": "off", // This is wrong; use the @typescript-eslint one instead.
 | 
			
		||||
      "@typescript-eslint/no-implied-eval": "error",
 | 
			
		||||
      "@typescript-eslint/no-misused-new": "error",
 | 
			
		||||
      "@typescript-eslint/no-misused-promises": "error",
 | 
			
		||||
      "@typescript-eslint/no-namespace": "error",
 | 
			
		||||
      "@typescript-eslint/no-non-null-asserted-optional-chain": "error",
 | 
			
		||||
      "@typescript-eslint/no-redundant-type-constituents": "error",
 | 
			
		||||
      "@typescript-eslint/no-this-alias": "warn",
 | 
			
		||||
      "@typescript-eslint/no-unnecessary-type-assertion": "error",
 | 
			
		||||
      "@typescript-eslint/no-unnecessary-type-constraint": "error",
 | 
			
		||||
      "no-unused-vars": "off", // This is wrong; use the @typescript-eslint one instead.
 | 
			
		||||
      "@typescript-eslint/no-unused-vars": ["error", {
 | 
			
		||||
        "varsIgnorePattern": "^_",
 | 
			
		||||
        "argsIgnorePattern": "^_",
 | 
			
		||||
        "ignoreRestSiblings": true,
 | 
			
		||||
        "vars": "all",
 | 
			
		||||
        "args": "none"
 | 
			
		||||
      }],
 | 
			
		||||
      "@typescript-eslint/no-unsafe-unary-minus": "error",
 | 
			
		||||
      "@typescript-eslint/no-wrapper-object-types": "error",
 | 
			
		||||
      "no-throw-literal": "off", // Use @typescript-eslint/only-throw-error instead.
 | 
			
		||||
      "@typescript-eslint/only-throw-error": "error",
 | 
			
		||||
      "@typescript-eslint/prefer-as-const": "warn",
 | 
			
		||||
      "@typescript-eslint/prefer-namespace-keyword": "error",
 | 
			
		||||
      "@typescript-eslint/restrict-plus-operands": "error",
 | 
			
		||||
      "jsx-a11y/click-events-have-key-events": "off",
 | 
			
		||||
      "jsx-a11y/no-autofocus": "off",
 | 
			
		||||
      "jsx-a11y/no-noninteractive-element-interactions": "off",
 | 
			
		||||
      "no-restricted-globals": [
 | 
			
		||||
        "error",
 | 
			
		||||
        {
 | 
			
		||||
          "name": "isNaN",
 | 
			
		||||
          "message": "Use Number.isNaN() instead."
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "no-restricted-syntax": [
 | 
			
		||||
        "error",
 | 
			
		||||
        {
 | 
			
		||||
          "selector": "CallExpression[callee.object.name='Array'][callee.property.name='isArray']",
 | 
			
		||||
          "message": "Use isArray() in lib/utils.ts instead of Array.isArray()."
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "semi": [
 | 
			
		||||
        "error",
 | 
			
		||||
        "never"
 | 
			
		||||
      ],
 | 
			
		||||
      "react-hooks/exhaustive-deps": "off",
 | 
			
		||||
      "suggest-no-throw/suggest-no-throw": "error"
 | 
			
		||||
    },
 | 
			
		||||
    "overrides": [
 | 
			
		||||
      {
 | 
			
		||||
        "files": ["e2e/**/*.ts"], // Update the pattern based on your file structure
 | 
			
		||||
        "extends": [
 | 
			
		||||
          "plugin:testing-library/react"
 | 
			
		||||
        ],
 | 
			
		||||
        "rules": {
 | 
			
		||||
          "suggest-no-throw/suggest-no-throw": "off",
 | 
			
		||||
          "testing-library/prefer-screen-queries": "off",
 | 
			
		||||
          "jest/valid-expect": "off"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "files": ["src/**/*.test.ts"],
 | 
			
		||||
        "extends": [
 | 
			
		||||
          "plugin:testing-library/react"
 | 
			
		||||
        ],
 | 
			
		||||
        "rules": {
 | 
			
		||||
          "suggest-no-throw/suggest-no-throw": "off"
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										127
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,127 @@
 | 
			
		||||
{
 | 
			
		||||
  "parser": "@typescript-eslint/parser",
 | 
			
		||||
  "parserOptions": {
 | 
			
		||||
    "project": "./tsconfig.json"
 | 
			
		||||
  },
 | 
			
		||||
  "plugins": [
 | 
			
		||||
    "react-perf",
 | 
			
		||||
    "css-modules",
 | 
			
		||||
    "jest",
 | 
			
		||||
    "jsx-a11y",
 | 
			
		||||
    "react",
 | 
			
		||||
    "react-hooks",
 | 
			
		||||
    "suggest-no-throw",
 | 
			
		||||
    "testing-library",
 | 
			
		||||
    "@typescript-eslint"
 | 
			
		||||
  ],
 | 
			
		||||
  "extends": [
 | 
			
		||||
    "plugin:css-modules/recommended",
 | 
			
		||||
    "plugin:jsx-a11y/recommended",
 | 
			
		||||
    "plugin:react-hooks/recommended"
 | 
			
		||||
  ],
 | 
			
		||||
  "rules": {
 | 
			
		||||
    "no-array-constructor": "off", // This is wrong; use the @typescript-eslint one instead.
 | 
			
		||||
    "@typescript-eslint/no-array-constructor": "error",
 | 
			
		||||
    "@typescript-eslint/no-array-delete": "error",
 | 
			
		||||
    "@typescript-eslint/no-duplicate-enum-values": "error",
 | 
			
		||||
    "@typescript-eslint/no-duplicate-type-constituents": "error",
 | 
			
		||||
    "@typescript-eslint/no-empty-object-type": "error",
 | 
			
		||||
    "@typescript-eslint/no-extra-non-null-assertion": "error",
 | 
			
		||||
    "@typescript-eslint/no-floating-promises": "error",
 | 
			
		||||
    "@typescript-eslint/no-for-in-array": "error",
 | 
			
		||||
    "no-implied-eval": "off", // This is wrong; use the @typescript-eslint one instead.
 | 
			
		||||
    "@typescript-eslint/no-implied-eval": "error",
 | 
			
		||||
    "@typescript-eslint/no-misused-new": "error",
 | 
			
		||||
    "@typescript-eslint/no-misused-promises": "error",
 | 
			
		||||
    "@typescript-eslint/no-namespace": "error",
 | 
			
		||||
    "@typescript-eslint/no-non-null-asserted-optional-chain": "error",
 | 
			
		||||
    "@typescript-eslint/no-redundant-type-constituents": "error",
 | 
			
		||||
    "@typescript-eslint/no-this-alias": "warn",
 | 
			
		||||
    "@typescript-eslint/no-unnecessary-type-assertion": "error",
 | 
			
		||||
    "@typescript-eslint/no-unnecessary-type-constraint": "error",
 | 
			
		||||
    "no-unused-vars": "off", // This is wrong; use the @typescript-eslint one instead.
 | 
			
		||||
    "@typescript-eslint/no-unused-vars": [
 | 
			
		||||
      "error",
 | 
			
		||||
      {
 | 
			
		||||
        "varsIgnorePattern": "^_",
 | 
			
		||||
        "argsIgnorePattern": "^_",
 | 
			
		||||
        "ignoreRestSiblings": true,
 | 
			
		||||
        "vars": "all",
 | 
			
		||||
        "args": "none"
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "@typescript-eslint/no-unsafe-unary-minus": "error",
 | 
			
		||||
    "@typescript-eslint/no-wrapper-object-types": "error",
 | 
			
		||||
    "no-throw-literal": "off", // Use @typescript-eslint/only-throw-error instead.
 | 
			
		||||
    "@typescript-eslint/only-throw-error": "error",
 | 
			
		||||
    "@typescript-eslint/prefer-as-const": "warn",
 | 
			
		||||
    "@typescript-eslint/prefer-namespace-keyword": "error",
 | 
			
		||||
    "@typescript-eslint/consistent-type-imports": "error",
 | 
			
		||||
    "@typescript-eslint/restrict-plus-operands": "error",
 | 
			
		||||
    "jsx-a11y/click-events-have-key-events": "off",
 | 
			
		||||
    "jsx-a11y/no-autofocus": "off",
 | 
			
		||||
    "jsx-a11y/no-noninteractive-element-interactions": "off",
 | 
			
		||||
    "no-restricted-globals": [
 | 
			
		||||
      "error",
 | 
			
		||||
      {
 | 
			
		||||
        "name": "isNaN",
 | 
			
		||||
        "message": "Use Number.isNaN() instead."
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "no-restricted-syntax": [
 | 
			
		||||
      "error",
 | 
			
		||||
      {
 | 
			
		||||
        "selector": "CallExpression[callee.object.name='Array'][callee.property.name='isArray']",
 | 
			
		||||
        "message": "Use isArray() in lib/utils.ts instead of Array.isArray()."
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "selector": "CallExpression[callee.object.name='TOML'][callee.property.name='stringify']",
 | 
			
		||||
        "message": "Do not use TOML.stringify directly. Use the wrappers in test-utils instead like settingsToToml."
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "selector": "CallExpression[callee.object.name='TOML'][callee.property.name='parse']",
 | 
			
		||||
        "message": "Do not use TOML.parse directly. Use the wrappers in test-utils instead like tomlToSettings."
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "no-restricted-imports": [
 | 
			
		||||
      "error",
 | 
			
		||||
      {
 | 
			
		||||
        "patterns": [
 | 
			
		||||
          // Restrict all relative imports except for .css files.
 | 
			
		||||
          {
 | 
			
		||||
            "group": ["./*", "../*", "!./*.css", "!../*.css"],
 | 
			
		||||
            "message": "Use absolute imports instead."
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "semi": ["error", "never"],
 | 
			
		||||
    "react-hooks/exhaustive-deps": "off",
 | 
			
		||||
    "suggest-no-throw/suggest-no-throw": "error"
 | 
			
		||||
  },
 | 
			
		||||
  "overrides": [
 | 
			
		||||
    {
 | 
			
		||||
      "files": ["e2e/**/*.ts"], // Update the pattern based on your file structure
 | 
			
		||||
      "extends": ["plugin:testing-library/react"],
 | 
			
		||||
      "rules": {
 | 
			
		||||
        "suggest-no-throw/suggest-no-throw": "off",
 | 
			
		||||
        "testing-library/prefer-screen-queries": "off",
 | 
			
		||||
        "jest/valid-expect": "off"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "files": ["src/**/*.test.ts"],
 | 
			
		||||
      "extends": ["plugin:testing-library/react"],
 | 
			
		||||
      "rules": {
 | 
			
		||||
        "suggest-no-throw/suggest-no-throw": "off"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "files": ["packages/**/*.ts", "rust/**/*.ts"],
 | 
			
		||||
      "extends": [],
 | 
			
		||||
      "rules": {
 | 
			
		||||
        "no-restricted-imports": "off"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -267784,9 +267784,10 @@
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "schema": {
 | 
			
		||||
          "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
 | 
			
		||||
          "title": "double",
 | 
			
		||||
          "title": "Nullable_double",
 | 
			
		||||
          "type": "number",
 | 
			
		||||
          "format": "double",
 | 
			
		||||
          "nullable": true,
 | 
			
		||||
          "definitions": {
 | 
			
		||||
            "Solid": {
 | 
			
		||||
              "type": "object",
 | 
			
		||||
@ -269371,9 +269372,9 @@
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "required": true,
 | 
			
		||||
        "required": false,
 | 
			
		||||
        "includeInSnippet": true,
 | 
			
		||||
        "description": "The scale factor for the x axis.",
 | 
			
		||||
        "description": "The scale factor for the x axis. Default is 1 if not provided.",
 | 
			
		||||
        "labelRequired": true
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
@ -269381,9 +269382,10 @@
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "schema": {
 | 
			
		||||
          "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
 | 
			
		||||
          "title": "double",
 | 
			
		||||
          "title": "Nullable_double",
 | 
			
		||||
          "type": "number",
 | 
			
		||||
          "format": "double",
 | 
			
		||||
          "nullable": true,
 | 
			
		||||
          "definitions": {
 | 
			
		||||
            "Solid": {
 | 
			
		||||
              "type": "object",
 | 
			
		||||
@ -270968,9 +270970,9 @@
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "required": true,
 | 
			
		||||
        "required": false,
 | 
			
		||||
        "includeInSnippet": true,
 | 
			
		||||
        "description": "The scale factor for the y axis.",
 | 
			
		||||
        "description": "The scale factor for the y axis. Default is 1 if not provided.",
 | 
			
		||||
        "labelRequired": true
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
@ -270978,9 +270980,10 @@
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "schema": {
 | 
			
		||||
          "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
 | 
			
		||||
          "title": "double",
 | 
			
		||||
          "title": "Nullable_double",
 | 
			
		||||
          "type": "number",
 | 
			
		||||
          "format": "double",
 | 
			
		||||
          "nullable": true,
 | 
			
		||||
          "definitions": {
 | 
			
		||||
            "Solid": {
 | 
			
		||||
              "type": "object",
 | 
			
		||||
@ -272565,9 +272568,9 @@
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "required": true,
 | 
			
		||||
        "required": false,
 | 
			
		||||
        "includeInSnippet": true,
 | 
			
		||||
        "description": "The scale factor for the z axis.",
 | 
			
		||||
        "description": "The scale factor for the z axis. Default is 1 if not provided.",
 | 
			
		||||
        "labelRequired": true
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
@ -275836,9 +275839,9 @@
 | 
			
		||||
    "unpublished": false,
 | 
			
		||||
    "deprecated": false,
 | 
			
		||||
    "examples": [
 | 
			
		||||
      "// Scale a pipe.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n  |> startProfileAt([0.05, 0.05], %)\n  |> line(end = [0, 7])\n  |> tangentialArc({ offset = 90, radius = 5 }, %)\n  |> line(end = [-3, 0])\n  |> tangentialArc({ offset = -90, radius = 5 }, %)\n  |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n  |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n  |> circle(center = [0, 0], radius = 2)\n  |> hole(pipeHole, %)\n  |> sweep(path = sweepPath)\n  |> scale(x = 1.0, y = 1.0, z = 2.5)",
 | 
			
		||||
      "// Scale an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n  |> scale(x = 1.0, y = 1.0, z = 2.5)",
 | 
			
		||||
      "// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n  |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n  |> angledLine([\n       segAng(rectangleSegmentA001) - 90,\n       50.61\n     ], %)\n  |> angledLine([\n       segAng(rectangleSegmentA001),\n       -segLen(rectangleSegmentA001)\n     ], %)\n  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n  |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n  |> yLine(length = 231.81)\n  |> tangentialArc({ radius = 80, offset = -90 }, %)\n  |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Scale the sweep.\nscale(\n  parts,\n  x = 1.0,\n  y = 1.0,\n  z = 0.5,\n)"
 | 
			
		||||
      "// Scale a pipe.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n  |> startProfileAt([0.05, 0.05], %)\n  |> line(end = [0, 7])\n  |> tangentialArc({ offset = 90, radius = 5 }, %)\n  |> line(end = [-3, 0])\n  |> tangentialArc({ offset = -90, radius = 5 }, %)\n  |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n  |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n  |> circle(center = [0, 0], radius = 2)\n  |> hole(pipeHole, %)\n  |> sweep(path = sweepPath)\n  |> scale(z = 2.5)",
 | 
			
		||||
      "// Scale an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n  |> scale(z = 2.5)",
 | 
			
		||||
      "// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n  |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n  |> angledLine([\n       segAng(rectangleSegmentA001) - 90,\n       50.61\n     ], %)\n  |> angledLine([\n       segAng(rectangleSegmentA001),\n       -segLen(rectangleSegmentA001)\n     ], %)\n  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n  |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n  |> yLine(length = 231.81)\n  |> tangentialArc({ radius = 80, offset = -90 }, %)\n  |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Scale the sweep.\nscale(parts, z = 0.5)"
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
@ -326051,9 +326054,10 @@
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "schema": {
 | 
			
		||||
          "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
 | 
			
		||||
          "title": "double",
 | 
			
		||||
          "title": "Nullable_double",
 | 
			
		||||
          "type": "number",
 | 
			
		||||
          "format": "double",
 | 
			
		||||
          "nullable": true,
 | 
			
		||||
          "definitions": {
 | 
			
		||||
            "Solid": {
 | 
			
		||||
              "type": "object",
 | 
			
		||||
@ -327638,9 +327642,9 @@
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "required": true,
 | 
			
		||||
        "required": false,
 | 
			
		||||
        "includeInSnippet": true,
 | 
			
		||||
        "description": "The amount to move the solid or sketch along the x axis.",
 | 
			
		||||
        "description": "The amount to move the solid or sketch along the x axis. Defaults to 0 if not provided.",
 | 
			
		||||
        "labelRequired": true
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
@ -327648,9 +327652,10 @@
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "schema": {
 | 
			
		||||
          "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
 | 
			
		||||
          "title": "double",
 | 
			
		||||
          "title": "Nullable_double",
 | 
			
		||||
          "type": "number",
 | 
			
		||||
          "format": "double",
 | 
			
		||||
          "nullable": true,
 | 
			
		||||
          "definitions": {
 | 
			
		||||
            "Solid": {
 | 
			
		||||
              "type": "object",
 | 
			
		||||
@ -329235,9 +329240,9 @@
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "required": true,
 | 
			
		||||
        "required": false,
 | 
			
		||||
        "includeInSnippet": true,
 | 
			
		||||
        "description": "The amount to move the solid or sketch along the y axis.",
 | 
			
		||||
        "description": "The amount to move the solid or sketch along the y axis. Defaults to 0 if not provided.",
 | 
			
		||||
        "labelRequired": true
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
@ -329245,9 +329250,10 @@
 | 
			
		||||
        "type": "number",
 | 
			
		||||
        "schema": {
 | 
			
		||||
          "$schema": "https://spec.openapis.org/oas/3.0/schema/2019-04-02#/definitions/Schema",
 | 
			
		||||
          "title": "double",
 | 
			
		||||
          "title": "Nullable_double",
 | 
			
		||||
          "type": "number",
 | 
			
		||||
          "format": "double",
 | 
			
		||||
          "nullable": true,
 | 
			
		||||
          "definitions": {
 | 
			
		||||
            "Solid": {
 | 
			
		||||
              "type": "object",
 | 
			
		||||
@ -330832,9 +330838,9 @@
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "required": true,
 | 
			
		||||
        "required": false,
 | 
			
		||||
        "includeInSnippet": true,
 | 
			
		||||
        "description": "The amount to move the solid or sketch along the z axis.",
 | 
			
		||||
        "description": "The amount to move the solid or sketch along the z axis. Defaults to 0 if not provided.",
 | 
			
		||||
        "labelRequired": true
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
@ -334106,8 +334112,8 @@
 | 
			
		||||
      "// Move a pipe.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n  |> startProfileAt([0.05, 0.05], %)\n  |> line(end = [0, 7])\n  |> tangentialArc({ offset = 90, radius = 5 }, %)\n  |> line(end = [-3, 0])\n  |> tangentialArc({ offset = -90, radius = 5 }, %)\n  |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n  |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n  |> circle(center = [0, 0], radius = 2)\n  |> hole(pipeHole, %)\n  |> sweep(path = sweepPath)\n  |> translate(x = 1.0, y = 1.0, z = 2.5)",
 | 
			
		||||
      "// Move an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n  |> translate(x = 1.0, y = 1.0, z = 2.5)",
 | 
			
		||||
      "// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n  |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n  |> angledLine([\n       segAng(rectangleSegmentA001) - 90,\n       50.61\n     ], %)\n  |> angledLine([\n       segAng(rectangleSegmentA001),\n       -segLen(rectangleSegmentA001)\n     ], %)\n  |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n  |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n  |> yLine(length = 231.81)\n  |> tangentialArc({ radius = 80, offset = -90 }, %)\n  |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Move the sweeps.\ntranslate(\n  parts,\n  x = 1.0,\n  y = 1.0,\n  z = 2.5,\n)",
 | 
			
		||||
      "// Move a sketch.\n\n\nfn square(length) {\n  l = length / 2\n  p0 = [-l, -l]\n  p1 = [-l, l]\n  p2 = [l, l]\n  p3 = [l, -l]\n\n  return startSketchOn(XY)\n    |> startProfileAt(p0, %)\n    |> line(endAbsolute = p1)\n    |> line(endAbsolute = p2)\n    |> line(endAbsolute = p3)\n    |> close()\n}\n\nsquare(10)\n  |> translate(x = 5, y = 5, z = 0)\n  |> extrude(length = 10)",
 | 
			
		||||
      "// Translate and rotate a sketch to create a loft.\nsketch001 = startSketchOn(XY)\n\nfn square() {\n  return startProfileAt([-10, 10], sketch001)\n    |> xLine(length = 20)\n    |> yLine(length = -20)\n    |> xLine(length = -20)\n    |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n    |> close()\n}\n\nprofile001 = square()\n\nprofile002 = square()\n  |> translate(x = 0, y = 0, z = 20)\n  |> rotate(axis = [0, 0, 1.0], angle = 45)\n\nloft([profile001, profile002])"
 | 
			
		||||
      "// Move a sketch.\n\n\nfn square(length) {\n  l = length / 2\n  p0 = [-l, -l]\n  p1 = [-l, l]\n  p2 = [l, l]\n  p3 = [l, -l]\n\n  return startSketchOn(XY)\n    |> startProfileAt(p0, %)\n    |> line(endAbsolute = p1)\n    |> line(endAbsolute = p2)\n    |> line(endAbsolute = p3)\n    |> close()\n}\n\nsquare(10)\n  |> translate(x = 5, y = 5)\n  |> extrude(length = 10)",
 | 
			
		||||
      "// Translate and rotate a sketch to create a loft.\nsketch001 = startSketchOn(XY)\n\nfn square() {\n  return startProfileAt([-10, 10], sketch001)\n    |> xLine(length = 20)\n    |> yLine(length = -20)\n    |> xLine(length = -20)\n    |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n    |> close()\n}\n\nprofile001 = square()\n\nprofile002 = square()\n  |> translate(z = 20)\n  |> rotate(axis = [0, 0, 1.0], angle = 45)\n\nloft([profile001, profile002])"
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
@ -13,9 +13,9 @@ Translate is really useful for sketches if you want to move a sketch and then ro
 | 
			
		||||
```js
 | 
			
		||||
translate(
 | 
			
		||||
  objects: SolidOrSketchOrImportedGeometry,
 | 
			
		||||
  x: number,
 | 
			
		||||
  y: number,
 | 
			
		||||
  z: number,
 | 
			
		||||
  x?: number,
 | 
			
		||||
  y?: number,
 | 
			
		||||
  z?: number,
 | 
			
		||||
  global?: bool,
 | 
			
		||||
): SolidOrSketchOrImportedGeometry
 | 
			
		||||
```
 | 
			
		||||
@ -26,9 +26,9 @@ translate(
 | 
			
		||||
| Name | Type | Description | Required |
 | 
			
		||||
|----------|------|-------------|----------|
 | 
			
		||||
| `objects` | [`SolidOrSketchOrImportedGeometry`](/docs/kcl/types/SolidOrSketchOrImportedGeometry) | The solid, sketch, or set of solids or sketches to move. | Yes |
 | 
			
		||||
| `x` | [`number`](/docs/kcl/types/number) | The amount to move the solid or sketch along the x axis. | Yes |
 | 
			
		||||
| `y` | [`number`](/docs/kcl/types/number) | The amount to move the solid or sketch along the y axis. | Yes |
 | 
			
		||||
| `z` | [`number`](/docs/kcl/types/number) | The amount to move the solid or sketch along the z axis. | Yes |
 | 
			
		||||
| `x` | [`number`](/docs/kcl/types/number) | The amount to move the solid or sketch along the x axis. Defaults to 0 if not provided. | No |
 | 
			
		||||
| `y` | [`number`](/docs/kcl/types/number) | The amount to move the solid or sketch along the y axis. Defaults to 0 if not provided. | No |
 | 
			
		||||
| `z` | [`number`](/docs/kcl/types/number) | The amount to move the solid or sketch along the z axis. Defaults to 0 if not provided. | No |
 | 
			
		||||
| `global` | [`bool`](/docs/kcl/types/bool) | If true, the transform is applied in global space. The origin of the model will move. By default, the transform is applied in local sketch axis, therefore the origin will not move. | No |
 | 
			
		||||
 | 
			
		||||
### Returns
 | 
			
		||||
@ -134,7 +134,7 @@ fn square(length) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
square(10)
 | 
			
		||||
  |> translate(x = 5, y = 5, z = 0)
 | 
			
		||||
  |> translate(x = 5, y = 5)
 | 
			
		||||
  |> extrude(length = 10)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -156,7 +156,7 @@ fn square() {
 | 
			
		||||
profile001 = square()
 | 
			
		||||
 | 
			
		||||
profile002 = square()
 | 
			
		||||
  |> translate(x = 0, y = 0, z = 20)
 | 
			
		||||
  |> translate(z = 20)
 | 
			
		||||
  |> rotate(axis = [0, 0, 1.0], angle = 45)
 | 
			
		||||
 | 
			
		||||
loft([profile001, profile002])
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Electron app header tests', () => {
 | 
			
		||||
  test(
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,14 @@
 | 
			
		||||
import { Page } from '@playwright/test'
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import type { Page } from '@playwright/test'
 | 
			
		||||
 | 
			
		||||
import type { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
 | 
			
		||||
import {
 | 
			
		||||
  getUtils,
 | 
			
		||||
  PERSIST_MODELING_CONTEXT,
 | 
			
		||||
  TEST_COLORS,
 | 
			
		||||
  commonPoints,
 | 
			
		||||
  PERSIST_MODELING_CONTEXT,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import { HomePageFixture } from './fixtures/homePageFixture'
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.setTimeout(120000)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,8 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import fs from 'node:fs/promises'
 | 
			
		||||
import path from 'node:path'
 | 
			
		||||
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Point and click for boolean workflows', () => {
 | 
			
		||||
  // Boolean operations to test
 | 
			
		||||
  const booleanOperations = [
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,11 @@
 | 
			
		||||
import { Page } from '@playwright/test'
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { HomePageFixture } from './fixtures/homePageFixture'
 | 
			
		||||
import { getUtils } from './test-utils'
 | 
			
		||||
import { EngineCommand } from 'lang/std/artifactGraph'
 | 
			
		||||
import { uuidv4 } from 'lib/utils'
 | 
			
		||||
import { SceneFixture } from './fixtures/sceneFixture'
 | 
			
		||||
import type { Page } from '@playwright/test'
 | 
			
		||||
import type { EngineCommand } from '@src/lang/std/artifactGraph'
 | 
			
		||||
import { uuidv4 } from '@src/lib/utils'
 | 
			
		||||
 | 
			
		||||
import type { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
 | 
			
		||||
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
 | 
			
		||||
import { getUtils } from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe(
 | 
			
		||||
  'Can create sketches on all planes and their back sides',
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,14 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import {
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  executorInputPath,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
import { bracket } from 'lib/exampleKcl'
 | 
			
		||||
import { TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW } from './storageStates'
 | 
			
		||||
import { bracket } from '@src/lib/exampleKcl'
 | 
			
		||||
import fsp from 'fs/promises'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
 | 
			
		||||
import { TEST_CODE_LONG_WITH_ERROR_OUT_OF_VIEW } from '@e2e/playwright/storageStates'
 | 
			
		||||
import {
 | 
			
		||||
  executorInputPath,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Code pane and errors', { tag: ['@skipWin'] }, () => {
 | 
			
		||||
  test('Typing KCL errors induces a badge on the code pane button', async ({
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,13 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { KCL_DEFAULT_LENGTH } from '@src/lib/constants'
 | 
			
		||||
import * as fsp from 'fs/promises'
 | 
			
		||||
import path, { join } from 'path'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  executorInputPath,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
 | 
			
		||||
import path, { join } from 'path'
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Command bar tests', { tag: ['@skipWin'] }, () => {
 | 
			
		||||
  test('Extrude from command bar selects extrude line after', async ({
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { getUtils } from './test-utils'
 | 
			
		||||
import { getUtils } from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Copilot ghost text', () => {
 | 
			
		||||
  // eslint-disable-next-line jest/valid-title
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
 | 
			
		||||
import { getUtils } from './test-utils'
 | 
			
		||||
import { getUtils } from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
function countNewlines(input: string): number {
 | 
			
		||||
  let count = 0
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,12 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import fsp from 'fs/promises'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  getUtils,
 | 
			
		||||
  executorInputPath,
 | 
			
		||||
  getPlaywrightDownloadDir,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import fsp from 'fs/promises'
 | 
			
		||||
  getUtils,
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test(
 | 
			
		||||
  'export works on the first try',
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,14 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { uuidv4 } from '@src/lib/utils'
 | 
			
		||||
import fsp from 'fs/promises'
 | 
			
		||||
import { uuidv4 } from 'lib/utils'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  TEST_COLORS,
 | 
			
		||||
  executorInputPath,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
  TEST_COLORS,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Editor tests', { tag: ['@skipWin'] }, () => {
 | 
			
		||||
  test('can comment out code with ctrl+/', async ({ page, homePage }) => {
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,8 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import * as fsp from 'fs/promises'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
const FEATURE_TREE_EXAMPLE_CODE = `export fn timesFive(x) {
 | 
			
		||||
  return 5 * x
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,16 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import * as fsp from 'fs/promises'
 | 
			
		||||
import { FILE_EXT } from '@src/lib/constants'
 | 
			
		||||
import * as fs from 'fs'
 | 
			
		||||
import * as fsp from 'fs/promises'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  createProject,
 | 
			
		||||
  executorInputPath,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
  runningOnWindows,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
import { FILE_EXT } from 'lib/constants'
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('integrations tests', () => {
 | 
			
		||||
  test(
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import type { Page, Locator, Route, Request } from '@playwright/test'
 | 
			
		||||
import { expect, TestInfo } from '@playwright/test'
 | 
			
		||||
import type { Locator, Page, Request, Route, TestInfo } from '@playwright/test'
 | 
			
		||||
import { expect } from '@playwright/test'
 | 
			
		||||
import * as fs from 'fs'
 | 
			
		||||
import * as path from 'path'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,12 @@
 | 
			
		||||
import type { Page, Locator } from '@playwright/test'
 | 
			
		||||
import type { Locator, Page } from '@playwright/test'
 | 
			
		||||
import { expect } from '@playwright/test'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  closePane,
 | 
			
		||||
  checkIfPaneIsOpen,
 | 
			
		||||
  closePane,
 | 
			
		||||
  openPane,
 | 
			
		||||
  sansWhitespace,
 | 
			
		||||
} from '../test-utils'
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
 | 
			
		||||
interface EditorState {
 | 
			
		||||
  activeLines: Array<string>
 | 
			
		||||
 | 
			
		||||
@ -1,28 +1,28 @@
 | 
			
		||||
/* eslint-disable react-hooks/rules-of-hooks */
 | 
			
		||||
 | 
			
		||||
import type {
 | 
			
		||||
  BrowserContext,
 | 
			
		||||
  ElectronApplication,
 | 
			
		||||
  TestInfo,
 | 
			
		||||
  Page,
 | 
			
		||||
  TestInfo,
 | 
			
		||||
} from '@playwright/test'
 | 
			
		||||
 | 
			
		||||
import { _electron as electron } from '@playwright/test'
 | 
			
		||||
 | 
			
		||||
import * as TOML from '@iarna/toml'
 | 
			
		||||
import { TEST_SETTINGS } from '../storageStates'
 | 
			
		||||
import { SETTINGS_FILE_NAME } from 'lib/constants'
 | 
			
		||||
import { getUtils, setup } from '../test-utils'
 | 
			
		||||
import { SETTINGS_FILE_NAME } from '@src/lib/constants'
 | 
			
		||||
import type { DeepPartial } from '@src/lib/types'
 | 
			
		||||
import fsp from 'fs/promises'
 | 
			
		||||
import fs from 'node:fs'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
import { CmdBarFixture } from './cmdBarFixture'
 | 
			
		||||
import { EditorFixture } from './editorFixture'
 | 
			
		||||
import { ToolbarFixture } from './toolbarFixture'
 | 
			
		||||
import { SceneFixture } from './sceneFixture'
 | 
			
		||||
import { HomePageFixture } from './homePageFixture'
 | 
			
		||||
import { DeepPartial } from 'lib/types'
 | 
			
		||||
import { Settings } from '@rust/kcl-lib/bindings/Settings'
 | 
			
		||||
 | 
			
		||||
import type { Settings } from '@rust/kcl-lib/bindings/Settings'
 | 
			
		||||
 | 
			
		||||
import { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
 | 
			
		||||
import { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
 | 
			
		||||
import { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
 | 
			
		||||
import { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
 | 
			
		||||
import { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
 | 
			
		||||
 | 
			
		||||
import { TEST_SETTINGS } from '@e2e/playwright/storageStates'
 | 
			
		||||
import { getUtils, settingsToToml, setup } from '@e2e/playwright/test-utils'
 | 
			
		||||
 | 
			
		||||
export class AuthenticatedApp {
 | 
			
		||||
  public readonly page: Page
 | 
			
		||||
@ -287,26 +287,30 @@ export class ElectronZoo {
 | 
			
		||||
    let settingsOverridesToml = ''
 | 
			
		||||
 | 
			
		||||
    if (appSettings) {
 | 
			
		||||
      settingsOverridesToml = TOML.stringify({
 | 
			
		||||
        // @ts-expect-error
 | 
			
		||||
      settingsOverridesToml = settingsToToml({
 | 
			
		||||
        settings: {
 | 
			
		||||
          ...TEST_SETTINGS,
 | 
			
		||||
          ...appSettings,
 | 
			
		||||
          app: {
 | 
			
		||||
            ...TEST_SETTINGS.app,
 | 
			
		||||
            project_directory: this.projectDirName,
 | 
			
		||||
            ...appSettings.app,
 | 
			
		||||
          },
 | 
			
		||||
          project: {
 | 
			
		||||
            ...TEST_SETTINGS.project,
 | 
			
		||||
            directory: this.projectDirName,
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
    } else {
 | 
			
		||||
      settingsOverridesToml = TOML.stringify({
 | 
			
		||||
        // @ts-expect-error
 | 
			
		||||
      settingsOverridesToml = settingsToToml({
 | 
			
		||||
        settings: {
 | 
			
		||||
          ...TEST_SETTINGS,
 | 
			
		||||
          app: {
 | 
			
		||||
            ...TEST_SETTINGS.app,
 | 
			
		||||
            project_directory: this.projectDirName,
 | 
			
		||||
          },
 | 
			
		||||
          project: {
 | 
			
		||||
            ...TEST_SETTINGS.project,
 | 
			
		||||
            directory: this.projectDirName,
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import type { Page, Locator } from '@playwright/test'
 | 
			
		||||
import type { Locator, Page } from '@playwright/test'
 | 
			
		||||
import { expect } from '@playwright/test'
 | 
			
		||||
 | 
			
		||||
interface ProjectCardState {
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,17 @@
 | 
			
		||||
import type { Page, Locator } from '@playwright/test'
 | 
			
		||||
import { expect } from '../zoo-test'
 | 
			
		||||
import { isArray, uuidv4 } from 'lib/utils'
 | 
			
		||||
import { CmdBarFixture } from './cmdBarFixture'
 | 
			
		||||
import type { Locator, Page } from '@playwright/test'
 | 
			
		||||
import { isArray, uuidv4 } from '@src/lib/utils'
 | 
			
		||||
 | 
			
		||||
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  closeDebugPanel,
 | 
			
		||||
  doAndWaitForImageDiff,
 | 
			
		||||
  getPixelRGBs,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  openAndClearDebugPanel,
 | 
			
		||||
  sendCustomCmd,
 | 
			
		||||
  getUtils,
 | 
			
		||||
} from '../test-utils'
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
type MouseParams = {
 | 
			
		||||
  pixelDiff?: number
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,15 @@
 | 
			
		||||
import { type Page, type Locator, test } from '@playwright/test'
 | 
			
		||||
import { expect } from '../zoo-test'
 | 
			
		||||
import { type Locator, type Page, test } from '@playwright/test'
 | 
			
		||||
import type { SidebarType } from '@src/components/ModelingSidebar/ModelingPanes'
 | 
			
		||||
import { SIDEBAR_BUTTON_SUFFIX } from '@src/lib/constants'
 | 
			
		||||
import type { ToolbarModeName } from '@src/lib/toolbar'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  checkIfPaneIsOpen,
 | 
			
		||||
  closePane,
 | 
			
		||||
  doAndWaitForImageDiff,
 | 
			
		||||
  openPane,
 | 
			
		||||
} from '../test-utils'
 | 
			
		||||
import { SidebarType } from 'components/ModelingSidebar/ModelingPanes'
 | 
			
		||||
import { SIDEBAR_BUTTON_SUFFIX } from 'lib/constants'
 | 
			
		||||
import { ToolbarModeName } from 'lib/toolbar'
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
export class ToolbarFixture {
 | 
			
		||||
  public page: Page
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,8 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { executorInputPath } from './test-utils'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
import fsp from 'fs/promises'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
 | 
			
		||||
import { executorInputPath } from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test(
 | 
			
		||||
  'When machine-api server not found butt is disabled and shows the reason',
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,15 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { PROJECT_SETTINGS_FILE_NAME } from 'lib/constants'
 | 
			
		||||
import { PROJECT_SETTINGS_FILE_NAME } from '@src/lib/constants'
 | 
			
		||||
import * as fsp from 'fs/promises'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
 | 
			
		||||
import type { NamedView } from '@rust/kcl-lib/bindings/NamedView'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  createProject,
 | 
			
		||||
  tomlToPerProjectSettings,
 | 
			
		||||
  perProjectsettingsToToml,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import { NamedView } from '@rust/kcl-lib/bindings/NamedView'
 | 
			
		||||
  tomlToPerProjectSettings,
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
// Helper function to determine if the file path on disk exists
 | 
			
		||||
// Specifically this is used to check if project.toml exists on disk
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Not all menu actions are tested. Some are default electron menu actions.
 | 
			
		||||
@ -10,6 +10,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      test('File.Create project', async ({ tronApp, cmdBar, page }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const newProject =
 | 
			
		||||
@ -29,6 +30,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      test('File.Open project', async ({ tronApp, cmdBar, page }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const openProject =
 | 
			
		||||
@ -52,6 +54,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const userSettings = app.applicationMenu.getMenuItemById(
 | 
			
		||||
@ -75,6 +78,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const keybindings = app.applicationMenu.getMenuItemById(
 | 
			
		||||
@ -96,6 +100,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const menu = app.applicationMenu.getMenuItemById(
 | 
			
		||||
@ -112,6 +117,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      test('File.Preferences.Theme', async ({ tronApp, cmdBar, page }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const menu = app.applicationMenu.getMenuItemById(
 | 
			
		||||
@ -136,6 +142,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const menu = app.applicationMenu.getMenuItemById(
 | 
			
		||||
@ -152,6 +159,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      test('File.Preferences.Sign out', async ({ tronApp, cmdBar, page }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const menu = app.applicationMenu.getMenuItemById('File.Sign out')
 | 
			
		||||
@ -170,6 +178,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      test('Edit.Rename project', async ({ tronApp, cmdBar, page }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const menu = app.applicationMenu.getMenuItemById(
 | 
			
		||||
@ -188,6 +197,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      test('Edit.Delete project', async ({ tronApp, cmdBar, page }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const menu = app.applicationMenu.getMenuItemById(
 | 
			
		||||
@ -210,6 +220,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const menu = app.applicationMenu.getMenuItemById(
 | 
			
		||||
@ -228,6 +239,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      test('View.Command Palette...', async ({ tronApp, cmdBar, page }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const menu = app.applicationMenu.getMenuItemById(
 | 
			
		||||
@ -245,6 +257,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      test('Help.Show all commands', async ({ tronApp, cmdBar, page }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const menu = app.applicationMenu.getMenuItemById(
 | 
			
		||||
@ -260,6 +273,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      test('Help.KCL code samples', async ({ tronApp, cmdBar, page }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const menu = app.applicationMenu.getMenuItemById(
 | 
			
		||||
@ -275,6 +289,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const menu = app.applicationMenu.getMenuItemById(
 | 
			
		||||
@ -293,6 +308,7 @@ test.describe('Native file menu', { tag: ['@electron'] }, () => {
 | 
			
		||||
      test('Help.Reset onboarding', async ({ tronApp, cmdBar, page }) => {
 | 
			
		||||
        if (!tronApp) fail()
 | 
			
		||||
        // Run electron snippet to find the Menu!
 | 
			
		||||
        await page.waitForTimeout(100) // wait for createModelingPageMenu() to run
 | 
			
		||||
        await tronApp.electron.evaluate(async ({ app }) => {
 | 
			
		||||
          if (!app || !app.applicationMenu) fail()
 | 
			
		||||
          const menu = app.applicationMenu.getMenuItemById(
 | 
			
		||||
 | 
			
		||||
@ -2,8 +2,7 @@
 | 
			
		||||
// application, check it can make it to the project pane, and nothing more.
 | 
			
		||||
// It also tests our test wrappers are working.
 | 
			
		||||
// Additionally this serves as a nice minimal example.
 | 
			
		||||
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Open the application', () => {
 | 
			
		||||
  test('see the project view', async ({ page, context }) => {
 | 
			
		||||
 | 
			
		||||
@ -1,22 +1,23 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
import { bracket } from '@src/lib/exampleKcl'
 | 
			
		||||
import { onboardingPaths } from '@src/routes/Onboarding/paths'
 | 
			
		||||
import fsp from 'fs/promises'
 | 
			
		||||
import {
 | 
			
		||||
  getUtils,
 | 
			
		||||
  executorInputPath,
 | 
			
		||||
  createProject,
 | 
			
		||||
  settingsToToml,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import { bracket } from 'lib/exampleKcl'
 | 
			
		||||
import { onboardingPaths } from 'routes/Onboarding/paths'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
 | 
			
		||||
import { expectPixelColor } from '@e2e/playwright/fixtures/sceneFixture'
 | 
			
		||||
import {
 | 
			
		||||
  TEST_SETTINGS_KEY,
 | 
			
		||||
  TEST_SETTINGS_ONBOARDING_START,
 | 
			
		||||
  TEST_SETTINGS_ONBOARDING_EXPORT,
 | 
			
		||||
  TEST_SETTINGS_ONBOARDING_START,
 | 
			
		||||
  TEST_SETTINGS_ONBOARDING_USER_MENU,
 | 
			
		||||
} from './storageStates'
 | 
			
		||||
import { expectPixelColor } from './fixtures/sceneFixture'
 | 
			
		||||
} from '@e2e/playwright/storageStates'
 | 
			
		||||
import {
 | 
			
		||||
  createProject,
 | 
			
		||||
  executorInputPath,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
  settingsToToml,
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
// Because our default test settings have the onboardingStatus set to 'dismissed',
 | 
			
		||||
// we must set it to empty for the tests where we want to see the onboarding immediately.
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { test, expect } from '@playwright/test'
 | 
			
		||||
import { expect, test } from '@playwright/test'
 | 
			
		||||
 | 
			
		||||
/** @deprecated, import from ./fixtureSetup.ts instead */
 | 
			
		||||
export const _test = test
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
import { Page } from '@playwright/test'
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { EditorFixture } from './fixtures/editorFixture'
 | 
			
		||||
import { SceneFixture } from './fixtures/sceneFixture'
 | 
			
		||||
import { ToolbarFixture } from './fixtures/toolbarFixture'
 | 
			
		||||
import type { Locator, Page } from '@playwright/test'
 | 
			
		||||
import fs from 'node:fs/promises'
 | 
			
		||||
import path from 'node:path'
 | 
			
		||||
import { getUtils, orRunWhenFullSuiteEnabled } from './test-utils'
 | 
			
		||||
import { Locator } from '@playwright/test'
 | 
			
		||||
 | 
			
		||||
import type { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
 | 
			
		||||
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
 | 
			
		||||
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
 | 
			
		||||
import { getUtils, orRunWhenFullSuiteEnabled } from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
// test file is for testing point an click code gen functionality that's not sketch mode related
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,19 +1,20 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { DEFAULT_PROJECT_KCL_FILE } from '@src/lib/constants'
 | 
			
		||||
import fs from 'fs'
 | 
			
		||||
import fsp from 'fs/promises'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
 | 
			
		||||
import type { Paths } from '@e2e/playwright/test-utils'
 | 
			
		||||
import {
 | 
			
		||||
  createProject,
 | 
			
		||||
  doExport,
 | 
			
		||||
  executorInputPath,
 | 
			
		||||
  getPlaywrightDownloadDir,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  isOutOfViewInScrollContainer,
 | 
			
		||||
  Paths,
 | 
			
		||||
  createProject,
 | 
			
		||||
  getPlaywrightDownloadDir,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
  runningOnWindows,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import fsp from 'fs/promises'
 | 
			
		||||
import fs from 'fs'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
import { DEFAULT_PROJECT_KCL_FILE } from 'lib/constants'
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test(
 | 
			
		||||
  'projects reload if a new one is created, deleted, or renamed externally',
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
/* eslint-disable jest/no-conditional-expect */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { orRunWhenFullSuiteEnabled } from './test-utils'
 | 
			
		||||
import { orRunWhenFullSuiteEnabled } from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
/* eslint-disable jest/no-conditional-expect */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,18 @@
 | 
			
		||||
import { Page } from '@playwright/test'
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
import type { Page } from '@playwright/test'
 | 
			
		||||
import { bracket } from '@src/lib/exampleKcl'
 | 
			
		||||
import { reportRejection } from '@src/lib/trap'
 | 
			
		||||
import * as fsp from 'fs/promises'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
 | 
			
		||||
import { TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR } from '@e2e/playwright/storageStates'
 | 
			
		||||
import type { TestColor } from '@e2e/playwright/test-utils'
 | 
			
		||||
import {
 | 
			
		||||
  getUtils,
 | 
			
		||||
  TEST_COLORS,
 | 
			
		||||
  TestColor,
 | 
			
		||||
  executorInputPath,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import { TEST_CODE_TRIGGER_ENGINE_EXPORT_ERROR } from './storageStates'
 | 
			
		||||
import { bracket } from 'lib/exampleKcl'
 | 
			
		||||
import { reportRejection } from 'lib/trap'
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Regression tests', { tag: ['@skipWin'] }, () => {
 | 
			
		||||
  // bugs we found that don't fit neatly into other categories
 | 
			
		||||
 | 
			
		||||
@ -1,20 +1,20 @@
 | 
			
		||||
import { Page } from '@playwright/test'
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import type { Page } from '@playwright/test'
 | 
			
		||||
import { roundOff, uuidv4 } from '@src/lib/utils'
 | 
			
		||||
import fs from 'node:fs/promises'
 | 
			
		||||
import path from 'node:path'
 | 
			
		||||
import { HomePageFixture } from './fixtures/homePageFixture'
 | 
			
		||||
 | 
			
		||||
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
 | 
			
		||||
import type { HomePageFixture } from '@e2e/playwright/fixtures/homePageFixture'
 | 
			
		||||
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
 | 
			
		||||
import type { ToolbarFixture } from '@e2e/playwright/fixtures/toolbarFixture'
 | 
			
		||||
import {
 | 
			
		||||
  getMovementUtils,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  PERSIST_MODELING_CONTEXT,
 | 
			
		||||
  TEST_COLORS,
 | 
			
		||||
  getMovementUtils,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import { uuidv4, roundOff } from 'lib/utils'
 | 
			
		||||
import { SceneFixture } from './fixtures/sceneFixture'
 | 
			
		||||
import { ToolbarFixture } from './fixtures/toolbarFixture'
 | 
			
		||||
import { CmdBarFixture } from './fixtures/cmdBarFixture'
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Sketch tests', { tag: ['@skipWin'] }, () => {
 | 
			
		||||
  test('multi-sketch file shows multiple Edit Sketch buttons', async ({
 | 
			
		||||
 | 
			
		||||
@ -1,21 +1,22 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { secrets } from './secrets'
 | 
			
		||||
import {
 | 
			
		||||
  Paths,
 | 
			
		||||
  doExport,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  settingsToToml,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import { Models } from '@kittycad/lib'
 | 
			
		||||
import fsp from 'fs/promises'
 | 
			
		||||
import type { Models } from '@kittycad/lib'
 | 
			
		||||
import { KCL_DEFAULT_LENGTH } from '@src/lib/constants'
 | 
			
		||||
import { spawn } from 'child_process'
 | 
			
		||||
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
 | 
			
		||||
import fsp from 'fs/promises'
 | 
			
		||||
import JSZip from 'jszip'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from './storageStates'
 | 
			
		||||
import { SceneFixture } from './fixtures/sceneFixture'
 | 
			
		||||
import { CmdBarFixture } from './fixtures/cmdBarFixture'
 | 
			
		||||
 | 
			
		||||
import type { CmdBarFixture } from '@e2e/playwright/fixtures/cmdBarFixture'
 | 
			
		||||
import type { SceneFixture } from '@e2e/playwright/fixtures/sceneFixture'
 | 
			
		||||
import { secrets } from '@e2e/playwright/secrets'
 | 
			
		||||
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from '@e2e/playwright/storageStates'
 | 
			
		||||
import type { Paths } from '@e2e/playwright/test-utils'
 | 
			
		||||
import {
 | 
			
		||||
  doExport,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
  settingsToToml,
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.beforeEach(async ({ page, context }) => {
 | 
			
		||||
  // Make the user avatar image always 404
 | 
			
		||||
@ -345,7 +346,9 @@ const extrudeDefaultPlane = async (
 | 
			
		||||
          app: {
 | 
			
		||||
            onboarding_status: 'dismissed',
 | 
			
		||||
            show_debug_panel: true,
 | 
			
		||||
            theme: 'dark',
 | 
			
		||||
            appearance: {
 | 
			
		||||
              theme: 'dark',
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
          project: {
 | 
			
		||||
            default_project_name: 'project-$nnn',
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,19 @@
 | 
			
		||||
import { Settings } from '@rust/kcl-lib/bindings/Settings'
 | 
			
		||||
import { SaveSettingsPayload } from 'lib/settings/settingsTypes'
 | 
			
		||||
import { Themes } from 'lib/theme'
 | 
			
		||||
import { DeepPartial } from 'lib/types'
 | 
			
		||||
import { onboardingPaths } from 'routes/Onboarding/paths'
 | 
			
		||||
import type { SaveSettingsPayload } from '@src/lib/settings/settingsTypes'
 | 
			
		||||
import { Themes } from '@src/lib/theme'
 | 
			
		||||
import type { DeepPartial } from '@src/lib/types'
 | 
			
		||||
import { onboardingPaths } from '@src/routes/Onboarding/paths'
 | 
			
		||||
 | 
			
		||||
import type { Settings } from '@rust/kcl-lib/bindings/Settings'
 | 
			
		||||
 | 
			
		||||
export const IS_PLAYWRIGHT_KEY = 'playwright'
 | 
			
		||||
 | 
			
		||||
export const TEST_SETTINGS_KEY = '/settings.toml'
 | 
			
		||||
export const TEST_SETTINGS: DeepPartial<Settings> = {
 | 
			
		||||
  app: {
 | 
			
		||||
    theme: Themes.Dark,
 | 
			
		||||
    appearance: {
 | 
			
		||||
      theme: Themes.Dark,
 | 
			
		||||
    },
 | 
			
		||||
    onboarding_status: 'dismissed',
 | 
			
		||||
    project_directory: '',
 | 
			
		||||
    show_debug_panel: true,
 | 
			
		||||
  },
 | 
			
		||||
  modeling: {
 | 
			
		||||
@ -22,6 +24,7 @@ export const TEST_SETTINGS: DeepPartial<Settings> = {
 | 
			
		||||
  },
 | 
			
		||||
  project: {
 | 
			
		||||
    default_project_name: 'project-$nnn',
 | 
			
		||||
    directory: '',
 | 
			
		||||
  },
 | 
			
		||||
  text_editor: {
 | 
			
		||||
    text_wrapping: true,
 | 
			
		||||
@ -54,7 +57,7 @@ export const TEST_SETTINGS_ONBOARDING_START: DeepPartial<Settings> = {
 | 
			
		||||
 | 
			
		||||
export const TEST_SETTINGS_DEFAULT_THEME: DeepPartial<Settings> = {
 | 
			
		||||
  ...TEST_SETTINGS,
 | 
			
		||||
  app: { ...TEST_SETTINGS.app, theme: Themes.System },
 | 
			
		||||
  app: { ...TEST_SETTINGS.app, appearance: { theme: Themes.System } },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const TEST_SETTINGS_CORRUPTED = {
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,12 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { commonPoints, getUtils, orRunWhenFullSuiteEnabled } from './test-utils'
 | 
			
		||||
import { EngineCommand } from 'lang/std/artifactGraph'
 | 
			
		||||
import { uuidv4 } from 'lib/utils'
 | 
			
		||||
import type { EngineCommand } from '@src/lang/std/artifactGraph'
 | 
			
		||||
import { uuidv4 } from '@src/lib/utils'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  commonPoints,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Test network and connection issues', () => {
 | 
			
		||||
  test(
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,9 @@
 | 
			
		||||
import {
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
  runningOnLinux,
 | 
			
		||||
  runningOnMac,
 | 
			
		||||
  runningOnWindows,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
 | 
			
		||||
describe('platform detection utilities', () => {
 | 
			
		||||
  const originalPlatform = process.platform
 | 
			
		||||
 | 
			
		||||
@ -1,32 +1,29 @@
 | 
			
		||||
import {
 | 
			
		||||
  expect,
 | 
			
		||||
  BrowserContext,
 | 
			
		||||
  TestInfo,
 | 
			
		||||
  Locator,
 | 
			
		||||
  Page,
 | 
			
		||||
} from '@playwright/test'
 | 
			
		||||
import { test } from './zoo-test'
 | 
			
		||||
import { EngineCommand } from 'lang/std/artifactGraph'
 | 
			
		||||
import * as TOML from '@iarna/toml'
 | 
			
		||||
import type { Models } from '@kittycad/lib'
 | 
			
		||||
import type { BrowserContext, Locator, Page, TestInfo } from '@playwright/test'
 | 
			
		||||
import { expect } from '@playwright/test'
 | 
			
		||||
import type { EngineCommand } from '@src/lang/std/artifactGraph'
 | 
			
		||||
import type { Configuration } from '@src/lang/wasm'
 | 
			
		||||
import { COOKIE_NAME } from '@src/lib/constants'
 | 
			
		||||
import { reportRejection } from '@src/lib/trap'
 | 
			
		||||
import type { DeepPartial } from '@src/lib/types'
 | 
			
		||||
import { isArray } from '@src/lib/utils'
 | 
			
		||||
import fsp from 'fs/promises'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
import pixelMatch from 'pixelmatch'
 | 
			
		||||
import type { Protocol } from 'playwright-core/types/protocol'
 | 
			
		||||
import { PNG } from 'pngjs'
 | 
			
		||||
import { Protocol } from 'playwright-core/types/protocol'
 | 
			
		||||
import type { Models } from '@kittycad/lib'
 | 
			
		||||
import { COOKIE_NAME } from 'lib/constants'
 | 
			
		||||
import { secrets } from './secrets'
 | 
			
		||||
 | 
			
		||||
import type { ProjectConfiguration } from '@rust/kcl-lib/bindings/ProjectConfiguration'
 | 
			
		||||
 | 
			
		||||
import { isErrorWhitelisted } from '@e2e/playwright/lib/console-error-whitelist'
 | 
			
		||||
import { secrets } from '@e2e/playwright/secrets'
 | 
			
		||||
import {
 | 
			
		||||
  TEST_SETTINGS_KEY,
 | 
			
		||||
  TEST_SETTINGS,
 | 
			
		||||
  IS_PLAYWRIGHT_KEY,
 | 
			
		||||
} from './storageStates'
 | 
			
		||||
import * as TOML from '@iarna/toml'
 | 
			
		||||
import { isErrorWhitelisted } from './lib/console-error-whitelist'
 | 
			
		||||
import { isArray } from 'lib/utils'
 | 
			
		||||
import { reportRejection } from 'lib/trap'
 | 
			
		||||
import { DeepPartial } from 'lib/types'
 | 
			
		||||
import { Configuration } from 'lang/wasm'
 | 
			
		||||
import { ProjectConfiguration } from '@rust/kcl-lib/bindings/ProjectConfiguration'
 | 
			
		||||
  TEST_SETTINGS,
 | 
			
		||||
  TEST_SETTINGS_KEY,
 | 
			
		||||
} from '@e2e/playwright/storageStates'
 | 
			
		||||
import { test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
const toNormalizedCode = (text: string) => {
 | 
			
		||||
  return text.replace(/\s+/g, '')
 | 
			
		||||
@ -683,8 +680,8 @@ const _makeTemplate = (
 | 
			
		||||
          isArray(currentOptions)
 | 
			
		||||
            ? currentOptions[i]
 | 
			
		||||
            : typeof currentOptions === 'number'
 | 
			
		||||
            ? currentOptions
 | 
			
		||||
            : ''
 | 
			
		||||
              ? currentOptions
 | 
			
		||||
              : ''
 | 
			
		||||
        )
 | 
			
		||||
      )
 | 
			
		||||
    })
 | 
			
		||||
@ -903,15 +900,21 @@ export async function setup(
 | 
			
		||||
        settings: {
 | 
			
		||||
          ...TEST_SETTINGS,
 | 
			
		||||
          app: {
 | 
			
		||||
            appearance: {
 | 
			
		||||
              ...TEST_SETTINGS.app?.appearance,
 | 
			
		||||
              theme: 'dark',
 | 
			
		||||
            },
 | 
			
		||||
            ...TEST_SETTINGS.project,
 | 
			
		||||
            project_directory: TEST_SETTINGS.app?.project_directory,
 | 
			
		||||
            onboarding_status: 'dismissed',
 | 
			
		||||
            theme: 'dark',
 | 
			
		||||
          },
 | 
			
		||||
          project: {
 | 
			
		||||
            ...TEST_SETTINGS.project,
 | 
			
		||||
            directory: TEST_SETTINGS.project?.directory,
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      }),
 | 
			
		||||
      IS_PLAYWRIGHT_KEY,
 | 
			
		||||
      PLAYWRIGHT_TEST_DIR: TEST_SETTINGS.app?.project_directory || '',
 | 
			
		||||
      PLAYWRIGHT_TEST_DIR: TEST_SETTINGS.project?.directory || '',
 | 
			
		||||
      PERSIST_MODELING_CONTEXT,
 | 
			
		||||
    }
 | 
			
		||||
  )
 | 
			
		||||
@ -1112,21 +1115,25 @@ export async function pollEditorLinesSelectedLength(page: Page, lines: number) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function settingsToToml(settings: DeepPartial<Configuration>) {
 | 
			
		||||
  // eslint-disable-next-line no-restricted-syntax
 | 
			
		||||
  return TOML.stringify(settings as any)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function tomlToSettings(toml: string): DeepPartial<Configuration> {
 | 
			
		||||
  // eslint-disable-next-line no-restricted-syntax
 | 
			
		||||
  return TOML.parse(toml)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function tomlToPerProjectSettings(
 | 
			
		||||
  toml: string
 | 
			
		||||
): DeepPartial<ProjectConfiguration> {
 | 
			
		||||
  // eslint-disable-next-line no-restricted-syntax
 | 
			
		||||
  return TOML.parse(toml)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function perProjectsettingsToToml(
 | 
			
		||||
  settings: DeepPartial<ProjectConfiguration>
 | 
			
		||||
) {
 | 
			
		||||
  // eslint-disable-next-line no-restricted-syntax
 | 
			
		||||
  return TOML.stringify(settings as any)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,8 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { EngineCommand } from 'lang/std/artifactGraph'
 | 
			
		||||
import { uuidv4 } from 'lib/utils'
 | 
			
		||||
import { getUtils, orRunWhenFullSuiteEnabled } from './test-utils'
 | 
			
		||||
import type { EngineCommand } from '@src/lang/std/artifactGraph'
 | 
			
		||||
import { uuidv4 } from '@src/lib/utils'
 | 
			
		||||
 | 
			
		||||
import { getUtils, orRunWhenFullSuiteEnabled } from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Testing Camera Movement', { tag: ['@skipWin'] }, () => {
 | 
			
		||||
  test('Can move camera reliably', async ({ page, context, homePage }) => {
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,15 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { XOR } from '@src/lib/utils'
 | 
			
		||||
import * as fsp from 'fs/promises'
 | 
			
		||||
import {
 | 
			
		||||
  getUtils,
 | 
			
		||||
  TEST_COLORS,
 | 
			
		||||
  pollEditorLinesSelectedLength,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import { XOR } from 'lib/utils'
 | 
			
		||||
import path from 'node:path'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  TEST_COLORS,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
  pollEditorLinesSelectedLength,
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Testing constraints', { tag: ['@skipWin'] }, () => {
 | 
			
		||||
  test('Can constrain line length', async ({ page, homePage }) => {
 | 
			
		||||
    await page.addInitScript(async () => {
 | 
			
		||||
@ -1097,7 +1098,7 @@ test.describe('Electron constraint tests', () => {
 | 
			
		||||
  test(
 | 
			
		||||
    'Able to double click label to set constraint',
 | 
			
		||||
    { tag: '@electron' },
 | 
			
		||||
    async ({ page, context, homePage, scene, editor, toolbar }) => {
 | 
			
		||||
    async ({ page, context, homePage, scene, editor, toolbar, cmdBar }) => {
 | 
			
		||||
      await context.folderSetupFn(async (dir) => {
 | 
			
		||||
        const bracketDir = path.join(dir, 'test-sample')
 | 
			
		||||
        await fsp.mkdir(bracketDir, { recursive: true })
 | 
			
		||||
@ -1131,6 +1132,14 @@ test.describe('Electron constraint tests', () => {
 | 
			
		||||
        await scene.waitForExecutionDone()
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      async function clickOnFirstSegmentLabel() {
 | 
			
		||||
        const child = page
 | 
			
		||||
          .locator('.segment-length-label-text')
 | 
			
		||||
          .first()
 | 
			
		||||
          .locator('xpath=..')
 | 
			
		||||
        await child.dblclick()
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      await test.step('Double click to constrain', async () => {
 | 
			
		||||
        // Enter sketch edit mode via feature tree
 | 
			
		||||
        await toolbar.openPane('feature-tree')
 | 
			
		||||
@ -1138,21 +1147,19 @@ test.describe('Electron constraint tests', () => {
 | 
			
		||||
        await op.dblclick()
 | 
			
		||||
        await toolbar.closePane('feature-tree')
 | 
			
		||||
 | 
			
		||||
        const child = page
 | 
			
		||||
          .locator('.segment-length-label-text')
 | 
			
		||||
          .first()
 | 
			
		||||
          .locator('xpath=..')
 | 
			
		||||
        await child.dblclick()
 | 
			
		||||
        const cmdBarSubmitButton = page.getByRole('button', {
 | 
			
		||||
          name: 'arrow right Continue',
 | 
			
		||||
        })
 | 
			
		||||
        await cmdBarSubmitButton.click()
 | 
			
		||||
        await expect(page.locator('.cm-content')).toContainText(
 | 
			
		||||
          'length001 = 15.3'
 | 
			
		||||
        )
 | 
			
		||||
        await expect(page.locator('.cm-content')).toContainText(
 | 
			
		||||
          '|> angledLine([9, length001], %)'
 | 
			
		||||
        )
 | 
			
		||||
        await clickOnFirstSegmentLabel()
 | 
			
		||||
        await cmdBar.progressCmdBar()
 | 
			
		||||
        await editor.expectEditor.toContain('length001 = 15.3')
 | 
			
		||||
        await editor.expectEditor.toContain('|> angledLine([9, length001], %)')
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      await test.step('Double click again and expect failure', async () => {
 | 
			
		||||
        await clickOnFirstSegmentLabel()
 | 
			
		||||
 | 
			
		||||
        await expect(
 | 
			
		||||
          page.getByText('Unable to constrain the length of this segment')
 | 
			
		||||
        ).toBeVisible()
 | 
			
		||||
 | 
			
		||||
        await page.getByRole('button', { name: 'Exit Sketch' }).click()
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,8 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { getUtils } from './test-utils'
 | 
			
		||||
import { uuidv4 } from 'lib/utils'
 | 
			
		||||
import { TEST_CODE_GIZMO } from './storageStates'
 | 
			
		||||
import { uuidv4 } from '@src/lib/utils'
 | 
			
		||||
 | 
			
		||||
import { TEST_CODE_GIZMO } from '@e2e/playwright/storageStates'
 | 
			
		||||
import { getUtils } from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Testing Gizmo', { tag: ['@skipWin'] }, () => {
 | 
			
		||||
  const cases = [
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { getUtils, orRunWhenFullSuiteEnabled } from './test-utils'
 | 
			
		||||
import { getUtils, orRunWhenFullSuiteEnabled } from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Test toggling perspective', () => {
 | 
			
		||||
  test('via command palette and toggle', async ({ page, homePage }) => {
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,10 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import { getUtils } from './test-utils'
 | 
			
		||||
import { bracket } from 'lib/exampleKcl'
 | 
			
		||||
import { FILE_EXT } from '@src/lib/constants'
 | 
			
		||||
import { bracket } from '@src/lib/exampleKcl'
 | 
			
		||||
import * as fsp from 'fs/promises'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
import { FILE_EXT } from 'lib/constants'
 | 
			
		||||
 | 
			
		||||
import { getUtils } from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Testing in-app sample loading', () => {
 | 
			
		||||
  /**
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,15 @@
 | 
			
		||||
import { Page } from '@playwright/test'
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import type { Page } from '@playwright/test'
 | 
			
		||||
import type { LineInputsType } from '@src/lang/std/sketchcombos'
 | 
			
		||||
import { uuidv4 } from '@src/lib/utils'
 | 
			
		||||
 | 
			
		||||
import type { EditorFixture } from '@e2e/playwright/fixtures/editorFixture'
 | 
			
		||||
import {
 | 
			
		||||
  deg,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  wiggleMove,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import { LineInputsType } from 'lang/std/sketchcombos'
 | 
			
		||||
import { uuidv4 } from 'lib/utils'
 | 
			
		||||
import { EditorFixture } from './fixtures/editorFixture'
 | 
			
		||||
  wiggleMove,
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Testing segment overlays', { tag: ['@skipWin'] }, () => {
 | 
			
		||||
  test('Hover over a segment should show its overlay, hovering over the input overlays should show its popover, clicking the input overlay should constrain/unconstrain it:\nfor the following segments', () => {
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,13 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import type { Coords2d } from '@src/lang/std/sketch'
 | 
			
		||||
import { KCL_DEFAULT_LENGTH } from '@src/lib/constants'
 | 
			
		||||
import { uuidv4 } from '@src/lib/utils'
 | 
			
		||||
 | 
			
		||||
import { commonPoints, getUtils, orRunWhenFullSuiteEnabled } from './test-utils'
 | 
			
		||||
import { Coords2d } from 'lang/std/sketch'
 | 
			
		||||
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
 | 
			
		||||
import { uuidv4 } from 'lib/utils'
 | 
			
		||||
import {
 | 
			
		||||
  commonPoints,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Testing selections', { tag: ['@skipWin'] }, () => {
 | 
			
		||||
  test.setTimeout(90_000)
 | 
			
		||||
 | 
			
		||||
@ -1,24 +1,29 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import {
 | 
			
		||||
  PROJECT_SETTINGS_FILE_NAME,
 | 
			
		||||
  SETTINGS_FILE_NAME,
 | 
			
		||||
} from '@src/lib/constants'
 | 
			
		||||
import type { SettingsLevel } from '@src/lib/settings/settingsTypes'
 | 
			
		||||
import type { DeepPartial } from '@src/lib/types'
 | 
			
		||||
import * as fsp from 'fs/promises'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
 | 
			
		||||
import type { Settings } from '@rust/kcl-lib/bindings/Settings'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  getUtils,
 | 
			
		||||
  executorInputPath,
 | 
			
		||||
  createProject,
 | 
			
		||||
  tomlToSettings,
 | 
			
		||||
  TEST_COLORS,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import { SettingsLevel } from 'lib/settings/settingsTypes'
 | 
			
		||||
import { SETTINGS_FILE_NAME, PROJECT_SETTINGS_FILE_NAME } from 'lib/constants'
 | 
			
		||||
import {
 | 
			
		||||
  TEST_SETTINGS_KEY,
 | 
			
		||||
  TEST_SETTINGS_CORRUPTED,
 | 
			
		||||
  TEST_SETTINGS,
 | 
			
		||||
  TEST_SETTINGS_CORRUPTED,
 | 
			
		||||
  TEST_SETTINGS_DEFAULT_THEME,
 | 
			
		||||
} from './storageStates'
 | 
			
		||||
import { DeepPartial } from 'lib/types'
 | 
			
		||||
import { Settings } from '@rust/kcl-lib/bindings/Settings'
 | 
			
		||||
  TEST_SETTINGS_KEY,
 | 
			
		||||
} from '@e2e/playwright/storageStates'
 | 
			
		||||
import {
 | 
			
		||||
  TEST_COLORS,
 | 
			
		||||
  createProject,
 | 
			
		||||
  executorInputPath,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
  tomlToSettings,
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Testing settings', () => {
 | 
			
		||||
  test('Stored settings are validated and fall back to defaults', async ({
 | 
			
		||||
@ -45,12 +50,12 @@ test.describe('Testing settings', () => {
 | 
			
		||||
      )
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    expect(storedSettings.settings?.app?.theme).toBe('dark')
 | 
			
		||||
    expect(storedSettings.settings?.app?.appearance?.theme).toBe('dark')
 | 
			
		||||
 | 
			
		||||
    // Check that the invalid settings were changed to good defaults
 | 
			
		||||
    expect(storedSettings.settings?.modeling?.base_unit).toBe('in')
 | 
			
		||||
    expect(storedSettings.settings?.modeling?.mouse_controls).toBe('zoo')
 | 
			
		||||
    expect(storedSettings.settings?.app?.project_directory).toBe('')
 | 
			
		||||
    expect(storedSettings.settings?.project?.directory).toBe('')
 | 
			
		||||
    expect(storedSettings.settings?.project?.default_project_name).toBe(
 | 
			
		||||
      'project-$nnn'
 | 
			
		||||
    )
 | 
			
		||||
@ -381,7 +386,9 @@ test.describe('Testing settings', () => {
 | 
			
		||||
      }
 | 
			
		||||
      await tronApp.cleanProjectDir({
 | 
			
		||||
        app: {
 | 
			
		||||
          theme_color: '259',
 | 
			
		||||
          appearance: {
 | 
			
		||||
            color: 259,
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
@ -413,9 +420,12 @@ test.describe('Testing settings', () => {
 | 
			
		||||
 | 
			
		||||
      await tronApp.cleanProjectDir({
 | 
			
		||||
        app: {
 | 
			
		||||
          // Doesn't matter what you set it to. It will
 | 
			
		||||
          // default to 264.5
 | 
			
		||||
          theme_color: '0',
 | 
			
		||||
          appearance: {
 | 
			
		||||
            // Doesn't matter what you set it to. It will
 | 
			
		||||
            // default to 264.5
 | 
			
		||||
 | 
			
		||||
            color: 0,
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,13 @@
 | 
			
		||||
import { Page } from '@playwright/test'
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
import {
 | 
			
		||||
  getUtils,
 | 
			
		||||
  createProject,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
import type { Page } from '@playwright/test'
 | 
			
		||||
import fs from 'fs'
 | 
			
		||||
import { join } from 'path'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  createProject,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test.describe('Text-to-CAD tests', { tag: ['@skipWin'] }, () => {
 | 
			
		||||
  test('basic lego happy case', async ({ page, homePage }) => {
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,10 @@
 | 
			
		||||
import { test, expect } from './zoo-test'
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  doExport,
 | 
			
		||||
  getUtils,
 | 
			
		||||
  makeTemplate,
 | 
			
		||||
  orRunWhenFullSuiteEnabled,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
} from '@e2e/playwright/test-utils'
 | 
			
		||||
import { expect, test } from '@e2e/playwright/zoo-test'
 | 
			
		||||
 | 
			
		||||
test('Units menu', async ({ page, homePage }) => {
 | 
			
		||||
  test.fixme(orRunWhenFullSuiteEnabled())
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,11 @@
 | 
			
		||||
/* eslint-disable react-hooks/rules-of-hooks */
 | 
			
		||||
 | 
			
		||||
import { test as playwrightTestFn } from '@playwright/test'
 | 
			
		||||
 | 
			
		||||
import type { Fixtures } from '@e2e/playwright/fixtures/fixtureSetup'
 | 
			
		||||
import {
 | 
			
		||||
  fixturesBasedOnProcessEnvPlatform,
 | 
			
		||||
  Fixtures,
 | 
			
		||||
  ElectronZoo,
 | 
			
		||||
} from './fixtures/fixtureSetup'
 | 
			
		||||
  fixturesBasedOnProcessEnvPlatform,
 | 
			
		||||
} from '@e2e/playwright/fixtures/fixtureSetup'
 | 
			
		||||
 | 
			
		||||
export { expect } from '@playwright/test'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import type { ForgeConfig } from '@electron-forge/shared-types'
 | 
			
		||||
import { VitePlugin } from '@electron-forge/plugin-vite'
 | 
			
		||||
import { FusesPlugin } from '@electron-forge/plugin-fuses'
 | 
			
		||||
import { VitePlugin } from '@electron-forge/plugin-vite'
 | 
			
		||||
import type { ForgeConfig } from '@electron-forge/shared-types'
 | 
			
		||||
import { FuseV1Options, FuseVersion } from '@electron/fuses'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								forge.env.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								forge.env.d.ts
									
									
									
									
										vendored
									
									
								
							@ -26,7 +26,7 @@ declare global {
 | 
			
		||||
 | 
			
		||||
declare module 'vite' {
 | 
			
		||||
  interface ConfigEnv<
 | 
			
		||||
    K extends keyof VitePluginConfig = keyof VitePluginConfig
 | 
			
		||||
    K extends keyof VitePluginConfig = keyof VitePluginConfig,
 | 
			
		||||
  > {
 | 
			
		||||
    root: string
 | 
			
		||||
    forgeConfig: VitePluginConfig
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								interface.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								interface.d.ts
									
									
									
									
										vendored
									
									
								
							@ -1,13 +1,10 @@
 | 
			
		||||
import fs from 'node:fs/promises'
 | 
			
		||||
import fsSync from 'node:fs'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
import { dialog, shell } from 'electron'
 | 
			
		||||
import { MachinesListing } from 'components/MachineManagerProvider'
 | 
			
		||||
import type { Channel } from 'src/menu/channels'
 | 
			
		||||
import { Menu, WebContents } from 'electron'
 | 
			
		||||
import { ZooLabel, ZooMenuEvents } from 'menu/roles'
 | 
			
		||||
import type { MenuActionIPC } from 'menu/rules'
 | 
			
		||||
import 'electron'
 | 
			
		||||
import { dialog, shell } from 'electron'
 | 
			
		||||
import type { WebContentSendPayload } from 'menu/channels'
 | 
			
		||||
import { ZooLabel } from 'menu/roles'
 | 
			
		||||
import fs from 'node:fs/promises'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
 | 
			
		||||
// Extend the interface with additional custom properties
 | 
			
		||||
declare module 'electron' {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										29
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								package.json
									
									
									
									
									
								
							@ -26,7 +26,7 @@
 | 
			
		||||
    "@fortawesome/react-fontawesome": "^0.2.0",
 | 
			
		||||
    "@headlessui/react": "^1.7.19",
 | 
			
		||||
    "@headlessui/tailwindcss": "^0.2.2",
 | 
			
		||||
    "@kittycad/lib": "2.0.23",
 | 
			
		||||
    "@kittycad/lib": "2.0.25",
 | 
			
		||||
    "@lezer/highlight": "^1.2.1",
 | 
			
		||||
    "@lezer/lr": "^1.4.1",
 | 
			
		||||
    "@react-hook/resize-observer": "^2.0.1",
 | 
			
		||||
@ -88,9 +88,9 @@
 | 
			
		||||
    "simpleserver:ci": "yarn pretest && http-server ./public --cors -p 3000 &",
 | 
			
		||||
    "simpleserver:bg": "yarn pretest && http-server ./public --cors -p 3000 &",
 | 
			
		||||
    "simpleserver:stop": "kill-port 3000",
 | 
			
		||||
    "fmt": "prettier --write ./src *.ts *.json *.js ./e2e ./packages ./rust/kcl-language-server ./rust/kcl-lib/bindings ./rust/kcl-wasm-lib/pkg",
 | 
			
		||||
    "fmt:generated": "prettier --write *.ts *.json *.js ./rust/kcl-lib/bindings ./rust/kcl-wasm-lib/pkg",
 | 
			
		||||
    "fmt-check": "prettier --check ./src *.ts *.json *.js ./e2e ./packages ./rust/kcl-language-server",
 | 
			
		||||
    "fmt": "prettier --write .eslintrc.json ./src *.ts *.json *.js ./e2e ./packages ./rust/kcl-language-server ./rust/kcl-lib/bindings ./rust/kcl-wasm-lib/pkg",
 | 
			
		||||
    "fmt:generated": "prettier --write .eslintrc.json *.ts *.json *.js ./rust/kcl-lib/bindings ./rust/kcl-wasm-lib/pkg",
 | 
			
		||||
    "fmt-check": "prettier --check .eslintrc.json ./src *.ts *.json *.js ./e2e ./packages ./rust/kcl-language-server",
 | 
			
		||||
    "fetch:wasm": "./scripts/get-latest-wasm-bundle.sh",
 | 
			
		||||
    "fetch:wasm:windows": "./scripts/get-latest-wasm-bundle.ps1",
 | 
			
		||||
    "fetch:samples": "rm -rf public/kcl-samples* && curl -L -o public/kcl-samples.zip https://github.com/KittyCAD/kcl-samples/archive/refs/heads/achalmers/kw-args-xylineto.zip && unzip -o public/kcl-samples.zip -d public && mv public/kcl-samples-* public/kcl-samples",
 | 
			
		||||
@ -102,6 +102,7 @@
 | 
			
		||||
    "remove-importmeta": "sed -i 's/import.meta.url/window.location.origin/g' \"./rust/kcl-wasm-lib/pkg/kcl_wasm_lib.js\"; sed -i '' 's/import.meta.url/window.location.origin/g' \"./rust/kcl-wasm-lib/pkg/kcl_wasm_lib.js\" || echo \"sed for both mac and linux\"",
 | 
			
		||||
    "lint-fix": "eslint --fix --ext .ts --ext .tsx src e2e packages/codemirror-lsp-client/src rust/kcl-language-server/client/src",
 | 
			
		||||
    "lint": "eslint --max-warnings 0 --ext .ts --ext .tsx src e2e packages/codemirror-lsp-client/src rust/kcl-language-server/client/src",
 | 
			
		||||
    "circular-deps": "dpdm --no-warning --no-tree -T --skip-dynamic-imports=circular src/index.tsx",
 | 
			
		||||
    "files:set-version": "echo \"$(jq --arg v \"$VERSION\" '.version=$v' package.json --indent 2)\" > package.json",
 | 
			
		||||
    "files:set-notes": "./scripts/set-files-notes.sh",
 | 
			
		||||
    "files:flip-to-nightly": "./scripts/flip-files-to-nightly.sh",
 | 
			
		||||
@ -139,7 +140,20 @@
 | 
			
		||||
    "trailingComma": "es5",
 | 
			
		||||
    "tabWidth": 2,
 | 
			
		||||
    "semi": false,
 | 
			
		||||
    "singleQuote": true
 | 
			
		||||
    "singleQuote": true,
 | 
			
		||||
    "importOrder": [
 | 
			
		||||
      "<THIRD_PARTY_MODULES>",
 | 
			
		||||
      "^@rust/(.*)$",
 | 
			
		||||
      "^@e2e/(.*)$",
 | 
			
		||||
      "^@src/(.*)$",
 | 
			
		||||
      "^[./]"
 | 
			
		||||
    ],
 | 
			
		||||
    "importOrderSeparation": true,
 | 
			
		||||
    "importOrderSortSpecifiers": true,
 | 
			
		||||
    "plugins": [
 | 
			
		||||
      "@trivago/prettier-plugin-sort-imports",
 | 
			
		||||
      "prettier-plugin-organize-imports"
 | 
			
		||||
    ]
 | 
			
		||||
  },
 | 
			
		||||
  "browserslist": {
 | 
			
		||||
    "production": [
 | 
			
		||||
@ -167,6 +181,7 @@
 | 
			
		||||
    "@playwright/test": "^1.51.1",
 | 
			
		||||
    "@testing-library/jest-dom": "^5.14.1",
 | 
			
		||||
    "@testing-library/react": "^15.0.2",
 | 
			
		||||
    "@trivago/prettier-plugin-sort-imports": "^5.2.2",
 | 
			
		||||
    "@types/diff": "^7.0.2",
 | 
			
		||||
    "@types/electron": "^1.6.10",
 | 
			
		||||
    "@types/isomorphic-fetch": "^0.0.39",
 | 
			
		||||
@ -187,6 +202,7 @@
 | 
			
		||||
    "@vitest/web-worker": "^1.5.0",
 | 
			
		||||
    "@xstate/cli": "^0.5.17",
 | 
			
		||||
    "autoprefixer": "^10.4.21",
 | 
			
		||||
    "dpdm": "^3.14.0",
 | 
			
		||||
    "electron": "^34.1.1",
 | 
			
		||||
    "electron-builder": "^26.0.12",
 | 
			
		||||
    "eslint": "^8.0.1",
 | 
			
		||||
@ -208,7 +224,8 @@
 | 
			
		||||
    "pngjs": "^7.0.0",
 | 
			
		||||
    "postcss": "^8.4.43",
 | 
			
		||||
    "postinstall-postinstall": "^2.1.0",
 | 
			
		||||
    "prettier": "^2.8.8",
 | 
			
		||||
    "prettier": "^3.5.3",
 | 
			
		||||
    "prettier-plugin-organize-imports": "^4.1.0",
 | 
			
		||||
    "setimmediate": "^1.0.5",
 | 
			
		||||
    "tailwindcss": "^3.4.17",
 | 
			
		||||
    "ts-node": "^10.0.0",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import dts from 'rollup-plugin-dts'
 | 
			
		||||
import { lezer } from '@lezer/generator/rollup'
 | 
			
		||||
import typescript from '@rollup/plugin-typescript'
 | 
			
		||||
import dts from 'rollup-plugin-dts'
 | 
			
		||||
 | 
			
		||||
export default [
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,14 @@
 | 
			
		||||
// Base CodeMirror language support for kcl.
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  LRLanguage,
 | 
			
		||||
  LanguageSupport,
 | 
			
		||||
  indentNodeProp,
 | 
			
		||||
  continuedIndent,
 | 
			
		||||
  delimitedIndent,
 | 
			
		||||
  foldNodeProp,
 | 
			
		||||
  foldInside,
 | 
			
		||||
  foldNodeProp,
 | 
			
		||||
  indentNodeProp,
 | 
			
		||||
} from '@codemirror/language'
 | 
			
		||||
 | 
			
		||||
// @ts-ignore: No types available
 | 
			
		||||
import { parser } from './kcl.grammar'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,9 @@
 | 
			
		||||
import { KclLanguage } from '../src/index'
 | 
			
		||||
import { fileTests } from '@lezer/generator/dist/test'
 | 
			
		||||
 | 
			
		||||
import * as fs from 'fs'
 | 
			
		||||
import * as path from 'path'
 | 
			
		||||
 | 
			
		||||
import { KclLanguage } from '../src/index'
 | 
			
		||||
 | 
			
		||||
let caseDir = path.dirname(__filename)
 | 
			
		||||
 | 
			
		||||
for (let file of fs.readdirSync(caseDir)) {
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,8 @@
 | 
			
		||||
// Overrides the test options from the modeling-app config.
 | 
			
		||||
 | 
			
		||||
import viteTsconfigPaths from 'vite-tsconfig-paths'
 | 
			
		||||
import { defineConfig, configDefaults } from 'vitest/config'
 | 
			
		||||
// @ts-ignore: No types available
 | 
			
		||||
import { lezer } from '@lezer/generator/rollup'
 | 
			
		||||
import viteTsconfigPaths from 'vite-tsconfig-paths'
 | 
			
		||||
import { defineConfig } from 'vitest/config'
 | 
			
		||||
 | 
			
		||||
const config = defineConfig({
 | 
			
		||||
  test: {
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { encoder, decoder } from '../codec'
 | 
			
		||||
import { decoder, encoder } from './encode-decode'
 | 
			
		||||
 | 
			
		||||
export default class Bytes {
 | 
			
		||||
  static encode(input: string): Uint8Array {
 | 
			
		||||
@ -10,7 +10,7 @@ export default class Bytes {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static append<
 | 
			
		||||
    T extends { length: number; set(arr: T, offset: number): void }
 | 
			
		||||
    T extends { length: number; set(arr: T, offset: number): void },
 | 
			
		||||
  >(constructor: { new (length: number): T }, ...arrays: T[]) {
 | 
			
		||||
    let totalLength = 0
 | 
			
		||||
    for (const arr of arrays) {
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,10 @@
 | 
			
		||||
import * as vsrpc from 'vscode-jsonrpc'
 | 
			
		||||
 | 
			
		||||
import { Codec } from '.'
 | 
			
		||||
import Bytes from './bytes'
 | 
			
		||||
import PromiseMap from './map'
 | 
			
		||||
import Queue from './queue'
 | 
			
		||||
import Tracer from './tracer'
 | 
			
		||||
import PromiseMap from './map'
 | 
			
		||||
import { Codec } from './utils'
 | 
			
		||||
 | 
			
		||||
export default class StreamDemuxer extends Queue<Uint8Array> {
 | 
			
		||||
  readonly responses: PromiseMap<number | string, vsrpc.ResponseMessage> =
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,2 @@
 | 
			
		||||
export const encoder = new TextEncoder()
 | 
			
		||||
export const decoder = new TextDecoder()
 | 
			
		||||
@ -1,8 +1,7 @@
 | 
			
		||||
import * as jsrpc from 'json-rpc-2.0'
 | 
			
		||||
import * as vsrpc from 'vscode-jsonrpc'
 | 
			
		||||
import type * as vsrpc from 'vscode-jsonrpc'
 | 
			
		||||
 | 
			
		||||
import Bytes from './bytes'
 | 
			
		||||
import StreamDemuxer from './demuxer'
 | 
			
		||||
import { decoder } from './encode-decode'
 | 
			
		||||
import Headers from './headers'
 | 
			
		||||
import Queue from './queue'
 | 
			
		||||
import Tracer from './tracer'
 | 
			
		||||
@ -12,25 +11,6 @@ export enum LspWorkerEventType {
 | 
			
		||||
  Call = 'call',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const encoder = new TextEncoder()
 | 
			
		||||
export const decoder = new TextDecoder()
 | 
			
		||||
 | 
			
		||||
export class Codec {
 | 
			
		||||
  static encode(
 | 
			
		||||
    json: jsrpc.JSONRPCRequest | jsrpc.JSONRPCResponse
 | 
			
		||||
  ): Uint8Array {
 | 
			
		||||
    const message = JSON.stringify(json)
 | 
			
		||||
    const delimited = Headers.add(message)
 | 
			
		||||
    return Bytes.encode(delimited)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static decode<T>(data: Uint8Array): T {
 | 
			
		||||
    const delimited = Bytes.decode(data)
 | 
			
		||||
    const message = Headers.remove(delimited)
 | 
			
		||||
    return JSON.parse(message) as T
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FIXME: tracing efficiency
 | 
			
		||||
export class IntoServer
 | 
			
		||||
  extends Queue<Uint8Array>
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { Message } from 'vscode-languageserver-protocol'
 | 
			
		||||
import type { Message } from 'vscode-languageserver-protocol'
 | 
			
		||||
 | 
			
		||||
export default class Tracer {
 | 
			
		||||
  static client(message: string): void {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								packages/codemirror-lsp-client/src/client/codec/utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								packages/codemirror-lsp-client/src/client/codec/utils.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
import type * as jsrpc from 'json-rpc-2.0'
 | 
			
		||||
 | 
			
		||||
import Bytes from './bytes'
 | 
			
		||||
import Headers from './headers'
 | 
			
		||||
 | 
			
		||||
export class Codec {
 | 
			
		||||
  static encode(
 | 
			
		||||
    json: jsrpc.JSONRPCRequest | jsrpc.JSONRPCResponse
 | 
			
		||||
  ): Uint8Array {
 | 
			
		||||
    const message = JSON.stringify(json)
 | 
			
		||||
    const delimited = Headers.add(message)
 | 
			
		||||
    return Bytes.encode(delimited)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static decode<T>(data: Uint8Array): T {
 | 
			
		||||
    const delimited = Bytes.decode(data)
 | 
			
		||||
    const message = Headers.remove(delimited)
 | 
			
		||||
    return JSON.parse(message) as T
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -1,8 +1,8 @@
 | 
			
		||||
import type * as LSP from 'vscode-languageserver-protocol'
 | 
			
		||||
 | 
			
		||||
import { FromServer, IntoServer } from './codec'
 | 
			
		||||
import type { LanguageServerPlugin } from '../plugin/lsp'
 | 
			
		||||
import type { FromServer, IntoServer } from './codec'
 | 
			
		||||
import Client from './jsonrpc'
 | 
			
		||||
import { LanguageServerPlugin } from '../plugin/lsp'
 | 
			
		||||
 | 
			
		||||
// https://microsoft.github.io/language-server-protocol/specifications/specification-current/
 | 
			
		||||
 | 
			
		||||
@ -12,15 +12,15 @@ interface LSPRequestMap {
 | 
			
		||||
  'textDocument/hover': [LSP.HoverParams, LSP.Hover]
 | 
			
		||||
  'textDocument/completion': [
 | 
			
		||||
    LSP.CompletionParams,
 | 
			
		||||
    LSP.CompletionItem[] | LSP.CompletionList | null
 | 
			
		||||
    LSP.CompletionItem[] | LSP.CompletionList | null,
 | 
			
		||||
  ]
 | 
			
		||||
  'textDocument/semanticTokens/full': [
 | 
			
		||||
    LSP.SemanticTokensParams,
 | 
			
		||||
    LSP.SemanticTokens
 | 
			
		||||
    LSP.SemanticTokens,
 | 
			
		||||
  ]
 | 
			
		||||
  'textDocument/formatting': [
 | 
			
		||||
    LSP.DocumentFormattingParams,
 | 
			
		||||
    LSP.TextEdit[] | null
 | 
			
		||||
    LSP.TextEdit[] | null,
 | 
			
		||||
  ]
 | 
			
		||||
  'textDocument/foldingRange': [LSP.FoldingRangeParams, LSP.FoldingRange[]]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,12 @@
 | 
			
		||||
import * as jsrpc from 'json-rpc-2.0'
 | 
			
		||||
import * as LSP from 'vscode-languageserver-protocol'
 | 
			
		||||
 | 
			
		||||
import type { FromServer, IntoServer } from './codec'
 | 
			
		||||
import { Codec } from './codec/utils'
 | 
			
		||||
import {
 | 
			
		||||
  registerServerCapability,
 | 
			
		||||
  unregisterServerCapability,
 | 
			
		||||
} from './server-capability-registration'
 | 
			
		||||
import { Codec, FromServer, IntoServer } from './codec'
 | 
			
		||||
 | 
			
		||||
const client_capabilities: LSP.ClientCapabilities = {
 | 
			
		||||
  textDocument: {
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import {
 | 
			
		||||
import type {
 | 
			
		||||
  Registration,
 | 
			
		||||
  ServerCapabilities,
 | 
			
		||||
  Unregistration,
 | 
			
		||||
 | 
			
		||||
@ -1,36 +1,34 @@
 | 
			
		||||
import { foldService } from '@codemirror/language'
 | 
			
		||||
import { Extension, EditorState } from '@codemirror/state'
 | 
			
		||||
import type { EditorState, Extension } from '@codemirror/state'
 | 
			
		||||
import { ViewPlugin } from '@codemirror/view'
 | 
			
		||||
 | 
			
		||||
import type { LanguageServerOptions } from './plugin/lsp'
 | 
			
		||||
import {
 | 
			
		||||
  docPathFacet,
 | 
			
		||||
  LanguageServerPlugin,
 | 
			
		||||
  LanguageServerPluginSpec,
 | 
			
		||||
  docPathFacet,
 | 
			
		||||
  languageId,
 | 
			
		||||
  workspaceFolders,
 | 
			
		||||
  LanguageServerOptions,
 | 
			
		||||
} from './plugin/lsp'
 | 
			
		||||
 | 
			
		||||
export type { LanguageServerClientOptions } from './client'
 | 
			
		||||
export { LanguageServerClient } from './client'
 | 
			
		||||
export type { LanguageServerClientOptions } from './client'
 | 
			
		||||
export { FromServer, IntoServer, LspWorkerEventType } from './client/codec'
 | 
			
		||||
export { Codec } from './client/codec/utils'
 | 
			
		||||
export {
 | 
			
		||||
  Codec,
 | 
			
		||||
  FromServer,
 | 
			
		||||
  IntoServer,
 | 
			
		||||
  LspWorkerEventType,
 | 
			
		||||
} from './client/codec'
 | 
			
		||||
export type { LanguageServerOptions } from './plugin/lsp'
 | 
			
		||||
  lspDiagnosticsEvent,
 | 
			
		||||
  lspFormatCodeEvent,
 | 
			
		||||
  lspSemanticTokensEvent,
 | 
			
		||||
} from './plugin/annotation'
 | 
			
		||||
export {
 | 
			
		||||
  LanguageServerPlugin,
 | 
			
		||||
  LanguageServerPluginSpec,
 | 
			
		||||
  docPathFacet,
 | 
			
		||||
  languageId,
 | 
			
		||||
  workspaceFolders,
 | 
			
		||||
  lspSemanticTokensEvent,
 | 
			
		||||
  lspDiagnosticsEvent,
 | 
			
		||||
  lspFormatCodeEvent,
 | 
			
		||||
} from './plugin/lsp'
 | 
			
		||||
export { posToOffset, offsetToPos } from './plugin/util'
 | 
			
		||||
export type { LanguageServerOptions } from './plugin/lsp'
 | 
			
		||||
export { offsetToPos, posToOffset } from './plugin/util'
 | 
			
		||||
 | 
			
		||||
export function lspPlugin(options: LanguageServerOptions): Extension {
 | 
			
		||||
  let plugin: LanguageServerPlugin | null = null
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								packages/codemirror-lsp-client/src/plugin/annotation.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								packages/codemirror-lsp-client/src/plugin/annotation.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
import { Annotation } from '@codemirror/state'
 | 
			
		||||
 | 
			
		||||
export enum LspAnnotation {
 | 
			
		||||
  SemanticTokens = 'semantic-tokens',
 | 
			
		||||
  FormatCode = 'format-code',
 | 
			
		||||
  Diagnostics = 'diagnostics',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const lspEvent = Annotation.define<LspAnnotation>()
 | 
			
		||||
export const lspSemanticTokensEvent = lspEvent.of(LspAnnotation.SemanticTokens)
 | 
			
		||||
export const lspFormatCodeEvent = lspEvent.of(LspAnnotation.FormatCode)
 | 
			
		||||
export const lspDiagnosticsEvent = lspEvent.of(LspAnnotation.Diagnostics)
 | 
			
		||||
@ -9,17 +9,18 @@ import {
 | 
			
		||||
  prevSnippetField,
 | 
			
		||||
  startCompletion,
 | 
			
		||||
} from '@codemirror/autocomplete'
 | 
			
		||||
import { Prec, Extension } from '@codemirror/state'
 | 
			
		||||
import { EditorView, keymap, KeyBinding, ViewPlugin } from '@codemirror/view'
 | 
			
		||||
 | 
			
		||||
import { syntaxTree } from '@codemirror/language'
 | 
			
		||||
import type { Extension } from '@codemirror/state'
 | 
			
		||||
import { Prec } from '@codemirror/state'
 | 
			
		||||
import type { EditorView, KeyBinding, ViewPlugin } from '@codemirror/view'
 | 
			
		||||
import { keymap } from '@codemirror/view'
 | 
			
		||||
import {
 | 
			
		||||
  CompletionItemKind,
 | 
			
		||||
  CompletionTriggerKind,
 | 
			
		||||
} from 'vscode-languageserver-protocol'
 | 
			
		||||
 | 
			
		||||
import { LanguageServerPlugin } from './lsp'
 | 
			
		||||
import type { LanguageServerPlugin } from './lsp'
 | 
			
		||||
import { offsetToPos } from './util'
 | 
			
		||||
import { syntaxTree } from '@codemirror/language'
 | 
			
		||||
 | 
			
		||||
export const CompletionItemKindMap = Object.fromEntries(
 | 
			
		||||
  Object.entries(CompletionItemKind).map(([key, value]) => [value, key])
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,9 @@
 | 
			
		||||
import { Extension, Prec } from '@codemirror/state'
 | 
			
		||||
import { EditorView, keymap, KeyBinding, ViewPlugin } from '@codemirror/view'
 | 
			
		||||
import type { Extension } from '@codemirror/state'
 | 
			
		||||
import { Prec } from '@codemirror/state'
 | 
			
		||||
import type { EditorView, KeyBinding, ViewPlugin } from '@codemirror/view'
 | 
			
		||||
import { keymap } from '@codemirror/view'
 | 
			
		||||
 | 
			
		||||
import { LanguageServerPlugin } from './lsp'
 | 
			
		||||
import type { LanguageServerPlugin } from './lsp'
 | 
			
		||||
 | 
			
		||||
export default function lspFormatExt(
 | 
			
		||||
  plugin: ViewPlugin<LanguageServerPlugin>
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,8 @@
 | 
			
		||||
import { Extension } from '@codemirror/state'
 | 
			
		||||
import {
 | 
			
		||||
  hoverTooltip,
 | 
			
		||||
  tooltips,
 | 
			
		||||
  ViewPlugin,
 | 
			
		||||
  EditorView,
 | 
			
		||||
} from '@codemirror/view'
 | 
			
		||||
import type { Extension } from '@codemirror/state'
 | 
			
		||||
import type { ViewPlugin } from '@codemirror/view'
 | 
			
		||||
import { EditorView, hoverTooltip, tooltips } from '@codemirror/view'
 | 
			
		||||
 | 
			
		||||
import { LanguageServerPlugin } from './lsp'
 | 
			
		||||
import type { LanguageServerPlugin } from './lsp'
 | 
			
		||||
import { offsetToPos } from './util'
 | 
			
		||||
 | 
			
		||||
export default function lspHoverExt(
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import { indentService } from '@codemirror/language'
 | 
			
		||||
import { Extension } from '@codemirror/state'
 | 
			
		||||
import type { Extension } from '@codemirror/state'
 | 
			
		||||
 | 
			
		||||
export default function lspIndentExt(): Extension {
 | 
			
		||||
  // Match the indentation of the previous line (if present).
 | 
			
		||||
 | 
			
		||||
@ -4,39 +4,34 @@ import type {
 | 
			
		||||
  CompletionResult,
 | 
			
		||||
} from '@codemirror/autocomplete'
 | 
			
		||||
import { completeFromList, snippetCompletion } from '@codemirror/autocomplete'
 | 
			
		||||
import {
 | 
			
		||||
  Facet,
 | 
			
		||||
  StateEffect,
 | 
			
		||||
  Extension,
 | 
			
		||||
  Transaction,
 | 
			
		||||
  Annotation,
 | 
			
		||||
} from '@codemirror/state'
 | 
			
		||||
import type {
 | 
			
		||||
  ViewUpdate,
 | 
			
		||||
  PluginValue,
 | 
			
		||||
  PluginSpec,
 | 
			
		||||
  ViewPlugin,
 | 
			
		||||
} from '@codemirror/view'
 | 
			
		||||
import { EditorView, Tooltip } from '@codemirror/view'
 | 
			
		||||
import { linter } from '@codemirror/lint'
 | 
			
		||||
 | 
			
		||||
import type { PublishDiagnosticsParams } from 'vscode-languageserver-protocol'
 | 
			
		||||
import type { Extension, StateEffect } from '@codemirror/state'
 | 
			
		||||
import { Facet, Transaction } from '@codemirror/state'
 | 
			
		||||
import type {
 | 
			
		||||
  EditorView,
 | 
			
		||||
  PluginSpec,
 | 
			
		||||
  PluginValue,
 | 
			
		||||
  Tooltip,
 | 
			
		||||
  ViewPlugin,
 | 
			
		||||
  ViewUpdate,
 | 
			
		||||
} from '@codemirror/view'
 | 
			
		||||
import type * as LSP from 'vscode-languageserver-protocol'
 | 
			
		||||
import {
 | 
			
		||||
  DiagnosticSeverity,
 | 
			
		||||
import type {
 | 
			
		||||
  CompletionTriggerKind,
 | 
			
		||||
  PublishDiagnosticsParams,
 | 
			
		||||
} from 'vscode-languageserver-protocol'
 | 
			
		||||
import { DiagnosticSeverity } from 'vscode-languageserver-protocol'
 | 
			
		||||
import { URI } from 'vscode-uri'
 | 
			
		||||
 | 
			
		||||
import { LanguageServerClient } from '../client'
 | 
			
		||||
import { CompletionItemKindMap } from './autocomplete'
 | 
			
		||||
import { addToken, SemanticToken } from './semantic-tokens'
 | 
			
		||||
import { posToOffset, formatMarkdownContents } from './util'
 | 
			
		||||
import lspAutocompleteExt from './autocomplete'
 | 
			
		||||
import lspHoverExt from './hover'
 | 
			
		||||
import type { LanguageServerClient } from '../client'
 | 
			
		||||
import { lspFormatCodeEvent, lspSemanticTokensEvent } from './annotation'
 | 
			
		||||
import lspAutocompleteExt, { CompletionItemKindMap } from './autocomplete'
 | 
			
		||||
import lspFormatExt from './format'
 | 
			
		||||
import lspHoverExt from './hover'
 | 
			
		||||
import lspIndentExt from './indent'
 | 
			
		||||
import lspSemanticTokensExt from './semantic-tokens'
 | 
			
		||||
import type { SemanticToken } from './semantic-tokens'
 | 
			
		||||
import lspSemanticTokensExt, { addToken } from './semantic-tokens'
 | 
			
		||||
import { formatMarkdownContents, posToOffset } from './util'
 | 
			
		||||
 | 
			
		||||
const useLast = (values: readonly any[]) => values.reduce((_, v) => v, '')
 | 
			
		||||
export const docPathFacet = Facet.define<string, string>({
 | 
			
		||||
@ -48,17 +43,6 @@ export const workspaceFolders = Facet.define<
 | 
			
		||||
  LSP.WorkspaceFolder[]
 | 
			
		||||
>({ combine: useLast })
 | 
			
		||||
 | 
			
		||||
export enum LspAnnotation {
 | 
			
		||||
  SemanticTokens = 'semantic-tokens',
 | 
			
		||||
  FormatCode = 'format-code',
 | 
			
		||||
  Diagnostics = 'diagnostics',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const lspEvent = Annotation.define<LspAnnotation>()
 | 
			
		||||
export const lspSemanticTokensEvent = lspEvent.of(LspAnnotation.SemanticTokens)
 | 
			
		||||
export const lspFormatCodeEvent = lspEvent.of(LspAnnotation.FormatCode)
 | 
			
		||||
export const lspDiagnosticsEvent = lspEvent.of(LspAnnotation.Diagnostics)
 | 
			
		||||
 | 
			
		||||
export interface LanguageServerOptions {
 | 
			
		||||
  // We assume this is the main project directory, we are currently working in.
 | 
			
		||||
  workspaceFolders: LSP.WorkspaceFolder[]
 | 
			
		||||
@ -98,7 +82,10 @@ export class LanguageServerPlugin implements PluginValue {
 | 
			
		||||
  // document.
 | 
			
		||||
  private sendScheduled: number | null = null
 | 
			
		||||
 | 
			
		||||
  constructor(options: LanguageServerOptions, private view: EditorView) {
 | 
			
		||||
  constructor(
 | 
			
		||||
    options: LanguageServerOptions,
 | 
			
		||||
    private view: EditorView
 | 
			
		||||
  ) {
 | 
			
		||||
    this.client = options.client
 | 
			
		||||
    this.documentVersion = 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,12 @@
 | 
			
		||||
import { highlightingFor } from '@codemirror/language'
 | 
			
		||||
import { StateEffect, StateField, Extension } from '@codemirror/state'
 | 
			
		||||
import { EditorView, Decoration, DecorationSet } from '@codemirror/view'
 | 
			
		||||
import type { Extension } from '@codemirror/state'
 | 
			
		||||
import { StateEffect, StateField } from '@codemirror/state'
 | 
			
		||||
import type { DecorationSet } from '@codemirror/view'
 | 
			
		||||
import { Decoration, EditorView } from '@codemirror/view'
 | 
			
		||||
import type { Tag } from '@lezer/highlight'
 | 
			
		||||
import { tags } from '@lezer/highlight'
 | 
			
		||||
 | 
			
		||||
import { Tag, tags } from '@lezer/highlight'
 | 
			
		||||
 | 
			
		||||
import { lspSemanticTokensEvent } from './lsp'
 | 
			
		||||
import { lspSemanticTokensEvent } from './annotation'
 | 
			
		||||
 | 
			
		||||
export interface SemanticToken {
 | 
			
		||||
  from: number
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,8 @@
 | 
			
		||||
import { Text } from '@codemirror/state'
 | 
			
		||||
import { Marked, MarkedOptions } from '@ts-stack/markdown'
 | 
			
		||||
 | 
			
		||||
import type { Text } from '@codemirror/state'
 | 
			
		||||
import type { MarkedOptions } from '@ts-stack/markdown'
 | 
			
		||||
import { Marked } from '@ts-stack/markdown'
 | 
			
		||||
import type * as LSP from 'vscode-languageserver-protocol'
 | 
			
		||||
 | 
			
		||||
import { isArray } from '../lib/utils'
 | 
			
		||||
 | 
			
		||||
// takes a function and executes it after the wait time, if the function is called again before the wait time is up, the timer is reset
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,11 @@
 | 
			
		||||
/* eslint suggest-no-throw/suggest-no-throw: 0 */
 | 
			
		||||
import * as vscode from 'vscode'
 | 
			
		||||
import * as os from 'os'
 | 
			
		||||
import type { Config } from './config'
 | 
			
		||||
import { log, isValidExecutable } from './util'
 | 
			
		||||
import type { PersistentState } from './persistent_state'
 | 
			
		||||
import { exec } from 'child_process'
 | 
			
		||||
import * as os from 'os'
 | 
			
		||||
import * as vscode from 'vscode'
 | 
			
		||||
 | 
			
		||||
import type { Config } from './config'
 | 
			
		||||
import type { PersistentState } from './persistent_state'
 | 
			
		||||
import { isValidExecutable, log } from './util'
 | 
			
		||||
 | 
			
		||||
export async function bootstrap(
 | 
			
		||||
  context: vscode.ExtensionContext,
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
/* eslint suggest-no-throw/suggest-no-throw: 0 */
 | 
			
		||||
import * as lc from 'vscode-languageclient/node'
 | 
			
		||||
import type * as vscode from 'vscode'
 | 
			
		||||
import * as lc from 'vscode-languageclient/node'
 | 
			
		||||
 | 
			
		||||
export async function createClient(
 | 
			
		||||
  traceOutputChannel: vscode.OutputChannel,
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,8 @@
 | 
			
		||||
/* eslint suggest-no-throw/suggest-no-throw: 0 */
 | 
			
		||||
import { spawnSync } from 'child_process'
 | 
			
		||||
import * as vscode from 'vscode'
 | 
			
		||||
 | 
			
		||||
import type { Cmd, CtxInit } from './ctx'
 | 
			
		||||
import { spawnSync } from 'child_process'
 | 
			
		||||
 | 
			
		||||
export function serverVersion(ctx: CtxInit): Cmd {
 | 
			
		||||
  return async () => {
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,11 @@
 | 
			
		||||
/* eslint suggest-no-throw/suggest-no-throw: 0 */
 | 
			
		||||
import * as Is from 'vscode-languageclient/lib/common/utils/is'
 | 
			
		||||
import * as os from 'os'
 | 
			
		||||
import * as path from 'path'
 | 
			
		||||
import * as vscode from 'vscode'
 | 
			
		||||
import { log, type Env } from './util'
 | 
			
		||||
import * as Is from 'vscode-languageclient/lib/common/utils/is'
 | 
			
		||||
 | 
			
		||||
import { expectNotUndefined, unwrapUndefinable } from './undefinable'
 | 
			
		||||
import { type Env, log } from './util'
 | 
			
		||||
 | 
			
		||||
export type RunnableEnvCfgItem = {
 | 
			
		||||
  mask?: string
 | 
			
		||||
 | 
			
		||||
@ -1,20 +1,20 @@
 | 
			
		||||
/* eslint suggest-no-throw/suggest-no-throw: 0 */
 | 
			
		||||
import * as vscode from 'vscode'
 | 
			
		||||
import type * as lc from 'vscode-languageclient/node'
 | 
			
		||||
import { TransportKind } from 'vscode-languageclient/node'
 | 
			
		||||
 | 
			
		||||
import { Config, prepareVSCodeConfig } from './config'
 | 
			
		||||
import { bootstrap } from './bootstrap'
 | 
			
		||||
import { createClient } from './client'
 | 
			
		||||
import {
 | 
			
		||||
  isKclDocument,
 | 
			
		||||
  isKclEditor,
 | 
			
		||||
  LazyOutputChannel,
 | 
			
		||||
  log,
 | 
			
		||||
  type KclEditor,
 | 
			
		||||
} from './util'
 | 
			
		||||
import { Config, prepareVSCodeConfig } from './config'
 | 
			
		||||
import type { ServerStatusParams } from './lsp_ext'
 | 
			
		||||
import { PersistentState } from './persistent_state'
 | 
			
		||||
import { bootstrap } from './bootstrap'
 | 
			
		||||
import { TransportKind } from 'vscode-languageclient/node'
 | 
			
		||||
import {
 | 
			
		||||
  type KclEditor,
 | 
			
		||||
  LazyOutputChannel,
 | 
			
		||||
  isKclDocument,
 | 
			
		||||
  isKclEditor,
 | 
			
		||||
  log,
 | 
			
		||||
} from './util'
 | 
			
		||||
 | 
			
		||||
// We only support local folders, not eg. Live Share (`vlsl:` scheme), so don't activate if
 | 
			
		||||
// only those are in use. We use "Empty" to represent these scenarios
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
/* eslint suggest-no-throw/suggest-no-throw: 0 */
 | 
			
		||||
import type * as vscode from 'vscode'
 | 
			
		||||
 | 
			
		||||
import { log } from './util'
 | 
			
		||||
 | 
			
		||||
export class PersistentState {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import * as path from 'path'
 | 
			
		||||
 | 
			
		||||
import { runTests } from '@vscode/test-electron'
 | 
			
		||||
import * as path from 'path'
 | 
			
		||||
 | 
			
		||||
async function main() {
 | 
			
		||||
  try {
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,8 @@
 | 
			
		||||
import * as assert from 'assert'
 | 
			
		||||
 | 
			
		||||
// You can import and use all API from the 'vscode' module
 | 
			
		||||
// as well as import your extension to test it
 | 
			
		||||
import * as vscode from 'vscode'
 | 
			
		||||
 | 
			
		||||
// import * as myExtension from '../../extension';
 | 
			
		||||
 | 
			
		||||
suite('Extension Test Suite', () => {
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
import * as path from 'path'
 | 
			
		||||
 | 
			
		||||
const Mocha = require('mocha')
 | 
			
		||||
const { glob } = require('glob')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,8 @@
 | 
			
		||||
/* eslint suggest-no-throw/suggest-no-throw: 0 */
 | 
			
		||||
import * as vscode from 'vscode'
 | 
			
		||||
import { strict as nativeAssert } from 'assert'
 | 
			
		||||
import { exec, type ExecOptions, spawnSync } from 'child_process'
 | 
			
		||||
import { type ExecOptions, exec, spawnSync } from 'child_process'
 | 
			
		||||
import { inspect } from 'util'
 | 
			
		||||
import * as vscode from 'vscode'
 | 
			
		||||
 | 
			
		||||
export interface Env {
 | 
			
		||||
  [name: string]: string
 | 
			
		||||
 | 
			
		||||
@ -1227,7 +1227,7 @@ impl Node<CallExpressionKw> {
 | 
			
		||||
                    ));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let op = if func.feature_tree_operation() {
 | 
			
		||||
                let op = if func.feature_tree_operation() && !ctx.is_isolated_execution().await {
 | 
			
		||||
                    let op_labeled_args = args
 | 
			
		||||
                        .kw_args
 | 
			
		||||
                        .labeled
 | 
			
		||||
@ -1297,24 +1297,26 @@ impl Node<CallExpressionKw> {
 | 
			
		||||
                // exec_state.
 | 
			
		||||
                let func = fn_name.get_result(exec_state, ctx).await?.clone();
 | 
			
		||||
 | 
			
		||||
                // Track call operation.
 | 
			
		||||
                let op_labeled_args = args
 | 
			
		||||
                    .kw_args
 | 
			
		||||
                    .labeled
 | 
			
		||||
                    .iter()
 | 
			
		||||
                    .map(|(k, arg)| (k.clone(), OpArg::new(OpKclValue::from(&arg.value), arg.source_range)))
 | 
			
		||||
                    .collect();
 | 
			
		||||
                exec_state.global.operations.push(Operation::UserDefinedFunctionCall {
 | 
			
		||||
                    name: Some(fn_name.to_string()),
 | 
			
		||||
                    function_source_range: func.function_def_source_range().unwrap_or_default(),
 | 
			
		||||
                    unlabeled_arg: args
 | 
			
		||||
                if !ctx.is_isolated_execution().await {
 | 
			
		||||
                    // Track call operation.
 | 
			
		||||
                    let op_labeled_args = args
 | 
			
		||||
                        .kw_args
 | 
			
		||||
                        .unlabeled
 | 
			
		||||
                        .as_ref()
 | 
			
		||||
                        .map(|arg| OpArg::new(OpKclValue::from(&arg.value), arg.source_range)),
 | 
			
		||||
                    labeled_args: op_labeled_args,
 | 
			
		||||
                    source_range: callsite,
 | 
			
		||||
                });
 | 
			
		||||
                        .labeled
 | 
			
		||||
                        .iter()
 | 
			
		||||
                        .map(|(k, arg)| (k.clone(), OpArg::new(OpKclValue::from(&arg.value), arg.source_range)))
 | 
			
		||||
                        .collect();
 | 
			
		||||
                    exec_state.global.operations.push(Operation::UserDefinedFunctionCall {
 | 
			
		||||
                        name: Some(fn_name.to_string()),
 | 
			
		||||
                        function_source_range: func.function_def_source_range().unwrap_or_default(),
 | 
			
		||||
                        unlabeled_arg: args
 | 
			
		||||
                            .kw_args
 | 
			
		||||
                            .unlabeled
 | 
			
		||||
                            .as_ref()
 | 
			
		||||
                            .map(|arg| OpArg::new(OpKclValue::from(&arg.value), arg.source_range)),
 | 
			
		||||
                        labeled_args: op_labeled_args,
 | 
			
		||||
                        source_range: callsite,
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let Some(fn_src) = func.as_fn() else {
 | 
			
		||||
                    return Err(KclError::Semantic(KclErrorDetails {
 | 
			
		||||
@ -1341,8 +1343,10 @@ impl Node<CallExpressionKw> {
 | 
			
		||||
                    })
 | 
			
		||||
                })?;
 | 
			
		||||
 | 
			
		||||
                // Track return operation.
 | 
			
		||||
                exec_state.global.operations.push(Operation::UserDefinedFunctionReturn);
 | 
			
		||||
                if !ctx.is_isolated_execution().await {
 | 
			
		||||
                    // Track return operation.
 | 
			
		||||
                    exec_state.global.operations.push(Operation::UserDefinedFunctionReturn);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Ok(result)
 | 
			
		||||
            }
 | 
			
		||||
@ -1379,7 +1383,7 @@ impl Node<CallExpression> {
 | 
			
		||||
                    ));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let op = if func.feature_tree_operation() {
 | 
			
		||||
                let op = if func.feature_tree_operation() && !ctx.is_isolated_execution().await {
 | 
			
		||||
                    let op_labeled_args = func
 | 
			
		||||
                        .args(false)
 | 
			
		||||
                        .iter()
 | 
			
		||||
@ -1437,15 +1441,17 @@ impl Node<CallExpression> {
 | 
			
		||||
                // exec_state.
 | 
			
		||||
                let func = fn_name.get_result(exec_state, ctx).await?.clone();
 | 
			
		||||
 | 
			
		||||
                // Track call operation.
 | 
			
		||||
                exec_state.global.operations.push(Operation::UserDefinedFunctionCall {
 | 
			
		||||
                    name: Some(fn_name.to_string()),
 | 
			
		||||
                    function_source_range: func.function_def_source_range().unwrap_or_default(),
 | 
			
		||||
                    unlabeled_arg: None,
 | 
			
		||||
                    // TODO: Add the arguments for legacy positional parameters.
 | 
			
		||||
                    labeled_args: Default::default(),
 | 
			
		||||
                    source_range: callsite,
 | 
			
		||||
                });
 | 
			
		||||
                if !ctx.is_isolated_execution().await {
 | 
			
		||||
                    // Track call operation.
 | 
			
		||||
                    exec_state.global.operations.push(Operation::UserDefinedFunctionCall {
 | 
			
		||||
                        name: Some(fn_name.to_string()),
 | 
			
		||||
                        function_source_range: func.function_def_source_range().unwrap_or_default(),
 | 
			
		||||
                        unlabeled_arg: None,
 | 
			
		||||
                        // TODO: Add the arguments for legacy positional parameters.
 | 
			
		||||
                        labeled_args: Default::default(),
 | 
			
		||||
                        source_range: callsite,
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                let Some(fn_src) = func.as_fn() else {
 | 
			
		||||
                    return Err(KclError::Semantic(KclErrorDetails {
 | 
			
		||||
@ -1471,8 +1477,10 @@ impl Node<CallExpression> {
 | 
			
		||||
                    })
 | 
			
		||||
                })?;
 | 
			
		||||
 | 
			
		||||
                // Track return operation.
 | 
			
		||||
                exec_state.global.operations.push(Operation::UserDefinedFunctionReturn);
 | 
			
		||||
                if !ctx.is_isolated_execution().await {
 | 
			
		||||
                    // Track return operation.
 | 
			
		||||
                    exec_state.global.operations.push(Operation::UserDefinedFunctionReturn);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Ok(result)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -498,9 +498,13 @@ impl ExecutorContext {
 | 
			
		||||
        self.context_type == ContextType::Mock || self.context_type == ContextType::MockCustomForwarded
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn is_isolated_execution(&self) -> bool {
 | 
			
		||||
        self.engine.execution_kind().await.is_isolated()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns true if we should not send engine commands for any reason.
 | 
			
		||||
    pub async fn no_engine_commands(&self) -> bool {
 | 
			
		||||
        self.is_mock() || self.engine.execution_kind().await.is_isolated()
 | 
			
		||||
        self.is_mock() || self.is_isolated_execution().await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn send_clear_scene(
 | 
			
		||||
 | 
			
		||||
@ -113,15 +113,19 @@ pub struct AppSettings {
 | 
			
		||||
    pub onboarding_status: OnboardingStatus,
 | 
			
		||||
    /// Backwards compatible project directory setting.
 | 
			
		||||
    #[serde(default, alias = "projectDirectory", skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    #[ts(skip)]
 | 
			
		||||
    pub project_directory: Option<std::path::PathBuf>,
 | 
			
		||||
    /// Backwards compatible theme setting.
 | 
			
		||||
    #[serde(default, skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    #[ts(skip)]
 | 
			
		||||
    pub theme: Option<AppTheme>,
 | 
			
		||||
    /// The hue of the primary theme color for the app.
 | 
			
		||||
    #[serde(default, skip_serializing_if = "Option::is_none", alias = "themeColor")]
 | 
			
		||||
    #[ts(skip)]
 | 
			
		||||
    pub theme_color: Option<FloatOrInt>,
 | 
			
		||||
    /// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
 | 
			
		||||
    #[serde(default, alias = "enableSSAO", skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    #[ts(skip)]
 | 
			
		||||
    pub enable_ssao: Option<bool>,
 | 
			
		||||
    /// Permanently dismiss the banner warning to download the desktop app.
 | 
			
		||||
    /// This setting only applies to the web app. And is temporary until we have Linux support.
 | 
			
		||||
@ -285,6 +289,7 @@ pub struct ModelingSettings {
 | 
			
		||||
    /// of the app to aid in development.
 | 
			
		||||
    /// Remove this when we remove backwards compatibility with the old settings file.
 | 
			
		||||
    #[serde(default, alias = "showDebugPanel", skip_serializing_if = "is_default")]
 | 
			
		||||
    #[ts(skip)]
 | 
			
		||||
    pub show_debug_panel: bool,
 | 
			
		||||
    /// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
 | 
			
		||||
    #[serde(default, skip_serializing_if = "is_default")]
 | 
			
		||||
 | 
			
		||||
@ -94,9 +94,11 @@ pub struct ProjectAppSettings {
 | 
			
		||||
    pub onboarding_status: OnboardingStatus,
 | 
			
		||||
    /// The hue of the primary theme color for the app.
 | 
			
		||||
    #[serde(default, skip_serializing_if = "Option::is_none", alias = "themeColor")]
 | 
			
		||||
    #[ts(skip)]
 | 
			
		||||
    pub theme_color: Option<FloatOrInt>,
 | 
			
		||||
    /// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
 | 
			
		||||
    #[serde(default, alias = "enableSSAO", skip_serializing_if = "Option::is_none")]
 | 
			
		||||
    #[ts(skip)]
 | 
			
		||||
    pub enable_ssao: Option<bool>,
 | 
			
		||||
    /// Permanently dismiss the banner warning to download the desktop app.
 | 
			
		||||
    /// This setting only applies to the web app. And is temporary until we have Linux support.
 | 
			
		||||
@ -143,6 +145,7 @@ pub struct ProjectModelingSettings {
 | 
			
		||||
    /// of the app to aid in development.
 | 
			
		||||
    /// Remove this when we remove backwards compatibility with the old settings file.
 | 
			
		||||
    #[serde(default, alias = "showDebugPanel", skip_serializing_if = "is_default")]
 | 
			
		||||
    #[ts(skip)]
 | 
			
		||||
    pub show_debug_panel: bool,
 | 
			
		||||
    /// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
 | 
			
		||||
    #[serde(default, skip_serializing_if = "is_default")]
 | 
			
		||||
 | 
			
		||||
@ -28,11 +28,19 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
 | 
			
		||||
        ]),
 | 
			
		||||
        exec_state,
 | 
			
		||||
    )?;
 | 
			
		||||
    let scale_x = args.get_kw_arg("x")?;
 | 
			
		||||
    let scale_y = args.get_kw_arg("y")?;
 | 
			
		||||
    let scale_z = args.get_kw_arg("z")?;
 | 
			
		||||
    let scale_x = args.get_kw_arg_opt("x")?;
 | 
			
		||||
    let scale_y = args.get_kw_arg_opt("y")?;
 | 
			
		||||
    let scale_z = args.get_kw_arg_opt("z")?;
 | 
			
		||||
    let global = args.get_kw_arg_opt("global")?;
 | 
			
		||||
 | 
			
		||||
    // Ensure at least one scale value is provided.
 | 
			
		||||
    if scale_x.is_none() && scale_y.is_none() && scale_z.is_none() {
 | 
			
		||||
        return Err(KclError::Semantic(KclErrorDetails {
 | 
			
		||||
            message: "Expected `x`, `y`, or `z` to be provided.".to_string(),
 | 
			
		||||
            source_ranges: vec![args.source_range],
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let objects = inner_scale(objects, scale_x, scale_y, scale_z, global, exec_state, args).await?;
 | 
			
		||||
    Ok(objects.into())
 | 
			
		||||
}
 | 
			
		||||
@ -85,8 +93,6 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
 | 
			
		||||
///     |> hole(pipeHole, %)
 | 
			
		||||
///     |> sweep(path = sweepPath)   
 | 
			
		||||
///     |> scale(
 | 
			
		||||
///     x = 1.0,
 | 
			
		||||
///     y = 1.0,
 | 
			
		||||
///     z = 2.5,
 | 
			
		||||
///     )
 | 
			
		||||
/// ```
 | 
			
		||||
@ -98,8 +104,6 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
 | 
			
		||||
///
 | 
			
		||||
/// cube
 | 
			
		||||
///     |> scale(
 | 
			
		||||
///     x = 1.0,
 | 
			
		||||
///     y = 1.0,
 | 
			
		||||
///     z = 2.5,
 | 
			
		||||
///     )
 | 
			
		||||
/// ```
 | 
			
		||||
@ -135,7 +139,7 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
 | 
			
		||||
/// parts = sweep([rectangleSketch, circleSketch], path = sweepPath)
 | 
			
		||||
///
 | 
			
		||||
/// // Scale the sweep.
 | 
			
		||||
/// scale(parts, x = 1.0, y = 1.0, z = 0.5)
 | 
			
		||||
/// scale(parts, z = 0.5)
 | 
			
		||||
/// ```
 | 
			
		||||
#[stdlib {
 | 
			
		||||
    name = "scale",
 | 
			
		||||
@ -144,17 +148,17 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
 | 
			
		||||
    unlabeled_first = true,
 | 
			
		||||
    args = {
 | 
			
		||||
        objects = {docs = "The solid, sketch, or set of solids or sketches to scale."},
 | 
			
		||||
        x = {docs = "The scale factor for the x axis."},
 | 
			
		||||
        y = {docs = "The scale factor for the y axis."},
 | 
			
		||||
        z = {docs = "The scale factor for the z axis."},
 | 
			
		||||
        x = {docs = "The scale factor for the x axis. Default is 1 if not provided.", include_in_snippet = true},
 | 
			
		||||
        y = {docs = "The scale factor for the y axis. Default is 1 if not provided.", include_in_snippet = true},
 | 
			
		||||
        z = {docs = "The scale factor for the z axis. Default is 1 if not provided.", include_in_snippet = true},
 | 
			
		||||
        global = {docs = "If true, the transform is applied in global space. The origin of the model will move. By default, the transform is applied in local sketch axis, therefore the origin will not move."}
 | 
			
		||||
    }
 | 
			
		||||
}]
 | 
			
		||||
async fn inner_scale(
 | 
			
		||||
    objects: SolidOrSketchOrImportedGeometry,
 | 
			
		||||
    x: f64,
 | 
			
		||||
    y: f64,
 | 
			
		||||
    z: f64,
 | 
			
		||||
    x: Option<f64>,
 | 
			
		||||
    y: Option<f64>,
 | 
			
		||||
    z: Option<f64>,
 | 
			
		||||
    global: Option<bool>,
 | 
			
		||||
    exec_state: &mut ExecState,
 | 
			
		||||
    args: Args,
 | 
			
		||||
@ -174,7 +178,11 @@ async fn inner_scale(
 | 
			
		||||
                object_id,
 | 
			
		||||
                transforms: vec![shared::ComponentTransform {
 | 
			
		||||
                    scale: Some(shared::TransformBy::<Point3d<f64>> {
 | 
			
		||||
                        property: Point3d { x, y, z },
 | 
			
		||||
                        property: Point3d {
 | 
			
		||||
                            x: x.unwrap_or(1.0),
 | 
			
		||||
                            y: y.unwrap_or(1.0),
 | 
			
		||||
                            z: z.unwrap_or(1.0),
 | 
			
		||||
                        },
 | 
			
		||||
                        set: false,
 | 
			
		||||
                        is_local: !global.unwrap_or(false),
 | 
			
		||||
                    }),
 | 
			
		||||
@ -201,11 +209,19 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
 | 
			
		||||
        ]),
 | 
			
		||||
        exec_state,
 | 
			
		||||
    )?;
 | 
			
		||||
    let translate_x = args.get_kw_arg("x")?;
 | 
			
		||||
    let translate_y = args.get_kw_arg("y")?;
 | 
			
		||||
    let translate_z = args.get_kw_arg("z")?;
 | 
			
		||||
    let translate_x = args.get_kw_arg_opt("x")?;
 | 
			
		||||
    let translate_y = args.get_kw_arg_opt("y")?;
 | 
			
		||||
    let translate_z = args.get_kw_arg_opt("z")?;
 | 
			
		||||
    let global = args.get_kw_arg_opt("global")?;
 | 
			
		||||
 | 
			
		||||
    // Ensure at least one translation value is provided.
 | 
			
		||||
    if translate_x.is_none() && translate_y.is_none() && translate_z.is_none() {
 | 
			
		||||
        return Err(KclError::Semantic(KclErrorDetails {
 | 
			
		||||
            message: "Expected `x`, `y`, or `z` to be provided.".to_string(),
 | 
			
		||||
            source_ranges: vec![args.source_range],
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let objects = inner_translate(objects, translate_x, translate_y, translate_z, global, exec_state, args).await?;
 | 
			
		||||
    Ok(objects.into())
 | 
			
		||||
}
 | 
			
		||||
@ -326,7 +342,6 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
 | 
			
		||||
///     |> translate(
 | 
			
		||||
///         x = 5,
 | 
			
		||||
///         y = 5,
 | 
			
		||||
///         z = 0,
 | 
			
		||||
///     )
 | 
			
		||||
///     |> extrude(
 | 
			
		||||
///         length = 10,
 | 
			
		||||
@ -349,7 +364,7 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
 | 
			
		||||
/// profile001 = square()
 | 
			
		||||
///
 | 
			
		||||
/// profile002 = square()
 | 
			
		||||
///     |> translate(x = 0, y = 0, z = 20)
 | 
			
		||||
///     |> translate(z = 20)
 | 
			
		||||
///     |> rotate(axis = [0, 0, 1.0], angle = 45)
 | 
			
		||||
///
 | 
			
		||||
/// loft([profile001, profile002])
 | 
			
		||||
@ -361,17 +376,17 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
 | 
			
		||||
    unlabeled_first = true,
 | 
			
		||||
    args = {
 | 
			
		||||
        objects = {docs = "The solid, sketch, or set of solids or sketches to move."},
 | 
			
		||||
        x = {docs = "The amount to move the solid or sketch along the x axis."},
 | 
			
		||||
        y = {docs = "The amount to move the solid or sketch along the y axis."},
 | 
			
		||||
        z = {docs = "The amount to move the solid or sketch along the z axis."},
 | 
			
		||||
        x = {docs = "The amount to move the solid or sketch along the x axis. Defaults to 0 if not provided.", include_in_snippet = true},
 | 
			
		||||
        y = {docs = "The amount to move the solid or sketch along the y axis. Defaults to 0 if not provided.", include_in_snippet = true},
 | 
			
		||||
        z = {docs = "The amount to move the solid or sketch along the z axis. Defaults to 0 if not provided.", include_in_snippet = true},
 | 
			
		||||
        global = {docs = "If true, the transform is applied in global space. The origin of the model will move. By default, the transform is applied in local sketch axis, therefore the origin will not move."}
 | 
			
		||||
    }
 | 
			
		||||
}]
 | 
			
		||||
async fn inner_translate(
 | 
			
		||||
    objects: SolidOrSketchOrImportedGeometry,
 | 
			
		||||
    x: f64,
 | 
			
		||||
    y: f64,
 | 
			
		||||
    z: f64,
 | 
			
		||||
    x: Option<f64>,
 | 
			
		||||
    y: Option<f64>,
 | 
			
		||||
    z: Option<f64>,
 | 
			
		||||
    global: Option<bool>,
 | 
			
		||||
    exec_state: &mut ExecState,
 | 
			
		||||
    args: Args,
 | 
			
		||||
@ -392,9 +407,9 @@ async fn inner_translate(
 | 
			
		||||
                transforms: vec![shared::ComponentTransform {
 | 
			
		||||
                    translate: Some(shared::TransformBy::<Point3d<LengthUnit>> {
 | 
			
		||||
                        property: shared::Point3d {
 | 
			
		||||
                            x: LengthUnit(x),
 | 
			
		||||
                            y: LengthUnit(y),
 | 
			
		||||
                            z: LengthUnit(z),
 | 
			
		||||
                            x: LengthUnit(x.unwrap_or_default()),
 | 
			
		||||
                            y: LengthUnit(y.unwrap_or_default()),
 | 
			
		||||
                            z: LengthUnit(z.unwrap_or_default()),
 | 
			
		||||
                        },
 | 
			
		||||
                        set: false,
 | 
			
		||||
                        is_local: !global.unwrap_or(false),
 | 
			
		||||
@ -1001,4 +1016,34 @@ sweepSketch = startSketchOn('XY')
 | 
			
		||||
                .to_string()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[tokio::test(flavor = "multi_thread")]
 | 
			
		||||
    async fn test_translate_no_args() {
 | 
			
		||||
        let ast = PIPE.to_string()
 | 
			
		||||
            + r#"
 | 
			
		||||
    |> translate(
 | 
			
		||||
    )
 | 
			
		||||
"#;
 | 
			
		||||
        let result = parse_execute(&ast).await;
 | 
			
		||||
        assert!(result.is_err());
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            result.unwrap_err().message(),
 | 
			
		||||
            r#"Expected `x`, `y`, or `z` to be provided."#.to_string()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[tokio::test(flavor = "multi_thread")]
 | 
			
		||||
    async fn test_scale_no_args() {
 | 
			
		||||
        let ast = PIPE.to_string()
 | 
			
		||||
            + r#"
 | 
			
		||||
    |> scale(
 | 
			
		||||
    )
 | 
			
		||||
"#;
 | 
			
		||||
        let result = parse_execute(&ast).await;
 | 
			
		||||
        assert!(result.is_err());
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            result.unwrap_err().message(),
 | 
			
		||||
            r#"Expected `x`, `y`, or `z` to be provided."#.to_string()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2,43 +2,4 @@
 | 
			
		||||
source: kcl-lib/src/simulation_tests.rs
 | 
			
		||||
description: Operations executed import_function_not_sketch.kcl
 | 
			
		||||
---
 | 
			
		||||
[
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "data": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "String",
 | 
			
		||||
          "value": "XY"
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "startSketchOn",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": null
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "axis": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "String",
 | 
			
		||||
          "value": "y"
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "revolve",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": {
 | 
			
		||||
      "value": {
 | 
			
		||||
        "type": "Sketch",
 | 
			
		||||
        "value": {
 | 
			
		||||
          "artifactId": "[uuid]"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
[]
 | 
			
		||||
 | 
			
		||||
@ -2,86 +2,4 @@
 | 
			
		||||
source: kcl-lib/src/simulation_tests.rs
 | 
			
		||||
description: Operations executed import_side_effect.kcl
 | 
			
		||||
---
 | 
			
		||||
[
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "data": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "String",
 | 
			
		||||
          "value": "XY"
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "startSketchOn",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": null
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "circle",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      0,
 | 
			
		||||
      0,
 | 
			
		||||
      0
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "center": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Array",
 | 
			
		||||
          "value": [
 | 
			
		||||
            {
 | 
			
		||||
              "type": "Number",
 | 
			
		||||
              "value": 0.0,
 | 
			
		||||
              "ty": {
 | 
			
		||||
                "type": "Default",
 | 
			
		||||
                "len": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                },
 | 
			
		||||
                "angle": {
 | 
			
		||||
                  "type": "Degrees"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "type": "Number",
 | 
			
		||||
              "value": 0.0,
 | 
			
		||||
              "ty": {
 | 
			
		||||
                "type": "Default",
 | 
			
		||||
                "len": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                },
 | 
			
		||||
                "angle": {
 | 
			
		||||
                  "type": "Degrees"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          ]
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      },
 | 
			
		||||
      "radius": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Number",
 | 
			
		||||
          "value": 10.0,
 | 
			
		||||
          "ty": {
 | 
			
		||||
            "type": "Default",
 | 
			
		||||
            "len": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            },
 | 
			
		||||
            "angle": {
 | 
			
		||||
              "type": "Degrees"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
[]
 | 
			
		||||
 | 
			
		||||
@ -3,66 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
 | 
			
		||||
description: Operations executed multi-axis-robot.kcl
 | 
			
		||||
---
 | 
			
		||||
[
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "sin",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      0,
 | 
			
		||||
      0,
 | 
			
		||||
      0
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {},
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "cos",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      0,
 | 
			
		||||
      0,
 | 
			
		||||
      0
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {},
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "sin",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      0,
 | 
			
		||||
      0,
 | 
			
		||||
      0
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {},
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "cos",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      0,
 | 
			
		||||
      0,
 | 
			
		||||
      0
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {},
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "data": {
 | 
			
		||||
 | 
			
		||||
@ -3,36 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
 | 
			
		||||
description: Operations executed pipe-flange-assembly.kcl
 | 
			
		||||
---
 | 
			
		||||
[
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "cos",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      0,
 | 
			
		||||
      0,
 | 
			
		||||
      0
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {},
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "cos",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      0,
 | 
			
		||||
      0,
 | 
			
		||||
      0
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {},
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "flange",
 | 
			
		||||
 | 
			
		||||
@ -349,352 +349,6 @@ description: Operations executed walkie-talkie.kcl
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "body",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      359,
 | 
			
		||||
      2786,
 | 
			
		||||
      6
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {},
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "data": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Plane",
 | 
			
		||||
          "artifact_id": "[uuid]"
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "startSketchOn",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": null
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "length": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Number",
 | 
			
		||||
          "value": 1.0,
 | 
			
		||||
          "ty": {
 | 
			
		||||
            "type": "Default",
 | 
			
		||||
            "len": {
 | 
			
		||||
              "type": "Inches"
 | 
			
		||||
            },
 | 
			
		||||
            "angle": {
 | 
			
		||||
              "type": "Degrees"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "extrude",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": {
 | 
			
		||||
      "value": {
 | 
			
		||||
        "type": "Sketch",
 | 
			
		||||
        "value": {
 | 
			
		||||
          "artifactId": "[uuid]"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "length": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Number",
 | 
			
		||||
          "value": 0.325,
 | 
			
		||||
          "ty": {
 | 
			
		||||
            "type": "Default",
 | 
			
		||||
            "len": {
 | 
			
		||||
              "type": "Inches"
 | 
			
		||||
            },
 | 
			
		||||
            "angle": {
 | 
			
		||||
              "type": "Degrees"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      },
 | 
			
		||||
      "tags": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Array",
 | 
			
		||||
          "value": [
 | 
			
		||||
            {
 | 
			
		||||
              "type": "Uuid",
 | 
			
		||||
              "value": "[uuid]"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "type": "Uuid",
 | 
			
		||||
              "value": "[uuid]"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "type": "Uuid",
 | 
			
		||||
              "value": "[uuid]"
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "type": "Uuid",
 | 
			
		||||
              "value": "[uuid]"
 | 
			
		||||
            }
 | 
			
		||||
          ]
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "chamfer",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": {
 | 
			
		||||
      "value": {
 | 
			
		||||
        "type": "Solid",
 | 
			
		||||
        "value": {
 | 
			
		||||
          "artifactId": "[uuid]"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "data": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Solid",
 | 
			
		||||
          "value": {
 | 
			
		||||
            "artifactId": "[uuid]"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      },
 | 
			
		||||
      "tag": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "String",
 | 
			
		||||
          "value": "END"
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "startSketchOn",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": null
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "cos",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      0,
 | 
			
		||||
      0,
 | 
			
		||||
      0
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {},
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "cos",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      0,
 | 
			
		||||
      0,
 | 
			
		||||
      0
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {},
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "cos",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      0,
 | 
			
		||||
      0,
 | 
			
		||||
      0
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {},
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "cos",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      0,
 | 
			
		||||
      0,
 | 
			
		||||
      0
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {},
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "length": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Number",
 | 
			
		||||
          "value": -0.0625,
 | 
			
		||||
          "ty": {
 | 
			
		||||
            "type": "Default",
 | 
			
		||||
            "len": {
 | 
			
		||||
              "type": "Inches"
 | 
			
		||||
            },
 | 
			
		||||
            "angle": {
 | 
			
		||||
              "type": "Degrees"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "extrude",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": {
 | 
			
		||||
      "value": {
 | 
			
		||||
        "type": "Sketch",
 | 
			
		||||
        "value": {
 | 
			
		||||
          "artifactId": "[uuid]"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "data": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Solid",
 | 
			
		||||
          "value": {
 | 
			
		||||
            "artifactId": "[uuid]"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      },
 | 
			
		||||
      "tag": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "String",
 | 
			
		||||
          "value": "start"
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "startSketchOn",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": null
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "length": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Number",
 | 
			
		||||
          "value": -0.0625,
 | 
			
		||||
          "ty": {
 | 
			
		||||
            "type": "Default",
 | 
			
		||||
            "len": {
 | 
			
		||||
              "type": "Inches"
 | 
			
		||||
            },
 | 
			
		||||
            "angle": {
 | 
			
		||||
              "type": "Degrees"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "extrude",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": {
 | 
			
		||||
      "value": {
 | 
			
		||||
        "type": "Sketch",
 | 
			
		||||
        "value": {
 | 
			
		||||
          "artifactId": "[uuid]"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "data": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Solid",
 | 
			
		||||
          "value": {
 | 
			
		||||
            "artifactId": "[uuid]"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      },
 | 
			
		||||
      "tag": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "String",
 | 
			
		||||
          "value": "start"
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "startSketchOn",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": null
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "length": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Number",
 | 
			
		||||
          "value": -0.5,
 | 
			
		||||
          "ty": {
 | 
			
		||||
            "type": "Default",
 | 
			
		||||
            "len": {
 | 
			
		||||
              "type": "Inches"
 | 
			
		||||
            },
 | 
			
		||||
            "angle": {
 | 
			
		||||
              "type": "Degrees"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "extrude",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": {
 | 
			
		||||
      "value": {
 | 
			
		||||
        "type": "Sketch",
 | 
			
		||||
        "value": {
 | 
			
		||||
          "artifactId": "[uuid]"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "antenna",
 | 
			
		||||
 | 
			
		||||
@ -3,91 +3,6 @@ source: kcl-lib/src/simulation_tests.rs
 | 
			
		||||
description: Operations executed pattern_circular_in_module.kcl
 | 
			
		||||
---
 | 
			
		||||
[
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "thing",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      15,
 | 
			
		||||
      378,
 | 
			
		||||
      5
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {},
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "data": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Plane",
 | 
			
		||||
          "artifact_id": "[uuid]"
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "startSketchOn",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": null
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "length": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Number",
 | 
			
		||||
          "value": 1.0,
 | 
			
		||||
          "ty": {
 | 
			
		||||
            "type": "Default",
 | 
			
		||||
            "len": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            },
 | 
			
		||||
            "angle": {
 | 
			
		||||
              "type": "Degrees"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "extrude",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": {
 | 
			
		||||
      "value": {
 | 
			
		||||
        "type": "Array",
 | 
			
		||||
        "value": [
 | 
			
		||||
          {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "value": {
 | 
			
		||||
              "artifactId": "[uuid]"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "value": {
 | 
			
		||||
              "artifactId": "[uuid]"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "value": {
 | 
			
		||||
              "artifactId": "[uuid]"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "value": {
 | 
			
		||||
              "artifactId": "[uuid]"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "thing",
 | 
			
		||||
 | 
			
		||||
@ -169,175 +169,6 @@ description: Operations executed pattern_linear_in_module.kcl
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "thing",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      15,
 | 
			
		||||
      221,
 | 
			
		||||
      5
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {},
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "data": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Plane",
 | 
			
		||||
          "artifact_id": "[uuid]"
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "startSketchOn",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": null
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionCall",
 | 
			
		||||
    "name": "circle",
 | 
			
		||||
    "functionSourceRange": [
 | 
			
		||||
      0,
 | 
			
		||||
      0,
 | 
			
		||||
      0
 | 
			
		||||
    ],
 | 
			
		||||
    "unlabeledArg": null,
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "center": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Array",
 | 
			
		||||
          "value": [
 | 
			
		||||
            {
 | 
			
		||||
              "type": "Number",
 | 
			
		||||
              "value": 0.0,
 | 
			
		||||
              "ty": {
 | 
			
		||||
                "type": "Default",
 | 
			
		||||
                "len": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                },
 | 
			
		||||
                "angle": {
 | 
			
		||||
                  "type": "Degrees"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "type": "Number",
 | 
			
		||||
              "value": 0.0,
 | 
			
		||||
              "ty": {
 | 
			
		||||
                "type": "Default",
 | 
			
		||||
                "len": {
 | 
			
		||||
                  "type": "Mm"
 | 
			
		||||
                },
 | 
			
		||||
                "angle": {
 | 
			
		||||
                  "type": "Degrees"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          ]
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      },
 | 
			
		||||
      "radius": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Number",
 | 
			
		||||
          "value": 1.0,
 | 
			
		||||
          "ty": {
 | 
			
		||||
            "type": "Default",
 | 
			
		||||
            "len": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            },
 | 
			
		||||
            "angle": {
 | 
			
		||||
              "type": "Degrees"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "sourceRange": []
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "labeledArgs": {
 | 
			
		||||
      "length": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Number",
 | 
			
		||||
          "value": 1.0,
 | 
			
		||||
          "ty": {
 | 
			
		||||
            "type": "Default",
 | 
			
		||||
            "len": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            },
 | 
			
		||||
            "angle": {
 | 
			
		||||
              "type": "Degrees"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "name": "extrude",
 | 
			
		||||
    "sourceRange": [],
 | 
			
		||||
    "type": "StdLibCall",
 | 
			
		||||
    "unlabeledArg": {
 | 
			
		||||
      "value": {
 | 
			
		||||
        "type": "Array",
 | 
			
		||||
        "value": [
 | 
			
		||||
          {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "value": {
 | 
			
		||||
              "artifactId": "[uuid]"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "value": {
 | 
			
		||||
              "artifactId": "[uuid]"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "value": {
 | 
			
		||||
              "artifactId": "[uuid]"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "value": {
 | 
			
		||||
              "artifactId": "[uuid]"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "value": {
 | 
			
		||||
              "artifactId": "[uuid]"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "value": {
 | 
			
		||||
              "artifactId": "[uuid]"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "Sketch",
 | 
			
		||||
            "value": {
 | 
			
		||||
              "artifactId": "[uuid]"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "type": "UserDefinedFunctionReturn"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ name = "kcl-python-bindings"
 | 
			
		||||
version = "0.3.57"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
repository = "https://github.com/kittycad/modeling-app"
 | 
			
		||||
exclude = ["tests/*", "files/*", "venv/*"]
 | 
			
		||||
 | 
			
		||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
			
		||||
[lib]
 | 
			
		||||
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user