@aosengine/cli
Classes
GuestBuildError
A pipeline step that failed, with the child process output attached.
Extends
Error
Constructors
Constructor
ts
new GuestBuildError(
step,
message,
output?
): GuestBuildError;Build a pipeline failure.
Parameters
| Parameter | Type | Default value | Description |
|---|---|---|---|
step | string | undefined | Which stage failed. |
message | string | undefined | What went wrong. |
output | string | '' | Child-process output, already filtered. |
Returns
Overrides
ts
Error.constructorProperties
output
ts
readonly output: string;Filtered child-process output.
step
ts
readonly step: string;The step that failed, for example componentize.
Interfaces
ArgSpec
What a command accepts.
Properties
alias?
ts
readonly optional alias?: Readonly<Record<string, string>>;Single-character aliases, for example { t: 'template' }.
boolean?
ts
readonly optional boolean?: readonly string[];Option names that are true, false (via --no-x) or absent.
value?
ts
readonly optional value?: readonly string[];Option names that consume the following token, for example port.
CheckResult
The result of a single check.
Properties
detail
ts
readonly detail: string;One line of detail.
fix?
ts
readonly optional fix?: string;A command or edit that fixes it, when there is one.
name
ts
readonly name: string;Short label, for example node.
status
ts
readonly status: CheckStatus;Whether this blocks, warns, or passes.
DoctorDeps
Everything the checks touch, injectable so tests need no toolchain.
Properties
arch
ts
readonly arch: string;process.arch.
cwd
ts
readonly cwd: string;Absolute, forward-slashed game directory.
exists
ts
readonly exists: (path) => boolean;Does this path exist?
Parameters
| Parameter | Type |
|---|---|
path | string |
Returns
boolean
nodeVersion
ts
readonly nodeVersion: string;process.versions.node.
npmCli
ts
readonly npmCli: string | undefined;npm's own CLI entry point, when one can be found.
parseManifest
ts
readonly parseManifest: (json) => ParsedManifest;Validate an assets.json document. Throws on an invalid manifest.
Parameters
| Parameter | Type |
|---|---|
json | unknown |
Returns
ParsedManifest
platform
ts
readonly platform: string;process.platform.
resolveDir
ts
readonly resolveDir: (fromDir, name) => string | undefined;Resolve an installed package's own directory.
Parameters
| Parameter | Type |
|---|---|
fromDir | string |
name | string |
Returns
string | undefined
run
ts
readonly run: Runner;Child-process runner.
Methods
readFile()
ts
readFile(path): string;Read a UTF-8 file. May throw.
Parameters
| Parameter | Type |
|---|---|
path | string |
Returns
string
GuestBuildOptions
Everything guestBuild accepts.
Properties
entry?
ts
readonly optional entry?: string;The module whose default export is the defineGame result.
force?
ts
readonly optional force?: boolean;Rebuild even when nothing changed.
gameDir
ts
readonly gameDir: string;Absolute path to the game directory.
guestDir?
ts
readonly optional guestDir?: string;Where the transpiled guest lands. Defaults to <gameDir>/dist/guest.
onLog?
ts
readonly optional onLog?: (line) => void;Called with each progress line. Defaults to console.log.
Parameters
| Parameter | Type |
|---|---|
line | string |
Returns
void
release?
ts
readonly optional release?: boolean;Run wasm-opt -Oz over the transpiled core modules.
skipGuestTypes?
ts
readonly optional skipGuestTypes?: boolean;Skip jco guest-types, when the caller has already run it.
witDir?
ts
readonly optional witDir?: string;Override the WIT package directory.
workDir?
ts
readonly optional workDir?: string;Scratch directory for generated files. Defaults to <gameDir>/.aosengine.
GuestBuildResult
What guestBuild produced.
Properties
built
ts
readonly built: boolean;False when the outputs were already newer than every input.
durationMs
ts
readonly durationMs: number;Wall-clock duration in milliseconds.
guestDir
ts
readonly guestDir: string;Directory holding the transpiled guest.
guestEntry
ts
readonly guestEntry: string;The module exporting instantiate.
optimised
ts
readonly optimised: boolean;Whether wasm-opt ran.
toolchain
ts
readonly toolchain: GuestToolchain;The toolchain that was used.
wasmBytes
ts
readonly wasmBytes: number;Size of the component in bytes.
wasmPath
ts
readonly wasmPath: string;The component, before transpile.
GuestToolchain
Where the pipeline looks for things, once resolved.
Properties
jco
ts
readonly jco: string;jco's entry module.
sdkDir
ts
readonly sdkDir: string;The @aosengine/sdk package directory.
sdkEntry
ts
readonly sdkEntry: string;The SDK's WIT entry factory module.
wasmOpt
ts
readonly wasmOpt: string | undefined;wasm-opt, when binaryen is resolvable.
wit
ts
readonly wit: string;The authored WIT package directory.
MeasureOptions
Where measure should look.
Properties
guestDir
ts
readonly guestDir: string;The transpiled guest directory.
ticks?
ts
readonly optional ticks?: number;Number of ticks to time. Defaults to 1000.
wasmPath
ts
readonly wasmPath: string;The component, before transpile.
ParsedArgs
The result of parseArgs.
Properties
flags
ts
readonly flags: Readonly<Record<string, string | boolean>>;Declared options that were present.
positionals
ts
readonly positionals: readonly string[];Everything that was not an option, in order.
unknown
ts
readonly unknown: readonly string[];Tokens that looked like options but were not declared.
ReportGates
The thresholds --report enforces unless --no-gate is passed.
Properties
maxTickP99Ms
ts
readonly maxTickP99Ms: number;Maximum acceptable 99th-percentile tick, in milliseconds.
maxWasmBrotliBytes
ts
readonly maxWasmBrotliBytes: number;Maximum acceptable brotli size of the component, in bytes.
ReportNumbers
One measured build.
Properties
coldInstantiateMs
ts
readonly coldInstantiateMs: number;Milliseconds to import and instantiate the component the first time.
guestBrotli
ts
readonly guestBrotli: number;Sum of the brotli-11 sizes of everything in dist/guest.
guestBytes
ts
readonly guestBytes: number;Total size of everything in dist/guest.
tickP50
ts
readonly tickP50: number;Median tick, in milliseconds.
tickP99
ts
readonly tickP99: number;99th-percentile tick, in milliseconds.
ticks
ts
readonly ticks: number;Number of ticks measured.
warmInstantiateMs
ts
readonly warmInstantiateMs: number;Milliseconds to instantiate it again, with core modules already compiled.
wasmBrotli
ts
readonly wasmBrotli: number;Brotli-11 size of the same file.
wasmBytes
ts
readonly wasmBytes: number;Size of .aosengine/game.wasm.
RunOptions
How to run a child process.
Properties
cwd?
ts
readonly optional cwd?: string;Working directory. Defaults to process.cwd().
env?
ts
readonly optional env?: Readonly<Record<string, string | undefined>>;Extra environment variables, merged over process.env.
filter?
ts
readonly optional filter?: (text) => string;Transform each captured chunk before it is echoed.
Parameters
| Parameter | Type |
|---|---|
text | string |
Returns
string
inherit?
ts
readonly optional inherit?: boolean;Pipe output to this process as it arrives, as well as capturing it.
interactive?
ts
readonly optional interactive?: boolean;Hand the child this process's own stdio. Used for the dev server, which owns the terminal until Ctrl-C. Nothing is captured in this mode.
RunResult
What a finished child process produced.
Properties
status
ts
readonly status: number;Exit status. null becomes -1.
stderr
ts
readonly stderr: string;Everything written to stderr.
stdout
ts
readonly stdout: string;Everything written to stdout.
Type Aliases
CheckStatus
ts
type CheckStatus = "ok" | "warn" | "fail";How one check turned out.
Runner
ts
type Runner = (file, args, options?) => Promise<RunResult>;The subset of run the doctor needs, so tests can fake it.
Parameters
| Parameter | Type |
|---|---|
file | string |
args | readonly string[] |
options? | RunOptions |
Returns
Promise<RunResult>
Variables
color
ts
const color: object;The colours the CLI uses, in picocolors shape.
Type Declaration
bold
ts
readonly bold: (text) => string;Emphasis.
Parameters
| Parameter | Type |
|---|---|
text | string |
Returns
string
cyan
ts
readonly cyan: (text) => string;Paths and URLs.
Parameters
| Parameter | Type |
|---|---|
text | string |
Returns
string
dim
ts
readonly dim: (text) => string;De-emphasis.
Parameters
| Parameter | Type |
|---|---|
text | string |
Returns
string
gray
ts
readonly gray: (text) => string;Secondary detail.
Parameters
| Parameter | Type |
|---|---|
text | string |
Returns
string
green
ts
readonly green: (text) => string;Successes.
Parameters
| Parameter | Type |
|---|---|
text | string |
Returns
string
red
ts
readonly red: (text) => string;Failures.
Parameters
| Parameter | Type |
|---|---|
text | string |
Returns
string
yellow
ts
readonly yellow: (text) => string;Warnings.
Parameters
| Parameter | Type |
|---|---|
text | string |
Returns
string
colorEnabled
ts
const colorEnabled: boolean = enabled;Whether this process will emit ANSI sequences. Exported for tests.
DEFAULT_GATES
ts
const DEFAULT_GATES: ReportGates;What CI and the local build agree is acceptable.
mark
ts
const mark: object;Leading marks used by every command, so output reads the same everywhere.
Type Declaration
fail
ts
readonly fail: string;A check that failed.
ok
ts
readonly ok: string;A check that passed.
step
ts
readonly step: string;A step that is starting.
warn
ts
readonly warn: string;A check that passed with a caveat.
PACKAGE
ts
const PACKAGE: "@aosengine/cli";Package identity marker.
Example
ts
import { PACKAGE } from '@aosengine/cli';
console.log(PACKAGE); // '@aosengine/cli'Functions
absPosix()
ts
function absPosix(...parts): string;Resolve to an absolute, forward-slashed path.
Parameters
| Parameter | Type | Description |
|---|---|---|
...parts | string[] | Path segments, resolved left to right against process.cwd(). |
Returns
string
An absolute path with / separators.
brotliSize()
ts
function brotliSize(bytes): number;Brotli-compress a buffer the way a static host would.
Parameters
| Parameter | Type | Description |
|---|---|---|
bytes | Uint8Array | The file contents. |
Returns
number
The compressed size in bytes.
buildCommand()
ts
function buildCommand(argv, cwd): Promise<number>;Run the build.
Parameters
| Parameter | Type | Description |
|---|---|---|
argv | readonly string[] | Arguments after build. |
cwd | string | The game directory. |
Returns
Promise<number>
The process exit code.
bundleConfigSource()
ts
function bundleConfigSource(aliases): string;The generated rolldown configuration handed to --bundle-config.
Parameters
| Parameter | Type | Description |
|---|---|---|
aliases | Readonly<Record<string, string>> | Specifier to absolute source file. |
Returns
string
The config module source.
checkGates()
ts
function checkGates(numbers, gates): string[];Every gate the numbers failed.
Parameters
| Parameter | Type | Description |
|---|---|---|
numbers | ReportNumbers | A measured build. |
gates | ReportGates | The thresholds to apply. |
Returns
string[]
One human-readable line per failure; empty when everything passed.
componentizeBinding()
ts
function componentizeBinding(platform, arch): string;The napi binding package componentize-qjs needs on this machine.
Parameters
| Parameter | Type | Description |
|---|---|---|
platform | string | process.platform. |
arch | string | process.arch. |
Returns
string
The optional-dependency package name.
devCommand()
ts
function devCommand(argv, cwd): Promise<number>;Run the dev server.
Parameters
| Parameter | Type | Description |
|---|---|---|
argv | readonly string[] | Arguments after dev. |
cwd | string | The game directory. |
Returns
Promise<number>
The process exit code, once Vite exits.
directorySize()
ts
function directorySize(dir): number;Total size in bytes of every file directly inside a directory tree.
Parameters
| Parameter | Type | Description |
|---|---|---|
dir | string | Absolute directory. |
Returns
number
Bytes, or 0 when the directory is absent.
docsCommand()
ts
function docsCommand(argv, cwd): Promise<number>;Print or open the documentation.
Parameters
| Parameter | Type | Description |
|---|---|---|
argv | readonly string[] | Arguments after docs. |
cwd | string | The game directory. |
Returns
Promise<number>
The process exit code.
doctorCommand()
ts
function doctorCommand(argv, cwd): Promise<number>;Print the checks and return the number of failures.
Parameters
| Parameter | Type | Description |
|---|---|---|
argv | readonly string[] | Arguments after doctor. |
cwd | string | The game directory. |
Returns
Promise<number>
The process exit code: the number of failed checks.
entrySource()
ts
function entrySource(
workDir,
sdkEntry,
gameEntry
): string;The generated componentize entry.
Relative specifiers, not absolute ones: rolldown resolves them from the generated file's own directory, and relative paths keep working when the game moves. Extensions are omitted because rolldown resolves ./x to ./x.ts and TypeScript would reject an explicit .ts.
Parameters
| Parameter | Type | Description |
|---|---|---|
workDir | string | Absolute directory the entry is written into. |
sdkEntry | string | Absolute path to the SDK's WIT entry factory. |
gameEntry | string | Absolute path to the game module. |
Returns
string
The entry source.
filterJcoNoise()
ts
function filterJcoNoise(text): string;Drop jco componentize's expected UNRESOLVED_IMPORT diagnostics.
componentize bundles with rolldown before it links the component, so the versioned aos:engine/*@0.1.0 specifiers genuinely are unresolvable at that point — componentize supplies them itself afterwards. The warnings are red, multi-line and frightening, and they are noise every single time.
A block runs from the [UNRESOLVED_IMPORT] line to the closing box rule, plus the blank line after it.
Parameters
| Parameter | Type | Description |
|---|---|---|
text | string | Raw child-process output. |
Returns
string
The same output with those blocks removed.
findBundle()
ts
function findBundle(cwd, fileName): string | undefined;Resolve one bundle by file name.
Parameters
| Parameter | Type | Description |
|---|---|---|
cwd | string | The game directory. |
fileName | string | A bundle file name, for example llms-fps.txt. |
Returns
string | undefined
The absolute path, or undefined when it is not installed.
findNpmCli()
ts
function findNpmCli(): string | undefined;Locate npm's own JavaScript entry point.
Spawning npm directly is not an option: on Windows it is a .cmd shim, and node refuses to spawn those without a shell. npm's CLI is a plain script, so the doctor runs node npm-cli.js instead.
Returns
string | undefined
The absolute path, or undefined when npm cannot be found.
findRepoRoot()
ts
function findRepoRoot(startDir): string | undefined;Find the aosengine monorepo root above startDir, if there is one.
The marker is a package.json whose workspaces include packages/* together with a sibling wit/ directory. That is deliberately narrow: a generated game must never accidentally decide it is the engine repository.
Parameters
| Parameter | Type | Description |
|---|---|---|
startDir | string | Absolute directory to start from. |
Returns
string | undefined
The absolute, forward-slashed repository root, or undefined.
findUp()
ts
function findUp(startDir, relativeTarget): string | undefined;Walk up from startDir looking for a relative path that exists.
Parameters
| Parameter | Type | Description |
|---|---|---|
startDir | string | Absolute directory to start from. |
relativeTarget | string | Path to test in each ancestor, for example wit. |
Returns
string | undefined
The absolute, forward-slashed match, or undefined.
flagBool()
ts
function flagBool(
flags,
name,
fallback
): boolean;Read a boolean flag.
Parameters
| Parameter | Type | Description |
|---|---|---|
flags | Readonly<Record<string, string | boolean | undefined>> | Parsed flags. |
name | string | Option name. |
fallback | boolean | Value to use when the option is absent. |
Returns
boolean
The flag value.
flagNumber()
ts
function flagNumber(
flags,
name,
fallback
): number;Read a numeric flag.
Parameters
| Parameter | Type | Description |
|---|---|---|
flags | Readonly<Record<string, string | boolean | undefined>> | Parsed flags. |
name | string | Option name. |
fallback | number | Value to use when the option is absent or unparseable. |
Returns
number
The flag value.
flagString()
ts
function flagString(
flags,
name,
fallback
): string;Read a string flag.
Parameters
| Parameter | Type | Description |
|---|---|---|
flags | Readonly<Record<string, string | boolean | undefined>> | Parsed flags. |
name | string | Option name. |
fallback | string | Value to use when the option is absent. |
Returns
string
The flag value.
formatBytes()
ts
function formatBytes(bytes): string;Format a byte count for the report table.
Parameters
| Parameter | Type | Description |
|---|---|---|
bytes | number | A size. |
Returns
string
A short human-readable size.
formatReport()
ts
function formatReport(numbers, gates): string;Render the report as plain text.
Parameters
| Parameter | Type | Description |
|---|---|---|
numbers | ReportNumbers | A measured build. |
gates | ReportGates | The thresholds the numbers were checked against. |
Returns
string
The report body, without a trailing newline.
generateGuestTypes()
ts
function generateGuestTypes(toolchain, outDir): Promise<void>;Generate the ambient aos:engine/* declarations for the game's tsc.
Parameters
| Parameter | Type | Description |
|---|---|---|
toolchain | GuestToolchain | Resolved jco and WIT locations. |
outDir | string | Absolute output directory. |
Returns
Promise<void>
Nothing.
Throws
When jco fails.
guestBuild()
ts
function guestBuild(options): Promise<GuestBuildResult>;Build the game's WebAssembly component and transpile it for the browser.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | GuestBuildOptions | Game directory and pipeline overrides. |
Returns
Promise<GuestBuildResult>
Where the outputs landed and what they cost.
Throws
When any stage fails.
isAbsolutePath()
ts
function isAbsolutePath(path): boolean;True when path is already absolute.
Parameters
| Parameter | Type | Description |
|---|---|---|
path | string | Any path. |
Returns
boolean
Whether the path needs no base to be meaningful.
main()
ts
function main(argv, cwd): Promise<number>;Dispatch one invocation.
Parameters
| Parameter | Type | Description |
|---|---|---|
argv | readonly string[] | Arguments after the executable and script, usually process.argv.slice(2). |
cwd | string | Working directory the command applies to. |
Returns
Promise<number>
The process exit code.
measure()
ts
function measure(options): Promise<ReportNumbers>;Measure a finished build.
Parameters
| Parameter | Type | Description |
|---|---|---|
options | MeasureOptions | Where the component and the transpiled guest are. |
Returns
Promise<ReportNumbers>
Sizes and timings.
Throws
When the component cannot be instantiated in node.
meetsMajor()
ts
function meetsMajor(version, major): boolean;Compare a dotted version against a required major.
Parameters
| Parameter | Type | Description |
|---|---|---|
version | string | A version string, with or without a leading v. |
major | number | The minimum acceptable major version. |
Returns
boolean
True when the version is at least that major.
newestMtime()
ts
function newestMtime(path): number;Newest mtime under a path, recursively, ignoring build output.
Parameters
| Parameter | Type | Description |
|---|---|---|
path | string | Absolute file or directory. |
Returns
number
Milliseconds since the epoch, or 0 when the path is absent.
packageDirOf()
ts
function packageDirOf(moduleUrl): string;The directory of the npm package a module belongs to.
Works from src/ under vitest and from dist/ after a tsdown build, which is why nothing in this package hard-codes a relative depth.
Parameters
| Parameter | Type | Description |
|---|---|---|
moduleUrl | string | A module's import.meta.url. |
Returns
string
The absolute, forward-slashed package directory.
parseArgs()
ts
function parseArgs(argv, spec?): ParsedArgs;Parse an argv slice.
Parameters
| Parameter | Type | Description |
|---|---|---|
argv | readonly string[] | Arguments after the command name. |
spec | ArgSpec | What this command accepts. |
Returns
Positionals, flags and anything undeclared.
percentile()
ts
function percentile(samples, fraction): number;A percentile of an unsorted sample.
Parameters
| Parameter | Type | Description |
|---|---|---|
samples | readonly number[] | The measurements. |
fraction | number | Percentile as a fraction, for example 0.99. |
Returns
number
The sample at that percentile, or 0 when there are none.
realDeps()
ts
function realDeps(cwd): DoctorDeps;The default dependency set: the real filesystem and the real toolchain.
Parameters
| Parameter | Type | Description |
|---|---|---|
cwd | string | The game directory. |
Returns
Dependencies wired to this process.
relativeSpecifier()
ts
function relativeSpecifier(fromDir, toPath): string;A relative ESM specifier from one directory to one file.
Both arguments must already be absolute and forward-slashed. The result always starts with ./ or ../, so rolldown treats it as a path and not as a bare package name.
Parameters
| Parameter | Type | Description |
|---|---|---|
fromDir | string | Absolute directory the specifier is written in. |
toPath | string | Absolute file the specifier points at. |
Returns
string
A relative, forward-slashed specifier.
resolveFrom()
ts
function resolveFrom(fromDir, specifier): string | undefined;Resolve a package specifier as if from inside fromDir.
Parameters
| Parameter | Type | Description |
|---|---|---|
fromDir | string | Absolute directory whose node_modules chain applies. |
specifier | string | A bare specifier, for example @bytecodealliance/jco/package.json. |
Returns
string | undefined
The absolute, forward-slashed file, or undefined when unresolvable.
resolvePackageDir()
ts
function resolvePackageDir(fromDir, name): string | undefined;Resolve a package's own directory as if from inside fromDir.
The node_modules chain is walked directly rather than going through require.resolve('<name>/package.json'), because a package with an exports map that does not list ./package.json — @bytecodealliance/jco, for one — makes the resolver throw even though the package is plainly installed. The resolver is still the fallback, for layouts that are not plain node_modules.
Parameters
| Parameter | Type | Description |
|---|---|---|
fromDir | string | Absolute directory whose node_modules chain applies. |
name | string | Package name, for example @aosengine/sdk. |
Returns
string | undefined
The absolute, forward-slashed package directory, or undefined.
resolveToolchain()
ts
function resolveToolchain(gameDir, witOverride?): GuestToolchain;Locate jco, the WIT package, the SDK and (optionally) binaryen.
Resolution is deliberately layered: an explicit override, then the game's own node_modules, then the monorepo the game may be sitting inside, then the CLI's own copy. A published game resolves everything from its dependencies; a workspace member inside this repository resolves everything from the root.
Parameters
| Parameter | Type | Description |
|---|---|---|
gameDir | string | Absolute, forward-slashed game directory. |
witOverride? | string | Explicit WIT directory, when the caller has one. |
Returns
The resolved toolchain.
Throws
When jco, the WIT package or the SDK is missing.
run()
ts
function run(
file,
args,
options?
): Promise<RunResult>;Spawn a process and wait for it.
Parameters
| Parameter | Type | Description |
|---|---|---|
file | string | Executable, or a node script when file is process.execPath. |
args | readonly string[] | Arguments, already split. |
options | RunOptions | Working directory, environment and echo behaviour. |
Returns
Promise<RunResult>
The exit status and captured output.
runChecks()
ts
function runChecks(deps): Promise<CheckResult[]>;Run every check.
Parameters
| Parameter | Type | Description |
|---|---|---|
deps | DoctorDeps | Filesystem, child processes and resolution. |
Returns
Promise<CheckResult[]>
One result per check, in display order.
runNode()
ts
function runNode(
script,
args,
options?
): Promise<RunResult>;Run a node script.
Parameters
| Parameter | Type | Description |
|---|---|---|
script | string | Absolute path to the script. |
args | readonly string[] | Arguments for the script. |
options | RunOptions | Working directory, environment and echo behaviour. |
Returns
Promise<RunResult>
The exit status and captured output.
sdkAliases()
ts
function sdkAliases(sdkDir): Record<string, string>;Every @aosengine/sdk subpath that has a development target, mapped onto the SDK sources.
rolldown bundles with platform: "neutral", so the workspace development condition never applies and @aosengine/sdk would resolve to dist/, which may not exist. Reading the exports map rather than hard-coding the subpaths keeps the alias correct when the SDK grows one.
Parameters
| Parameter | Type | Description |
|---|---|---|
sdkDir | string | Absolute @aosengine/sdk directory. |
Returns
Record<string, string>
Specifier to absolute source file, longest specifier first.
stripAnsi()
ts
function stripAnsi(text): string;Remove every ANSI escape sequence from a string.
jco colours its diagnostics unconditionally; the noise filter has to match on the text underneath.
Parameters
| Parameter | Type | Description |
|---|---|---|
text | string | Possibly coloured text. |
Returns
string
The same text with SGR and CSI sequences removed.
threeVersions()
ts
function threeVersions(tree): string[];Every three version present in an npm ls three --json document.
Parameters
| Parameter | Type | Description |
|---|---|---|
tree | unknown | The parsed npm output. |
Returns
string[]
Distinct versions, sorted.
toPosix()
ts
function toPosix(path): string;Forward-slash a path and drop any trailing separator.
A bare drive root keeps its slash: C:\ becomes C:/, not C:.
Parameters
| Parameter | Type | Description |
|---|---|---|
path | string | Any path, in any separator style. |
Returns
string
The same path with / separators and no trailing slash.