Merge branch 'main' into franknoirot/4088/decouple-homeMachine
This commit is contained in:
68
.github/workflows/build-test-publish-apps.yml
vendored
68
.github/workflows/build-test-publish-apps.yml
vendored
@ -51,6 +51,8 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
VERSION=$(date +'%-y.%-m.%-d') yarn bump-jsons
|
VERSION=$(date +'%-y.%-m.%-d') yarn bump-jsons
|
||||||
|
|
||||||
|
# TODO: see if we need to inject updater nightly URL here https://dl.zoo.dev/releases/modeling-app/nightly/last_update.json
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: prepared-files
|
name: prepared-files
|
||||||
@ -61,25 +63,12 @@ jobs:
|
|||||||
- id: export_version
|
- id: export_version
|
||||||
run: echo "version=`cat package.json | jq -r '.version'`" >> "$GITHUB_OUTPUT"
|
run: echo "version=`cat package.json | jq -r '.version'`" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: Prepare electron-builder.yml file for nightly
|
|
||||||
if: ${{ github.event_name == 'schedule' }}
|
|
||||||
run: |
|
|
||||||
yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/nightly"' electron-builder.yml
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
if: ${{ github.event_name == 'schedule' }}
|
|
||||||
with:
|
|
||||||
name: prepared-files-nightly
|
|
||||||
path: |
|
|
||||||
electron-builder.yml
|
|
||||||
|
|
||||||
- name: Prepare electron-builder.yml file for updater test
|
- name: Prepare electron-builder.yml file for updater test
|
||||||
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||||
run: |
|
run: |
|
||||||
yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/updater-test"' electron-builder.yml
|
yq -i '.publish[0].url = "https://dl.zoo.dev/releases/modeling-app/updater-test"' electron-builder.yml
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
|
||||||
with:
|
with:
|
||||||
name: prepared-files-updater-test
|
name: prepared-files-updater-test
|
||||||
path: |
|
path: |
|
||||||
@ -119,16 +108,6 @@ jobs:
|
|||||||
mkdir src/wasm-lib/pkg
|
mkdir src/wasm-lib/pkg
|
||||||
cp prepared-files/src/wasm-lib/pkg/wasm_lib* src/wasm-lib/pkg
|
cp prepared-files/src/wasm-lib/pkg/wasm_lib* src/wasm-lib/pkg
|
||||||
|
|
||||||
- uses: actions/download-artifact@v3
|
|
||||||
if: ${{ github.event_name == 'schedule' }}
|
|
||||||
name: prepared-files-nightly
|
|
||||||
|
|
||||||
- name: Copy updated electron-builder.yml file for nightly build
|
|
||||||
if: ${{ github.event_name == 'schedule' }}
|
|
||||||
run: |
|
|
||||||
ls -R prepared-files-nightly
|
|
||||||
cp prepared-files-nightly/electron-builder.yml electron-builder.yml
|
|
||||||
|
|
||||||
- name: Sync node version and setup cache
|
- name: Sync node version and setup cache
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
@ -173,17 +152,11 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: out-arm64-${{ matrix.os }}
|
name: out-${{ matrix.os }}
|
||||||
path: |
|
path: |
|
||||||
out/Zoo*arm64*.*
|
out/Zoo*.*
|
||||||
out/latest*.yml
|
out/latest*.yml
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: out-x64-${{ matrix.os }}
|
|
||||||
path: |
|
|
||||||
out/Zoo*x*64*.*
|
|
||||||
|
|
||||||
# TODO: add the 'Build for Mac TestFlight (nightly)' stage back
|
# TODO: add the 'Build for Mac TestFlight (nightly)' stage back
|
||||||
|
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
@ -203,16 +176,10 @@ jobs:
|
|||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
||||||
with:
|
with:
|
||||||
name: updater-test-arm64-${{ matrix.os }}
|
name: updater-test-${{ matrix.os }}
|
||||||
path: |
|
path: |
|
||||||
out/Zoo*arm64*.*
|
out/Zoo*.*
|
||||||
|
out/latest*.yml
|
||||||
- uses: actions/upload-artifact@v3
|
|
||||||
if: ${{ env.CUT_RELEASE_PR == 'true' }}
|
|
||||||
with:
|
|
||||||
name: updater-test-x64-${{ matrix.os }}
|
|
||||||
path: |
|
|
||||||
out/Zoo*x64*.*
|
|
||||||
|
|
||||||
|
|
||||||
publish-apps-release:
|
publish-apps-release:
|
||||||
@ -234,32 +201,17 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: out-arm64-windows-2022
|
name: out-windows-2022
|
||||||
path: out
|
path: out
|
||||||
|
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: out-x64-windows-2022
|
name: out-macos-14
|
||||||
path: out
|
path: out
|
||||||
|
|
||||||
- uses: actions/download-artifact@v3
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: out-arm64-macos-14
|
name: out-ubuntu-22.04
|
||||||
path: out
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: out-x64-macos-14
|
|
||||||
path: out
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: out-arm64-ubuntu-22.04
|
|
||||||
path: out
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v3
|
|
||||||
with:
|
|
||||||
name: out-x64-ubuntu-22.04
|
|
||||||
path: out
|
path: out
|
||||||
|
|
||||||
- name: Generate the download static endpoint
|
- name: Generate the download static endpoint
|
||||||
|
@ -9,6 +9,7 @@ import {
|
|||||||
executorInputPath,
|
executorInputPath,
|
||||||
} from './test-utils'
|
} from './test-utils'
|
||||||
import { SaveSettingsPayload, SettingsLevel } from 'lib/settings/settingsTypes'
|
import { SaveSettingsPayload, SettingsLevel } from 'lib/settings/settingsTypes'
|
||||||
|
import { SETTINGS_FILE_NAME } from 'lib/constants'
|
||||||
import {
|
import {
|
||||||
TEST_SETTINGS_KEY,
|
TEST_SETTINGS_KEY,
|
||||||
TEST_SETTINGS_CORRUPTED,
|
TEST_SETTINGS_CORRUPTED,
|
||||||
@ -343,7 +344,7 @@ test.describe('Testing settings', () => {
|
|||||||
|
|
||||||
// Selectors and constants
|
// Selectors and constants
|
||||||
const errorHeading = page.getByRole('heading', {
|
const errorHeading = page.getByRole('heading', {
|
||||||
name: 'An unextected error occurred',
|
name: 'An unexpected error occurred',
|
||||||
})
|
})
|
||||||
const projectDirLink = page.getByText('Loaded from')
|
const projectDirLink = page.getByText('Loaded from')
|
||||||
|
|
||||||
@ -372,7 +373,7 @@ test.describe('Testing settings', () => {
|
|||||||
|
|
||||||
// Selectors and constants
|
// Selectors and constants
|
||||||
const errorHeading = page.getByRole('heading', {
|
const errorHeading = page.getByRole('heading', {
|
||||||
name: 'An unextected error occurred',
|
name: 'An unexpected error occurred',
|
||||||
})
|
})
|
||||||
const projectDirLink = page.getByText('Loaded from')
|
const projectDirLink = page.getByText('Loaded from')
|
||||||
|
|
||||||
@ -384,6 +385,66 @@ test.describe('Testing settings', () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// It was much easier to test the logo color than the background stream color.
|
||||||
|
test(
|
||||||
|
'user settings reload on external change, on project and modeling view',
|
||||||
|
{ tag: '@electron' },
|
||||||
|
async ({ browserName }, testInfo) => {
|
||||||
|
const {
|
||||||
|
electronApp,
|
||||||
|
page,
|
||||||
|
dir: projectDirName,
|
||||||
|
} = await setupElectron({
|
||||||
|
testInfo,
|
||||||
|
appSettings: {
|
||||||
|
app: {
|
||||||
|
// Doesn't matter what you set it to. It will
|
||||||
|
// default to 264.5
|
||||||
|
themeColor: '0',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
await page.setViewportSize({ width: 1200, height: 500 })
|
||||||
|
|
||||||
|
const logoLink = page.getByTestId('app-logo')
|
||||||
|
const projectDirLink = page.getByText('Loaded from')
|
||||||
|
|
||||||
|
await test.step('Wait for project view', async () => {
|
||||||
|
await expect(projectDirLink).toBeVisible()
|
||||||
|
await expect(logoLink).toHaveCSS('--primary-hue', '264.5')
|
||||||
|
})
|
||||||
|
|
||||||
|
const changeColor = async (color: string) => {
|
||||||
|
const tempSettingsFilePath = join(projectDirName, SETTINGS_FILE_NAME)
|
||||||
|
let tomlStr = await fsp.readFile(tempSettingsFilePath, 'utf-8')
|
||||||
|
tomlStr = tomlStr.replace(/(themeColor = ")[0-9]+(")/, `$1${color}$2`)
|
||||||
|
await fsp.writeFile(tempSettingsFilePath, tomlStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
await test.step('Check color of logo changed', async () => {
|
||||||
|
await changeColor('99')
|
||||||
|
await expect(logoLink).toHaveCSS('--primary-hue', '99')
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Check color of logo changed when in modeling view', async () => {
|
||||||
|
await page.getByRole('button', { name: 'New project' }).click()
|
||||||
|
await page.getByTestId('project-link').first().click()
|
||||||
|
await page.getByRole('button', { name: 'Dismiss' }).click()
|
||||||
|
await changeColor('58')
|
||||||
|
await expect(logoLink).toHaveCSS('--primary-hue', '58')
|
||||||
|
})
|
||||||
|
|
||||||
|
await test.step('Check going back to projects view still changes the color', async () => {
|
||||||
|
await logoLink.click()
|
||||||
|
await expect(projectDirLink).toBeVisible()
|
||||||
|
await changeColor('21')
|
||||||
|
await expect(logoLink).toHaveCSS('--primary-hue', '21')
|
||||||
|
})
|
||||||
|
await electronApp.close()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
test(
|
test(
|
||||||
`Closing settings modal should go back to the original file being viewed`,
|
`Closing settings modal should go back to the original file being viewed`,
|
||||||
{ tag: '@electron' },
|
{ tag: '@electron' },
|
||||||
|
1
interface.d.ts
vendored
1
interface.d.ts
vendored
@ -23,7 +23,6 @@ export interface IElectronAPI {
|
|||||||
callback: (eventType: string, path: string) => void
|
callback: (eventType: string, path: string) => void
|
||||||
) => void
|
) => void
|
||||||
watchFileOff: (path: string) => void
|
watchFileOff: (path: string) => void
|
||||||
watchFileObliterate: () => void
|
|
||||||
readFile: (path: string) => ReturnType<fs.readFile>
|
readFile: (path: string) => ReturnType<fs.readFile>
|
||||||
writeFile: (
|
writeFile: (
|
||||||
path: string,
|
path: string,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "zoo-modeling-app",
|
"name": "zoo-modeling-app",
|
||||||
"version": "0.25.5",
|
"version": "0.25.6",
|
||||||
"private": true,
|
"private": true,
|
||||||
"productName": "Zoo Modeling App",
|
"productName": "Zoo Modeling App",
|
||||||
"author": {
|
"author": {
|
||||||
@ -36,6 +36,7 @@
|
|||||||
"@xstate/inspect": "^0.8.0",
|
"@xstate/inspect": "^0.8.0",
|
||||||
"@xstate/react": "^4.1.1",
|
"@xstate/react": "^4.1.1",
|
||||||
"bonjour-service": "^1.2.1",
|
"bonjour-service": "^1.2.1",
|
||||||
|
"chokidar": "^4.0.1",
|
||||||
"codemirror": "^6.0.1",
|
"codemirror": "^6.0.1",
|
||||||
"decamelize": "^6.0.0",
|
"decamelize": "^6.0.0",
|
||||||
"electron-squirrel-startup": "^1.0.1",
|
"electron-squirrel-startup": "^1.0.1",
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
|
import { trap } from 'lib/trap'
|
||||||
import { useMachine } from '@xstate/react'
|
import { useMachine } from '@xstate/react'
|
||||||
import { useNavigate, useRouteLoaderData, useLocation } from 'react-router-dom'
|
import { useNavigate, useRouteLoaderData, useLocation } from 'react-router-dom'
|
||||||
import { PATHS } from 'lib/paths'
|
import { PATHS } from 'lib/paths'
|
||||||
import { authMachine, TOKEN_PERSIST_KEY } from '../machines/authMachine'
|
import { authMachine, TOKEN_PERSIST_KEY } from '../machines/authMachine'
|
||||||
import withBaseUrl from '../lib/withBaseURL'
|
import withBaseUrl from '../lib/withBaseURL'
|
||||||
import React, { createContext, useEffect } from 'react'
|
import React, { createContext, useEffect, useState } from 'react'
|
||||||
import useStateMachineCommands from '../hooks/useStateMachineCommands'
|
import useStateMachineCommands from '../hooks/useStateMachineCommands'
|
||||||
import { settingsMachine } from 'machines/settingsMachine'
|
import { settingsMachine } from 'machines/settingsMachine'
|
||||||
import { toast } from 'react-hot-toast'
|
import { toast } from 'react-hot-toast'
|
||||||
@ -15,7 +16,6 @@ import {
|
|||||||
} from 'lib/theme'
|
} from 'lib/theme'
|
||||||
import decamelize from 'decamelize'
|
import decamelize from 'decamelize'
|
||||||
import { Actor, AnyStateMachine, ContextFrom, Prop, StateFrom } from 'xstate'
|
import { Actor, AnyStateMachine, ContextFrom, Prop, StateFrom } from 'xstate'
|
||||||
import { isDesktop } from 'lib/isDesktop'
|
|
||||||
import { authCommandBarConfig } from 'lib/commandBarConfigs/authCommandConfig'
|
import { authCommandBarConfig } from 'lib/commandBarConfigs/authCommandConfig'
|
||||||
import {
|
import {
|
||||||
kclManager,
|
kclManager,
|
||||||
@ -33,8 +33,14 @@ import {
|
|||||||
import { useCommandsContext } from 'hooks/useCommandsContext'
|
import { useCommandsContext } from 'hooks/useCommandsContext'
|
||||||
import { Command } from 'lib/commandTypes'
|
import { Command } from 'lib/commandTypes'
|
||||||
import { BaseUnit } from 'lib/settings/settingsTypes'
|
import { BaseUnit } from 'lib/settings/settingsTypes'
|
||||||
import { saveSettings } from 'lib/settings/settingsUtils'
|
import {
|
||||||
|
saveSettings,
|
||||||
|
loadAndValidateSettings,
|
||||||
|
} from 'lib/settings/settingsUtils'
|
||||||
import { reportRejection } from 'lib/trap'
|
import { reportRejection } from 'lib/trap'
|
||||||
|
import { getAppSettingsFilePath } from 'lib/desktop'
|
||||||
|
import { isDesktop } from 'lib/isDesktop'
|
||||||
|
import { useFileSystemWatcher } from 'hooks/useFileSystemWatcher'
|
||||||
|
|
||||||
type MachineContext<T extends AnyStateMachine> = {
|
type MachineContext<T extends AnyStateMachine> = {
|
||||||
state: StateFrom<T>
|
state: StateFrom<T>
|
||||||
@ -99,6 +105,9 @@ export const SettingsAuthProviderBase = ({
|
|||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const { commandBarSend } = useCommandsContext()
|
const { commandBarSend } = useCommandsContext()
|
||||||
|
const [settingsPath, setSettingsPath] = useState<string | undefined>(
|
||||||
|
undefined
|
||||||
|
)
|
||||||
|
|
||||||
const [settingsState, settingsSend, settingsActor] = useMachine(
|
const [settingsState, settingsSend, settingsActor] = useMachine(
|
||||||
settingsMachine.provide({
|
settingsMachine.provide({
|
||||||
@ -191,7 +200,11 @@ export const SettingsAuthProviderBase = ({
|
|||||||
console.error('Error executing AST after settings change', e)
|
console.error('Error executing AST after settings change', e)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
persistSettings: ({ context }) => {
|
persistSettings: ({ context, event }) => {
|
||||||
|
// Without this, when a user changes the file, it'd
|
||||||
|
// create a detection loop with the file-system watcher.
|
||||||
|
if (event.doNotPersist) return
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
saveSettings(context, loadedProject?.project?.path)
|
saveSettings(context, loadedProject?.project?.path)
|
||||||
},
|
},
|
||||||
@ -201,6 +214,23 @@ export const SettingsAuthProviderBase = ({
|
|||||||
)
|
)
|
||||||
settingsStateRef = settingsState.context
|
settingsStateRef = settingsState.context
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isDesktop()) return
|
||||||
|
getAppSettingsFilePath().then(setSettingsPath).catch(trap)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useFileSystemWatcher(
|
||||||
|
async () => {
|
||||||
|
const data = await loadAndValidateSettings(loadedProject?.project?.path)
|
||||||
|
settingsSend({
|
||||||
|
type: 'Set all settings',
|
||||||
|
settings: data.settings,
|
||||||
|
doNotPersist: true,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
settingsPath ? [settingsPath] : []
|
||||||
|
)
|
||||||
|
|
||||||
// Add settings commands to the command bar
|
// Add settings commands to the command bar
|
||||||
// They're treated slightly differently than other commands
|
// They're treated slightly differently than other commands
|
||||||
// Because their state machine doesn't have a meaningful .nextEvents,
|
// Because their state machine doesn't have a meaningful .nextEvents,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { isDesktop } from 'lib/isDesktop'
|
import { isDesktop } from 'lib/isDesktop'
|
||||||
|
import { reportRejection } from 'lib/trap'
|
||||||
import { useEffect, useState, useRef } from 'react'
|
import { useEffect, useState, useRef } from 'react'
|
||||||
|
|
||||||
type Path = string
|
type Path = string
|
||||||
@ -11,13 +12,13 @@ type Path = string
|
|||||||
// watcher.addListener(() => { ... }).
|
// watcher.addListener(() => { ... }).
|
||||||
|
|
||||||
export const useFileSystemWatcher = (
|
export const useFileSystemWatcher = (
|
||||||
callback: (path: Path) => void,
|
callback: (path: Path) => Promise<void>,
|
||||||
dependencyArray: Path[]
|
dependencyArray: Path[]
|
||||||
): void => {
|
): void => {
|
||||||
// Track a ref to the callback. This is how we get the callback updated
|
// Track a ref to the callback. This is how we get the callback updated
|
||||||
// across the NodeJS<->Browser boundary.
|
// across the NodeJS<->Browser boundary.
|
||||||
const callbackRef = useRef<{ fn: (path: Path) => void }>({
|
const callbackRef = useRef<{ fn: (path: Path) => Promise<void> }>({
|
||||||
fn: (_path) => {},
|
fn: async (_path) => {},
|
||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -35,7 +36,9 @@ export const useFileSystemWatcher = (
|
|||||||
if (!isDesktop()) return
|
if (!isDesktop()) return
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.electron.watchFileObliterate()
|
for (let path of dependencyArray) {
|
||||||
|
window.electron.watchFileOff(path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
@ -46,6 +49,9 @@ export const useFileSystemWatcher = (
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hasDiff =
|
||||||
|
difference(dependencyArray, dependencyArrayTracked)[0].length !== 0
|
||||||
|
|
||||||
// Removing 1 watcher at a time is only possible because in a filesystem,
|
// Removing 1 watcher at a time is only possible because in a filesystem,
|
||||||
// a path is unique (there can never be two paths with the same name).
|
// a path is unique (there can never be two paths with the same name).
|
||||||
// Otherwise we would have to obliterate() the whole list and reconstruct it.
|
// Otherwise we would have to obliterate() the whole list and reconstruct it.
|
||||||
@ -53,6 +59,8 @@ export const useFileSystemWatcher = (
|
|||||||
// The hook is useless on web.
|
// The hook is useless on web.
|
||||||
if (!isDesktop()) return
|
if (!isDesktop()) return
|
||||||
|
|
||||||
|
if (!hasDiff) return
|
||||||
|
|
||||||
const [pathsRemoved, pathsRemaining] = difference(
|
const [pathsRemoved, pathsRemaining] = difference(
|
||||||
dependencyArrayTracked,
|
dependencyArrayTracked,
|
||||||
dependencyArray
|
dependencyArray
|
||||||
@ -62,10 +70,10 @@ export const useFileSystemWatcher = (
|
|||||||
}
|
}
|
||||||
const [pathsAdded] = difference(dependencyArray, dependencyArrayTracked)
|
const [pathsAdded] = difference(dependencyArray, dependencyArrayTracked)
|
||||||
for (let path of pathsAdded) {
|
for (let path of pathsAdded) {
|
||||||
window.electron.watchFileOn(path, (_eventType: string, path: Path) =>
|
window.electron.watchFileOn(path, (_eventType: string, path: Path) => {
|
||||||
callbackRef.current.fn(path)
|
callbackRef.current.fn(path).catch(reportRejection)
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
setDependencyArrayTracked(pathsRemaining.concat(pathsAdded))
|
setDependencyArrayTracked(pathsRemaining.concat(pathsAdded))
|
||||||
}, [difference(dependencyArray, dependencyArrayTracked)[0].length !== 0])
|
}, [hasDiff])
|
||||||
}
|
}
|
||||||
|
@ -379,7 +379,7 @@ const getAppFolderName = () => {
|
|||||||
return window.electron.packageJson.name
|
return window.electron.packageJson.name
|
||||||
}
|
}
|
||||||
|
|
||||||
const getAppSettingsFilePath = async () => {
|
export const getAppSettingsFilePath = async () => {
|
||||||
const isTestEnv = window.electron.process.env.IS_PLAYWRIGHT === 'true'
|
const isTestEnv = window.electron.process.env.IS_PLAYWRIGHT === 'true'
|
||||||
const testSettingsPath = window.electron.process.env.TEST_SETTINGS_FILE_KEY
|
const testSettingsPath = window.electron.process.env.TEST_SETTINGS_FILE_KEY
|
||||||
const appConfig = await window.electron.getPath('appData')
|
const appConfig = await window.electron.getPath('appData')
|
||||||
|
@ -177,14 +177,14 @@ export async function loadAndValidateSettings(
|
|||||||
|
|
||||||
if (err(appSettingsPayload)) return Promise.reject(appSettingsPayload)
|
if (err(appSettingsPayload)) return Promise.reject(appSettingsPayload)
|
||||||
|
|
||||||
const settings = createSettings()
|
let settingsNext = createSettings()
|
||||||
// Because getting the default directory is async, we need to set it after
|
// Because getting the default directory is async, we need to set it after
|
||||||
if (onDesktop) {
|
if (onDesktop) {
|
||||||
settings.app.projectDirectory.default = await getInitialDefaultDir()
|
settings.app.projectDirectory.default = await getInitialDefaultDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
setSettingsAtLevel(
|
settingsNext = setSettingsAtLevel(
|
||||||
settings,
|
settingsNext,
|
||||||
'user',
|
'user',
|
||||||
configurationToSettingsPayload(appSettingsPayload)
|
configurationToSettingsPayload(appSettingsPayload)
|
||||||
)
|
)
|
||||||
@ -199,8 +199,8 @@ export async function loadAndValidateSettings(
|
|||||||
return Promise.reject(new Error('Invalid project settings'))
|
return Promise.reject(new Error('Invalid project settings'))
|
||||||
|
|
||||||
const projectSettingsPayload = projectSettings
|
const projectSettingsPayload = projectSettings
|
||||||
setSettingsAtLevel(
|
settingsNext = setSettingsAtLevel(
|
||||||
settings,
|
settingsNext,
|
||||||
'project',
|
'project',
|
||||||
projectConfigurationToSettingsPayload(projectSettingsPayload)
|
projectConfigurationToSettingsPayload(projectSettingsPayload)
|
||||||
)
|
)
|
||||||
@ -208,7 +208,7 @@ export async function loadAndValidateSettings(
|
|||||||
|
|
||||||
// Return the settings object
|
// Return the settings object
|
||||||
return {
|
return {
|
||||||
settings,
|
settings: settingsNext,
|
||||||
configuration: appSettingsPayload,
|
configuration: appSettingsPayload,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ export const settingsMachine = setup({
|
|||||||
types: {
|
types: {
|
||||||
context: {} as ReturnType<typeof createSettings>,
|
context: {} as ReturnType<typeof createSettings>,
|
||||||
input: {} as ReturnType<typeof createSettings>,
|
input: {} as ReturnType<typeof createSettings>,
|
||||||
events: {} as
|
events: {} as (
|
||||||
| WildcardSetEvent<SettingsPaths>
|
| WildcardSetEvent<SettingsPaths>
|
||||||
| SetEventTypes
|
| SetEventTypes
|
||||||
| {
|
| {
|
||||||
@ -34,7 +34,8 @@ export const settingsMachine = setup({
|
|||||||
type: 'Reset settings'
|
type: 'Reset settings'
|
||||||
level: SettingsLevel
|
level: SettingsLevel
|
||||||
}
|
}
|
||||||
| { type: 'Set all settings'; settings: typeof settings },
|
| { type: 'Set all settings'; settings: typeof settings }
|
||||||
|
) & { doNotPersist?: boolean },
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setEngineTheme: () => {},
|
setEngineTheme: () => {},
|
||||||
|
@ -5,6 +5,7 @@ import os from 'node:os'
|
|||||||
import fsSync from 'node:fs'
|
import fsSync from 'node:fs'
|
||||||
import packageJson from '../package.json'
|
import packageJson from '../package.json'
|
||||||
import { MachinesListing } from 'lib/machineManager'
|
import { MachinesListing } from 'lib/machineManager'
|
||||||
|
import chokidar from 'chokidar'
|
||||||
|
|
||||||
const open = (args: any) => ipcRenderer.invoke('dialog.showOpenDialog', args)
|
const open = (args: any) => ipcRenderer.invoke('dialog.showOpenDialog', args)
|
||||||
const save = (args: any) => ipcRenderer.invoke('dialog.showSaveDialog', args)
|
const save = (args: any) => ipcRenderer.invoke('dialog.showSaveDialog', args)
|
||||||
@ -23,36 +24,21 @@ const isMac = os.platform() === 'darwin'
|
|||||||
const isWindows = os.platform() === 'win32'
|
const isWindows = os.platform() === 'win32'
|
||||||
const isLinux = os.platform() === 'linux'
|
const isLinux = os.platform() === 'linux'
|
||||||
|
|
||||||
let fsWatchListeners = new Map<
|
let fsWatchListeners = new Map<string, ReturnType<typeof chokidar.watch>>()
|
||||||
string,
|
|
||||||
{
|
|
||||||
watcher: fsSync.FSWatcher
|
|
||||||
callback: (eventType: string, path: string) => void
|
|
||||||
}
|
|
||||||
>()
|
|
||||||
|
|
||||||
const watchFileOn = (
|
const watchFileOn = (path: string, callback: (path: string) => void) => {
|
||||||
path: string,
|
const watcherMaybe = fsWatchListeners.get(path)
|
||||||
callback: (eventType: string, path: string) => void
|
if (watcherMaybe) return
|
||||||
) => {
|
const watcher = chokidar.watch(path)
|
||||||
const watcher = fsSync.watch(path)
|
watcher.on('all', callback)
|
||||||
watcher.on('change', callback)
|
fsWatchListeners.set(path, watcher)
|
||||||
fsWatchListeners.set(path, { watcher, callback })
|
|
||||||
}
|
}
|
||||||
const watchFileOff = (path: string) => {
|
const watchFileOff = (path: string) => {
|
||||||
const entry = fsWatchListeners.get(path)
|
const watcher = fsWatchListeners.get(path)
|
||||||
if (!entry) return
|
if (!watcher) return
|
||||||
const { watcher, callback } = entry
|
watcher.unwatch(path)
|
||||||
watcher.off('change', callback)
|
|
||||||
watcher.close()
|
|
||||||
fsWatchListeners.delete(path)
|
fsWatchListeners.delete(path)
|
||||||
}
|
}
|
||||||
const watchFileObliterate = () => {
|
|
||||||
for (let [pathAsKey] of fsWatchListeners) {
|
|
||||||
watchFileOff(pathAsKey)
|
|
||||||
}
|
|
||||||
fsWatchListeners = new Map()
|
|
||||||
}
|
|
||||||
const readFile = (path: string) => fs.readFile(path, 'utf-8')
|
const readFile = (path: string) => fs.readFile(path, 'utf-8')
|
||||||
// It seems like from the node source code this does not actually block but also
|
// It seems like from the node source code this does not actually block but also
|
||||||
// don't trust me on that (jess).
|
// don't trust me on that (jess).
|
||||||
@ -103,7 +89,6 @@ contextBridge.exposeInMainWorld('electron', {
|
|||||||
// exported.
|
// exported.
|
||||||
watchFileOn,
|
watchFileOn,
|
||||||
watchFileOff,
|
watchFileOff,
|
||||||
watchFileObliterate,
|
|
||||||
readFile,
|
readFile,
|
||||||
writeFile,
|
writeFile,
|
||||||
exists,
|
exists,
|
||||||
|
@ -57,7 +57,7 @@ const Home = () => {
|
|||||||
|
|
||||||
// Re-read projects listing if the projectDir has any updates.
|
// Re-read projects listing if the projectDir has any updates.
|
||||||
useFileSystemWatcher(
|
useFileSystemWatcher(
|
||||||
() => {
|
async () => {
|
||||||
setProjectsLoaderTrigger(projectsLoaderTrigger + 1)
|
setProjectsLoaderTrigger(projectsLoaderTrigger + 1)
|
||||||
},
|
},
|
||||||
projectsDir ? [projectsDir] : []
|
projectsDir ? [projectsDir] : []
|
||||||
|
43
src/wasm-lib/Cargo.lock
generated
43
src/wasm-lib/Cargo.lock
generated
@ -934,9 +934,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures"
|
name = "futures"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@ -949,9 +949,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
@ -959,15 +959,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-executor"
|
name = "futures-executor"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
@ -976,15 +976,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-io"
|
name = "futures-io"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-macro"
|
name = "futures-macro"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -993,21 +993,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-util"
|
name = "futures-util"
|
||||||
version = "0.3.30"
|
version = "0.3.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@ -1966,12 +1966,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.20.1"
|
version = "1.20.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1"
|
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||||
dependencies = [
|
|
||||||
"portable-atomic",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oncemutex"
|
name = "oncemutex"
|
||||||
|
@ -35,7 +35,7 @@ uuid = { version = "1.10.0", features = ["v4", "js", "serde"] }
|
|||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
console_error_panic_hook = "0.1.7"
|
console_error_panic_hook = "0.1.7"
|
||||||
futures = "0.3.30"
|
futures = "0.3.31"
|
||||||
js-sys = "0.3.69"
|
js-sys = "0.3.69"
|
||||||
tower-lsp = { version = "0.20.0", default-features = false, features = ["runtime-agnostic"] }
|
tower-lsp = { version = "0.20.0", default-features = false, features = ["runtime-agnostic"] }
|
||||||
wasm-bindgen-futures = { version = "0.4.41", features = ["futures-core-03-stream"] }
|
wasm-bindgen-futures = { version = "0.4.41", features = ["futures-core-03-stream"] }
|
||||||
|
@ -14,7 +14,7 @@ proc-macro = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
Inflector = "0.11.4"
|
Inflector = "0.11.4"
|
||||||
convert_case = "0.6.0"
|
convert_case = "0.6.0"
|
||||||
once_cell = "1.19.0"
|
once_cell = "1.20.2"
|
||||||
proc-macro2 = "1"
|
proc-macro2 = "1"
|
||||||
quote = "1"
|
quote = "1"
|
||||||
regex = "1.10"
|
regex = "1.10"
|
||||||
|
@ -22,7 +22,7 @@ dashmap = "6.1.0"
|
|||||||
databake = { version = "0.1.8", features = ["derive"] }
|
databake = { version = "0.1.8", features = ["derive"] }
|
||||||
derive-docs = { version = "0.1.29", path = "../derive-docs" }
|
derive-docs = { version = "0.1.29", path = "../derive-docs" }
|
||||||
form_urlencoded = "1.2.1"
|
form_urlencoded = "1.2.1"
|
||||||
futures = { version = "0.3.30" }
|
futures = { version = "0.3.31" }
|
||||||
git_rev = "0.1.0"
|
git_rev = "0.1.0"
|
||||||
gltf-json = "1.4.1"
|
gltf-json = "1.4.1"
|
||||||
http = { workspace = true }
|
http = { workspace = true }
|
||||||
|
43
yarn.lock
43
yarn.lock
@ -3780,6 +3780,13 @@ chokidar@^3.5.3:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents "~2.3.2"
|
fsevents "~2.3.2"
|
||||||
|
|
||||||
|
chokidar@^4.0.1:
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.1.tgz#4a6dff66798fb0f72a94f616abbd7e1a19f31d41"
|
||||||
|
integrity sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==
|
||||||
|
dependencies:
|
||||||
|
readdirp "^4.0.1"
|
||||||
|
|
||||||
chownr@^2.0.0:
|
chownr@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
|
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
|
||||||
@ -8155,6 +8162,11 @@ readable-stream@~2.3.6:
|
|||||||
string_decoder "~1.1.1"
|
string_decoder "~1.1.1"
|
||||||
util-deprecate "~1.0.1"
|
util-deprecate "~1.0.1"
|
||||||
|
|
||||||
|
readdirp@^4.0.1:
|
||||||
|
version "4.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.0.2.tgz#388fccb8b75665da3abffe2d8f8ed59fe74c230a"
|
||||||
|
integrity sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==
|
||||||
|
|
||||||
readdirp@~3.6.0:
|
readdirp@~3.6.0:
|
||||||
version "3.6.0"
|
version "3.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
||||||
@ -8773,16 +8785,7 @@ string-natural-compare@^3.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
|
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
|
||||||
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==
|
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==
|
||||||
|
|
||||||
"string-width-cjs@npm:string-width@^4.2.0":
|
"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||||
version "4.2.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
|
||||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
|
||||||
dependencies:
|
|
||||||
emoji-regex "^8.0.0"
|
|
||||||
is-fullwidth-code-point "^3.0.0"
|
|
||||||
strip-ansi "^6.0.1"
|
|
||||||
|
|
||||||
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
|
||||||
version "4.2.3"
|
version "4.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
@ -8876,14 +8879,7 @@ string_decoder@~1.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "~5.1.0"
|
safe-buffer "~5.1.0"
|
||||||
|
|
||||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||||
version "6.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
|
||||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
|
||||||
dependencies:
|
|
||||||
ansi-regex "^5.0.1"
|
|
||||||
|
|
||||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
|
||||||
version "6.0.1"
|
version "6.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
@ -9757,16 +9753,7 @@ word-wrap@^1.2.3, word-wrap@^1.2.5:
|
|||||||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
|
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
|
||||||
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
|
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
|
||||||
|
|
||||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
|
||||||
version "7.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
|
||||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
|
||||||
dependencies:
|
|
||||||
ansi-styles "^4.0.0"
|
|
||||||
string-width "^4.1.0"
|
|
||||||
strip-ansi "^6.0.0"
|
|
||||||
|
|
||||||
wrap-ansi@^7.0.0:
|
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||||
|
Reference in New Issue
Block a user