At implementing login and getUser
This commit is contained in:
@ -60,6 +60,9 @@ root.render(
|
|||||||
reportWebVitals()
|
reportWebVitals()
|
||||||
|
|
||||||
const runTauriUpdater = async () => {
|
const runTauriUpdater = async () => {
|
||||||
|
console.log('STUB: @pierre')
|
||||||
|
return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const update = await check()
|
const update = await check()
|
||||||
if (update && update.available) {
|
if (update && update.available) {
|
||||||
|
@ -15,14 +15,16 @@ class FileSystemManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async join(dir: string, path: string): Promise<string> {
|
async join(dir: string, path: string): Promise<string> {
|
||||||
return window.electron.ipcRenderer.invoke('join', [dir, path]);
|
return window.electron.ipcRenderer.invoke('join', [dir, path])
|
||||||
}
|
}
|
||||||
|
|
||||||
async readFile(path: string): Promise<Uint8Array | void> {
|
async readFile(path: string): Promise<Uint8Array | void> {
|
||||||
// Using local file system only works from desktop.
|
// Using local file system only works from desktop.
|
||||||
if (!isDesktop()) {
|
if (!isDesktop()) {
|
||||||
return Promise.reject(
|
return Promise.reject(
|
||||||
new Error('This function can only be called from the desktop application')
|
new Error(
|
||||||
|
'This function can only be called from the desktop application'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +41,9 @@ class FileSystemManager {
|
|||||||
// Using local file system only works from desktop.
|
// Using local file system only works from desktop.
|
||||||
if (!isDesktop()) {
|
if (!isDesktop()) {
|
||||||
return Promise.reject(
|
return Promise.reject(
|
||||||
new Error('This function can only be called from the desktop application')
|
new Error(
|
||||||
|
'This function can only be called from the desktop application'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +60,9 @@ class FileSystemManager {
|
|||||||
// Using local file system only works from desktop.
|
// Using local file system only works from desktop.
|
||||||
if (!isDesktop()) {
|
if (!isDesktop()) {
|
||||||
return Promise.reject(
|
return Promise.reject(
|
||||||
new Error('This function can only be called from the desktop application')
|
new Error(
|
||||||
|
'This function can only be called from the desktop application'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +71,8 @@ class FileSystemManager {
|
|||||||
return Promise.reject(new Error(`Error joining dir: ${error}`))
|
return Promise.reject(new Error(`Error joining dir: ${error}`))
|
||||||
})
|
})
|
||||||
.then((filepath) => {
|
.then((filepath) => {
|
||||||
return window.electron.ipcRenderer.invoke('readdir', [filepath])
|
return window.electron.ipcRenderer
|
||||||
|
.invoke('readdir', [filepath])
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
return Promise.reject(new Error(`Error reading dir: ${error}`))
|
return Promise.reject(new Error(`Error reading dir: ${error}`))
|
||||||
})
|
})
|
||||||
|
@ -17,6 +17,7 @@ import init, {
|
|||||||
parse_project_settings,
|
parse_project_settings,
|
||||||
default_project_settings,
|
default_project_settings,
|
||||||
parse_project_route,
|
parse_project_route,
|
||||||
|
serialize_project_settings,
|
||||||
} from '../wasm-lib/pkg/wasm_lib'
|
} from '../wasm-lib/pkg/wasm_lib'
|
||||||
import { KCLError } from './errors'
|
import { KCLError } from './errors'
|
||||||
import { KclError as RustKclError } from '../wasm-lib/kcl/bindings/KclError'
|
import { KclError as RustKclError } from '../wasm-lib/kcl/bindings/KclError'
|
||||||
@ -558,7 +559,7 @@ export function tomlStringify(toml: any): string | Error {
|
|||||||
return toml_stringify(JSON.stringify(toml))
|
return toml_stringify(JSON.stringify(toml))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function defaultAppSettings(): Configuration | Error {
|
export function defaultAppSettings(): Configuration {
|
||||||
return default_app_settings()
|
return default_app_settings()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,3 +583,79 @@ export function parseProjectRoute(
|
|||||||
): ProjectRoute | Error {
|
): ProjectRoute | Error {
|
||||||
return parse_project_route(JSON.stringify(configuration), route_str)
|
return parse_project_route(JSON.stringify(configuration), route_str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_HOST = 'https://api.zoo.dev'
|
||||||
|
const SETTINGS_FILE_NAME = 'settings.toml'
|
||||||
|
const PROJECT_SETTINGS_FILE_NAME = 'project.toml'
|
||||||
|
const PROJECT_FOLDER = 'zoo-modeling-app-projects'
|
||||||
|
|
||||||
|
const getAppSettingsFilePath = async () => {
|
||||||
|
const appConfig = await window.electron.getPath('appData')
|
||||||
|
const fullPath = window.electron.path.join(
|
||||||
|
appConfig,
|
||||||
|
window.electron.packageJson.name
|
||||||
|
)
|
||||||
|
try {
|
||||||
|
await window.electron.exists(fullPath)
|
||||||
|
} catch (e) {
|
||||||
|
// File/path doesn't exist
|
||||||
|
if (e.code === 'ENOENT') {
|
||||||
|
window.electron.mkdir(fullPath, { recursive: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return window.electron.path.join(fullPath, SETTINGS_FILE_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getInitialDefaultDir = async () => {
|
||||||
|
const dir = await window.electron.getPath('documents')
|
||||||
|
return window.electron.path.join(dir, PROJECT_FOLDER)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const readAppSettingsFile = async () => {
|
||||||
|
let settingsPath = await getAppSettingsFilePath()
|
||||||
|
try {
|
||||||
|
await window.electron.exists(settingsPath)
|
||||||
|
} catch (e) {
|
||||||
|
if (e === 'ENOENT') {
|
||||||
|
const config = defaultAppSettings()
|
||||||
|
config.settings.project.directory = await getInitialDefaultDir()
|
||||||
|
console.log(config)
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const configToml = await window.electron.readFile(settingsPath)
|
||||||
|
const configObj = parseProjectSettings(configStr)
|
||||||
|
return configObj
|
||||||
|
}
|
||||||
|
|
||||||
|
export const writeAppSettingsFile = async () => {
|
||||||
|
debugger
|
||||||
|
console.log("STUB")
|
||||||
|
}
|
||||||
|
|
||||||
|
let appStateStore = undefined
|
||||||
|
|
||||||
|
export const getState = async (): Promise<ProjectState | undefined> => {
|
||||||
|
return Promise.resolve(appStateStore)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const setState = async (
|
||||||
|
state: ProjectState | undefined
|
||||||
|
): Promise<void> => {
|
||||||
|
appStateStore = state
|
||||||
|
}
|
||||||
|
|
||||||
|
const initializeProjectDirectory = () => {
|
||||||
|
debugger
|
||||||
|
console.log('STUB')
|
||||||
|
}
|
||||||
|
|
||||||
|
export const login = () => {
|
||||||
|
debugger
|
||||||
|
console.log('STUB')
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getUser = (token: string, host: string) => {
|
||||||
|
debugger
|
||||||
|
console.log("STUB")
|
||||||
|
}
|
||||||
|
@ -8,21 +8,14 @@ import { ProjectRoute } from 'wasm-lib/kcl/bindings/ProjectRoute'
|
|||||||
import { components } from './machine-api'
|
import { components } from './machine-api'
|
||||||
import { isDesktop } from './isDesktop'
|
import { isDesktop } from './isDesktop'
|
||||||
|
|
||||||
// Get the app state from desktop.
|
export {
|
||||||
export async function getState(): Promise<ProjectState | undefined> {
|
readAppSettingsFile,
|
||||||
if (!isDesktop()) {
|
writeAppSettingsFile,
|
||||||
return undefined
|
getState,
|
||||||
}
|
setState,
|
||||||
return await window.electron.ipcRenderer.invoke('get_state')
|
getUser,
|
||||||
}
|
login,
|
||||||
|
} from 'lang/wasm'
|
||||||
// Set the app state in desktop.
|
|
||||||
export async function setState(state: ProjectState | undefined): Promise<void> {
|
|
||||||
if (!isDesktop()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return window.electron.ipcRenderer.invoke('set_state', { state })
|
|
||||||
}
|
|
||||||
|
|
||||||
// List machines on the local network.
|
// List machines on the local network.
|
||||||
export async function listMachines(): Promise<{
|
export async function listMachines(): Promise<{
|
||||||
@ -41,21 +34,18 @@ export async function renameProjectDirectory(
|
|||||||
projectPath: string,
|
projectPath: string,
|
||||||
newName: string
|
newName: string
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
return window.electron.ipcRenderer.invoke<string>('rename_project_directory', { projectPath, newName })
|
return window.electron.ipcRenderer.invoke<string>(
|
||||||
|
'rename_project_directory',
|
||||||
|
{ projectPath, newName }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the initial default dir for holding all projects.
|
// Get the initial default dir for holding all projects.
|
||||||
export async function getInitialDefaultDir(): Promise<string> {
|
export async function getInitialDefaultDir(): Promise<string> {
|
||||||
if (!isDesktop()) {
|
return window.electron.getInitialDefaultDir()
|
||||||
return ''
|
|
||||||
}
|
|
||||||
return invoke<string>('get_initial_default_dir')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function showInFolder(path: string | undefined): Promise<void> {
|
export async function showInFolder(path: string | undefined): Promise<void> {
|
||||||
if (!isDesktop()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (!path) {
|
if (!path) {
|
||||||
console.error('path is undefined cannot call desktop showInFolder')
|
console.error('path is undefined cannot call desktop showInFolder')
|
||||||
return
|
return
|
||||||
@ -64,14 +54,20 @@ export async function showInFolder(path: string | undefined): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function initializeProjectDirectory(
|
export async function initializeProjectDirectory(
|
||||||
settings: Configuration
|
config: Configuration
|
||||||
): Promise<string | undefined> {
|
): Promise<string | undefined> {
|
||||||
if (!isDesktop()) {
|
const projectDir = config.settings.project.directory
|
||||||
return undefined
|
try {
|
||||||
|
await window.electron.exists(projectDir)
|
||||||
|
} catch (e) {
|
||||||
|
if (e === 'ENOENT') {
|
||||||
|
window.electron.mkdir(projectDir, { recursive: true }, (e) => {
|
||||||
|
console.log(e)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return window.electron.ipcRenderer.invoke('initialize_project_directory', {
|
|
||||||
configuration: settings,
|
return projectDir
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createNewProjectDirectory(
|
export async function createNewProjectDirectory(
|
||||||
@ -92,10 +88,13 @@ export async function createNewProjectDirectory(
|
|||||||
export async function listProjects(
|
export async function listProjects(
|
||||||
configuration?: Configuration
|
configuration?: Configuration
|
||||||
): Promise<Project[]> {
|
): Promise<Project[]> {
|
||||||
if (!configuration) {
|
const projectDir = await initializeProjectDirectory(configuration)
|
||||||
configuration = await readAppSettingsFile()
|
const projects = []
|
||||||
|
const entries = await window.electron.readdir(projectDir)
|
||||||
|
for (let entry of entries) {
|
||||||
|
// Ignore directories
|
||||||
|
console.log(entry)
|
||||||
}
|
}
|
||||||
return window.electron.ipcRenderer.invoke('list_projects', { configuration })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getProjectInfo(
|
export async function getProjectInfo(
|
||||||
@ -111,10 +110,6 @@ export async function getProjectInfo(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function login(host: string): Promise<string> {
|
|
||||||
return window.electron.ipcRenderer.invoke('login', { host })
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function parseProjectRoute(
|
export async function parseProjectRoute(
|
||||||
configuration: Configuration,
|
configuration: Configuration,
|
||||||
route: string
|
route: string
|
||||||
@ -125,40 +120,10 @@ export async function parseProjectRoute(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getUser(
|
|
||||||
token: string | undefined,
|
|
||||||
host: string
|
|
||||||
): Promise<Models['User_type'] | Record<'error_code', unknown> | void> {
|
|
||||||
if (!token) {
|
|
||||||
console.error('token is undefined cannot call desktop getUser')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return window.electron.ipcRenderer.invoke>(
|
|
||||||
'get_user',
|
|
||||||
{
|
|
||||||
token: token,
|
|
||||||
hostname: host,
|
|
||||||
}
|
|
||||||
).catch((err) => console.error('error from Tauri getUser', err))
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function readDirRecursive(path: string): Promise<FileEntry[]> {
|
export async function readDirRecursive(path: string): Promise<FileEntry[]> {
|
||||||
return window.electron.ipcRenderer.invoke('read_dir_recursive', { path })
|
return window.electron.ipcRenderer.invoke('read_dir_recursive', { path })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the contents of the app settings.
|
|
||||||
export async function readAppSettingsFile(): Promise<Configuration> {
|
|
||||||
return window.electron.ipcRenderer.invoke('read_app_settings_file')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the contents of the app settings.
|
|
||||||
export async function writeAppSettingsFile(
|
|
||||||
settings: Configuration
|
|
||||||
): Promise<void> {
|
|
||||||
return window.electron.ipcRenderer.invoke('write_app_settings_file', { configuration: settings })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read project settings file.
|
// Read project settings file.
|
||||||
export async function readProjectSettingsFile(
|
export async function readProjectSettingsFile(
|
||||||
projectPath: string
|
projectPath: string
|
||||||
|
@ -1,19 +1,25 @@
|
|||||||
import { contextBridge } from 'electron'
|
import { ipcRenderer, contextBridge } from 'electron'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import fs from 'node:fs'
|
import fs from 'node:fs/promises'
|
||||||
|
import packageJson from '../../package.json'
|
||||||
|
|
||||||
// All these functions call into lib/electron since many require filesystem
|
const readFile = (path: string) => fs.readFile(path, 'utf-8')
|
||||||
// access, and the second half is the original tauri code also stored app
|
const readdir = (path: string) => fs.readdir(path, 'utf-8')
|
||||||
// state on the "desktop" side.
|
const exists = (path: string) =>
|
||||||
|
new Promise((resolve, reject) =>
|
||||||
|
fs.stat(path, (err, data) => {
|
||||||
|
if (err) return reject(err.code)
|
||||||
|
return resolve(data)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
const getPath = async (name: string) => ipcRenderer.invoke('app.getPath', name)
|
||||||
|
|
||||||
const DEFAULT_HOST = "https://api.zoo.dev"
|
contextBridge.exposeInMainWorld('electron', {
|
||||||
const SETTINGS_FILE_NAME = "settings.toml"
|
readFile,
|
||||||
const PROJECT_SETTINGS_FILE_NAME = "project.toml"
|
readdir,
|
||||||
const PROJECT_FOLDER = "zoo-modeling-app-projects"
|
path,
|
||||||
|
exists,
|
||||||
contextBridge.exposeInMainWorld("fs", {
|
mkdir: fs.mkdir,
|
||||||
readFile(p: string) { return fs.readFile(p, 'utf-8') },
|
getPath,
|
||||||
readdir(p: string) { return fs.readdir(p, 'utf-8') },
|
packageJson,
|
||||||
join() { return path.join(...arguments) },
|
|
||||||
exists(p: string) { fs.exists(p) },
|
|
||||||
})
|
})
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// https://github.com/electron/electron/issues/2288#issuecomment-337858978
|
// https://github.com/electron/electron/issues/2288#issuecomment-337858978
|
||||||
// Thank you
|
// Thank you
|
||||||
export function isDesktop(): boolean {
|
export function isDesktop(): boolean {
|
||||||
return navigator.userAgent.toLowerCase().indexOf("electron") > -1;
|
return navigator.userAgent.toLowerCase().indexOf('electron') > -1
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,8 @@ export function createSettings() {
|
|||||||
description: 'The directory to save and load projects from',
|
description: 'The directory to save and load projects from',
|
||||||
hideOnLevel: 'project',
|
hideOnLevel: 'project',
|
||||||
hideOnPlatform: 'web',
|
hideOnPlatform: 'web',
|
||||||
validate: (v) => typeof v === 'string' && (v.length > 0 || !isDesktop()),
|
validate: (v) =>
|
||||||
|
typeof v === 'string' && (v.length > 0 || !isDesktop()),
|
||||||
Component: ({ value, updateValue }) => {
|
Component: ({ value, updateValue }) => {
|
||||||
const inputRef = useRef<HTMLInputElement>(null)
|
const inputRef = useRef<HTMLInputElement>(null)
|
||||||
return (
|
return (
|
||||||
|
@ -161,10 +161,8 @@ export async function loadAndValidateSettings(
|
|||||||
const settings = createSettings()
|
const settings = createSettings()
|
||||||
const onDesktop = isDesktop()
|
const onDesktop = isDesktop()
|
||||||
|
|
||||||
if (!onDesktop) {
|
// Make sure we have wasm initialized.
|
||||||
// Make sure we have wasm initialized.
|
await initPromise
|
||||||
await initPromise
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the app settings from the file system or localStorage.
|
// Load the app settings from the file system or localStorage.
|
||||||
const appSettings = onDesktop
|
const appSettings = onDesktop
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
import toast from 'react-hot-toast'
|
let toast = undefined
|
||||||
|
|
||||||
|
try {
|
||||||
|
global
|
||||||
|
} catch (e) {
|
||||||
|
import('react-hot-toast').then((_toast) => {
|
||||||
|
toast = _toast
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type ExcludeErr<T> = Exclude<T, Error>
|
type ExcludeErr<T> = Exclude<T, Error>
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import { Models } from '@kittycad/lib'
|
|||||||
import withBaseURL from '../lib/withBaseURL'
|
import withBaseURL from '../lib/withBaseURL'
|
||||||
import { isDesktop } from 'lib/isDesktop'
|
import { isDesktop } from 'lib/isDesktop'
|
||||||
import { VITE_KC_API_BASE_URL, VITE_KC_DEV_TOKEN } from 'env'
|
import { VITE_KC_API_BASE_URL, VITE_KC_DEV_TOKEN } from 'env'
|
||||||
import { getUser as getUserTauri } from 'lib/desktop'
|
import { getUser as getUserDesktop } from 'lib/desktop'
|
||||||
|
|
||||||
const SKIP_AUTH =
|
const SKIP_AUTH =
|
||||||
import.meta.env.VITE_KC_SKIP_AUTH === 'true' && import.meta.env.DEV
|
import.meta.env.VITE_KC_SKIP_AUTH === 'true' && import.meta.env.DEV
|
||||||
@ -146,7 +146,7 @@ async function getUser(context: UserContext) {
|
|||||||
})
|
})
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.catch((err) => console.error('error from Browser getUser', err))
|
.catch((err) => console.error('error from Browser getUser', err))
|
||||||
: getUserTauri(context.token, VITE_KC_API_BASE_URL)
|
: getUserDesktop(context.token, VITE_KC_API_BASE_URL)
|
||||||
|
|
||||||
const user = await userPromise
|
const user = await userPromise
|
||||||
|
|
||||||
|
10
src/main.ts
10
src/main.ts
@ -1,7 +1,8 @@
|
|||||||
// Some of the following was taken from bits and pieces of the vite-typescript
|
// Some of the following was taken from bits and pieces of the vite-typescript
|
||||||
// template that ElectronJS provides.
|
// template that ElectronJS provides.
|
||||||
|
|
||||||
import { app, BrowserWindow } from 'electron'
|
import { Configuration } from 'wasm-lib/kcl/bindings/Configuration'
|
||||||
|
import { app, BrowserWindow, ipcMain } from 'electron'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
|
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
|
||||||
@ -17,8 +18,8 @@ const createWindow = () => {
|
|||||||
nodeIntegration: false, // do not give the application implicit system access
|
nodeIntegration: false, // do not give the application implicit system access
|
||||||
contextIsolation: true, // expose system functions in preload
|
contextIsolation: true, // expose system functions in preload
|
||||||
sandbox: false, // expose nodejs in preload
|
sandbox: false, // expose nodejs in preload
|
||||||
preload: path.join(__dirname, "./preload.js")
|
preload: path.join(__dirname, './preload.js'),
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// and load the index.html of the app.
|
// and load the index.html of the app.
|
||||||
@ -48,3 +49,6 @@ app.on('window-all-closed', () => {
|
|||||||
// Some APIs can only be used after this event occurs.
|
// Some APIs can only be used after this event occurs.
|
||||||
app.on('ready', createWindow)
|
app.on('ready', createWindow)
|
||||||
|
|
||||||
|
ipcMain.handle('app.getPath', (event, data) => {
|
||||||
|
return app.getPath(data)
|
||||||
|
})
|
||||||
|
13
src/wasm-lib/Cargo.lock
generated
13
src/wasm-lib/Cargo.lock
generated
@ -2589,6 +2589,17 @@ dependencies = [
|
|||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde-wasm-bindgen"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"serde",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_bytes"
|
name = "serde_bytes"
|
||||||
version = "0.11.14"
|
version = "0.11.14"
|
||||||
@ -3625,6 +3636,8 @@ dependencies = [
|
|||||||
"kittycad",
|
"kittycad",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"serde",
|
||||||
|
"serde-wasm-bindgen",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml",
|
"toml",
|
||||||
|
@ -16,6 +16,8 @@ gloo-utils = "0.2.0"
|
|||||||
kcl-lib = { path = "kcl" }
|
kcl-lib = { path = "kcl" }
|
||||||
kittycad.workspace = true
|
kittycad.workspace = true
|
||||||
serde_json = "1.0.122"
|
serde_json = "1.0.122"
|
||||||
|
serde_json = "1.0.122"
|
||||||
|
serde-wasm-bindgen = "0.6.5"
|
||||||
tokio = { version = "1.39.2", features = ["sync"] }
|
tokio = { version = "1.39.2", features = ["sync"] }
|
||||||
toml = "0.8.19"
|
toml = "0.8.19"
|
||||||
uuid = { version = "1.10.0", features = ["v4", "js", "serde"] }
|
uuid = { version = "1.10.0", features = ["v4", "js", "serde"] }
|
||||||
|
@ -19,7 +19,7 @@ const DEFAULT_PROJECT_NAME_TEMPLATE: &str = "project-$nnn";
|
|||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct Configuration {
|
pub struct Configuration {
|
||||||
/// The settings for the modeling app.
|
/// The settings for the modeling app.
|
||||||
#[serde(default, skip_serializing_if = "is_default")]
|
#[serde(default)]
|
||||||
#[validate(nested)]
|
#[validate(nested)]
|
||||||
pub settings: Settings,
|
pub settings: Settings,
|
||||||
}
|
}
|
||||||
@ -183,23 +183,23 @@ impl Configuration {
|
|||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
/// The settings for the modeling app.
|
/// The settings for the modeling app.
|
||||||
#[serde(default, skip_serializing_if = "is_default")]
|
#[serde(default)]
|
||||||
#[validate(nested)]
|
#[validate(nested)]
|
||||||
pub app: AppSettings,
|
pub app: AppSettings,
|
||||||
/// Settings that affect the behavior while modeling.
|
/// Settings that affect the behavior while modeling.
|
||||||
#[serde(default, skip_serializing_if = "is_default")]
|
#[serde(default)]
|
||||||
#[validate(nested)]
|
#[validate(nested)]
|
||||||
pub modeling: ModelingSettings,
|
pub modeling: ModelingSettings,
|
||||||
/// Settings that affect the behavior of the KCL text editor.
|
/// Settings that affect the behavior of the KCL text editor.
|
||||||
#[serde(default, alias = "textEditor", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "textEditor")]
|
||||||
#[validate(nested)]
|
#[validate(nested)]
|
||||||
pub text_editor: TextEditorSettings,
|
pub text_editor: TextEditorSettings,
|
||||||
/// Settings that affect the behavior of project management.
|
/// Settings that affect the behavior of project management.
|
||||||
#[serde(default, alias = "projects", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "projects")]
|
||||||
#[validate(nested)]
|
#[validate(nested)]
|
||||||
pub project: ProjectSettings,
|
pub project: ProjectSettings,
|
||||||
/// Settings that affect the behavior of the command bar.
|
/// Settings that affect the behavior of the command bar.
|
||||||
#[serde(default, alias = "commandBar", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "commandBar")]
|
||||||
#[validate(nested)]
|
#[validate(nested)]
|
||||||
pub command_bar: CommandBarSettings,
|
pub command_bar: CommandBarSettings,
|
||||||
}
|
}
|
||||||
@ -212,11 +212,11 @@ pub struct Settings {
|
|||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct AppSettings {
|
pub struct AppSettings {
|
||||||
/// The settings for the appearance of the app.
|
/// The settings for the appearance of the app.
|
||||||
#[serde(default, skip_serializing_if = "is_default")]
|
#[serde(default)]
|
||||||
#[validate(nested)]
|
#[validate(nested)]
|
||||||
pub appearance: AppearanceSettings,
|
pub appearance: AppearanceSettings,
|
||||||
/// The onboarding status of the app.
|
/// The onboarding status of the app.
|
||||||
#[serde(default, alias = "onboardingStatus", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "onboardingStatus")]
|
||||||
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")]
|
||||||
@ -232,10 +232,10 @@ pub struct AppSettings {
|
|||||||
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.
|
||||||
#[serde(default, alias = "dismissWebBanner", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "dismissWebBanner")]
|
||||||
pub dismiss_web_banner: bool,
|
pub dismiss_web_banner: bool,
|
||||||
/// When the user is idle, and this is true, the stream will be torn down.
|
/// When the user is idle, and this is true, the stream will be torn down.
|
||||||
#[serde(default, alias = "streamIdleMode", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "streamIdleMode")]
|
||||||
stream_idle_mode: bool,
|
stream_idle_mode: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,10 +275,10 @@ impl From<FloatOrInt> for AppColor {
|
|||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct AppearanceSettings {
|
pub struct AppearanceSettings {
|
||||||
/// The overall theme of the app.
|
/// The overall theme of the app.
|
||||||
#[serde(default, skip_serializing_if = "is_default")]
|
#[serde(default)]
|
||||||
pub theme: AppTheme,
|
pub theme: 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 = "is_default")]
|
#[serde(default)]
|
||||||
#[validate(nested)]
|
#[validate(nested)]
|
||||||
pub color: AppColor,
|
pub color: AppColor,
|
||||||
}
|
}
|
||||||
@ -367,23 +367,23 @@ impl From<AppTheme> for kittycad::types::Color {
|
|||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
pub struct ModelingSettings {
|
pub struct ModelingSettings {
|
||||||
/// The default unit to use in modeling dimensions.
|
/// The default unit to use in modeling dimensions.
|
||||||
#[serde(default, alias = "defaultUnit", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "defaultUnit")]
|
||||||
pub base_unit: UnitLength,
|
pub base_unit: UnitLength,
|
||||||
/// The controls for how to navigate the 3D view.
|
/// The controls for how to navigate the 3D view.
|
||||||
#[serde(default, alias = "mouseControls", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "mouseControls")]
|
||||||
pub mouse_controls: MouseControlType,
|
pub mouse_controls: MouseControlType,
|
||||||
/// Highlight edges of 3D objects?
|
/// Highlight edges of 3D objects?
|
||||||
#[serde(default, alias = "highlightEdges", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "highlightEdges")]
|
||||||
pub highlight_edges: DefaultTrue,
|
pub highlight_edges: DefaultTrue,
|
||||||
/// Whether to show the debug panel, which lets you see various states
|
/// Whether to show the debug panel, which lets you see various states
|
||||||
/// of the app to aid in development.
|
/// of the app to aid in development.
|
||||||
#[serde(default, alias = "showDebugPanel", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "showDebugPanel")]
|
||||||
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)]
|
||||||
pub enable_ssao: DefaultTrue,
|
pub enable_ssao: DefaultTrue,
|
||||||
/// Whether or not to show a scale grid in the 3D modeling view
|
/// Whether or not to show a scale grid in the 3D modeling view
|
||||||
#[serde(default, alias = "showScaleGrid", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "showScaleGrid")]
|
||||||
pub show_scale_grid: bool,
|
pub show_scale_grid: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,10 +492,10 @@ pub enum MouseControlType {
|
|||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
pub struct TextEditorSettings {
|
pub struct TextEditorSettings {
|
||||||
/// Whether to wrap text in the editor or overflow with scroll.
|
/// Whether to wrap text in the editor or overflow with scroll.
|
||||||
#[serde(default, alias = "textWrapping", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "textWrapping")]
|
||||||
pub text_wrapping: DefaultTrue,
|
pub text_wrapping: DefaultTrue,
|
||||||
/// Whether to make the cursor blink in the editor.
|
/// Whether to make the cursor blink in the editor.
|
||||||
#[serde(default, alias = "blinkingCursor", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "blinkingCursor")]
|
||||||
pub blinking_cursor: DefaultTrue,
|
pub blinking_cursor: DefaultTrue,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,10 +505,10 @@ pub struct TextEditorSettings {
|
|||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
pub struct ProjectSettings {
|
pub struct ProjectSettings {
|
||||||
/// The directory to save and load projects from.
|
/// The directory to save and load projects from.
|
||||||
#[serde(default, skip_serializing_if = "is_default")]
|
#[serde(default)]
|
||||||
pub directory: std::path::PathBuf,
|
pub directory: std::path::PathBuf,
|
||||||
/// The default project name to use when creating a new project.
|
/// The default project name to use when creating a new project.
|
||||||
#[serde(default, alias = "defaultProjectName", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "defaultProjectName")]
|
||||||
pub default_project_name: ProjectNameTemplate,
|
pub default_project_name: ProjectNameTemplate,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,7 +541,7 @@ impl From<String> for ProjectNameTemplate {
|
|||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
pub struct CommandBarSettings {
|
pub struct CommandBarSettings {
|
||||||
/// Whether to include settings in the command bar.
|
/// Whether to include settings in the command bar.
|
||||||
#[serde(default, alias = "includeSettings", skip_serializing_if = "is_default")]
|
#[serde(default, alias = "includeSettings")]
|
||||||
pub include_settings: DefaultTrue,
|
pub include_settings: DefaultTrue,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,8 +6,9 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use futures::stream::TryStreamExt;
|
use futures::stream::TryStreamExt;
|
||||||
use gloo_utils::format::JsValueSerdeExt;
|
use kcl_lib::{coredump::CoreDump, engine::EngineManager, executor::ExecutorSettings, lint::checks};
|
||||||
use kcl_lib::{coredump::CoreDump, engine::EngineManager, executor::ExecutorSettings};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_wasm_bindgen;
|
||||||
use tower_lsp::{LspService, Server};
|
use tower_lsp::{LspService, Server};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
@ -54,14 +55,13 @@ pub async fn execute_wasm(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let memory = ctx.run(&program, Some(memory)).await.map_err(String::from)?;
|
let memory = ctx.run(&program, Some(memory)).await.map_err(String::from)?;
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
|
||||||
// gloo-serialize crate instead.
|
serde_wasm_bindgen::to_value(&memory).map_err(|e| e.to_string())
|
||||||
JsValue::from_serde(&memory).map_err(|e| e.to_string())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// wasm_bindgen wrapper for execute
|
// wasm_bindgen wrapper for execute
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub async fn kcl_lint(program_str: &str) -> Result<JsValue, String> {
|
pub async fn kcl_lint(program_str: &str) -> Result<JsValue, JsValue> {
|
||||||
console_error_panic_hook::set_once();
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
let program: kcl_lib::ast::types::Program = serde_json::from_str(program_str).map_err(|e| e.to_string())?;
|
let program: kcl_lib::ast::types::Program = serde_json::from_str(program_str).map_err(|e| e.to_string())?;
|
||||||
@ -70,7 +70,7 @@ pub async fn kcl_lint(program_str: &str) -> Result<JsValue, String> {
|
|||||||
findings.push(discovered_finding);
|
findings.push(discovered_finding);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(JsValue::from_serde(&findings).map_err(|e| e.to_string())?)
|
Ok(serde_wasm_bindgen::to_value(&findings)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
// wasm_bindgen wrapper for creating default planes
|
// wasm_bindgen wrapper for creating default planes
|
||||||
@ -89,9 +89,7 @@ pub async fn make_default_planes(
|
|||||||
.await
|
.await
|
||||||
.map_err(String::from)?;
|
.map_err(String::from)?;
|
||||||
|
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
serde_wasm_bindgen::to_value(&default_planes).map_err(|e| e.to_string())
|
||||||
// gloo-serialize crate instead.
|
|
||||||
JsValue::from_serde(&default_planes).map_err(|e| e.to_string())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// wasm_bindgen wrapper for modifying the grid
|
// wasm_bindgen wrapper for modifying the grid
|
||||||
@ -143,9 +141,7 @@ pub async fn modify_ast_for_sketch_wasm(
|
|||||||
.await
|
.await
|
||||||
.map_err(String::from)?;
|
.map_err(String::from)?;
|
||||||
|
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
serde_wasm_bindgen::to_value(&program).map_err(|e| e.to_string())
|
||||||
// gloo-serialize crate instead.
|
|
||||||
JsValue::from_serde(&program).map_err(|e| e.to_string())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
@ -161,7 +157,7 @@ pub fn deserialize_files(data: &[u8]) -> Result<JsValue, JsError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(kittycad::types::OkWebSocketResponseData::Export { files }) = ws_resp.resp {
|
if let Some(kittycad::types::OkWebSocketResponseData::Export { files }) = ws_resp.resp {
|
||||||
return Ok(JsValue::from_serde(&files)?);
|
return Ok(serde_wasm_bindgen::to_value(&files)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(JsError::new(&format!("Invalid response type, got: {:?}", ws_resp)))
|
Err(JsError::new(&format!("Invalid response type, got: {:?}", ws_resp)))
|
||||||
@ -174,7 +170,7 @@ pub fn lexer_wasm(js: &str) -> Result<JsValue, JsError> {
|
|||||||
console_error_panic_hook::set_once();
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
let tokens = kcl_lib::token::lexer(js).map_err(JsError::from)?;
|
let tokens = kcl_lib::token::lexer(js).map_err(JsError::from)?;
|
||||||
Ok(JsValue::from_serde(&tokens)?)
|
Ok(serde_wasm_bindgen::to_value(&tokens)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
@ -184,9 +180,7 @@ pub fn parse_wasm(js: &str) -> Result<JsValue, String> {
|
|||||||
let tokens = kcl_lib::token::lexer(js).map_err(String::from)?;
|
let tokens = kcl_lib::token::lexer(js).map_err(String::from)?;
|
||||||
let parser = kcl_lib::parser::Parser::new(tokens);
|
let parser = kcl_lib::parser::Parser::new(tokens);
|
||||||
let program = parser.ast().map_err(String::from)?;
|
let program = parser.ast().map_err(String::from)?;
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
serde_wasm_bindgen::to_value(&program).map_err(|e| e.to_string())
|
||||||
// gloo-serialize crate instead.
|
|
||||||
JsValue::from_serde(&program).map_err(|e| e.to_string())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// wasm_bindgen wrapper for recast
|
// wasm_bindgen wrapper for recast
|
||||||
@ -200,7 +194,7 @@ pub fn recast_wasm(json_str: &str) -> Result<JsValue, JsError> {
|
|||||||
|
|
||||||
// Use the default options until we integrate into the UI the ability to change them.
|
// Use the default options until we integrate into the UI the ability to change them.
|
||||||
let result = program.recast(&Default::default(), 0);
|
let result = program.recast(&Default::default(), 0);
|
||||||
Ok(JsValue::from_serde(&result)?)
|
Ok(serde_wasm_bindgen::to_value(&result)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
@ -481,9 +475,7 @@ pub fn program_memory_init() -> Result<JsValue, String> {
|
|||||||
|
|
||||||
let memory = kcl_lib::executor::ProgramMemory::default();
|
let memory = kcl_lib::executor::ProgramMemory::default();
|
||||||
|
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
serde_wasm_bindgen::to_value(&memory).map_err(|e| e.to_string())
|
||||||
// gloo-serialize crate instead.
|
|
||||||
JsValue::from_serde(&memory).map_err(|e| e.to_string())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a coredump.
|
/// Get a coredump.
|
||||||
@ -494,9 +486,7 @@ pub async fn coredump(core_dump_manager: kcl_lib::coredump::wasm::CoreDumpManage
|
|||||||
let core_dumper = kcl_lib::coredump::wasm::CoreDumper::new(core_dump_manager);
|
let core_dumper = kcl_lib::coredump::wasm::CoreDumper::new(core_dump_manager);
|
||||||
let dump = core_dumper.dump().await.map_err(|e| e.to_string())?;
|
let dump = core_dumper.dump().await.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
serde_wasm_bindgen::to_value(&dump).map_err(|e| e.to_string())
|
||||||
// gloo-serialize crate instead.
|
|
||||||
JsValue::from_serde(&dump).map_err(|e| e.to_string())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the default app settings.
|
/// Get the default app settings.
|
||||||
@ -505,10 +495,9 @@ pub fn default_app_settings() -> Result<JsValue, String> {
|
|||||||
console_error_panic_hook::set_once();
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
let settings = kcl_lib::settings::types::Configuration::default();
|
let settings = kcl_lib::settings::types::Configuration::default();
|
||||||
|
web_sys::console::log(&js_sys::Array::of1(&JsValue::from_str(&format!("{:?}", settings))));
|
||||||
|
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
serde_wasm_bindgen::to_value(&settings).map_err(|e| e.to_string())
|
||||||
// gloo-serialize crate instead.
|
|
||||||
JsValue::from_serde(&settings).map_err(|e| e.to_string())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse the app settings.
|
/// Parse the app settings.
|
||||||
@ -519,9 +508,7 @@ pub fn parse_app_settings(toml_str: &str) -> Result<JsValue, String> {
|
|||||||
let settings = kcl_lib::settings::types::Configuration::backwards_compatible_toml_parse(&toml_str)
|
let settings = kcl_lib::settings::types::Configuration::backwards_compatible_toml_parse(&toml_str)
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
serde_wasm_bindgen::to_value(&settings).map_err(|e| e.to_string())
|
||||||
// gloo-serialize crate instead.
|
|
||||||
JsValue::from_serde(&settings).map_err(|e| e.to_string())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the default project settings.
|
/// Get the default project settings.
|
||||||
@ -531,12 +518,10 @@ pub fn default_project_settings() -> Result<JsValue, String> {
|
|||||||
|
|
||||||
let settings = kcl_lib::settings::types::project::ProjectConfiguration::default();
|
let settings = kcl_lib::settings::types::project::ProjectConfiguration::default();
|
||||||
|
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
serde_wasm_bindgen::to_value(&settings).map_err(|e| e.to_string())
|
||||||
// gloo-serialize crate instead.
|
|
||||||
JsValue::from_serde(&settings).map_err(|e| e.to_string())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse the project settings.
|
/// Parse (deserialize) the project settings.
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn parse_project_settings(toml_str: &str) -> Result<JsValue, String> {
|
pub fn parse_project_settings(toml_str: &str) -> Result<JsValue, String> {
|
||||||
console_error_panic_hook::set_once();
|
console_error_panic_hook::set_once();
|
||||||
@ -544,9 +529,17 @@ pub fn parse_project_settings(toml_str: &str) -> Result<JsValue, String> {
|
|||||||
let settings = kcl_lib::settings::types::project::ProjectConfiguration::backwards_compatible_toml_parse(&toml_str)
|
let settings = kcl_lib::settings::types::project::ProjectConfiguration::backwards_compatible_toml_parse(&toml_str)
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
serde_wasm_bindgen::to_value(&settings).map_err(|e| e.to_string())
|
||||||
// gloo-serialize crate instead.
|
}
|
||||||
JsValue::from_serde(&settings).map_err(|e| e.to_string())
|
|
||||||
|
/// Serialize the project settings.
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn serialize_project_settings(val: JsValue) -> Result<JsValue, String> {
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
|
let config: kcl_lib::settings::types::Configuration = serde_wasm_bindgen::from_value(val).map_err(|e| e.to_string())?;
|
||||||
|
let toml_str = toml::to_string_pretty(&config).map_err(|e| e.to_string())?;
|
||||||
|
serde_wasm_bindgen::to_value(&toml_str).map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse the project route.
|
/// Parse the project route.
|
||||||
@ -560,7 +553,5 @@ pub fn parse_project_route(configuration: &str, route: &str) -> Result<JsValue,
|
|||||||
let route =
|
let route =
|
||||||
kcl_lib::settings::types::file::ProjectRoute::from_route(&configuration, route).map_err(|e| e.to_string())?;
|
kcl_lib::settings::types::file::ProjectRoute::from_route(&configuration, route).map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// The serde-wasm-bindgen does not work here because of weird HashMap issues so we use the
|
serde_wasm_bindgen::to_value(&route).map_err(|e| e.to_string())
|
||||||
// gloo-serialize crate instead.
|
|
||||||
JsValue::from_serde(&route).map_err(|e| e.to_string())
|
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,42 @@
|
|||||||
import type { ConfigEnv, UserConfig } from 'vite'
|
import type { ConfigEnv, UserConfig } from 'vite'
|
||||||
import { defineConfig, mergeConfig } from 'vite'
|
import { defineConfig, mergeConfig } from 'vite'
|
||||||
import { getBuildConfig, external, pluginHotRestart } from './vite.base.config'
|
import { configDefaults } from 'vitest/config'
|
||||||
import viteTsconfigPaths from 'vite-tsconfig-paths'
|
import viteTsconfigPaths from 'vite-tsconfig-paths'
|
||||||
|
import {
|
||||||
|
getBuildConfig,
|
||||||
|
getBuildDefine,
|
||||||
|
external,
|
||||||
|
pluginHotRestart,
|
||||||
|
} from './vite.base.config'
|
||||||
|
|
||||||
// https://vitejs.dev/config
|
// https://vitejs.dev/config
|
||||||
export default defineConfig((env) => {
|
export default defineConfig((env) => {
|
||||||
const forgeEnv = env as ConfigEnv<'build'>
|
const forgeEnv = env as ConfigEnv<'build'>
|
||||||
const { forgeConfigSelf } = forgeEnv
|
const define = getBuildDefine(forgeEnv)
|
||||||
|
const { root, mode, forgeConfigSelf } = forgeEnv
|
||||||
const config: UserConfig = {
|
const config: UserConfig = {
|
||||||
|
root,
|
||||||
|
mode,
|
||||||
|
base: './',
|
||||||
build: {
|
build: {
|
||||||
|
lib: {
|
||||||
|
entry: forgeConfigSelf.entry!,
|
||||||
|
fileName: () => '[name].js',
|
||||||
|
formats: ['cjs'],
|
||||||
|
},
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
external,
|
external,
|
||||||
// Preload scripts may contain Web assets, so use the `build.rollupOptions.input` instead `build.lib.entry`.
|
|
||||||
input: forgeConfigSelf.entry!,
|
|
||||||
output: {
|
|
||||||
format: 'cjs',
|
|
||||||
// It should not be split chunks.
|
|
||||||
inlineDynamicImports: true,
|
|
||||||
entryFileNames: '[name].js',
|
|
||||||
chunkFileNames: '[name].js',
|
|
||||||
assetFileNames: '[name].[ext]',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [pluginHotRestart('reload'), viteTsconfigPaths()],
|
resolve: {
|
||||||
|
// Load the Node.js entry.
|
||||||
|
mainFields: ['module', 'jsnext:main', 'jsnext'],
|
||||||
|
},
|
||||||
|
plugins: [pluginHotRestart('restart'), viteTsconfigPaths()],
|
||||||
|
worker: {
|
||||||
|
plugins: () => [viteTsconfigPaths()],
|
||||||
|
},
|
||||||
|
define,
|
||||||
}
|
}
|
||||||
|
|
||||||
return mergeConfig(getBuildConfig(forgeEnv), config)
|
return mergeConfig(getBuildConfig(forgeEnv), config)
|
||||||
|
Reference in New Issue
Block a user