@moneypot/hub 1.19.16 → 1.20.0-dev.1

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.
Files changed (44) hide show
  1. package/README.md +26 -0
  2. package/dist/dashboard/assets/index-Gvpn1nS9.js +350 -0
  3. package/dist/dashboard/index.html +1 -1
  4. package/dist/src/audit-log.d.ts +9 -9
  5. package/dist/src/audit-log.js +7 -1
  6. package/dist/src/config.js +4 -8
  7. package/dist/src/db/public.d.ts +8 -8
  8. package/dist/src/db/public.js +29 -7
  9. package/dist/src/db/transaction.d.ts +2 -5
  10. package/dist/src/db/transaction.js +0 -1
  11. package/dist/src/db/types.d.ts +11 -2
  12. package/dist/src/db/util.d.ts +1 -3
  13. package/dist/src/deprecated.d.ts +6 -0
  14. package/dist/src/deprecated.js +2 -0
  15. package/dist/src/hash-chain/plugins/hub-create-hash-chain.js +12 -12
  16. package/dist/src/index.d.ts +7 -2
  17. package/dist/src/index.js +4 -0
  18. package/dist/src/liability/internal/db.d.ts +5 -0
  19. package/dist/src/liability/internal/db.js +12 -0
  20. package/dist/src/liability/internal/index.d.ts +2 -0
  21. package/dist/src/liability/internal/index.js +2 -0
  22. package/dist/src/liability/internal/processor.d.ts +16 -0
  23. package/dist/src/liability/internal/processor.js +122 -0
  24. package/dist/src/liability/public/config.d.ts +37 -0
  25. package/dist/src/liability/public/config.js +15 -0
  26. package/dist/src/liability/public/db.d.ts +10 -0
  27. package/dist/src/liability/public/db.js +53 -0
  28. package/dist/src/liability/public/index.d.ts +2 -0
  29. package/dist/src/liability/public/index.js +1 -0
  30. package/dist/src/liability/types.d.ts +24 -0
  31. package/dist/src/liability/types.js +1 -0
  32. package/dist/src/migrations.js +2 -2
  33. package/dist/src/pg-versions/017-liability.sql +48 -0
  34. package/dist/src/plugins/hub-make-outcome-bet.js +4 -4
  35. package/dist/src/plugins/hub-risk-limits.js +1 -1
  36. package/dist/src/risk-policy.d.ts +2 -2
  37. package/dist/src/risk-policy.js +3 -3
  38. package/dist/src/server/index.d.ts +4 -2
  39. package/dist/src/server/index.js +14 -3
  40. package/dist/src/test/index.d.ts +7 -6
  41. package/dist/src/test/index.js +7 -2
  42. package/dist/src/util.d.ts +5 -0
  43. package/package.json +10 -11
  44. package/dist/dashboard/assets/index-QbfKgHTj.js +0 -350
