Compare commits
9 Commits
pierremtb/
...
v0.35.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c2a0a8c07 | |||
| 97cef4d16c | |||
| 9358278f7b | |||
| a174e084d4 | |||
| df7246897a | |||
| 0c9f64dd7c | |||
| d2b9d3a058 | |||
| 7e54f08778 | |||
| d9c2dd376e |
46
.github/dependabot.yml
vendored
@ -5,24 +5,28 @@
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: 'npm' # See documentation for possible values
|
||||
directory: '/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
reviewers:
|
||||
- franknoirot
|
||||
- irev-dev
|
||||
- package-ecosystem: 'github-actions' # See documentation for possible values
|
||||
directory: '/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
reviewers:
|
||||
- adamchalmers
|
||||
- jessfraz
|
||||
- package-ecosystem: 'cargo' # See documentation for possible values
|
||||
directory: '/src/wasm-lib/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
reviewers:
|
||||
- adamchalmers
|
||||
- jessfraz
|
||||
- package-ecosystem: 'npm' # See documentation for possible values
|
||||
directory: '/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
reviewers:
|
||||
- franknoirot
|
||||
- irev-dev
|
||||
- package-ecosystem: 'github-actions' # See documentation for possible values
|
||||
directory: '/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
reviewers:
|
||||
- adamchalmers
|
||||
- jessfraz
|
||||
- package-ecosystem: 'cargo' # See documentation for possible values
|
||||
directory: '/src/wasm-lib/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'weekly'
|
||||
reviewers:
|
||||
- adamchalmers
|
||||
- jessfraz
|
||||
groups:
|
||||
serde-dependencies:
|
||||
patterns:
|
||||
- "serde*"
|
||||
|
||||
6
.github/workflows/e2e-tests.yml
vendored
@ -127,9 +127,12 @@ jobs:
|
||||
shell: bash
|
||||
run: yarn tron:package
|
||||
- name: Run ubuntu/chrome snapshots
|
||||
if: ${{ matrix.os == 'namespace-profile-ubuntu-8-cores' && matrix.shardIndex == 1 }}
|
||||
shell: bash
|
||||
# TODO: break this in its own job, for now it's not slowing down the overall execution as ubuntu is the quickest,
|
||||
# but we could do better. This forces a large 1/1 shard of all 20 snapshot tests that runs in about 3 minutes.
|
||||
run: |
|
||||
PLATFORM=web yarn playwright test --config=playwright.config.ts --retries="3" --update-snapshots --grep=@snapshot --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
|
||||
PLATFORM=web yarn playwright test --config=playwright.config.ts --retries="3" --update-snapshots --grep=@snapshot --shard=1/1
|
||||
env:
|
||||
CI: true
|
||||
NODE_ENV: development
|
||||
@ -150,6 +153,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
run: rm -r test-results
|
||||
- name: check for changes
|
||||
if: ${{ matrix.os == 'namespace-profile-ubuntu-8-cores' && matrix.shardIndex == 1 }}
|
||||
shell: bash
|
||||
id: git-check
|
||||
run: |
|
||||
|
||||
40
README.md
@ -337,13 +337,47 @@ For individual testing:
|
||||
yarn test abstractSyntaxTree -t "unexpected closed curly brace" --silent=false
|
||||
```
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
### Rust tests
|
||||
|
||||
```bash
|
||||
**Dependencies**
|
||||
|
||||
- `KITTYCAD_API_TOKEN`
|
||||
- `cargo-nextest`
|
||||
- `just`
|
||||
|
||||
#### Setting KITTYCAD_API_TOKEN
|
||||
Use the production zoo.dev token, set this environment variable before running the tests
|
||||
|
||||
#### Installing cargonextest
|
||||
|
||||
```
|
||||
cd src/wasm-lib
|
||||
KITTYCAD_API_TOKEN=XXX cargo test -- --test-threads=1
|
||||
cargo search cargo-nextest
|
||||
cargo install cargo-nextest
|
||||
```
|
||||
|
||||
#### just
|
||||
install [`just`](https://github.com/casey/just?tab=readme-ov-file#pre-built-binaries)
|
||||
|
||||
#### Running the tests
|
||||
|
||||
```bash
|
||||
# With just
|
||||
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
|
||||
# Make sure you installed cargo-nextest
|
||||
# Make sure you installed just
|
||||
cd src/wasm-lib
|
||||
just test
|
||||
```
|
||||
|
||||
```bash
|
||||
# Without just
|
||||
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
|
||||
# Make sure you installed cargo-nextest
|
||||
cd src/wasm-lib
|
||||
export RUST_BRACKTRACE="full" && cargo nextest run --workspace --test-threads=1
|
||||
```
|
||||
|
||||
Where `XXX` is an API token from the production engine (NOT the dev environment).
|
||||
|
||||
@ -1323,3 +1323,85 @@ test.describe(`Sketching with offset planes`, () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// Regression test for https://github.com/KittyCAD/modeling-app/issues/4891
|
||||
test.describe(`Click based selection don't brick the app when clicked out of range after format using cache`, () => {
|
||||
test(`Can select a line that reformmed after entering sketch mode`, async ({
|
||||
context,
|
||||
page,
|
||||
scene,
|
||||
toolbar,
|
||||
editor,
|
||||
homePage,
|
||||
}) => {
|
||||
// We seed the scene with a single offset plane
|
||||
await context.addInitScript(() => {
|
||||
localStorage.setItem(
|
||||
'persistCode',
|
||||
`sketch001 = startSketchOn('XZ')
|
||||
|> startProfileAt([0, 0], %)
|
||||
|> line([3.14, 3.14], %)
|
||||
|> arcTo({
|
||||
end = [4, 2],
|
||||
interior = [1, 2]
|
||||
}, %)
|
||||
`
|
||||
)
|
||||
})
|
||||
|
||||
await homePage.goToModelingScene()
|
||||
await scene.waitForExecutionDone()
|
||||
|
||||
await test.step(`format the code`, async () => {
|
||||
// doesn't contain condensed version
|
||||
await editor.expectEditor.not.toContain(
|
||||
`arcTo({ end = [4, 2], interior = [1, 2] }, %)`
|
||||
)
|
||||
// click the code to enter sketch mode
|
||||
await page.getByText(`arcTo`).click()
|
||||
// Format the code.
|
||||
await page.locator('#code-pane button:first-child').click()
|
||||
await page.locator('button:has-text("Format code")').click()
|
||||
})
|
||||
|
||||
await test.step(`Ensure the code reformatted`, async () => {
|
||||
await editor.expectEditor.toContain(
|
||||
`arcTo({ end = [4, 2], interior = [1, 2] }, %)`
|
||||
)
|
||||
})
|
||||
|
||||
const [arcClick, arcHover] = scene.makeMouseHelpers(699, 337)
|
||||
await test.step('Ensure we can hover the arc', async () => {
|
||||
await arcHover()
|
||||
|
||||
// Check that the code is highlighted
|
||||
await editor.expectState({
|
||||
activeLines: ["sketch001=startSketchOn('XZ')"],
|
||||
diagnostics: [],
|
||||
highlightedCode: 'arcTo({end = [4, 2], interior = [1, 2]}, %)',
|
||||
})
|
||||
})
|
||||
|
||||
await test.step('reset the selection', async () => {
|
||||
// Move the mouse out of the way
|
||||
await page.mouse.move(655, 337)
|
||||
|
||||
await editor.expectState({
|
||||
activeLines: ["sketch001=startSketchOn('XZ')"],
|
||||
diagnostics: [],
|
||||
highlightedCode: '',
|
||||
})
|
||||
})
|
||||
|
||||
await test.step('Ensure we can click the arc', async () => {
|
||||
await arcClick()
|
||||
|
||||
// Check that the code is highlighted
|
||||
await editor.expectState({
|
||||
activeLines: [],
|
||||
diagnostics: [],
|
||||
highlightedCode: 'arcTo({end = [4, 2], interior = [1, 2]}, %)',
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
Before Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 144 KiB |
|
Before Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 128 KiB After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 38 KiB |
@ -156,13 +156,13 @@ test.describe('Text-to-CAD tests', () => {
|
||||
const cmdSearchBar = page.getByPlaceholder('Search commands')
|
||||
await expect(cmdSearchBar).toBeVisible()
|
||||
|
||||
const textToCadCommand = page.getByText('Text-to-CAD')
|
||||
const textToCadCommand = page.getByRole('option', { name: 'Text-to-CAD' })
|
||||
await expect(textToCadCommand.first()).toBeVisible()
|
||||
// Click the Text-to-CAD command
|
||||
await textToCadCommand.first().click()
|
||||
|
||||
// Enter the prompt.
|
||||
const prompt = page.getByText('Prompt')
|
||||
const prompt = page.getByRole('textbox', { name: 'Prompt' })
|
||||
await expect(prompt.first()).toBeVisible()
|
||||
|
||||
// Type the prompt.
|
||||
@ -224,13 +224,13 @@ test.describe('Text-to-CAD tests', () => {
|
||||
const cmdSearchBar = page.getByPlaceholder('Search commands')
|
||||
await expect(cmdSearchBar).toBeVisible()
|
||||
|
||||
const textToCadCommand = page.getByText('Text-to-CAD')
|
||||
const textToCadCommand = page.getByRole('option', { name: 'Text-to-CAD' })
|
||||
await expect(textToCadCommand.first()).toBeVisible()
|
||||
// Click the Text-to-CAD command
|
||||
await textToCadCommand.first().click()
|
||||
|
||||
// Enter the prompt.
|
||||
const prompt = page.getByText('Prompt')
|
||||
const prompt = page.getByRole('textbox', { name: 'Prompt' })
|
||||
await expect(prompt.first()).toBeVisible()
|
||||
|
||||
const badPrompt = 'akjsndladf lajbhflauweyfaaaljhr472iouafyvsssssss'
|
||||
@ -314,13 +314,13 @@ test.describe('Text-to-CAD tests', () => {
|
||||
const cmdSearchBar = page.getByPlaceholder('Search commands')
|
||||
await expect(cmdSearchBar).toBeVisible()
|
||||
|
||||
const textToCadCommand = page.getByText('Text-to-CAD')
|
||||
const textToCadCommand = page.getByRole('option', { name: 'Text-to-CAD' })
|
||||
await expect(textToCadCommand.first()).toBeVisible()
|
||||
// Click the Text-to-CAD command
|
||||
await textToCadCommand.first().click()
|
||||
|
||||
// Enter the prompt.
|
||||
const prompt = page.getByText('Prompt')
|
||||
const prompt = page.getByRole('textbox', { name: 'Prompt' })
|
||||
await expect(prompt.first()).toBeVisible()
|
||||
|
||||
const badPrompt = 'akjsndladflajbhflauweyf15;'
|
||||
@ -392,13 +392,13 @@ test.describe('Text-to-CAD tests', () => {
|
||||
const cmdSearchBar = page.getByPlaceholder('Search commands')
|
||||
await expect(cmdSearchBar).toBeVisible()
|
||||
|
||||
const textToCadCommand = page.getByText('Text-to-CAD')
|
||||
const textToCadCommand = page.getByRole('option', { name: 'Text-to-CAD' })
|
||||
await expect(textToCadCommand.first()).toBeVisible()
|
||||
// Click the Text-to-CAD command
|
||||
await textToCadCommand.first().click()
|
||||
|
||||
// Enter the prompt.
|
||||
const prompt = page.getByText('Prompt')
|
||||
const prompt = page.getByRole('textbox', { name: 'Prompt' })
|
||||
await expect(prompt.first()).toBeVisible()
|
||||
|
||||
// Type the prompt.
|
||||
@ -604,7 +604,7 @@ async function sendPromptFromCommandBar(page: Page, promptStr: string) {
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
// Enter the prompt.
|
||||
const prompt = page.getByText('Prompt')
|
||||
const prompt = page.getByRole('textbox', { name: 'Prompt' })
|
||||
await expect(prompt.first()).toBeVisible()
|
||||
|
||||
// Type the prompt.
|
||||
|
||||
7
interface.d.ts
vendored
@ -11,6 +11,13 @@ export interface IElectronAPI {
|
||||
open: typeof dialog.showOpenDialog
|
||||
save: typeof dialog.showSaveDialog
|
||||
openExternal: typeof shell.openExternal
|
||||
takeElectronWindowScreenshot: ({
|
||||
width,
|
||||
height,
|
||||
}: {
|
||||
width: number
|
||||
height: number
|
||||
}) => Promise<string>
|
||||
showInFolder: typeof shell.showItemInFolder
|
||||
/** Require to be called first before {@link loginWithDeviceFlow} */
|
||||
startDeviceFlow: (host: string) => Promise<string>
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
statement[@isGroup=Statement] {
|
||||
ImportStatement { kw<"import"> ImportItems ImportFrom String } |
|
||||
FunctionDeclaration { kw<"export">? kw<"fn"> VariableDefinition Equals ParamList Arrow Body } |
|
||||
FunctionDeclaration { kw<"export">? kw<"fn"> VariableDefinition Equals? ParamList Arrow? Body } |
|
||||
VariableDeclaration { kw<"export">? (kw<"var"> | kw<"let"> | kw<"const">)? VariableDefinition Equals expression } |
|
||||
ReturnStatement { kw<"return"> expression } |
|
||||
ExpressionStatement { expression }
|
||||
|
||||
60
packages/codemirror-lang-kcl/test/fn.txt
Normal file
@ -0,0 +1,60 @@
|
||||
# full
|
||||
|
||||
fn two = () => {
|
||||
return 2
|
||||
}
|
||||
|
||||
==>
|
||||
|
||||
Program(FunctionDeclaration(fn,
|
||||
VariableDefinition,
|
||||
Equals,
|
||||
ParamList,
|
||||
Arrow,
|
||||
Body(ReturnStatement(return,
|
||||
Number))))
|
||||
|
||||
# = is optional
|
||||
|
||||
fn one () => {
|
||||
return 1
|
||||
}
|
||||
|
||||
==>
|
||||
|
||||
Program(FunctionDeclaration(fn,
|
||||
VariableDefinition,
|
||||
ParamList,
|
||||
Arrow,
|
||||
Body(ReturnStatement(return,
|
||||
Number))))
|
||||
|
||||
# => is optional
|
||||
|
||||
fn one = () {
|
||||
return 1
|
||||
}
|
||||
|
||||
==>
|
||||
|
||||
Program(FunctionDeclaration(fn,
|
||||
VariableDefinition,
|
||||
Equals,
|
||||
ParamList,
|
||||
Body(ReturnStatement(return,
|
||||
Number))))
|
||||
|
||||
# terse
|
||||
|
||||
fn two() {
|
||||
return 2
|
||||
}
|
||||
|
||||
==>
|
||||
|
||||
Program(FunctionDeclaration(fn,
|
||||
VariableDefinition,
|
||||
ParamList,
|
||||
Body(ReturnStatement(return,
|
||||
Number))))
|
||||
|
||||
@ -75,6 +75,7 @@ function CommandBarTextareaInput({
|
||||
target.selectionStart = selectionStart + 1
|
||||
target.selectionEnd = selectionStart + 1
|
||||
} else if (event.key === 'Enter') {
|
||||
event.preventDefault()
|
||||
formRef.current?.dispatchEvent(
|
||||
new Event('submit', { bubbles: true })
|
||||
)
|
||||
|
||||
@ -97,6 +97,7 @@ export const KclEditorPane = () => {
|
||||
if (!editorIsMounted || !lastSelectionEvent || !editorManager.editorView) {
|
||||
return
|
||||
}
|
||||
|
||||
editorManager.editorView.dispatch({
|
||||
selection: lastSelectionEvent.codeMirrorSelection,
|
||||
annotations: [modelingMachineEvent, Transaction.addToHistory.of(false)],
|
||||
|
||||
@ -40,6 +40,7 @@ export const setDiagnosticsEvent = setDiagnosticsAnnotation.of(true)
|
||||
export default class EditorManager {
|
||||
private _copilotEnabled: boolean = true
|
||||
|
||||
private _isAllTextSelected: boolean = false
|
||||
private _isShiftDown: boolean = false
|
||||
private _selectionRanges: Selections = {
|
||||
otherSelections: [],
|
||||
@ -117,6 +118,10 @@ export default class EditorManager {
|
||||
})
|
||||
}
|
||||
|
||||
get isAllTextSelected() {
|
||||
return this._isAllTextSelected
|
||||
}
|
||||
|
||||
get editorView(): EditorView | null {
|
||||
return this._editorView
|
||||
}
|
||||
@ -129,6 +134,21 @@ export default class EditorManager {
|
||||
this._isShiftDown = isShiftDown
|
||||
}
|
||||
|
||||
private selectionsWithSafeEnds(
|
||||
selection: Array<Selection['codeRef']['range']>
|
||||
): Array<[number, number]> {
|
||||
if (!this._editorView) {
|
||||
return selection.map((s): [number, number] => {
|
||||
return [s[0], s[1]]
|
||||
})
|
||||
}
|
||||
|
||||
return selection.map((s): [number, number] => {
|
||||
const safeEnd = Math.min(s[1], this._editorView?.state.doc.length || s[1])
|
||||
return [s[0], safeEnd]
|
||||
})
|
||||
}
|
||||
|
||||
set selectionRanges(selectionRanges: Selections) {
|
||||
this._selectionRanges = selectionRanges
|
||||
}
|
||||
@ -154,14 +174,9 @@ export default class EditorManager {
|
||||
}
|
||||
|
||||
setHighlightRange(range: Array<Selection['codeRef']['range']>): void {
|
||||
this._highlightRange = range.map((s): [number, number] => {
|
||||
return [s[0], s[1]]
|
||||
})
|
||||
const selectionsWithSafeEnds = this.selectionsWithSafeEnds(range)
|
||||
|
||||
const selectionsWithSafeEnds = range.map((s): [number, number] => {
|
||||
const safeEnd = Math.min(s[1], this._editorView?.state.doc.length || s[1])
|
||||
return [s[0], safeEnd]
|
||||
})
|
||||
this._highlightRange = selectionsWithSafeEnds
|
||||
|
||||
if (this._editorView) {
|
||||
this._editorView.dispatch({
|
||||
@ -302,20 +317,20 @@ export default class EditorManager {
|
||||
}
|
||||
let codeBasedSelections = []
|
||||
for (const selection of selections.graphSelections) {
|
||||
const safeEnd = Math.min(
|
||||
selection.codeRef.range[1],
|
||||
this._editorView?.state.doc.length || selection.codeRef.range[1]
|
||||
)
|
||||
codeBasedSelections.push(
|
||||
EditorSelection.range(
|
||||
selection.codeRef.range[0],
|
||||
selection.codeRef.range[1]
|
||||
)
|
||||
EditorSelection.range(selection.codeRef.range[0], safeEnd)
|
||||
)
|
||||
}
|
||||
|
||||
codeBasedSelections.push(
|
||||
EditorSelection.cursor(
|
||||
selections.graphSelections[selections.graphSelections.length - 1]
|
||||
.codeRef.range[1]
|
||||
)
|
||||
)
|
||||
const end =
|
||||
selections.graphSelections[selections.graphSelections.length - 1].codeRef
|
||||
.range[1]
|
||||
const safeEnd = Math.min(end, this._editorView?.state.doc.length || end)
|
||||
codeBasedSelections.push(EditorSelection.cursor(safeEnd))
|
||||
|
||||
if (!this._editorView) {
|
||||
return
|
||||
@ -352,6 +367,16 @@ export default class EditorManager {
|
||||
return
|
||||
}
|
||||
|
||||
this._isAllTextSelected = viewUpdate.state.selection.ranges.some(
|
||||
(selection) => {
|
||||
return (
|
||||
// The user will need to select the empty new lines as well to be considered all of the text.
|
||||
// CTRL+A is the best way to select all the text
|
||||
selection.from === 0 && selection.to === viewUpdate.state.doc.length
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
const eventInfo = processCodeMirrorRanges({
|
||||
codeMirrorRanges: viewUpdate.state.selection.ranges,
|
||||
selectionRanges: this._selectionRanges,
|
||||
|
||||
@ -464,13 +464,42 @@ export class KclManager {
|
||||
}
|
||||
async executeCode(zoomToFit?: boolean): Promise<void> {
|
||||
const ast = await this.safeParse(codeManager.code)
|
||||
|
||||
if (!ast) {
|
||||
this.clearAst()
|
||||
return
|
||||
}
|
||||
|
||||
zoomToFit = this.tryToZoomToFitOnCodeUpdate(ast, zoomToFit)
|
||||
|
||||
this.ast = { ...ast }
|
||||
return this.executeAst({ zoomToFit })
|
||||
}
|
||||
/**
|
||||
* This will override the zoom to fit to zoom into the model if the previous AST was empty.
|
||||
* Workflows this improves,
|
||||
* When someone comments the entire file then uncomments the entire file it zooms to the model
|
||||
* When someone CRTL+A and deletes the code then adds the code back it zooms to the model
|
||||
* When someone CRTL+A and copies new code into the editor it zooms to the model
|
||||
*/
|
||||
tryToZoomToFitOnCodeUpdate(
|
||||
ast: Node<Program>,
|
||||
zoomToFit: boolean | undefined
|
||||
) {
|
||||
const isAstEmpty = this._isAstEmpty(this._ast)
|
||||
const isRequestedAstEmpty = this._isAstEmpty(ast)
|
||||
|
||||
// If the AST went from empty to not empty or
|
||||
// If the user has all of the content selected and they copy new code in
|
||||
if (
|
||||
(isAstEmpty && !isRequestedAstEmpty) ||
|
||||
editorManager.isAllTextSelected
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
return zoomToFit
|
||||
}
|
||||
async format() {
|
||||
const originalCode = codeManager.code
|
||||
const ast = await this.safeParse(originalCode)
|
||||
|
||||
@ -1,6 +1,24 @@
|
||||
import html2canvas from 'html2canvas-pro'
|
||||
function takeScreenshotOfVideoStreamCanvas() {
|
||||
const canvas = document.querySelector('[data-engine]')
|
||||
const video = document.getElementById('video-stream')
|
||||
if (
|
||||
canvas &&
|
||||
video &&
|
||||
canvas instanceof HTMLCanvasElement &&
|
||||
video instanceof HTMLVideoElement
|
||||
) {
|
||||
const videoCanvas = document.createElement('canvas')
|
||||
videoCanvas.width = canvas.width
|
||||
videoCanvas.height = canvas.height
|
||||
const context = videoCanvas.getContext('2d')
|
||||
context?.drawImage(video, 0, 0, videoCanvas.width, videoCanvas.height)
|
||||
const url = videoCanvas.toDataURL('image/png')
|
||||
return url
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
// Return a data URL (png format) of the screenshot of the current page.
|
||||
export default async function screenshot(): Promise<string> {
|
||||
if (typeof window === 'undefined') {
|
||||
return Promise.reject(
|
||||
@ -9,11 +27,17 @@ export default async function screenshot(): Promise<string> {
|
||||
)
|
||||
)
|
||||
}
|
||||
return html2canvas(document.documentElement)
|
||||
.then((canvas) => {
|
||||
return canvas.toDataURL()
|
||||
})
|
||||
.catch((error) => {
|
||||
return Promise.reject(error)
|
||||
})
|
||||
|
||||
if (window.electron) {
|
||||
const canvas = document.querySelector('[data-engine]')
|
||||
if (canvas instanceof HTMLCanvasElement) {
|
||||
const url = await window.electron.takeElectronWindowScreenshot({
|
||||
width: canvas?.width || 500,
|
||||
height: canvas?.height || 500,
|
||||
})
|
||||
return url !== '' ? url : takeScreenshotOfVideoStreamCanvas()
|
||||
}
|
||||
}
|
||||
|
||||
return takeScreenshotOfVideoStreamCanvas()
|
||||
}
|
||||
|
||||
@ -323,7 +323,8 @@ export function handleSelectionBatch({
|
||||
resetAndSetEngineEntitySelectionCmds(selectionToEngine)
|
||||
selections.graphSelections.forEach(({ codeRef }) => {
|
||||
if (codeRef.range?.[1]) {
|
||||
ranges.push(EditorSelection.cursor(codeRef.range[1]))
|
||||
const safeEnd = Math.min(codeRef.range[1], codeManager.code.length)
|
||||
ranges.push(EditorSelection.cursor(safeEnd))
|
||||
}
|
||||
})
|
||||
if (ranges.length)
|
||||
|
||||
@ -274,6 +274,35 @@ export const toolbarConfig: Record<ToolbarModeName, ToolbarMode> = {
|
||||
links: [],
|
||||
},
|
||||
],
|
||||
'break',
|
||||
[
|
||||
{
|
||||
id: 'text-to-cad',
|
||||
onClick: ({ commandBarSend }) =>
|
||||
commandBarSend({
|
||||
type: 'Find and select command',
|
||||
data: { name: 'Text-to-CAD', groupId: 'modeling' },
|
||||
}),
|
||||
icon: 'sparkles',
|
||||
status: 'available',
|
||||
title: 'Text-to-CAD',
|
||||
description: 'Generate geometry from a text prompt.',
|
||||
links: [],
|
||||
},
|
||||
{
|
||||
id: 'prompt-to-edit',
|
||||
onClick: ({ commandBarSend }) =>
|
||||
commandBarSend({
|
||||
type: 'Find and select command',
|
||||
data: { name: 'Prompt-to-edit', groupId: 'modeling' },
|
||||
}),
|
||||
icon: 'sparkles',
|
||||
status: 'available',
|
||||
title: 'Prompt-to-Edit',
|
||||
description: 'Edit geometry based on a text prompt.',
|
||||
links: [],
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
sketching: {
|
||||
|
||||
42
src/main.ts
@ -8,6 +8,8 @@ import {
|
||||
dialog,
|
||||
shell,
|
||||
nativeTheme,
|
||||
desktopCapturer,
|
||||
systemPreferences,
|
||||
} from 'electron'
|
||||
import path from 'path'
|
||||
import { Issuer } from 'openid-client'
|
||||
@ -21,6 +23,8 @@ import os from 'node:os'
|
||||
import { reportRejection } from 'lib/trap'
|
||||
import argvFromYargs from './commandLineArgs'
|
||||
|
||||
import * as packageJSON from '../package.json'
|
||||
|
||||
let mainWindow: BrowserWindow | null = null
|
||||
|
||||
// Check the command line arguments for a project path
|
||||
@ -181,6 +185,44 @@ ipcMain.handle('shell.openExternal', (event, data) => {
|
||||
return shell.openExternal(data)
|
||||
})
|
||||
|
||||
ipcMain.handle(
|
||||
'take.screenshot',
|
||||
async (event, data: { width: number; height: number }) => {
|
||||
/**
|
||||
* Operation system access to getting screen sources, even though we are only use application windows
|
||||
* Linux: Yes!
|
||||
* Mac OS: This user consent was not required on macOS 10.13 High Sierra so this method will always return granted. macOS 10.14 Mojave or higher requires consent for microphone and camera access. macOS 10.15 Catalina or higher requires consent for screen access.
|
||||
* Windows 10: has a global setting controlling microphone and camera access for all win32 applications. It will always return granted for screen and for all media types on older versions of Windows.
|
||||
*/
|
||||
let accessToScreenSources = true
|
||||
|
||||
// Can we check for access and if so, is it granted
|
||||
// Linux does not even have access to the function getMediaAccessStatus, not going to polyfill
|
||||
if (systemPreferences && systemPreferences.getMediaAccessStatus) {
|
||||
const accessString = systemPreferences.getMediaAccessStatus('screen')
|
||||
accessToScreenSources = accessString === 'granted' ? true : false
|
||||
}
|
||||
|
||||
if (accessToScreenSources) {
|
||||
const sources = await desktopCapturer.getSources({
|
||||
types: ['window'],
|
||||
thumbnailSize: { width: data.width, height: data.height },
|
||||
})
|
||||
|
||||
for (const source of sources) {
|
||||
// electron-builder uses the value of productName in package.json for the title of the application
|
||||
if (source.name === packageJSON.productName) {
|
||||
// @ts-ignore image/png is real.
|
||||
return source.thumbnail.toDataURL('image/png') // The image to display the screenshot
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cannot take a native desktop screenshot, unable to access screens
|
||||
return ''
|
||||
}
|
||||
)
|
||||
|
||||
ipcMain.handle('argv.parser', (event, data) => {
|
||||
return argvFromYargs
|
||||
})
|
||||
|
||||
@ -12,6 +12,13 @@ const resizeWindow = (width: number, height: number) =>
|
||||
const open = (args: any) => ipcRenderer.invoke('dialog.showOpenDialog', args)
|
||||
const save = (args: any) => ipcRenderer.invoke('dialog.showSaveDialog', args)
|
||||
const openExternal = (url: any) => ipcRenderer.invoke('shell.openExternal', url)
|
||||
const takeElectronWindowScreenshot = ({
|
||||
width,
|
||||
height,
|
||||
}: {
|
||||
width: number
|
||||
height: number
|
||||
}) => ipcRenderer.invoke('take.screenshot', { width, height })
|
||||
const showInFolder = (path: string) =>
|
||||
ipcRenderer.invoke('shell.showItemInFolder', path)
|
||||
const startDeviceFlow = (host: string): Promise<string> =>
|
||||
@ -160,6 +167,7 @@ contextBridge.exposeInMainWorld('electron', {
|
||||
version: process.version,
|
||||
join: path.join,
|
||||
sep: path.sep,
|
||||
takeElectronWindowScreenshot,
|
||||
os: {
|
||||
isMac,
|
||||
isWindows,
|
||||
|
||||
108
src/wasm-lib/Cargo.lock
generated
@ -176,7 +176,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -187,7 +187,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -204,7 +204,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -474,7 +474,7 @@ dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -665,7 +665,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -676,7 +676,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -737,7 +737,7 @@ dependencies = [
|
||||
"rustfmt-wrapper",
|
||||
"serde",
|
||||
"serde_tokenstream",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -748,7 +748,7 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -791,7 +791,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -829,7 +829,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -990,7 +990,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1086,7 +1086,7 @@ dependencies = [
|
||||
"inflections",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1494,7 +1494,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1851,7 +1851,7 @@ dependencies = [
|
||||
"kittycad-modeling-cmds-macros-impl",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1862,7 +1862,7 @@ checksum = "6607507a8a0e4273b943179f0a3ef8e90712308d1d3095246040c29cfdbf985b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2012,7 +2012,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2311,7 +2311,7 @@ dependencies = [
|
||||
"regex",
|
||||
"regex-syntax 0.8.5",
|
||||
"structmeta",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2325,7 +2325,7 @@ dependencies = [
|
||||
"regex",
|
||||
"regex-syntax 0.8.5",
|
||||
"structmeta",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2365,7 +2365,7 @@ dependencies = [
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2423,7 +2423,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2553,14 +2553,14 @@ dependencies = [
|
||||
"proc-macro-error-attr2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.89"
|
||||
version = "1.0.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
|
||||
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -2612,7 +2612,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"pyo3-macros-backend",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2625,7 +2625,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"pyo3-build-config",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3160,7 +3160,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_derive_internals",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3224,7 +3224,7 @@ checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3235,7 +3235,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3259,7 +3259,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3280,7 +3280,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3429,7 +3429,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"structmeta-derive",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3440,7 +3440,7 @@ checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3462,7 +3462,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3505,9 +3505,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.87"
|
||||
version = "2.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
|
||||
checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -3531,7 +3531,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3639,7 +3639,7 @@ checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3650,7 +3650,7 @@ checksum = "22efd00f33f93fa62848a7cab956c3d38c8d43095efda1decfc2b3a5dc0b8972"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3762,7 +3762,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3904,7 +3904,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3932,7 +3932,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3993,15 +3993,15 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||
|
||||
[[package]]
|
||||
name = "ts-rs"
|
||||
version = "10.0.0"
|
||||
version = "10.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a2f31991cee3dce1ca4f929a8a04fdd11fd8801aac0f2030b0fa8a0a3fef6b9"
|
||||
checksum = "e640d9b0964e9d39df633548591090ab92f7a4567bc31d3891af23471a3365c6"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"indexmap 2.7.0",
|
||||
"lazy_static",
|
||||
"serde_json",
|
||||
"thiserror 1.0.68",
|
||||
"thiserror 2.0.0",
|
||||
"ts-rs-macros",
|
||||
"url",
|
||||
"uuid",
|
||||
@ -4009,13 +4009,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ts-rs-macros"
|
||||
version = "10.0.0"
|
||||
version = "10.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ea0b99e8ec44abd6f94a18f28f7934437809dd062820797c52401298116f70e"
|
||||
checksum = "0e9d8656589772eeec2cf7a8264d9cda40fb28b9bc53118ceb9e8c07f8f38730"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
@ -4194,7 +4194,7 @@ dependencies = [
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4255,7 +4255,7 @@ dependencies = [
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -4291,7 +4291,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@ -4672,7 +4672,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
@ -4694,7 +4694,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4714,7 +4714,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
@ -4743,7 +4743,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@ -20,7 +20,7 @@ quote = "1"
|
||||
regex = "1.11"
|
||||
serde = { version = "1.0.214", features = ["derive"] }
|
||||
serde_tokenstream = "0.2"
|
||||
syn = { version = "2.0.87", features = ["full"] }
|
||||
syn = { version = "2.0.95", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
anyhow = "1.0.95"
|
||||
|
||||
@ -31,3 +31,5 @@ new-sim-test test_name render_to_png="true":
|
||||
{{cita}} -p kcl-lib -- simulation_tests::{{test_name}}::unparse
|
||||
TWENTY_TWENTY=overwrite {{cita}} -p kcl-lib -- tests::{{test_name}}::kcl_test_execute
|
||||
|
||||
test:
|
||||
export RUST_BRACKTRACE="full" && cargo nextest run --workspace --test-threads=1
|
||||
|
||||
@ -60,7 +60,7 @@ sha2 = "0.10.8"
|
||||
tabled = { version = "0.15.0", optional = true }
|
||||
thiserror = "2.0.0"
|
||||
toml = "0.8.19"
|
||||
ts-rs = { version = "10.0.0", features = [
|
||||
ts-rs = { version = "10.1.0", features = [
|
||||
"uuid-impl",
|
||||
"url-impl",
|
||||
"chrono-impl",
|
||||
|
||||
@ -163,6 +163,9 @@ impl CoreDumpInfo {
|
||||
|
||||

|
||||
|
||||
> _Note: If you are capturing from a browser there is limited support for screenshots, only captures the modeling scene.
|
||||
If you are on MacOS native screenshots may be disabled by default. To enable native screenshots add Zoo Modeling App to System Settings -> Screen & SystemAudio Recording for native screenshots._
|
||||
|
||||
<details>
|
||||
<summary><b>Core Dump</b></summary>
|
||||
|
||||
|
||||