@coffer-org/server 3.1.0 → 3.2.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/dist/condition-where.js +32 -2
- package/package.json +3 -3
package/dist/condition-where.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { COMPILABLE_SCALAR_OPS as SCALAR_OPS, COMPILABLE_ARRAY_OPS as ARRAY_OPS } from '@coffer-org/sdk/condition';
|
|
1
|
+
import { COMPILABLE_SCALAR_OPS as SCALAR_OPS, COMPILABLE_ARRAY_OPS as ARRAY_OPS, COMPILABLE_MEMBER_OPS as MEMBER_OPS, } from '@coffer-org/sdk/condition';
|
|
2
2
|
import { fieldMap } from '@coffer-org/sdk/shelf';
|
|
3
3
|
import { isJsonStored } from '@coffer-org/sdk/fields';
|
|
4
4
|
import { coerceFilter } from "./records-api.js";
|
|
@@ -9,6 +9,28 @@ export class ConditionCompileError extends Error {
|
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
const coerce = (f, v) => typeof v === 'boolean' ? v : coerceFilter(String(v), f.column);
|
|
12
|
+
function memberOperator(pred, key, where) {
|
|
13
|
+
if (typeof pred !== 'object' || pred === null)
|
|
14
|
+
return undefined;
|
|
15
|
+
const ops = Object.keys(pred);
|
|
16
|
+
const member = ops.filter((op) => MEMBER_OPS.has(op));
|
|
17
|
+
if (!member.length)
|
|
18
|
+
return undefined;
|
|
19
|
+
if (ops.length > 1) {
|
|
20
|
+
throw new ConditionCompileError(`${where}: '${key}' mixes '${member[0]}' with other operators`);
|
|
21
|
+
}
|
|
22
|
+
return member[0];
|
|
23
|
+
}
|
|
24
|
+
function compileMember(key, operand, where) {
|
|
25
|
+
if (typeof operand === 'object' && operand !== null) {
|
|
26
|
+
throw new ConditionCompileError(`${where}: '${key}' $contains expects a single scalar element`);
|
|
27
|
+
}
|
|
28
|
+
const token = String(operand);
|
|
29
|
+
if (/[%_\\]/.test(token)) {
|
|
30
|
+
throw new ConditionCompileError(`${where}: '${key}' $contains operand '${token}' contains a LIKE metacharacter`);
|
|
31
|
+
}
|
|
32
|
+
return { $like: `%${JSON.stringify(token)}%` };
|
|
33
|
+
}
|
|
12
34
|
function compilePredicate(key, f, pred, where) {
|
|
13
35
|
if (typeof pred !== 'object' || pred === null)
|
|
14
36
|
return coerce(f, pred);
|
|
@@ -48,8 +70,16 @@ export function conditionToWhere(m, cond) {
|
|
|
48
70
|
throw new ConditionCompileError(`${where}: unknown field '${key}'`);
|
|
49
71
|
if (f.virtual)
|
|
50
72
|
throw new ConditionCompileError(`${where}: '${key}' is virtual and has no column`);
|
|
73
|
+
const memberOp = memberOperator(spec, key, where);
|
|
74
|
+
if (memberOp && !f.hints['multiple']) {
|
|
75
|
+
throw new ConditionCompileError(`${where}: '${key}' is not a multiple field — '${memberOp}' does not apply`);
|
|
76
|
+
}
|
|
51
77
|
if (isJsonStored(f)) {
|
|
52
|
-
|
|
78
|
+
if (!memberOp) {
|
|
79
|
+
throw new ConditionCompileError(`${where}: '${key}' is stored as JSON — only ${[...MEMBER_OPS].join('/')} applies`);
|
|
80
|
+
}
|
|
81
|
+
out[key] = compileMember(key, spec[memberOp], where);
|
|
82
|
+
continue;
|
|
53
83
|
}
|
|
54
84
|
if (f.columns) {
|
|
55
85
|
throw new ConditionCompileError(`${where}: '${key}' is a composite scalar stored across sub-columns — scalar operators do not apply`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coffer-org/server",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=24"
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"postpack": "node ../../scripts/swap-exports.mjs src"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@coffer-org/core": "^3.
|
|
28
|
-
"@coffer-org/sdk": "^3.
|
|
27
|
+
"@coffer-org/core": "^3.2.0",
|
|
28
|
+
"@coffer-org/sdk": "^3.2.0",
|
|
29
29
|
"@extractus/oembed-extractor": "^4.1.0",
|
|
30
30
|
"@fastify/cors": "^11.2.0",
|
|
31
31
|
"@fastify/multipart": "^10.0.0",
|