@@ -0,0 +1,53 @@
1
+ import { exactlyOneRow } from "../../db/util.js";
2
+ export async function dbCreateLiability(pgClient, { lockedBankrollId, casinoId, experienceId, userId, currencyKey, refId, refType, maxPayout, deadline, }) {
3
+ const row = await pgClient
4
+ .query({
5
+ text: `
6
+ WITH inserted AS (
7
+ INSERT INTO hub.liability (bankroll_id, casino_id, experience_id, user_id, currency_key, ref_id, ref_type, max_payout, deadline)
8
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
9
+ RETURNING *
10
+ ),
11
+ bankroll_update AS (
12
+ UPDATE hub.bankroll
13
+ SET liability = liability + $8
14
+ WHERE id = $1
15
+ )
16
+ SELECT * FROM inserted
17
+ `,
18
+ values: [
19
+ lockedBankrollId,
20
+ casinoId,
21
+ experienceId,
22
+ userId,
23
+ currencyKey,
24
+ refId,
25
+ refType,
26
+ maxPayout,
27
+ deadline,
28
+ ],
29
+ })
30
+ .then(exactlyOneRow);
31
+ return row;
32
+ }
33
+ export async function dbResolveLiabilityByRef(pgClient, { refType, refId, lockedBankrollId, }) {
34
+ const _proofOfGoodBehavior = lockedBankrollId;
35
+ const result = await pgClient.query({
36
+ text: `
37
+ WITH resolved AS (
38
+ UPDATE hub.liability
39
+ SET resolved_at = now()
40
+ WHERE ref_type = $1
41
+ AND ref_id = $2
42
+ AND resolved_at IS NULL
43
+ RETURNING bankroll_id, max_payout
44
+ )
45
+ UPDATE hub.bankroll
46
+ SET liability = liability - resolved.max_payout
47
+ FROM resolved
48
+ WHERE hub.bankroll.id = resolved.bankroll_id
49
+ `,
50
+ values: [refType, refId],
51
+ });
52
+ return result.rowCount === 1;
53
+ }
@@ -0,0 +1,2 @@
1
+ export type { DbLiability, NewLiability } from "../types.js";
2
+ export { type LiabilityConfig, type LiabilityRefTypeConfig as LiabilityHandler, type LiabilityResolved, type DbLockedLiability, LIABILITY_RESOLVED, createLiabilityConfig, } from "./config.js";
@@ -0,0 +1 @@
1
+ export { LIABILITY_RESOLVED, createLiabilityConfig, } from "./config.js";
@@ -0,0 +1,24 @@
1
+ export type DbLiability = {
2
+ id: string;
3
+ bankroll_id: string;
4
+ casino_id: string;
5
+ experience_id: string;
6
+ user_id: string;
7
+ currency_key: string;
8
+ ref_id: string;
9
+ ref_type: string;
10
+ max_payout: number;
11
+ deadline: Date;
12
+ resolved_at: Date | null;
13
+ };
14
+ export type NewLiability<RefType extends string = string> = {
15
+ lockedBankrollId: string;
16
+ casinoId: string;
17
+ experienceId: string;
18
+ userId: string;
19
+ currencyKey: string;
20
+ refId: string;
21
+ refType: RefType;
22
+ maxPayout: number;
23
+ deadline: Date;
24
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -14,7 +14,7 @@ export async function runMigrations(options) {
14
14
  }
15
15
  }
