@moneypot/hub 1.16.1 → 1.16.3
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/cli/add-casino.js +6 -3
- package/dist/dashboard/assets/index-32DtKox_.css +5 -0
- package/dist/dashboard/assets/index-B4xPUnuF.js +412 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/src/__generated__/graphql.d.ts +74 -32
- package/dist/src/__generated__/graphql.js +23 -14
- package/dist/src/hash-chain/db-hash-chain.d.ts +2 -1
- package/dist/src/hash-chain/db-hash-chain.js +11 -16
- package/dist/src/hash-chain/plugins/hub-reveal-hash-chain.js +9 -10
- package/dist/src/hash-chain/reveal-hash-chain.d.ts +3 -3
- package/dist/src/hash-chain/reveal-hash-chain.js +28 -5
- package/dist/src/plugins/chat/hub-chat-subscription.d.ts +1 -1
- package/dist/src/plugins/hub-authenticate.js +1 -1
- package/dist/src/plugins/hub-make-outcome-bet.d.ts +4 -44
- package/dist/src/plugins/hub-make-outcome-bet.js +2 -1
- package/dist/src/plugins/hub-put-alert.js +2 -2
- package/dist/src/plugins/listen-with-filter.d.ts +4 -3
- package/dist/src/plugins/listen-with-filter.js +65 -8
- package/dist/src/plugins/validate-fields.js +25 -33
- package/dist/src/process-transfers/index.js +1 -1
- package/dist/src/risk-policy.js +1 -1
- package/dist/src/services/jwt-service.js +1 -1
- package/dist/src/validate-zod.d.ts +3 -0
- package/dist/src/validate-zod.js +19 -0
- package/package.json +3 -4
- package/dist/dashboard/assets/index-D7SlWXgD.js +0 -383
- package/dist/dashboard/assets/index-LZVcTrKv.css +0 -5
- package/dist/src/validate.d.ts +0 -9
- package/dist/src/validate.js +0 -91
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { context, lambda } from "postgraphile/grafast";
|
|
2
|
-
import { gql,
|
|
2
|
+
import { gql, extendSchema } from "postgraphile/utils";
|
|
3
3
|
import { jsonParse } from "postgraphile/@dataplan/json";
|
|
4
4
|
import { listenWithFilter } from "./listen-with-filter.js";
|
|
5
5
|
import { logger } from "../logger.js";
|
|
6
|
-
export const HubPutAlertPlugin =
|
|
6
|
+
export const HubPutAlertPlugin = extendSchema((_build) => {
|
|
7
7
|
return {
|
|
8
8
|
typeDefs: gql `
|
|
9
9
|
extend type Subscription {
|
|
@@ -6,7 +6,7 @@ export declare class ListenWithFilterStep<TTopics extends {
|
|
|
6
6
|
}, TTopic extends keyof TTopics, TPayloadStep extends Step, TFilterInput> extends Step<TTopics[TTopic][]> {
|
|
7
7
|
itemPlan: (itemPlan: __ItemStep<TTopics[TTopic]>) => TPayloadStep;
|
|
8
8
|
filterFn: (item: unknown, filterInput: TFilterInput) => boolean;
|
|
9
|
-
static
|
|
9
|
+
static $export: {
|
|
10
10
|
moduleName: string;
|
|
11
11
|
exportName: string;
|
|
12
12
|
};
|
|
@@ -14,9 +14,10 @@ export declare class ListenWithFilterStep<TTopics extends {
|
|
|
14
14
|
private pubsubDep;
|
|
15
15
|
private topicDep;
|
|
16
16
|
private filterInputDep;
|
|
17
|
-
|
|
17
|
+
private initialEventDep;
|
|
18
|
+
constructor(pubsubOrPlan: Step<GrafastSubscriber<TTopics> | null> | GrafastSubscriber<TTopics> | null, topicOrPlan: Step<TTopic> | string, itemPlan: ((itemPlan: __ItemStep<TTopics[TTopic]>) => TPayloadStep) | undefined, filterInputPlan: Step<TFilterInput>, filterFn: (item: unknown, filterInput: TFilterInput) => boolean, $initialEvent?: Step<TTopics[TTopic]>);
|
|
18
19
|
execute({ indexMap, values, stream, }: ExecutionDetails<readonly [GrafastSubscriber<TTopics>, TTopic]>): GrafastResultStreamList<TTopics[TTopic]>;
|
|
19
20
|
}
|
|
20
21
|
export declare function listenWithFilter<TTopics extends {
|
|
21
22
|
[topic: string]: any;
|
|
22
|
-
}, TTopic extends keyof TTopics, TPayloadStep extends Step, TFilterInput>(pubsubOrPlan: Step<GrafastSubscriber<TTopics> | null> | GrafastSubscriber<TTopics> | null, topicOrPlan: Step<TTopic> | string, itemPlan: ((itemPlan: __ItemStep<TTopics[TTopic]>) => TPayloadStep) | undefined, filterInputPlan: Step<TFilterInput>, filterFn: (item: unknown, filterInput: TFilterInput) => boolean): ListenWithFilterStep<TTopics, TTopic, TPayloadStep, TFilterInput>;
|
|
23
|
+
}, TTopic extends keyof TTopics, TPayloadStep extends Step, TFilterInput>(pubsubOrPlan: Step<GrafastSubscriber<TTopics> | null> | GrafastSubscriber<TTopics> | null, topicOrPlan: Step<TTopic> | string, itemPlan: ((itemPlan: __ItemStep<TTopics[TTopic]>) => TPayloadStep) | undefined, filterInputPlan: Step<TFilterInput>, filterFn: (item: unknown, filterInput: TFilterInput) => boolean, $initialEvent?: Step<TTopics[TTopic]>): ListenWithFilterStep<TTopics, TTopic, TPayloadStep, TFilterInput>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { constant, isDev,
|
|
1
|
+
import { constant, isDev, isStep, SafeError, } from "postgraphile/grafast";
|
|
2
2
|
import { Step } from "postgraphile/grafast";
|
|
3
3
|
export class ListenWithFilterStep extends Step {
|
|
4
4
|
itemPlan;
|
|
5
5
|
filterFn;
|
|
6
|
-
static
|
|
6
|
+
static $export = {
|
|
7
7
|
moduleName: "grafast",
|
|
8
8
|
exportName: "ListenWithFilterStep",
|
|
9
9
|
};
|
|
@@ -11,17 +11,21 @@ export class ListenWithFilterStep extends Step {
|
|
|
11
11
|
pubsubDep;
|
|
12
12
|
topicDep;
|
|
13
13
|
filterInputDep;
|
|
14
|
-
|
|
14
|
+
initialEventDep = null;
|
|
15
|
+
constructor(pubsubOrPlan, topicOrPlan, itemPlan = ($item) => $item, filterInputPlan, filterFn, $initialEvent) {
|
|
15
16
|
super();
|
|
16
17
|
this.itemPlan = itemPlan;
|
|
17
18
|
this.filterFn = filterFn;
|
|
18
19
|
const $topic = typeof topicOrPlan === "string" ? constant(topicOrPlan) : topicOrPlan;
|
|
19
|
-
const $pubsub =
|
|
20
|
+
const $pubsub = isStep(pubsubOrPlan)
|
|
20
21
|
? pubsubOrPlan
|
|
21
22
|
: constant(pubsubOrPlan, false);
|
|
22
23
|
this.pubsubDep = this.addDependency($pubsub);
|
|
23
24
|
this.topicDep = this.addDependency($topic);
|
|
24
25
|
this.filterInputDep = this.addDependency(filterInputPlan);
|
|
26
|
+
if ($initialEvent) {
|
|
27
|
+
this.initialEventDep = this.addDependency($initialEvent);
|
|
28
|
+
}
|
|
25
29
|
}
|
|
26
30
|
execute({ indexMap, values, stream, }) {
|
|
27
31
|
if (!stream) {
|
|
@@ -30,20 +34,22 @@ export class ListenWithFilterStep extends Step {
|
|
|
30
34
|
const pubsubValue = values[this.pubsubDep];
|
|
31
35
|
const topicValue = values[this.topicDep];
|
|
32
36
|
const filterInputValue = values[this.filterInputDep];
|
|
37
|
+
const initialEventValue = this.initialEventDep !== null ? values[this.initialEventDep] : null;
|
|
33
38
|
return indexMap((i) => {
|
|
34
39
|
const pubsub = pubsubValue.at(i);
|
|
35
40
|
if (!pubsub) {
|
|
36
41
|
throw new SafeError("Subscription not supported", isDev
|
|
37
42
|
? {
|
|
38
|
-
hint:
|
|
43
|
+
hint: `Pubsub did not provide a GrafastSubscriber; perhaps you forgot to add the relevant property to context?`,
|
|
39
44
|
}
|
|
40
45
|
: {});
|
|
41
46
|
}
|
|
42
47
|
const topic = topicValue.at(i);
|
|
43
48
|
const filterInput = filterInputValue.at(i);
|
|
44
49
|
const origStream = pubsub.subscribe(topic);
|
|
50
|
+
const initialEvent = initialEventValue?.at(i);
|
|
45
51
|
const filterFn = this.filterFn;
|
|
46
|
-
|
|
52
|
+
const filteredStream = {
|
|
47
53
|
[Symbol.asyncIterator]: async function* () {
|
|
48
54
|
const iterator = await origStream;
|
|
49
55
|
for await (const item of iterator) {
|
|
@@ -53,9 +59,60 @@ export class ListenWithFilterStep extends Step {
|
|
|
53
59
|
}
|
|
54
60
|
},
|
|
55
61
|
};
|
|
62
|
+
if (initialEvent === undefined) {
|
|
63
|
+
return filteredStream;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
if (filterFn(initialEvent, filterInput)) {
|
|
67
|
+
return withInitialValue(initialEvent, filteredStream);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
return filteredStream;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
56
73
|
});
|
|
57
74
|
}
|
|
58
75
|
}
|
|
59
|
-
export function listenWithFilter(pubsubOrPlan, topicOrPlan, itemPlan = ($item) => $item, filterInputPlan, filterFn) {
|
|
60
|
-
return new ListenWithFilterStep(pubsubOrPlan, topicOrPlan, itemPlan, filterInputPlan, filterFn);
|
|
76
|
+
export function listenWithFilter(pubsubOrPlan, topicOrPlan, itemPlan = ($item) => $item, filterInputPlan, filterFn, $initialEvent) {
|
|
77
|
+
return new ListenWithFilterStep(pubsubOrPlan, topicOrPlan, itemPlan, filterInputPlan, filterFn, $initialEvent);
|
|
61
78
|
}
|
|
79
|
+
const DONE = Object.freeze({ value: undefined, done: true });
|
|
80
|
+
const withInitialValue = (initialVal, source) => ({
|
|
81
|
+
[Symbol.asyncIterator]() {
|
|
82
|
+
const sourceIterator = source[Symbol.asyncIterator]();
|
|
83
|
+
let first = true;
|
|
84
|
+
let done = null;
|
|
85
|
+
return {
|
|
86
|
+
async next() {
|
|
87
|
+
if (done)
|
|
88
|
+
return done;
|
|
89
|
+
if (first) {
|
|
90
|
+
first = false;
|
|
91
|
+
return { value: initialVal, done: false };
|
|
92
|
+
}
|
|
93
|
+
const res = await sourceIterator.next();
|
|
94
|
+
if (res.done)
|
|
95
|
+
done = res;
|
|
96
|
+
return res;
|
|
97
|
+
},
|
|
98
|
+
async return(value) {
|
|
99
|
+
done ??= { value: value, done: true };
|
|
100
|
+
if (typeof sourceIterator.return === "function") {
|
|
101
|
+
try {
|
|
102
|
+
await sourceIterator.return();
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return done;
|
|
108
|
+
},
|
|
109
|
+
async throw(err) {
|
|
110
|
+
done ??= DONE;
|
|
111
|
+
if (typeof sourceIterator.throw === "function") {
|
|
112
|
+
return sourceIterator.throw(err);
|
|
113
|
+
}
|
|
114
|
+
throw err;
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
},
|
|
118
|
+
});
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { sideEffect } from "postgraphile/grafast";
|
|
2
2
|
import { GraphQLError } from "postgraphile/graphql";
|
|
3
|
-
import {
|
|
4
|
-
import * as v from "../validate.js";
|
|
5
|
-
import
|
|
3
|
+
import { wrapPlans } from "postgraphile/utils";
|
|
4
|
+
import * as v from "../validate-zod.js";
|
|
5
|
+
import z, { prettifyError } from "zod/v4";
|
|
6
6
|
function validate(value, schema) {
|
|
7
7
|
try {
|
|
8
|
-
schema.
|
|
8
|
+
schema.parse(value);
|
|
9
9
|
}
|
|
10
10
|
catch (e) {
|
|
11
|
-
if (e instanceof
|
|
12
|
-
const
|
|
11
|
+
if (e instanceof z.ZodError) {
|
|
12
|
+
const fieldPath = e.issues.map((issue) => issue.path.join(".")).join(".");
|
|
13
|
+
const errorMessage = `Field "${fieldPath}": ${prettifyError(e)}`;
|
|
13
14
|
throw new GraphQLError(errorMessage);
|
|
14
15
|
}
|
|
15
16
|
else {
|
|
@@ -17,45 +18,36 @@ function validate(value, schema) {
|
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
|
-
const
|
|
21
|
-
.
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
const CasinoPatchSchema = z.strictObject({
|
|
22
|
+
name: z.string().trim().min(1).optional(),
|
|
23
|
+
graphqlUrl: v.graphqlUrl().optional(),
|
|
24
|
+
baseUrl: v.baseUrl().optional(),
|
|
25
|
+
});
|
|
26
|
+
const AddCasinoSchema = z.strictObject({
|
|
27
|
+
name: z.string().trim().min(1),
|
|
24
28
|
baseUrl: v.baseUrl(),
|
|
25
|
-
|
|
26
|
-
.
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
graphqlUrl: v.graphqlUrl().required(),
|
|
33
|
-
apiKey: v.uuid().required(),
|
|
34
|
-
})
|
|
35
|
-
.strict()
|
|
36
|
-
.noUnknown();
|
|
37
|
-
const updateBankrollSchema = Yup.object()
|
|
38
|
-
.shape({
|
|
39
|
-
amount: Yup.number().integer().min(0).required(),
|
|
40
|
-
})
|
|
41
|
-
.strict()
|
|
42
|
-
.noUnknown();
|
|
43
|
-
export const ValidateCasinoFieldsPlugin = makeWrapPlansPlugin({
|
|
29
|
+
graphqlUrl: v.graphqlUrl(),
|
|
30
|
+
apiKey: z.uuid(),
|
|
31
|
+
});
|
|
32
|
+
const UpdateBankrollSchema = z.strictObject({
|
|
33
|
+
amount: z.number().int().min(0),
|
|
34
|
+
});
|
|
35
|
+
export const ValidateCasinoFieldsPlugin = wrapPlans(() => ({
|
|
44
36
|
Mutation: {
|
|
45
37
|
updateHubCasinoById: (plan, $source, fieldArgs) => {
|
|
46
38
|
const $patch = fieldArgs.getRaw(["input", "hubCasinoPatch"]);
|
|
47
|
-
sideEffect($patch, (patch) => validate(patch,
|
|
39
|
+
sideEffect($patch, (patch) => validate(patch, CasinoPatchSchema));
|
|
48
40
|
return plan();
|
|
49
41
|
},
|
|
50
42
|
hubAddCasino: (plan, $source, fieldArgs) => {
|
|
51
43
|
const $input = fieldArgs.getRaw(["input"]);
|
|
52
|
-
sideEffect($input, (input) => validate(input,
|
|
44
|
+
sideEffect($input, (input) => validate(input, AddCasinoSchema));
|
|
53
45
|
return plan();
|
|
54
46
|
},
|
|
55
47
|
updateHubBankrollById: (plan, $source, fieldArgs) => {
|
|
56
48
|
const $patch = fieldArgs.getRaw(["input", "hubBankrollPatch"]);
|
|
57
|
-
sideEffect($patch, (patch) => validate(patch,
|
|
49
|
+
sideEffect($patch, (patch) => validate(patch, UpdateBankrollSchema));
|
|
58
50
|
return plan();
|
|
59
51
|
},
|
|
60
52
|
},
|
|
61
|
-
});
|
|
53
|
+
}));
|
|
@@ -6,7 +6,7 @@ import { logger } from "../logger.js";
|
|
|
6
6
|
import * as config from "../config.js";
|
|
7
7
|
import * as db from "../db/index.js";
|
|
8
8
|
import * as pg from "pg";
|
|
9
|
-
import { z } from "zod";
|
|
9
|
+
import { z } from "zod/v4";
|
|
10
10
|
const activeCasinos = new Set();
|
|
11
11
|
export async function startCasinoTransferProcessor({ casinoId, signal, pool, }) {
|
|
12
12
|
if (activeCasinos.has(casinoId)) {
|
package/dist/src/risk-policy.js
CHANGED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import z from "zod/v4";
|
|
2
|
+
export declare const baseUrl: () => z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<URL, string>>, z.ZodTransform<string, URL>>;
|
|
3
|
+
export declare const graphqlUrl: () => z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<URL, string>>, z.ZodTransform<string, URL>>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import z from "zod/v4";
|
|
2
|
+
export const baseUrl = () => z
|
|
3
|
+
.string()
|
|
4
|
+
.trim()
|
|
5
|
+
.min(1, "Base URL is required")
|
|
6
|
+
.refine((val) => URL.canParse(val), "Base URL is not a valid URL")
|
|
7
|
+
.transform((val) => new URL(val))
|
|
8
|
+
.refine((val) => val.protocol === "http:" || val.protocol === "https:", "Base URL must use http or https protocol")
|
|
9
|
+
.refine((val) => val.pathname === "/" && val.search === "" && val.hash === "", "Base URL must have no path, query, nor hash")
|
|
10
|
+
.transform((val) => val.toString().replace(/\/$/, ""));
|
|
11
|
+
export const graphqlUrl = () => z
|
|
12
|
+
.string()
|
|
13
|
+
.trim()
|
|
14
|
+
.min(1, "GraphQL URL is required")
|
|
15
|
+
.refine((val) => URL.canParse(val), "GraphQL URL is not a valid URL")
|
|
16
|
+
.transform((val) => new URL(val))
|
|
17
|
+
.refine((val) => val.protocol === "http:" || val.protocol === "https:", "GraphQL URL must use http or https protocol")
|
|
18
|
+
.refine((val) => val.pathname === "/graphql", "GraphQL URL must have /graphql path")
|
|
19
|
+
.transform((val) => val.toString().replace(/\/$/, ""));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moneypot/hub",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.3",
|
|
4
4
|
"author": "moneypot.com",
|
|
5
5
|
"homepage": "https://moneypot.com/hub",
|
|
6
6
|
"keywords": [
|
|
@@ -59,10 +59,9 @@
|
|
|
59
59
|
"pg": "^8.12.0",
|
|
60
60
|
"pg-connection-string": "^2.6.4",
|
|
61
61
|
"pino": "^9.7.0",
|
|
62
|
-
"postgraphile": "^5.0.0-beta.
|
|
62
|
+
"postgraphile": "^5.0.0-beta.49",
|
|
63
63
|
"tsafe": "^1.6.6",
|
|
64
|
-
"
|
|
65
|
-
"zod": "^3.23.5"
|
|
64
|
+
"zod": "^4.1.12"
|
|
66
65
|
},
|
|
67
66
|
"devDependencies": {
|
|
68
67
|
"@eslint/js": "^9.8.0",
|