@jxsuite/connector 0.8.7 → 0.8.9

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/worker.ts +19 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jxsuite/connector",
3
- "version": "0.8.7",
3
+ "version": "0.8.9",
4
4
  "description": "Jx database connections and dynamic data tables served over /_jx/data",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -57,7 +57,7 @@
57
57
  "upgrade": "bun update --latest && bun install"
58
58
  },
59
59
  "dependencies": {
60
- "@jxsuite/schema": "^5.5.0",
60
+ "@jxsuite/schema": "^6.0.0",
61
61
  "kysely": "^0.29.8",
62
62
  "kysely-d1": "^0.4.0",
63
63
  "kysely-postgres-js": "^5.0.1",
package/src/worker.ts CHANGED
@@ -162,8 +162,10 @@ export async function handleDataRequest(
162
162
  try {
163
163
  ({ db, kind } = await getDb(state, options, env, tableDef.connection));
164
164
  } catch (error) {
165
- const message = error instanceof Error ? error.message : String(error);
166
- return fail(500, `Connection error: ${message}`);
165
+ /* The cause names an env var, a host or a driver: the owner's to read in the log, and nothing
166
+ a visitor should be handed. */
167
+ console.error(`jx data: connection "${tableDef.connection}" failed:`, error);
168
+ return fail(500, "Connection error");
167
169
  }
168
170
 
169
171
  const plan = planTable(tableName, tableDef, tables, kind);
@@ -190,8 +192,10 @@ export async function handleDataRequest(
190
192
  }
191
193
  }
192
194
  } catch (error) {
193
- const message = error instanceof Error ? error.message : String(error);
194
- return fail(500, message);
195
+ /* A driver's message quotes the statement, the table and the constraint that refused it. That
196
+ is the schema, so it goes to the log and the caller is told only that the request failed. */
197
+ console.error(`jx data: ${action} on "${tableName}" failed:`, error);
198
+ return fail(500, "Server error");
195
199
  }
196
200
  }
197
201
 
@@ -622,11 +626,22 @@ async function expandIncludes(
622
626
  return expanded.map(({ payload }) => payload);
623
627
  }
624
628
 
629
+ /** `application/json` or a `+json` structured-syntax type (RFC 6839), parameters allowed. */
630
+ const JSON_MEDIA_TYPE = /^application\/(?:[\w.-]+\+)?json\b/iu;
631
+
625
632
  /**
626
633
  * Read a request body as JSON. `Body.json()` is `JSON.parse` of the body text, so the result is a
627
634
  * JSON value; an absent or malformed body reads as null, the same as a literal `null` body.
635
+ *
636
+ * A body that does not declare itself JSON reads as null too, whatever it holds. An HTML form can
637
+ * post JSON-shaped text as `text/plain` from any site, with the visitor's cookies and no preflight;
638
+ * it cannot set `application/json`, so requiring the type is what keeps a write a same-origin
639
+ * script's to make (specs/extensions.md §13).
628
640
  */
629
641
  function readJsonBody(request: Request): Promise<JsonValue> {
642
+ if (!JSON_MEDIA_TYPE.test(request.headers.get("content-type") ?? "")) {
643
+ return Promise.resolve(null);
644
+ }
630
645
  return request.json().catch(() => null);
631
646
  }
632
647