Compare commits
47 Commits
Author | SHA1 | Date | |
---|---|---|---|
440eb2636a | |||
344e72d7ec | |||
ec7b733a0d | |||
63159c1cb8 | |||
df62a995b5 | |||
fa762c1c4d | |||
82b03a9d47 | |||
793b7407f6 | |||
040bcc2c09 | |||
ae2e219394 | |||
a83f549257 | |||
3871d2858f | |||
3effb87f8e | |||
3f2f035a9b | |||
4735eaef8c | |||
69f8da058a | |||
93ebf13621 | |||
20c4d44b8b | |||
8ea8f80e32 | |||
d73339fd8d | |||
031b230690 | |||
1125d74f12 | |||
5c7a2822d0 | |||
d44b1f8e54 | |||
c4ca69496b | |||
f06de7f586 | |||
75c6ae6e66 | |||
48639d70db | |||
c565d9670d | |||
7bf5953299 | |||
a9ab35e55f | |||
15418e98b0 | |||
20838bf618 | |||
acd52ab350 | |||
75b9d2913f | |||
d92e6f6453 | |||
c1a879837e | |||
daacca500c | |||
c1e8bb5288 | |||
8ca4166b08 | |||
4624f1c0ba | |||
7ac6a3a4f2 | |||
3cbf2b194a | |||
44f06aa199 | |||
1b878865b8 | |||
3b840e9a80 | |||
4a0811eec8 |
17
README.md
@ -59,7 +59,9 @@ followed by:
|
||||
```
|
||||
yarn build:wasm-dev
|
||||
```
|
||||
|
||||
or if you have the gh cli installed
|
||||
|
||||
```
|
||||
./get-latest-wasm-bundle.sh # this will download the latest main wasm bundle
|
||||
```
|
||||
@ -100,6 +102,7 @@ yarn test
|
||||
Which will run our suite of [Vitest unit](https://vitest.dev/) and [React Testing Library E2E](https://testing-library.com/docs/react-testing-library/intro/) tests, in interactive mode by default.
|
||||
|
||||
For running the rust (not tauri rust though) only, you can
|
||||
|
||||
```bash
|
||||
cd src/wasm-lib
|
||||
cargo test
|
||||
@ -162,6 +165,7 @@ console.log(
|
||||
- `)
|
||||
)
|
||||
```
|
||||
|
||||
grab the md list and delete any that are older than the last bump
|
||||
|
||||
2. Merge the PR
|
||||
@ -191,23 +195,26 @@ $ cargo +nightly fuzz run parser
|
||||
For more information on fuzzing you can check out
|
||||
[this guide](https://rust-fuzz.github.io/book/cargo-fuzz.html).
|
||||
|
||||
|
||||
### Playwright
|
||||
|
||||
First time running plawright locally, you'll need to add the secrets file
|
||||
|
||||
```bash
|
||||
touch ./e2e/playwright/playwright-secrets.env
|
||||
printf 'token="your-token"\nsnapshottoken="your-snapshot-token"' > ./e2e/playwright/playwright-secrets.env
|
||||
```
|
||||
|
||||
then replace "your-token" with a dev token from dev.zoo.dev/account/api-tokens
|
||||
|
||||
then:
|
||||
run playwright
|
||||
|
||||
```
|
||||
yarn playwright test
|
||||
```
|
||||
|
||||
run a specific test suite
|
||||
|
||||
```
|
||||
yarn playwright test src/e2e-tests/example.spec.ts
|
||||
```
|
||||
@ -216,14 +223,17 @@ run a specific test change the test from `test('...` to `test.only('...`
|
||||
(note if you commit this, the tests will instantly fail without running any of the tests)
|
||||
|
||||
run headed
|
||||
|
||||
```
|
||||
yarn playwright test --headed
|
||||
```
|
||||
|
||||
run with step through debugger
|
||||
|
||||
```
|
||||
PWDEBUG=1 yarn playwright test
|
||||
```
|
||||
|
||||
However, if you want a debugger I recommend using VSCode and the `playwright` extension, as the above command is a cruder debugger that steps into every function call which is annoying.
|
||||
With the extension you can set a breakpoint after `waitForDefaultPlanesVisibilityChange` in order to skip app loading, then the vscode debugger's "step over" is much better for being able to stay at the right level of abstraction as you debug the code.
|
||||
|
||||
@ -268,7 +278,6 @@ Where `./store` should look like this
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
However because much of our tests involve clicking in the stream at specific locations, it's code-gen looks `await page.locator('video').click();` when really we need to use a pixel coord, so I think it's of limited use.
|
||||
|
||||
#### Some notes on CI
|
||||
@ -299,3 +308,7 @@ PS: for the debug panel, the following JSON is useful for snapping the camera
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## KCL
|
||||
|
||||
For how to contribute to KCL, [see our KCL README](https://github.com/KittyCAD/modeling-app/tree/main/src/wasm-lib/kcl).
|
||||
|
@ -56,6 +56,9 @@ layout: manual
|
||||
* [`patternLinear3d`](kcl/patternLinear3d)
|
||||
* [`pi`](kcl/pi)
|
||||
* [`pow`](kcl/pow)
|
||||
* [`profileStart`](kcl/profileStart)
|
||||
* [`profileStartX`](kcl/profileStartX)
|
||||
* [`profileStartY`](kcl/profileStartY)
|
||||
* [`revolve`](kcl/revolve)
|
||||
* [`segAng`](kcl/segAng)
|
||||
* [`segEndX`](kcl/segEndX)
|
||||
|
206
docs/kcl/profileStart.md
Normal file
201
docs/kcl/profileStartX.md
Normal file
200
docs/kcl/profileStartY.md
Normal file
2987
docs/kcl/std.json
@ -13,6 +13,7 @@ import {
|
||||
} from './storageStates'
|
||||
import * as TOML from '@iarna/toml'
|
||||
import { Coords2d } from 'lang/std/sketch'
|
||||
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
|
||||
|
||||
/*
|
||||
debug helper: unfortunately we do rely on exact coord mouse clicks in a few places
|
||||
@ -347,6 +348,15 @@ test('if you use the format keyboard binding it formats your code', async ({
|
||||
|> close(%)`)
|
||||
})
|
||||
|
||||
test('ensure the Zoo logo is not a link in browser app', async ({ page }) => {
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.goto('/')
|
||||
|
||||
const zooLogo = page.locator('[data-testid="app-logo"]')
|
||||
// Make sure it's not a link
|
||||
await expect(zooLogo).not.toHaveAttribute('href')
|
||||
})
|
||||
|
||||
test('if you write invalid kcl you get inlined errors', async ({ page }) => {
|
||||
const u = getUtils(page)
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
@ -414,6 +424,80 @@ test('if you write invalid kcl you get inlined errors', async ({ page }) => {
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
})
|
||||
|
||||
test('error with 2 source ranges gets 2 diagnostics', async ({ page }) => {
|
||||
const u = getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`const length = .750
|
||||
const width = 0.500
|
||||
const height = 0.500
|
||||
const dia = 4
|
||||
|
||||
fn squareHole = (l, w) => {
|
||||
const squareHoleSketch = startSketchOn('XY')
|
||||
|> startProfileAt([-width / 2, -length / 2], %)
|
||||
|> lineTo([width / 2, -length / 2], %)
|
||||
|> lineTo([width / 2, length / 2], %)
|
||||
|> lineTo([-width / 2, length / 2], %)
|
||||
|> close(%)
|
||||
return squareHoleSketch
|
||||
}
|
||||
`
|
||||
)
|
||||
})
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.goto('/')
|
||||
const lspStartPromise = page.waitForEvent('console', async (message) => {
|
||||
// it would be better to wait for a message that the kcl lsp has started by looking for the message message.text().includes('[lsp] [window/logMessage]')
|
||||
// but that doesn't seem to make it to the console for macos/safari :(
|
||||
if (message.text().includes('start kcl lsp')) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 200))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
await page.goto('/')
|
||||
await u.waitForAuthSkipAppStart()
|
||||
await lspStartPromise
|
||||
|
||||
await u.openDebugPanel()
|
||||
await u.expectCmdLog('[data-message-type="execution-done"]')
|
||||
await u.closeDebugPanel()
|
||||
|
||||
// check no error to begin with
|
||||
await expect(page.locator('.cm-lint-marker-error')).not.toBeVisible()
|
||||
|
||||
// Click on the bottom of the code editor to add a new line
|
||||
await page.click('.cm-content')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('Enter')
|
||||
await page.keyboard.type(`const extrusion = startSketchOn('XY')
|
||||
|> circle([0, 0], dia/2, %)
|
||||
|> hole(squareHole(length, width, height), %)
|
||||
|> extrude(height, %)`)
|
||||
|
||||
// error in gutter
|
||||
await expect(page.locator('.cm-lint-marker-error').first()).toBeVisible()
|
||||
await page.hover('.cm-lint-marker-error:first-child')
|
||||
await expect(page.getByText('Expected 2 arguments, got 3')).toBeVisible()
|
||||
|
||||
// Make sure there are two diagnostics
|
||||
await expect(page.locator('.cm-lint-marker-error')).toHaveCount(2)
|
||||
})
|
||||
|
||||
test('if your kcl gets an error from the engine it is inlined', async ({
|
||||
page,
|
||||
}) => {
|
||||
@ -636,8 +720,8 @@ test('Auto complete works', async ({ page }) => {
|
||||
await page.click('.cm-content')
|
||||
await page.keyboard.type('const part001 = start')
|
||||
|
||||
// expect there to be three auto complete options
|
||||
await expect(page.locator('.cm-completionLabel')).toHaveCount(3)
|
||||
// expect there to be six auto complete options
|
||||
await expect(page.locator('.cm-completionLabel')).toHaveCount(6)
|
||||
await page.getByText('startSketchOn').click()
|
||||
await page.keyboard.type("'XZ'")
|
||||
await page.keyboard.press('Tab')
|
||||
@ -765,6 +849,130 @@ test('Project settings can be set and override user settings', async ({
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
})
|
||||
|
||||
test('Project settings can be opened with keybinding from the editor', async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.goto('/', { waitUntil: 'domcontentloaded' })
|
||||
await page
|
||||
.getByRole('button', { name: 'Start Sketch' })
|
||||
.waitFor({ state: 'visible' })
|
||||
|
||||
// Put the cursor in the editor
|
||||
await page.click('.cm-content')
|
||||
|
||||
// Open the settings modal with the browser keyboard shortcut
|
||||
await page.keyboard.press('Meta+Shift+,')
|
||||
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'Settings', exact: true })
|
||||
).toBeVisible()
|
||||
await page
|
||||
.locator('select[name="app-theme"]')
|
||||
.selectOption({ value: 'light' })
|
||||
|
||||
// Verify the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "light" for this project`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
|
||||
// Check that the user setting was not changed
|
||||
await page.getByRole('radio', { name: 'User' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('dark')
|
||||
|
||||
// Roll back to default "system" theme
|
||||
await page
|
||||
.getByText(
|
||||
'themeRoll back themeRoll back to match defaultThe overall appearance of the appl'
|
||||
)
|
||||
.hover()
|
||||
await page
|
||||
.getByRole('button', {
|
||||
name: 'Roll back theme ; Has tooltip: Roll back to match default',
|
||||
})
|
||||
.click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
|
||||
// Check that the project setting did not change
|
||||
await page.getByRole('radio', { name: 'Project' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
})
|
||||
|
||||
test('Project and user settings can be reset', async ({ page }) => {
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.goto('/', { waitUntil: 'domcontentloaded' })
|
||||
await page
|
||||
.getByRole('button', { name: 'Start Sketch' })
|
||||
.waitFor({ state: 'visible' })
|
||||
|
||||
// Put the cursor in the editor
|
||||
await page.click('.cm-content')
|
||||
|
||||
// Open the settings modal with the browser keyboard shortcut
|
||||
await page.keyboard.press('Meta+Shift+,')
|
||||
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'Settings', exact: true })
|
||||
).toBeVisible()
|
||||
|
||||
// Click the reset settings button.
|
||||
await page.getByRole('button', { name: 'Restore default settings' }).click()
|
||||
|
||||
await page
|
||||
.locator('select[name="app-theme"]')
|
||||
.selectOption({ value: 'light' })
|
||||
|
||||
// Verify the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "light" for this project`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
|
||||
// Check that the user setting was not changed
|
||||
await page.getByRole('radio', { name: 'User' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
|
||||
// Click the reset settings button.
|
||||
await page.getByRole('button', { name: 'Restore default settings' }).click()
|
||||
|
||||
// Verify it is now set to the default value
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
|
||||
// Set the user theme to light.
|
||||
await page
|
||||
.locator('select[name="app-theme"]')
|
||||
.selectOption({ value: 'light' })
|
||||
|
||||
// Verify the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "light" as a user default`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
|
||||
await page.getByRole('radio', { name: 'Project' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
|
||||
|
||||
// Click the reset settings button.
|
||||
await page.getByRole('button', { name: 'Restore default settings' }).click()
|
||||
// Verify it is now set to the default value
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
|
||||
await page.getByRole('radio', { name: 'User' }).click()
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
|
||||
// Click the reset settings button.
|
||||
await page.getByRole('button', { name: 'Restore default settings' }).click()
|
||||
|
||||
// Verify it is now set to the default value
|
||||
await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
|
||||
})
|
||||
|
||||
test('Click through each onboarding step', async ({ page }) => {
|
||||
const u = getUtils(page)
|
||||
|
||||
@ -1082,6 +1290,51 @@ test.describe('Command bar tests', () => {
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
})
|
||||
|
||||
test('Command bar keybinding works from code editor and can change a setting', async ({
|
||||
page,
|
||||
}) => {
|
||||
// Brief boilerplate
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.goto('/', { waitUntil: 'domcontentloaded' })
|
||||
|
||||
let cmdSearchBar = page.getByPlaceholder('Search commands')
|
||||
|
||||
// Put the cursor in the code editor
|
||||
await page.click('.cm-content')
|
||||
|
||||
// Now try the same, but with the keyboard shortcut, check focus
|
||||
await page.keyboard.press('Meta+K')
|
||||
await expect(cmdSearchBar).toBeVisible()
|
||||
await expect(cmdSearchBar).toBeFocused()
|
||||
|
||||
// Try typing in the command bar
|
||||
await page.keyboard.type('theme')
|
||||
const themeOption = page.getByRole('option', {
|
||||
name: 'Settings · app · theme',
|
||||
})
|
||||
await expect(themeOption).toBeVisible()
|
||||
await themeOption.click()
|
||||
const themeInput = page.getByPlaceholder('Select an option')
|
||||
await expect(themeInput).toBeVisible()
|
||||
await expect(themeInput).toBeFocused()
|
||||
// Select dark theme
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await page.keyboard.press('ArrowDown')
|
||||
await expect(page.getByRole('option', { name: 'system' })).toHaveAttribute(
|
||||
'data-headlessui-state',
|
||||
'active'
|
||||
)
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
// Check the toast appeared
|
||||
await expect(
|
||||
page.getByText(`Set theme to "system" for this project`)
|
||||
).toBeVisible()
|
||||
// Check that the theme changed
|
||||
await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
|
||||
})
|
||||
|
||||
test('Can extrude from the command bar', async ({ page }) => {
|
||||
await page.addInitScript(async () => {
|
||||
localStorage.setItem(
|
||||
@ -1145,7 +1398,7 @@ test.describe('Command bar tests', () => {
|
||||
|
||||
// Assert we're back on the distance step
|
||||
await expect(
|
||||
page.getByRole('button', { name: 'Distance 12', exact: false })
|
||||
page.getByRole('button', { name: 'Distance 5', exact: false })
|
||||
).toBeDisabled()
|
||||
|
||||
await continueButton.click()
|
||||
@ -1156,7 +1409,7 @@ test.describe('Command bar tests', () => {
|
||||
// Unfortunately this indentation seems to matter for the test
|
||||
await expect(page.locator('.cm-content')).toHaveText(
|
||||
`const distance = sqrt(20)
|
||||
const distance001 = 5 + 7
|
||||
const distance001 = ${KCL_DEFAULT_LENGTH}
|
||||
const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([-6.95, 10.98], %)
|
||||
|> line([25.1, 0.41], %)
|
||||
@ -1353,7 +1606,7 @@ test('ProgramMemory can be serialised', async ({ page }) => {
|
||||
|
||||
test('Hovering over 3d features highlights code', async ({ page }) => {
|
||||
const u = getUtils(page)
|
||||
await page.addInitScript(async () => {
|
||||
await page.addInitScript(async (KCL_DEFAULT_LENGTH) => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`const part001 = startSketchOn('-XZ')
|
||||
@ -1378,7 +1631,7 @@ test('Hovering over 3d features highlights code', async ({ page }) => {
|
||||
|> extrude(5 + 7, %)
|
||||
`
|
||||
)
|
||||
})
|
||||
}, KCL_DEFAULT_LENGTH)
|
||||
await page.setViewportSize({ width: 1000, height: 500 })
|
||||
await page.goto('/')
|
||||
await u.waitForAuthSkipAppStart()
|
||||
@ -1957,6 +2210,6 @@ test('Extrude from command bar selects extrude line after', async ({
|
||||
await page.keyboard.press('Enter')
|
||||
await page.waitForTimeout(100)
|
||||
await expect(page.locator('.cm-activeLine')).toHaveText(
|
||||
` |> extrude(5 + 7, %)`
|
||||
` |> extrude(${KCL_DEFAULT_LENGTH}, %)`
|
||||
)
|
||||
})
|
||||
|
@ -4,7 +4,7 @@ import { getUtils } from './test-utils'
|
||||
import { Models } from '@kittycad/lib'
|
||||
import fsp from 'fs/promises'
|
||||
import { spawn } from 'child_process'
|
||||
import { APP_NAME } from 'lib/constants'
|
||||
import { APP_NAME, KCL_DEFAULT_LENGTH } from 'lib/constants'
|
||||
import JSZip from 'jszip'
|
||||
import path from 'path'
|
||||
import { TEST_SETTINGS, TEST_SETTINGS_KEY } from './storageStates'
|
||||
@ -273,6 +273,8 @@ const part001 = startSketchOn('-XZ')
|
||||
for (let { modelPath, imagePath, outputType } of exportLocations) {
|
||||
// May change depending on the file being dealt with
|
||||
let cliCommand = `export ZOO_TOKEN=${secrets.snapshottoken} && zoo file snapshot --output-format=png --src-format=${outputType} ${modelPath} ${imagePath}`
|
||||
const fileSize = (await fsp.stat(modelPath)).size
|
||||
console.log(`Size of the file at ${modelPath}: ${fileSize} bytes`)
|
||||
|
||||
const parentPath = path.dirname(modelPath)
|
||||
|
||||
@ -718,7 +720,7 @@ test.describe('Client side scene scale should match engine scale', () => {
|
||||
|
||||
test('Sketch on face with none z-up', async ({ page, context }) => {
|
||||
const u = getUtils(page)
|
||||
await context.addInitScript(async () => {
|
||||
await context.addInitScript(async (KCL_DEFAULT_LENGTH) => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`const part001 = startSketchOn('-XZ')
|
||||
@ -726,16 +728,16 @@ test('Sketch on face with none z-up', async ({ page, context }) => {
|
||||
|> line([9.31, 10.55], %, 'seg01')
|
||||
|> line([11.91, -10.42], %)
|
||||
|> close(%)
|
||||
|> extrude(5 + 7, %)
|
||||
|> extrude(${KCL_DEFAULT_LENGTH}, %)
|
||||
const part002 = startSketchOn(part001, 'seg01')
|
||||
|> startProfileAt([8, 8], %)
|
||||
|> line([4.68, 3.05], %)
|
||||
|> line([0, -7.79], %, 'seg02')
|
||||
|> close(%)
|
||||
|> extrude(5 + 7, %)
|
||||
|> extrude(${KCL_DEFAULT_LENGTH}, %)
|
||||
`
|
||||
)
|
||||
})
|
||||
}, KCL_DEFAULT_LENGTH)
|
||||
|
||||
await page.setViewportSize({ width: 1200, height: 500 })
|
||||
await page.goto('/')
|
||||
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 47 KiB |
12
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "untitled-app",
|
||||
"version": "0.21.3",
|
||||
"version": "0.21.6",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.16.0",
|
||||
@ -17,12 +17,12 @@
|
||||
"@replit/codemirror-interact": "^6.3.1",
|
||||
"@tauri-apps/api": "2.0.0-beta.8",
|
||||
"@tauri-apps/plugin-dialog": "^2.0.0-beta.2",
|
||||
"@tauri-apps/plugin-fs": "^2.0.0-beta.2",
|
||||
"@tauri-apps/plugin-fs": "^2.0.0-beta.3",
|
||||
"@tauri-apps/plugin-http": "^2.0.0-beta.2",
|
||||
"@tauri-apps/plugin-os": "^2.0.0-beta.2",
|
||||
"@tauri-apps/plugin-process": "^2.0.0-beta.2",
|
||||
"@tauri-apps/plugin-shell": "^2.0.0-beta.2",
|
||||
"@tauri-apps/plugin-updater": "^2.0.0-beta.2",
|
||||
"@tauri-apps/plugin-updater": "^2.0.0-beta.3",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^15.0.2",
|
||||
"@testing-library/user-event": "^14.5.2",
|
||||
@ -52,15 +52,15 @@
|
||||
"react-json-view": "^1.21.3",
|
||||
"react-modal": "^3.16.1",
|
||||
"react-modal-promise": "^1.0.2",
|
||||
"react-router-dom": "^6.22.3",
|
||||
"react-router-dom": "^6.23.1",
|
||||
"sketch-helpers": "^0.0.4",
|
||||
"swr": "^2.2.5",
|
||||
"three": "^0.163.0",
|
||||
"three": "^0.164.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.4.5",
|
||||
"ua-parser-js": "^1.0.37",
|
||||
"uuid": "^9.0.1",
|
||||
"vitest": "^1.5.0",
|
||||
"vitest": "^1.6.0",
|
||||
"vscode-jsonrpc": "^8.1.0",
|
||||
"vscode-languageserver-protocol": "^3.17.5",
|
||||
"wasm-pack": "^0.12.1",
|
||||
|
207
src-tauri/Cargo.lock
generated
@ -169,9 +169,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.83"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3"
|
||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
]
|
||||
@ -199,7 +199,7 @@ dependencies = [
|
||||
"tauri-plugin-shell",
|
||||
"tauri-plugin-updater",
|
||||
"tokio",
|
||||
"toml 0.8.12",
|
||||
"toml 0.8.13",
|
||||
"url",
|
||||
]
|
||||
|
||||
@ -212,6 +212,15 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
|
||||
dependencies = [
|
||||
"derive_arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.4"
|
||||
@ -334,7 +343,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -369,7 +378,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -415,7 +424,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -564,7 +573,7 @@ dependencies = [
|
||||
"proc-macro-crate 3.1.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
"syn_derive",
|
||||
]
|
||||
|
||||
@ -756,7 +765,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a969e13a7589e9e3e4207e153bae624ade2b5622fb4684a4923b23ec3d57719"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"toml 0.8.12",
|
||||
"toml 0.8.13",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -873,7 +882,7 @@ dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1075,7 +1084,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1085,7 +1094,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1109,7 +1118,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim 0.10.0",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1120,7 +1129,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1167,7 +1176,7 @@ checksum = "377af281d8f23663862a7c84623bc5dcf7f8c44b13c7496a590bdc157f941a43"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
@ -1204,7 +1213,18 @@ dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_tokenstream",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_arbitrary"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1258,6 +1278,17 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
|
||||
|
||||
[[package]]
|
||||
name = "displaydoc"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dlib"
|
||||
version = "0.5.2"
|
||||
@ -1287,7 +1318,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1341,7 +1372,7 @@ dependencies = [
|
||||
"cc",
|
||||
"memchr",
|
||||
"rustc_version",
|
||||
"toml 0.8.12",
|
||||
"toml 0.8.13",
|
||||
"vswhom",
|
||||
"winreg 0.52.0",
|
||||
]
|
||||
@ -1385,7 +1416,7 @@ checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1536,7 +1567,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1652,7 +1683,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1928,7 +1959,7 @@ dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1956,7 +1987,7 @@ dependencies = [
|
||||
"inflections",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2031,7 +2062,7 @@ dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2569,7 +2600,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-tungstenite",
|
||||
"toml 0.8.12",
|
||||
"toml 0.8.13",
|
||||
"tower-lsp",
|
||||
"ts-rs",
|
||||
"url",
|
||||
@ -2579,7 +2610,7 @@ dependencies = [
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"winnow 0.5.40",
|
||||
"zip",
|
||||
"zip 1.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2640,7 +2671,7 @@ checksum = "0611fc9b9786175da21d895ffa0f65039e19c9111e94a41b7af999e3b95f045f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3362,7 +3393,7 @@ dependencies = [
|
||||
"regex",
|
||||
"regex-syntax 0.7.5",
|
||||
"structmeta 0.2.0",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3376,7 +3407,7 @@ dependencies = [
|
||||
"regex",
|
||||
"regex-syntax 0.8.3",
|
||||
"structmeta 0.3.0",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3518,7 +3549,7 @@ dependencies = [
|
||||
"phf_shared 0.11.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3586,7 +3617,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4424,7 +4455,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_derive_internals",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4509,9 +4540,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.201"
|
||||
version = "1.0.202"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c"
|
||||
checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@ -4527,13 +4558,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.201"
|
||||
version = "1.0.202"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865"
|
||||
checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4544,7 +4575,7 @@ checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4577,14 +4608,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.5"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
|
||||
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@ -4598,7 +4629,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4640,7 +4671,7 @@ dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4908,7 +4939,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"structmeta-derive 0.2.0",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4920,7 +4951,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"structmeta-derive 0.3.0",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4931,7 +4962,7 @@ checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4942,7 +4973,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4964,7 +4995,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4997,9 +5028,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.63"
|
||||
version = "2.0.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704"
|
||||
checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -5015,7 +5046,7 @@ dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5032,7 +5063,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5074,7 +5105,7 @@ dependencies = [
|
||||
"cfg-expr",
|
||||
"heck 0.5.0",
|
||||
"pkg-config",
|
||||
"toml 0.8.12",
|
||||
"toml 0.8.13",
|
||||
"version-compare",
|
||||
]
|
||||
|
||||
@ -5227,7 +5258,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"tauri-utils",
|
||||
"tauri-winres",
|
||||
"toml 0.8.12",
|
||||
"toml 0.8.13",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
@ -5249,7 +5280,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
"tauri-utils",
|
||||
"thiserror",
|
||||
"time",
|
||||
@ -5267,7 +5298,7 @@ dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
"tauri-codegen",
|
||||
"tauri-utils",
|
||||
]
|
||||
@ -5285,7 +5316,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri-utils",
|
||||
"toml 0.8.12",
|
||||
"toml 0.8.13",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
@ -5471,7 +5502,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"url",
|
||||
"windows-sys 0.52.0",
|
||||
"zip",
|
||||
"zip 0.6.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5546,7 +5577,7 @@ dependencies = [
|
||||
"serde_with",
|
||||
"swift-rs",
|
||||
"thiserror",
|
||||
"toml 0.8.12",
|
||||
"toml 0.8.13",
|
||||
"url",
|
||||
"urlpattern",
|
||||
"walkdir",
|
||||
@ -5602,22 +5633,22 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.60"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18"
|
||||
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.60"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524"
|
||||
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5706,7 +5737,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5774,21 +5805,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.12"
|
||||
version = "0.8.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
|
||||
checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit 0.22.12",
|
||||
"toml_edit 0.22.13",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.5"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@ -5830,9 +5861,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.12"
|
||||
version = "0.22.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef"
|
||||
checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c"
|
||||
dependencies = [
|
||||
"indexmap 2.2.6",
|
||||
"serde",
|
||||
@ -5895,7 +5926,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5924,7 +5955,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -6048,7 +6079,7 @@ dependencies = [
|
||||
"Inflector",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
@ -6261,7 +6292,7 @@ dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -6360,7 +6391,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -6394,7 +6425,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@ -6535,7 +6566,7 @@ checksum = "ac1345798ecd8122468840bcdf1b95e5dc6d2206c5e4b0eafa078d061f59c9bc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -6641,7 +6672,7 @@ checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -6652,7 +6683,7 @@ checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -7094,7 +7125,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -7123,6 +7154,20 @@ dependencies = [
|
||||
"zstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1f4a27345eb6f7aa7bd015ba7eb4175fa4e1b462a29874b779e0bbcf96c6ac7"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"crc32fast",
|
||||
"crossbeam-utils",
|
||||
"displaydoc",
|
||||
"indexmap 2.2.6",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.11.2+zstd.1.5.2"
|
||||
|
@ -121,11 +121,8 @@ async fn write_app_settings_file(app: tauri::AppHandle, configuration: Configura
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_project_settings_file_path(
|
||||
app_settings: Configuration,
|
||||
project_name: &str,
|
||||
) -> Result<PathBuf, InvokeError> {
|
||||
let project_dir = app_settings.settings.project.directory.join(project_name);
|
||||
async fn get_project_settings_file_path(project_path: &str) -> Result<PathBuf, InvokeError> {
|
||||
let project_dir = std::path::Path::new(project_path);
|
||||
|
||||
if !project_dir.exists() {
|
||||
tokio::fs::create_dir_all(&project_dir)
|
||||
@ -137,11 +134,8 @@ async fn get_project_settings_file_path(
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn read_project_settings_file(
|
||||
app_settings: Configuration,
|
||||
project_name: &str,
|
||||
) -> Result<ProjectConfiguration, InvokeError> {
|
||||
let settings_path = get_project_settings_file_path(app_settings, project_name).await?;
|
||||
async fn read_project_settings_file(project_path: &str) -> Result<ProjectConfiguration, InvokeError> {
|
||||
let settings_path = get_project_settings_file_path(project_path).await?;
|
||||
|
||||
// Check if this file exists.
|
||||
if !settings_path.exists() {
|
||||
@ -159,11 +153,10 @@ async fn read_project_settings_file(
|
||||
|
||||
#[tauri::command]
|
||||
async fn write_project_settings_file(
|
||||
app_settings: Configuration,
|
||||
project_name: &str,
|
||||
project_path: &str,
|
||||
configuration: ProjectConfiguration,
|
||||
) -> Result<(), InvokeError> {
|
||||
let settings_path = get_project_settings_file_path(app_settings, project_name).await?;
|
||||
let settings_path = get_project_settings_file_path(project_path).await?;
|
||||
let contents = toml::to_string_pretty(&configuration).map_err(|e| InvokeError::from_anyhow(e.into()))?;
|
||||
tokio::fs::write(settings_path, contents.as_bytes())
|
||||
.await
|
||||
|
@ -74,5 +74,5 @@
|
||||
}
|
||||
},
|
||||
"productName": "Zoo Modeling App",
|
||||
"version": "0.21.3"
|
||||
"version": "0.21.6"
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import { useRefreshSettings } from 'hooks/useRefreshSettings'
|
||||
import { ModelingSidebar } from 'components/ModelingSidebar/ModelingSidebar'
|
||||
import { LowerRightControls } from 'components/LowerRightControls'
|
||||
import ModalContainer from 'react-modal-promise'
|
||||
import useHotkeyWrapper from 'lib/hotkeyWrapper'
|
||||
|
||||
export function App() {
|
||||
useRefreshSettings(paths.FILE + 'SETTINGS')
|
||||
@ -63,8 +64,8 @@ export function App() {
|
||||
useHotkeys('backspace', (e) => {
|
||||
e.preventDefault()
|
||||
})
|
||||
useHotkeys(
|
||||
isTauri() ? 'mod + ,' : 'shift + mod + ,',
|
||||
useHotkeyWrapper(
|
||||
[isTauri() ? 'mod + ,' : 'shift + mod + ,'],
|
||||
() => navigate(filePath + paths.SETTINGS),
|
||||
{
|
||||
splitKey: '|',
|
||||
|
@ -34,7 +34,7 @@ export const AppHeader = ({
|
||||
}
|
||||
>
|
||||
<ProjectSidebarMenu
|
||||
renderAsLink={!enableMenu}
|
||||
enableMenu={enableMenu}
|
||||
project={project?.project}
|
||||
file={project?.file}
|
||||
/>
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Dialog, Popover, Transition } from '@headlessui/react'
|
||||
import { Fragment, useEffect } from 'react'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
import { useCommandsContext } from 'hooks/useCommandsContext'
|
||||
import CommandBarArgument from './CommandBarArgument'
|
||||
import CommandComboBox from '../CommandComboBox'
|
||||
import CommandBarReview from './CommandBarReview'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import useHotkeyWrapper from 'lib/hotkeyWrapper'
|
||||
|
||||
export const CommandBar = () => {
|
||||
const { pathname } = useLocation()
|
||||
@ -22,7 +22,7 @@ export const CommandBar = () => {
|
||||
}, [pathname])
|
||||
|
||||
// Hook up keyboard shortcuts
|
||||
useHotkeys(['mod+k', 'mod+/'], () => {
|
||||
useHotkeyWrapper(['mod+k', 'mod+/'], () => {
|
||||
if (commandBarState.context.commands.length === 0) return
|
||||
if (commandBarState.matches('Closed')) {
|
||||
commandBarSend({ type: 'Open' })
|
||||
|
@ -56,7 +56,7 @@ function CommandBarSelectionInput({
|
||||
// In future the engine's edit mode will go away and this will be handled differently.
|
||||
useEffect(() => {
|
||||
kclManager.exitEditMode()
|
||||
return () => kclManager.enterEditMode()
|
||||
return () => kclManager.defaultSelectionFilter()
|
||||
}, [])
|
||||
|
||||
// Fast-forward through this arg if it's marked as skippable
|
||||
|
@ -8,7 +8,6 @@ import { Dialog, Disclosure } from '@headlessui/react'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { faChevronRight, faTrashAlt } from '@fortawesome/free-solid-svg-icons'
|
||||
import { useFileContext } from 'hooks/useFileContext'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
import styles from './FileTree.module.css'
|
||||
import { sortProject } from 'lib/tauriFS'
|
||||
import { FILE_EXT } from 'lib/constants'
|
||||
@ -16,6 +15,7 @@ import { CustomIcon } from './CustomIcon'
|
||||
import { codeManager, kclManager } from 'lib/singletons'
|
||||
import { useDocumentHasFocus } from 'hooks/useDocumentHasFocus'
|
||||
import { useLspContext } from './LspProvider'
|
||||
import useHotkeyWrapper from 'lib/hotkeyWrapper'
|
||||
|
||||
function getIndentationCSS(level: number) {
|
||||
return `calc(1rem * ${level + 1})`
|
||||
@ -333,8 +333,8 @@ export const FileTreeMenu = () => {
|
||||
send({ type: 'Create file', data: { name: '', makeDir: true } })
|
||||
}
|
||||
|
||||
useHotkeys('meta + n', createFile)
|
||||
useHotkeys('meta + shift + n', createFolder)
|
||||
useHotkeyWrapper(['meta + n'], createFile)
|
||||
useHotkeyWrapper(['meta + shift + n'], createFolder)
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -22,8 +22,7 @@ import {
|
||||
LspWorker,
|
||||
} from 'editor/plugins/lsp/types'
|
||||
import { wasmUrl } from 'lang/wasm'
|
||||
|
||||
const DEFAULT_FILE_NAME: string = 'main.kcl'
|
||||
import { PROJECT_ENTRYPOINT } from 'lib/constants'
|
||||
|
||||
function getWorkspaceFolders(): LSP.WorkspaceFolder[] {
|
||||
return []
|
||||
@ -137,7 +136,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
if (isKclLspServerReady && !TEST && kclLspClient) {
|
||||
// Set up the lsp plugin.
|
||||
const lsp = kclLanguage({
|
||||
documentUri: `file:///${DEFAULT_FILE_NAME}`,
|
||||
documentUri: `file:///${PROJECT_ENTRYPOINT}`,
|
||||
workspaceFolders: getWorkspaceFolders(),
|
||||
client: kclLspClient,
|
||||
})
|
||||
@ -211,7 +210,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
if (isCopilotLspServerReady && !TEST && copilotLspClient) {
|
||||
// Set up the lsp plugin.
|
||||
const lsp = copilotPlugin({
|
||||
documentUri: `file:///${DEFAULT_FILE_NAME}`,
|
||||
documentUri: `file:///${PROJECT_ENTRYPOINT}`,
|
||||
workspaceFolders: getWorkspaceFolders(),
|
||||
client: copilotLspClient,
|
||||
allowHTMLContent: true,
|
||||
@ -236,7 +235,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
redirect: boolean
|
||||
) => {
|
||||
const currentFilePath = projectBasename(
|
||||
file?.path || DEFAULT_FILE_NAME,
|
||||
file?.path || PROJECT_ENTRYPOINT,
|
||||
projectPath || ''
|
||||
)
|
||||
lspClients.forEach((lspClient) => {
|
||||
@ -267,7 +266,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
if (file) {
|
||||
// Send that the file was opened.
|
||||
const filename = projectBasename(
|
||||
file?.path || DEFAULT_FILE_NAME,
|
||||
file?.path || PROJECT_ENTRYPOINT,
|
||||
project?.path || ''
|
||||
)
|
||||
lspClients.forEach((lspClient) => {
|
||||
@ -285,7 +284,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
|
||||
const onFileOpen = (filePath: string | null, projectPath: string | null) => {
|
||||
const currentFilePath = projectBasename(
|
||||
filePath || DEFAULT_FILE_NAME,
|
||||
filePath || PROJECT_ENTRYPOINT,
|
||||
projectPath || ''
|
||||
)
|
||||
lspClients.forEach((lspClient) => {
|
||||
@ -302,7 +301,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
|
||||
const onFileClose = (filePath: string | null, projectPath: string | null) => {
|
||||
const currentFilePath = projectBasename(
|
||||
filePath || DEFAULT_FILE_NAME,
|
||||
filePath || PROJECT_ENTRYPOINT,
|
||||
projectPath || ''
|
||||
)
|
||||
lspClients.forEach((lspClient) => {
|
||||
|
@ -55,9 +55,9 @@ import { Models } from '@kittycad/lib/dist/types/src'
|
||||
import toast from 'react-hot-toast'
|
||||
import { EditorSelection } from '@uiw/react-codemirror'
|
||||
import { CoreDumpManager } from 'lib/coredump'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import { letEngineAnimateAndSyncCamAfter } from 'clientSideScene/CameraControls'
|
||||
import useHotkeyWrapper from 'lib/hotkeyWrapper'
|
||||
|
||||
type MachineContext<T extends AnyStateMachine> = {
|
||||
state: StateFrom<T>
|
||||
@ -103,7 +103,7 @@ export const ModelingMachineProvider = ({
|
||||
htmlRef,
|
||||
token
|
||||
)
|
||||
useHotkeys('meta + shift + .', () => coreDump(coreDumpManager, true))
|
||||
useHotkeyWrapper(['meta + shift + .'], () => coreDump(coreDumpManager, true))
|
||||
|
||||
// Settings machine setup
|
||||
// const retrievedSettings = useRef(
|
||||
|
@ -36,10 +36,6 @@ import {
|
||||
import interact from '@replit/codemirror-interact'
|
||||
import { kclManager, editorManager, codeManager } from 'lib/singletons'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
import { isTauri } from 'lib/isTauri'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { paths } from 'lib/paths'
|
||||
import makeUrlPathRelative from 'lib/makeUrlPathRelative'
|
||||
import { useLspContext } from 'components/LspProvider'
|
||||
import { Prec, EditorState, Extension } from '@codemirror/state'
|
||||
import {
|
||||
@ -67,7 +63,6 @@ export const KclEditorPane = () => {
|
||||
? getSystemTheme()
|
||||
: context.app.theme.current
|
||||
const { copilotLSP, kclLSP } = useLspContext()
|
||||
const navigate = useNavigate()
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined') return
|
||||
@ -76,6 +71,8 @@ export const KclEditorPane = () => {
|
||||
return () => window.removeEventListener('online', onlineCallback)
|
||||
}, [])
|
||||
|
||||
// Since these already exist in the editor, we don't need to define them
|
||||
// with the wrapper.
|
||||
useHotkeys('mod+z', (e) => {
|
||||
e.preventDefault()
|
||||
editorManager.undo()
|
||||
@ -87,6 +84,7 @@ export const KclEditorPane = () => {
|
||||
|
||||
const textWrapping = context.textEditor.textWrapping
|
||||
const cursorBlinking = context.textEditor.blinkingCursor
|
||||
const codeMirrorHotkeys = codeManager.getCodemirrorHotkeys()
|
||||
|
||||
const editorExtensions = useMemo(() => {
|
||||
const extensions = [
|
||||
@ -106,20 +104,7 @@ export const KclEditorPane = () => {
|
||||
...completionKeymap,
|
||||
...lintKeymap,
|
||||
indentWithTab,
|
||||
{
|
||||
key: 'Meta-k',
|
||||
run: () => {
|
||||
editorManager.commandBarSend({ type: 'Open' })
|
||||
return false
|
||||
},
|
||||
},
|
||||
{
|
||||
key: isTauri() ? 'Meta-,' : 'Meta-Shift-,',
|
||||
run: () => {
|
||||
navigate(makeUrlPathRelative(paths.SETTINGS))
|
||||
return false
|
||||
},
|
||||
},
|
||||
...codeMirrorHotkeys,
|
||||
{
|
||||
key: editorShortcutMeta.convertToVariable.codeMirror,
|
||||
run: () => {
|
||||
@ -188,7 +173,13 @@ export const KclEditorPane = () => {
|
||||
}
|
||||
|
||||
return extensions
|
||||
}, [kclLSP, copilotLSP, textWrapping.current, cursorBlinking.current])
|
||||
}, [
|
||||
kclLSP,
|
||||
copilotLSP,
|
||||
textWrapping.current,
|
||||
cursorBlinking.current,
|
||||
codeMirrorHotkeys,
|
||||
])
|
||||
|
||||
const initialCode = useRef(codeManager.code)
|
||||
|
||||
|
@ -38,7 +38,7 @@ describe('processMemory', () => {
|
||||
expect(output.otherVar).toEqual(3)
|
||||
expect(output).toEqual({
|
||||
myVar: 5,
|
||||
myFn: undefined,
|
||||
myFn: '__function(a)__',
|
||||
otherVar: 3,
|
||||
theExtrude: [
|
||||
{
|
||||
|
@ -3,6 +3,43 @@ import { useMemo } from 'react'
|
||||
import { ProgramMemory, Path, ExtrudeSurface } from 'lang/wasm'
|
||||
import { useKclContext } from 'lang/KclProvider'
|
||||
import { useResolvedTheme } from 'hooks/useResolvedTheme'
|
||||
import { ActionButton } from 'components/ActionButton'
|
||||
import toast from 'react-hot-toast'
|
||||
import Tooltip from 'components/Tooltip'
|
||||
|
||||
export const MemoryPaneMenu = () => {
|
||||
const { programMemory } = useKclContext()
|
||||
|
||||
function copyProgramMemoryToClipboard() {
|
||||
if (globalThis && 'navigator' in globalThis) {
|
||||
try {
|
||||
navigator.clipboard.writeText(JSON.stringify(programMemory))
|
||||
toast.success('Program memory copied to clipboard')
|
||||
} catch (e) {
|
||||
toast.error('Failed to copy program memory to clipboard')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ActionButton
|
||||
Element="button"
|
||||
iconStart={{
|
||||
icon: 'clipboardPlus',
|
||||
iconClassName: '!text-current',
|
||||
bgClassName: 'bg-transparent',
|
||||
}}
|
||||
className="!p-0 !bg-transparent hover:text-primary border-transparent hover:border-primary !outline-none"
|
||||
onClick={copyProgramMemoryToClipboard}
|
||||
>
|
||||
<Tooltip position="bottom-right" delay={750}>
|
||||
Copy to clipboard
|
||||
</Tooltip>
|
||||
</ActionButton>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const MemoryPane = () => {
|
||||
const theme = useResolvedTheme()
|
||||
@ -24,6 +61,7 @@ export const MemoryPane = () => {
|
||||
displayObjectSize={true}
|
||||
indentWidth={2}
|
||||
quotesOnKeys={false}
|
||||
sortKeys={true}
|
||||
name={false}
|
||||
theme={theme === 'light' ? 'rjv-default' : 'monokai'}
|
||||
/>
|
||||
@ -46,6 +84,10 @@ export const processMemory = (programMemory: ProgramMemory) => {
|
||||
processedMemory[key] = val.value.map(({ ...rest }: ExtrudeSurface) => {
|
||||
return rest
|
||||
})
|
||||
} else if ((val.type as any) === 'Function') {
|
||||
processedMemory[key] = `__function(${(val as any)?.expression?.params
|
||||
?.map?.(({ identifier }: any) => identifier?.name || '')
|
||||
.join(', ')})__`
|
||||
} else {
|
||||
processedMemory[key] = val.value
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import { KclEditorMenu } from 'components/ModelingSidebar/ModelingPanes/KclEdito
|
||||
import { CustomIconName } from 'components/CustomIcon'
|
||||
import { KclEditorPane } from 'components/ModelingSidebar/ModelingPanes/KclEditorPane'
|
||||
import { ReactNode } from 'react'
|
||||
import { MemoryPane } from './MemoryPane'
|
||||
import { MemoryPane, MemoryPaneMenu } from './MemoryPane'
|
||||
import { KclErrorsPane, LogsPane } from './LoggingPanes'
|
||||
import { DebugPane } from './DebugPane'
|
||||
import { FileTreeInner, FileTreeMenu } from 'components/FileTree'
|
||||
@ -61,6 +61,7 @@ export const bottomPanes: SidebarPane[] = [
|
||||
title: 'Variables',
|
||||
icon: faSquareRootVariable,
|
||||
Content: MemoryPane,
|
||||
Menu: MemoryPaneMenu,
|
||||
keybinding: 'shift + v',
|
||||
},
|
||||
{
|
||||
|
@ -47,6 +47,13 @@ export function ModelingSidebar({ paneOpacity }: ModelingSidebarProps) {
|
||||
right:
|
||||
(openPanes.length === 0 ? 'hidden ' : 'block ') +
|
||||
'translate-x-1/2 hover:bg-chalkboard-10 hover:dark:bg-chalkboard-110 bg-transparent transition-colors duration-75 transition-ease-out delay-100 ',
|
||||
left: 'hidden',
|
||||
top: 'hidden',
|
||||
topLeft: 'hidden',
|
||||
topRight: 'hidden',
|
||||
bottom: 'hidden',
|
||||
bottomLeft: 'hidden',
|
||||
bottomRight: 'hidden',
|
||||
}}
|
||||
>
|
||||
<div className={styles.grid + ' flex-1'}>
|
||||
|
@ -70,9 +70,9 @@ function ProjectCard({
|
||||
className="group relative min-h-[5em] p-1 rounded-sm border border-chalkboard-20 dark:border-chalkboard-80 hover:!border-primary"
|
||||
>
|
||||
{isEditing ? (
|
||||
<form onSubmit={handleSave} className="flex gap-2 items-center">
|
||||
<form onSubmit={handleSave} className="flex items-center gap-2">
|
||||
<input
|
||||
className="dark:bg-chalkboard-80 dark:border-chalkboard-40 min-w-0 p-1 focus:outline-none"
|
||||
className="min-w-0 p-1 dark:bg-chalkboard-80 dark:border-chalkboard-40 focus:outline-none"
|
||||
type="text"
|
||||
id="newProjectName"
|
||||
name="newProjectName"
|
||||
@ -81,7 +81,7 @@ function ProjectCard({
|
||||
defaultValue={project.name}
|
||||
ref={inputRef}
|
||||
/>
|
||||
<div className="flex gap-1 items-center">
|
||||
<div className="flex items-center gap-1">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
type="submit"
|
||||
@ -117,28 +117,27 @@ function ProjectCard({
|
||||
</form>
|
||||
) : (
|
||||
<>
|
||||
<div className="p-1 flex flex-col h-full gap-2">
|
||||
<Link
|
||||
className="flex-1 !no-underline !text-chalkboard-110 dark:!text-chalkboard-10 after:content-[''] after:absolute after:inset-0"
|
||||
to={`${paths.FILE}/${encodeURIComponent(project.path)}`}
|
||||
className="relative z-0 flex flex-col h-full gap-2 p-1 !no-underline !text-chalkboard-110 dark:!text-chalkboard-10"
|
||||
to={`${paths.FILE}/${encodeURIComponent(project.default_file)}`}
|
||||
data-testid="project-link"
|
||||
>
|
||||
{project.name?.replace(FILE_EXT, '')}
|
||||
</Link>
|
||||
<span className="text-chalkboard-60 text-xs">
|
||||
<div className="flex-1">{project.name?.replace(FILE_EXT, '')}</div>
|
||||
<span className="text-xs text-chalkboard-60">
|
||||
{numberOfFiles} file{numberOfFiles === 1 ? '' : 's'}{' '}
|
||||
{numberOfFolders > 0 &&
|
||||
`/ ${numberOfFolders} folder${
|
||||
numberOfFolders === 1 ? '' : 's'
|
||||
}`}
|
||||
</span>
|
||||
<span className="text-chalkboard-60 text-xs">
|
||||
<span className="text-xs text-chalkboard-60">
|
||||
Edited{' '}
|
||||
{project.metadata && project.metadata?.modified
|
||||
? getDisplayedTime(project.metadata.modified)
|
||||
: 'never'}
|
||||
</span>
|
||||
<div className="absolute z-10 bottom-2 right-2 flex gap-1 items-center opacity-0 group-hover:opacity-100 group-focus-within:opacity-100">
|
||||
</Link>
|
||||
<div className="absolute z-10 flex items-center gap-1 opacity-0 bottom-2 right-2 group-hover:opacity-100 group-focus-within:opacity-100">
|
||||
<ActionButton
|
||||
Element="button"
|
||||
iconStart={{
|
||||
@ -180,15 +179,14 @@ function ProjectCard({
|
||||
</Tooltip>
|
||||
</ActionButton>
|
||||
</div>
|
||||
</div>
|
||||
<Dialog
|
||||
open={isConfirmingDelete}
|
||||
onClose={() => setIsConfirmingDelete(false)}
|
||||
className="relative z-50"
|
||||
>
|
||||
<div className="fixed inset-0 bg-chalkboard-110/80 grid place-content-center">
|
||||
<Dialog.Panel className="rounded p-4 bg-chalkboard-10 dark:bg-chalkboard-100 border border-destroy-80 max-w-2xl">
|
||||
<Dialog.Title as="h2" className="text-2xl font-bold mb-4">
|
||||
<div className="fixed inset-0 grid bg-chalkboard-110/80 place-content-center">
|
||||
<Dialog.Panel className="max-w-2xl p-4 border rounded bg-chalkboard-10 dark:bg-chalkboard-100 border-destroy-80">
|
||||
<Dialog.Title as="h2" className="mb-4 text-2xl font-bold">
|
||||
Delete File
|
||||
</Dialog.Title>
|
||||
<Dialog.Description>
|
||||
|
@ -24,6 +24,7 @@ const projectWellFormed = {
|
||||
},
|
||||
kcl_file_count: 1,
|
||||
directory_count: 0,
|
||||
default_file: '/some/path/Simple Box/main.kcl',
|
||||
} satisfies Project
|
||||
|
||||
describe('ProjectSidebarMenu tests', () => {
|
||||
@ -32,7 +33,7 @@ describe('ProjectSidebarMenu tests', () => {
|
||||
<BrowserRouter>
|
||||
<CommandBarProvider>
|
||||
<SettingsAuthProviderJest>
|
||||
<ProjectSidebarMenu project={projectWellFormed} />
|
||||
<ProjectSidebarMenu project={projectWellFormed} enableMenu={true} />
|
||||
</SettingsAuthProviderJest>
|
||||
</CommandBarProvider>
|
||||
</BrowserRouter>
|
||||
@ -53,7 +54,7 @@ describe('ProjectSidebarMenu tests', () => {
|
||||
<BrowserRouter>
|
||||
<CommandBarProvider>
|
||||
<SettingsAuthProviderJest>
|
||||
<ProjectSidebarMenu />
|
||||
<ProjectSidebarMenu enableMenu={true} />
|
||||
</SettingsAuthProviderJest>
|
||||
</CommandBarProvider>
|
||||
</BrowserRouter>
|
||||
@ -64,22 +65,18 @@ describe('ProjectSidebarMenu tests', () => {
|
||||
expect(screen.getByTestId('projectName')).toHaveTextContent(APP_NAME)
|
||||
})
|
||||
|
||||
test('Renders as a link if set to do so', () => {
|
||||
test('Disables popover menu by default', () => {
|
||||
render(
|
||||
<BrowserRouter>
|
||||
<CommandBarProvider>
|
||||
<SettingsAuthProviderJest>
|
||||
<ProjectSidebarMenu
|
||||
project={projectWellFormed}
|
||||
renderAsLink={true}
|
||||
/>
|
||||
<ProjectSidebarMenu project={projectWellFormed} />
|
||||
</SettingsAuthProviderJest>
|
||||
</CommandBarProvider>
|
||||
</BrowserRouter>
|
||||
)
|
||||
|
||||
expect(screen.getByTestId('project-sidebar-link')).toBeInTheDocument()
|
||||
expect(screen.getByTestId('project-sidebar-link-name')).toHaveTextContent(
|
||||
expect(screen.getByTestId('project-name')).toHaveTextContent(
|
||||
projectWellFormed.name
|
||||
)
|
||||
})
|
||||
|
@ -17,53 +17,63 @@ import { engineCommandManager } from 'lib/singletons'
|
||||
const ProjectSidebarMenu = ({
|
||||
project,
|
||||
file,
|
||||
renderAsLink = false,
|
||||
enableMenu = false,
|
||||
}: {
|
||||
renderAsLink?: boolean
|
||||
enableMenu?: boolean
|
||||
project?: IndexLoaderData['project']
|
||||
file?: IndexLoaderData['file']
|
||||
}) => {
|
||||
const { onProjectClose } = useLspContext()
|
||||
return (
|
||||
<div className="!no-underline h-full mr-auto max-h-min min-h-12 min-w-max flex items-center gap-2">
|
||||
<Link
|
||||
onClick={() => {
|
||||
onProjectClose(file || null, project?.path || null, false)
|
||||
// Clear the scene and end the session.
|
||||
engineCommandManager.endSession()
|
||||
}}
|
||||
to={paths.HOME}
|
||||
className="relative h-full grid place-content-center group p-1.5 before:block before:content-[''] before:absolute before:inset-0 before:bottom-2.5 before:z-[-1] before:bg-primary hover:before:brightness-110 before:rounded-b-sm"
|
||||
>
|
||||
<Logo className="w-auto h-4 text-chalkboard-10" />
|
||||
</Link>
|
||||
{renderAsLink ? (
|
||||
<>
|
||||
<Link
|
||||
onClick={() => {
|
||||
onProjectClose(file || null, project?.path || null, false)
|
||||
// Clear the scene and end the session.
|
||||
engineCommandManager.endSession()
|
||||
}}
|
||||
to={paths.HOME}
|
||||
className="!no-underline"
|
||||
data-testid="project-sidebar-link"
|
||||
>
|
||||
<AppLogoLink project={project} file={file} />
|
||||
{enableMenu ? (
|
||||
<ProjectMenuPopover project={project} file={file} />
|
||||
) : (
|
||||
<span
|
||||
className="hidden text-sm text-chalkboard-110 dark:text-chalkboard-20 whitespace-nowrap lg:block"
|
||||
data-testid="project-sidebar-link-name"
|
||||
className="hidden select-none cursor-default text-sm text-chalkboard-110 dark:text-chalkboard-20 whitespace-nowrap lg:block"
|
||||
data-testid="project-name"
|
||||
>
|
||||
{project?.name ? project.name : APP_NAME}
|
||||
</span>
|
||||
</Link>
|
||||
</>
|
||||
) : (
|
||||
<ProjectMenuPopover project={project} file={file} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function AppLogoLink({
|
||||
project,
|
||||
file,
|
||||
}: {
|
||||
project?: IndexLoaderData['project']
|
||||
file?: IndexLoaderData['file']
|
||||
}) {
|
||||
const { onProjectClose } = useLspContext()
|
||||
const wrapperClassName =
|
||||
"relative h-full grid place-content-center group p-1.5 before:block before:content-[''] before:absolute before:inset-0 before:bottom-2.5 before:z-[-1] before:bg-primary before:rounded-b-sm"
|
||||
const logoClassName = 'w-auto h-4 text-chalkboard-10'
|
||||
|
||||
return isTauri() ? (
|
||||
<Link
|
||||
data-testid="app-logo"
|
||||
onClick={() => {
|
||||
onProjectClose(file || null, project?.path || null, false)
|
||||
// Clear the scene and end the session.
|
||||
engineCommandManager.endSession()
|
||||
}}
|
||||
to={paths.HOME}
|
||||
className={wrapperClassName + ' hover:before:brightness-110'}
|
||||
>
|
||||
<Logo className={logoClassName} />
|
||||
<span className="sr-only">{APP_NAME}</span>
|
||||
</Link>
|
||||
) : (
|
||||
<div className={wrapperClassName} data-testid="app-logo">
|
||||
<Logo className={logoClassName} />
|
||||
<span className="sr-only">{APP_NAME}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function ProjectMenuPopover({
|
||||
project,
|
||||
file,
|
||||
|
@ -172,7 +172,7 @@ export const SettingsAuthProviderBase = ({
|
||||
},
|
||||
'Execute AST': () => kclManager.executeCode(true),
|
||||
persistSettings: (context) =>
|
||||
saveSettings(context, loadedProject?.project?.name),
|
||||
saveSettings(context, loadedProject?.project?.path),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
@ -134,6 +134,7 @@ code {
|
||||
#code-mirror-override > div,
|
||||
#code-mirror-override .cm-editor {
|
||||
@apply bg-transparent h-full;
|
||||
@apply select-auto;
|
||||
}
|
||||
|
||||
#code-mirror-override .cm-scroller {
|
||||
|
@ -188,7 +188,7 @@ export class KclManager {
|
||||
engineCommandManager: this.engineCommandManager,
|
||||
})
|
||||
sceneInfra.modelingSend({ type: 'code edit during sketch' })
|
||||
enterEditMode(programMemory, this.engineCommandManager)
|
||||
defaultSelectionFilter(programMemory, this.engineCommandManager)
|
||||
this.isExecuting = false
|
||||
// Check the cancellation token for this execution before applying side effects
|
||||
if (this._cancelTokens.get(currentExecutionId)) {
|
||||
@ -348,9 +348,6 @@ export class KclManager {
|
||||
void this.engineCommandManager.setPlaneHidden(this.defaultPlanes.yz, true)
|
||||
void this.engineCommandManager.setPlaneHidden(this.defaultPlanes.xz, true)
|
||||
}
|
||||
enterEditMode() {
|
||||
enterEditMode(this.programMemory, this.engineCommandManager)
|
||||
}
|
||||
exitEditMode() {
|
||||
this.engineCommandManager.sendSceneCommand({
|
||||
type: 'modeling_cmd_req',
|
||||
@ -358,9 +355,12 @@ export class KclManager {
|
||||
cmd: { type: 'edit_mode_exit' },
|
||||
})
|
||||
}
|
||||
defaultSelectionFilter() {
|
||||
defaultSelectionFilter(this.programMemory, this.engineCommandManager)
|
||||
}
|
||||
}
|
||||
|
||||
function enterEditMode(
|
||||
function defaultSelectionFilter(
|
||||
programMemory: ProgramMemory,
|
||||
engineCommandManager: EngineCommandManager
|
||||
) {
|
||||
|
@ -6,6 +6,7 @@ import { isTauri } from 'lib/isTauri'
|
||||
import { writeTextFile } from '@tauri-apps/plugin-fs'
|
||||
import toast from 'react-hot-toast'
|
||||
import { editorManager } from 'lib/singletons'
|
||||
import { KeyBinding } from '@uiw/react-codemirror'
|
||||
|
||||
const PERSIST_CODE_TOKEN = 'persistCode'
|
||||
|
||||
@ -13,6 +14,7 @@ export default class CodeManager {
|
||||
private _code: string = bracket
|
||||
#updateState: (arg: string) => void = () => {}
|
||||
private _currentFilePath: string | null = null
|
||||
private _hotkeys: { [key: string]: () => void } = {}
|
||||
|
||||
constructor() {
|
||||
if (isTauri()) {
|
||||
@ -48,6 +50,20 @@ export default class CodeManager {
|
||||
this.#updateState = setCode
|
||||
}
|
||||
|
||||
registerHotkey(hotkey: string, callback: () => void) {
|
||||
this._hotkeys[hotkey] = callback
|
||||
}
|
||||
|
||||
getCodemirrorHotkeys(): KeyBinding[] {
|
||||
return Object.keys(this._hotkeys).map((key) => ({
|
||||
key,
|
||||
run: () => {
|
||||
this._hotkeys[key]()
|
||||
return false
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
updateCurrentFilePath(path: string) {
|
||||
this._currentFilePath = path
|
||||
}
|
||||
|
@ -1,20 +1,21 @@
|
||||
import { ToolTip } from '../useStore'
|
||||
import { Selection, Selections } from 'lib/selections'
|
||||
import {
|
||||
ArrayExpression,
|
||||
BinaryExpression,
|
||||
Program,
|
||||
SyntaxType,
|
||||
Value,
|
||||
CallExpression,
|
||||
ExpressionStatement,
|
||||
VariableDeclaration,
|
||||
ReturnStatement,
|
||||
ArrayExpression,
|
||||
PathToNode,
|
||||
PipeExpression,
|
||||
Program,
|
||||
ProgramMemory,
|
||||
ReturnStatement,
|
||||
SketchGroup,
|
||||
SourceRange,
|
||||
PipeExpression,
|
||||
SyntaxType,
|
||||
Value,
|
||||
VariableDeclaration,
|
||||
VariableDeclarator,
|
||||
} from './wasm'
|
||||
import { createIdentifier, splitPathAtLastIndex } from './modifyAst'
|
||||
import { getSketchSegmentFromSourceRange } from './std/sketchConstraints'
|
||||
@ -295,6 +296,58 @@ export function getNodePathFromSourceRange(
|
||||
return path
|
||||
}
|
||||
|
||||
type KCLNode =
|
||||
| Value
|
||||
| ExpressionStatement
|
||||
| VariableDeclaration
|
||||
| VariableDeclarator
|
||||
| ReturnStatement
|
||||
|
||||
export function traverse(
|
||||
node: KCLNode,
|
||||
option: {
|
||||
enter?: (node: KCLNode) => void
|
||||
leave?: (node: KCLNode) => void
|
||||
}
|
||||
) {
|
||||
option?.enter?.(node)
|
||||
const _traverse = (node: KCLNode) => traverse(node, option)
|
||||
|
||||
if (node.type === 'VariableDeclaration') {
|
||||
node.declarations.forEach(_traverse)
|
||||
} else if (node.type === 'VariableDeclarator') {
|
||||
_traverse(node.init)
|
||||
} else if (node.type === 'PipeExpression') {
|
||||
node.body.forEach(_traverse)
|
||||
} else if (node.type === 'CallExpression') {
|
||||
_traverse(node.callee)
|
||||
node.arguments.forEach(_traverse)
|
||||
} else if (node.type === 'BinaryExpression') {
|
||||
_traverse(node.left)
|
||||
_traverse(node.right)
|
||||
} else if (node.type === 'Identifier') {
|
||||
// do nothing
|
||||
} else if (node.type === 'Literal') {
|
||||
// do nothing
|
||||
} else if (node.type === 'ArrayExpression') {
|
||||
node.elements.forEach(_traverse)
|
||||
} else if (node.type === 'ObjectExpression') {
|
||||
node.properties.forEach(({ key, value }) => {
|
||||
_traverse(key)
|
||||
_traverse(value)
|
||||
})
|
||||
} else if (node.type === 'UnaryExpression') {
|
||||
_traverse(node.argument)
|
||||
} else if (node.type === 'MemberExpression') {
|
||||
// hmm this smell
|
||||
_traverse(node.object)
|
||||
_traverse(node.property)
|
||||
} else if ('body' in node && Array.isArray(node.body)) {
|
||||
node.body.forEach(_traverse)
|
||||
}
|
||||
option?.leave?.(node)
|
||||
}
|
||||
|
||||
export interface PrevVariable<T> {
|
||||
key: string
|
||||
value: T
|
||||
|
@ -54,8 +54,16 @@ interface PendingCommand extends CommandInfo {
|
||||
resolve: (val: ResolveCommand) => void
|
||||
}
|
||||
|
||||
/**
|
||||
* The ArtifactMap is a client-side representation of the artifacts that
|
||||
* have been sent to the server-side engine. It is used to keep track of
|
||||
* the state of each command, and to resolve the promise that was returned.
|
||||
* It is also used to keep track of what entities are in the engine scene,
|
||||
* so that we can associate IDs returned from the engine with the
|
||||
* lines of KCL code that generated them.
|
||||
*/
|
||||
export interface ArtifactMap {
|
||||
[key: string]: ResultCommand | PendingCommand | FailedCommand
|
||||
[commandId: string]: ResultCommand | PendingCommand | FailedCommand
|
||||
}
|
||||
|
||||
interface NewTrackArgs {
|
||||
@ -63,10 +71,11 @@ interface NewTrackArgs {
|
||||
mediaStream: MediaStream
|
||||
}
|
||||
|
||||
// This looks funny, I know. This is needed because node and the browser
|
||||
// disagree as to the type. In a browser it's a number, but in node it's a
|
||||
// "Timeout".
|
||||
type Timeout = ReturnType<typeof setTimeout>
|
||||
/** This looks funny, I know. This is needed because node and the browser
|
||||
* disagree as to the type. In a browser it's a number, but in node it's a
|
||||
* "Timeout".
|
||||
*/
|
||||
type IsomorphicTimeout = ReturnType<typeof setTimeout>
|
||||
|
||||
type ClientMetrics = Models['ClientMetrics_type']
|
||||
|
||||
@ -188,9 +197,11 @@ export type EngineConnectionState =
|
||||
| State<EngineConnectionStateType.Disconnecting, DisconnectingValue>
|
||||
| State<EngineConnectionStateType.Disconnected, void>
|
||||
|
||||
// EngineConnection encapsulates the connection(s) to the Engine
|
||||
// for the EngineCommandManager; namely, the underlying WebSocket
|
||||
// and WebRTC connections.
|
||||
/**
|
||||
* EngineConnection encapsulates the connection(s) to the Engine
|
||||
* for the EngineCommandManager; namely, the underlying WebSocket
|
||||
* and WebRTC connections.
|
||||
*/
|
||||
class EngineConnection {
|
||||
websocket?: WebSocket
|
||||
pc?: RTCPeerConnection
|
||||
@ -227,23 +238,40 @@ class EngineConnection {
|
||||
this.onConnectionStateChange(this._state)
|
||||
}
|
||||
|
||||
private failedConnTimeout: Timeout | null
|
||||
private failedConnTimeout: IsomorphicTimeout | null
|
||||
|
||||
readonly url: string
|
||||
private readonly token?: string
|
||||
|
||||
// For now, this is only used by the NetworkHealthIndicator.
|
||||
// We can eventually use it for more, but one step at a time.
|
||||
/**For now, this is only used by the NetworkHealthIndicator.
|
||||
* We can eventually use it for more, but one step at a time.
|
||||
*/
|
||||
private onConnectionStateChange: (state: EngineConnectionState) => void
|
||||
|
||||
// These are used for the EngineCommandManager and were created
|
||||
// before onConnectionStateChange existed.
|
||||
/**
|
||||
* Used for the EngineCommandManager, created before
|
||||
* onConnectionStateChange existed.
|
||||
*/
|
||||
private onEngineConnectionOpen: (engineConnection: EngineConnection) => void
|
||||
/**
|
||||
* Used for the EngineCommandManager, created before
|
||||
* onConnectionStateChange existed.
|
||||
*/
|
||||
private onConnectionStarted: (engineConnection: EngineConnection) => void
|
||||
/**
|
||||
* Used for the EngineCommandManager, created before
|
||||
* onConnectionStateChange existed.
|
||||
*/
|
||||
private onClose: (engineConnection: EngineConnection) => void
|
||||
/**
|
||||
* Used for the EngineCommandManager, created before
|
||||
* onConnectionStateChange existed.
|
||||
*/
|
||||
private onNewTrack: (track: NewTrackArgs) => void
|
||||
|
||||
// TODO: actual type is ClientMetrics
|
||||
/**
|
||||
* @todo actual type is `ClientMetrics`
|
||||
*/
|
||||
public webrtcStatsCollector?: () => Promise<WebRTCClientMetrics>
|
||||
private engineCommandManager: EngineCommandManager
|
||||
|
||||
@ -322,11 +350,13 @@ class EngineConnection {
|
||||
}
|
||||
}
|
||||
|
||||
// connect will attempt to connect to the Engine over a WebSocket, and
|
||||
// establish the WebRTC connections.
|
||||
//
|
||||
// This will attempt the full handshake, and retry if the connection
|
||||
// did not establish.
|
||||
/**
|
||||
* Attempts to connect to the Engine over a WebSocket, and
|
||||
* establish the WebRTC connections.
|
||||
*
|
||||
* This will attempt the full handshake, and retry if the connection
|
||||
* did not establish.
|
||||
*/
|
||||
connect() {
|
||||
if (this.isConnecting() || this.isReady()) {
|
||||
return
|
||||
@ -521,6 +551,7 @@ class EngineConnection {
|
||||
// Everything is now connected.
|
||||
this.state = { type: EngineConnectionStateType.ConnectionEstablished }
|
||||
|
||||
this.engineCommandManager.inSequence = 1
|
||||
this.onEngineConnectionOpen(this)
|
||||
})
|
||||
|
||||
@ -908,21 +939,66 @@ export type CommandLog =
|
||||
data: null
|
||||
}
|
||||
|
||||
/**
|
||||
* The EngineCommandManager is the main interface to the Engine for Modeling App.
|
||||
*
|
||||
* It is responsible for sending commands to the Engine, and managing the state
|
||||
* of those commands. It also sets up and tears down the connection to the Engine
|
||||
* through the {@link EngineConnection} class.
|
||||
*
|
||||
* It also maintains an {@link artifactMap} that keeps track of the state of each
|
||||
* command, and the artifacts that have been generated by those commands.
|
||||
*/
|
||||
export class EngineCommandManager {
|
||||
/**
|
||||
* The artifactMap is a client-side representation of the commands that have been sent
|
||||
* to the server-side geometry engine, and the state of their resulting artifacts.
|
||||
*
|
||||
* It is used to keep track of the state of each command, which can fail, succeed, or be
|
||||
* pending.
|
||||
*
|
||||
* It is also used to keep track of our client's understanding of what is in the engine scene
|
||||
* so that we can map to and from KCL code. Each artifact maintains a source range to the part
|
||||
* of the KCL code that generated it.
|
||||
*/
|
||||
artifactMap: ArtifactMap = {}
|
||||
/**
|
||||
* The {@link ArtifactMap} from the previous engine connection. This is used as a fallback
|
||||
* when the engine connection is reset without a full client-side refresh.
|
||||
*
|
||||
* @deprecated This was used during a short time when we were choosing to not execute the engine in certain cases.
|
||||
*/
|
||||
lastArtifactMap: ArtifactMap = {}
|
||||
/**
|
||||
* The client-side representation of the scene command artifacts that have been sent to the server;
|
||||
* that is, the *non-modeling* commands and corresponding artifacts.
|
||||
*
|
||||
* For modeling commands, see {@link artifactMap}.
|
||||
*/
|
||||
sceneCommandArtifacts: ArtifactMap = {}
|
||||
/**
|
||||
* A counter that is incremented with each command sent over the *unreliable* channel to the engine.
|
||||
* This is compared to the latest received {@link inSequence} number to determine if we should ignore
|
||||
* any out-of-order late responses in the unreliable channel.
|
||||
*/
|
||||
outSequence = 1
|
||||
/**
|
||||
* The latest sequence number received from the engine over the *unreliable* channel.
|
||||
* This is compared to the {@link outSequence} number to determine if we should ignore
|
||||
* any out-of-order late responses in the unreliable channel.
|
||||
*/
|
||||
inSequence = 1
|
||||
pool?: string
|
||||
engineConnection?: EngineConnection
|
||||
defaultPlanes: DefaultPlanes | null = null
|
||||
commandLogs: CommandLog[] = []
|
||||
_commandLogCallBack: (command: CommandLog[]) => void = () => {}
|
||||
// Folks should realize that wait for ready does not get called _everytime_
|
||||
// the connection resets and restarts, it only gets called the first time.
|
||||
// Be careful what you put here.
|
||||
private resolveReady = () => {}
|
||||
/** Folks should realize that wait for ready does not get called _everytime_
|
||||
* the connection resets and restarts, it only gets called the first time.
|
||||
*
|
||||
* Be careful what you put here.
|
||||
*/
|
||||
waitForReady: Promise<void> = new Promise((resolve) => {
|
||||
this.resolveReady = resolve
|
||||
})
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Models } from '@kittycad/lib'
|
||||
import { CommandSetConfig, KclCommandValue } from 'lib/commandTypes'
|
||||
import { KCL_DEFAULT_LENGTH } from 'lib/constants'
|
||||
import { Selections } from 'lib/selections'
|
||||
import { modelingMachine } from 'machines/modelingMachine'
|
||||
|
||||
@ -135,7 +136,7 @@ export const modelingMachineConfig: CommandSetConfig<
|
||||
// },
|
||||
distance: {
|
||||
inputType: 'kcl',
|
||||
defaultValue: '5 + 7',
|
||||
defaultValue: KCL_DEFAULT_LENGTH,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
@ -42,3 +42,5 @@ export const RELEVANT_FILE_TYPES = [
|
||||
] as const
|
||||
/** The default name for a tutorial project */
|
||||
export const ONBOARDING_PROJECT_NAME = 'Tutorial Project $nn'
|
||||
/** The default KCL length expression */
|
||||
export const KCL_DEFAULT_LENGTH = `5`
|
||||
|
37
src/lib/hotkeyWrapper.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { Options, useHotkeys } from 'react-hotkeys-hook'
|
||||
import { useEffect } from 'react'
|
||||
import { codeManager } from './singletons'
|
||||
|
||||
// Hotkey wrapper wraps hotkeys for the app (outside of the editor)
|
||||
// With hotkeys inside the editor.
|
||||
// This way we can have hotkeys defined in one place and not have to worry about
|
||||
// conflicting hotkeys, or them only being implemented for the app but not
|
||||
// inside the editor.
|
||||
// TODO: would be nice if this didn't have to be a react hook. It's not needed
|
||||
// for the code mirror stuff but but it is needed for the useHotkeys hook.
|
||||
export default function useHotkeyWrapper(
|
||||
hotkey: string[],
|
||||
callback: () => void,
|
||||
additionalOptions?: Options
|
||||
) {
|
||||
useHotkeys(hotkey, callback, additionalOptions)
|
||||
useEffect(() => {
|
||||
for (const key of hotkey) {
|
||||
const keybinding = mapHotkeyToCodeMirrorHotkey(key)
|
||||
codeManager.registerHotkey(keybinding, callback)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Convert hotkey to code mirror hotkey
|
||||
// See: https://codemirror.net/docs/ref/#view.KeyBinding
|
||||
function mapHotkeyToCodeMirrorHotkey(hotkey: string): string {
|
||||
return hotkey
|
||||
.replaceAll('+', '-')
|
||||
.replaceAll(' ', '')
|
||||
.replaceAll('mod', 'Meta')
|
||||
.replaceAll('meta', 'Meta')
|
||||
.replaceAll('ctrl', 'Ctrl')
|
||||
.replaceAll('shift', 'Shift')
|
||||
.replaceAll('alt', 'Alt')
|
||||
}
|
@ -38,8 +38,8 @@ export const settingsLoader: LoaderFunction = async ({
|
||||
configuration
|
||||
)
|
||||
if (projectPathData) {
|
||||
const { project_name } = projectPathData
|
||||
const { settings: s } = await loadAndValidateSettings(project_name)
|
||||
const { project_path } = projectPathData
|
||||
const { settings: s } = await loadAndValidateSettings(project_path)
|
||||
settings = s
|
||||
}
|
||||
}
|
||||
@ -118,6 +118,7 @@ export const fileLoader: LoaderFunction = async ({
|
||||
children: [],
|
||||
kcl_file_count: 0,
|
||||
directory_count: 0,
|
||||
default_file: project_path,
|
||||
},
|
||||
file: {
|
||||
name: current_file_name,
|
||||
|
@ -77,7 +77,29 @@ export async function getEventForSelectWithPoint(
|
||||
},
|
||||
}
|
||||
}
|
||||
const _artifact = engineCommandManager.artifactMap[data.entity_id]
|
||||
let _artifact = engineCommandManager.artifactMap[data.entity_id]
|
||||
if (!_artifact) {
|
||||
// This logic for getting the parent id is for solid2ds as in edit mode it return the face id
|
||||
// but we don't recognise that in the artifact map because we store the path id when the path is
|
||||
// created, the solid2d is implicitly created with the close stdlib function
|
||||
// there's plans to get the faceId back from the solid2d creation
|
||||
// https://github.com/KittyCAD/engine/issues/2094
|
||||
// at which point we can add it to the artifact map and remove this logic
|
||||
const parentId = (
|
||||
await engineCommandManager.sendSceneCommand({
|
||||
type: 'modeling_cmd_req',
|
||||
cmd: {
|
||||
type: 'entity_get_parent_id',
|
||||
entity_id: data.entity_id,
|
||||
},
|
||||
cmd_id: uuidv4(),
|
||||
})
|
||||
)?.data?.data?.entity_id
|
||||
const parentArtifact = engineCommandManager.artifactMap[parentId]
|
||||
if (parentArtifact) {
|
||||
_artifact = parentArtifact
|
||||
}
|
||||
}
|
||||
const sourceRange = _artifact?.range
|
||||
if (_artifact) {
|
||||
if (_artifact.commandType === 'solid3d_get_extrusion_face_info') {
|
||||
|
@ -147,7 +147,7 @@ export interface AppSettings {
|
||||
}
|
||||
|
||||
export async function loadAndValidateSettings(
|
||||
projectName?: string
|
||||
projectPath?: string
|
||||
): Promise<AppSettings> {
|
||||
const settings = createSettings()
|
||||
const inTauri = isTauri()
|
||||
@ -166,9 +166,9 @@ export async function loadAndValidateSettings(
|
||||
setSettingsAtLevel(settings, 'user', appSettingsPayload)
|
||||
|
||||
// Load the project settings if they exist
|
||||
if (projectName) {
|
||||
if (projectPath) {
|
||||
const projectSettings = inTauri
|
||||
? await readProjectSettingsFile(appSettings, projectName)
|
||||
? await readProjectSettingsFile(projectPath)
|
||||
: readLocalStorageProjectSettingsFile()
|
||||
|
||||
const projectSettingsPayload =
|
||||
@ -182,7 +182,7 @@ export async function loadAndValidateSettings(
|
||||
|
||||
export async function saveSettings(
|
||||
allSettings: typeof settings,
|
||||
projectName?: string
|
||||
projectPath?: string
|
||||
) {
|
||||
// Make sure we have wasm initialized.
|
||||
await initPromise
|
||||
@ -204,7 +204,7 @@ export async function saveSettings(
|
||||
)
|
||||
}
|
||||
|
||||
if (!projectName) {
|
||||
if (!projectPath) {
|
||||
// If we're not saving project settings, we're done.
|
||||
return
|
||||
}
|
||||
@ -217,7 +217,7 @@ export async function saveSettings(
|
||||
|
||||
// Write the project settings.
|
||||
if (inTauri) {
|
||||
await writeProjectSettingsFile(appSettings, projectName, projectSettings)
|
||||
await writeProjectSettingsFile(projectPath, projectSettings)
|
||||
} else {
|
||||
localStorage.setItem(
|
||||
localStorageProjectSettingsPath(),
|
||||
|
@ -8,23 +8,36 @@ import { Project } from 'wasm-lib/kcl/bindings/Project'
|
||||
import { FileEntry } from 'wasm-lib/kcl/bindings/FileEntry'
|
||||
import { ProjectState } from 'wasm-lib/kcl/bindings/ProjectState'
|
||||
import { ProjectRoute } from 'wasm-lib/kcl/bindings/ProjectRoute'
|
||||
import { isTauri } from './isTauri'
|
||||
|
||||
// Get the app state from tauri.
|
||||
export async function getState(): Promise<ProjectState | undefined> {
|
||||
if (!isTauri()) {
|
||||
return undefined
|
||||
}
|
||||
return await invoke<ProjectState | undefined>('get_state')
|
||||
}
|
||||
|
||||
// Set the app state in tauri.
|
||||
export async function setState(state: ProjectState | undefined): Promise<void> {
|
||||
if (!isTauri()) {
|
||||
return
|
||||
}
|
||||
return await invoke('set_state', { state })
|
||||
}
|
||||
|
||||
// Get the initial default dir for holding all projects.
|
||||
export async function getInitialDefaultDir(): Promise<string> {
|
||||
if (!isTauri()) {
|
||||
return ''
|
||||
}
|
||||
return invoke<string>('get_initial_default_dir')
|
||||
}
|
||||
|
||||
export async function showInFolder(path: string | undefined): Promise<void> {
|
||||
if (!isTauri()) {
|
||||
return
|
||||
}
|
||||
if (!path) {
|
||||
console.error('path is undefined cannot call tauri showInFolder')
|
||||
return
|
||||
@ -34,7 +47,10 @@ export async function showInFolder(path: string | undefined): Promise<void> {
|
||||
|
||||
export async function initializeProjectDirectory(
|
||||
settings: Configuration
|
||||
): Promise<string> {
|
||||
): Promise<string | undefined> {
|
||||
if (!isTauri()) {
|
||||
return undefined
|
||||
}
|
||||
return await invoke<string>('initialize_project_directory', {
|
||||
configuration: settings,
|
||||
})
|
||||
@ -127,24 +143,20 @@ export async function writeAppSettingsFile(
|
||||
|
||||
// Read project settings file.
|
||||
export async function readProjectSettingsFile(
|
||||
appSettings: Configuration,
|
||||
projectName: string
|
||||
projectPath: string
|
||||
): Promise<ProjectConfiguration> {
|
||||
return await invoke<ProjectConfiguration>('read_project_settings_file', {
|
||||
appSettings,
|
||||
projectName,
|
||||
projectPath,
|
||||
})
|
||||
}
|
||||
|
||||
// Write project settings file.
|
||||
export async function writeProjectSettingsFile(
|
||||
appSettings: Configuration,
|
||||
projectName: string,
|
||||
projectPath: string,
|
||||
settings: ProjectConfiguration
|
||||
): Promise<void> {
|
||||
return await invoke('write_project_settings_file', {
|
||||
appSettings,
|
||||
projectName,
|
||||
projectPath,
|
||||
configuration: settings,
|
||||
})
|
||||
}
|
||||
|
@ -906,12 +906,20 @@ export const modelingMachine = createMachine(
|
||||
type: 'default_camera_set_perspective',
|
||||
},
|
||||
})
|
||||
const center = { x: 0, y: 0, z: 0 }
|
||||
const camPos = sceneInfra.camControls.camera.position
|
||||
if (camPos.x === 0 && camPos.y === 0) {
|
||||
// looking straight up or down is going to cause issues with the engine
|
||||
// tweaking the center to be a little off center
|
||||
// TODO come up with a proper fix
|
||||
center.y = 0.05
|
||||
}
|
||||
await engineCommandManager.sendSceneCommand({
|
||||
type: 'modeling_cmd_req',
|
||||
cmd_id: uuidv4(),
|
||||
cmd: {
|
||||
type: 'default_camera_look_at',
|
||||
center: { x: 0, y: 0, z: 0 },
|
||||
center,
|
||||
vantage: sceneInfra.camControls.camera.position,
|
||||
up: { x: 0, y: 0, z: 1 },
|
||||
},
|
||||
@ -1045,7 +1053,8 @@ export const modelingMachine = createMachine(
|
||||
filter: ['face', 'plane'],
|
||||
},
|
||||
}),
|
||||
'set selection filter to defaults': () => kclManager.enterEditMode(),
|
||||
'set selection filter to defaults': () =>
|
||||
kclManager.defaultSelectionFilter(),
|
||||
},
|
||||
// end actions
|
||||
}
|
||||
|
219
src/wasm-lib/Cargo.lock
generated
@ -155,9 +155,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.83"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3"
|
||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
]
|
||||
@ -177,6 +177,15 @@ dependencies = [
|
||||
"num-traits 0.2.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110"
|
||||
dependencies = [
|
||||
"derive_arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "1.7.0"
|
||||
@ -246,7 +255,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -257,7 +266,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -280,7 +289,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -596,7 +605,7 @@ dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -846,7 +855,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -870,7 +879,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim 0.10.0",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -881,7 +890,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -922,7 +931,7 @@ checksum = "377af281d8f23663862a7c84623bc5dcf7f8c44b13c7496a590bdc157f941a43"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
"synstructure 0.13.1",
|
||||
]
|
||||
|
||||
@ -976,7 +985,18 @@ dependencies = [
|
||||
"rustfmt-wrapper",
|
||||
"serde",
|
||||
"serde_tokenstream",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_arbitrary"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -988,7 +1008,7 @@ dependencies = [
|
||||
"diesel_table_macro_syntax",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -997,7 +1017,7 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5"
|
||||
dependencies = [
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1026,7 +1046,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1051,9 +1071,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.10.0"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
|
||||
checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
|
||||
|
||||
[[package]]
|
||||
name = "elliptic-curve"
|
||||
@ -1108,7 +1128,7 @@ checksum = "03cdc46ec28bd728e67540c528013c6a10eb69a02eb31078a1bda695438cbfb8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1325,7 +1345,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1436,7 +1456,7 @@ dependencies = [
|
||||
"inflections",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1652,7 +1672,7 @@ dependencies = [
|
||||
"futures-util",
|
||||
"http 0.2.12",
|
||||
"hyper",
|
||||
"rustls 0.21.11",
|
||||
"rustls 0.21.12",
|
||||
"tokio",
|
||||
"tokio-rustls 0.24.1",
|
||||
]
|
||||
@ -1853,18 +1873,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.11.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
|
||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
@ -1918,7 +1938,7 @@ dependencies = [
|
||||
"iai",
|
||||
"image",
|
||||
"insta",
|
||||
"itertools 0.12.1",
|
||||
"itertools 0.13.0",
|
||||
"js-sys",
|
||||
"kittycad",
|
||||
"kittycad-execution-plan-macros",
|
||||
@ -1959,18 +1979,18 @@ dependencies = [
|
||||
"pretty_assertions",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kittycad"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c6e12eb45fd9a28c8e99dbdef54556246b39acee14e4aa6f0fc43636caa62d9"
|
||||
checksum = "81d3481e1b63f063ccf7d211f643da0563d2a42dd8b95b6006610742b729996b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"base64 0.21.7",
|
||||
"base64 0.22.1",
|
||||
"bigdecimal",
|
||||
"bytes",
|
||||
"chrono",
|
||||
@ -1979,10 +1999,10 @@ dependencies = [
|
||||
"format_serde_error",
|
||||
"futures",
|
||||
"http 0.2.12",
|
||||
"itertools 0.10.5",
|
||||
"itertools 0.12.1",
|
||||
"log",
|
||||
"mime_guess",
|
||||
"parse-display 0.8.2",
|
||||
"parse-display 0.9.0",
|
||||
"phonenumber",
|
||||
"rand 0.8.5",
|
||||
"reqwest",
|
||||
@ -2032,7 +2052,7 @@ checksum = "0611fc9b9786175da21d895ffa0f65039e19c9111e94a41b7af999e3b95f045f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2083,7 +2103,7 @@ checksum = "385775cc9d5bf25579f3029824ca1a6e7ab1b7c338e972ec8e8fcefff801f353"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2457,7 +2477,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2614,7 +2634,7 @@ dependencies = [
|
||||
"regex",
|
||||
"regex-syntax 0.7.5",
|
||||
"structmeta 0.2.0",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2628,7 +2648,7 @@ dependencies = [
|
||||
"regex",
|
||||
"regex-syntax 0.8.2",
|
||||
"structmeta 0.3.0",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2658,14 +2678,14 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "phonenumber"
|
||||
version = "0.3.3+8.13.9"
|
||||
version = "0.3.5+8.13.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "635f3e6288e4f01c049d89332a031bd74f25d64b6fb94703ca966e819488cd06"
|
||||
checksum = "f174c8db59b620032bd52b655fc97000458850fec0db35fcd4e802b668517ec0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"either",
|
||||
"fnv",
|
||||
"itertools 0.11.0",
|
||||
"itertools 0.12.1",
|
||||
"lazy_static",
|
||||
"nom",
|
||||
"quick-xml",
|
||||
@ -2694,7 +2714,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2841,9 +2861,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.82"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
|
||||
checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -3078,7 +3098,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls 0.21.11",
|
||||
"rustls 0.21.12",
|
||||
"rustls-pemfile 1.0.4",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -3304,9 +3324,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.21.11"
|
||||
version = "0.21.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4"
|
||||
checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring 0.17.8",
|
||||
@ -3316,9 +3336,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.22.2"
|
||||
version = "0.22.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41"
|
||||
checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring 0.17.8",
|
||||
@ -3419,9 +3439,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
version = "0.8.17"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f55c82c700538496bdc329bb4918a81f87cc8888811bd123cf325a0f2f8d309"
|
||||
checksum = "b0218ceea14babe24a4a5836f86ade86c1effbc198164e619194cb5069187e29"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"bytes",
|
||||
@ -3436,14 +3456,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "schemars_derive"
|
||||
version = "0.8.17"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83263746fe5e32097f06356968a077f96089739c927a61450efa069905eec108"
|
||||
checksum = "3ed5a1ccce8ff962e31a165d41f6e2a2dd1245099dc4d594f5574a86cd90f4d3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_derive_internals",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3519,9 +3539,9 @@ checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.201"
|
||||
version = "1.0.202"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c"
|
||||
checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@ -3537,13 +3557,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.201"
|
||||
version = "1.0.202"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865"
|
||||
checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3554,7 +3574,7 @@ checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3577,14 +3597,14 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.5"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
|
||||
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@ -3598,7 +3618,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3773,7 +3793,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"structmeta-derive 0.2.0",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3785,7 +3805,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"structmeta-derive 0.3.0",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3796,7 +3816,7 @@ checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3807,7 +3827,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3879,9 +3899,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.63"
|
||||
version = "2.0.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704"
|
||||
checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -3914,7 +3934,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4000,22 +4020,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.60"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18"
|
||||
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.60"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524"
|
||||
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4122,7 +4142,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4141,7 +4161,7 @@ version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
|
||||
dependencies = [
|
||||
"rustls 0.21.11",
|
||||
"rustls 0.21.12",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@ -4151,7 +4171,7 @@ version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
|
||||
dependencies = [
|
||||
"rustls 0.22.2",
|
||||
"rustls 0.22.4",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
]
|
||||
@ -4164,7 +4184,7 @@ checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"rustls 0.22.2",
|
||||
"rustls 0.22.4",
|
||||
"rustls-native-certs",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
@ -4188,9 +4208,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.12"
|
||||
version = "0.8.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
|
||||
checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
@ -4200,18 +4220,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.5"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.9"
|
||||
version = "0.22.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4"
|
||||
checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c"
|
||||
dependencies = [
|
||||
"indexmap 2.2.5",
|
||||
"serde",
|
||||
@ -4285,7 +4305,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4313,7 +4333,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4390,7 +4410,7 @@ dependencies = [
|
||||
"Inflector",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
@ -4407,7 +4427,7 @@ dependencies = [
|
||||
"httparse",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
"rustls 0.22.2",
|
||||
"rustls 0.22.4",
|
||||
"rustls-pki-types",
|
||||
"sha1",
|
||||
"thiserror",
|
||||
@ -4586,7 +4606,7 @@ dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4662,7 +4682,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -4697,7 +4717,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@ -4800,7 +4820,7 @@ dependencies = [
|
||||
"ring 0.17.8",
|
||||
"rtcp",
|
||||
"rtp",
|
||||
"rustls 0.21.11",
|
||||
"rustls 0.21.12",
|
||||
"sdp",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -4860,7 +4880,7 @@ dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
"rcgen",
|
||||
"ring 0.17.8",
|
||||
"rustls 0.21.11",
|
||||
"rustls 0.21.12",
|
||||
"sec1",
|
||||
"serde",
|
||||
"sha1",
|
||||
@ -5269,7 +5289,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -5289,18 +5309,21 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.63",
|
||||
"syn 2.0.65",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "0.6.6"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
|
||||
checksum = "f1f4a27345eb6f7aa7bd015ba7eb4175fa4e1b462a29874b779e0bbcf96c6ac7"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"arbitrary",
|
||||
"crc32fast",
|
||||
"crossbeam-utils",
|
||||
"displaydoc",
|
||||
"indexmap 2.2.5",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -17,7 +17,7 @@ kcl-lib = { path = "kcl" }
|
||||
kittycad = { workspace = true }
|
||||
serde_json = "1.0.116"
|
||||
tokio = { version = "1.37.0", features = ["sync"] }
|
||||
toml = "0.8.12"
|
||||
toml = "0.8.13"
|
||||
uuid = { version = "1.8.0", features = ["v4", "js", "serde"] }
|
||||
wasm-bindgen = "0.2.91"
|
||||
wasm-bindgen-futures = "0.4.42"
|
||||
|
@ -18,12 +18,12 @@ once_cell = "1.19.0"
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
regex = "1.10"
|
||||
serde = { version = "1.0.201", features = ["derive"] }
|
||||
serde = { version = "1.0.202", features = ["derive"] }
|
||||
serde_tokenstream = "0.2"
|
||||
syn = { version = "2.0.63", features = ["full"] }
|
||||
syn = { version = "2.0.65", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
anyhow = "1.0.83"
|
||||
anyhow = "1.0.86"
|
||||
expectorate = "1.1.0"
|
||||
pretty_assertions = "1.4.0"
|
||||
rustfmt-wrapper = "0.2.1"
|
||||
|
@ -201,7 +201,7 @@ fn do_stdlib_inner(
|
||||
.code_blocks
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, code_block)| generate_code_block_test(&fn_name_str, code_block, index, &metadata.tags))
|
||||
.map(|(index, code_block)| generate_code_block_test(&fn_name_str, code_block, index))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let tags = metadata
|
||||
@ -731,27 +731,13 @@ fn parse_array_type(type_name: &str) -> Option<(&str, usize)> {
|
||||
|
||||
// For each kcl code block, we want to generate a test that checks that the
|
||||
// code block is valid kcl code and compiles and executes.
|
||||
fn generate_code_block_test(
|
||||
fn_name: &str,
|
||||
code_block: &str,
|
||||
index: usize,
|
||||
tags: &[String],
|
||||
) -> proc_macro2::TokenStream {
|
||||
fn generate_code_block_test(fn_name: &str, code_block: &str, index: usize) -> proc_macro2::TokenStream {
|
||||
let test_name = format_ident!("serial_test_example_{}{}", fn_name, index);
|
||||
let test_name_mock = format_ident!("test_mock_example_{}{}", fn_name, index);
|
||||
let test_name_str = format!("serial_test_example_{}{}", fn_name, index);
|
||||
|
||||
// TODO: We ignore import for now, because the files don't exist and we just want
|
||||
// to show easy imports.
|
||||
let ignored = if tags.contains(&"norun".to_string()) {
|
||||
quote! { #[ignore] }
|
||||
} else {
|
||||
quote! {}
|
||||
};
|
||||
|
||||
quote! {
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
#ignored
|
||||
async fn #test_name_mock() {
|
||||
let tokens = crate::token::lexer(#code_block).unwrap();
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
@ -768,7 +754,6 @@ fn generate_code_block_test(
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
|
||||
#ignored
|
||||
async fn #test_name() {
|
||||
let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
|
||||
let http_client = reqwest::Client::builder()
|
||||
|
@ -340,43 +340,6 @@ fn test_stdlib_doc_comment_with_code() {
|
||||
expectorate::assert_contents("tests/doc_comment_with_code.gen", &get_text_fmt(&item).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdlib_doc_comment_with_code_on_ignored_function() {
|
||||
let (item, errors) = do_stdlib(
|
||||
quote! {
|
||||
name = "import",
|
||||
tags = ["norun"]
|
||||
},
|
||||
quote! {
|
||||
/// This is some function.
|
||||
/// It does shit.
|
||||
///
|
||||
/// This is code.
|
||||
/// It does other shit.
|
||||
/// import
|
||||
///
|
||||
/// ```
|
||||
/// This is another code block.
|
||||
/// yes sirrr.
|
||||
/// import
|
||||
/// ```
|
||||
fn inner_import(
|
||||
/// The args to do shit to.
|
||||
args: Option<kittycad::types::InputFormat>
|
||||
) -> Result<Vec<Box<SketchGroup>>> {
|
||||
args
|
||||
}
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(errors.is_empty());
|
||||
expectorate::assert_contents(
|
||||
"tests/doc_comment_with_code_on_ignored_function.gen",
|
||||
&get_text_fmt(&item).unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdlib_fail_non_camel_case() {
|
||||
let (_, errors) = do_stdlib(
|
||||
|
@ -1,303 +0,0 @@
|
||||
#[cfg(test)]
|
||||
mod test_examples_import {
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
#[ignore]
|
||||
async fn test_mock_example_import0() {
|
||||
let tokens =
|
||||
crate::token::lexer("This is another code block.\nyes sirrr.\nimport").unwrap();
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn_mock::EngineConnection::new()
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: std::sync::Arc::new(crate::fs::FileManager::new()),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
settings: Default::default(),
|
||||
is_mock: true,
|
||||
};
|
||||
ctx.run(program, None).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
|
||||
#[ignore]
|
||||
async fn serial_test_example_import0() {
|
||||
let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
|
||||
let http_client = reqwest::Client::builder()
|
||||
.user_agent(user_agent)
|
||||
.timeout(std::time::Duration::from_secs(600))
|
||||
.connect_timeout(std::time::Duration::from_secs(60));
|
||||
let ws_client = reqwest::Client::builder()
|
||||
.user_agent(user_agent)
|
||||
.timeout(std::time::Duration::from_secs(600))
|
||||
.connect_timeout(std::time::Duration::from_secs(60))
|
||||
.connection_verbose(true)
|
||||
.tcp_keepalive(std::time::Duration::from_secs(600))
|
||||
.http1_only();
|
||||
let token = std::env::var("KITTYCAD_API_TOKEN").expect("KITTYCAD_API_TOKEN not set");
|
||||
let mut client = kittycad::Client::new_from_reqwest(token, http_client, ws_client);
|
||||
if let Ok(addr) = std::env::var("LOCAL_ENGINE_ADDR") {
|
||||
client.set_base_url(addr);
|
||||
}
|
||||
|
||||
let tokens =
|
||||
crate::token::lexer("This is another code block.\nyes sirrr.\nimport").unwrap();
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let ctx = crate::executor::ExecutorContext::new(&client, Default::default())
|
||||
.await
|
||||
.unwrap();
|
||||
ctx.run(program, None).await.unwrap();
|
||||
ctx.engine
|
||||
.send_modeling_cmd(
|
||||
uuid::Uuid::new_v4(),
|
||||
crate::executor::SourceRange::default(),
|
||||
kittycad::types::ModelingCmd::ZoomToFit {
|
||||
object_ids: Default::default(),
|
||||
padding: 0.1,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let resp = ctx
|
||||
.engine
|
||||
.send_modeling_cmd(
|
||||
uuid::Uuid::new_v4(),
|
||||
crate::executor::SourceRange::default(),
|
||||
kittycad::types::ModelingCmd::TakeSnapshot {
|
||||
format: kittycad::types::ImageFormat::Png,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let output_file =
|
||||
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
|
||||
if let kittycad::types::OkWebSocketResponseData::Modeling {
|
||||
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
|
||||
} = &resp
|
||||
{
|
||||
std::fs::write(&output_file, &data.contents.0).unwrap();
|
||||
} else {
|
||||
panic!("Unexpected response from engine: {:?}", resp);
|
||||
}
|
||||
|
||||
let actual = image::io::Reader::open(output_file)
|
||||
.unwrap()
|
||||
.decode()
|
||||
.unwrap();
|
||||
twenty_twenty::assert_image(
|
||||
&format!("tests/outputs/{}.png", "serial_test_example_import0"),
|
||||
&actual,
|
||||
1.0,
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
#[ignore]
|
||||
async fn test_mock_example_import1() {
|
||||
let tokens = crate::token::lexer("This is code.\nIt does other shit.\nimport").unwrap();
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn_mock::EngineConnection::new()
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: std::sync::Arc::new(crate::fs::FileManager::new()),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
settings: Default::default(),
|
||||
is_mock: true,
|
||||
};
|
||||
ctx.run(program, None).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
|
||||
#[ignore]
|
||||
async fn serial_test_example_import1() {
|
||||
let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
|
||||
let http_client = reqwest::Client::builder()
|
||||
.user_agent(user_agent)
|
||||
.timeout(std::time::Duration::from_secs(600))
|
||||
.connect_timeout(std::time::Duration::from_secs(60));
|
||||
let ws_client = reqwest::Client::builder()
|
||||
.user_agent(user_agent)
|
||||
.timeout(std::time::Duration::from_secs(600))
|
||||
.connect_timeout(std::time::Duration::from_secs(60))
|
||||
.connection_verbose(true)
|
||||
.tcp_keepalive(std::time::Duration::from_secs(600))
|
||||
.http1_only();
|
||||
let token = std::env::var("KITTYCAD_API_TOKEN").expect("KITTYCAD_API_TOKEN not set");
|
||||
let mut client = kittycad::Client::new_from_reqwest(token, http_client, ws_client);
|
||||
if let Ok(addr) = std::env::var("LOCAL_ENGINE_ADDR") {
|
||||
client.set_base_url(addr);
|
||||
}
|
||||
|
||||
let tokens = crate::token::lexer("This is code.\nIt does other shit.\nimport").unwrap();
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let ctx = crate::executor::ExecutorContext::new(&client, Default::default())
|
||||
.await
|
||||
.unwrap();
|
||||
ctx.run(program, None).await.unwrap();
|
||||
ctx.engine
|
||||
.send_modeling_cmd(
|
||||
uuid::Uuid::new_v4(),
|
||||
crate::executor::SourceRange::default(),
|
||||
kittycad::types::ModelingCmd::ZoomToFit {
|
||||
object_ids: Default::default(),
|
||||
padding: 0.1,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let resp = ctx
|
||||
.engine
|
||||
.send_modeling_cmd(
|
||||
uuid::Uuid::new_v4(),
|
||||
crate::executor::SourceRange::default(),
|
||||
kittycad::types::ModelingCmd::TakeSnapshot {
|
||||
format: kittycad::types::ImageFormat::Png,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let output_file =
|
||||
std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
|
||||
if let kittycad::types::OkWebSocketResponseData::Modeling {
|
||||
modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
|
||||
} = &resp
|
||||
{
|
||||
std::fs::write(&output_file, &data.contents.0).unwrap();
|
||||
} else {
|
||||
panic!("Unexpected response from engine: {:?}", resp);
|
||||
}
|
||||
|
||||
let actual = image::io::Reader::open(output_file)
|
||||
.unwrap()
|
||||
.decode()
|
||||
.unwrap();
|
||||
twenty_twenty::assert_image(
|
||||
&format!("tests/outputs/{}.png", "serial_test_example_import1"),
|
||||
&actual,
|
||||
1.0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types, missing_docs)]
|
||||
#[doc = "Std lib function: import\nThis is some function.\nIt does shit."]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, schemars :: JsonSchema, ts_rs :: TS)]
|
||||
#[ts(export)]
|
||||
pub(crate) struct Import {}
|
||||
|
||||
#[allow(non_upper_case_globals, missing_docs)]
|
||||
#[doc = "Std lib function: import\nThis is some function.\nIt does shit."]
|
||||
pub(crate) const Import: Import = Import {};
|
||||
fn boxed_import(
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::MemoryItem, crate::errors::KclError>,
|
||||
> + Send,
|
||||
>,
|
||||
> {
|
||||
Box::pin(import(args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for Import {
|
||||
fn name(&self) -> String {
|
||||
"import".to_string()
|
||||
}
|
||||
|
||||
fn summary(&self) -> String {
|
||||
"This is some function.".to_string()
|
||||
}
|
||||
|
||||
fn description(&self) -> String {
|
||||
"It does shit.".to_string()
|
||||
}
|
||||
|
||||
fn tags(&self) -> Vec<String> {
|
||||
vec!["norun".to_string()]
|
||||
}
|
||||
|
||||
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
|
||||
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
||||
settings.inline_subschemas = true;
|
||||
let mut generator = schemars::gen::SchemaGenerator::new(settings);
|
||||
vec![crate::docs::StdLibFnArg {
|
||||
name: "args".to_string(),
|
||||
type_: "kittycad::types::InputFormat".to_string(),
|
||||
schema: <Option<kittycad::types::InputFormat>>::json_schema(&mut generator),
|
||||
required: false,
|
||||
}]
|
||||
}
|
||||
|
||||
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
|
||||
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
||||
settings.inline_subschemas = true;
|
||||
let mut generator = schemars::gen::SchemaGenerator::new(settings);
|
||||
Some(crate::docs::StdLibFnArg {
|
||||
name: "".to_string(),
|
||||
type_: "[SketchGroup]".to_string(),
|
||||
schema: <Vec<SketchGroup>>::json_schema(&mut generator),
|
||||
required: true,
|
||||
})
|
||||
}
|
||||
|
||||
fn unpublished(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn deprecated(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<String> {
|
||||
let code_blocks = vec![
|
||||
"This is another code block.\nyes sirrr.\nimport",
|
||||
"This is code.\nIt does other shit.\nimport",
|
||||
];
|
||||
code_blocks
|
||||
.iter()
|
||||
.map(|cb| {
|
||||
let tokens = crate::token::lexer(cb).unwrap();
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut options: crate::ast::types::FormatOptions = Default::default();
|
||||
options.insert_final_newline = false;
|
||||
program.recast(&options, 0)
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
}
|
||||
|
||||
fn std_lib_fn(&self) -> crate::std::StdFn {
|
||||
boxed_import
|
||||
}
|
||||
|
||||
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = r" This is some function."]
|
||||
#[doc = r" It does shit."]
|
||||
#[doc = r""]
|
||||
#[doc = r" This is code."]
|
||||
#[doc = r" It does other shit."]
|
||||
#[doc = r" import"]
|
||||
#[doc = r""]
|
||||
#[doc = r" ```"]
|
||||
#[doc = r" This is another code block."]
|
||||
#[doc = r" yes sirrr."]
|
||||
#[doc = r" import"]
|
||||
#[doc = r" ```"]
|
||||
fn inner_import(
|
||||
#[doc = r" The args to do shit to."] args: Option<kittycad::types::InputFormat>,
|
||||
) -> Result<Vec<Box<SketchGroup>>> {
|
||||
args
|
||||
}
|
@ -14,7 +14,7 @@ kittycad-execution-plan-traits = { workspace = true }
|
||||
kittycad-execution-plan-macros = { workspace = true }
|
||||
kittycad-modeling-cmds = { workspace = true }
|
||||
kittycad-modeling-session = { workspace = true }
|
||||
thiserror = "1.0.60"
|
||||
thiserror = "1.0.61"
|
||||
tokio = { version = "1.37.0", features = ["macros", "rt"] }
|
||||
twenty-twenty = "0.7.0"
|
||||
uuid = "1.8"
|
||||
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
@ -15,7 +15,7 @@ databake = "0.1.7"
|
||||
kcl-lib = { path = "../kcl" }
|
||||
proc-macro2 = "1"
|
||||
quote = "1"
|
||||
syn = { version = "2.0.63", features = ["full"] }
|
||||
syn = { version = "2.0.65", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "1.4.0"
|
||||
|
@ -11,7 +11,7 @@ keywords = ["kcl", "KittyCAD", "CAD"]
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = { version = "1.0.83", features = ["backtrace"] }
|
||||
anyhow = { version = "1.0.86", features = ["backtrace"] }
|
||||
async-recursion = "1.1.1"
|
||||
async-trait = "0.1.80"
|
||||
base64 = "0.22.1"
|
||||
@ -33,17 +33,17 @@ parse-display = "0.9.0"
|
||||
reqwest = { version = "0.11.26", default-features = false, features = ["stream", "rustls-tls"] }
|
||||
ropey = "1.6.1"
|
||||
schemars = { version = "0.8.17", features = ["impl_json_schema", "url", "uuid1"] }
|
||||
serde = { version = "1.0.201", features = ["derive"] }
|
||||
serde = { version = "1.0.202", features = ["derive"] }
|
||||
serde_json = "1.0.116"
|
||||
sha2 = "0.10.8"
|
||||
thiserror = "1.0.60"
|
||||
toml = "0.8.12"
|
||||
ts-rs = { version = "7.1.1", features = ["uuid-impl", "url-impl", "chrono-impl"] }
|
||||
thiserror = "1.0.61"
|
||||
toml = "0.8.13"
|
||||
ts-rs = { version = "7.1.1", features = ["uuid-impl", "url-impl", "chrono-impl", "no-serde-warnings"] }
|
||||
url = { version = "2.5.0", features = ["serde"] }
|
||||
uuid = { version = "1.8.0", features = ["v4", "js", "serde"] }
|
||||
validator = { version = "0.18.1", features = ["derive"] }
|
||||
winnow = "0.5.40"
|
||||
zip = { version = "0.6.6", default-features = false }
|
||||
zip = { version = "1.3.0", default-features = false }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
js-sys = { version = "0.3.69" }
|
||||
@ -80,7 +80,7 @@ expectorate = "1.1.0"
|
||||
iai = "0.1"
|
||||
image = "0.24.9"
|
||||
insta = { version = "1.38.0", features = ["json"] }
|
||||
itertools = "0.12.1"
|
||||
itertools = "0.13.0"
|
||||
pretty_assertions = "1.4.0"
|
||||
tokio = { version = "1.37.0", features = ["rt-multi-thread", "macros", "time"] }
|
||||
twenty-twenty = "0.7.0"
|
||||
|
20
src/wasm-lib/kcl/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
# KCL
|
||||
|
||||
Our language for defining geometry and working with our Geometry Engine efficiently. Short for KittyCAD Language, named after our Design API.
|
||||
|
||||
## Contributing a standard library function
|
||||
|
||||
We've built a lot of tooling to make contributing to KCL easier. If you are interested in contributing a new standard library function to KCL, here is the rough process:
|
||||
|
||||
1. Open just the wasm-lib folder in your editor of choice. VS Code, for example, struggles to run rust-analyzer on the entire modeling-app directory because it's such a turducken of TS and Rust code.
|
||||
2. Find the definition for similar standard library functions in `./kcl/src/std` and place your new one near it or in the same category file.
|
||||
3. Add your new code. A new standard library function consists of:
|
||||
4. A `pub async` of the actual standard library function in Rust
|
||||
5. A doc comment block containing at least one example using your new standard library function (the Rust compiler will error if you don't provide an example our teammates are dope)
|
||||
6. A `stdlib` macro providing the name that will need to be written by KCL users to use the function (this is usually a camelCase version of your Rust implementation, which is named with snake_case)
|
||||
7. An inner function that is published only to the crate
|
||||
8. Add your new standard library function to [the long list of CORE_FNS in mod.rs](https://github.com/KittyCAD/modeling-app/blob/main/src/wasm-lib/kcl/src/std/mod.rs#L42)
|
||||
9. Get a production Zoo dev token and run `export KITTYCAD_API_TOKEN=your-token-here` in a terminal
|
||||
10. Run `TWENTY_TWENTY=overwrite cargo nextest run --workspace --no-fail-fast` to take snapshot tests of your example code running in the engine
|
||||
11. Run `EXPECTORATE=overwrite cargo test --all generate_stdlib -- --nocapture` to generate new Markdown documentation for your function that will be used [to generate docs on our website](https://zoo.dev/docs/kcl).
|
||||
12. Create a PR in GitHub.
|
458
src/wasm-lib/kcl/fuzz/Cargo.lock
generated
@ -64,10 +64,59 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.81"
|
||||
name = "anstream"
|
||||
version = "0.6.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
|
||||
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
]
|
||||
@ -105,24 +154,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-recursion"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30c5ef0ede93efbf733c1a727f3b6b5a1060bbedd5600183e66f6e4be4af0ec5"
|
||||
checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.79"
|
||||
version = "0.1.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681"
|
||||
checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -176,6 +225,12 @@ version = "0.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "bigdecimal"
|
||||
version = "0.4.1"
|
||||
@ -287,9 +342,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.37"
|
||||
version = "0.4.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e"
|
||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
@ -300,6 +355,54 @@ dependencies = [
|
||||
"windows-targets 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
"unicase",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.1.0"
|
||||
@ -369,6 +472,41 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.20.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "5.5.3"
|
||||
@ -407,7 +545,7 @@ checksum = "377af281d8f23663862a7c84623bc5dcf7f8c44b13c7496a590bdc157f941a43"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
@ -419,9 +557,7 @@ checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
|
||||
|
||||
[[package]]
|
||||
name = "derive-docs"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138b94245509a9dd516008788b585c34847829cf37b40a758b4aa581cf94f147"
|
||||
version = "0.1.18"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"convert_case",
|
||||
@ -431,7 +567,7 @@ dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_tokenstream",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -479,9 +615,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.0"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
|
||||
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
@ -561,7 +697,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -624,22 +760,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
|
||||
|
||||
[[package]]
|
||||
name = "gltf-derive"
|
||||
version = "1.4.0"
|
||||
name = "git_rev"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "438ffe1a5540d75403feaf23636b164e816e93f6f03131674722b3886ce32a57"
|
||||
checksum = "60884563ea313b5037683cd5d44f1e14e9cb07b08543756242a65887f9cff48e"
|
||||
|
||||
[[package]]
|
||||
name = "gltf-derive"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14070e711538afba5d6c807edb74bcb84e5dbb9211a3bf5dea0dfab5b24f4c51"
|
||||
dependencies = [
|
||||
"inflections",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gltf-json"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "655951ba557f2bc69ea4b0799446bae281fa78efae6319968bdd2c3e9a06d8e1"
|
||||
checksum = "e6176f9d60a7eab0a877e8e96548605dedbde9190a7ae1e80bbcc1c9af03ab14"
|
||||
dependencies = [
|
||||
"gltf-derive",
|
||||
"serde",
|
||||
@ -684,6 +826,12 @@ version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.2"
|
||||
@ -774,7 +922,7 @@ dependencies = [
|
||||
"futures-util",
|
||||
"http 0.2.9",
|
||||
"hyper",
|
||||
"rustls 0.21.7",
|
||||
"rustls 0.21.12",
|
||||
"tokio",
|
||||
"tokio-rustls 0.24.1",
|
||||
]
|
||||
@ -803,10 +951,16 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.4.0"
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
@ -844,6 +998,12 @@ version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
@ -879,18 +1039,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kcl-lib"
|
||||
version = "0.1.47"
|
||||
version = "0.1.55"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"approx",
|
||||
"async-recursion",
|
||||
"async-trait",
|
||||
"base64 0.22.1",
|
||||
"bson",
|
||||
"chrono",
|
||||
"clap",
|
||||
"dashmap",
|
||||
"databake",
|
||||
"derive-docs",
|
||||
"form_urlencoded",
|
||||
"futures",
|
||||
"git_rev",
|
||||
"gltf-json",
|
||||
"js-sys",
|
||||
"kittycad",
|
||||
@ -908,13 +1072,16 @@ dependencies = [
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-tungstenite",
|
||||
"toml",
|
||||
"tower-lsp",
|
||||
"ts-rs",
|
||||
"url",
|
||||
"uuid",
|
||||
"validator",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"winnow",
|
||||
"winnow 0.5.40",
|
||||
"zip",
|
||||
]
|
||||
|
||||
@ -928,9 +1095,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kittycad"
|
||||
version = "0.2.63"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93a332250e08fd715ad3d5826e04d36da1c5bb42d0c1b1ff1f0598278b9ebf3c"
|
||||
checksum = "2c6e12eb45fd9a28c8e99dbdef54556246b39acee14e4aa6f0fc43636caa62d9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@ -938,6 +1105,7 @@ dependencies = [
|
||||
"bigdecimal",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"clap",
|
||||
"data-encoding",
|
||||
"format_serde_error",
|
||||
"futures",
|
||||
@ -968,7 +1136,7 @@ checksum = "0611fc9b9786175da21d895ffa0f65039e19c9111e94a41b7af999e3b95f045f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1240,7 +1408,7 @@ dependencies = [
|
||||
"regex",
|
||||
"regex-syntax 0.7.5",
|
||||
"structmeta 0.2.0",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1254,14 +1422,14 @@ dependencies = [
|
||||
"regex",
|
||||
"regex-syntax 0.8.2",
|
||||
"structmeta 0.3.0",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.0"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
|
||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||
|
||||
[[package]]
|
||||
name = "phonenumber"
|
||||
@ -1301,7 +1469,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1348,9 +1516,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.78"
|
||||
version = "1.0.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -1495,7 +1663,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls 0.21.7",
|
||||
"rustls 0.21.12",
|
||||
"rustls-pemfile 1.0.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -1563,21 +1731,21 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.21.7"
|
||||
version = "0.21.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8"
|
||||
checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring 0.16.20",
|
||||
"rustls-webpki 0.101.4",
|
||||
"ring 0.17.8",
|
||||
"rustls-webpki 0.101.7",
|
||||
"sct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.22.2"
|
||||
version = "0.22.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41"
|
||||
checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring 0.17.8",
|
||||
@ -1627,12 +1795,12 @@ checksum = "048a63e5b3ac996d78d402940b5fa47973d2d080c6c6fffa1d0f19c4445310b7"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.101.4"
|
||||
version = "0.101.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d"
|
||||
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
|
||||
dependencies = [
|
||||
"ring 0.16.20",
|
||||
"untrusted 0.7.1",
|
||||
"ring 0.17.8",
|
||||
"untrusted 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1669,9 +1837,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
version = "0.8.16"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29"
|
||||
checksum = "fc6e7ed6919cb46507fb01ff1654309219f62b4d603822501b0b80d42f6f21ef"
|
||||
dependencies = [
|
||||
"bigdecimal",
|
||||
"bytes",
|
||||
@ -1686,14 +1854,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "schemars_derive"
|
||||
version = "0.8.16"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967"
|
||||
checksum = "185f2b7aa7e02d418e453790dde16890256bbd2bcd04b7dc5348811052b53f49"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_derive_internals",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1737,9 +1905,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.197"
|
||||
version = "1.0.202"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
@ -1755,31 +1923,31 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.197"
|
||||
version = "1.0.202"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive_internals"
|
||||
version = "0.26.0"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c"
|
||||
checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.115"
|
||||
version = "1.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
|
||||
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
||||
dependencies = [
|
||||
"indexmap 2.2.3",
|
||||
"itoa",
|
||||
@ -1795,7 +1963,16 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1807,7 +1984,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1918,6 +2095,12 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9557cb6521e8d009c51a8666f09356f4b817ba9ba0981a305bd86aee47bd35c"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "structmeta"
|
||||
version = "0.2.0"
|
||||
@ -1927,7 +2110,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"structmeta-derive 0.2.0",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1939,7 +2122,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"structmeta-derive 0.3.0",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1950,7 +2133,7 @@ checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1961,7 +2144,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1979,7 +2162,7 @@ version = "0.24.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
@ -2005,9 +2188,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.58"
|
||||
version = "2.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
|
||||
checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -2028,7 +2211,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2069,22 +2252,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.58"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
|
||||
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.58"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2157,7 +2340,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2166,7 +2349,7 @@ version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
|
||||
dependencies = [
|
||||
"rustls 0.21.7",
|
||||
"rustls 0.21.12",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@ -2176,7 +2359,7 @@ version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
|
||||
dependencies = [
|
||||
"rustls 0.22.2",
|
||||
"rustls 0.22.4",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
]
|
||||
@ -2189,7 +2372,7 @@ checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"rustls 0.22.2",
|
||||
"rustls 0.22.4",
|
||||
"rustls-native-certs",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
@ -2211,6 +2394,40 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c"
|
||||
dependencies = [
|
||||
"indexmap 2.2.3",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow 0.6.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.13"
|
||||
@ -2263,7 +2480,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2292,7 +2509,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2316,8 +2533,10 @@ version = "7.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc2cae1fc5d05d47aa24b64f9a4f7cba24cdc9187a2084dd97ac57bef5eccae6"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"thiserror",
|
||||
"ts-rs-macros",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
@ -2330,7 +2549,7 @@ dependencies = [
|
||||
"Inflector",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
@ -2347,7 +2566,7 @@ dependencies = [
|
||||
"httparse",
|
||||
"log",
|
||||
"rand",
|
||||
"rustls 0.22.2",
|
||||
"rustls 0.22.4",
|
||||
"rustls-pki-types",
|
||||
"sha1",
|
||||
"thiserror",
|
||||
@ -2397,6 +2616,12 @@ version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
@ -2411,9 +2636,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.4.1"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
|
||||
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
@ -2427,6 +2652,12 @@ version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.8.0"
|
||||
@ -2439,6 +2670,36 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "validator"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db79c75af171630a3148bd3e6d7c4f42b6a9a014c2945bc5ed0020cbb8d9478e"
|
||||
dependencies = [
|
||||
"idna",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"url",
|
||||
"validator_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "validator_derive"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55591299b7007f551ed1eb79a684af7672c19c3193fb9e0a31936987bb2438ec"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"once_cell",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
@ -2481,7 +2742,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -2515,7 +2776,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.58",
|
||||
"syn 2.0.64",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@ -2736,6 +2997,15 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.50.0"
|
||||
|
@ -1214,7 +1214,11 @@ impl CallExpression {
|
||||
let func = memory.get(&fn_name, self.into())?;
|
||||
let result = func
|
||||
.call_fn(fn_args, memory.clone(), ctx.clone())
|
||||
.await?
|
||||
.await
|
||||
.map_err(|e| {
|
||||
// Add the call expression to the source ranges.
|
||||
e.add_source_ranges(vec![self.into()])
|
||||
})?
|
||||
.ok_or_else(|| {
|
||||
KclError::UndefinedValue(KclErrorDetails {
|
||||
message: format!("Result of user-defined function {} is undefined", fn_name),
|
||||
|
@ -142,6 +142,25 @@ impl KclError {
|
||||
|
||||
new
|
||||
}
|
||||
|
||||
pub fn add_source_ranges(&self, source_ranges: Vec<SourceRange>) -> Self {
|
||||
let mut new = self.clone();
|
||||
match &mut new {
|
||||
KclError::Lexical(e) => e.source_ranges.extend(source_ranges),
|
||||
KclError::Syntax(e) => e.source_ranges.extend(source_ranges),
|
||||
KclError::Semantic(e) => e.source_ranges.extend(source_ranges),
|
||||
KclError::Type(e) => e.source_ranges.extend(source_ranges),
|
||||
KclError::Unimplemented(e) => e.source_ranges.extend(source_ranges),
|
||||
KclError::Unexpected(e) => e.source_ranges.extend(source_ranges),
|
||||
KclError::ValueAlreadyDefined(e) => e.source_ranges.extend(source_ranges),
|
||||
KclError::UndefinedValue(e) => e.source_ranges.extend(source_ranges),
|
||||
KclError::InvalidExpression(e) => e.source_ranges.extend(source_ranges),
|
||||
KclError::Engine(e) => e.source_ranges.extend(source_ranges),
|
||||
KclError::Internal(e) => e.source_ranges.extend(source_ranges),
|
||||
}
|
||||
|
||||
new
|
||||
}
|
||||
}
|
||||
|
||||
/// This is different than to_string() in that it will serialize the Error
|
||||
|
@ -498,14 +498,13 @@ impl Backend {
|
||||
for (entry, value) in self.code_map.inner().await.iter() {
|
||||
let file_name = entry.replace("file://", "").to_string();
|
||||
|
||||
let options = zip::write::FileOptions::default().compression_method(zip::CompressionMethod::Stored);
|
||||
let options = zip::write::SimpleFileOptions::default().compression_method(zip::CompressionMethod::Stored);
|
||||
zip.start_file(file_name, options)?;
|
||||
zip.write_all(value)?;
|
||||
}
|
||||
// Apply the changes you've made.
|
||||
// Dropping the `ZipWriter` will have the same effect, but may silently fail
|
||||
zip.finish()?;
|
||||
drop(zip);
|
||||
|
||||
Ok(buf)
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! Types for interacting with files in projects.
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::Result;
|
||||
@ -7,7 +8,7 @@ use parse_display::{Display, FromStr};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::settings::types::{Configuration, DEFAULT_PROJECT_KCL_FILE};
|
||||
use crate::settings::types::Configuration;
|
||||
|
||||
/// State management for the application.
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, JsonSchema, ts_rs::TS, PartialEq)]
|
||||
@ -48,7 +49,7 @@ impl ProjectState {
|
||||
.map_err(|e| anyhow::anyhow!("Error loading project from path {}: {:?}", source_path.display(), e))?;
|
||||
|
||||
// Check if we have a main.kcl file in the project.
|
||||
let project_file = source_path.join(DEFAULT_PROJECT_KCL_FILE);
|
||||
let project_file = source_path.join(crate::settings::types::DEFAULT_PROJECT_KCL_FILE);
|
||||
|
||||
if !project_file.exists() {
|
||||
// Create the default file in the project.
|
||||
@ -93,6 +94,44 @@ impl ProjectState {
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Error loading project from path {}: {:?}", source_path.display(), e))?;
|
||||
|
||||
// If we got a import model file, we need to check if we have a file in the project for
|
||||
// this import model.
|
||||
if crate::settings::utils::IMPORT_FILE_EXTENSIONS.contains(&ext) {
|
||||
let import_file_name = source_path
|
||||
.file_name()
|
||||
.ok_or_else(|| anyhow::anyhow!("Error getting the file name of the file: {}", source_path.display()))?
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
// Check if we have a file in the project for this import model.
|
||||
let kcl_wrapper_filename = format!("{}.kcl", import_file_name);
|
||||
let kcl_wrapper_file_path = parent.join(&kcl_wrapper_filename);
|
||||
|
||||
if !kcl_wrapper_file_path.exists() {
|
||||
// Create the file in the project.
|
||||
// With the default import content.
|
||||
tokio::fs::write(
|
||||
&kcl_wrapper_file_path,
|
||||
format!(
|
||||
r#"// This file was automatically generated by the application when you
|
||||
// double-clicked on the model file.
|
||||
// You can edit this file to add your own content.
|
||||
// But we recommend you keep the import statement as it is.
|
||||
// For more information on the import statement, see the documentation at:
|
||||
// https://zoo.dev/docs/kcl/import
|
||||
const model = import("{}")"#,
|
||||
import_file_name
|
||||
)
|
||||
.as_bytes(),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
return Ok(ProjectState {
|
||||
project,
|
||||
current_file: Some(kcl_wrapper_file_path.display().to_string()),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(ProjectState {
|
||||
project,
|
||||
current_file: Some(source_path.display().to_string()),
|
||||
@ -209,6 +248,8 @@ pub struct Project {
|
||||
#[serde(default)]
|
||||
#[ts(type = "number")]
|
||||
pub directory_count: u64,
|
||||
/// The default file to open on load.
|
||||
pub default_file: String,
|
||||
}
|
||||
|
||||
impl Project {
|
||||
@ -228,12 +269,13 @@ impl Project {
|
||||
}
|
||||
|
||||
let file = crate::settings::utils::walk_dir(&path).await?;
|
||||
let metadata = std::fs::metadata(path).ok().map(|m| m.into());
|
||||
let metadata = std::fs::metadata(&path).ok().map(|m| m.into());
|
||||
let mut project = Self {
|
||||
file,
|
||||
file: file.clone(),
|
||||
metadata,
|
||||
kcl_file_count: 0,
|
||||
directory_count: 0,
|
||||
default_file: get_default_kcl_file_for_dir(path, file).await?,
|
||||
};
|
||||
project.populate_kcl_file_count()?;
|
||||
project.populate_directory_count()?;
|
||||
@ -271,6 +313,40 @@ impl Project {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the default KCL file for a directory.
|
||||
/// This determines what the default file to open is.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[async_recursion::async_recursion]
|
||||
pub async fn get_default_kcl_file_for_dir<P>(dir: P, file: FileEntry) -> Result<String>
|
||||
where
|
||||
P: AsRef<Path> + Send,
|
||||
{
|
||||
// Make sure the dir is a directory.
|
||||
if !dir.as_ref().is_dir() {
|
||||
return Err(anyhow::anyhow!("Path `{}` is not a directory", dir.as_ref().display()));
|
||||
}
|
||||
|
||||
let default_file = dir.as_ref().join(crate::settings::types::DEFAULT_PROJECT_KCL_FILE);
|
||||
if !default_file.exists() {
|
||||
// Find a kcl file in the directory.
|
||||
if let Some(children) = file.children {
|
||||
for entry in children.iter() {
|
||||
if entry.name.ends_with(".kcl") {
|
||||
return Ok(dir.as_ref().join(&entry.name).display().to_string());
|
||||
} else if entry.children.is_some() {
|
||||
// Recursively find a kcl file in the directory.
|
||||
return get_default_kcl_file_for_dir(entry.path.clone(), entry.clone()).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find a kcl file, create one.
|
||||
tokio::fs::write(&default_file, vec![]).await?;
|
||||
}
|
||||
|
||||
Ok(default_file.display().to_string())
|
||||
}
|
||||
|
||||
/// Information about a file or directory.
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, JsonSchema, ts_rs::TS, PartialEq)]
|
||||
#[ts(export)]
|
||||
@ -550,4 +626,100 @@ mod tests {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_project_route_from_route_non_main_file() {
|
||||
let mut configuration = crate::settings::types::Configuration::default();
|
||||
configuration.settings.project.directory =
|
||||
std::path::PathBuf::from("/Users/macinatormax/Documents/kittycad-modeling-projects");
|
||||
|
||||
let route = "/Users/macinatormax/Documents/kittycad-modeling-projects/assembly/thing.kcl";
|
||||
let state = super::ProjectRoute::from_route(&configuration, route).unwrap();
|
||||
assert_eq!(
|
||||
state,
|
||||
super::ProjectRoute {
|
||||
project_name: Some("assembly".to_string()),
|
||||
project_path: "/Users/macinatormax/Documents/kittycad-modeling-projects/assembly".to_string(),
|
||||
current_file_name: Some("thing.kcl".to_string()),
|
||||
current_file_path: Some(
|
||||
"/Users/macinatormax/Documents/kittycad-modeling-projects/assembly/thing.kcl".to_string()
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_default_kcl_file_for_dir_non_exist() {
|
||||
let name = format!("kittycad-modeling-projects-{}", uuid::Uuid::new_v4());
|
||||
let dir = std::env::temp_dir().join(&name);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let file = crate::settings::utils::walk_dir(&dir).await.unwrap();
|
||||
|
||||
let default_file = super::get_default_kcl_file_for_dir(&dir, file).await.unwrap();
|
||||
assert_eq!(default_file, dir.join("main.kcl").display().to_string());
|
||||
|
||||
std::fs::remove_dir_all(dir).unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_default_kcl_file_for_dir_main_kcl() {
|
||||
let name = format!("kittycad-modeling-projects-{}", uuid::Uuid::new_v4());
|
||||
let dir = std::env::temp_dir().join(&name);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
std::fs::write(dir.join("main.kcl"), vec![]).unwrap();
|
||||
let file = crate::settings::utils::walk_dir(&dir).await.unwrap();
|
||||
|
||||
let default_file = super::get_default_kcl_file_for_dir(&dir, file).await.unwrap();
|
||||
assert_eq!(default_file, dir.join("main.kcl").display().to_string());
|
||||
|
||||
std::fs::remove_dir_all(dir).unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_default_kcl_file_for_dir_thing_kcl() {
|
||||
let name = format!("kittycad-modeling-projects-{}", uuid::Uuid::new_v4());
|
||||
let dir = std::env::temp_dir().join(&name);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
std::fs::write(dir.join("thing.kcl"), vec![]).unwrap();
|
||||
let file = crate::settings::utils::walk_dir(&dir).await.unwrap();
|
||||
|
||||
let default_file = super::get_default_kcl_file_for_dir(&dir, file).await.unwrap();
|
||||
assert_eq!(default_file, dir.join("thing.kcl").display().to_string());
|
||||
std::fs::remove_dir_all(dir).unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_default_kcl_file_for_dir_nested_main_kcl() {
|
||||
let name = format!("kittycad-modeling-projects-{}", uuid::Uuid::new_v4());
|
||||
let dir = std::env::temp_dir().join(&name);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
std::fs::create_dir_all(dir.join("assembly")).unwrap();
|
||||
std::fs::write(dir.join("assembly").join("main.kcl"), vec![]).unwrap();
|
||||
let file = crate::settings::utils::walk_dir(&dir).await.unwrap();
|
||||
|
||||
let default_file = super::get_default_kcl_file_for_dir(&dir, file).await.unwrap();
|
||||
assert_eq!(
|
||||
default_file,
|
||||
dir.join("assembly").join("main.kcl").display().to_string()
|
||||
);
|
||||
|
||||
std::fs::remove_dir_all(dir).unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_default_kcl_file_for_dir_nested_thing_kcl() {
|
||||
let name = format!("kittycad-modeling-projects-{}", uuid::Uuid::new_v4());
|
||||
let dir = std::env::temp_dir().join(&name);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
std::fs::create_dir_all(dir.join("assembly")).unwrap();
|
||||
std::fs::write(dir.join("assembly").join("thing.kcl"), vec![]).unwrap();
|
||||
let file = crate::settings::utils::walk_dir(&dir).await.unwrap();
|
||||
|
||||
let default_file = super::get_default_kcl_file_for_dir(&dir, file).await.unwrap();
|
||||
assert_eq!(
|
||||
default_file,
|
||||
dir.join("assembly").join("thing.kcl").display().to_string()
|
||||
);
|
||||
std::fs::remove_dir_all(dir).unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -109,6 +109,7 @@ impl Configuration {
|
||||
// Because we just created it and it's empty.
|
||||
children: None,
|
||||
},
|
||||
default_file: project_file.to_string_lossy().to_string(),
|
||||
metadata: Some(tokio::fs::metadata(&project_dir).await?.into()),
|
||||
kcl_file_count: 1,
|
||||
directory_count: 0,
|
||||
@ -130,7 +131,13 @@ impl Configuration {
|
||||
continue;
|
||||
}
|
||||
|
||||
projects.push(self.get_project_info(&e.path().display().to_string()).await?);
|
||||
// Make sure the project has at least one kcl file in it.
|
||||
let project = self.get_project_info(&e.path().display().to_string()).await?;
|
||||
if project.kcl_file_count == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
projects.push(project);
|
||||
}
|
||||
|
||||
Ok(projects)
|
||||
@ -150,11 +157,14 @@ impl Configuration {
|
||||
return Err(anyhow::anyhow!("Project path is not a directory: {}", project_path));
|
||||
}
|
||||
|
||||
let walked = crate::settings::utils::walk_dir(project_dir).await?;
|
||||
|
||||
let mut project = crate::settings::types::file::Project {
|
||||
file: crate::settings::utils::walk_dir(project_dir).await?,
|
||||
file: walked.clone(),
|
||||
metadata: Some(tokio::fs::metadata(&project_dir).await?.into()),
|
||||
kcl_file_count: 0,
|
||||
directory_count: 0,
|
||||
default_file: crate::settings::types::file::get_default_kcl_file_for_dir(project_dir, walked).await?,
|
||||
};
|
||||
|
||||
// Populate the number of KCL files in the project.
|
||||
|
@ -8,14 +8,21 @@ use clap::ValueEnum;
|
||||
use crate::settings::types::file::FileEntry;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref RELEVANT_EXTENSIONS: Vec<String> = {
|
||||
let mut relevant_extensions = vec!["kcl".to_string(), "stp".to_string(), "glb".to_string(), "fbxb".to_string()];
|
||||
|
||||
pub static ref IMPORT_FILE_EXTENSIONS: Vec<String> = {
|
||||
let mut import_file_extensions = vec!["stp".to_string(), "glb".to_string(), "fbxb".to_string()];
|
||||
let named_extensions = kittycad::types::FileImportFormat::value_variants()
|
||||
.iter()
|
||||
.map(|x| format!("{}", x))
|
||||
.collect::<Vec<String>>();
|
||||
// Add all the default import formats.
|
||||
relevant_extensions.extend_from_slice(&named_extensions);
|
||||
import_file_extensions.extend_from_slice(&named_extensions);
|
||||
import_file_extensions
|
||||
};
|
||||
|
||||
pub static ref RELEVANT_EXTENSIONS: Vec<String> = {
|
||||
let mut relevant_extensions = IMPORT_FILE_EXTENSIONS.clone();
|
||||
relevant_extensions.push("kcl".to_string());
|
||||
relevant_extensions
|
||||
};
|
||||
}
|
||||
@ -26,6 +33,16 @@ pub async fn walk_dir<P>(dir: P) -> Result<FileEntry>
|
||||
where
|
||||
P: AsRef<Path> + Send,
|
||||
{
|
||||
// Make sure the path is a directory.
|
||||
if !dir.as_ref().is_dir() {
|
||||
return Err(anyhow::anyhow!("Path `{}` is not a directory", dir.as_ref().display()));
|
||||
}
|
||||
|
||||
// Make sure the directory exists.
|
||||
if !dir.as_ref().exists() {
|
||||
return Err(anyhow::anyhow!("Directory `{}` does not exist", dir.as_ref().display()));
|
||||
}
|
||||
|
||||
let mut entry = FileEntry {
|
||||
name: dir
|
||||
.as_ref()
|
||||
|
@ -129,27 +129,27 @@ pub async fn import(args: Args) -> Result<MemoryItem, KclError> {
|
||||
/// not in browser.
|
||||
///
|
||||
/// ```no_run
|
||||
/// const model = import("thing.obj")
|
||||
/// const model = import("tests/inputs/cube.obj")
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
/// const model = import("cube.obj", {type: "obj", units: "m"})
|
||||
/// const model = import("tests/inputs/cube.obj", {type: "obj", units: "m"})
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
/// const model = import("my_model.gltf")
|
||||
/// const model = import("tests/inputs/cube.gltf")
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
/// const model = import("my_model.sldprt")
|
||||
/// const model = import("tests/inputs/cube.sldprt")
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
/// const model = import("my_model.step")
|
||||
/// const model = import("tests/inputs/cube.step")
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "import",
|
||||
tags = ["norun"],
|
||||
tags = [],
|
||||
}]
|
||||
async fn inner_import(
|
||||
file_path: String,
|
||||
@ -163,6 +163,9 @@ async fn inner_import(
|
||||
}));
|
||||
}
|
||||
|
||||
//print the current working directory
|
||||
println!("Current working directory: {:?}", std::env::current_dir().unwrap());
|
||||
|
||||
// Make sure the file exists.
|
||||
if !args.ctx.fs.exists(&file_path, args.source_range).await? {
|
||||
return Err(KclError::Semantic(KclErrorDetails {
|
||||
|
@ -239,7 +239,7 @@ pub async fn max(args: Args) -> Result<MemoryItem, KclError> {
|
||||
tags = ["math"],
|
||||
}]
|
||||
fn inner_max(args: Vec<f64>) -> f64 {
|
||||
let mut max = std::f64::MAX;
|
||||
let mut max = std::f64::MIN;
|
||||
for arg in args.iter() {
|
||||
if *arg > max {
|
||||
max = *arg;
|
||||
@ -533,3 +533,38 @@ pub async fn to_degrees(args: Args) -> Result<MemoryItem, KclError> {
|
||||
fn inner_to_degrees(num: f64) -> Result<f64, KclError> {
|
||||
Ok(num.to_degrees())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_inner_max() {
|
||||
let nums = vec![4.0, 5.0, 6.0];
|
||||
let result = inner_max(nums);
|
||||
assert_eq!(result, 6.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inner_max_with_neg() {
|
||||
let nums = vec![4.0, -5.0];
|
||||
let result = inner_max(nums);
|
||||
assert_eq!(result, 4.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inner_min() {
|
||||
let nums = vec![4.0, 5.0, 6.0];
|
||||
let result = inner_min(nums);
|
||||
assert_eq!(result, 4.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inner_min_with_neg() {
|
||||
let nums = vec![4.0, -5.0];
|
||||
let result = inner_min(nums);
|
||||
assert_eq!(result, -5.0);
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,9 @@ lazy_static! {
|
||||
Box::new(crate::std::sketch::StartSketchAt),
|
||||
Box::new(crate::std::sketch::StartSketchOn),
|
||||
Box::new(crate::std::sketch::StartProfileAt),
|
||||
Box::new(crate::std::sketch::ProfileStartX),
|
||||
Box::new(crate::std::sketch::ProfileStartY),
|
||||
Box::new(crate::std::sketch::ProfileStart),
|
||||
Box::new(crate::std::sketch::Close),
|
||||
Box::new(crate::std::sketch::Arc),
|
||||
Box::new(crate::std::sketch::TangentialArc),
|
||||
@ -1058,9 +1061,7 @@ layout: manual
|
||||
fn_docs.push_str("\n```\n\n");
|
||||
|
||||
// If the function has tags, we should add them to the docs.
|
||||
let mut tags = internal_fn.tags().clone();
|
||||
// Remove norun tag from the list of tags.
|
||||
tags.retain(|tag| tag != "norun");
|
||||
let tags = internal_fn.tags().clone();
|
||||
if !tags.is_empty() {
|
||||
fn_docs.push_str("### Tags\n\n");
|
||||
for tag in tags {
|
||||
@ -1079,9 +1080,7 @@ layout: manual
|
||||
|
||||
// If this is not a "utilities" function,
|
||||
// we should add the image to the docs.
|
||||
if !internal_fn.tags().contains(&"utilities".to_string())
|
||||
&& !internal_fn.tags().contains(&"norun".to_string())
|
||||
{
|
||||
if !internal_fn.tags().contains(&"utilities".to_string()) {
|
||||
// Get the path to this specific rust file.
|
||||
let dir = env!("CARGO_MANIFEST_DIR");
|
||||
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||
errors::{KclError, KclErrorDetails},
|
||||
executor::{
|
||||
BasePath, ExtrudeGroup, ExtrudeSurface, Face, GeoMeta, MemoryItem, Path, Plane, PlaneType, Point2d, Point3d,
|
||||
Position, Rotation, SketchGroup, SketchGroupSet, SketchSurface, SourceRange,
|
||||
Position, Rotation, SketchGroup, SketchGroupSet, SketchSurface, SourceRange, UserVal,
|
||||
},
|
||||
std::{
|
||||
utils::{
|
||||
@ -995,7 +995,14 @@ async fn start_sketch_on_face(
|
||||
args: Args,
|
||||
) -> Result<Box<Face>, KclError> {
|
||||
let extrude_plane_id = match tag {
|
||||
SketchOnFaceTag::String(ref s) => extrude_group
|
||||
SketchOnFaceTag::String(ref s) => {
|
||||
if s.is_empty() {
|
||||
return Err(KclError::Type(KclErrorDetails {
|
||||
message: "Expected a non-empty tag for the face to sketch on".to_string(),
|
||||
source_ranges: vec![args.source_range],
|
||||
}));
|
||||
}
|
||||
extrude_group
|
||||
.value
|
||||
.iter()
|
||||
.find_map(|extrude_surface| match extrude_surface {
|
||||
@ -1015,7 +1022,8 @@ async fn start_sketch_on_face(
|
||||
message: format!("Expected a face with the tag `{}`", tag),
|
||||
source_ranges: vec![args.source_range],
|
||||
})
|
||||
})??,
|
||||
})??
|
||||
}
|
||||
SketchOnFaceTag::StartOrEnd(StartOrEnd::Start) => extrude_group.start_cap_id.ok_or_else(|| {
|
||||
KclError::Type(KclErrorDetails {
|
||||
message: "Expected a start face to sketch on".to_string(),
|
||||
@ -1206,6 +1214,78 @@ pub(crate) async fn inner_start_profile_at(
|
||||
Ok(Box::new(sketch_group))
|
||||
}
|
||||
|
||||
/// Returns the X component of the sketch profile start point.
|
||||
pub async fn profile_start_x(args: Args) -> Result<MemoryItem, KclError> {
|
||||
let sketch_group: Box<SketchGroup> = args.get_sketch_group()?;
|
||||
let x = inner_profile_start_x(sketch_group)?;
|
||||
args.make_user_val_from_f64(x)
|
||||
}
|
||||
|
||||
/// ```no_run
|
||||
/// const sketch001 = startSketchOn('XY')
|
||||
/// |> startProfileAt([5, 2], %)
|
||||
/// |> angledLine([-26.6, 50], %)
|
||||
/// |> angledLine([90, 50], %)
|
||||
/// |> angledLineToX({ angle: 30, to: profileStartX(%) }, %)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "profileStartX"
|
||||
}]
|
||||
pub(crate) fn inner_profile_start_x(sketch_group: Box<SketchGroup>) -> Result<f64, KclError> {
|
||||
Ok(sketch_group.start.to[0])
|
||||
}
|
||||
|
||||
/// Returns the Y component of the sketch profile start point.
|
||||
pub async fn profile_start_y(args: Args) -> Result<MemoryItem, KclError> {
|
||||
let sketch_group: Box<SketchGroup> = args.get_sketch_group()?;
|
||||
let x = inner_profile_start_y(sketch_group)?;
|
||||
args.make_user_val_from_f64(x)
|
||||
}
|
||||
|
||||
/// ```no_run
|
||||
/// const sketch001 = startSketchOn('XY')
|
||||
/// |> startProfileAt([5, 2], %)
|
||||
/// |> angledLine({ angle: -60, length: 14 }, %)
|
||||
/// |> angledLineToY({ angle: 30, to: profileStartY(%) }, %)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "profileStartY"
|
||||
}]
|
||||
pub(crate) fn inner_profile_start_y(sketch_group: Box<SketchGroup>) -> Result<f64, KclError> {
|
||||
Ok(sketch_group.start.to[1])
|
||||
}
|
||||
|
||||
/// Returns the sketch profile start point.
|
||||
pub async fn profile_start(args: Args) -> Result<MemoryItem, KclError> {
|
||||
let sketch_group: Box<SketchGroup> = args.get_sketch_group()?;
|
||||
let point = inner_profile_start(sketch_group)?;
|
||||
Ok(MemoryItem::UserVal(UserVal {
|
||||
value: serde_json::to_value(point).map_err(|e| {
|
||||
KclError::Type(KclErrorDetails {
|
||||
message: format!("Failed to convert point to json: {}", e),
|
||||
source_ranges: vec![args.source_range],
|
||||
})
|
||||
})?,
|
||||
meta: Default::default(),
|
||||
}))
|
||||
}
|
||||
|
||||
/// ```no_run
|
||||
/// const sketch001 = startSketchOn('XY')
|
||||
/// |> startProfileAt([5, 2], %)
|
||||
/// |> angledLine({ angle: 120, length: 50 }, %, 'seg01')
|
||||
/// |> angledLine({ angle: segAng('seg01', %) + 120, length: 50 }, %)
|
||||
/// |> lineTo(profileStart(%), %)
|
||||
/// |> close(%)
|
||||
/// |> extrude(20, %)
|
||||
/// ```
|
||||
#[stdlib {
|
||||
name = "profileStart"
|
||||
}]
|
||||
pub(crate) fn inner_profile_start(sketch_group: Box<SketchGroup>) -> Result<[f64; 2], KclError> {
|
||||
Ok(sketch_group.start.to)
|
||||
}
|
||||
|
||||
/// Close the current sketch.
|
||||
pub async fn close(args: Args) -> Result<MemoryItem, KclError> {
|
||||
let (sketch_group, tag): (Box<SketchGroup>, Option<String>) = args.get_sketch_group_and_optional_tag()?;
|
||||
|
108
src/wasm-lib/kcl/tests/inputs/cube.gltf
Normal file
@ -0,0 +1,108 @@
|
||||
{
|
||||
"asset": {
|
||||
"generator": "Khronos glTF Blender I/O v3.4.50",
|
||||
"version": "2.0"
|
||||
},
|
||||
"scene": 0,
|
||||
"scenes": [
|
||||
{
|
||||
"name": "Scene",
|
||||
"nodes": [0]
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"mesh": 0,
|
||||
"name": "Cube"
|
||||
}
|
||||
],
|
||||
"materials": [
|
||||
{
|
||||
"doubleSided": true,
|
||||
"name": "Material",
|
||||
"pbrMetallicRoughness": {
|
||||
"baseColorFactor": [
|
||||
0.800000011920929, 0.800000011920929, 0.800000011920929, 1
|
||||
],
|
||||
"metallicFactor": 0,
|
||||
"roughnessFactor": 0.5
|
||||
}
|
||||
}
|
||||
],
|
||||
"meshes": [
|
||||
{
|
||||
"name": "Cube",
|
||||
"primitives": [
|
||||
{
|
||||
"attributes": {
|
||||
"POSITION": 0,
|
||||
"TEXCOORD_0": 1,
|
||||
"NORMAL": 2
|
||||
},
|
||||
"indices": 3,
|
||||
"material": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"accessors": [
|
||||
{
|
||||
"bufferView": 0,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"max": [1, 1, 1],
|
||||
"min": [-1, -1, -1],
|
||||
"type": "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView": 1,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"type": "VEC2"
|
||||
},
|
||||
{
|
||||
"bufferView": 2,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"type": "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView": 3,
|
||||
"componentType": 5123,
|
||||
"count": 36,
|
||||
"type": "SCALAR"
|
||||
}
|
||||
],
|
||||
"bufferViews": [
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteLength": 288,
|
||||
"byteOffset": 0,
|
||||
"target": 34962
|
||||
},
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteLength": 192,
|
||||
"byteOffset": 288,
|
||||
"target": 34962
|
||||
},
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteLength": 288,
|
||||
"byteOffset": 480,
|
||||
"target": 34962
|
||||
},
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteLength": 72,
|
||||
"byteOffset": 768,
|
||||
"target": 34963
|
||||
}
|
||||
],
|
||||
"buffers": [
|
||||
{
|
||||
"byteLength": 840,
|
||||
"uri": "data:application/octet-stream;base64,AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AAAgPwAAAD8AACA/AAAAPwAAID8AAAA/AADAPgAAAD8AAMA+AAAAPwAAwD4AAAA/AAAgPwAAgD4AACA/AACAPgAAID8AAIA+AADAPgAAgD4AAMA+AACAPgAAwD4AAIA+AAAgPwAAQD8AACA/AABAPwAAYD8AAAA/AAAAPgAAAD8AAMA+AABAPwAAwD4AAEA/AAAgPwAAAAAAACA/AACAPwAAYD8AAIA+AAAAPgAAgD4AAMA+AAAAAAAAwD4AAIA/AAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAPwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAPwAAAAAAAACAAACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAAAAAAAAgL8AAACAAACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIA/AACAvwAAAAAAAACAAAAAAAAAgD8AAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAvwAAAAAAAACAAQAOABQAAQAUAAcACgAGABIACgASABYAFwATAAwAFwAMABAADwADAAkADwAJABUABQACAAgABQAIAAsAEQANAAAAEQAAAAQA"
|
||||
}
|
||||
]
|
||||
}
|
12
src/wasm-lib/kcl/tests/inputs/cube.mtl
Normal file
@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl Material
|
||||
Ns 359.999993
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Kd 0.800000 0.800000 0.800000
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.450000
|
||||
d 1.000000
|
||||
illum 2
|
40
src/wasm-lib/kcl/tests/inputs/cube.obj
Normal file
@ -0,0 +1,40 @@
|
||||
# Blender v3.2.2 OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib cube.mtl
|
||||
o Cube
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 1.000000 -1.000000
|
||||
vt 0.625000 0.500000
|
||||
vt 0.875000 0.500000
|
||||
vt 0.875000 0.750000
|
||||
vt 0.625000 0.750000
|
||||
vt 0.375000 0.750000
|
||||
vt 0.625000 1.000000
|
||||
vt 0.375000 1.000000
|
||||
vt 0.375000 0.000000
|
||||
vt 0.625000 0.000000
|
||||
vt 0.625000 0.250000
|
||||
vt 0.375000 0.250000
|
||||
vt 0.125000 0.500000
|
||||
vt 0.375000 0.500000
|
||||
vt 0.125000 0.750000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
usemtl Material
|
||||
s off
|
||||
f 1/1/1 5/2/1 7/3/1 3/4/1
|
||||
f 4/5/2 3/4/2 7/6/2 8/7/2
|
||||
f 8/8/3 7/9/3 5/10/3 6/11/3
|
||||
f 6/12/4 2/13/4 4/5/4 8/14/4
|
||||
f 2/13/5 1/1/5 3/4/5 4/5/5
|
||||
f 6/11/6 5/10/6 1/1/6 2/13/6
|
BIN
src/wasm-lib/kcl/tests/inputs/cube.sldprt
Normal file
254
src/wasm-lib/kcl/tests/inputs/cube.step
Normal file
@ -0,0 +1,254 @@
|
||||
ISO-10303-21;
|
||||
HEADER;
|
||||
FILE_DESCRIPTION (( 'STEP AP203' ),
|
||||
'1' );
|
||||
FILE_NAME ('Cube_1m.STEP',
|
||||
'2023-07-31T15:10:19',
|
||||
( '' ),
|
||||
( '' ),
|
||||
'SwSTEP 2.0',
|
||||
'SolidWorks 2023',
|
||||
'' );
|
||||
FILE_SCHEMA (( 'CONFIG_CONTROL_DESIGN' ));
|
||||
ENDSEC;
|
||||
|
||||
DATA;
|
||||
#1 = AXIS2_PLACEMENT_3D ( 'NONE', #133, #116, #72 ) ;
|
||||
#2 =( LENGTH_UNIT ( ) NAMED_UNIT ( * ) SI_UNIT ( .MILLI., .METRE. ) );
|
||||
#3 = FACE_OUTER_BOUND ( 'NONE', #99, .T. ) ;
|
||||
#4 = CARTESIAN_POINT ( 'NONE', ( 500.0000000000000000, 1000.000000000000000, -500.0000000000000000 ) ) ;
|
||||
#5 = VECTOR ( 'NONE', #233, 1000.000000000000000 ) ;
|
||||
#6 = ORIENTED_EDGE ( 'NONE', *, *, #15, .T. ) ;
|
||||
#7 = DIRECTION ( 'NONE', ( -0.000000000000000000, -1.000000000000000000, -0.000000000000000000 ) ) ;
|
||||
#8 = ORIENTED_EDGE ( 'NONE', *, *, #75, .T. ) ;
|
||||
#9 = VECTOR ( 'NONE', #205, 1000.000000000000000 ) ;
|
||||
#10 = LOCAL_TIME ( 11, 10, 19.00000000000000000, #88 ) ;
|
||||
#11 = PLANE ( 'NONE', #220 ) ;
|
||||
#12 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 1000.000000000000000, 500.0000000000000000 ) ) ;
|
||||
#13 = DIRECTION ( 'NONE', ( -0.000000000000000000, -1.000000000000000000, -0.000000000000000000 ) ) ;
|
||||
#14 = CARTESIAN_POINT ( 'NONE', ( 500.0000000000000000, 1000.000000000000000, -500.0000000000000000 ) ) ;
|
||||
#15 = EDGE_CURVE ( 'NONE', #40, #58, #139, .T. ) ;
|
||||
#16 = CALENDAR_DATE ( 2023, 31, 7 ) ;
|
||||
#17 = AXIS2_PLACEMENT_3D ( 'NONE', #175, #73, #126 ) ;
|
||||
#18 = PERSON_AND_ORGANIZATION ( #134, #228 ) ;
|
||||
#19 = PLANE ( 'NONE', #145 ) ;
|
||||
#20 = PERSON_AND_ORGANIZATION ( #134, #228 ) ;
|
||||
#21 =( GEOMETRIC_REPRESENTATION_CONTEXT ( 3 ) GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT ( ( #152 ) ) GLOBAL_UNIT_ASSIGNED_CONTEXT ( ( #2, #168, #174 ) ) REPRESENTATION_CONTEXT ( 'NONE', 'WORKASPACE' ) );
|
||||
#22 = FACE_OUTER_BOUND ( 'NONE', #137, .T. ) ;
|
||||
#23 = PRODUCT_DEFINITION ( 'UNKNOWN', '', #51, #86 ) ;
|
||||
#24 = DIRECTION ( 'NONE', ( 0.000000000000000000, 0.000000000000000000, -1.000000000000000000 ) ) ;
|
||||
#25 = APPLICATION_PROTOCOL_DEFINITION ( 'international standard', 'config_control_design', 1994, #59 ) ;
|
||||
#26 = PLANE ( 'NONE', #17 ) ;
|
||||
#27 = EDGE_LOOP ( 'NONE', ( #141, #8, #121, #123 ) ) ;
|
||||
#28 = CARTESIAN_POINT ( 'NONE', ( 500.0000000000000000, 1000.000000000000000, -500.0000000000000000 ) ) ;
|
||||
#29 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 0.000000000000000000, -500.0000000000000000 ) ) ;
|
||||
#30 = FACE_OUTER_BOUND ( 'NONE', #78, .T. ) ;
|
||||
#31 = LINE ( 'NONE', #183, #179 ) ;
|
||||
#32 = PLANE ( 'NONE', #173 ) ;
|
||||
#33 = VECTOR ( 'NONE', #44, 1000.000000000000000 ) ;
|
||||
#34 = DATE_AND_TIME ( #16, #224 ) ;
|
||||
#35 = ADVANCED_FACE ( 'NONE', ( #198 ), #26, .T. ) ;
|
||||
#36 = CALENDAR_DATE ( 2023, 31, 7 ) ;
|
||||
#37 = VECTOR ( 'NONE', #61, 1000.000000000000000 ) ;
|
||||
#38 = CC_DESIGN_APPROVAL ( #210, ( #51 ) ) ;
|
||||
#39 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 1000.000000000000000, 500.0000000000000000 ) ) ;
|
||||
#40 = VERTEX_POINT ( 'NONE', #98 ) ;
|
||||
#41 = ORIENTED_EDGE ( 'NONE', *, *, #119, .F. ) ;
|
||||
#42 = ORIENTED_EDGE ( 'NONE', *, *, #69, .T. ) ;
|
||||
#43 = CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT ( #167, #188, ( #180 ) ) ;
|
||||
#44 = DIRECTION ( 'NONE', ( 0.000000000000000000, 0.000000000000000000, 1.000000000000000000 ) ) ;
|
||||
#45 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 0.000000000000000000, 500.0000000000000000 ) ) ;
|
||||
#46 = APPLICATION_CONTEXT ( 'configuration controlled 3d designs of mechanical parts and assemblies' ) ;
|
||||
#47 = LINE ( 'NONE', #203, #101 ) ;
|
||||
#48 = ORIENTED_EDGE ( 'NONE', *, *, #144, .F. ) ;
|
||||
#49 = CARTESIAN_POINT ( 'NONE', ( 500.0000000000000000, 0.000000000000000000, 500.0000000000000000 ) ) ;
|
||||
#50 = CARTESIAN_POINT ( 'NONE', ( 500.0000000000000000, 1000.000000000000000, 500.0000000000000000 ) ) ;
|
||||
#51 = PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE ( 'ANY', '', #68, .NOT_KNOWN. ) ;
|
||||
#52 = DATE_AND_TIME ( #110, #186 ) ;
|
||||
#53 = CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT ( #192, #92, ( #68 ) ) ;
|
||||
#54 = DATE_AND_TIME ( #117, #90 ) ;
|
||||
#55 = VECTOR ( 'NONE', #209, 1000.000000000000000 ) ;
|
||||
#56 = PLANE ( 'NONE', #129 ) ;
|
||||
#57 = VERTEX_POINT ( 'NONE', #127 ) ;
|
||||
#58 = VERTEX_POINT ( 'NONE', #49 ) ;
|
||||
#59 = APPLICATION_CONTEXT ( 'configuration controlled 3d designs of mechanical parts and assemblies' ) ;
|
||||
#60 = EDGE_CURVE ( 'NONE', #57, #80, #185, .T. ) ;
|
||||
#61 = DIRECTION ( 'NONE', ( -0.000000000000000000, -1.000000000000000000, -0.000000000000000000 ) ) ;
|
||||
#62 = ORIENTED_EDGE ( 'NONE', *, *, #211, .F. ) ;
|
||||
#63 = LINE ( 'NONE', #232, #236 ) ;
|
||||
#64 = ORIENTED_EDGE ( 'NONE', *, *, #96, .F. ) ;
|
||||
#65 = CARTESIAN_POINT ( 'NONE', ( 500.0000000000000000, 0.000000000000000000, -500.0000000000000000 ) ) ;
|
||||
#66 = PLANE ( 'NONE', #70 ) ;
|
||||
#67 = CLOSED_SHELL ( 'NONE', ( #226, #164, #169, #234, #35, #219 ) ) ;
|
||||
#68 = PRODUCT ( 'Cube_1m', 'Cube_1m', '', ( #155 ) ) ;
|
||||
#69 = EDGE_CURVE ( 'NONE', #80, #120, #31, .T. ) ;
|
||||
#70 = AXIS2_PLACEMENT_3D ( 'NONE', #138, #105, #217 ) ;
|
||||
#71 = DATE_AND_TIME ( #172, #194 ) ;
|
||||
#72 = DIRECTION ( 'NONE', ( 1.000000000000000000, 0.000000000000000000, 0.000000000000000000 ) ) ;
|
||||
#73 = DIRECTION ( 'NONE', ( 0.000000000000000000, 1.000000000000000000, 0.000000000000000000 ) ) ;
|
||||
#74 = VERTEX_POINT ( 'NONE', #124 ) ;
|
||||
#75 = EDGE_CURVE ( 'NONE', #80, #135, #81, .T. ) ;
|
||||
#76 = LINE ( 'NONE', #50, #170 ) ;
|
||||
#77 = CC_DESIGN_APPROVAL ( #166, ( #23 ) ) ;
|
||||
#78 = EDGE_LOOP ( 'NONE', ( #97, #199, #230, #42 ) ) ;
|
||||
#79 = CARTESIAN_POINT ( 'NONE', ( 0.000000000000000000, 0.000000000000000000, 0.000000000000000000 ) ) ;
|
||||
#80 = VERTEX_POINT ( 'NONE', #28 ) ;
|
||||
#81 = LINE ( 'NONE', #103, #85 ) ;
|
||||
#82 = DIRECTION ( 'NONE', ( -1.000000000000000000, -0.000000000000000000, -0.000000000000000000 ) ) ;
|
||||
#83 = CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT ( #93, #115, ( #23 ) ) ;
|
||||
#84 = APPROVAL_DATE_TIME ( #112, #210 ) ;
|
||||
#85 = VECTOR ( 'NONE', #82, 1000.000000000000000 ) ;
|
||||
#86 = DESIGN_CONTEXT ( 'detailed design', #59, 'design' ) ;
|
||||
#87 = APPROVAL_STATUS ( 'not_yet_approved' ) ;
|
||||
#88 = COORDINATED_UNIVERSAL_TIME_OFFSET ( 5, 0, .BEHIND. ) ;
|
||||
#89 = COORDINATED_UNIVERSAL_TIME_OFFSET ( 5, 0, .BEHIND. ) ;
|
||||
#90 = LOCAL_TIME ( 11, 10, 19.00000000000000000, #154 ) ;
|
||||
#91 = PERSON_AND_ORGANIZATION ( #134, #228 ) ;
|
||||
#92 = PERSON_AND_ORGANIZATION_ROLE ( 'design_owner' ) ;
|
||||
#93 = PERSON_AND_ORGANIZATION ( #134, #228 ) ;
|
||||
#94 = APPLICATION_PROTOCOL_DEFINITION ( 'international standard', 'config_control_design', 1994, #46 ) ;
|
||||
#95 = APPROVAL ( #87, 'UNSPECIFIED' ) ;
|
||||
#96 = EDGE_CURVE ( 'NONE', #74, #57, #162, .T. ) ;
|
||||
#97 = ORIENTED_EDGE ( 'NONE', *, *, #144, .T. ) ;
|
||||
#98 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 0.000000000000000000, 500.0000000000000000 ) ) ;
|
||||
#99 = EDGE_LOOP ( 'NONE', ( #6, #125, #64, #118 ) ) ;
|
||||
#100 = DIRECTION ( 'NONE', ( 1.000000000000000000, 0.000000000000000000, -0.000000000000000000 ) ) ;
|
||||
#101 = VECTOR ( 'NONE', #204, 1000.000000000000000 ) ;
|
||||
#102 = EDGE_LOOP ( 'NONE', ( #178, #202, #41, #48 ) ) ;
|
||||
#103 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 1000.000000000000000, -500.0000000000000000 ) ) ;
|
||||
#104 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 1000.000000000000000, -500.0000000000000000 ) ) ;
|
||||
#105 = DIRECTION ( 'NONE', ( 1.000000000000000000, 0.000000000000000000, 0.000000000000000000 ) ) ;
|
||||
#106 = PRODUCT_RELATED_PRODUCT_CATEGORY ( 'detail', '', ( #68 ) ) ;
|
||||
#107 = EDGE_CURVE ( 'NONE', #135, #215, #140, .T. ) ;
|
||||
#108 = CC_DESIGN_APPROVAL ( #95, ( #180 ) ) ;
|
||||
#109 = SHAPE_DEFINITION_REPRESENTATION ( #146, #222 ) ;
|
||||
#110 = CALENDAR_DATE ( 2023, 31, 7 ) ;
|
||||
#111 = PERSON_AND_ORGANIZATION ( #134, #228 ) ;
|
||||
#112 = DATE_AND_TIME ( #36, #10 ) ;
|
||||
#113 = APPROVAL_PERSON_ORGANIZATION ( #18, #95, #130 ) ;
|
||||
#114 = APPROVAL_PERSON_ORGANIZATION ( #111, #210, #132 ) ;
|
||||
#115 = PERSON_AND_ORGANIZATION_ROLE ( 'creator' ) ;
|
||||
#116 = DIRECTION ( 'NONE', ( 0.000000000000000000, 0.000000000000000000, 1.000000000000000000 ) ) ;
|
||||
#117 = CALENDAR_DATE ( 2023, 31, 7 ) ;
|
||||
#118 = ORIENTED_EDGE ( 'NONE', *, *, #128, .T. ) ;
|
||||
#119 = EDGE_CURVE ( 'NONE', #215, #40, #63, .T. ) ;
|
||||
#120 = VERTEX_POINT ( 'NONE', #159 ) ;
|
||||
#121 = ORIENTED_EDGE ( 'NONE', *, *, #211, .T. ) ;
|
||||
#122 = DIRECTION ( 'NONE', ( 0.000000000000000000, 0.000000000000000000, 1.000000000000000000 ) ) ;
|
||||
#123 = ORIENTED_EDGE ( 'NONE', *, *, #96, .T. ) ;
|
||||
#124 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 1000.000000000000000, 500.0000000000000000 ) ) ;
|
||||
#125 = ORIENTED_EDGE ( 'NONE', *, *, #189, .F. ) ;
|
||||
#126 = DIRECTION ( 'NONE', ( 0.000000000000000000, -0.000000000000000000, 1.000000000000000000 ) ) ;
|
||||
#127 = CARTESIAN_POINT ( 'NONE', ( 500.0000000000000000, 1000.000000000000000, 500.0000000000000000 ) ) ;
|
||||
#128 = EDGE_CURVE ( 'NONE', #74, #40, #142, .T. ) ;
|
||||
#129 = AXIS2_PLACEMENT_3D ( 'NONE', #4, #195, #171 ) ;
|
||||
#130 = APPROVAL_ROLE ( '' ) ;
|
||||
#131 = APPROVAL_DATE_TIME ( #71, #166 ) ;
|
||||
#132 = APPROVAL_ROLE ( '' ) ;
|
||||
#133 = CARTESIAN_POINT ( 'NONE', ( 0.000000000000000000, 0.000000000000000000, 0.000000000000000000 ) ) ;
|
||||
#134 = PERSON ( 'UNSPECIFIED', 'UNSPECIFIED', 'UNSPECIFIED', ('UNSPECIFIED'), ('UNSPECIFIED'), ('UNSPECIFIED') ) ;
|
||||
#135 = VERTEX_POINT ( 'NONE', #214 ) ;
|
||||
#136 = APPROVAL_PERSON_ORGANIZATION ( #91, #166, #151 ) ;
|
||||
#137 = EDGE_LOOP ( 'NONE', ( #158, #176, #157, #212 ) ) ;
|
||||
#138 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 1000.000000000000000, -500.0000000000000000 ) ) ;
|
||||
#139 = LINE ( 'NONE', #45, #55 ) ;
|
||||
#140 = LINE ( 'NONE', #177, #37 ) ;
|
||||
#141 = ORIENTED_EDGE ( 'NONE', *, *, #60, .T. ) ;
|
||||
#142 = LINE ( 'NONE', #231, #193 ) ;
|
||||
#143 = FACE_OUTER_BOUND ( 'NONE', #227, .T. ) ;
|
||||
#144 = EDGE_CURVE ( 'NONE', #120, #215, #47, .T. ) ;
|
||||
#145 = AXIS2_PLACEMENT_3D ( 'NONE', #39, #24, #207 ) ;
|
||||
#146 = PRODUCT_DEFINITION_SHAPE ( 'NONE', 'NONE', #23 ) ;
|
||||
#147 = PERSON_AND_ORGANIZATION_ROLE ( 'creator' ) ;
|
||||
#148 = CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT ( #165, #147, ( #51 ) ) ;
|
||||
#149 = DATE_TIME_ROLE ( 'classification_date' ) ;
|
||||
#150 = EDGE_CURVE ( 'NONE', #58, #120, #163, .T. ) ;
|
||||
#151 = APPROVAL_ROLE ( '' ) ;
|
||||
#152 = UNCERTAINTY_MEASURE_WITH_UNIT (LENGTH_MEASURE( 1.000000000000000082E-05 ), #2, 'distance_accuracy_value', 'NONE');
|
||||
#153 = CC_DESIGN_SECURITY_CLASSIFICATION ( #180, ( #51 ) ) ;
|
||||
#154 = COORDINATED_UNIVERSAL_TIME_OFFSET ( 5, 0, .BEHIND. ) ;
|
||||
#155 = MECHANICAL_CONTEXT ( 'NONE', #46, 'mechanical' ) ;
|
||||
#156 = VECTOR ( 'NONE', #229, 1000.000000000000000 ) ;
|
||||
#157 = ORIENTED_EDGE ( 'NONE', *, *, #60, .F. ) ;
|
||||
#158 = ORIENTED_EDGE ( 'NONE', *, *, #150, .T. ) ;
|
||||
#159 = CARTESIAN_POINT ( 'NONE', ( 500.0000000000000000, 0.000000000000000000, -500.0000000000000000 ) ) ;
|
||||
#160 = ORIENTED_EDGE ( 'NONE', *, *, #119, .T. ) ;
|
||||
#161 = DIRECTION ( 'NONE', ( 0.000000000000000000, 1.000000000000000000, 0.000000000000000000 ) ) ;
|
||||
#162 = LINE ( 'NONE', #12, #9 ) ;
|
||||
#163 = LINE ( 'NONE', #65, #5 ) ;
|
||||
#164 = ADVANCED_FACE ( 'NONE', ( #30 ), #32, .F. ) ;
|
||||
#165 = PERSON_AND_ORGANIZATION ( #134, #228 ) ;
|
||||
#166 = APPROVAL ( #196, 'UNSPECIFIED' ) ;
|
||||
#167 = PERSON_AND_ORGANIZATION ( #134, #228 ) ;
|
||||
#168 =( NAMED_UNIT ( * ) PLANE_ANGLE_UNIT ( ) SI_UNIT ( $, .RADIAN. ) );
|
||||
#169 = ADVANCED_FACE ( 'NONE', ( #143 ), #66, .F. ) ;
|
||||
#170 = VECTOR ( 'NONE', #7, 1000.000000000000000 ) ;
|
||||
#171 = DIRECTION ( 'NONE', ( 0.000000000000000000, 0.000000000000000000, 1.000000000000000000 ) ) ;
|
||||
#172 = CALENDAR_DATE ( 2023, 31, 7 ) ;
|
||||
#173 = AXIS2_PLACEMENT_3D ( 'NONE', #104, #184, #100 ) ;
|
||||
#174 =( NAMED_UNIT ( * ) SI_UNIT ( $, .STERADIAN. ) SOLID_ANGLE_UNIT ( ) );
|
||||
#175 = CARTESIAN_POINT ( 'NONE', ( 0.000000000000000000, 1000.000000000000000, 0.000000000000000000 ) ) ;
|
||||
#176 = ORIENTED_EDGE ( 'NONE', *, *, #69, .F. ) ;
|
||||
#177 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 1000.000000000000000, -500.0000000000000000 ) ) ;
|
||||
#178 = ORIENTED_EDGE ( 'NONE', *, *, #150, .F. ) ;
|
||||
#179 = VECTOR ( 'NONE', #13, 1000.000000000000000 ) ;
|
||||
#180 = SECURITY_CLASSIFICATION ( '', '', #223 ) ;
|
||||
#181 = FACE_OUTER_BOUND ( 'NONE', #102, .T. ) ;
|
||||
#182 = ORIENTED_EDGE ( 'NONE', *, *, #107, .T. ) ;
|
||||
#183 = CARTESIAN_POINT ( 'NONE', ( 500.0000000000000000, 1000.000000000000000, -500.0000000000000000 ) ) ;
|
||||
#184 = DIRECTION ( 'NONE', ( 0.000000000000000000, 0.000000000000000000, 1.000000000000000000 ) ) ;
|
||||
#185 = LINE ( 'NONE', #14, #156 ) ;
|
||||
#186 = LOCAL_TIME ( 11, 10, 19.00000000000000000, #221 ) ;
|
||||
#187 = CC_DESIGN_DATE_AND_TIME_ASSIGNMENT ( #54, #197, ( #23 ) ) ;
|
||||
#188 = PERSON_AND_ORGANIZATION_ROLE ( 'classification_officer' ) ;
|
||||
#189 = EDGE_CURVE ( 'NONE', #57, #58, #76, .T. ) ;
|
||||
#190 = APPROVAL_STATUS ( 'not_yet_approved' ) ;
|
||||
#191 = PERSON_AND_ORGANIZATION_ROLE ( 'design_supplier' ) ;
|
||||
#192 = PERSON_AND_ORGANIZATION ( #134, #228 ) ;
|
||||
#193 = VECTOR ( 'NONE', #216, 1000.000000000000000 ) ;
|
||||
#194 = LOCAL_TIME ( 11, 10, 19.00000000000000000, #208 ) ;
|
||||
#195 = DIRECTION ( 'NONE', ( -1.000000000000000000, 0.000000000000000000, 0.000000000000000000 ) ) ;
|
||||
#196 = APPROVAL_STATUS ( 'not_yet_approved' ) ;
|
||||
#197 = DATE_TIME_ROLE ( 'creation_date' ) ;
|
||||
#198 = FACE_OUTER_BOUND ( 'NONE', #27, .T. ) ;
|
||||
#199 = ORIENTED_EDGE ( 'NONE', *, *, #107, .F. ) ;
|
||||
#200 = ORIENTED_EDGE ( 'NONE', *, *, #128, .F. ) ;
|
||||
#201 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 1000.000000000000000, -500.0000000000000000 ) ) ;
|
||||
#202 = ORIENTED_EDGE ( 'NONE', *, *, #15, .F. ) ;
|
||||
#203 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 0.000000000000000000, -500.0000000000000000 ) ) ;
|
||||
#204 = DIRECTION ( 'NONE', ( -1.000000000000000000, -0.000000000000000000, -0.000000000000000000 ) ) ;
|
||||
#205 = DIRECTION ( 'NONE', ( 1.000000000000000000, 0.000000000000000000, 0.000000000000000000 ) ) ;
|
||||
#206 = DIRECTION ( 'NONE', ( 0.000000000000000000, -0.000000000000000000, 1.000000000000000000 ) ) ;
|
||||
#207 = DIRECTION ( 'NONE', ( -1.000000000000000000, 0.000000000000000000, -0.000000000000000000 ) ) ;
|
||||
#208 = COORDINATED_UNIVERSAL_TIME_OFFSET ( 5, 0, .BEHIND. ) ;
|
||||
#209 = DIRECTION ( 'NONE', ( 1.000000000000000000, 0.000000000000000000, 0.000000000000000000 ) ) ;
|
||||
#210 = APPROVAL ( #190, 'UNSPECIFIED' ) ;
|
||||
#211 = EDGE_CURVE ( 'NONE', #135, #74, #213, .T. ) ;
|
||||
#212 = ORIENTED_EDGE ( 'NONE', *, *, #189, .T. ) ;
|
||||
#213 = LINE ( 'NONE', #201, #33 ) ;
|
||||
#214 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 1000.000000000000000, -500.0000000000000000 ) ) ;
|
||||
#215 = VERTEX_POINT ( 'NONE', #29 ) ;
|
||||
#216 = DIRECTION ( 'NONE', ( -0.000000000000000000, -1.000000000000000000, -0.000000000000000000 ) ) ;
|
||||
#217 = DIRECTION ( 'NONE', ( 0.000000000000000000, 0.000000000000000000, -1.000000000000000000 ) ) ;
|
||||
#218 = CC_DESIGN_DATE_AND_TIME_ASSIGNMENT ( #52, #149, ( #180 ) ) ;
|
||||
#219 = ADVANCED_FACE ( 'NONE', ( #181 ), #11, .F. ) ;
|
||||
#220 = AXIS2_PLACEMENT_3D ( 'NONE', #79, #161, #206 ) ;
|
||||
#221 = COORDINATED_UNIVERSAL_TIME_OFFSET ( 5, 0, .BEHIND. ) ;
|
||||
#222 = ADVANCED_BREP_SHAPE_REPRESENTATION ( 'Cube_1m', ( #235, #1 ), #21 ) ;
|
||||
#223 = SECURITY_CLASSIFICATION_LEVEL ( 'unclassified' ) ;
|
||||
#224 = LOCAL_TIME ( 11, 10, 19.00000000000000000, #89 ) ;
|
||||
#225 = CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT ( #20, #191, ( #51 ) ) ;
|
||||
#226 = ADVANCED_FACE ( 'NONE', ( #22 ), #56, .F. ) ;
|
||||
#227 = EDGE_LOOP ( 'NONE', ( #160, #200, #62, #182 ) ) ;
|
||||
#228 = ORGANIZATION ( 'UNSPECIFIED', 'UNSPECIFIED', '' ) ;
|
||||
#229 = DIRECTION ( 'NONE', ( -0.000000000000000000, -0.000000000000000000, -1.000000000000000000 ) ) ;
|
||||
#230 = ORIENTED_EDGE ( 'NONE', *, *, #75, .F. ) ;
|
||||
#231 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 1000.000000000000000, 500.0000000000000000 ) ) ;
|
||||
#232 = CARTESIAN_POINT ( 'NONE', ( -500.0000000000000000, 0.000000000000000000, -500.0000000000000000 ) ) ;
|
||||
#233 = DIRECTION ( 'NONE', ( -0.000000000000000000, -0.000000000000000000, -1.000000000000000000 ) ) ;
|
||||
#234 = ADVANCED_FACE ( 'NONE', ( #3 ), #19, .F. ) ;
|
||||
#235 = MANIFOLD_SOLID_BREP ( 'Boss-Extrude1', #67 ) ;
|
||||
#236 = VECTOR ( 'NONE', #122, 1000.000000000000000 ) ;
|
||||
#237 = APPROVAL_DATE_TIME ( #34, #95 ) ;
|
||||
ENDSEC;
|
||||
END-ISO-10303-21;
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 214 KiB After Width: | Height: | Size: 214 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_import0.png
Normal file
After Width: | Height: | Size: 125 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_import1.png
Normal file
After Width: | Height: | Size: 131 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_import2.png
Normal file
After Width: | Height: | Size: 131 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_import3.png
Normal file
After Width: | Height: | Size: 119 KiB |
BIN
src/wasm-lib/kcl/tests/outputs/serial_test_example_import4.png
Normal file
After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 95 KiB |
@ -2057,3 +2057,58 @@ const bracket = startSketchOn('XY')
|
||||
r#"engine: KclErrorDetails { source_ranges: [SourceRange([1443, 1443])], message: "Modeling command failed: Some([ApiError { error_code: BadRequest, message: \"Fillet failed\" }])" }"#
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn serial_test_error_empty_start_sketch_on_string() {
|
||||
let code = r#"const part001 = startSketchOn('-XZ')
|
||||
|> startProfileAt([75.75, 184.25], %)
|
||||
|> line([190.03, -118.13], %)
|
||||
|> line([-33.38, -202.86], %)
|
||||
|> line([-315.86, -64.2], %)
|
||||
|> tangentialArcTo([-147.66, 121.34], %)
|
||||
|> close(%)
|
||||
|> extrude(100, %)
|
||||
|
||||
const secondSketch = startSketchOn(part001, '')
|
||||
|> circle([-20, 50], 40, %)
|
||||
|> extrude(20, %)
|
||||
"#;
|
||||
|
||||
let result = execute_and_snapshot(code, kcl_lib::settings::types::UnitLength::Mm).await;
|
||||
assert!(result.is_err());
|
||||
assert_eq!(
|
||||
result.err().unwrap().to_string(),
|
||||
r#"type: KclErrorDetails { source_ranges: [SourceRange([272, 298])], message: "Expected a non-empty tag for the face to sketch on" }"#
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn serial_test_error_user_function_wrong_args() {
|
||||
let code = r#"const length = .750
|
||||
const width = 0.500
|
||||
const height = 0.500
|
||||
const dia = 4
|
||||
|
||||
fn squareHole = (l, w) => {
|
||||
const squareHoleSketch = startSketchOn('XY')
|
||||
|> startProfileAt([-width / 2, -length / 2], %)
|
||||
|> lineTo([width / 2, -length / 2], %)
|
||||
|> lineTo([width / 2, length / 2], %)
|
||||
|> lineTo([-width / 2, length / 2], %)
|
||||
|> close(%)
|
||||
return squareHoleSketch
|
||||
}
|
||||
|
||||
const extrusion = startSketchOn('XY')
|
||||
|> circle([0, 0], dia/2, %)
|
||||
|> hole(squareHole(length, width, height), %)
|
||||
|> extrude(height, %)
|
||||
"#;
|
||||
|
||||
let result = execute_and_snapshot(code, kcl_lib::settings::types::UnitLength::Mm).await;
|
||||
assert!(result.is_err());
|
||||
assert_eq!(
|
||||
result.err().unwrap().to_string(),
|
||||
r#"semantic: KclErrorDetails { source_ranges: [SourceRange([92, 364]), SourceRange([444, 477])], message: "Expected 2 arguments, got 3" }"#
|
||||
);
|
||||
}
|
||||
|