mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-29 04:46:50 -06:00
A document carries things the app acts on for whoever opens it. Three of them were taken as given. Prototype Open link and Dev Mode dev resources both reached the platform's opener with any scheme. In the web build the opener is window.open, so a saved document could run script in the app's own origin; on the desktop any scheme went to the system's handler. Both now pass through the new engine module `doc_urls`, which allows http, https and mailto and nothing else. It is an allow-list on purpose: a list of known-bad schemes is outgrown by every handler a platform adds. A figcraft:// invite link joined the session at once. The system hands the app whatever such link was followed, which may come from a page or a message, so the Join dialog now opens with the link filled in and the person confirms. A library link stored in a document was loaded from wherever it pointed. Only a path on this computer is followed now, so opening someone else's file cannot make the app contact their server (which on Windows would also send credentials). Tests: each change has one that fails without it, verified by reverting. The prototype test fires through an afterDelay trigger, since no click is needed, and keeps a positive case so a refusal cannot pass vacuously.
122 lines
4.1 KiB
TOML
122 lines
4.1 KiB
TOML
[workspace]
|
||
resolver = "3"
|
||
members = ["crates/*", "apps/*", "xtask"]
|
||
# The plugin SDK and examples build for wasm32 in a workspace of their own (`cargo xtask plugins`).
|
||
exclude = ["plugins"]
|
||
# default-members = ["crates/*", "apps/figcraft", "apps/figcraft-cli", "xtask"]
|
||
|
||
[workspace.package]
|
||
version = "0.6.0"
|
||
edition = "2024"
|
||
license = "MIT OR Apache-2.0"
|
||
rust-version = "1.95"
|
||
repository = "https://github.com/storytold/figcraft"
|
||
|
||
[workspace.dependencies]
|
||
# internal
|
||
figcraft-geom = { path = "crates/geom" }
|
||
figcraft-color = { path = "crates/color" }
|
||
figcraft-doc = { path = "crates/doc" }
|
||
figcraft-layout = { path = "crates/layout" }
|
||
figcraft-text = { path = "crates/text" }
|
||
figcraft-pathops = { path = "crates/pathops" }
|
||
figcraft-render = { path = "crates/render" }
|
||
figcraft-svg = { path = "crates/svg" }
|
||
figcraft-pdf = { path = "crates/pdf" }
|
||
figcraft-format = { path = "crates/format" }
|
||
figcraft-tools = { path = "crates/tools" }
|
||
figcraft-collab = { path = "crates/collab" }
|
||
figcraft-engine = { path = "crates/engine" }
|
||
figcraft-ui-egui = { path = "crates/ui-egui" }
|
||
figcraft-mcp = { path = "crates/mcp" }
|
||
figcraft-collab-net = { path = "crates/collab-net" }
|
||
figcraft-plugin = { path = "crates/plugin" }
|
||
|
||
# Which paths stored in a document may be followed (craft-libs).
|
||
craft-docpath = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "82a24b006eefa036b43c09a67fb9a3fbd17ffe63" }
|
||
|
||
# foundation
|
||
kurbo = { version = "0.13", features = ["serde"] }
|
||
thiserror = "2"
|
||
serde = { version = "1", features = ["derive", "rc"] }
|
||
serde_json = { version = "1", features = ["float_roundtrip"] }
|
||
regex = "1.13"
|
||
log = "0.4"
|
||
proptest = "1"
|
||
imbl = { version = "7", features = ["serde"] }
|
||
postcard = { version = "1", default-features = false, features = ["alloc"] }
|
||
|
||
# rendering / formats
|
||
tiny-skia = "0.12"
|
||
image = { version = "0.25", default-features = false, features = ["png", "jpeg", "webp", "gif", "bmp", "tiff"] }
|
||
# Already built for `image`: embedded ICC profiles (moxcms) and PNG colour chunks (png).
|
||
moxcms = "0.8"
|
||
png = "0.18"
|
||
usvg = "0.48"
|
||
krilla = "0.8"
|
||
skrifa = "0.47"
|
||
harfrust = "0.13"
|
||
unicode-bidi = "0.3"
|
||
unicode-segmentation = "1.13"
|
||
linesweeper = "0.4"
|
||
zip = { version = "2", default-features = false, features = ["deflate"] }
|
||
# `.fig` import: raw deflate chunks (already built for zip) and zstd chunks (pure Rust, MIT, wasm-safe).
|
||
flate2 = { version = "1", default-features = false, features = ["rust_backend"] }
|
||
ruzstd = { version = "0.9.1", default-features = false, features = ["std"] }
|
||
sha2 = "0.10"
|
||
base64 = "0.22"
|
||
crc32fast = "1"
|
||
|
||
# plugins: a pure-Rust, metered WebAssembly interpreter (no JIT; also runs in the web build). The
|
||
# portable dispatch loop: tail-call dispatch relies on an LLVM optimisation that unoptimised and
|
||
# debug builds may not do, and then a long-running plugin overflows the native stack.
|
||
wasmi = { version = "2", default-features = false, features = ["std", "stable", "validate", "portable-dispatch"] }
|
||
wat = "1.261"
|
||
|
||
# ui
|
||
egui = "0.36"
|
||
egui_extras = { version = "0.36", default-features = false }
|
||
eframe = { version = "0.36", default-features = false }
|
||
rfd = "0.17"
|
||
arboard = { version = "3.6", default-features = false }
|
||
webbrowser = "1"
|
||
|
||
[workspace.lints.rust]
|
||
unsafe_code = "forbid"
|
||
|
||
[workspace.lints.clippy]
|
||
dbg_macro = "warn"
|
||
# Style lints from newer toolchains that fight index-heavy pixel code.
|
||
needless_range_loop = "allow"
|
||
chunks_exact_to_as_chunks = "allow"
|
||
# FigCraft never crashes: shipped code returns `Result`/`Option` instead of panicking (see
|
||
# AGENTS.md › Never crash). Tests may unwrap (clippy.toml).
|
||
unwrap_used = "deny"
|
||
expect_used = "deny"
|
||
panic = "deny"
|
||
todo = "deny"
|
||
unimplemented = "deny"
|
||
unreachable = "deny"
|
||
|
||
[profile.dev.package."*"]
|
||
opt-level = 2
|
||
|
||
[profile.dev]
|
||
opt-level = 1
|
||
|
||
[profile.release]
|
||
lto = "thin"
|
||
codegen-units = 4
|
||
|
||
# The browser build only (apps/figcraft-web/index.html: data-cargo-profile). Optimised for size:
|
||
# packaging/web/package.sh fails a .wasm over 24 MiB (Cloudflare's per-file cap is 25 MiB).
|
||
# wasm32-unknown-unknown always aborts on panic, so panic = "abort" changes nothing there.
|
||
[profile.web-release]
|
||
inherits = "release"
|
||
opt-level = "s"
|
||
lto = "fat"
|
||
codegen-units = 1
|
||
debug = false
|
||
strip = true
|
||
panic = "abort"
|