16
16
  try {
17
- await PgUpgradeSchema.default({
17
+ await PgUpgradeSchema({
18
18
  pgClient,
19
19
  dirname: join(import.meta.dirname, "pg-versions"),
20
20
  schemaName: "hub_core_versions",
@@ -30,7 +30,7 @@ export async function runMigrations(options) {
30
30
  throw e;
31
31
  }
32
32
  if (options.userDatabaseMigrationsPath) {
33
- await PgUpgradeSchema.default({
33
+ await PgUpgradeSchema({
34
34
  pgClient,
35
35
  dirname: options.userDatabaseMigrationsPath,
36
36
  schemaName: "hub_user_versions",
@@ -0,0 +1,48 @@
1
+ DROP TABLE IF EXISTS hub.liability CASCADE;
2
+ DROP FUNCTION IF EXISTS hub.update_bankroll_liability() CASCADE;
3
+ DROP FUNCTION IF EXISTS hub.liability_is_active(timestamptz, timestamptz) CASCADE;
4
+ DROP TRIGGER IF EXISTS liability_trigger ON hub.liability;
5
+ ALTER TABLE hub.bankroll DROP COLUMN IF EXISTS liability;
6
+
7
+ CREATE TABLE hub.liability (
8
+ id uuid PRIMARY KEY DEFAULT hub_hidden.uuid_generate_v7(),
9
+
10
+ bankroll_id uuid NOT NULL REFERENCES hub.bankroll,
11
+
12
+ casino_id uuid NOT NULL REFERENCES hub.casino,
13
+ experience_id uuid NOT NULL REFERENCES hub.experience,
14
+ user_id uuid NOT NULL REFERENCES hub.user,
15
+
16
+ currency_key text NOT NULL,
17
+ foreign key (currency_key, casino_id) references hub.currency(key, casino_id),
18
+
19
+ ref_id uuid NOT NULL,
20
+ ref_type text NOT NULL,
21
+
22
+ CONSTRAINT hub_liability_unique_ref UNIQUE (ref_type, ref_id),
23
+
24
+ max_payout float NOT NULL CHECK (max_payout >= 0),
25
+
26
+ deadline timestamptz NOT NULL,
27
+ resolved_at timestamptz NULL
28
+ );
29
+
30
+ CREATE INDEX liability_active_idx ON hub.liability(bankroll_id)
31
+ WHERE resolved_at IS NULL;
32
+
33
+ CREATE INDEX liability_needs_expiration_idx ON hub.liability(deadline)
34
+ WHERE resolved_at IS NULL;
35
+
36
+ ALTER TABLE hub.bankroll ADD COLUMN liability float NOT NULL DEFAULT 0;
37
+
38
+ ALTER TABLE hub.bankroll ADD CONSTRAINT bankroll_liability_bounds CHECK (liability >= 0 AND liability <= amount);
39
+
40
+
41
+ ALTER TABLE hub.liability ENABLE ROW LEVEL SECURITY;
42
+
43
+ GRANT SELECT ON hub.liability TO app_postgraphile;
44
+
45
+ CREATE POLICY select_liability ON hub.liability FOR SELECT
46
+ USING (
47
+ hub_hidden.is_operator()
48
+ );
@@ -293,13 +293,13 @@ export function MakeOutcomeBetPlugin({ outcomeBetConfigs, }) {
293
293
  const riskLimits = betConfig.riskPolicy({
294
294
  type: "get-limits",
295
295
  currency: input.currency,
296
- bankroll: dbHouseBankroll.amount,
296
+ availableBankroll: dbHouseBankroll.available,
297
297
  });
298
298
  const riskResult = validateRisk({
299
299
  type: "validate-bet",
300
300
  currency: input.currency,
301
301
  wager: input.wager,
302
- bankroll: dbHouseBankroll.amount,
302
+ availableBankroll: dbHouseBankroll.available,
303
303
  maxPotentialPayout,
304
304
  riskLimits,
305
305
  displayUnitName: dbCurrency.display_unit_name,
@@ -406,8 +406,8 @@ export function MakeOutcomeBetPlugin({ outcomeBetConfigs, }) {
406
406
  balanceNew: dbPlayerBalance.amount + netPlayerAmount,
407
407
  balanceDelta: netPlayerAmount,
408
408
  bankrollId: dbHouseBankroll.id,
409
- bankrollOld: dbHouseBankroll.amount,
410
- bankrollNew: dbHouseBankroll.amount + houseBankrollDelta,
409
+ bankrollOld: dbHouseBankroll.grossAmount,
410
+ bankrollNew: dbHouseBankroll.grossAmount + houseBankrollDelta,
411
411
  bankrollDelta: houseBankrollDelta,
412
412
  action: "hub:outcome_bet",
413
413
  refType: "hub.outcome_bet",
@@ -87,7 +87,7 @@ export function HubRiskLimitsPlugin({ outcomeBetConfigs, customGameConfigs, }) {
87
87
  const riskLimits = config.riskPolicy({
88
88
  type: "get-limits",
89
89
  currency: bankroll.currency_key,
90
- bankroll: bankroll.amount,
90
+ availableBankroll: bankroll.available,
91
91
  });
92
92
  return {
93
93
  gameKind,
@@ -4,14 +4,14 @@ export type RiskPolicyArgs = {
4
4
  type: "validate-bet";
5
5
  currency: string;
6
6
  wager: number;
7
- bankroll: number;
7
+ availableBankroll: number;
8
8
  maxPotentialPayout: number;
9
9
  outcomes: DbOutcome[];
10
10
  };
11
11
  export type BetLimitPolicyArgs = {
12
12
  type: "get-limits";
13
13
  currency: string;
14
- bankroll: number;
14
+ availableBankroll: number;
15
15
  };
16
16
  export type RiskLimits = {
17
17
  maxPayout: number;
@@ -6,7 +6,7 @@ const _RiskLimitsSchema = z
6
6
  })
7
7
  .strict();
8
8
  export function validateRisk(options) {
9
- const { bankroll, maxPotentialPayout } = options;
9
+ const { availableBankroll, maxPotentialPayout } = options;
10
10
  if (maxPotentialPayout > options.riskLimits.maxPayout) {
11
11
  const message = `Payout (${formatCurrency(maxPotentialPayout, {
12
12
  displayUnitName: options.displayUnitName,
@@ -20,11 +20,11 @@ export function validateRisk(options) {
20
20
  error: { message, riskLimits: options.riskLimits },
21
21
  };
22
22
  }
23
- if (maxPotentialPayout > bankroll) {
23
+ if (maxPotentialPayout > availableBankroll) {
24
24
  const message = `House cannot cover potential payout (${formatCurrency(maxPotentialPayout, {
25
25
  displayUnitName: options.displayUnitName,
26
26
  displayUnitScale: options.displayUnitScale,
27
- })}). Bankroll: ${formatCurrency(bankroll, {
27
+ })}). Bankroll: ${formatCurrency(availableBankroll, {
28
28
  displayUnitName: options.displayUnitName,
29
29
  displayUnitScale: options.displayUnitScale,
30
30
  })}`;
@@ -1,4 +1,5 @@
1
1
  import { ServerContext } from "../context.js";
2
+ import type { LiabilityConfig } from "../liability/public/index.js";
2
3
  export type HubServer = {
3
4
  listen: () => Promise<{
4
5
  port: number;
@@ -11,7 +12,7 @@ export type ConfigureAppArgs = {
11
12
  app: Express;
12
13
  superuserPool: ServerContext["superuserPool"];
13
14
  };
14
- export type CreateHubServerOptions = {
15
+ export type CreateHubServerOptions<LiabilityRefType extends string = string> = {
15
16
  configureApp?: (args: ConfigureAppArgs) => void;
16
17
  plugins?: readonly HubPlugin[];
17
18
  extraPgSchemas?: string[];
@@ -23,5 +24,6 @@ export type CreateHubServerOptions = {
23
24
  superuserDatabaseUrl: string;
24
25
  postgraphileDatabaseUrl: string;
25
26
  poolMax?: number;
27
+ liabilityConfig?: LiabilityConfig<LiabilityRefType>;
26
28
  };
27
- export declare function createHubServer({ configureApp, plugins, exportSchemaSDLPath, extraPgSchemas, enableChat, enablePlayground, port, runProcessors, superuserDatabaseUrl, postgraphileDatabaseUrl, poolMax, }: CreateHubServerOptions): HubServer;
29
+ export declare function createHubServer<LiabilityRefType extends string = string>({ configureApp, plugins, exportSchemaSDLPath, extraPgSchemas, enableChat, enablePlayground, port, runProcessors, superuserDatabaseUrl, postgraphileDatabaseUrl, poolMax, liabilityConfig, }: CreateHubServerOptions<LiabilityRefType>): HubServer;
@@ -1,9 +1,13 @@
1
1
  import { createServer as createNodeServer } from "node:http";
2
2
  import { grafserv } from "postgraphile/grafserv/express/v4";
3
- import postgraphile from "postgraphile";
3
+ import postgraphileImport from "postgraphile";
4
+ const postgraphile = typeof postgraphileImport === "function"
5
+ ? postgraphileImport
6
+ : postgraphileImport.default;
4
7
  import { createPreset, defaultPlugins } from "./graphile.config.js";
5
8
  import { createServerContext, closeServerContext, } from "../context.js";
6
9
  import { initializeTransferProcessors } from "../process-transfers/index.js";
10
+ import { startLiabilityExpirationProcessor } from "../liability/internal/index.js";
7
11
  import express from "express";
8
12
  import { logger } from "../logger.js";
9
13
  import cors from "./middleware/cors.js";
@@ -46,7 +50,7 @@ function createExpressServer(context) {
46
50
  });
47
51
  return app;
48
52
  }
49
- export function createHubServer({ configureApp, plugins, exportSchemaSDLPath, extraPgSchemas, enableChat, enablePlayground, port, runProcessors, superuserDatabaseUrl, postgraphileDatabaseUrl, poolMax, }) {
53
+ export function createHubServer({ configureApp, plugins, exportSchemaSDLPath, extraPgSchemas, enableChat, enablePlayground, port, runProcessors, superuserDatabaseUrl, postgraphileDatabaseUrl, poolMax, liabilityConfig, }) {
50
54
  const abortController = new AbortController();
51
55
  const context = createServerContext({
52
56
  superuserDatabaseUrl,
@@ -65,7 +69,7 @@ export function createHubServer({ configureApp, plugins, exportSchemaSDLPath, ex
65
69
  enablePlayground,
66
70
  poolMax,
67
71
  });
68
- const pgl = postgraphile.default(preset);
72
+ const pgl = postgraphile(preset);
69
73
  const serv = pgl.createServ(grafserv);
70
74
  if (configureApp) {
71
75
  configureApp({ app: expressServer, superuserPool: context.superuserPool });
@@ -82,6 +86,13 @@ export function createHubServer({ configureApp, plugins, exportSchemaSDLPath, ex
82
86
  signal: abortController.signal,
83
87
  pool: context.superuserPool,
84
88
  });
89
+ if (liabilityConfig) {
90
+ startLiabilityExpirationProcessor({
91
+ signal: abortController.signal,
92
+ pool: context.superuserPool,
93
+ liabilityConfig: liabilityConfig,
94
+ });
95
+ }
85
96
  }
86
97
  await serv.addTo(expressServer, nodeServer);
87
98
  await pgl.getSchema();
@@ -1,7 +1,8 @@
1
1
  import { Pool, PoolClient } from "pg";
2
- import { DbUser, DbBalance, DbHashChain, DbCasino, DbExperience, DbCurrency, DbBankroll } from "../db/types.js";
2
+ import { DbUser, DbPlayerBalance, DbHashChain, DbCasino, DbExperience, DbCurrency, DbHouseBankroll } from "../db/types.js";
3
3
  import { GraphQLClient } from "graphql-request";
4
4
  import { ServerOptions } from "../index.js";
5
+ export declare function uniqueTestId(): string;
5
6
  export type HubTestServer = {
6
7
  port: number;
7
8
  stop: () => Promise<void>;
@@ -16,10 +17,10 @@ export type HubTestServer = {
16
17
  export type TestServerConfig = {
17
18
  plugins?: ServerOptions["plugins"];
18
19
  userDatabaseMigrationsPath?: string;
19
- databaseName?: string;
20
+ testId: string;
20
21
  extraPgSchemas?: string[];
21
22
  };
22
- export declare function startTestServer({ plugins, userDatabaseMigrationsPath, databaseName, extraPgSchemas, }?: TestServerConfig): Promise<HubTestServer>;
23
+ export declare function startTestServer({ plugins, userDatabaseMigrationsPath, testId, extraPgSchemas, }: TestServerConfig): Promise<HubTestServer>;
23
24
  type PgClient = Pool | PoolClient;
24
25
  export declare function createUser(pgClient: PgClient, { casinoId, uname, }: {
25
26
  casinoId: DbCasino["id"];
@@ -30,7 +31,7 @@ export declare function createPlayerBalance(pgClient: PgClient, { userId, experi
30
31
  experienceId: DbExperience["id"];
31
32
  currencyKey: DbCurrency["key"];
32
33
  amount: number;
33
- }): Promise<DbBalance>;
34
+ }): Promise<DbPlayerBalance>;
34
35
  export declare function createHashChain(pgClient: PgClient, { userId, experienceId, casinoId, maxIterations, }: {
35
36
  userId: DbUser["id"];
36
37
  experienceId: DbExperience["id"];
@@ -54,10 +55,10 @@ export declare function createHouseBankroll(pgClient: PgClient, { casinoId, curr
54
55
  casinoId: DbCasino["id"];
55
56
  currencyKey: DbCurrency["key"];
56
57
  amount: number;
57
- }): Promise<DbBankroll>;
58
+ }): Promise<DbHouseBankroll>;
58
59
  export { createUser as createPlayer };
59
60
  export declare function getPlayerBalance(pgClient: PgClient, { userId, experienceId, currencyKey, }: {
60
61
  userId: DbUser["id"];
61
62
  experienceId: DbExperience["id"];
62
63
  currencyKey: DbCurrency["key"];
63
- }): Promise<DbBalance | null>;
64
+ }): Promise<DbPlayerBalance | null>;
@@ -8,8 +8,13 @@ import { exactlyOneRow, maybeOneRow } from "../db/index.js";
8
8
  import { GraphQLClient } from "graphql-request";
9
9
  import { defaultPlugins, runMigrations } from "../index.js";
10
10
  import { createHubServer } from "../server/index.js";
11
- export async function startTestServer({ plugins = [...defaultPlugins], userDatabaseMigrationsPath, databaseName, extraPgSchemas = [], } = {}) {
12
- const dbName = databaseName ?? `hub-test-${randomUUID().slice(0, 8)}`;
11
+ let testCounter = 0;
12
+ export function uniqueTestId() {
13
+ const workerId = process.env.VITEST_POOL_ID ?? "0";
14
+ return `${workerId}-${testCounter++}`;
15
+ }
16
+ export async function startTestServer({ plugins = [...defaultPlugins], userDatabaseMigrationsPath, testId, extraPgSchemas = [], }) {
17
+ const dbName = `hub-test-${testId}`;
13
18
  const connectionString = `postgres://postgres@localhost/${dbName}`;
14
19
  try {
15
20
  await execAsync(`psql -U postgres -c "CREATE DATABASE \\"${dbName}\\""`);
@@ -1,4 +1,8 @@
1
1
  import z from "zod/v4";
2
+ declare const BRAND: unique symbol;
3
+ export type Branded<Brand, T> = T & {
4
+ readonly [BRAND]: Brand;
5
+ };
2
6
  export declare function isUuid(input: any): boolean;
3
7
  export type Result<V, E> = {
4
8
  ok: true;
@@ -9,3 +13,4 @@ export type Result<V, E> = {
9
13
  };
10
14
  export declare function extractFirstZodErrorMessage(e: z.ZodError): string;
11
15
  export declare function uuidEqual(a: string, b: string): boolean;
16
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moneypot/hub",
3
- "version": "1.19.16",
3
+ "version": "1.20.0-dev.1",
4
4
  "author": "moneypot.com",
5
5
  "homepage": "https://moneypot.com/hub",
6
6
  "keywords": [
@@ -14,8 +14,6 @@
14
14
  "exports": {
15
15
  ".": "./dist/src/index.js",
16
16
  "./db": "./dist/src/db/index.js",
17
- "./db/types": "./dist/src/db/types.js",
18
- "./db/util": "./dist/src/db/util.js",
19
17
  "./config": "./dist/src/config.js",
20
18
  "./graphile": "./dist/src/graphile.js",
21
19
  "./graphql": "./dist/src/graphql.js",
@@ -26,6 +24,7 @@
26
24
  "./hash-chain": "./dist/src/hash-chain/index.js",
27
25
  "./logger": "./dist/src/logger.js",
28
26
  "./audit-log": "./dist/src/audit-log.js",
27
+ "./liability": "./dist/src/liability/public/index.js",
29
28
  "./test": "./dist/src/test/index.js"
30
29
  },
31
30
  "files": [
@@ -36,8 +35,8 @@
36
35
  "db-migrate": "./dist/cli/db-migrate.js"
37
36
  },
38
37
  "scripts": {
39
- "build:hub": "tsc && cp -R src/pg-versions dist/src/ && ./scripts/strip-sql.sh",
40
- "build": "pnpm run build:hub && pnpm run build-dashboard",
38
+ "build:hub": "rm -rf dist/src && tsc && cp -R src/pg-versions dist/src/ && ./scripts/strip-sql.sh",
39
+ "build": "pnpm run build:hub && rm -rf dist/dashboard && pnpm run build-dashboard",
41
40
  "check": "tsc --noEmit && pnpm run check-dashboard",
42
41
  "check-tests": "tsc -p tests/tsconfig.json --noEmit",
43
42
  "check-dashboard": "cd ./dashboard && pnpm run check",
@@ -56,7 +55,7 @@
56
55
  "dependencies": {
57
56
  "@graphile-contrib/pg-omit-archived": "4.0.0-rc.1",
58
57
  "@moneypot/hash-herald": "^1.0.0",
59
- "@moneypot/pg-upgrade-schema": "^2.1.0",
58
+ "@moneypot/pg-upgrade-schema": "^2.2.1",
60
59
  "dotenv": "^17.2.3",
61
60
  "express": "^5.2.1",
62
61
  "graphql": "^16.12.0",
@@ -68,15 +67,15 @@
68
67
  "pino": "^10.1.0",
69
68
  "postgraphile": "5.0.0-rc.3",
70
69
  "tsafe": "^1.8.12",
71
- "zod": "^4.1.13"
70
+ "zod": "^4.2.1"
72
71
  },
73
72
  "devDependencies": {
74
73
  "@eslint/js": "^9.39.2",
75
74
  "@graphql-codegen/cli": "^6.1.0",
76
- "@graphql-codegen/client-preset": "^5.2.1",
75
+ "@graphql-codegen/client-preset": "^5.2.2",
77
76
  "@graphql-typed-document-node/core": "^3.2.0",
78
77
  "@types/express": "^5.0.6",
79
- "@types/node": "^25.0.1",
78
+ "@types/node": "^25.0.3",
80
79
  "@types/pg": "^8.16.0",
81
80
  "@types/supertest": "^6.0.3",
82
81
  "eslint": "^9.39.2",
@@ -86,8 +85,8 @@
86
85
  "supertest": "^7.1.4",
87
86
  "tsx": "^4.21.0",
88
87
  "typescript": "^5.9.3",
89
- "typescript-eslint": "^8.49.0",
90
- "vitest": "^4.0.15"
88
+ "typescript-eslint": "^8.50.1",
89
+ "vitest": "^4.0.16"
91
90
  },
92
91
  "peerDependencies": {
93
92
  "graphile-config": "^1.0.0-rc.2"