Category subdirectories for request/report; ams/xcam split; print vs pushing fix
Each root JSON key ('info', 'pushing', 'print') now gets its own category
folder under request/ and report/, so a category can hold multiple command
schemas without flattening them into one directory - v1/request.schema.json
and v1/report.schema.json route into these via oneOf per category (also
future-proofs for a category ever needing more than one shape).
Split pushall's ams/xcam fields the same way module_info was already
split: ams.schema.json/ams_unit.schema.json/ams_tray.schema.json/
xcam.schema.json/print.schema.json, each referencing the next by relative
$ref. ams_tray.schema.json uses oneOf for the empty-vs-loaded tray shapes
- verified (and initially got wrong, then fixed) that LoadedTray needs
every field required, not just id, or a bare {"id":"0"} validates
against both branches and oneOf fails, since oneOf demands exactly one
match.
Real correction: the report/ category for what a pushall request
triggers is "print", not "pushing" - re-reading the original examples,
pushall's REQUEST goes to "pushing", but the resulting state-push stream
arrives under "print", a different root key. report/pushing/ (my
original mistake) is removed; report/print/ holds the corrected content.
request/pushing/ is untouched - that side was correct.
Also: v2/ removed (found as broken copy-pasted stubs still pointing at
v1 $ids - no real V2-specific content yet, better to have nothing than
broken duplicates); all $ids switched to real, verified Gitea raw-file
URLs (raw/branch/main/<path> - confirmed this is the correct pattern,
not raw/<path>) instead of a placeholder domain; fixed a broken relative
$ref in the request-side files left over from an earlier move (still
pointing 2 levels up instead of 3 after nesting one level deeper).
Re-validated everything against real examples after restructuring,
including the full ams/xcam print report and two negative cases -
see schemas/bambulab/README.md for the validation script.
This commit is contained in:
+53
-15
@@ -15,19 +15,40 @@ bambulab/
|
||||
every command in every generation, so it lives
|
||||
here unversioned, not duplicated under v1/v2
|
||||
v1/
|
||||
request.schema.json BambuRequest dispatcher — {"info": ...} / {"pushing": ...}
|
||||
report.schema.json BambuReport dispatcher
|
||||
request.schema.json BambuRequest dispatcher — one key per category
|
||||
("info", "pushing", ...), each a oneOf (a
|
||||
category can have more than one request shape)
|
||||
report.schema.json BambuReport dispatcher, same idea
|
||||
request/
|
||||
get_version.schema.json
|
||||
pushall.schema.json
|
||||
info/
|
||||
get_version.schema.json
|
||||
pushing/
|
||||
pushall.schema.json
|
||||
report/
|
||||
get_version.schema.json
|
||||
pushall.schema.json
|
||||
module_info.schema.json
|
||||
v2/ add the same request/report split once V2's
|
||||
wire format is known to differ from V1's
|
||||
info/
|
||||
get_version.schema.json
|
||||
module_info.schema.json
|
||||
print/
|
||||
print.schema.json the ongoing print-state push
|
||||
ams.schema.json
|
||||
ams_unit.schema.json
|
||||
ams_tray.schema.json
|
||||
xcam.schema.json
|
||||
v2/ add the same split once V2's wire format is
|
||||
known to differ from V1's — removed for now
|
||||
rather than leave broken copy-pasted stubs
|
||||
```
|
||||
|
||||
**One real correction baked into this layout**: the report category for
|
||||
whatever a `pushall` request triggers is `report/print/`, not
|
||||
`report/pushing/`. Sending `pushall` (which *does* go to the `pushing` key
|
||||
on the request side) makes the printer start/refresh an ongoing state-push
|
||||
stream, and that stream arrives under the `print` key — a different root
|
||||
key from the request that triggered it. A category folder here means
|
||||
"what root key does this arrive under", not "what request caused it" — the
|
||||
first version of this schema got that wrong (see git history) before a
|
||||
closer read of the real capture caught it.
|
||||
|
||||
## The "inheritance" pattern
|
||||
|
||||
Every command/response schema *extends* `envelope.schema.json` with
|
||||
@@ -36,7 +57,7 @@ Every command/response schema *extends* `envelope.schema.json` with
|
||||
```json
|
||||
{
|
||||
"allOf": [
|
||||
{ "$ref": "../../envelope.schema.json" },
|
||||
{ "$ref": "../../../envelope.schema.json" },
|
||||
{ "type": "object", "properties": { "command": { "const": "get_version" } } }
|
||||
]
|
||||
}
|
||||
@@ -47,10 +68,16 @@ project's schema stack (proto, Rust): the instance must satisfy the base
|
||||
schema *and* the extension schema simultaneously, and — verified with
|
||||
negative test cases, not just asserted — `envelope.schema.json`'s
|
||||
`required: ["sequence_id", "command"]` is actually enforced on every
|
||||
schema that extends it, not just copy-pasted as documentation. Proto and
|
||||
Rust only ever gave us composition (embed a field holding the base),
|
||||
never something that reuses a *named, referenced* schema's constraints
|
||||
automatically like this.
|
||||
schema that extends it, not just copy-pasted as documentation.
|
||||
|
||||
`v1/report/print/ams_tray.schema.json` is the other JSON-Schema-specific
|
||||
tool worth knowing: `oneOf`, for "this is exactly one of several
|
||||
genuinely different shapes" (an AMS tray slot is either empty — just
|
||||
`id` — or loaded — the full field set — never something in between).
|
||||
`oneOf` requires exactly one branch to match; watch out for a base-style
|
||||
branch (like `EmptyTray`) accidentally also matching a more specific
|
||||
branch's instance if the specific branch doesn't require enough fields —
|
||||
verified and fixed once already here, see that file's description.
|
||||
|
||||
**One gotcha if you add a new base-style schema**: don't set
|
||||
`"additionalProperties": false` on something meant to be `allOf`-extended.
|
||||
@@ -62,12 +89,23 @@ base; enforce closedness only on the top-level dispatcher schemas
|
||||
(`v1/request.schema.json`/`v1/report.schema.json` do this correctly —
|
||||
check their `additionalProperties: false`).
|
||||
|
||||
## `$id` convention
|
||||
|
||||
Every schema's `$id` is its real Gitea raw-file URL:
|
||||
`https://git.octoturge.com/Continuum/continuum-schemas/raw/branch/main/schemas/bambulab/...`
|
||||
— a genuinely dereferenceable URI (verified: `raw/branch/main/<path>` is
|
||||
the correct Gitea pattern, not `raw/<path>` or `raw/<branch>/<path>`),
|
||||
rather than a made-up placeholder domain. `$ref`s between files stay
|
||||
relative paths; `$id` is what a validator uses as the base URI to resolve
|
||||
those relative refs, and it's also what lets a schema be fetched
|
||||
standalone by anything that wants to dereference it directly.
|
||||
|
||||
## Validating something
|
||||
|
||||
`$ref` resolution here relies on each schema's `$id` as the base URI for
|
||||
its own relative refs (standard JSON Schema behavior) — register schemas
|
||||
by `$id`, not by filename, or you'll hit collisions (`get_version.schema.json`
|
||||
exists in both `request/` and `report/`):
|
||||
exists under both `request/info/` and `report/info/`):
|
||||
|
||||
```python
|
||||
from referencing import Registry, Resource
|
||||
|
||||
Reference in New Issue
Block a user