2023-09-29 11:11:01 -07:00
|
|
|
import init, {
|
|
|
|
parse_wasm,
|
|
|
|
recast_wasm,
|
|
|
|
execute_wasm,
|
2024-06-26 00:04:52 -04:00
|
|
|
kcl_lint,
|
2023-09-29 11:11:01 -07:00
|
|
|
lexer_wasm,
|
|
|
|
modify_ast_for_sketch_wasm,
|
2024-02-11 12:59:00 +11:00
|
|
|
is_points_ccw,
|
|
|
|
get_tangential_arc_to_info,
|
2024-02-11 18:26:09 -08:00
|
|
|
program_memory_init,
|
2024-04-15 17:18:32 -07:00
|
|
|
make_default_planes,
|
2024-06-30 19:21:24 -07:00
|
|
|
modify_grid,
|
2024-04-09 18:05:36 -07:00
|
|
|
coredump,
|
2024-04-16 21:36:19 -07:00
|
|
|
toml_stringify,
|
2024-04-25 00:13:09 -07:00
|
|
|
default_app_settings,
|
|
|
|
parse_app_settings,
|
|
|
|
parse_project_settings,
|
|
|
|
default_project_settings,
|
2024-04-25 11:55:11 -07:00
|
|
|
parse_project_route,
|
2023-09-29 11:11:01 -07:00
|
|
|
} from '../wasm-lib/pkg/wasm_lib'
|
|
|
|
import { KCLError } from './errors'
|
|
|
|
import { KclError as RustKclError } from '../wasm-lib/kcl/bindings/KclError'
|
2023-10-14 03:47:46 +11:00
|
|
|
import { EngineCommandManager } from './std/engineConnection'
|
2023-09-29 11:11:01 -07:00
|
|
|
import { ProgramReturn } from '../wasm-lib/kcl/bindings/ProgramReturn'
|
2024-06-26 00:04:52 -04:00
|
|
|
import { Discovered } from '../wasm-lib/kcl/bindings/Discovered'
|
2023-09-29 11:11:01 -07:00
|
|
|
import { MemoryItem } from '../wasm-lib/kcl/bindings/MemoryItem'
|
|
|
|
import type { Program } from '../wasm-lib/kcl/bindings/Program'
|
|
|
|
import type { Token } from '../wasm-lib/kcl/bindings/Token'
|
2024-02-11 12:59:00 +11:00
|
|
|
import { Coords2d } from './std/sketch'
|
2024-02-12 12:18:37 -08:00
|
|
|
import { fileSystemManager } from 'lang/std/fileSystemManager'
|
2024-06-20 16:36:28 -07:00
|
|
|
import { CoreDumpInfo } from 'wasm-lib/kcl/bindings/CoreDumpInfo'
|
2024-04-09 18:05:36 -07:00
|
|
|
import { CoreDumpManager } from 'lib/coredump'
|
|
|
|
import openWindow from 'lib/openWindow'
|
2024-04-15 17:18:32 -07:00
|
|
|
import { DefaultPlanes } from 'wasm-lib/kcl/bindings/DefaultPlanes'
|
2024-04-19 14:24:40 -07:00
|
|
|
import { TEST } from 'env'
|
2024-04-25 00:13:09 -07:00
|
|
|
import { Configuration } from 'wasm-lib/kcl/bindings/Configuration'
|
|
|
|
import { ProjectConfiguration } from 'wasm-lib/kcl/bindings/ProjectConfiguration'
|
2024-04-25 11:55:11 -07:00
|
|
|
import { ProjectRoute } from 'wasm-lib/kcl/bindings/ProjectRoute'
|
2024-06-24 11:45:40 -04:00
|
|
|
import { err } from 'lib/trap'
|
2023-09-29 11:11:01 -07:00
|
|
|
|
|
|
|
export type { Program } from '../wasm-lib/kcl/bindings/Program'
|
|
|
|
export type { Value } from '../wasm-lib/kcl/bindings/Value'
|
|
|
|
export type { ObjectExpression } from '../wasm-lib/kcl/bindings/ObjectExpression'
|
|
|
|
export type { MemberExpression } from '../wasm-lib/kcl/bindings/MemberExpression'
|
|
|
|
export type { PipeExpression } from '../wasm-lib/kcl/bindings/PipeExpression'
|
|
|
|
export type { VariableDeclaration } from '../wasm-lib/kcl/bindings/VariableDeclaration'
|
2023-11-20 11:19:08 -06:00
|
|
|
export type { Parameter } from '../wasm-lib/kcl/bindings/Parameter'
|
2023-09-29 11:11:01 -07:00
|
|
|
export type { PipeSubstitution } from '../wasm-lib/kcl/bindings/PipeSubstitution'
|
|
|
|
export type { Identifier } from '../wasm-lib/kcl/bindings/Identifier'
|
|
|
|
export type { UnaryExpression } from '../wasm-lib/kcl/bindings/UnaryExpression'
|
|
|
|
export type { BinaryExpression } from '../wasm-lib/kcl/bindings/BinaryExpression'
|
|
|
|
export type { ReturnStatement } from '../wasm-lib/kcl/bindings/ReturnStatement'
|
|
|
|
export type { ExpressionStatement } from '../wasm-lib/kcl/bindings/ExpressionStatement'
|
|
|
|
export type { CallExpression } from '../wasm-lib/kcl/bindings/CallExpression'
|
|
|
|
export type { VariableDeclarator } from '../wasm-lib/kcl/bindings/VariableDeclarator'
|
|
|
|
export type { BinaryPart } from '../wasm-lib/kcl/bindings/BinaryPart'
|
|
|
|
export type { Literal } from '../wasm-lib/kcl/bindings/Literal'
|
|
|
|
export type { ArrayExpression } from '../wasm-lib/kcl/bindings/ArrayExpression'
|
|
|
|
|
|
|
|
export type SyntaxType =
|
|
|
|
| 'Program'
|
|
|
|
| 'ExpressionStatement'
|
|
|
|
| 'BinaryExpression'
|
|
|
|
| 'CallExpression'
|
|
|
|
| 'Identifier'
|
|
|
|
| 'ReturnStatement'
|
|
|
|
| 'VariableDeclaration'
|
|
|
|
| 'VariableDeclarator'
|
|
|
|
| 'MemberExpression'
|
|
|
|
| 'ArrayExpression'
|
|
|
|
| 'ObjectExpression'
|
|
|
|
| 'ObjectProperty'
|
|
|
|
| 'FunctionExpression'
|
|
|
|
| 'PipeExpression'
|
|
|
|
| 'PipeSubstitution'
|
|
|
|
| 'Literal'
|
|
|
|
| 'NonCodeNode'
|
|
|
|
| 'UnaryExpression'
|
|
|
|
|
|
|
|
export type { SourceRange } from '../wasm-lib/kcl/bindings/SourceRange'
|
|
|
|
export type { Path } from '../wasm-lib/kcl/bindings/Path'
|
|
|
|
export type { SketchGroup } from '../wasm-lib/kcl/bindings/SketchGroup'
|
2024-03-22 10:23:04 +11:00
|
|
|
export type { ExtrudeGroup } from '../wasm-lib/kcl/bindings/ExtrudeGroup'
|
2023-09-29 11:11:01 -07:00
|
|
|
export type { MemoryItem } from '../wasm-lib/kcl/bindings/MemoryItem'
|
|
|
|
export type { ExtrudeSurface } from '../wasm-lib/kcl/bindings/ExtrudeSurface'
|
|
|
|
|
2024-04-16 21:36:19 -07:00
|
|
|
export const wasmUrl = () => {
|
2023-09-29 11:11:01 -07:00
|
|
|
const baseUrl =
|
|
|
|
typeof window === 'undefined'
|
|
|
|
? 'http://127.0.0.1:3000'
|
|
|
|
: window.location.origin.includes('tauri://localhost')
|
2023-10-17 09:37:16 -04:00
|
|
|
? 'tauri://localhost' // custom protocol for macOS
|
|
|
|
: window.location.origin.includes('tauri.localhost')
|
2024-04-09 08:04:36 -04:00
|
|
|
? 'http://tauri.localhost' // fallback for Windows
|
2023-09-29 11:11:01 -07:00
|
|
|
: window.location.origin.includes('localhost')
|
|
|
|
? 'http://localhost:3000'
|
|
|
|
: window.location.origin && window.location.origin !== 'null'
|
|
|
|
? window.location.origin
|
|
|
|
: 'http://localhost:3000'
|
|
|
|
const fullUrl = baseUrl + '/wasm_lib_bg.wasm'
|
2023-10-17 09:37:16 -04:00
|
|
|
console.log(`Full URL for WASM: ${fullUrl}`)
|
2024-04-16 21:36:19 -07:00
|
|
|
|
|
|
|
return fullUrl
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialise the wasm module.
|
|
|
|
const initialise = async () => {
|
2024-04-19 14:24:40 -07:00
|
|
|
try {
|
|
|
|
const fullUrl = wasmUrl()
|
|
|
|
const input = await fetch(fullUrl)
|
|
|
|
const buffer = await input.arrayBuffer()
|
|
|
|
return await init(buffer)
|
|
|
|
} catch (e) {
|
|
|
|
console.log('Error initialising WASM', e)
|
2024-06-24 11:45:40 -04:00
|
|
|
return Promise.reject(e)
|
2024-04-19 14:24:40 -07:00
|
|
|
}
|
2023-09-29 11:11:01 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
export const initPromise = initialise()
|
|
|
|
|
|
|
|
export const rangeTypeFix = (ranges: number[][]): [number, number][] =>
|
|
|
|
ranges.map(([start, end]) => [start, end])
|
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
export const parse = (code: string | Error): Program | Error => {
|
|
|
|
if (err(code)) return code
|
|
|
|
|
2023-09-29 11:11:01 -07:00
|
|
|
try {
|
|
|
|
const program: Program = parse_wasm(code)
|
|
|
|
return program
|
|
|
|
} catch (e: any) {
|
|
|
|
const parsed: RustKclError = JSON.parse(e.toString())
|
2024-06-24 11:45:40 -04:00
|
|
|
return new KCLError(
|
2023-09-29 11:11:01 -07:00
|
|
|
parsed.kind,
|
|
|
|
parsed.msg,
|
|
|
|
rangeTypeFix(parsed.sourceRanges)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export type PathToNode = [string | number, string][]
|
|
|
|
|
|
|
|
interface Memory {
|
|
|
|
[key: string]: MemoryItem
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface ProgramMemory {
|
|
|
|
root: Memory
|
|
|
|
return: ProgramReturn | null
|
|
|
|
}
|
|
|
|
|
|
|
|
export const executor = async (
|
|
|
|
node: Program,
|
2024-06-24 11:45:40 -04:00
|
|
|
programMemory: ProgramMemory | Error = { root: {}, return: null },
|
2024-03-26 19:32:31 -07:00
|
|
|
engineCommandManager: EngineCommandManager,
|
|
|
|
isMock: boolean = false
|
2023-09-29 11:11:01 -07:00
|
|
|
): Promise<ProgramMemory> => {
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(programMemory)) return Promise.reject(programMemory)
|
|
|
|
|
2023-09-29 11:11:01 -07:00
|
|
|
engineCommandManager.startNewSession()
|
|
|
|
const _programMemory = await _executor(
|
|
|
|
node,
|
|
|
|
programMemory,
|
2024-03-26 19:32:31 -07:00
|
|
|
engineCommandManager,
|
|
|
|
isMock
|
2023-09-29 11:11:01 -07:00
|
|
|
)
|
2023-10-14 03:47:46 +11:00
|
|
|
await engineCommandManager.waitForAllCommands()
|
2023-09-29 11:11:01 -07:00
|
|
|
|
|
|
|
engineCommandManager.endSession()
|
|
|
|
return _programMemory
|
|
|
|
}
|
|
|
|
|
|
|
|
export const _executor = async (
|
|
|
|
node: Program,
|
2024-06-24 11:45:40 -04:00
|
|
|
programMemory: ProgramMemory | Error = { root: {}, return: null },
|
2024-03-26 19:32:31 -07:00
|
|
|
engineCommandManager: EngineCommandManager,
|
|
|
|
isMock: boolean
|
2023-09-29 11:11:01 -07:00
|
|
|
): Promise<ProgramMemory> => {
|
2024-06-24 11:45:40 -04:00
|
|
|
if (err(programMemory)) return Promise.reject(programMemory)
|
|
|
|
|
2023-09-29 11:11:01 -07:00
|
|
|
try {
|
2024-04-19 14:24:40 -07:00
|
|
|
let baseUnit = 'mm'
|
|
|
|
if (!TEST) {
|
|
|
|
const getSettingsState = import('components/SettingsAuthProvider').then(
|
|
|
|
(module) => module.getSettingsState
|
|
|
|
)
|
|
|
|
baseUnit =
|
|
|
|
(await getSettingsState)()?.modeling.defaultUnit.current || 'mm'
|
|
|
|
}
|
2023-09-29 11:11:01 -07:00
|
|
|
const memory: ProgramMemory = await execute_wasm(
|
|
|
|
JSON.stringify(node),
|
|
|
|
JSON.stringify(programMemory),
|
2024-02-20 17:55:06 -08:00
|
|
|
baseUnit,
|
2024-02-12 12:18:37 -08:00
|
|
|
engineCommandManager,
|
2024-03-26 19:32:31 -07:00
|
|
|
fileSystemManager,
|
|
|
|
isMock
|
2023-09-29 11:11:01 -07:00
|
|
|
)
|
|
|
|
return memory
|
|
|
|
} catch (e: any) {
|
2024-02-11 15:08:54 -08:00
|
|
|
console.log(e)
|
2023-09-29 11:11:01 -07:00
|
|
|
const parsed: RustKclError = JSON.parse(e.toString())
|
|
|
|
const kclError = new KCLError(
|
|
|
|
parsed.kind,
|
|
|
|
parsed.msg,
|
|
|
|
rangeTypeFix(parsed.sourceRanges)
|
|
|
|
)
|
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
return Promise.reject(kclError)
|
2023-09-29 11:11:01 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-26 00:04:52 -04:00
|
|
|
export const kclLint = async (ast: Program): Promise<Array<Discovered>> => {
|
|
|
|
try {
|
|
|
|
const discovered_findings: Array<Discovered> = await kcl_lint(
|
|
|
|
JSON.stringify(ast)
|
|
|
|
)
|
|
|
|
return discovered_findings
|
|
|
|
} catch (e: any) {
|
|
|
|
return Promise.reject(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
export const recast = (ast: Program): string | Error => {
|
|
|
|
return recast_wasm(JSON.stringify(ast))
|
2023-09-29 11:11:01 -07:00
|
|
|
}
|
|
|
|
|
2024-04-15 17:18:32 -07:00
|
|
|
export const makeDefaultPlanes = async (
|
|
|
|
engineCommandManager: EngineCommandManager
|
|
|
|
): Promise<DefaultPlanes> => {
|
|
|
|
try {
|
|
|
|
const planes: DefaultPlanes = await make_default_planes(
|
|
|
|
engineCommandManager
|
|
|
|
)
|
|
|
|
return planes
|
|
|
|
} catch (e) {
|
|
|
|
// TODO: do something real with the error.
|
|
|
|
console.log('make default planes error', e)
|
2024-06-24 11:45:40 -04:00
|
|
|
return Promise.reject(e)
|
2024-04-15 17:18:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-30 19:21:24 -07:00
|
|
|
export const modifyGrid = async (
|
|
|
|
engineCommandManager: EngineCommandManager,
|
|
|
|
hidden: boolean
|
|
|
|
): Promise<void> => {
|
|
|
|
try {
|
|
|
|
await modify_grid(engineCommandManager, hidden)
|
|
|
|
return
|
|
|
|
} catch (e) {
|
|
|
|
// TODO: do something real with the error.
|
|
|
|
console.log('modify grid error', e)
|
|
|
|
return Promise.reject(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
export function lexer(str: string): Token[] | Error {
|
|
|
|
return lexer_wasm(str)
|
2023-09-29 11:11:01 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
export const modifyAstForSketch = async (
|
|
|
|
engineCommandManager: EngineCommandManager,
|
|
|
|
ast: Program,
|
|
|
|
variableName: string,
|
2023-10-05 14:27:48 -07:00
|
|
|
currentPlane: string,
|
2023-09-29 11:11:01 -07:00
|
|
|
engineId: string
|
|
|
|
): Promise<Program> => {
|
|
|
|
try {
|
|
|
|
const updatedAst: Program = await modify_ast_for_sketch_wasm(
|
|
|
|
engineCommandManager,
|
|
|
|
JSON.stringify(ast),
|
|
|
|
variableName,
|
2023-10-05 14:27:48 -07:00
|
|
|
JSON.stringify(currentPlane),
|
2023-09-29 11:11:01 -07:00
|
|
|
engineId
|
|
|
|
)
|
|
|
|
|
|
|
|
return updatedAst
|
|
|
|
} catch (e: any) {
|
|
|
|
const parsed: RustKclError = JSON.parse(e.toString())
|
|
|
|
const kclError = new KCLError(
|
|
|
|
parsed.kind,
|
|
|
|
parsed.msg,
|
|
|
|
rangeTypeFix(parsed.sourceRanges)
|
|
|
|
)
|
|
|
|
|
|
|
|
console.log(kclError)
|
2024-06-24 11:45:40 -04:00
|
|
|
return Promise.reject(kclError)
|
2023-09-29 11:11:01 -07:00
|
|
|
}
|
|
|
|
}
|
2024-02-11 12:59:00 +11:00
|
|
|
|
|
|
|
export function isPointsCCW(points: Coords2d[]): number {
|
|
|
|
return is_points_ccw(new Float64Array(points.flat()))
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getTangentialArcToInfo({
|
|
|
|
arcStartPoint,
|
|
|
|
arcEndPoint,
|
|
|
|
tanPreviousPoint,
|
|
|
|
obtuse = true,
|
|
|
|
}: {
|
|
|
|
arcStartPoint: Coords2d
|
|
|
|
arcEndPoint: Coords2d
|
|
|
|
tanPreviousPoint: Coords2d
|
|
|
|
obtuse?: boolean
|
|
|
|
}): {
|
|
|
|
center: Coords2d
|
|
|
|
arcMidPoint: Coords2d
|
|
|
|
radius: number
|
|
|
|
startAngle: number
|
|
|
|
endAngle: number
|
|
|
|
ccw: boolean
|
2024-04-03 13:22:56 +11:00
|
|
|
arcLength: number
|
2024-02-11 12:59:00 +11:00
|
|
|
} {
|
|
|
|
const result = get_tangential_arc_to_info(
|
|
|
|
arcStartPoint[0],
|
|
|
|
arcStartPoint[1],
|
|
|
|
arcEndPoint[0],
|
|
|
|
arcEndPoint[1],
|
|
|
|
tanPreviousPoint[0],
|
|
|
|
tanPreviousPoint[1],
|
|
|
|
obtuse
|
|
|
|
)
|
|
|
|
return {
|
|
|
|
center: [result.center_x, result.center_y],
|
|
|
|
arcMidPoint: [result.arc_mid_point_x, result.arc_mid_point_y],
|
|
|
|
radius: result.radius,
|
|
|
|
startAngle: result.start_angle,
|
|
|
|
endAngle: result.end_angle,
|
|
|
|
ccw: result.ccw > 0,
|
2024-04-03 13:22:56 +11:00
|
|
|
arcLength: result.arc_length,
|
2024-02-11 12:59:00 +11:00
|
|
|
}
|
|
|
|
}
|
2024-02-11 18:26:09 -08:00
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
export function programMemoryInit(): ProgramMemory | Error {
|
2024-02-11 18:26:09 -08:00
|
|
|
try {
|
|
|
|
const memory: ProgramMemory = program_memory_init()
|
|
|
|
return memory
|
|
|
|
} catch (e: any) {
|
|
|
|
console.log(e)
|
|
|
|
const parsed: RustKclError = JSON.parse(e.toString())
|
2024-06-24 11:45:40 -04:00
|
|
|
return new KCLError(
|
2024-02-11 18:26:09 -08:00
|
|
|
parsed.kind,
|
|
|
|
parsed.msg,
|
|
|
|
rangeTypeFix(parsed.sourceRanges)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2024-03-11 17:50:31 -07:00
|
|
|
|
2024-04-09 18:05:36 -07:00
|
|
|
export async function coreDump(
|
|
|
|
coreDumpManager: CoreDumpManager,
|
|
|
|
openGithubIssue: boolean = false
|
2024-06-20 16:36:28 -07:00
|
|
|
): Promise<CoreDumpInfo> {
|
2024-04-09 18:05:36 -07:00
|
|
|
try {
|
2024-06-28 18:06:40 -07:00
|
|
|
console.warn('CoreDump: Initializing core dump')
|
2024-06-20 16:36:28 -07:00
|
|
|
const dump: CoreDumpInfo = await coredump(coreDumpManager)
|
|
|
|
/* NOTE: this console output of the coredump should include the field
|
|
|
|
`github_issue_url` which is not in the uploaded coredump file.
|
|
|
|
`github_issue_url` is added after the file is uploaded
|
|
|
|
and is only needed for the openWindow operation which creates
|
|
|
|
a new GitHub issue for the user.
|
|
|
|
*/
|
2024-04-09 18:05:36 -07:00
|
|
|
if (openGithubIssue && dump.github_issue_url) {
|
|
|
|
openWindow(dump.github_issue_url)
|
2024-06-20 16:36:28 -07:00
|
|
|
} else {
|
|
|
|
console.error(
|
|
|
|
'github_issue_url undefined. Unable to create GitHub issue for coredump.'
|
|
|
|
)
|
2024-04-09 18:05:36 -07:00
|
|
|
}
|
2024-06-20 16:36:28 -07:00
|
|
|
console.log('CoreDump: final coredump', dump)
|
|
|
|
console.log('CoreDump: final coredump JSON', JSON.stringify(dump))
|
2024-04-09 18:05:36 -07:00
|
|
|
return dump
|
|
|
|
} catch (e: any) {
|
2024-06-20 16:36:28 -07:00
|
|
|
console.error('CoreDump: error', e)
|
2024-06-24 11:45:40 -04:00
|
|
|
return Promise.reject(new Error(`Error getting core dump: ${e}`))
|
2024-04-09 18:05:36 -07:00
|
|
|
}
|
|
|
|
}
|
2024-04-16 21:36:19 -07:00
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
export function tomlStringify(toml: any): string | Error {
|
|
|
|
return toml_stringify(JSON.stringify(toml))
|
2024-04-16 21:36:19 -07:00
|
|
|
}
|
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
export function defaultAppSettings(): Configuration | Error {
|
|
|
|
return default_app_settings()
|
2024-04-25 00:13:09 -07:00
|
|
|
}
|
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
export function parseAppSettings(toml: string): Configuration | Error {
|
|
|
|
return parse_app_settings(toml)
|
2024-04-25 00:13:09 -07:00
|
|
|
}
|
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
export function defaultProjectSettings(): ProjectConfiguration | Error {
|
|
|
|
return default_project_settings()
|
2024-04-25 00:13:09 -07:00
|
|
|
}
|
|
|
|
|
2024-06-24 11:45:40 -04:00
|
|
|
export function parseProjectSettings(
|
|
|
|
toml: string
|
|
|
|
): ProjectConfiguration | Error {
|
|
|
|
return parse_project_settings(toml)
|
2024-04-16 21:36:19 -07:00
|
|
|
}
|
2024-04-25 11:55:11 -07:00
|
|
|
|
|
|
|
export function parseProjectRoute(
|
|
|
|
configuration: Configuration,
|
|
|
|
route_str: string
|
2024-06-24 11:45:40 -04:00
|
|
|
): ProjectRoute | Error {
|
|
|
|
return parse_project_route(JSON.stringify(configuration), route_str)
|
2024-04-25 11:55:11 -07:00
|
|
|
}
|