mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 12:24:54 +00:00
Commands: parameter schemas cover every route, bound hostile values and translate their errors
Check a new call's params against the schema in execute_spec, after the key check and before the parser, and check every command.batch step before the first one runs. menucmds::run_raw and the two other direct runs go through the same check. Saved steps keep keys the schema does not name and have the values it names checked. Limit nesting to 16 levels, cut error text and paths to a fixed length, and copy nothing before it has passed. Treat a whole number written with a fraction as an integer. Check declared defaults and duplicate names once at first use. Give the five schema errors rows in the 22 complete-message catalogs.
This commit is contained in:
+14
-8
@@ -1388,16 +1388,20 @@ Some commands have a machine-readable parameter schema: at present `view.capsLoc
|
||||
`view.saved.edit`, `view.saved.list`, `view.transparencyGrid` and `view.snapToGlyph.options`. The engine's
|
||||
`engine.commands` list gives such a command a `schema` field: an object schema in the shape of JSON Schema 2020-12
|
||||
(https://json-schema.org/draft/2020-12), with `type`, `properties`, `required`, `additionalProperties: false`,
|
||||
`minimum` and `exclusiveMinimum` for ranges, `enum`, and `default` for a default the engine fills in. VectorCraft's own
|
||||
`minimum`, `maximum`, `exclusiveMinimum` and `exclusiveMaximum` for ranges, `enum`, and `default` for a default the engine fills in. VectorCraft's own
|
||||
fields are `x-since` (the API level that added the command or the parameter), `x-deprecatedSince`, `x-lenient`,
|
||||
`x-unit`, `x-kind` (`id`, `color` or `point`), `x-default` (a default the command works out, such as `toggle`),
|
||||
`x-cost`, `x-writes` (`nothing`, `session`, `preferences` or `document`) and `x-returns`. A parameter that reads null
|
||||
as left out is an `anyOf` with `{"type": "null"}`. The command's `params` text is written from the same schema.
|
||||
as left out is an `anyOf` with `{"type": "null"}`. A number with no fractional part, such as `2.0`, is an integer, as
|
||||
JSON Schema defines one, and the command receives `2`. An `x-lenient` parameter's schema states the documented type,
|
||||
and the engine also passes a value of another type to the command. The command's `params` text is written from the same
|
||||
schema.
|
||||
|
||||
Every caller, the desktop app and a step of `command.batch` included, has the params of such a command checked against
|
||||
its schema before the command runs. A value of the wrong type, out of range or not in its list, a missing required
|
||||
parameter or an unknown key is refused with a parameter error that names the parameter, with the path to a value
|
||||
inside a list or an object, and the document and its undo history stay as they were:
|
||||
The engine checks the params of such a command against its schema before the command runs, for every new call: from
|
||||
the desktop app, the control channel, MCP or the CLI, and when one command runs another. The steps of `command.batch`
|
||||
and `action.batch` are checked before the first step runs. A value of the wrong type, out of range or not in its list,
|
||||
a missing required parameter or an unknown key is refused with a parameter error that names the parameter, with the
|
||||
path to a value inside a list or an object, and the document and its undo history stay as they were:
|
||||
|
||||
```json
|
||||
{"id": "view.saved.new", "params": {"center": [0, 0], "zoom": 0}}
|
||||
@@ -1407,8 +1411,10 @@ inside a list or an object, and the document and its undo history stay as they w
|
||||
```
|
||||
|
||||
An omitted value with a `default` takes it (`rotation` 0 in `view.saved.new`); the journal keeps the params as they
|
||||
were given. The schemas belong to API level 1 (`vectorcraft_engine::schemas::API_VERSION`); a change to any schema
|
||||
raises the level.
|
||||
were given. Saved steps played from a journal or an action keep a key the schema does not name, unless its value nests
|
||||
more than 16 levels deep, and the values of the parameters it names are checked as in a new call. The schemas of built-in commands belong to API level 1
|
||||
(`vectorcraft_engine::schemas::API_VERSION`); a change to any of them raises the level. Commands that plug-ins add have
|
||||
no schema here.
|
||||
|
||||
## Checking scripts written for the reference app
|
||||
|
||||
|
||||
@@ -664,7 +664,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- **Linux file associations:** the desktop entry lists the MIME type of every format File › Open reads but PSD, PSB, `.ps` PostScript, Targa, PCX, Pixar, JPEG 2000, HEIC/HEIF and JPEG XL, `.ai`, `.ait` and EPS included, and the MIME package declares the types shared-mime-info lacks (VectorCraft documents and templates, `.ait`, Affinity), so file managers list VectorCraft under Open With for them, as Finder does on macOS. `the_linux_desktop_entry_opens_every_readable_format` in `apps/vectorcraft/src/tests.rs` checks both files against `OPEN_EXTS`. On Debian 13, Ubuntu 24.04 and Fedora 42, `desktop-file-validate` accepts the desktop entry, `update-mime-database` accepts the MIME package, and `gio` registers the app for every one of these types.
|
||||
|
||||
- **Architecture:** 19+ crates with enforced layering (`cargo xtask layers`). Every action is a command (~400 engine + ~50 UI). Undo is unlimited via structural sharing. `command.batch` runs several commands as one transaction.
|
||||
- **Parameter schemas:** a command can carry a machine-readable parameter schema (the new `vectorcraft-apischema` crate): each parameter's type, range, unit, whether it is required, its default, whether null counts as left out, and the API levels it was added and deprecated at. `engine.commands` lists the schema in the shape of a JSON Schema 2020-12 object schema, the command's `params` text is written from it, and every caller has the params checked against it before the command runs, with an error naming the parameter and no change to the document. The View commands `view.capsLock`, `view.saved.new`, `view.saved.edit`, `view.saved.list`, `view.transparencyGrid` and `view.snapToGlyph.options` have schemas. The schemas belong to API level 1 (`vectorcraft_engine::schemas::API_VERSION`), and a test fails when a schema changes without a new level. Tests: `crates/apischema/src/tests.rs`, `schemas::tests` and `cmd::views::tests::each_view_command_refuses_a_bad_value_naming_the_parameter` in `vectorcraft-engine`.
|
||||
- **Parameter schemas:** a command can carry a machine-readable parameter schema (the new `vectorcraft-apischema` crate): each parameter's type, range, unit, whether it is required, its default, whether null counts as left out, and the API levels it was added and deprecated at. `engine.commands` lists the schema in the shape of a JSON Schema 2020-12 object schema, the command's `params` text is written from it, and a new call has the params checked against it before the command runs (batch steps before the first step), with an error naming the parameter and no change to the document; saved steps keep a key the schema does not name, and their values are checked. The View commands `view.capsLock`, `view.saved.new`, `view.saved.edit`, `view.saved.list`, `view.transparencyGrid` and `view.snapToGlyph.options` have schemas. The schemas belong to API level 1 (`vectorcraft_engine::schemas::API_VERSION`), and a test fails when a schema changes without a new level. Tests: `crates/apischema/src/tests.rs` (with `conformance.rs`, a separate check of the JSON form against the JSON Schema 2020-12 rules), `schemas::tests` and `cmd::views::tests::each_view_command_refuses_a_bad_value_naming_the_parameter` in `vectorcraft-engine`.
|
||||
- **Automation:**
|
||||
- Variables: Update Data Set writes what the art holds into the active data set for the variables that data set holds, and keeps the data set's value for a text, image or graph variable whose objects are locked or inside a locked layer or group; `dataset.update {all: true}` also adds the other variables that the art reports a value for.
|
||||
- Variables: `dataset.select`, `dataset.next` and `dataset.prev` rewrite type and apply the other values on hidden objects and in hidden layers and groups, which stay hidden unless a visibility value shows them, so a layer shown later holds the selected data set's text; objects that are locked or in a locked layer or group are skipped, except by a visibility value.
|
||||
|
||||
Reference in New Issue
Block a user