@noy-db/hub 0.2.0-pre.14 → 0.2.0-pre.15
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/aggregate/index.cjs +56 -56
- package/dist/aggregate/index.cjs.map +1 -1
- package/dist/aggregate/index.d.cts +2 -2
- package/dist/aggregate/index.d.ts +2 -2
- package/dist/aggregate/index.js +3 -3
- package/dist/attestation/index.d.cts +5 -5
- package/dist/attestation/index.d.ts +5 -5
- package/dist/blobs/index.d.cts +6 -6
- package/dist/blobs/index.d.ts +6 -6
- package/dist/bundle/index.cjs +426 -68
- package/dist/bundle/index.cjs.map +1 -1
- package/dist/bundle/index.d.cts +7 -7
- package/dist/bundle/index.d.ts +7 -7
- package/dist/bundle/index.js +1 -1
- package/dist/{chunk-3EWA37FV.js → chunk-3EWXMOK3.js} +7 -266
- package/dist/chunk-3EWXMOK3.js.map +1 -0
- package/dist/{chunk-ACKFRSAH.js → chunk-7EFFHEN5.js} +26 -19
- package/dist/chunk-7EFFHEN5.js.map +1 -0
- package/dist/{chunk-UWNYBOOO.js → chunk-C5T5AFWN.js} +2 -2
- package/dist/chunk-CJORTUJ2.js +524 -0
- package/dist/chunk-CJORTUJ2.js.map +1 -0
- package/dist/{chunk-YNTBADIY.js → chunk-CZI2A4MQ.js} +2 -2
- package/dist/{chunk-KGCORI4L.js → chunk-EYVQHAGH.js} +266 -66
- package/dist/chunk-EYVQHAGH.js.map +1 -0
- package/dist/{chunk-NP6EZT44.js → chunk-IQLVUT37.js} +2 -2
- package/dist/{chunk-4PEFEETV.js → chunk-KIP6JLTF.js} +2 -2
- package/dist/{chunk-ZWTNWAO4.js → chunk-NU6Q3FOR.js} +3 -3
- package/dist/chunk-NU6Q3FOR.js.map +1 -0
- package/dist/{chunk-WIBHRONM.js → chunk-XWH4MXIU.js} +2 -2
- package/dist/consent/index.d.cts +6 -6
- package/dist/consent/index.d.ts +6 -6
- package/dist/derivations/index.d.cts +7 -7
- package/dist/derivations/index.d.ts +7 -7
- package/dist/{dev-unlock-DV7ujTCI.d.ts → dev-unlock-iAS8z9jc.d.ts} +1 -1
- package/dist/{dev-unlock-BF4OSxRv.d.cts → dev-unlock-nVkuRLLe.d.cts} +1 -1
- package/dist/{executor-723ZP6TH.js → executor-HSSRXDOB.js} +4 -4
- package/dist/guards/index.d.cts +7 -7
- package/dist/guards/index.d.ts +7 -7
- package/dist/{hash-BcF5WQXl.d.cts → hash-Cv6byZs7.d.cts} +1 -1
- package/dist/{hash-DswxkLtW.d.ts → hash-DHOnRarj.d.ts} +1 -1
- package/dist/history/index.d.cts +7 -7
- package/dist/history/index.d.ts +7 -7
- package/dist/i18n/index.d.cts +6 -6
- package/dist/i18n/index.d.ts +6 -6
- package/dist/{immutable-guard-C8IYdzfu.d.ts → immutable-guard-BehB1YGB.d.ts} +1 -1
- package/dist/{immutable-guard-7KqslW2K.d.cts → immutable-guard-yBEOYmif.d.cts} +1 -1
- package/dist/{index-CUVOMtgg.d.cts → index-D95VK1Qy.d.cts} +11 -3
- package/dist/{index-Cqzp4tt9.d.ts → index-XNB2r6bX.d.ts} +11 -3
- package/dist/index.cjs +567 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +145 -15
- package/dist/index.d.ts +145 -15
- package/dist/index.js +132 -16
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.cjs +92 -31
- package/dist/indexing/index.cjs.map +1 -1
- package/dist/indexing/index.d.cts +3 -3
- package/dist/indexing/index.d.ts +3 -3
- package/dist/indexing/index.js +3 -3
- package/dist/{lazy-builder-D5GU14TS.d.ts → lazy-builder-ChSqcF5t.d.ts} +1 -1
- package/dist/{lazy-builder-Ci5_YG73.d.cts → lazy-builder-eYZzLEL1.d.cts} +1 -1
- package/dist/materialized-views/index.cjs +2 -2
- package/dist/materialized-views/index.cjs.map +1 -1
- package/dist/materialized-views/index.d.cts +7 -7
- package/dist/materialized-views/index.d.ts +7 -7
- package/dist/materialized-views/index.js +5 -5
- package/dist/{noydb-VZ4JVW55.js → noydb-GZGFBA4E.js} +8 -8
- package/dist/overlay-views/index.d.cts +7 -7
- package/dist/overlay-views/index.d.ts +7 -7
- package/dist/periods/index.d.cts +6 -6
- package/dist/periods/index.d.ts +6 -6
- package/dist/{predicate-Bt5ft-9c.d.cts → predicate-BmhBSPCH.d.cts} +59 -2
- package/dist/{predicate-Bt5ft-9c.d.ts → predicate-BmhBSPCH.d.ts} +59 -2
- package/dist/query/index.cjs +580 -195
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +3 -3
- package/dist/query/index.d.ts +3 -3
- package/dist/query/index.js +5 -5
- package/dist/session/index.d.cts +7 -7
- package/dist/session/index.d.ts +7 -7
- package/dist/shadow/index.d.cts +6 -6
- package/dist/shadow/index.d.ts +6 -6
- package/dist/snapshots/index.d.cts +6 -6
- package/dist/snapshots/index.d.ts +6 -6
- package/dist/{stale-7FRJVHN6.js → stale-JH67FU57.js} +2 -2
- package/dist/store/index.d.cts +6 -6
- package/dist/store/index.d.ts +6 -6
- package/dist/{strategy-CrS7PnbE.d.ts → strategy-CbneC7bS.d.cts} +1 -1
- package/dist/{strategy-CrS7PnbE.d.cts → strategy-CbneC7bS.d.ts} +1 -1
- package/dist/sync/index.d.cts +5 -5
- package/dist/sync/index.d.ts +5 -5
- package/dist/team/index.d.cts +6 -6
- package/dist/team/index.d.ts +6 -6
- package/dist/tx/index.d.cts +6 -6
- package/dist/tx/index.d.ts +6 -6
- package/dist/{types-BFHQUjdy.d.ts → types-4t1-tWS4.d.ts} +22 -7
- package/dist/{types-V5R2-pd4.d.cts → types-BpPV5uyy.d.cts} +22 -7
- package/dist/{ulid-CwNf9e6-.d.cts → ulid-CiPrpGqm.d.cts} +1 -1
- package/dist/{ulid-p2nKiiKg.d.ts → ulid-DAfenvFd.d.ts} +1 -1
- package/dist/{vault-group-W7QC4UYW.js → vault-group-KOM7QRJG.js} +3 -3
- package/dist/{with-derivation-C9K43BOB.d.cts → with-derivation-DBqJB3dQ.d.cts} +1 -1
- package/dist/{with-derivation-Ds9yZgCj.d.ts → with-derivation-OK9M2sJE.d.ts} +1 -1
- package/dist/{with-materialized-view-DwR4jkV5.d.ts → with-materialized-view-Dt-ufPWQ.d.ts} +1 -1
- package/dist/{with-materialized-view-DgQcAjYv.d.cts → with-materialized-view-NzuxYPDF.d.cts} +1 -1
- package/dist/{with-overlayed-view-7-rUB3vD.d.cts → with-overlayed-view-CC0_ocy-.d.cts} +1 -1
- package/dist/{with-overlayed-view-ByyhHdVr.d.ts → with-overlayed-view-eDvMs6LO.d.ts} +1 -1
- package/package.json +3 -3
- package/dist/chunk-3EWA37FV.js.map +0 -1
- package/dist/chunk-ACKFRSAH.js.map +0 -1
- package/dist/chunk-KGCORI4L.js.map +0 -1
- package/dist/chunk-TV3YZ35S.js +0 -90
- package/dist/chunk-TV3YZ35S.js.map +0 -1
- package/dist/chunk-ZWTNWAO4.js.map +0 -1
- /package/dist/{chunk-UWNYBOOO.js.map → chunk-C5T5AFWN.js.map} +0 -0
- /package/dist/{chunk-YNTBADIY.js.map → chunk-CZI2A4MQ.js.map} +0 -0
- /package/dist/{chunk-NP6EZT44.js.map → chunk-IQLVUT37.js.map} +0 -0
- /package/dist/{chunk-4PEFEETV.js.map → chunk-KIP6JLTF.js.map} +0 -0
- /package/dist/{chunk-WIBHRONM.js.map → chunk-XWH4MXIU.js.map} +0 -0
- /package/dist/{executor-723ZP6TH.js.map → executor-HSSRXDOB.js.map} +0 -0
- /package/dist/{noydb-VZ4JVW55.js.map → noydb-GZGFBA4E.js.map} +0 -0
- /package/dist/{stale-7FRJVHN6.js.map → stale-JH67FU57.js.map} +0 -0
- /package/dist/{vault-group-W7QC4UYW.js.map → vault-group-KOM7QRJG.js.map} +0 -0
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
|
-
MoneyPrecisionError,
|
|
3
|
-
formatScaledInt,
|
|
4
|
-
parseToScaledInt,
|
|
5
2
|
wrapMoneyReducers
|
|
6
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3EWXMOK3.js";
|
|
7
4
|
import {
|
|
5
|
+
MoneyPrecisionError,
|
|
8
6
|
evaluateClause,
|
|
7
|
+
formatScaledInt,
|
|
8
|
+
hasFnClause,
|
|
9
|
+
moneyFieldClause,
|
|
10
|
+
parseToScaledInt,
|
|
9
11
|
readPath
|
|
10
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-CJORTUJ2.js";
|
|
11
13
|
import {
|
|
12
14
|
CrossJoinSourceUnknownError,
|
|
13
15
|
CrossJoinTooLargeError,
|
|
14
16
|
DanglingReferenceError,
|
|
15
|
-
JoinTooLargeError
|
|
17
|
+
JoinTooLargeError,
|
|
18
|
+
ValidationError
|
|
16
19
|
} from "./chunk-535SSHBS.js";
|
|
17
20
|
|
|
18
21
|
// src/query/join.ts
|
|
@@ -260,6 +263,108 @@ var NO_AGGREGATE = {
|
|
|
260
263
|
}
|
|
261
264
|
};
|
|
262
265
|
|
|
266
|
+
// src/money/paths.ts
|
|
267
|
+
var SEGMENT_RE = /^(\*|[^.[\]*]+)(\[\])?$/;
|
|
268
|
+
var parseCache = /* @__PURE__ */ new Map();
|
|
269
|
+
function parseMoneyPath(path) {
|
|
270
|
+
const cached = parseCache.get(path);
|
|
271
|
+
if (cached) return cached;
|
|
272
|
+
if (typeof path !== "string" || path.length === 0) {
|
|
273
|
+
throw new ValidationError("moneyFields: path must be a non-empty string");
|
|
274
|
+
}
|
|
275
|
+
const segments = [];
|
|
276
|
+
for (const part of path.split(".")) {
|
|
277
|
+
const m = SEGMENT_RE.exec(part);
|
|
278
|
+
if (!m) {
|
|
279
|
+
throw new ValidationError(
|
|
280
|
+
`moneyFields: invalid path "${path}" \u2014 segment "${part}" must be a key, "key[]", "*", or "*[]"`
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
const array = m[2] === "[]";
|
|
284
|
+
segments.push(
|
|
285
|
+
m[1] === "*" ? { kind: "wildcard", array } : { kind: "key", key: m[1], array }
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
parseCache.set(path, segments);
|
|
289
|
+
return segments;
|
|
290
|
+
}
|
|
291
|
+
function isSimpleMoneyPath(path) {
|
|
292
|
+
return !path.includes(".") && !path.includes("[") && !path.includes("*");
|
|
293
|
+
}
|
|
294
|
+
function validateMoneyFieldPaths(moneyFields) {
|
|
295
|
+
for (const path of Object.keys(moneyFields)) parseMoneyPath(path);
|
|
296
|
+
}
|
|
297
|
+
function transformAtMoneyPath(node, path, segments, index, visit, lenient) {
|
|
298
|
+
if (node === null || node === void 0) return node;
|
|
299
|
+
const seg = segments[index];
|
|
300
|
+
const last = index === segments.length - 1;
|
|
301
|
+
if (seg.kind === "key") {
|
|
302
|
+
if (typeof node !== "object" || Array.isArray(node)) {
|
|
303
|
+
if (lenient) return node;
|
|
304
|
+
throw new ValidationError(
|
|
305
|
+
`moneyFields: path "${path}" expected an object at segment "${seg.key}", got ${Array.isArray(node) ? "an array" : typeof node}`
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
const obj2 = node;
|
|
309
|
+
if (!(seg.key in obj2) || obj2[seg.key] === null || obj2[seg.key] === void 0) return node;
|
|
310
|
+
if (seg.array) {
|
|
311
|
+
const arr = obj2[seg.key];
|
|
312
|
+
if (!Array.isArray(arr)) {
|
|
313
|
+
if (lenient) return node;
|
|
314
|
+
throw new ValidationError(
|
|
315
|
+
`moneyFields: path "${path}" declares "${seg.key}[]" but the value is not an array`
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
const cloned = [...arr];
|
|
319
|
+
if (last) {
|
|
320
|
+
for (let i = 0; i < cloned.length; i++) visit(cloned, i);
|
|
321
|
+
} else {
|
|
322
|
+
for (let i = 0; i < cloned.length; i++) {
|
|
323
|
+
cloned[i] = transformAtMoneyPath(cloned[i], path, segments, index + 1, visit, lenient);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return { ...obj2, [seg.key]: cloned };
|
|
327
|
+
}
|
|
328
|
+
const clone2 = { ...obj2 };
|
|
329
|
+
if (last) {
|
|
330
|
+
visit(clone2, seg.key);
|
|
331
|
+
} else {
|
|
332
|
+
clone2[seg.key] = transformAtMoneyPath(clone2[seg.key], path, segments, index + 1, visit, lenient);
|
|
333
|
+
}
|
|
334
|
+
return clone2;
|
|
335
|
+
}
|
|
336
|
+
if (seg.array) {
|
|
337
|
+
if (!Array.isArray(node)) {
|
|
338
|
+
if (lenient) return node;
|
|
339
|
+
throw new ValidationError(`moneyFields: path "${path}" declares "*[]" but the value is not an array`);
|
|
340
|
+
}
|
|
341
|
+
const cloned = [...node];
|
|
342
|
+
if (last) {
|
|
343
|
+
for (let i = 0; i < cloned.length; i++) visit(cloned, i);
|
|
344
|
+
} else {
|
|
345
|
+
for (let i = 0; i < cloned.length; i++) {
|
|
346
|
+
cloned[i] = transformAtMoneyPath(cloned[i], path, segments, index + 1, visit, lenient);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return cloned;
|
|
350
|
+
}
|
|
351
|
+
if (typeof node !== "object" || Array.isArray(node)) {
|
|
352
|
+
if (lenient) return node;
|
|
353
|
+
throw new ValidationError(
|
|
354
|
+
`moneyFields: path "${path}" applies "*" to a non-object (${Array.isArray(node) ? 'array \u2014 use "*[]"' : typeof node})`
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
const obj = node;
|
|
358
|
+
const clone = { ...obj };
|
|
359
|
+
for (const key of Object.keys(obj)) {
|
|
360
|
+
const v = clone[key];
|
|
361
|
+
if (v === null || v === void 0) continue;
|
|
362
|
+
if (last) visit(clone, key);
|
|
363
|
+
else clone[key] = transformAtMoneyPath(v, path, segments, index + 1, visit, lenient);
|
|
364
|
+
}
|
|
365
|
+
return clone;
|
|
366
|
+
}
|
|
367
|
+
|
|
263
368
|
// src/money/normalize.ts
|
|
264
369
|
function isMoneyValueObject(v) {
|
|
265
370
|
return typeof v === "object" && v !== null && "currency" in v;
|
|
@@ -272,33 +377,68 @@ function quantizeAmount(field, input, scale, rounding) {
|
|
|
272
377
|
}
|
|
273
378
|
return r.value.toString();
|
|
274
379
|
}
|
|
380
|
+
function canonicalizeStoredMoney(record, moneyFields) {
|
|
381
|
+
if (record === null || record === void 0) return record;
|
|
382
|
+
if (!moneyFields || Object.keys(moneyFields).length === 0) return record;
|
|
383
|
+
return decodeMoneyFields(record, moneyFields, "raw");
|
|
384
|
+
}
|
|
385
|
+
function canonicalizeIncomingMoney(record, moneyFields) {
|
|
386
|
+
if (!moneyFields || Object.keys(moneyFields).length === 0) return record;
|
|
387
|
+
try {
|
|
388
|
+
return decodeMoneyFields(
|
|
389
|
+
quantizeMoneyFields(record, moneyFields),
|
|
390
|
+
moneyFields,
|
|
391
|
+
"raw"
|
|
392
|
+
);
|
|
393
|
+
} catch {
|
|
394
|
+
return record;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
function quantizeValue(field, raw, desc) {
|
|
398
|
+
if (desc.mode === "fixed") {
|
|
399
|
+
const currency2 = desc.fixedCurrency;
|
|
400
|
+
return quantizeAmount(field, raw, desc.scaleFor(currency2), desc.rounding);
|
|
401
|
+
}
|
|
402
|
+
let amount;
|
|
403
|
+
let currency;
|
|
404
|
+
if (isMoneyValueObject(raw)) {
|
|
405
|
+
currency = String(raw.currency);
|
|
406
|
+
amount = raw.amount;
|
|
407
|
+
} else {
|
|
408
|
+
const sole = desc.soleCurrency();
|
|
409
|
+
if (sole === void 0) {
|
|
410
|
+
throw new TypeError(
|
|
411
|
+
`money: field "${field}" is multi-currency \u2014 write { amount, currency }, not a bare amount`
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
currency = sole;
|
|
415
|
+
amount = raw;
|
|
416
|
+
}
|
|
417
|
+
const scale = desc.scaleFor(currency);
|
|
418
|
+
return { amount: quantizeAmount(field, amount, scale, desc.rounding), currency };
|
|
419
|
+
}
|
|
275
420
|
function quantizeMoneyFields(record, moneyFields) {
|
|
276
|
-
|
|
277
|
-
for (const [
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
out[field] = quantizeAmount(field, raw, desc.scaleFor(currency2), desc.rounding);
|
|
421
|
+
let out = { ...record };
|
|
422
|
+
for (const [path, desc] of Object.entries(moneyFields)) {
|
|
423
|
+
if (isSimpleMoneyPath(path)) {
|
|
424
|
+
const raw = out[path];
|
|
425
|
+
if (raw === null || raw === void 0) continue;
|
|
426
|
+
out[path] = quantizeValue(path, raw, desc);
|
|
283
427
|
continue;
|
|
284
428
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
amount = raw;
|
|
299
|
-
}
|
|
300
|
-
const scale = desc.scaleFor(currency);
|
|
301
|
-
out[field] = { amount: quantizeAmount(field, amount, scale, desc.rounding), currency };
|
|
429
|
+
out = transformAtMoneyPath(
|
|
430
|
+
out,
|
|
431
|
+
path,
|
|
432
|
+
parseMoneyPath(path),
|
|
433
|
+
0,
|
|
434
|
+
(container, key) => {
|
|
435
|
+
const raw = container[key];
|
|
436
|
+
if (raw === null || raw === void 0) return;
|
|
437
|
+
container[key] = quantizeValue(path, raw, desc);
|
|
438
|
+
},
|
|
439
|
+
/* lenient */
|
|
440
|
+
false
|
|
441
|
+
);
|
|
302
442
|
}
|
|
303
443
|
return out;
|
|
304
444
|
}
|
|
@@ -311,33 +451,70 @@ function formatCurrency(decimal, currency, scale, locale) {
|
|
|
311
451
|
});
|
|
312
452
|
return fmt.format(decimal);
|
|
313
453
|
}
|
|
454
|
+
function decodeValue(stored, desc) {
|
|
455
|
+
let currency;
|
|
456
|
+
let scaledIntString;
|
|
457
|
+
if (desc.mode === "fixed") {
|
|
458
|
+
if (typeof stored !== "string" && typeof stored !== "number") return null;
|
|
459
|
+
currency = desc.fixedCurrency;
|
|
460
|
+
scaledIntString = String(stored);
|
|
461
|
+
} else {
|
|
462
|
+
if (!isMoneyValueObject(stored)) return null;
|
|
463
|
+
const amount = stored.amount;
|
|
464
|
+
if (typeof stored.currency !== "string" || typeof amount !== "string" && typeof amount !== "number") return null;
|
|
465
|
+
currency = stored.currency;
|
|
466
|
+
scaledIntString = String(amount);
|
|
467
|
+
}
|
|
468
|
+
const scale = desc.scaleFor(currency);
|
|
469
|
+
let decimal;
|
|
470
|
+
try {
|
|
471
|
+
decimal = formatScaledInt(BigInt(scaledIntString), scale);
|
|
472
|
+
} catch {
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
return {
|
|
476
|
+
decoded: desc.mode === "fixed" ? decimal : { amount: decimal, currency },
|
|
477
|
+
decimal,
|
|
478
|
+
currency,
|
|
479
|
+
scale
|
|
480
|
+
};
|
|
481
|
+
}
|
|
314
482
|
function decodeMoneyFields(record, moneyFields, locale) {
|
|
315
|
-
|
|
483
|
+
let out = { ...record };
|
|
316
484
|
const format = locale !== "raw";
|
|
317
485
|
const fmtLocale = typeof locale === "string" && locale !== "raw" ? locale : "en-US";
|
|
318
|
-
for (const [
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
if (typeof stored.currency !== "string" || typeof amount !== "string" && typeof amount !== "number") continue;
|
|
331
|
-
currency = stored.currency;
|
|
332
|
-
scaledIntString = String(amount);
|
|
333
|
-
}
|
|
334
|
-
const scale = desc.scaleFor(currency);
|
|
335
|
-
const decimal = formatScaledInt(BigInt(scaledIntString), scale);
|
|
336
|
-
out[field] = desc.mode === "fixed" ? decimal : { amount: decimal, currency };
|
|
337
|
-
if (format) {
|
|
338
|
-
out[`${field}Formatted`] = formatCurrency(decimal, currency, scale, fmtLocale);
|
|
339
|
-
out[`${field}Number`] = Number(decimal);
|
|
486
|
+
for (const [path, desc] of Object.entries(moneyFields)) {
|
|
487
|
+
if (isSimpleMoneyPath(path)) {
|
|
488
|
+
const stored = out[path];
|
|
489
|
+
if (stored === null || stored === void 0) continue;
|
|
490
|
+
const r = decodeValue(stored, desc);
|
|
491
|
+
if (r === null) continue;
|
|
492
|
+
out[path] = r.decoded;
|
|
493
|
+
if (format) {
|
|
494
|
+
out[`${path}Formatted`] = formatCurrency(r.decimal, r.currency, r.scale, fmtLocale);
|
|
495
|
+
out[`${path}Number`] = Number(r.decimal);
|
|
496
|
+
}
|
|
497
|
+
continue;
|
|
340
498
|
}
|
|
499
|
+
out = transformAtMoneyPath(
|
|
500
|
+
out,
|
|
501
|
+
path,
|
|
502
|
+
parseMoneyPath(path),
|
|
503
|
+
0,
|
|
504
|
+
(container, key) => {
|
|
505
|
+
const stored = container[key];
|
|
506
|
+
if (stored === null || stored === void 0) return;
|
|
507
|
+
const r = decodeValue(stored, desc);
|
|
508
|
+
if (r === null) return;
|
|
509
|
+
container[key] = r.decoded;
|
|
510
|
+
if (format && typeof key === "string" && !Array.isArray(container)) {
|
|
511
|
+
container[`${key}Formatted`] = formatCurrency(r.decimal, r.currency, r.scale, fmtLocale);
|
|
512
|
+
container[`${key}Number`] = Number(r.decimal);
|
|
513
|
+
}
|
|
514
|
+
},
|
|
515
|
+
/* lenient */
|
|
516
|
+
true
|
|
517
|
+
);
|
|
341
518
|
}
|
|
342
519
|
return out;
|
|
343
520
|
}
|
|
@@ -434,9 +611,18 @@ var Query = class _Query {
|
|
|
434
611
|
this.predicates
|
|
435
612
|
);
|
|
436
613
|
}
|
|
437
|
-
/**
|
|
614
|
+
/**
|
|
615
|
+
* Add a field comparison. Multiple where() calls are AND-combined.
|
|
616
|
+
*
|
|
617
|
+
* A declared money field compares in MAJOR units (#336): the operand
|
|
618
|
+
* (`10000`, `'10000.00'`, or `{ amount, currency }` in multi mode) is
|
|
619
|
+
* quantized into stored scaled-int space at build time and evaluated
|
|
620
|
+
* BigInt-exact per record. A malformed operand or a string operator
|
|
621
|
+
* (`contains`/`startsWith`) throws here, at the call site.
|
|
622
|
+
*/
|
|
438
623
|
where(field, op, value) {
|
|
439
|
-
const
|
|
624
|
+
const desc = this.source.moneyFields?.[field];
|
|
625
|
+
const clause = desc ? moneyFieldClause(field, op, value, desc) : { type: "field", field, op, value };
|
|
440
626
|
return new _Query(
|
|
441
627
|
this.source,
|
|
442
628
|
{ ...this.plan, clauses: [...this.plan.clauses, clause] },
|
|
@@ -762,7 +948,7 @@ var Query = class _Query {
|
|
|
762
948
|
}
|
|
763
949
|
const { candidates, remainingClauses } = candidateRecords(this.source, this.plan.clauses);
|
|
764
950
|
if (remainingClauses.length === 0) return candidates.length;
|
|
765
|
-
return filterRecords(candidates, remainingClauses).length;
|
|
951
|
+
return filterRecords(candidates, remainingClauses, fnViewDecoder(this.source)).length;
|
|
766
952
|
}
|
|
767
953
|
/**
|
|
768
954
|
* Reduce the matching records through a named set of reducers.
|
|
@@ -819,7 +1005,7 @@ var Query = class _Query {
|
|
|
819
1005
|
return executeClausePipeline(source, clauses, joinCtx);
|
|
820
1006
|
}
|
|
821
1007
|
const { candidates, remainingClauses } = candidateRecords(source, clauses);
|
|
822
|
-
return remainingClauses.length === 0 ? candidates : filterRecords(candidates, remainingClauses);
|
|
1008
|
+
return remainingClauses.length === 0 ? candidates : filterRecords(candidates, remainingClauses, fnViewDecoder(source));
|
|
823
1009
|
};
|
|
824
1010
|
const upstreams = [];
|
|
825
1011
|
if (source.subscribe) {
|
|
@@ -842,7 +1028,7 @@ var Query = class _Query {
|
|
|
842
1028
|
return executeClausePipeline(source, clauses, joinCtx);
|
|
843
1029
|
}
|
|
844
1030
|
const { candidates, remainingClauses } = candidateRecords(source, clauses);
|
|
845
|
-
return remainingClauses.length === 0 ? candidates : filterRecords(candidates, remainingClauses);
|
|
1031
|
+
return remainingClauses.length === 0 ? candidates : filterRecords(candidates, remainingClauses, fnViewDecoder(source));
|
|
846
1032
|
};
|
|
847
1033
|
const upstreams = [];
|
|
848
1034
|
if (source.subscribe) {
|
|
@@ -994,7 +1180,7 @@ function executePlanWithSource(source, plan, joinContext) {
|
|
|
994
1180
|
result = executeClausePipeline(source, plan.clauses, joinContext);
|
|
995
1181
|
} else {
|
|
996
1182
|
const { candidates, remainingClauses } = candidateRecords(source, plan.clauses);
|
|
997
|
-
result = remainingClauses.length === 0 ? [...candidates] : filterRecords(candidates, remainingClauses);
|
|
1183
|
+
result = remainingClauses.length === 0 ? [...candidates] : filterRecords(candidates, remainingClauses, fnViewDecoder(source));
|
|
998
1184
|
}
|
|
999
1185
|
if (plan.orderBy.length > 0) {
|
|
1000
1186
|
result = sortRecords(result, plan.orderBy);
|
|
@@ -1017,6 +1203,7 @@ function candidateRecords(source, clauses) {
|
|
|
1017
1203
|
const clause = clauses[i];
|
|
1018
1204
|
if (clause.type !== "field") continue;
|
|
1019
1205
|
if (!indexes.has(clause.field)) continue;
|
|
1206
|
+
if (clause.money?.mode === "multi") continue;
|
|
1020
1207
|
let ids = null;
|
|
1021
1208
|
if (clause.op === "==") {
|
|
1022
1209
|
ids = indexes.lookupEqual(clause.field, clause.value);
|
|
@@ -1062,13 +1249,20 @@ function executePlan(records, plan) {
|
|
|
1062
1249
|
}
|
|
1063
1250
|
return result;
|
|
1064
1251
|
}
|
|
1065
|
-
function
|
|
1252
|
+
function fnViewDecoder(source) {
|
|
1253
|
+
const mf = source.moneyFields;
|
|
1254
|
+
if (!mf || Object.keys(mf).length === 0) return void 0;
|
|
1255
|
+
return (r) => decodeMoneyFields(r, mf, "raw");
|
|
1256
|
+
}
|
|
1257
|
+
function filterRecords(records, clauses, decodeForFns) {
|
|
1066
1258
|
if (clauses.length === 0) return [...records];
|
|
1259
|
+
const needsFnView = decodeForFns !== void 0 && hasFnClause(clauses);
|
|
1067
1260
|
const out = [];
|
|
1068
1261
|
for (const r of records) {
|
|
1262
|
+
const fnView = needsFnView ? decodeForFns(r) : void 0;
|
|
1069
1263
|
let matches = true;
|
|
1070
1264
|
for (const clause of clauses) {
|
|
1071
|
-
if (!evaluateClause(r, clause)) {
|
|
1265
|
+
if (!evaluateClause(r, clause, fnView)) {
|
|
1072
1266
|
matches = false;
|
|
1073
1267
|
break;
|
|
1074
1268
|
}
|
|
@@ -1080,10 +1274,11 @@ function filterRecords(records, clauses) {
|
|
|
1080
1274
|
function executeClausePipeline(source, clauses, joinContext) {
|
|
1081
1275
|
let rel = [...source.snapshot()];
|
|
1082
1276
|
let filterBatch = [];
|
|
1277
|
+
const decodeForFns = fnViewDecoder(source);
|
|
1083
1278
|
for (const clause of clauses) {
|
|
1084
1279
|
if (clause.type === "crossJoin") {
|
|
1085
1280
|
if (filterBatch.length > 0) {
|
|
1086
|
-
rel = filterRecords(rel, filterBatch);
|
|
1281
|
+
rel = filterRecords(rel, filterBatch, decodeForFns);
|
|
1087
1282
|
filterBatch = [];
|
|
1088
1283
|
}
|
|
1089
1284
|
const rightSource = joinContext.resolveSource(clause.target);
|
|
@@ -1096,7 +1291,7 @@ function executeClausePipeline(source, clauses, joinContext) {
|
|
|
1096
1291
|
}
|
|
1097
1292
|
}
|
|
1098
1293
|
if (filterBatch.length > 0) {
|
|
1099
|
-
rel = filterRecords(rel, filterBatch);
|
|
1294
|
+
rel = filterRecords(rel, filterBatch, decodeForFns);
|
|
1100
1295
|
}
|
|
1101
1296
|
return rel;
|
|
1102
1297
|
}
|
|
@@ -1331,7 +1526,8 @@ var ScanBuilder = class _ScanBuilder {
|
|
|
1331
1526
|
* evaluates clauses per record in O(1) per clause.
|
|
1332
1527
|
*/
|
|
1333
1528
|
where(field, op, value) {
|
|
1334
|
-
const
|
|
1529
|
+
const desc = this.moneyFields?.[field];
|
|
1530
|
+
const clause = desc ? moneyFieldClause(field, op, value, desc) : { type: "field", field, op, value };
|
|
1335
1531
|
return new _ScanBuilder(
|
|
1336
1532
|
this.pageProvider,
|
|
1337
1533
|
this.pageSize,
|
|
@@ -1677,8 +1873,9 @@ var ScanBuilder = class _ScanBuilder {
|
|
|
1677
1873
|
*/
|
|
1678
1874
|
recordMatches(record) {
|
|
1679
1875
|
if (this.clauses.length === 0) return true;
|
|
1876
|
+
const fnView = this.moneyFields && Object.keys(this.moneyFields).length > 0 && hasFnClause(this.clauses) ? this.decodeMoney(record) : void 0;
|
|
1680
1877
|
for (const clause of this.clauses) {
|
|
1681
|
-
if (!evaluateClause(record, clause)) return false;
|
|
1878
|
+
if (!evaluateClause(record, clause, fnView)) return false;
|
|
1682
1879
|
}
|
|
1683
1880
|
return true;
|
|
1684
1881
|
}
|
|
@@ -1691,6 +1888,9 @@ function coerceRefKey2(value) {
|
|
|
1691
1888
|
}
|
|
1692
1889
|
|
|
1693
1890
|
export {
|
|
1891
|
+
validateMoneyFieldPaths,
|
|
1892
|
+
canonicalizeStoredMoney,
|
|
1893
|
+
canonicalizeIncomingMoney,
|
|
1694
1894
|
quantizeMoneyFields,
|
|
1695
1895
|
decodeMoneyFields,
|
|
1696
1896
|
DEFAULT_JOIN_MAX_ROWS,
|
|
@@ -1703,4 +1903,4 @@ export {
|
|
|
1703
1903
|
executePlan,
|
|
1704
1904
|
ScanBuilder
|
|
1705
1905
|
};
|
|
1706
|
-
//# sourceMappingURL=chunk-
|
|
1906
|
+
//# sourceMappingURL=chunk-EYVQHAGH.js.map
|