@arcote.tech/arc-adapter-db-postgres 0.7.26 → 0.7.28
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/index.js +295 -82
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1779,9 +1779,21 @@ class LocalEventPublisher {
|
|
|
1779
1779
|
views = [];
|
|
1780
1780
|
syncCallback;
|
|
1781
1781
|
subscribers = new Map;
|
|
1782
|
+
pending = new Set;
|
|
1782
1783
|
constructor(dataStorage) {
|
|
1783
1784
|
this.dataStorage = dataStorage;
|
|
1784
1785
|
}
|
|
1786
|
+
track(work) {
|
|
1787
|
+
const wrapped = Promise.resolve(work).catch(() => {}).finally(() => {
|
|
1788
|
+
this.pending.delete(wrapped);
|
|
1789
|
+
});
|
|
1790
|
+
this.pending.add(wrapped);
|
|
1791
|
+
}
|
|
1792
|
+
async whenIdle() {
|
|
1793
|
+
while (this.pending.size > 0) {
|
|
1794
|
+
await Promise.all([...this.pending]);
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1785
1797
|
onPublish(callback) {
|
|
1786
1798
|
this.syncCallback = callback;
|
|
1787
1799
|
}
|
|
@@ -1817,9 +1829,12 @@ class LocalEventPublisher {
|
|
|
1817
1829
|
store: EVENT_TABLES.events,
|
|
1818
1830
|
changes: [{ type: "set", data: storedEvent }]
|
|
1819
1831
|
});
|
|
1820
|
-
|
|
1832
|
+
const tagFields = event.definition?.tagFields ?? [];
|
|
1833
|
+
if (tagFields.length > 0 && event.payload && typeof event.payload === "object") {
|
|
1834
|
+
const payload = event.payload;
|
|
1821
1835
|
const tagChanges = [];
|
|
1822
|
-
for (const
|
|
1836
|
+
for (const key of tagFields) {
|
|
1837
|
+
const value = payload[key];
|
|
1823
1838
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1824
1839
|
tagChanges.push({
|
|
1825
1840
|
type: "set",
|
|
@@ -1977,6 +1992,47 @@ class LocalEventPublisher {
|
|
|
1977
1992
|
return allViewChanges;
|
|
1978
1993
|
}
|
|
1979
1994
|
}
|
|
1995
|
+
function murmurHash(key, seed = 0) {
|
|
1996
|
+
let remainder, bytes, h1, h1b, c1, c2, k1, i;
|
|
1997
|
+
remainder = key.length & 3;
|
|
1998
|
+
bytes = key.length - remainder;
|
|
1999
|
+
h1 = seed;
|
|
2000
|
+
c1 = 3432918353;
|
|
2001
|
+
c2 = 461845907;
|
|
2002
|
+
i = 0;
|
|
2003
|
+
while (i < bytes) {
|
|
2004
|
+
k1 = key.charCodeAt(i) & 255 | (key.charCodeAt(++i) & 255) << 8 | (key.charCodeAt(++i) & 255) << 16 | (key.charCodeAt(++i) & 255) << 24;
|
|
2005
|
+
++i;
|
|
2006
|
+
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
2007
|
+
k1 = k1 << 15 | k1 >>> 17;
|
|
2008
|
+
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
2009
|
+
h1 ^= k1;
|
|
2010
|
+
h1 = h1 << 13 | h1 >>> 19;
|
|
2011
|
+
h1b = (h1 & 65535) * 5 + (((h1 >>> 16) * 5 & 65535) << 16) & 4294967295;
|
|
2012
|
+
h1 = (h1b & 65535) + 27492 + (((h1b >>> 16) + 58964 & 65535) << 16);
|
|
2013
|
+
}
|
|
2014
|
+
k1 = 0;
|
|
2015
|
+
if (remainder >= 3) {
|
|
2016
|
+
k1 ^= (key.charCodeAt(i + 2) & 255) << 16;
|
|
2017
|
+
}
|
|
2018
|
+
if (remainder >= 2) {
|
|
2019
|
+
k1 ^= (key.charCodeAt(i + 1) & 255) << 8;
|
|
2020
|
+
}
|
|
2021
|
+
if (remainder >= 1) {
|
|
2022
|
+
k1 ^= key.charCodeAt(i) & 255;
|
|
2023
|
+
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
2024
|
+
k1 = k1 << 15 | k1 >>> 17;
|
|
2025
|
+
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
2026
|
+
h1 ^= k1;
|
|
2027
|
+
}
|
|
2028
|
+
h1 ^= key.length;
|
|
2029
|
+
h1 ^= h1 >>> 16;
|
|
2030
|
+
h1 = (h1 & 65535) * 2246822507 + (((h1 >>> 16) * 2246822507 & 65535) << 16) & 4294967295;
|
|
2031
|
+
h1 ^= h1 >>> 13;
|
|
2032
|
+
h1 = (h1 & 65535) * 3266489909 + (((h1 >>> 16) * 3266489909 & 65535) << 16) & 4294967295;
|
|
2033
|
+
h1 ^= h1 >>> 16;
|
|
2034
|
+
return h1 >>> 0;
|
|
2035
|
+
}
|
|
1980
2036
|
class ArcOptional {
|
|
1981
2037
|
parent;
|
|
1982
2038
|
constructor(parent) {
|
|
@@ -2002,6 +2058,11 @@ class ArcOptional {
|
|
|
2002
2058
|
return false;
|
|
2003
2059
|
return this.parent.validate(value);
|
|
2004
2060
|
}
|
|
2061
|
+
coerce(value) {
|
|
2062
|
+
if (value == null)
|
|
2063
|
+
return;
|
|
2064
|
+
return this.parent.coerce(value);
|
|
2065
|
+
}
|
|
2005
2066
|
toJsonSchema() {
|
|
2006
2067
|
const parentSchema = this.parent.toJsonSchema?.() ?? {};
|
|
2007
2068
|
return {
|
|
@@ -2048,6 +2109,9 @@ class ArcBranded {
|
|
|
2048
2109
|
validate(value) {
|
|
2049
2110
|
return this.parent.validate(value);
|
|
2050
2111
|
}
|
|
2112
|
+
coerce(value) {
|
|
2113
|
+
return this.parent.coerce(value);
|
|
2114
|
+
}
|
|
2051
2115
|
toJsonSchema() {
|
|
2052
2116
|
return this.parent.toJsonSchema?.() ?? {};
|
|
2053
2117
|
}
|
|
@@ -2068,7 +2132,14 @@ class ArcDefault {
|
|
|
2068
2132
|
this.defaultValueOrCallback = defaultValueOrCallback;
|
|
2069
2133
|
}
|
|
2070
2134
|
validate(value) {
|
|
2071
|
-
|
|
2135
|
+
if (value === undefined || value === null)
|
|
2136
|
+
return false;
|
|
2137
|
+
return this.parent.validate(value);
|
|
2138
|
+
}
|
|
2139
|
+
coerce(value) {
|
|
2140
|
+
if (value === undefined || value === null)
|
|
2141
|
+
return;
|
|
2142
|
+
return this.parent.coerce(value);
|
|
2072
2143
|
}
|
|
2073
2144
|
parse(value) {
|
|
2074
2145
|
if (value)
|
|
@@ -2152,6 +2223,9 @@ class ArcAbstract {
|
|
|
2152
2223
|
}
|
|
2153
2224
|
return false;
|
|
2154
2225
|
}
|
|
2226
|
+
coerce(value) {
|
|
2227
|
+
return this.validate(value) ? undefined : value;
|
|
2228
|
+
}
|
|
2155
2229
|
pipeValidation(name, validator) {
|
|
2156
2230
|
const newInstance = this.clone();
|
|
2157
2231
|
newInstance.validations = [...this.validations, { name, validator }];
|
|
@@ -2289,6 +2363,17 @@ class ArcArray extends ArcAbstract {
|
|
|
2289
2363
|
return { msg: "array is empty" };
|
|
2290
2364
|
});
|
|
2291
2365
|
}
|
|
2366
|
+
coerce(value) {
|
|
2367
|
+
if (!Array.isArray(value))
|
|
2368
|
+
return;
|
|
2369
|
+
const out = [];
|
|
2370
|
+
for (const item of value) {
|
|
2371
|
+
const coerced = this.parent.coerce(item);
|
|
2372
|
+
if (coerced !== undefined)
|
|
2373
|
+
out.push(coerced);
|
|
2374
|
+
}
|
|
2375
|
+
return this.validate(out) ? undefined : out;
|
|
2376
|
+
}
|
|
2292
2377
|
parse(value) {
|
|
2293
2378
|
return value.map((v) => this.parent.parse(v));
|
|
2294
2379
|
}
|
|
@@ -2360,6 +2445,19 @@ class ArcObject extends ArcAbstract {
|
|
|
2360
2445
|
]);
|
|
2361
2446
|
this.rawShape = rawShape;
|
|
2362
2447
|
}
|
|
2448
|
+
coerce(value) {
|
|
2449
|
+
if (value == null || typeof value !== "object" || Array.isArray(value)) {
|
|
2450
|
+
return;
|
|
2451
|
+
}
|
|
2452
|
+
const src = value;
|
|
2453
|
+
const out = {};
|
|
2454
|
+
for (const [key, element] of Object.entries(this.rawShape)) {
|
|
2455
|
+
const coerced = element.coerce(src[key]);
|
|
2456
|
+
if (coerced !== undefined)
|
|
2457
|
+
out[key] = coerced;
|
|
2458
|
+
}
|
|
2459
|
+
return this.validate(out) ? undefined : out;
|
|
2460
|
+
}
|
|
2363
2461
|
parse(value) {
|
|
2364
2462
|
return Object.entries(this.rawShape).reduce((acc, [key, element]) => {
|
|
2365
2463
|
acc[key] = element.parse(value[key]);
|
|
@@ -2594,6 +2692,51 @@ class ScopedDataStorage extends DataStorage {
|
|
|
2594
2692
|
return this.#inner.getReadWriteTransaction();
|
|
2595
2693
|
}
|
|
2596
2694
|
}
|
|
2695
|
+
class ArcAuthenticationError extends Error {
|
|
2696
|
+
arcCode = "AUTHENTICATION";
|
|
2697
|
+
constructor(message = "Authentication required") {
|
|
2698
|
+
super(message);
|
|
2699
|
+
this.name = "ArcAuthenticationError";
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
|
|
2703
|
+
class ArcAuthorizationError extends Error {
|
|
2704
|
+
arcCode = "AUTHORIZATION";
|
|
2705
|
+
constructor(message = "Forbidden") {
|
|
2706
|
+
super(message);
|
|
2707
|
+
this.name = "ArcAuthorizationError";
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
function collectFieldPaths(errors, prefix = "") {
|
|
2711
|
+
if (!errors || typeof errors !== "object")
|
|
2712
|
+
return [];
|
|
2713
|
+
const schema = errors.schema;
|
|
2714
|
+
if (!schema || typeof schema !== "object")
|
|
2715
|
+
return [];
|
|
2716
|
+
const out = [];
|
|
2717
|
+
for (const [field, fieldError] of Object.entries(schema)) {
|
|
2718
|
+
if (!fieldError)
|
|
2719
|
+
continue;
|
|
2720
|
+
const path = prefix ? `${prefix}.${field}` : field;
|
|
2721
|
+
const nested = collectFieldPaths(fieldError, path);
|
|
2722
|
+
if (nested.length > 0)
|
|
2723
|
+
out.push(...nested);
|
|
2724
|
+
else
|
|
2725
|
+
out.push(path);
|
|
2726
|
+
}
|
|
2727
|
+
return out;
|
|
2728
|
+
}
|
|
2729
|
+
|
|
2730
|
+
class ArcValidationError extends Error {
|
|
2731
|
+
arcCode = "VALIDATION";
|
|
2732
|
+
fields;
|
|
2733
|
+
constructor(errors, message = "Invalid parameters") {
|
|
2734
|
+
super(message);
|
|
2735
|
+
this.name = "ArcValidationError";
|
|
2736
|
+
const paths = collectFieldPaths(errors);
|
|
2737
|
+
this.fields = paths.length > 0 ? paths : errors && typeof errors === "object" ? Object.keys(errors) : [];
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2597
2740
|
class ArcPrimitive extends ArcAbstract {
|
|
2598
2741
|
serialize(value) {
|
|
2599
2742
|
return value;
|
|
@@ -2766,6 +2909,8 @@ class ArcFragmentBase {
|
|
|
2766
2909
|
class ArcContextElement extends ArcFragmentBase {
|
|
2767
2910
|
name;
|
|
2768
2911
|
types = ["context-element"];
|
|
2912
|
+
__contextId;
|
|
2913
|
+
__contextName;
|
|
2769
2914
|
get id() {
|
|
2770
2915
|
return this.name;
|
|
2771
2916
|
}
|
|
@@ -2956,7 +3101,8 @@ class ArcEvent extends ArcContextElement {
|
|
|
2956
3101
|
payload,
|
|
2957
3102
|
id: this.eventId.generate(),
|
|
2958
3103
|
createdAt: new Date,
|
|
2959
|
-
authContext
|
|
3104
|
+
authContext,
|
|
3105
|
+
definition: this
|
|
2960
3106
|
};
|
|
2961
3107
|
await adapters.eventPublisher.publish(event);
|
|
2962
3108
|
}
|
|
@@ -3009,8 +3155,8 @@ class ArcEvent extends ArcContextElement {
|
|
|
3009
3155
|
const tagsSchema = new ArcObject({
|
|
3010
3156
|
_id: new ArcString().primaryKey(),
|
|
3011
3157
|
eventId: new ArcString().index(),
|
|
3012
|
-
tagKey: new ArcString
|
|
3013
|
-
tagValue: new ArcString
|
|
3158
|
+
tagKey: new ArcString,
|
|
3159
|
+
tagValue: new ArcString
|
|
3014
3160
|
});
|
|
3015
3161
|
const syncStatusSchema = new ArcObject({
|
|
3016
3162
|
_id: new ArcString().primaryKey(),
|
|
@@ -3105,6 +3251,27 @@ class ArcFunction {
|
|
|
3105
3251
|
get results() {
|
|
3106
3252
|
return this.data.results;
|
|
3107
3253
|
}
|
|
3254
|
+
validateParams(params) {
|
|
3255
|
+
const schema = this.data.params;
|
|
3256
|
+
if (!schema || typeof schema.validate !== "function")
|
|
3257
|
+
return;
|
|
3258
|
+
const errors = schema.validate(params ?? {});
|
|
3259
|
+
if (errors)
|
|
3260
|
+
throw new ArcValidationError(errors);
|
|
3261
|
+
}
|
|
3262
|
+
async authorize(adapters) {
|
|
3263
|
+
if (!this.hasProtections)
|
|
3264
|
+
return;
|
|
3265
|
+
const decoded = adapters.authAdapter?.getDecoded?.();
|
|
3266
|
+
if (!decoded) {
|
|
3267
|
+
throw new ArcAuthenticationError;
|
|
3268
|
+
}
|
|
3269
|
+
const instances = this.data.protections.filter((p) => p.token?.name === decoded.tokenName).map((p) => p.token.create(decoded.params, adapters));
|
|
3270
|
+
const ok = await this.verifyProtections(instances);
|
|
3271
|
+
if (!ok) {
|
|
3272
|
+
throw new ArcAuthorizationError;
|
|
3273
|
+
}
|
|
3274
|
+
}
|
|
3108
3275
|
async verifyProtections(tokens) {
|
|
3109
3276
|
if (!this.data.protections || this.data.protections.length === 0) {
|
|
3110
3277
|
return true;
|
|
@@ -3265,6 +3432,8 @@ class ArcCommand extends ArcContextElement {
|
|
|
3265
3432
|
if (!this.data.handler) {
|
|
3266
3433
|
throw new Error(`Command "${this.data.name}" has no handler`);
|
|
3267
3434
|
}
|
|
3435
|
+
this.#fn.validateParams(params);
|
|
3436
|
+
await this.#fn.authorize(adapters);
|
|
3268
3437
|
const context2 = this.buildCommandContext(adapters);
|
|
3269
3438
|
return await this.data.handler(context2, params);
|
|
3270
3439
|
}
|
|
@@ -3375,9 +3544,10 @@ class ArcListener extends ArcContextElement {
|
|
|
3375
3544
|
}
|
|
3376
3545
|
}
|
|
3377
3546
|
if (this.data.isAsync) {
|
|
3378
|
-
Promise.resolve(this.data.handler(context2, event2)).catch((error) => {
|
|
3547
|
+
const work = Promise.resolve(this.data.handler(context2, event2)).catch((error) => {
|
|
3379
3548
|
console.error(`Async listener "${this.data.name}" error:`, error);
|
|
3380
3549
|
});
|
|
3550
|
+
adapters.eventPublisher?.track?.(work);
|
|
3381
3551
|
} else {
|
|
3382
3552
|
await this.data.handler(context2, event2);
|
|
3383
3553
|
}
|
|
@@ -3584,48 +3754,6 @@ function deepMerge(target, source) {
|
|
|
3584
3754
|
function isPlainObject(item) {
|
|
3585
3755
|
return item && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && Object.prototype.toString.call(item) === "[object Object]";
|
|
3586
3756
|
}
|
|
3587
|
-
function murmurHash(key, seed = 0) {
|
|
3588
|
-
let remainder, bytes, h1, h1b, c1, c2, k1, i;
|
|
3589
|
-
remainder = key.length & 3;
|
|
3590
|
-
bytes = key.length - remainder;
|
|
3591
|
-
h1 = seed;
|
|
3592
|
-
c1 = 3432918353;
|
|
3593
|
-
c2 = 461845907;
|
|
3594
|
-
i = 0;
|
|
3595
|
-
while (i < bytes) {
|
|
3596
|
-
k1 = key.charCodeAt(i) & 255 | (key.charCodeAt(++i) & 255) << 8 | (key.charCodeAt(++i) & 255) << 16 | (key.charCodeAt(++i) & 255) << 24;
|
|
3597
|
-
++i;
|
|
3598
|
-
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
3599
|
-
k1 = k1 << 15 | k1 >>> 17;
|
|
3600
|
-
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
3601
|
-
h1 ^= k1;
|
|
3602
|
-
h1 = h1 << 13 | h1 >>> 19;
|
|
3603
|
-
h1b = (h1 & 65535) * 5 + (((h1 >>> 16) * 5 & 65535) << 16) & 4294967295;
|
|
3604
|
-
h1 = (h1b & 65535) + 27492 + (((h1b >>> 16) + 58964 & 65535) << 16);
|
|
3605
|
-
}
|
|
3606
|
-
k1 = 0;
|
|
3607
|
-
if (remainder >= 3) {
|
|
3608
|
-
k1 ^= (key.charCodeAt(i + 2) & 255) << 16;
|
|
3609
|
-
}
|
|
3610
|
-
if (remainder >= 2) {
|
|
3611
|
-
k1 ^= (key.charCodeAt(i + 1) & 255) << 8;
|
|
3612
|
-
}
|
|
3613
|
-
if (remainder >= 1) {
|
|
3614
|
-
k1 ^= key.charCodeAt(i) & 255;
|
|
3615
|
-
k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
|
|
3616
|
-
k1 = k1 << 15 | k1 >>> 17;
|
|
3617
|
-
k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
|
|
3618
|
-
h1 ^= k1;
|
|
3619
|
-
}
|
|
3620
|
-
h1 ^= key.length;
|
|
3621
|
-
h1 ^= h1 >>> 16;
|
|
3622
|
-
h1 = (h1 & 65535) * 2246822507 + (((h1 >>> 16) * 2246822507 & 65535) << 16) & 4294967295;
|
|
3623
|
-
h1 ^= h1 >>> 13;
|
|
3624
|
-
h1 = (h1 & 65535) * 3266489909 + (((h1 >>> 16) * 3266489909 & 65535) << 16) & 4294967295;
|
|
3625
|
-
h1 ^= h1 >>> 16;
|
|
3626
|
-
return h1 >>> 0;
|
|
3627
|
-
}
|
|
3628
|
-
|
|
3629
3757
|
class ForkedStoreState extends StoreState {
|
|
3630
3758
|
master;
|
|
3631
3759
|
changedItems = new Map;
|
|
@@ -3969,16 +4097,57 @@ function resolveQueryChange(currentResult, event3, options) {
|
|
|
3969
4097
|
}
|
|
3970
4098
|
const shouldBeInResult = checkItemMatchesWhere(event3.item, options.where);
|
|
3971
4099
|
if (isInCurrentResult && shouldBeInResult) {
|
|
3972
|
-
|
|
3973
|
-
|
|
4100
|
+
if (!options.orderBy) {
|
|
4101
|
+
return applyLimit(currentResult.toSpliced(index, 1, event3.item), options);
|
|
4102
|
+
}
|
|
4103
|
+
const cmp = compareByOrderBy(options.orderBy);
|
|
4104
|
+
if (cmp(currentResult[index], event3.item) === 0) {
|
|
4105
|
+
return applyLimit(currentResult.toSpliced(index, 1, event3.item), options);
|
|
4106
|
+
}
|
|
4107
|
+
const without = currentResult.toSpliced(index, 1);
|
|
4108
|
+
const at = upperBound(without, event3.item, cmp);
|
|
4109
|
+
return applyLimit(without.toSpliced(at, 0, event3.item), options);
|
|
3974
4110
|
} else if (isInCurrentResult && !shouldBeInResult) {
|
|
3975
4111
|
return currentResult.toSpliced(index, 1);
|
|
3976
4112
|
} else if (!isInCurrentResult && shouldBeInResult) {
|
|
3977
|
-
|
|
3978
|
-
|
|
4113
|
+
if (!options.orderBy) {
|
|
4114
|
+
return applyLimit([...currentResult, event3.item], options);
|
|
4115
|
+
}
|
|
4116
|
+
const cmp = compareByOrderBy(options.orderBy);
|
|
4117
|
+
const at = upperBound(currentResult, event3.item, cmp);
|
|
4118
|
+
return applyLimit(currentResult.toSpliced(at, 0, event3.item), options);
|
|
3979
4119
|
}
|
|
3980
4120
|
return false;
|
|
3981
4121
|
}
|
|
4122
|
+
function compareByOrderBy(orderBy) {
|
|
4123
|
+
const entries = Object.entries(orderBy);
|
|
4124
|
+
return (a, b) => {
|
|
4125
|
+
for (const [key, direction] of entries) {
|
|
4126
|
+
const aVal = a[key];
|
|
4127
|
+
const bVal = b[key];
|
|
4128
|
+
if (aVal < bVal)
|
|
4129
|
+
return direction === "asc" ? -1 : 1;
|
|
4130
|
+
if (aVal > bVal)
|
|
4131
|
+
return direction === "asc" ? 1 : -1;
|
|
4132
|
+
}
|
|
4133
|
+
return 0;
|
|
4134
|
+
};
|
|
4135
|
+
}
|
|
4136
|
+
function upperBound(arr, item, cmp) {
|
|
4137
|
+
let lo = 0;
|
|
4138
|
+
let hi = arr.length;
|
|
4139
|
+
while (lo < hi) {
|
|
4140
|
+
const mid = lo + hi >> 1;
|
|
4141
|
+
if (cmp(arr[mid], item) <= 0)
|
|
4142
|
+
lo = mid + 1;
|
|
4143
|
+
else
|
|
4144
|
+
hi = mid;
|
|
4145
|
+
}
|
|
4146
|
+
return lo;
|
|
4147
|
+
}
|
|
4148
|
+
function applyLimit(result, options) {
|
|
4149
|
+
return options.limit !== undefined && result.length > options.limit ? result.slice(0, options.limit) : result;
|
|
4150
|
+
}
|
|
3982
4151
|
function checkItemMatchesWhere(item, where) {
|
|
3983
4152
|
if (!where) {
|
|
3984
4153
|
return true;
|
|
@@ -4014,27 +4183,6 @@ function checkItemMatchesWhere(item, where) {
|
|
|
4014
4183
|
});
|
|
4015
4184
|
});
|
|
4016
4185
|
}
|
|
4017
|
-
function applyOrderByAndLimit(result, options) {
|
|
4018
|
-
let sorted = result;
|
|
4019
|
-
if (options.orderBy) {
|
|
4020
|
-
sorted = [...result].sort((a, b) => {
|
|
4021
|
-
for (const [key, direction] of Object.entries(options.orderBy)) {
|
|
4022
|
-
const aVal = a[key];
|
|
4023
|
-
const bVal = b[key];
|
|
4024
|
-
if (aVal < bVal)
|
|
4025
|
-
return direction === "asc" ? -1 : 1;
|
|
4026
|
-
if (aVal > bVal)
|
|
4027
|
-
return direction === "asc" ? 1 : -1;
|
|
4028
|
-
}
|
|
4029
|
-
return 0;
|
|
4030
|
-
});
|
|
4031
|
-
}
|
|
4032
|
-
if (options.limit !== undefined) {
|
|
4033
|
-
sorted = sorted.slice(0, options.limit);
|
|
4034
|
-
}
|
|
4035
|
-
return sorted;
|
|
4036
|
-
}
|
|
4037
|
-
|
|
4038
4186
|
class ObservableDataStorage {
|
|
4039
4187
|
source;
|
|
4040
4188
|
onChange;
|
|
@@ -4682,6 +4830,8 @@ class SecuredDataStorage {
|
|
|
4682
4830
|
return this.dataStorage.fork();
|
|
4683
4831
|
}
|
|
4684
4832
|
}
|
|
4833
|
+
var _te = new TextEncoder;
|
|
4834
|
+
var _td = new TextDecoder;
|
|
4685
4835
|
class TokenCache {
|
|
4686
4836
|
instanceCache = new Map;
|
|
4687
4837
|
permissionCache = new Map;
|
|
@@ -5249,7 +5399,7 @@ kebab.column.to = fromKebab;
|
|
|
5249
5399
|
// ../../../../node_modules/.bun/postgres@3.4.9/node_modules/postgres/src/connection.js
|
|
5250
5400
|
import net from "net";
|
|
5251
5401
|
import tls from "tls";
|
|
5252
|
-
import
|
|
5402
|
+
import crypto2 from "crypto";
|
|
5253
5403
|
import Stream from "stream";
|
|
5254
5404
|
import { performance } from "perf_hooks";
|
|
5255
5405
|
|
|
@@ -5830,14 +5980,14 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
5830
5980
|
write(bytes_default().p().str(payload).z(1).end());
|
|
5831
5981
|
}
|
|
5832
5982
|
async function SASL() {
|
|
5833
|
-
nonce = (await
|
|
5983
|
+
nonce = (await crypto2.randomBytes(18)).toString("base64");
|
|
5834
5984
|
bytes_default().p().str("SCRAM-SHA-256" + bytes_default.N);
|
|
5835
5985
|
const i = bytes_default.i;
|
|
5836
5986
|
write(bytes_default.inc(4).str("n,,n=*,r=" + nonce).i32(bytes_default.i - i - 4, i).end());
|
|
5837
5987
|
}
|
|
5838
5988
|
async function SASLContinue(x) {
|
|
5839
5989
|
const res = x.toString("utf8", 9).split(",").reduce((acc, x2) => (acc[x2[0]] = x2.slice(2), acc), {});
|
|
5840
|
-
const saltedPassword = await
|
|
5990
|
+
const saltedPassword = await crypto2.pbkdf2Sync(await Pass(), Buffer.from(res.s, "base64"), parseInt(res.i), 32, "sha256");
|
|
5841
5991
|
const clientKey = await hmac(saltedPassword, "Client Key");
|
|
5842
5992
|
const auth = "n=*,r=" + nonce + "," + "r=" + res.r + ",s=" + res.s + ",i=" + res.i + ",c=biws,r=" + res.r;
|
|
5843
5993
|
serverSignature = (await hmac(await hmac(saltedPassword, "Server Key"), auth)).toString("base64");
|
|
@@ -6058,13 +6208,13 @@ function parseError(x) {
|
|
|
6058
6208
|
return error;
|
|
6059
6209
|
}
|
|
6060
6210
|
function md5(x) {
|
|
6061
|
-
return
|
|
6211
|
+
return crypto2.createHash("md5").update(x).digest("hex");
|
|
6062
6212
|
}
|
|
6063
6213
|
function hmac(key, x) {
|
|
6064
|
-
return
|
|
6214
|
+
return crypto2.createHmac("sha256", key).update(x).digest();
|
|
6065
6215
|
}
|
|
6066
6216
|
function sha256(x) {
|
|
6067
|
-
return
|
|
6217
|
+
return crypto2.createHash("sha256").update(x).digest();
|
|
6068
6218
|
}
|
|
6069
6219
|
function xor(a, b2) {
|
|
6070
6220
|
const length = Math.max(a.length, b2.length);
|
|
@@ -6751,6 +6901,40 @@ function osUsername() {
|
|
|
6751
6901
|
}
|
|
6752
6902
|
|
|
6753
6903
|
// src/postgres-adapter.ts
|
|
6904
|
+
var MAX_SAFE_INT = BigInt(Number.MAX_SAFE_INTEGER);
|
|
6905
|
+
var MIN_SAFE_INT = BigInt(Number.MIN_SAFE_INTEGER);
|
|
6906
|
+
function unsafeIntMessage(raw, columnName) {
|
|
6907
|
+
const where = columnName ? ` w kolumnie "${columnName}"` : "";
|
|
6908
|
+
return `[PostgreSQL] Wartość całkowita ${raw}${where} przekracza bezpieczny zakres ` + `JS Number (±2^53-1). Odczyt jako number cicho straciłby precyzję. ` + `Użyj kolumny TEXT/NUMERIC i obsłuż wartość jako string/BigInt.`;
|
|
6909
|
+
}
|
|
6910
|
+
function coercePgNumber(value, columnName) {
|
|
6911
|
+
if (value === null || value === undefined)
|
|
6912
|
+
return value;
|
|
6913
|
+
if (typeof value === "number")
|
|
6914
|
+
return value;
|
|
6915
|
+
if (typeof value === "bigint") {
|
|
6916
|
+
if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) {
|
|
6917
|
+
throw new Error(unsafeIntMessage(value.toString(), columnName));
|
|
6918
|
+
}
|
|
6919
|
+
return Number(value);
|
|
6920
|
+
}
|
|
6921
|
+
if (typeof value === "string") {
|
|
6922
|
+
const s = value.trim();
|
|
6923
|
+
if (s === "")
|
|
6924
|
+
return value;
|
|
6925
|
+
if (/^[+-]?\d+$/.test(s)) {
|
|
6926
|
+
const big = BigInt(s);
|
|
6927
|
+
if (big > MAX_SAFE_INT || big < MIN_SAFE_INT) {
|
|
6928
|
+
throw new Error(unsafeIntMessage(s, columnName));
|
|
6929
|
+
}
|
|
6930
|
+
return Number(big);
|
|
6931
|
+
}
|
|
6932
|
+
const n = Number(s);
|
|
6933
|
+
return Number.isNaN(n) ? value : n;
|
|
6934
|
+
}
|
|
6935
|
+
return value;
|
|
6936
|
+
}
|
|
6937
|
+
|
|
6754
6938
|
class PostgreSQLReadTransaction {
|
|
6755
6939
|
db;
|
|
6756
6940
|
tables;
|
|
@@ -6772,7 +6956,27 @@ class PostgreSQLReadTransaction {
|
|
|
6772
6956
|
deserializeValue(value, column) {
|
|
6773
6957
|
if (value === null || value === undefined)
|
|
6774
6958
|
return null;
|
|
6775
|
-
|
|
6959
|
+
const type = column.type.toLowerCase().split("(")[0].trim();
|
|
6960
|
+
switch (type) {
|
|
6961
|
+
case "bigint":
|
|
6962
|
+
case "int8":
|
|
6963
|
+
case "bigserial":
|
|
6964
|
+
case "serial8":
|
|
6965
|
+
case "serial":
|
|
6966
|
+
case "serial4":
|
|
6967
|
+
case "integer":
|
|
6968
|
+
case "int":
|
|
6969
|
+
case "int4":
|
|
6970
|
+
case "smallint":
|
|
6971
|
+
case "int2":
|
|
6972
|
+
case "numeric":
|
|
6973
|
+
case "decimal":
|
|
6974
|
+
case "real":
|
|
6975
|
+
case "double precision":
|
|
6976
|
+
case "float":
|
|
6977
|
+
case "float4":
|
|
6978
|
+
case "float8":
|
|
6979
|
+
return coercePgNumber(value, column.name);
|
|
6776
6980
|
case "json":
|
|
6777
6981
|
case "jsonb":
|
|
6778
6982
|
if (typeof value === "string") {
|
|
@@ -7423,7 +7627,15 @@ class PostgresJsDatabase {
|
|
|
7423
7627
|
}
|
|
7424
7628
|
var createPostgreSQLAdapterFactoryFromUrl = (connectionString) => {
|
|
7425
7629
|
const sql = src_default(connectionString, {
|
|
7426
|
-
onnotice: () => {}
|
|
7630
|
+
onnotice: () => {},
|
|
7631
|
+
types: {
|
|
7632
|
+
bigint: {
|
|
7633
|
+
to: 20,
|
|
7634
|
+
from: [20],
|
|
7635
|
+
serialize: (v) => v.toString(),
|
|
7636
|
+
parse: (v) => coercePgNumber(v)
|
|
7637
|
+
}
|
|
7638
|
+
}
|
|
7427
7639
|
});
|
|
7428
7640
|
const db = new PostgresJsDatabase(sql);
|
|
7429
7641
|
return createPostgreSQLAdapterFactory(db);
|
|
@@ -7431,5 +7643,6 @@ var createPostgreSQLAdapterFactoryFromUrl = (connectionString) => {
|
|
|
7431
7643
|
export {
|
|
7432
7644
|
createPostgreSQLAdapterFactoryFromUrl,
|
|
7433
7645
|
createPostgreSQLAdapterFactory,
|
|
7646
|
+
coercePgNumber,
|
|
7434
7647
|
PostgreSQLAdapter
|
|
7435
7648
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcote.tech/arc-adapter-db-postgres",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.28",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"postgres": "^3.4.4"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
|
-
"@arcote.tech/arc": "^0.7.
|
|
26
|
+
"@arcote.tech/arc": "^0.7.28"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/pg": "^8.11.0",
|