save as bw compatible (#6088)
* save as bw compatible Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * js side only for bw compatibility changes Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * failure for doing wrong thing Signed-off-by: Jess Frazelle <github@jessfraz.com> * remove from ts side Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -69,6 +69,14 @@
|
|||||||
{
|
{
|
||||||
"selector": "CallExpression[callee.object.name='Array'][callee.property.name='isArray']",
|
"selector": "CallExpression[callee.object.name='Array'][callee.property.name='isArray']",
|
||||||
"message": "Use isArray() in lib/utils.ts instead of Array.isArray()."
|
"message": "Use isArray() in lib/utils.ts instead of Array.isArray()."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selector": "CallExpression[callee.object.name='TOML'][callee.property.name='stringify']",
|
||||||
|
"message": "Do not use TOML.stringify directly. Use the wrappers in test-utils instead like settingsToToml."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"selector": "CallExpression[callee.object.name='TOML'][callee.property.name='parse']",
|
||||||
|
"message": "Do not use TOML.parse directly. Use the wrappers in test-utils instead like tomlToSettings."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"semi": [
|
"semi": [
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/* eslint-disable react-hooks/rules-of-hooks */
|
/* eslint-disable react-hooks/rules-of-hooks */
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
BrowserContext,
|
BrowserContext,
|
||||||
ElectronApplication,
|
ElectronApplication,
|
||||||
@ -9,10 +8,9 @@ import type {
|
|||||||
|
|
||||||
import { _electron as electron } from '@playwright/test'
|
import { _electron as electron } from '@playwright/test'
|
||||||
|
|
||||||
import * as TOML from '@iarna/toml'
|
|
||||||
import { TEST_SETTINGS } from '../storageStates'
|
import { TEST_SETTINGS } from '../storageStates'
|
||||||
import { SETTINGS_FILE_NAME } from 'lib/constants'
|
import { SETTINGS_FILE_NAME } from 'lib/constants'
|
||||||
import { getUtils, setup } from '../test-utils'
|
import { getUtils, setup, settingsToToml } from '../test-utils'
|
||||||
import fsp from 'fs/promises'
|
import fsp from 'fs/promises'
|
||||||
import fs from 'node:fs'
|
import fs from 'node:fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
@ -287,26 +285,30 @@ export class ElectronZoo {
|
|||||||
let settingsOverridesToml = ''
|
let settingsOverridesToml = ''
|
||||||
|
|
||||||
if (appSettings) {
|
if (appSettings) {
|
||||||
settingsOverridesToml = TOML.stringify({
|
settingsOverridesToml = settingsToToml({
|
||||||
// @ts-expect-error
|
|
||||||
settings: {
|
settings: {
|
||||||
...TEST_SETTINGS,
|
...TEST_SETTINGS,
|
||||||
...appSettings,
|
...appSettings,
|
||||||
app: {
|
app: {
|
||||||
...TEST_SETTINGS.app,
|
...TEST_SETTINGS.app,
|
||||||
project_directory: this.projectDirName,
|
|
||||||
...appSettings.app,
|
...appSettings.app,
|
||||||
},
|
},
|
||||||
|
project: {
|
||||||
|
...TEST_SETTINGS.project,
|
||||||
|
directory: this.projectDirName,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
settingsOverridesToml = TOML.stringify({
|
settingsOverridesToml = settingsToToml({
|
||||||
// @ts-expect-error
|
|
||||||
settings: {
|
settings: {
|
||||||
...TEST_SETTINGS,
|
...TEST_SETTINGS,
|
||||||
app: {
|
app: {
|
||||||
...TEST_SETTINGS.app,
|
...TEST_SETTINGS.app,
|
||||||
project_directory: this.projectDirName,
|
},
|
||||||
|
project: {
|
||||||
|
...TEST_SETTINGS.project,
|
||||||
|
directory: this.projectDirName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -345,8 +345,10 @@ const extrudeDefaultPlane = async (
|
|||||||
app: {
|
app: {
|
||||||
onboarding_status: 'dismissed',
|
onboarding_status: 'dismissed',
|
||||||
show_debug_panel: true,
|
show_debug_panel: true,
|
||||||
|
appearance: {
|
||||||
theme: 'dark',
|
theme: 'dark',
|
||||||
},
|
},
|
||||||
|
},
|
||||||
project: {
|
project: {
|
||||||
default_project_name: 'project-$nnn',
|
default_project_name: 'project-$nnn',
|
||||||
},
|
},
|
||||||
|
@ -9,9 +9,10 @@ export const IS_PLAYWRIGHT_KEY = 'playwright'
|
|||||||
export const TEST_SETTINGS_KEY = '/settings.toml'
|
export const TEST_SETTINGS_KEY = '/settings.toml'
|
||||||
export const TEST_SETTINGS: DeepPartial<Settings> = {
|
export const TEST_SETTINGS: DeepPartial<Settings> = {
|
||||||
app: {
|
app: {
|
||||||
|
appearance: {
|
||||||
theme: Themes.Dark,
|
theme: Themes.Dark,
|
||||||
|
},
|
||||||
onboarding_status: 'dismissed',
|
onboarding_status: 'dismissed',
|
||||||
project_directory: '',
|
|
||||||
show_debug_panel: true,
|
show_debug_panel: true,
|
||||||
},
|
},
|
||||||
modeling: {
|
modeling: {
|
||||||
@ -22,6 +23,7 @@ export const TEST_SETTINGS: DeepPartial<Settings> = {
|
|||||||
},
|
},
|
||||||
project: {
|
project: {
|
||||||
default_project_name: 'project-$nnn',
|
default_project_name: 'project-$nnn',
|
||||||
|
directory: '',
|
||||||
},
|
},
|
||||||
text_editor: {
|
text_editor: {
|
||||||
text_wrapping: true,
|
text_wrapping: true,
|
||||||
@ -54,7 +56,7 @@ export const TEST_SETTINGS_ONBOARDING_START: DeepPartial<Settings> = {
|
|||||||
|
|
||||||
export const TEST_SETTINGS_DEFAULT_THEME: DeepPartial<Settings> = {
|
export const TEST_SETTINGS_DEFAULT_THEME: DeepPartial<Settings> = {
|
||||||
...TEST_SETTINGS,
|
...TEST_SETTINGS,
|
||||||
app: { ...TEST_SETTINGS.app, theme: Themes.System },
|
app: { ...TEST_SETTINGS.app, appearance: { theme: Themes.System } },
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TEST_SETTINGS_CORRUPTED = {
|
export const TEST_SETTINGS_CORRUPTED = {
|
||||||
|
@ -903,15 +903,21 @@ export async function setup(
|
|||||||
settings: {
|
settings: {
|
||||||
...TEST_SETTINGS,
|
...TEST_SETTINGS,
|
||||||
app: {
|
app: {
|
||||||
...TEST_SETTINGS.project,
|
appearance: {
|
||||||
project_directory: TEST_SETTINGS.app?.project_directory,
|
...TEST_SETTINGS.app?.appearance,
|
||||||
onboarding_status: 'dismissed',
|
|
||||||
theme: 'dark',
|
theme: 'dark',
|
||||||
},
|
},
|
||||||
|
...TEST_SETTINGS.project,
|
||||||
|
onboarding_status: 'dismissed',
|
||||||
|
},
|
||||||
|
project: {
|
||||||
|
...TEST_SETTINGS.project,
|
||||||
|
directory: TEST_SETTINGS.project?.directory,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
IS_PLAYWRIGHT_KEY,
|
IS_PLAYWRIGHT_KEY,
|
||||||
PLAYWRIGHT_TEST_DIR: TEST_SETTINGS.app?.project_directory || '',
|
PLAYWRIGHT_TEST_DIR: TEST_SETTINGS.project?.directory || '',
|
||||||
PERSIST_MODELING_CONTEXT,
|
PERSIST_MODELING_CONTEXT,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -1112,21 +1118,25 @@ export async function pollEditorLinesSelectedLength(page: Page, lines: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function settingsToToml(settings: DeepPartial<Configuration>) {
|
export function settingsToToml(settings: DeepPartial<Configuration>) {
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
return TOML.stringify(settings as any)
|
return TOML.stringify(settings as any)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tomlToSettings(toml: string): DeepPartial<Configuration> {
|
export function tomlToSettings(toml: string): DeepPartial<Configuration> {
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
return TOML.parse(toml)
|
return TOML.parse(toml)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tomlToPerProjectSettings(
|
export function tomlToPerProjectSettings(
|
||||||
toml: string
|
toml: string
|
||||||
): DeepPartial<ProjectConfiguration> {
|
): DeepPartial<ProjectConfiguration> {
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
return TOML.parse(toml)
|
return TOML.parse(toml)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function perProjectsettingsToToml(
|
export function perProjectsettingsToToml(
|
||||||
settings: DeepPartial<ProjectConfiguration>
|
settings: DeepPartial<ProjectConfiguration>
|
||||||
) {
|
) {
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
return TOML.stringify(settings as any)
|
return TOML.stringify(settings as any)
|
||||||
}
|
}
|
||||||
|
@ -45,12 +45,12 @@ test.describe('Testing settings', () => {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(storedSettings.settings?.app?.theme).toBe('dark')
|
expect(storedSettings.settings?.app?.appearance?.theme).toBe('dark')
|
||||||
|
|
||||||
// Check that the invalid settings were changed to good defaults
|
// Check that the invalid settings were changed to good defaults
|
||||||
expect(storedSettings.settings?.modeling?.base_unit).toBe('in')
|
expect(storedSettings.settings?.modeling?.base_unit).toBe('in')
|
||||||
expect(storedSettings.settings?.modeling?.mouse_controls).toBe('zoo')
|
expect(storedSettings.settings?.modeling?.mouse_controls).toBe('zoo')
|
||||||
expect(storedSettings.settings?.app?.project_directory).toBe('')
|
expect(storedSettings.settings?.project?.directory).toBe('')
|
||||||
expect(storedSettings.settings?.project?.default_project_name).toBe(
|
expect(storedSettings.settings?.project?.default_project_name).toBe(
|
||||||
'project-$nnn'
|
'project-$nnn'
|
||||||
)
|
)
|
||||||
@ -381,7 +381,9 @@ test.describe('Testing settings', () => {
|
|||||||
}
|
}
|
||||||
await tronApp.cleanProjectDir({
|
await tronApp.cleanProjectDir({
|
||||||
app: {
|
app: {
|
||||||
theme_color: '259',
|
appearance: {
|
||||||
|
color: 259,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -413,9 +415,12 @@ test.describe('Testing settings', () => {
|
|||||||
|
|
||||||
await tronApp.cleanProjectDir({
|
await tronApp.cleanProjectDir({
|
||||||
app: {
|
app: {
|
||||||
|
appearance: {
|
||||||
// Doesn't matter what you set it to. It will
|
// Doesn't matter what you set it to. It will
|
||||||
// default to 264.5
|
// default to 264.5
|
||||||
theme_color: '0',
|
|
||||||
|
color: 0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -113,15 +113,19 @@ pub struct AppSettings {
|
|||||||
pub onboarding_status: OnboardingStatus,
|
pub onboarding_status: OnboardingStatus,
|
||||||
/// Backwards compatible project directory setting.
|
/// Backwards compatible project directory setting.
|
||||||
#[serde(default, alias = "projectDirectory", skip_serializing_if = "Option::is_none")]
|
#[serde(default, alias = "projectDirectory", skip_serializing_if = "Option::is_none")]
|
||||||
|
#[ts(skip)]
|
||||||
pub project_directory: Option<std::path::PathBuf>,
|
pub project_directory: Option<std::path::PathBuf>,
|
||||||
/// Backwards compatible theme setting.
|
/// Backwards compatible theme setting.
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
#[ts(skip)]
|
||||||
pub theme: Option<AppTheme>,
|
pub theme: Option<AppTheme>,
|
||||||
/// The hue of the primary theme color for the app.
|
/// The hue of the primary theme color for the app.
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none", alias = "themeColor")]
|
#[serde(default, skip_serializing_if = "Option::is_none", alias = "themeColor")]
|
||||||
|
#[ts(skip)]
|
||||||
pub theme_color: Option<FloatOrInt>,
|
pub theme_color: Option<FloatOrInt>,
|
||||||
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
|
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
|
||||||
#[serde(default, alias = "enableSSAO", skip_serializing_if = "Option::is_none")]
|
#[serde(default, alias = "enableSSAO", skip_serializing_if = "Option::is_none")]
|
||||||
|
#[ts(skip)]
|
||||||
pub enable_ssao: Option<bool>,
|
pub enable_ssao: Option<bool>,
|
||||||
/// Permanently dismiss the banner warning to download the desktop app.
|
/// Permanently dismiss the banner warning to download the desktop app.
|
||||||
/// This setting only applies to the web app. And is temporary until we have Linux support.
|
/// This setting only applies to the web app. And is temporary until we have Linux support.
|
||||||
@ -285,6 +289,7 @@ pub struct ModelingSettings {
|
|||||||
/// of the app to aid in development.
|
/// of the app to aid in development.
|
||||||
/// Remove this when we remove backwards compatibility with the old settings file.
|
/// Remove this when we remove backwards compatibility with the old settings file.
|
||||||
#[serde(default, alias = "showDebugPanel", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "showDebugPanel", skip_serializing_if = "is_default")]
|
||||||
|
#[ts(skip)]
|
||||||
pub show_debug_panel: bool,
|
pub show_debug_panel: bool,
|
||||||
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
|
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
|
||||||
#[serde(default, skip_serializing_if = "is_default")]
|
#[serde(default, skip_serializing_if = "is_default")]
|
||||||
|
@ -94,9 +94,11 @@ pub struct ProjectAppSettings {
|
|||||||
pub onboarding_status: OnboardingStatus,
|
pub onboarding_status: OnboardingStatus,
|
||||||
/// The hue of the primary theme color for the app.
|
/// The hue of the primary theme color for the app.
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none", alias = "themeColor")]
|
#[serde(default, skip_serializing_if = "Option::is_none", alias = "themeColor")]
|
||||||
|
#[ts(skip)]
|
||||||
pub theme_color: Option<FloatOrInt>,
|
pub theme_color: Option<FloatOrInt>,
|
||||||
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
|
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
|
||||||
#[serde(default, alias = "enableSSAO", skip_serializing_if = "Option::is_none")]
|
#[serde(default, alias = "enableSSAO", skip_serializing_if = "Option::is_none")]
|
||||||
|
#[ts(skip)]
|
||||||
pub enable_ssao: Option<bool>,
|
pub enable_ssao: Option<bool>,
|
||||||
/// Permanently dismiss the banner warning to download the desktop app.
|
/// Permanently dismiss the banner warning to download the desktop app.
|
||||||
/// This setting only applies to the web app. And is temporary until we have Linux support.
|
/// This setting only applies to the web app. And is temporary until we have Linux support.
|
||||||
@ -143,6 +145,7 @@ pub struct ProjectModelingSettings {
|
|||||||
/// of the app to aid in development.
|
/// of the app to aid in development.
|
||||||
/// Remove this when we remove backwards compatibility with the old settings file.
|
/// Remove this when we remove backwards compatibility with the old settings file.
|
||||||
#[serde(default, alias = "showDebugPanel", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "showDebugPanel", skip_serializing_if = "is_default")]
|
||||||
|
#[ts(skip)]
|
||||||
pub show_debug_panel: bool,
|
pub show_debug_panel: bool,
|
||||||
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
|
/// Whether or not Screen Space Ambient Occlusion (SSAO) is enabled.
|
||||||
#[serde(default, skip_serializing_if = "is_default")]
|
#[serde(default, skip_serializing_if = "is_default")]
|
||||||
|
@ -176,6 +176,8 @@ pub fn serialize_configuration(val: JsValue) -> Result<JsValue, String> {
|
|||||||
let config: kcl_lib::Configuration = val.into_serde().map_err(|e| e.to_string())?;
|
let config: kcl_lib::Configuration = val.into_serde().map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
let toml_str = toml::to_string_pretty(&config).map_err(|e| e.to_string())?;
|
let toml_str = toml::to_string_pretty(&config).map_err(|e| e.to_string())?;
|
||||||
|
let settings = kcl_lib::Configuration::backwards_compatible_toml_parse(&toml_str).map_err(|e| e.to_string())?;
|
||||||
|
let toml_str = toml::to_string_pretty(&settings).map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
||||||
// gloo-serialize crate instead.
|
// gloo-serialize crate instead.
|
||||||
@ -190,6 +192,9 @@ pub fn serialize_project_configuration(val: JsValue) -> Result<JsValue, String>
|
|||||||
let config: kcl_lib::ProjectConfiguration = val.into_serde().map_err(|e| e.to_string())?;
|
let config: kcl_lib::ProjectConfiguration = val.into_serde().map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
let toml_str = toml::to_string_pretty(&config).map_err(|e| e.to_string())?;
|
let toml_str = toml::to_string_pretty(&config).map_err(|e| e.to_string())?;
|
||||||
|
let settings =
|
||||||
|
kcl_lib::ProjectConfiguration::backwards_compatible_toml_parse(&toml_str).map_err(|e| e.to_string())?;
|
||||||
|
let toml_str = toml::to_string_pretty(&settings).map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
||||||
// gloo-serialize crate instead.
|
// gloo-serialize crate instead.
|
||||||
|
@ -39,7 +39,6 @@ export function mouseControlsToCameraSystem(
|
|||||||
// TODO: understand why the values come back without underscores and fix the root cause
|
// TODO: understand why the values come back without underscores and fix the root cause
|
||||||
// @ts-ignore: TS2678
|
// @ts-ignore: TS2678
|
||||||
case 'onshape':
|
case 'onshape':
|
||||||
case 'on_shape':
|
|
||||||
return 'OnShape'
|
return 'OnShape'
|
||||||
case 'trackpad_friendly':
|
case 'trackpad_friendly':
|
||||||
return 'Trackpad Friendly'
|
return 'Trackpad Friendly'
|
||||||
@ -52,7 +51,6 @@ export function mouseControlsToCameraSystem(
|
|||||||
// TODO: understand why the values come back without underscores and fix the root cause
|
// TODO: understand why the values come back without underscores and fix the root cause
|
||||||
// @ts-ignore: TS2678
|
// @ts-ignore: TS2678
|
||||||
case 'autocad':
|
case 'autocad':
|
||||||
case 'auto_cad':
|
|
||||||
return 'AutoCAD'
|
return 'AutoCAD'
|
||||||
default:
|
default:
|
||||||
return undefined
|
return undefined
|
||||||
|
@ -67,9 +67,7 @@ export async function renameProjectDirectory(
|
|||||||
export async function ensureProjectDirectoryExists(
|
export async function ensureProjectDirectoryExists(
|
||||||
config: DeepPartial<Configuration>
|
config: DeepPartial<Configuration>
|
||||||
): Promise<string | undefined> {
|
): Promise<string | undefined> {
|
||||||
const projectDir =
|
const projectDir = config.settings?.project?.directory
|
||||||
config.settings?.app?.project_directory ||
|
|
||||||
config.settings?.project?.directory
|
|
||||||
if (!projectDir) {
|
if (!projectDir) {
|
||||||
console.error('projectDir is falsey', config)
|
console.error('projectDir is falsey', config)
|
||||||
return Promise.reject(new Error('projectDir is falsey'))
|
return Promise.reject(new Error('projectDir is falsey'))
|
||||||
@ -588,8 +586,7 @@ export const readAppSettingsFile = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const hasProjectDirectorySetting =
|
const hasProjectDirectorySetting =
|
||||||
parsedAppConfig.settings?.project?.directory ||
|
parsedAppConfig.settings?.project?.directory
|
||||||
parsedAppConfig.settings?.app?.project_directory
|
|
||||||
|
|
||||||
if (hasProjectDirectorySetting) {
|
if (hasProjectDirectorySetting) {
|
||||||
return parsedAppConfig
|
return parsedAppConfig
|
||||||
|
Reference in New Issue
Block a user