@jxsuite/protocol 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/routes.ts +26 -1
- package/src/types.ts +10 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxsuite/protocol",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "The Studio Backend Protocol — wire types and the canonical route table every Jx Studio backend implements",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -27,6 +27,6 @@
|
|
|
27
27
|
"test:coverage": "bun test --isolate --coverage"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@jxsuite/schema": "^2.
|
|
30
|
+
"@jxsuite/schema": "^2.3.0"
|
|
31
31
|
}
|
|
32
32
|
}
|
package/src/routes.ts
CHANGED
|
@@ -83,7 +83,7 @@ export const STUDIO_ROUTES = {
|
|
|
83
83
|
"GET",
|
|
84
84
|
"/__studio/locate-directory",
|
|
85
85
|
`Resolve the absolute path of a showDirectoryPicker() folder by the id in its ${LOCATION_ID_FILE}`,
|
|
86
|
-
"
|
|
86
|
+
"Browse… reports that the folder could not be placed; the Location is typed by hand.",
|
|
87
87
|
),
|
|
88
88
|
createProject: route(
|
|
89
89
|
"POST",
|
|
@@ -119,6 +119,31 @@ export const STUDIO_ROUTES = {
|
|
|
119
119
|
"Upload binary content to a path → UploadResult {path, size?}. `path` is the answer, not an " +
|
|
120
120
|
"echo: a store that de-duplicates, suffixes, or normalizes names reports what it really wrote",
|
|
121
121
|
),
|
|
122
|
+
/**
|
|
123
|
+
* A project file's raw BYTES, as an answer rather than as a URL.
|
|
124
|
+
*
|
|
125
|
+
* `fileRead` cannot serve this and never could: it answers `readFile(abs, "utf8")`, and Bun
|
|
126
|
+
* replaces every byte sequence that is not valid UTF-8 with U+FFFD — so a JPEG round-trips
|
|
127
|
+
* through it as mojibake, silently and losslessly-looking. A caller that wants to DECODE a
|
|
128
|
+
* project image (Studio's image editor) needs the bytes intact.
|
|
129
|
+
*
|
|
130
|
+
* Distinct from {@link documentRaw}, which serves files at a URL a `<img src>` or a `fetch` in
|
|
131
|
+
* the canvas realm can name. That is the right shape for rendering and the wrong one for reading:
|
|
132
|
+
* on the desktop the canvas origin is a cross-origin loopback, and `server.md` §4.2 bans CORS
|
|
133
|
+
* outright, so nothing in the shell can read those bytes back. This route is addressed by the
|
|
134
|
+
* PAL, not by a document, which is what lets every backend answer it the same way.
|
|
135
|
+
*
|
|
136
|
+
* `Cache-Control: no-store`, deliberately unlike `fileRead`'s `max-age=5`: the caller is an
|
|
137
|
+
* editor about to overwrite the file, and five seconds of staleness is an edit applied to the
|
|
138
|
+
* wrong bytes.
|
|
139
|
+
*/
|
|
140
|
+
fileBytes: route(
|
|
141
|
+
"GET",
|
|
142
|
+
"/__studio/file/bytes",
|
|
143
|
+
"A project file's raw bytes, undecoded — the read side of `fileUpload`, for a caller that must " +
|
|
144
|
+
"not go through UTF-8",
|
|
145
|
+
"Studio can only read a project file as text, so any surface that must decode one stays hidden.",
|
|
146
|
+
),
|
|
122
147
|
/**
|
|
123
148
|
* A project file as its own BYTES, at its own URL.
|
|
124
149
|
*
|
package/src/types.ts
CHANGED
|
@@ -758,6 +758,13 @@ export interface AiModelsResponse {
|
|
|
758
758
|
defaultModel?: string;
|
|
759
759
|
/** Set when the upstream provider was unreachable and defaults were returned. */
|
|
760
760
|
upstreamError?: number | string;
|
|
761
|
+
/**
|
|
762
|
+
* The upstream's own error message, when {@link upstreamError} is set. Populated from whatever
|
|
763
|
+
* envelope the upstream used — OpenAI's `{error}`, or an array-shaped one like Cloudflare's
|
|
764
|
+
* `{errors: [{message}]}` — so a caller can show the real reason (e.g. "No route for that URI")
|
|
765
|
+
* instead of a bare status code.
|
|
766
|
+
*/
|
|
767
|
+
upstreamMessage?: string;
|
|
761
768
|
/**
|
|
762
769
|
* Why the backend holds no working credentials, when it holds none.
|
|
763
770
|
*
|
|
@@ -765,9 +772,10 @@ export interface AiModelsResponse {
|
|
|
765
772
|
* lapsed", and those are different sentences on screen — the second one explains a thing that
|
|
766
773
|
* used to work. `cf_upstream_error` is the third case and deliberately arrives WITH `configured:
|
|
767
774
|
* true`: Cloudflare being briefly unreachable is not a reason to send someone round an OAuth flow
|
|
768
|
-
* that fixes nothing.
|
|
775
|
+
* that fixes nothing. `cf_account_required` is a live grant with no account chosen (ai.md §2.1):
|
|
776
|
+
* re-authorizing lands back in the same state, so it calls for the account picker instead.
|
|
769
777
|
*/
|
|
770
|
-
code?: "cf_not_connected" | "cf_reconnect_required" | "cf_upstream_error";
|
|
778
|
+
code?: "cf_not_connected" | "cf_reconnect_required" | "cf_account_required" | "cf_upstream_error";
|
|
771
779
|
}
|
|
772
780
|
|
|
773
781
|
// ─── Cloudflare publish surface ──────────────────────────────────────────────
|