Compare commits
	
		
			9 Commits
		
	
	
		
			nightly-v2
			...
			v0.52.0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| befac6ad87 | |||
| 60bc38559b | |||
| 2a56155587 | |||
| 87c3673a71 | |||
| 21889162ff | |||
| f1cccc22cd | |||
| 10c1f3a849 | |||
| d168ef94e9 | |||
| 29f8b05f56 | 
							
								
								
									
										111
									
								
								.eslintrc
									
									
									
									
									
								
							
							
						
						| @ -1,111 +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()." | ||||
|         }, | ||||
|         { | ||||
|             "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." | ||||
|         } | ||||
|       ], | ||||
|       "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
									
								
							
							
						
						| @ -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" | ||||
|       } | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										30
									
								
								.github/workflows/static-analysis.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -136,6 +136,36 @@ jobs: | ||||
|  | ||||
|       - run: yarn lint | ||||
|  | ||||
|   yarn-circular-dependencies: | ||||
|     runs-on: ubuntu-latest | ||||
|     needs: yarn-build-wasm | ||||
|  | ||||
|     steps: | ||||
|       - uses: actions/checkout@v4 | ||||
|       - uses: actions/setup-node@v4 | ||||
|         with: | ||||
|           node-version-file: '.nvmrc' | ||||
|           cache: 'yarn' | ||||
|       - run: yarn install | ||||
|  | ||||
|       - name: Download all artifacts | ||||
|         uses: actions/download-artifact@v4 | ||||
|  | ||||
|       - name: Copy prepared wasm | ||||
|         run: | | ||||
|           ls -R prepared-wasm | ||||
|           cp prepared-wasm/kcl_wasm_lib_bg.wasm public | ||||
|           mkdir rust/kcl-wasm-lib/pkg | ||||
|           cp prepared-wasm/kcl_wasm_lib* rust/kcl-wasm-lib/pkg | ||||
|  | ||||
|       - name: Copy prepared ts-rs bindings | ||||
|         run: | | ||||
|           ls -R prepared-ts-rs-bindings | ||||
|           mkdir rust/kcl-lib/bindings | ||||
|           cp -r prepared-ts-rs-bindings/* rust/kcl-lib/bindings/ | ||||
|  | ||||
|       - run: yarn circular-deps:diff | ||||
|  | ||||
|   python-codespell: | ||||
|     runs-on: ubuntu-22.04 | ||||
|     steps: | ||||
|  | ||||
							
								
								
									
										50
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						| @ -4,18 +4,38 @@ all: install build check | ||||
| ############################################################################### | ||||
| # INSTALL | ||||
|  | ||||
| WASM_PACK ?= ~/.cargo/bin/wasm-pack | ||||
| ifeq ($(OS),Windows_NT) | ||||
| 	CARGO ?= ~/.cargo/bin/cargo.exe | ||||
| 	WASM_PACK ?= ~/.cargo/bin/wasm-pack.exe | ||||
| else | ||||
| 	CARGO ?= ~/.cargo/bin/cargo | ||||
| 	WASM_PACK ?= ~/.cargo/bin/wasm-pack | ||||
| endif | ||||
|  | ||||
| .PHONY: install | ||||
| install: node_modules/.yarn-integrity $(WASM_PACK) ## Install dependencies | ||||
| install: node_modules/.yarn-integrity $(CARGO) $(WASM_PACK) ## Install dependencies | ||||
|  | ||||
| node_modules/.yarn-integrity: package.json yarn.lock | ||||
| 	yarn install | ||||
| ifeq ($(OS),Windows_NT) | ||||
| 	@ type nul > $@ | ||||
| else | ||||
| 	@ touch $@ | ||||
| endif | ||||
|  | ||||
| $(CARGO): | ||||
| ifeq ($(OS),Windows_NT) | ||||
| 	yarn install:rust:windows | ||||
| else | ||||
| 	yarn install:rust | ||||
| endif | ||||
|  | ||||
| $(WASM_PACK): | ||||
| 	yarn install:rust | ||||
| ifeq ($(OS),Windows_NT) | ||||
| 	yarn install:wasm-pack:cargo | ||||
| else | ||||
| 	yarn install:wasm-pack:sh | ||||
| endif | ||||
|  | ||||
| ############################################################################### | ||||
| # BUILD | ||||
| @ -31,13 +51,17 @@ VITE_SOURCES := $(wildcard vite.*) $(wildcard vite/**/*.tsx) | ||||
| build: build-web build-desktop | ||||
|  | ||||
| .PHONY: build-web | ||||
| build-web: public/kcl_wasm_lib_bg.wasm build/index.html | ||||
| build-web: install public/kcl_wasm_lib_bg.wasm build/index.html | ||||
|  | ||||
| .PHONY: build-desktop | ||||
| build-desktop: public/kcl_wasm_lib_bg.wasm .vite/build/main.js | ||||
| build-desktop: install public/kcl_wasm_lib_bg.wasm .vite/build/main.js | ||||
|  | ||||
| public/kcl_wasm_lib_bg.wasm: $(CARGO_SOURCES)$(RUST_SOURCES) | ||||
| public/kcl_wasm_lib_bg.wasm: $(CARGO_SOURCES) $(RUST_SOURCES) | ||||
| ifeq ($(OS),Windows_NT) | ||||
| 	yarn build:wasm:dev:windows | ||||
| else | ||||
| 	yarn build:wasm:dev | ||||
| endif | ||||
|  | ||||
| build/index.html: $(REACT_SOURCES) $(TYPESCRIPT_SOURCES) $(VITE_SOURCES) | ||||
| 	yarn build:local | ||||
| @ -63,8 +87,10 @@ lint: install ## Lint the code | ||||
| ############################################################################### | ||||
| # RUN | ||||
|  | ||||
| TARGET ?= web | ||||
|  | ||||
| .PHONY: run | ||||
| run: run-web | ||||
| run: run-$(TARGET) | ||||
|  | ||||
| .PHONY: run-web | ||||
| run-web: install build-web ## Start the web app | ||||
| @ -90,7 +116,7 @@ test-unit: install ## Run the unit tests | ||||
| 	yarn test:unit | ||||
|  | ||||
| .PHONY: test-e2e | ||||
| test-e2e: test-e2e-desktop | ||||
| test-e2e: test-e2e-$(TARGET) | ||||
|  | ||||
| .PHONY: test-e2e-web | ||||
| test-e2e-web: install build-web ## Run the web e2e tests | ||||
| @ -106,15 +132,23 @@ test-e2e-desktop: install build-desktop ## Run the desktop e2e tests | ||||
|  | ||||
| .PHONY: clean | ||||
| clean: ## Delete all artifacts | ||||
| ifeq ($(OS),Windows_NT) | ||||
| 	git clean --force -d -X | ||||
| else | ||||
| 	rm -rf .vite/ build/ | ||||
| 	rm -rf trace.zip playwright-report/ test-results/ | ||||
| 	rm -rf public/kcl_wasm_lib_bg.wasm | ||||
| 	rm -rf rust/*/bindings/ rust/*/pkg/ rust/target/ | ||||
| 	rm -rf node_modules/ rust/*/node_modules/ | ||||
| endif | ||||
|  | ||||
| .PHONY: help | ||||
| help: install | ||||
| ifeq ($(OS),Windows_NT) | ||||
| 	@ powershell -Command "Get-Content $(MAKEFILE_LIST) | Select-String -Pattern '^[^\s]+:.*##\s.*$$' | ForEach-Object { $$line = $$_.Line -split ':.*?##\s+'; Write-Host -NoNewline $$line[0].PadRight(30) -ForegroundColor Cyan; Write-Host $$line[1] }" | ||||
| else | ||||
| 	@ grep -E '^[^[:space:]]+:.*## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' | ||||
| endif | ||||
|  | ||||
| .DEFAULT_GOAL := help | ||||
|  | ||||
|  | ||||
| @ -256392,7 +256392,7 @@ | ||||
|         }, | ||||
|         "required": false, | ||||
|         "includeInSnippet": true, | ||||
|         "description": "The roll angle in degrees. Must be used with `pitch` and `yaw`. Must be between -360 and 360.", | ||||
|         "description": "The roll angle in degrees. Must be between -360 and 360. Default is 0 if not given.", | ||||
|         "labelRequired": true | ||||
|       }, | ||||
|       { | ||||
| @ -257990,7 +257990,7 @@ | ||||
|         }, | ||||
|         "required": false, | ||||
|         "includeInSnippet": true, | ||||
|         "description": "The pitch angle in degrees. Must be used with `roll` and `yaw`. Must be between -360 and 360.", | ||||
|         "description": "The pitch angle in degrees. Must be between -360 and 360. Default is 0 if not given.", | ||||
|         "labelRequired": true | ||||
|       }, | ||||
|       { | ||||
| @ -259588,7 +259588,7 @@ | ||||
|         }, | ||||
|         "required": false, | ||||
|         "includeInSnippet": true, | ||||
|         "description": "The yaw angle in degrees. Must be used with `roll` and `pitch`. Must be between -360 and 360.", | ||||
|         "description": "The yaw angle in degrees. Must be between -360 and 360. Default is 0 if not given.", | ||||
|         "labelRequired": true | ||||
|       }, | ||||
|       { | ||||
| @ -266057,6 +266057,7 @@ | ||||
|     "deprecated": false, | ||||
|     "examples": [ | ||||
|       "// Rotate a pipe with roll, pitch, and yaw.\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  |> rotate(roll = 10, pitch = 10, yaw = 90)", | ||||
|       "// Rotate a pipe with just roll.\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  |> rotate(roll = 10)", | ||||
|       "// Rotate a pipe about an axis with an angle.\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  |> rotate(axis = [0, 0, 1.0], angle = 90)", | ||||
|       "// Rotate an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n  |> rotate(axis = [0, 0, 1.0], angle = 90)", | ||||
|       "// 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// Rotate the sweeps.\nrotate(parts, axis = [0, 0, 1.0], angle = 90)", | ||||
|  | ||||
| @ -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 }) => { | ||||
| @ -985,12 +985,13 @@ sketch001 = startSketchOn(XZ) | ||||
|   test( | ||||
|     'Can undo a sketch modification with ctrl+z', | ||||
|     { tag: ['@skipWin'] }, | ||||
|     async ({ page, homePage }) => { | ||||
|     async ({ page, homePage, editor }) => { | ||||
|       const u = await getUtils(page) | ||||
|       await page.addInitScript(async () => { | ||||
|         localStorage.setItem( | ||||
|           'persistCode', | ||||
|           `sketch001 = startSketchOn(XZ) | ||||
|           `@settings(defaultLengthUnit=in) | ||||
| sketch001 = startSketchOn(XZ) | ||||
|   |> startProfileAt([4.61, -10.01], %) | ||||
|   |> line(end = [12.73, -0.09]) | ||||
|   |> tangentialArcTo([24.95, -0.38], %) | ||||
| @ -1080,41 +1081,45 @@ sketch001 = startSketchOn(XZ) | ||||
|       await expect(page.locator('.cm-content')).not.toHaveText(prevContent) | ||||
|  | ||||
|       // expect the code to have changed | ||||
|       await expect(page.locator('.cm-content')) | ||||
|         .toHaveText(`sketch001 = startSketchOn(XZ) | ||||
|       await editor.expectEditor.toContain( | ||||
|         `sketch001 = startSketchOn(XZ) | ||||
|     |> startProfileAt([2.71, -2.71], %) | ||||
|     |> line(end = [15.4, -2.78]) | ||||
|     |> tangentialArcTo([27.6, -3.05], %) | ||||
|     |> close() | ||||
|     |> extrude(length = 5) | ||||
|   `) | ||||
|     |> extrude(length = 5)`, | ||||
|         { shouldNormalise: true } | ||||
|       ) | ||||
|  | ||||
|       // Hit undo | ||||
|       await page.keyboard.down('Control') | ||||
|       await page.keyboard.press('KeyZ') | ||||
|       await page.keyboard.up('Control') | ||||
|  | ||||
|       await expect(page.locator('.cm-content')) | ||||
|         .toHaveText(`sketch001 = startSketchOn(XZ) | ||||
|       await editor.expectEditor.toContain( | ||||
|         `sketch001 = startSketchOn(XZ) | ||||
|     |> startProfileAt([2.71, -2.71], %) | ||||
|     |> line(end = [15.4, -2.78]) | ||||
|     |> tangentialArcTo([24.95, -0.38], %) | ||||
|     |> close() | ||||
|     |> extrude(length = 5)`) | ||||
|     |> extrude(length = 5)`, | ||||
|         { shouldNormalise: true } | ||||
|       ) | ||||
|  | ||||
|       // Hit undo again. | ||||
|       await page.keyboard.down('Control') | ||||
|       await page.keyboard.press('KeyZ') | ||||
|       await page.keyboard.up('Control') | ||||
|  | ||||
|       await expect(page.locator('.cm-content')) | ||||
|         .toHaveText(`sketch001 = startSketchOn(XZ) | ||||
|       await editor.expectEditor.toContain( | ||||
|         `sketch001 = startSketchOn(XZ) | ||||
|     |> startProfileAt([2.71, -2.71], %) | ||||
|     |> line(end = [12.73, -0.09]) | ||||
|     |> tangentialArcTo([24.95, -0.38], %) | ||||
|     |> close() | ||||
|     |> extrude(length = 5) | ||||
|   `) | ||||
|     |> extrude(length = 5)`, | ||||
|         { shouldNormalise: true } | ||||
|       ) | ||||
|  | ||||
|       // Hit undo again. | ||||
|       await page.keyboard.down('Control') | ||||
| @ -1122,13 +1127,15 @@ sketch001 = startSketchOn(XZ) | ||||
|       await page.keyboard.up('Control') | ||||
|  | ||||
|       await page.waitForTimeout(100) | ||||
|       await expect(page.locator('.cm-content')) | ||||
|         .toHaveText(`sketch001 = startSketchOn(XZ) | ||||
|       await editor.expectEditor.toContain( | ||||
|         `sketch001 = startSketchOn(XZ) | ||||
|     |> startProfileAt([4.61, -10.01], %) | ||||
|     |> line(end = [12.73, -0.09]) | ||||
|     |> tangentialArcTo([24.95, -0.38], %) | ||||
|     |> close() | ||||
|   |> extrude(length = 5)`) | ||||
|     |> extrude(length = 5)`, | ||||
|         { shouldNormalise: true } | ||||
|       ) | ||||
|     } | ||||
|   ) | ||||
|  | ||||
|  | ||||
| @ -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> | ||||
|  | ||||
| @ -2,25 +2,27 @@ | ||||
| import type { | ||||
|   BrowserContext, | ||||
|   ElectronApplication, | ||||
|   TestInfo, | ||||
|   Page, | ||||
|   TestInfo, | ||||
| } from '@playwright/test' | ||||
|  | ||||
| import { _electron as electron } from '@playwright/test' | ||||
|  | ||||
| import { TEST_SETTINGS } from '../storageStates' | ||||
| import { SETTINGS_FILE_NAME } from 'lib/constants' | ||||
| import { getUtils, setup, settingsToToml } 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 | ||||
|  | ||||
| @ -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,18 @@ | ||||
| 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' | ||||
| import { type baseUnitLabels } from '@src/lib/settings/settingsTypes' | ||||
|  | ||||
| type LengthUnitLabel = (typeof baseUnitLabels)[keyof typeof baseUnitLabels] | ||||
|  | ||||
| export class ToolbarFixture { | ||||
|   public page: Page | ||||
| @ -235,6 +239,12 @@ export class ToolbarFixture { | ||||
|   async checkIfFeatureTreePaneIsOpen() { | ||||
|     return this.checkIfPaneIsOpen(this.featureTreeId) | ||||
|   } | ||||
|   async selectUnit(unit: LengthUnitLabel) { | ||||
|     await this.page.getByTestId('units-menu').click() | ||||
|     const optionLocator = this.page.getByRole('button', { name: unit }) | ||||
|     await expect(optionLocator).toBeVisible() | ||||
|     await optionLocator.click() | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Get a specific operation button from the Feature Tree pane. | ||||
|  | ||||
| @ -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. | ||||
|  | ||||
| @ -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 | ||||
| @ -797,6 +798,74 @@ plane002 = offsetPlane(XZ, offset = -2 * x)` | ||||
|       await page.getByTestId('custom-cmd-send-button').click() | ||||
|     } | ||||
|   ) | ||||
|  | ||||
|   test('scale other than default works with sketch mode', async ({ | ||||
|     page, | ||||
|     homePage, | ||||
|     toolbar, | ||||
|     editor, | ||||
|     scene, | ||||
|   }) => { | ||||
|     await test.step('Load the washer code', async () => { | ||||
|       await page.addInitScript(async () => { | ||||
|         localStorage.setItem( | ||||
|           'persistCode', | ||||
|           `@settings(defaultLengthUnit = in) | ||||
|  | ||||
| innerDiameter = 0.203 | ||||
| outerDiameter = 0.438 | ||||
| thicknessMax = 0.038 | ||||
| thicknessMin = 0.024 | ||||
| washerSketch = startSketchOn(XY) | ||||
|   |> circle(center = [0, 0], radius = outerDiameter / 2) | ||||
|  | ||||
| washer = extrude(washerSketch, length = thicknessMax)` | ||||
|         ) | ||||
|       }) | ||||
|       await page.setBodyDimensions({ width: 1200, height: 500 }) | ||||
|       await homePage.goToModelingScene() | ||||
|     }) | ||||
|     const [circleCenterClick] = scene.makeMouseHelpers(650, 300) | ||||
|     const [circleRadiusClick] = scene.makeMouseHelpers(800, 320) | ||||
|     const [washerFaceClick] = scene.makeMouseHelpers(657, 286) | ||||
|  | ||||
|     await page.waitForTimeout(100) | ||||
|     await test.step('Start sketching on the washer face', async () => { | ||||
|       await toolbar.startSketchPlaneSelection() | ||||
|       await washerFaceClick() | ||||
|       await page.waitForTimeout(600) // engine animation | ||||
|       await toolbar.expectToolbarMode.toBe('sketching') | ||||
|     }) | ||||
|  | ||||
|     await test.step('Draw a circle and verify code', async () => { | ||||
|       // select circle tool | ||||
|       await expect | ||||
|         .poll(async () => { | ||||
|           await toolbar.circleBtn.click() | ||||
|           return toolbar.circleBtn.getAttribute('aria-pressed') | ||||
|         }) | ||||
|         .toBe('true') | ||||
|       await page.waitForTimeout(100) | ||||
|       await circleCenterClick() | ||||
|       // this number will be different if the scale is not set correctly for inches | ||||
|       await editor.expectEditor.toContain( | ||||
|         'circle(sketch001, center = [0.06, -0.06]' | ||||
|       ) | ||||
|       await circleRadiusClick() | ||||
|  | ||||
|       await editor.expectEditor.toContain( | ||||
|         'circle(sketch001, center = [0.06, -0.06], radius = 0.18' | ||||
|       ) | ||||
|     }) | ||||
|  | ||||
|     await test.step('Exit sketch mode', async () => { | ||||
|       await toolbar.exitSketch() | ||||
|       await toolbar.expectToolbarMode.toBe('modeling') | ||||
|  | ||||
|       await toolbar.selectUnit('Yards') | ||||
|       await editor.expectEditor.toContain('@settings(defaultLengthUnit = yd)') | ||||
|     }) | ||||
|   }) | ||||
| }) | ||||
|  | ||||
| async function clickExportButton(page: Page) { | ||||
|  | ||||
| @ -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 ({ | ||||
| @ -479,7 +479,8 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002) | ||||
|     await page.addInitScript(async () => { | ||||
|       localStorage.setItem( | ||||
|         'persistCode', | ||||
|         `sketch001 = startSketchOn(XZ) | ||||
|         `@settings(defaultLengthUnit=in) | ||||
| sketch001 = startSketchOn(XZ) | ||||
|     |> circle(center = [4.61, -5.01], radius = 8)` | ||||
|       ) | ||||
|     }) | ||||
| @ -564,12 +565,14 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002) | ||||
|   test('Can edit a sketch that has been extruded in the same pipe', async ({ | ||||
|     page, | ||||
|     homePage, | ||||
|     editor, | ||||
|   }) => { | ||||
|     const u = await getUtils(page) | ||||
|     await page.addInitScript(async () => { | ||||
|       localStorage.setItem( | ||||
|         'persistCode', | ||||
|         `sketch001 = startSketchOn(XZ) | ||||
|         `@settings(defaultLengthUnit=in) | ||||
| sketch001 = startSketchOn(XZ) | ||||
|   |> startProfileAt([4.61, -10.01], %) | ||||
|   |> line(end = [12.73, -0.09]) | ||||
|   |> tangentialArcTo([24.95, -0.38], %) | ||||
| @ -654,26 +657,29 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002) | ||||
|     await expect(page.locator('.cm-content')).not.toHaveText(prevContent) | ||||
|  | ||||
|     // expect the code to have changed | ||||
|     await expect(page.locator('.cm-content')) | ||||
|       .toHaveText(`sketch001 = startSketchOn(XZ) | ||||
|     await editor.expectEditor.toContain( | ||||
|       `sketch001 = startSketchOn(XZ) | ||||
|     |> startProfileAt([7.12, -12.68], %) | ||||
|     |> line(end = [12.68, -1.09]) | ||||
|     |> tangentialArcTo([24.89, 0.68], %) | ||||
|     |> close() | ||||
|     |> extrude(length = 5) | ||||
|   `) | ||||
|     |> extrude(length = 5)`, | ||||
|       { shouldNormalise: true } | ||||
|     ) | ||||
|   }) | ||||
|  | ||||
|   test('Can edit a sketch that has been revolved in the same pipe', async ({ | ||||
|     page, | ||||
|     homePage, | ||||
|     scene, | ||||
|     editor, | ||||
|   }) => { | ||||
|     const u = await getUtils(page) | ||||
|     await page.addInitScript(async () => { | ||||
|       localStorage.setItem( | ||||
|         'persistCode', | ||||
|         `sketch001 = startSketchOn(XZ) | ||||
|         `@settings(defaultLengthUnit=in) | ||||
| sketch001 = startSketchOn(XZ) | ||||
|   |> startProfileAt([4.61, -14.01], %) | ||||
|   |> line(end = [12.73, -0.09]) | ||||
|   |> tangentialArcTo([24.95, -5.38], %) | ||||
| @ -758,14 +764,16 @@ sketch001 = startProfileAt([12.34, -12.34], sketch002) | ||||
|     await expect(page.locator('.cm-content')).not.toHaveText(prevContent) | ||||
|  | ||||
|     // expect the code to have changed | ||||
|     await expect(page.locator('.cm-content')) | ||||
|       .toHaveText(`sketch001 = startSketchOn(XZ) | ||||
|     await editor.expectEditor.toContain( | ||||
|       `sketch001 = startSketchOn(XZ) | ||||
|   |> startProfileAt([6.44, -12.07], %) | ||||
|   |> line(end = [14.72, 1.97]) | ||||
|   |> tangentialArcTo([24.95, -5.38], %) | ||||
|   |> line(end = [1.97, 2.06]) | ||||
|   |> close() | ||||
|   |> revolve(axis = "X")`) | ||||
|   |> revolve(axis = "X")`, | ||||
|       { shouldNormalise: true } | ||||
|     ) | ||||
|   }) | ||||
|   test('Can add multiple sketches', async ({ page, homePage }) => { | ||||
|     const u = await getUtils(page) | ||||
|  | ||||
| @ -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 | ||||
| @ -454,7 +455,7 @@ test( | ||||
|     await page.waitForTimeout(700) // TODO detect animation ending, or disable animation | ||||
|  | ||||
|     await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) | ||||
|     code += `profile001 = startProfileAt([7.19, -9.7], sketch001)` | ||||
|     code += `profile001 = startProfileAt([182.59, -246.32], sketch001)` | ||||
|     await expect(page.locator('.cm-content')).toHaveText(code) | ||||
|     await page.waitForTimeout(100) | ||||
|  | ||||
| @ -472,7 +473,7 @@ test( | ||||
|     await page.waitForTimeout(500) | ||||
|  | ||||
|     code += ` | ||||
|   |> xLine(length = 7.25)` | ||||
|   |> xLine(length = 184.3)` | ||||
|     await expect(page.locator('.cm-content')).toHaveText(code) | ||||
|  | ||||
|     await page | ||||
| @ -630,7 +631,7 @@ test( | ||||
|       mask: [page.getByTestId('model-state-indicator')], | ||||
|     }) | ||||
|     await expect(page.locator('.cm-content')).toHaveText( | ||||
|       `sketch001 = startSketchOn(XZ)profile001 = circle(sketch001, center = [14.44, -2.44], radius = 1)` | ||||
|       `sketch001 = startSketchOn(XZ)profile001 = circle(sketch001, center = [366.89, -62.01], radius = 1)` | ||||
|     ) | ||||
|   } | ||||
| ) | ||||
| @ -667,7 +668,7 @@ test.describe( | ||||
|  | ||||
|       const startXPx = 600 | ||||
|       await page.mouse.click(startXPx + PUR * 10, 500 - PUR * 10) | ||||
|       code += `profile001 = startProfileAt([7.19, -9.7], sketch001)` | ||||
|       code += `profile001 = startProfileAt([182.59, -246.32], sketch001)` | ||||
|       await expect(u.codeLocator).toHaveText(code) | ||||
|       await page.waitForTimeout(100) | ||||
|  | ||||
| @ -675,7 +676,7 @@ test.describe( | ||||
|       await page.waitForTimeout(100) | ||||
|  | ||||
|       code += ` | ||||
|   |> xLine(length = 7.25)` | ||||
|   |> xLine(length = 184.3)` | ||||
|       await expect(u.codeLocator).toHaveText(code) | ||||
|  | ||||
|       await page | ||||
| @ -690,7 +691,7 @@ test.describe( | ||||
|       await page.mouse.click(startXPx + PUR * 30, 500 - PUR * 20) | ||||
|  | ||||
|       code += ` | ||||
|   |> tangentialArcTo([21.7, -2.44], %)` | ||||
|   |> tangentialArcTo([551.2, -62.01], %)` | ||||
|       await expect(u.codeLocator).toHaveText(code) | ||||
|  | ||||
|       // click tangential arc tool again to unequip it | ||||
|  | ||||
| Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 58 KiB | 
| Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 52 KiB | 
| Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 59 KiB | 
| Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 52 KiB | 
| Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 52 KiB | 
| Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 50 KiB | 
| Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 46 KiB | 
| Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 49 KiB | 
| Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 55 KiB | 
| Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 60 KiB | 
| Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 65 KiB | 
| Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 78 KiB | 
| Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 50 KiB | 
| Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 60 KiB | 
| Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 140 KiB | 
| Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 124 KiB | 
| Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 68 KiB | 
| Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 71 KiB | 
| Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 67 KiB | 
| Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 70 KiB | 
| Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 70 KiB | 
| Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 66 KiB | 
| @ -29,5 +29,5 @@ | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
|   "kcl_version": "0.2.54" | ||||
|   "kcl_version": "0.2.57" | ||||
| } | ||||
| @ -1,8 +1,9 @@ | ||||
| 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' | ||||
|  | ||||
|  | ||||
| @ -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, '') | ||||
|  | ||||
| @ -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 clickOnFirstSegmentLabel() | ||||
|         await cmdBar.progressCmdBar() | ||||
|         await editor.expectEditor.toContain('length001 = 15.3') | ||||
|         await editor.expectEditor.toContain('|> angledLine([9, length001], %)') | ||||
|       }) | ||||
|         await cmdBarSubmitButton.click() | ||||
|         await expect(page.locator('.cm-content')).toContainText( | ||||
|           'length001 = 15.3' | ||||
|         ) | ||||
|         await expect(page.locator('.cm-content')).toContainText( | ||||
|           '|> 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 ({ | ||||
|  | ||||
| @ -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
									
									
								
							
							
						
						| @ -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
									
									
								
							
							
						
						| @ -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' { | ||||
|  | ||||
							
								
								
									
										1
									
								
								known-circular.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1 @@ | ||||
| $ dpdm --no-warning --no-tree -T --skip-dynamic-imports=circular src/index.tsx• Circular Dependencies  01) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/modifyAst/addEdgeTreatment.ts  02) src/lang/std/sketch.ts -> src/lang/modifyAst.ts  03) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/std/sketchcombos.ts  04) src/clientSideScene/CameraControls.ts -> src/clientSideScene/sceneInfra.ts  05) src/lib/singletons.ts -> src/editor/manager.ts -> src/lib/selections.ts  06) src/lib/singletons.ts -> src/editor/manager.ts  07) src/lib/singletons.ts -> src/lang/KclSingleton.ts  08) src/lib/singletons.ts -> src/lang/codeManager.ts  09) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/components/Toolbar/angleLengthInfo.ts  10) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/LspProvider.tsx -> src/editor/plugins/lsp/copilot/index.ts  11) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/LspProvider.tsx -> src/editor/plugins/lsp/kcl/language.ts -> src/editor/plugins/lsp/kcl/index.ts  12) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/LspProvider.tsx  13) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/LspProvider.tsx  14) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/Settings/SettingsFieldInput.tsx  15) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx  16) src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx  17) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/SettingsSearchBar.tsx  18) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/SettingsSectionsList.tsx  19) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts  20) src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts  21) src/hooks/useModelingContext.ts -> src/components/ModelingMachineProvider.tsx -> src/components/Toolbar/Intersect.tsx -> src/components/SetHorVertDistanceModal.tsx -> src/lib/useCalculateKclExpression.ts  22) src/components/ToastTextToCad.tsx -> src/lib/textToCad.ts  23) src/hooks/useModelingContext.ts -> src/components/ModelingMachineProvider.tsx -> src/machines/modelingMachine.ts -> src/clientSideScene/ClientSideSceneComp.tsx  24) src/routes/Onboarding/index.tsx -> src/routes/Onboarding/Camera.tsx -> src/routes/Onboarding/utils.tsx | ||||
							
								
								
									
										36
									
								
								package.json
									
									
									
									
									
								
							
							
						
						| @ -88,24 +88,26 @@ | ||||
|     "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:wasm:windows": "powershell -ExecutionPolicy Bypass -File ./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", | ||||
|     "build:wasm": "./scripts/build-wasm.sh", | ||||
|     "build:wasm:windows": "./scripts/build-wasm.ps1", | ||||
|     "build:wasm:windows": "powershell -ExecutionPolicy Bypass -File ./scripts/build-wasm.ps1", | ||||
|     "build:wasm-dev": "yarn build:wasm:dev", | ||||
|     "build:wasm:dev": "./scripts/build-wasm-dev.sh", | ||||
|     "build:wasm:dev:windows": "./scripts/build-wasm-dev.ps1", | ||||
|     "build:wasm:dev:windows": "powershell -ExecutionPolicy Bypass -File ./scripts/build-wasm-dev.ps1", | ||||
|     "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", | ||||
|     "circular-deps:diff": "./scripts/diff-circular-deps.sh", | ||||
|     "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", | ||||
|     "files:flip-to-nightly:windows": "./scripts/flip-files-to-nightly.ps1", | ||||
|     "files:flip-to-nightly:windows": "powershell -ExecutionPolicy Bypass -File ./scripts/flip-files-to-nightly.ps1", | ||||
|     "files:invalidate-bucket": "./scripts/invalidate-files-bucket.sh", | ||||
|     "files:invalidate-bucket:nightly": "./scripts/invalidate-files-bucket.sh --nightly", | ||||
|     "postinstall": "yarn --cwd ./rust/kcl-language-server --modules-folder node_modules install && ./node_modules/.bin/electron-rebuild", | ||||
| @ -139,7 +141,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 +182,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 +203,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 +225,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
									
								
							
							
						
						| @ -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
									
								
							
							
						
						| @ -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 | ||||
|  | ||||
|  | ||||
