joist-core 2.4.0-next.3 → 2.4.0-next.4

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.
@@ -1294,19 +1294,19 @@ function checkCondition(value) {
1294
1294
  if ("and" in condition || "or" in condition) {
1295
1295
  if ("and" in condition === "or" in condition) require_utils.fail("Query conditions require exactly one and/or group");
1296
1296
  const key = "and" in condition ? "and" : "or";
1297
- checkConditionKeys(condition, [key, "pruneIfUndefined"], "Query condition group");
1297
+ checkPojoKeys(condition, [key, "pruneIfUndefined"], "Query condition group");
1298
1298
  if (!Array.isArray(condition[key])) require_utils.fail("Query condition groups require an array");
1299
1299
  if (condition.pruneIfUndefined !== void 0 && condition.pruneIfUndefined !== "any" && condition.pruneIfUndefined !== "all") require_utils.fail("Invalid query pruneIfUndefined policy");
1300
1300
  for (const child of condition[key]) checkCondition(child);
1301
1301
  } else if ("exists" in condition || "notExists" in condition) {
1302
1302
  const key = "exists" in condition ? "exists" : "notExists";
1303
- checkConditionKeys(condition, [key], "Query existence condition");
1303
+ checkPojoKeys(condition, [key], "Query existence condition");
1304
1304
  const query = condition[key];
1305
1305
  if (query === void 0) return;
1306
1306
  if (!(query instanceof SubqueryExpr) && !isReadQueryValue(query)) require_utils.fail(`Query ${key} requires a query(...) value`);
1307
1307
  toQuery(query);
1308
1308
  } else if (condition.kind === "raw") {
1309
- checkConditionKeys(condition, [
1309
+ checkPojoKeys(condition, [
1310
1310
  "kind",
1311
1311
  "aliases",
1312
1312
  "condition",
@@ -1317,7 +1317,7 @@ function checkCondition(value) {
1317
1317
  ], "Query raw condition");
1318
1318
  if (typeof condition.condition !== "string" || !Array.isArray(condition.aliases) || !condition.aliases.every((alias) => typeof alias === "string") || !Array.isArray(condition.bindings) || typeof condition.pruneable !== "boolean") require_utils.fail("Malformed query raw condition");
1319
1319
  } else if (condition.kind === "column") {
1320
- checkConditionKeys(condition, [
1320
+ checkPojoKeys(condition, [
1321
1321
  "kind",
1322
1322
  "alias",
1323
1323
  "column",
@@ -1329,7 +1329,7 @@ function checkCondition(value) {
1329
1329
  if (typeof condition.alias !== "string" || typeof condition.column !== "string" || typeof condition.dbType !== "string" || condition.pruneable !== void 0 && typeof condition.pruneable !== "boolean") require_utils.fail("Malformed query column condition");
1330
1330
  const filter = condition.cond;
1331
1331
  if (!filter) require_utils.fail("Malformed query column filter");
1332
- checkConditionKeys(filter, ["kind", "value"], "Query column filter");
1332
+ checkPojoKeys(filter, ["kind", "value"], "Query column filter");
1333
1333
  const unary = filter.kind === "is-null" || filter.kind === "not-null";
1334
1334
  if (!unary && (![
1335
1335
  "eq",
@@ -1360,8 +1360,18 @@ function checkCondition(value) {
1360
1360
  if (unary && "value" in filter) require_utils.fail("Unary query filters do not accept values");
1361
1361
  } else require_utils.fail("Unknown query condition");
1362
1362
  }
1363
- /** Conditions use own enumerable POJO fields, with predicate-brand and SQL-resolver symbols allowed. */
1364
- function checkConditionKeys(value, allowed, description) {
1363
+ /**
1364
+ * Accepts only own enumerable POJO fields, so nothing a caller supplied can be silently ignored: the
1365
+ * compilers read these POJOs back with `Object.entries`/`Object.keys`, which skip inherited,
1366
+ * non-enumerable, and symbol keys, so a field hidden behind one of those would never reach the SQL.
1367
+ * I.e. an UPDATE whose `set` carries `title` on a prototype would leave `title` unchanged and still
1368
+ * report success.
1369
+ *
1370
+ * Conditions, mutation clauses, and assignment POJOs all share this rule; `allowed` may include symbol
1371
+ * keys, i.e. a condition's predicate brand and SQL resolver. Read-query clauses instead use
1372
+ * `validateQueryKeys`, which walks the prototype chain and reports mutation clauses by name.
1373
+ */
1374
+ function checkPojoKeys(value, allowed, description) {
1365
1375
  if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) require_utils.fail(`${description} must be a plain POJO`);
1366
1376
  for (const key of Reflect.ownKeys(value)) {
1367
1377
  if (!allowed.includes(key)) require_utils.fail(`${description} does not support '${String(key)}'`);
@@ -1590,6 +1600,7 @@ function typedSql(strings, ...values) {
1590
1600
  //#endregion
1591
1601
  exports.Ctx = Ctx;
1592
1602
  exports.SubqueryHandle = SubqueryHandle;
1603
+ exports.checkPojoKeys = checkPojoKeys;
1593
1604
  exports.conditionToSql = conditionToSql;
1594
1605
  exports.entityQueryBrand = entityQueryBrand;
1595
1606
  exports.injectedConditions = injectedConditions;