@moneypot/hub 0.0.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 (106) hide show
  1. package/README.md +108 -0
  2. package/dist/cli/add-casino.d.ts +2 -0
  3. package/dist/cli/add-casino.js +116 -0
  4. package/dist/dashboard/assets/index-BtrbrisP.js +360 -0
  5. package/dist/dashboard/assets/index-tK7EUtyc.css +5 -0
  6. package/dist/dashboard/index.html +13 -0
  7. package/dist/src/GraphQLError.d.ts +8 -0
  8. package/dist/src/GraphQLError.js +79 -0
  9. package/dist/src/__generated__/fragment-masking.d.ts +19 -0
  10. package/dist/src/__generated__/fragment-masking.js +16 -0
  11. package/dist/src/__generated__/gql.d.ts +26 -0
  12. package/dist/src/__generated__/gql.js +15 -0
  13. package/dist/src/__generated__/graphql.d.ts +3129 -0
  14. package/dist/src/__generated__/graphql.js +454 -0
  15. package/dist/src/__generated__/index.d.ts +2 -0
  16. package/dist/src/__generated__/index.js +2 -0
  17. package/dist/src/config.d.ts +14 -0
  18. package/dist/src/config.js +57 -0
  19. package/dist/src/db/index.d.ts +89 -0
  20. package/dist/src/db/index.js +339 -0
  21. package/dist/src/db/internal.d.ts +7 -0
  22. package/dist/src/db/internal.js +33 -0
  23. package/dist/src/db/public.d.ts +7 -0
  24. package/dist/src/db/public.js +20 -0
  25. package/dist/src/db/types.d.ts +80 -0
  26. package/dist/src/db/types.js +1 -0
  27. package/dist/src/db/util.d.ts +6 -0
  28. package/dist/src/db/util.js +9 -0
  29. package/dist/src/express.d.ts +13 -0
  30. package/dist/src/express.js +1 -0
  31. package/dist/src/grafast.d.ts +1 -0
  32. package/dist/src/grafast.js +1 -0
  33. package/dist/src/graphile.d.ts +1 -0
  34. package/dist/src/graphile.js +1 -0
  35. package/dist/src/graphql-client.d.ts +6 -0
  36. package/dist/src/graphql-client.js +8 -0
  37. package/dist/src/graphql-queries.d.ts +18 -0
  38. package/dist/src/graphql-queries.js +123 -0
  39. package/dist/src/graphql.d.ts +1 -0
  40. package/dist/src/graphql.js +1 -0
  41. package/dist/src/index.d.ts +15 -0
  42. package/dist/src/index.js +65 -0
  43. package/dist/src/logger.d.ts +9 -0
  44. package/dist/src/logger.js +21 -0
  45. package/dist/src/pg-versions/001-schema.sql +456 -0
  46. package/dist/src/plugins/caas-add-casino.d.ts +1 -0
  47. package/dist/src/plugins/caas-add-casino.js +150 -0
  48. package/dist/src/plugins/caas-authenticate.d.ts +1 -0
  49. package/dist/src/plugins/caas-authenticate.js +175 -0
  50. package/dist/src/plugins/caas-balance-alert.d.ts +1 -0
  51. package/dist/src/plugins/caas-balance-alert.js +43 -0
  52. package/dist/src/plugins/caas-claim-faucet.d.ts +1 -0
  53. package/dist/src/plugins/caas-claim-faucet.js +85 -0
  54. package/dist/src/plugins/caas-current-x.d.ts +1 -0
  55. package/dist/src/plugins/caas-current-x.js +62 -0
  56. package/dist/src/plugins/caas-schema-prefix.d.ts +1 -0
  57. package/dist/src/plugins/caas-schema-prefix.js +25 -0
  58. package/dist/src/plugins/caas-user-balance-by-currency.d.ts +1 -0
  59. package/dist/src/plugins/caas-user-balance-by-currency.js +55 -0
  60. package/dist/src/plugins/caas-withdraw.d.ts +1 -0
  61. package/dist/src/plugins/caas-withdraw.js +133 -0
  62. package/dist/src/plugins/debug.d.ts +1 -0
  63. package/dist/src/plugins/debug.js +14 -0
  64. package/dist/src/plugins/hub-add-casino.d.ts +1 -0
  65. package/dist/src/plugins/hub-add-casino.js +150 -0
  66. package/dist/src/plugins/hub-authenticate.d.ts +1 -0
  67. package/dist/src/plugins/hub-authenticate.js +175 -0
  68. package/dist/src/plugins/hub-balance-alert.d.ts +1 -0
  69. package/dist/src/plugins/hub-balance-alert.js +43 -0
  70. package/dist/src/plugins/hub-claim-faucet.d.ts +1 -0
  71. package/dist/src/plugins/hub-claim-faucet.js +85 -0
  72. package/dist/src/plugins/hub-current-x.d.ts +1 -0
  73. package/dist/src/plugins/hub-current-x.js +62 -0
  74. package/dist/src/plugins/hub-schema-prefix.d.ts +1 -0
  75. package/dist/src/plugins/hub-schema-prefix.js +25 -0
  76. package/dist/src/plugins/hub-user-balance-by-currency.d.ts +1 -0
  77. package/dist/src/plugins/hub-user-balance-by-currency.js +55 -0
  78. package/dist/src/plugins/hub-withdraw.d.ts +1 -0
  79. package/dist/src/plugins/hub-withdraw.js +133 -0
  80. package/dist/src/plugins/id-to-node-id.d.ts +1 -0
  81. package/dist/src/plugins/id-to-node-id.js +31 -0
  82. package/dist/src/plugins/validate-fields.d.ts +1 -0
  83. package/dist/src/plugins/validate-fields.js +61 -0
  84. package/dist/src/process-transfers.d.ts +7 -0
  85. package/dist/src/process-transfers.js +413 -0
  86. package/dist/src/process-withdrawal-request.d.ts +5 -0
  87. package/dist/src/process-withdrawal-request.js +129 -0
  88. package/dist/src/server/graphile.config.d.ts +33 -0
  89. package/dist/src/server/graphile.config.js +166 -0
  90. package/dist/src/server/handle-errors.d.ts +10 -0
  91. package/dist/src/server/handle-errors.js +88 -0
  92. package/dist/src/server/index.d.ts +2 -0
  93. package/dist/src/server/index.js +69 -0
  94. package/dist/src/server/middleware/authentication.d.ts +4 -0
  95. package/dist/src/server/middleware/authentication.js +55 -0
  96. package/dist/src/server/middleware/cors.d.ts +3 -0
  97. package/dist/src/server/middleware/cors.js +14 -0
  98. package/dist/src/services/jwt-service.d.ts +13 -0
  99. package/dist/src/services/jwt-service.js +131 -0
  100. package/dist/src/smart-tags.d.ts +1 -0
  101. package/dist/src/smart-tags.js +55 -0
  102. package/dist/src/util.d.ts +12 -0
  103. package/dist/src/util.js +4 -0
  104. package/dist/src/validate.d.ts +9 -0
  105. package/dist/src/validate.js +91 -0
  106. package/package.json +69 -0
@@ -0,0 +1,150 @@
1
+ import { constant, context, object, sideEffect } from "postgraphile/grafast";
2
+ import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
3
+ import { exactlyOneRow } from "../db/util.js";
4
+ import { gql as generatedGql } from "../__generated__/gql.js";
5
+ import { GraphQLClient } from "graphql-request";
6
+ import { GraphQLError } from "graphql";
7
+ import { superuserPool, upsertCurrencies, withPgPoolTransaction, } from "../db/index.js";
8
+ import { logger } from "../logger.js";
9
+ import { assert, is } from "tsafe";
10
+ import * as jwtService from "../services/jwt-service.js";
11
+ import { startTransferProcessor } from "../process-transfers.js";
12
+ const GET_CURRENT_CONTROLLER = generatedGql(`
13
+ query GetCurrentController {
14
+ currentController {
15
+ id
16
+ }
17
+ allCurrencies {
18
+ nodes {
19
+ id
20
+ displayUnitName
21
+ displayUnitScale
22
+ }
23
+ }
24
+ }
25
+ `);
26
+ export const CaasAddCasinoPlugin = makeExtendSchemaPlugin((build) => {
27
+ const casinoTable = build.input.pgRegistry.pgResources.caas_casino;
28
+ return {
29
+ typeDefs: gql `
30
+ input CaasAddCasinoInput {
31
+ name: String!
32
+ baseUrl: String!
33
+ graphqlUrl: String!
34
+ apiKey: String!
35
+ }
36
+
37
+ type CaasAddCasinoPayload {
38
+ casino: CaasCasino
39
+ query: Query
40
+ }
41
+
42
+ extend type Mutation {
43
+ caasAddCasino(input: CaasAddCasinoInput!): CaasAddCasinoPayload
44
+ }
45
+ `,
46
+ plans: {
47
+ Mutation: {
48
+ caasAddCasino(_, { $input }) {
49
+ const $identity = context().get("identity");
50
+ const $casinoId = sideEffect([$input, $identity], ([input, identity]) => {
51
+ return withPgPoolTransaction(superuserPool, async (pgClient) => {
52
+ if (identity?.kind !== "operator") {
53
+ throw new GraphQLError("Unauthorized");
54
+ }
55
+ assert(is(input));
56
+ const { name, baseUrl, graphqlUrl, apiKey } = input;
57
+ const graphqlClient = new GraphQLClient(graphqlUrl, {
58
+ headers: {
59
+ Authorization: `apikey:${apiKey}`,
60
+ },
61
+ });
62
+ console.log(`[caasAddCasino] Making request to ${graphqlUrl}`);
63
+ const result = await graphqlClient
64
+ .request(GET_CURRENT_CONTROLLER)
65
+ .catch((e) => {
66
+ if (e.cause?.code === "ECONNREFUSED" ||
67
+ e.cause?.code === "ENOTFOUND") {
68
+ throw new GraphQLError(`Cannot connect to graphqlUrl`);
69
+ }
70
+ throw e;
71
+ });
72
+ if (!result) {
73
+ throw new GraphQLError("Invalid API key");
74
+ }
75
+ if (!result.currentController) {
76
+ throw new GraphQLError("Invalid API key");
77
+ }
78
+ let casino;
79
+ try {
80
+ casino = await pgClient
81
+ .query({
82
+ text: `
83
+ INSERT INTO caas.casino(name, base_url, graphql_url)
84
+ VALUES($1, $2, $3)
85
+ returning id
86
+ `,
87
+ values: [name, baseUrl, graphqlUrl],
88
+ })
89
+ .then((res) => {
90
+ console.log("res", res.rows);
91
+ return res;
92
+ })
93
+ .then(exactlyOneRow);
94
+ }
95
+ catch (e) {
96
+ if (e instanceof Error &&
97
+ "code" in e &&
98
+ e.code === "23505" &&
99
+ "constraint" in e) {
100
+ switch (e.constraint) {
101
+ case "casino_graphql_url_idx":
102
+ throw new GraphQLError("Casino with that graphqlUrl already exists");
103
+ case "casino_base_url_idx":
104
+ throw new GraphQLError("Casino with that baseUrl already exists");
105
+ default:
106
+ throw new GraphQLError(`Duplicate constraint violation: ${e.constraint}`);
107
+ }
108
+ }
109
+ logger.error("Error adding casino", e);
110
+ throw e;
111
+ }
112
+ await pgClient.query({
113
+ text: `
114
+ INSERT INTO caas.casino_secret(id, controller_id, api_key)
115
+ VALUES($1, $2, $3)
116
+ `,
117
+ values: [casino.id, result.currentController.id, apiKey],
118
+ });
119
+ const currencies = result.allCurrencies?.nodes.flatMap((x) => x || []) || [];
120
+ await upsertCurrencies(pgClient, {
121
+ casinoId: casino.id,
122
+ currencies,
123
+ });
124
+ await pgClient.query({
125
+ text: `
126
+ INSERT INTO caas.bankroll (casino_id, currency_key)
127
+ SELECT casino_id, key
128
+ FROM caas.currency
129
+ WHERE casino_id = $1
130
+ `,
131
+ values: [casino.id],
132
+ });
133
+ logger.info(`Fetching JWKS for new casino from ${graphqlUrl}...`);
134
+ await jwtService.refreshCasinoJwksTask(pgClient, {
135
+ graphqlClient,
136
+ casinoId: casino.id,
137
+ });
138
+ startTransferProcessor({ casinoId: casino.id });
139
+ return casino.id;
140
+ });
141
+ });
142
+ return object({
143
+ casino: casinoTable.get({ id: $casinoId }),
144
+ query: constant(true),
145
+ });
146
+ },
147
+ },
148
+ },
149
+ };
150
+ });
@@ -0,0 +1 @@
1
+ export declare const CaasAuthenticatePlugin: GraphileConfig.Plugin;
@@ -0,0 +1,175 @@
1
+ import { GraphQLError } from "graphql";
2
+ import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
3
+ import { assert, is } from "tsafe";
4
+ import { GET_USER_FROM_USER_TOKEN } from "../graphql-queries.js";
5
+ import { exactlyOneRow, maybeOneRow } from "../db/util.js";
6
+ import { createGraphqlClient } from "../graphql-client.js";
7
+ import { constant, context, error, object, sideEffect, } from "postgraphile/grafast";
8
+ import { superuserPool, withPgPoolTransaction, } from "../db/index.js";
9
+ import { logger } from "../logger.js";
10
+ import * as jwtService from "../services/jwt-service.js";
11
+ import { extractGraphQLErrorInfo, isGraphQLError } from "../GraphQLError.js";
12
+ export const CaasAuthenticatePlugin = makeExtendSchemaPlugin(() => {
13
+ return {
14
+ typeDefs: gql `
15
+ input CaasAuthenticateInput {
16
+ casinoBaseUrl: String!
17
+ userToken: String!
18
+ }
19
+
20
+ type CaasAuthenticateSuccess {
21
+ experienceId: UUID!
22
+ sessionKey: UUID!
23
+ userId: UUID!
24
+ uname: String!
25
+ }
26
+
27
+ type CaasAuthenticatePayload {
28
+ query: Query
29
+ success: CaasAuthenticateSuccess
30
+ }
31
+
32
+ extend type Mutation {
33
+ caasAuthenticate(input: CaasAuthenticateInput!): CaasAuthenticatePayload
34
+ }
35
+ `,
36
+ plans: {
37
+ Mutation: {
38
+ caasAuthenticate(_, { $input }) {
39
+ try {
40
+ const $context = context();
41
+ const $success = sideEffect([$input, $context], ([input, context]) => {
42
+ return withPgPoolTransaction(superuserPool, async (pgClient) => {
43
+ assert(is(input));
44
+ const { userToken: jwt, casinoBaseUrl } = input;
45
+ const casino = await pgClient
46
+ .query({
47
+ text: `
48
+ SELECT c.*, s.api_key
49
+ FROM caas.casino c
50
+ LEFT JOIN caas.casino_secret s ON c.id = s.id
51
+ WHERE c.base_url = $1`,
52
+ values: [casinoBaseUrl],
53
+ })
54
+ .then(maybeOneRow);
55
+ if (!casino) {
56
+ throw new GraphQLError(`CAAS is unaware of casino with a base url of provided casinoBaseUrl`);
57
+ }
58
+ if (!casino.api_key) {
59
+ throw new GraphQLError("Casino secret not configured");
60
+ }
61
+ const graphqlClient = createGraphqlClient({
62
+ graphqlUrl: casino.graphql_url,
63
+ apiKey: casino.api_key,
64
+ });
65
+ const verifyResult = await jwtService.verifyJwtFromDbCacheAndEnsureNotAlreadyUsed(pgClient, {
66
+ casinoId: casino.id,
67
+ jwt,
68
+ });
69
+ if (!verifyResult.ok) {
70
+ throw new GraphQLError(`Error verifying userToken: ${verifyResult.error}`);
71
+ }
72
+ const { userToken } = verifyResult.value;
73
+ let res;
74
+ try {
75
+ res = await graphqlClient.request(GET_USER_FROM_USER_TOKEN, {
76
+ token: userToken,
77
+ });
78
+ }
79
+ catch (e) {
80
+ logger.error(`[caasAuthenticate] Error when making GET_USER_FROM_USER_TOKEN to casino:`, e);
81
+ if (isGraphQLError(e)) {
82
+ const errorInfo = extractGraphQLErrorInfo(e);
83
+ if (errorInfo.code === "UNAUTHENTICATED") {
84
+ throw new GraphQLError("Invalid api key");
85
+ }
86
+ else {
87
+ throw new GraphQLError(errorInfo.message);
88
+ }
89
+ }
90
+ throw error;
91
+ }
92
+ const result = res.userFromUserToken;
93
+ if (!result || !result.user || !result.experience) {
94
+ return null;
95
+ }
96
+ const mpUserId = result.user.id;
97
+ assert(mpUserId);
98
+ const uname = result.user.uname;
99
+ assert(uname);
100
+ const dbUser = await pgClient
101
+ .query({
102
+ text: `
103
+ INSERT INTO caas.user(casino_id, mp_user_id, uname)
104
+ VALUES($1, $2, $3)
105
+ ON CONFLICT (casino_id, mp_user_id) DO UPDATE
106
+ SET uname = EXCLUDED.uname
107
+ RETURNING id, uname
108
+ `,
109
+ values: [casino.id, mpUserId, uname],
110
+ })
111
+ .then(exactlyOneRow);
112
+ const userId = dbUser.id;
113
+ const mpExperience = result.experience;
114
+ assert(mpExperience);
115
+ const dbExperience = await pgClient
116
+ .query({
117
+ text: `
118
+ INSERT INTO caas.experience(casino_id, mp_experience_id, name)
119
+ VALUES($1, $2, $3)
120
+ ON CONFLICT (casino_id, mp_experience_id) DO UPDATE
121
+ SET name = EXCLUDED.name
122
+ RETURNING id
123
+ `,
124
+ values: [casino.id, mpExperience.id, mpExperience.name],
125
+ })
126
+ .then(exactlyOneRow);
127
+ const dbSession = await pgClient
128
+ .query({
129
+ text: `
130
+ INSERT INTO caas.session(casino_id, user_id, experience_id, user_token)
131
+ VALUES($1, $2, $3, $4)
132
+ RETURNING id, key
133
+ `,
134
+ values: [casino.id, userId, dbExperience.id, userToken],
135
+ })
136
+ .then(exactlyOneRow);
137
+ const ret = {
138
+ userId,
139
+ uname: dbUser.uname,
140
+ experienceId: dbExperience.id,
141
+ sessionKey: dbSession.key,
142
+ };
143
+ context.identity = {
144
+ kind: "user",
145
+ session: {
146
+ user_id: userId,
147
+ mp_user_id: mpUserId,
148
+ casino_id: casino.id,
149
+ experience_id: dbExperience.id,
150
+ session_id: dbSession.id,
151
+ },
152
+ };
153
+ context.pgSettings = {
154
+ "session.user_id": userId,
155
+ "session.casino_id": casino.id,
156
+ "session.experience_id": dbExperience.id,
157
+ "session.session_id": dbSession.id,
158
+ };
159
+ return ret;
160
+ });
161
+ });
162
+ return object({
163
+ query: constant(true),
164
+ success: $success,
165
+ });
166
+ }
167
+ catch (error) {
168
+ logger.error(error);
169
+ throw error;
170
+ }
171
+ },
172
+ },
173
+ },
174
+ };
175
+ });
@@ -0,0 +1 @@
1
+ export declare const CaasBalanceAlertPlugin: GraphileConfig.Plugin;
@@ -0,0 +1,43 @@
1
+ import { makeExtendSchemaPlugin, gql } from "postgraphile/utils";
2
+ import { context, lambda, listen } from "postgraphile/grafast";
3
+ import { jsonParse } from "postgraphile/@dataplan/json";
4
+ export const CaasBalanceAlertPlugin = makeExtendSchemaPlugin(() => {
5
+ return {
6
+ typeDefs: gql `
7
+ extend type Subscription {
8
+ caasBalanceAlert: CaasBalanceAlertPayload
9
+ }
10
+
11
+ type CaasBalanceAlertPayload {
12
+ currencyKey: String
13
+ }
14
+ `,
15
+ plans: {
16
+ Subscription: {
17
+ caasBalanceAlert: {
18
+ subscribePlan(_$root) {
19
+ const $pgSubscriber = context().get("pgSubscriber");
20
+ const $identity = context().get("identity");
21
+ const $channelKey = lambda($identity, (identity) => {
22
+ if (identity?.kind === "user") {
23
+ return `caas:user:${identity.session.user_id}:balance_alert`;
24
+ }
25
+ else {
26
+ return "";
27
+ }
28
+ });
29
+ return listen($pgSubscriber, $channelKey, jsonParse);
30
+ },
31
+ plan($event) {
32
+ return $event;
33
+ },
34
+ },
35
+ },
36
+ CaasBalanceAlertPayload: {
37
+ currencyKey($event) {
38
+ return $event.get("currency_key");
39
+ },
40
+ },
41
+ },
42
+ };
43
+ });
@@ -0,0 +1 @@
1
+ export declare const CaasClaimFaucetPlugin: GraphileConfig.Plugin;
@@ -0,0 +1,85 @@
1
+ import { object } from "grafast";
2
+ import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
3
+ import { superuserPool, withPgPoolTransaction } from "../db/index.js";
4
+ import { constant, context, sideEffect } from "postgraphile/grafast";
5
+ const CLAIM_AMOUNT = 1000;
6
+ export const CaasClaimFaucetPlugin = makeExtendSchemaPlugin(() => {
7
+ return {
8
+ typeDefs: gql `
9
+ type CaasClaimFaucetPayload {
10
+ success: Boolean!
11
+ query: Query
12
+ }
13
+
14
+ extend type Mutation {
15
+ caasClaimFaucet: CaasClaimFaucetPayload
16
+ }
17
+ `,
18
+ plans: {
19
+ Mutation: {
20
+ caasClaimFaucet() {
21
+ const $identity = context().get("identity");
22
+ const $result = sideEffect([$identity], ([identity]) => {
23
+ if (identity?.kind !== "user") {
24
+ throw new Error("Must be logged in as user");
25
+ }
26
+ const { session } = identity;
27
+ return withPgPoolTransaction(superuserPool, async (pgClient) => {
28
+ await upsertPlayCurrency(pgClient, session.casino_id);
29
+ await pgClient.query({
30
+ text: `
31
+ insert into caas.faucet_claim (user_id, casino_id, experience_id, currency_key, amount)
32
+ values ($1, $2, $3, $4, $5)
33
+ `,
34
+ values: [
35
+ session.user_id,
36
+ session.casino_id,
37
+ session.experience_id,
38
+ "PLAY",
39
+ CLAIM_AMOUNT,
40
+ ],
41
+ });
42
+ await pgClient.query({
43
+ text: `
44
+ INSERT INTO caas.balance (user_id, experience_id, casino_id, currency_key, amount)
45
+ VALUES ($1, $2, $3, $4, $5)
46
+ ON CONFLICT (user_id, experience_id, casino_id, currency_key) DO UPDATE
47
+ SET amount = balance.amount + EXCLUDED.amount
48
+ `,
49
+ values: [
50
+ session.user_id,
51
+ session.experience_id,
52
+ session.casino_id,
53
+ "PLAY",
54
+ CLAIM_AMOUNT,
55
+ ],
56
+ });
57
+ return true;
58
+ });
59
+ });
60
+ return object({
61
+ result: $result,
62
+ });
63
+ },
64
+ },
65
+ CaasClaimFaucetPayload: {
66
+ success($data) {
67
+ return $data.get("result");
68
+ },
69
+ query() {
70
+ return constant(true);
71
+ },
72
+ },
73
+ },
74
+ };
75
+ });
76
+ async function upsertPlayCurrency(pgClient, casinoId) {
77
+ return pgClient.query({
78
+ text: `
79
+ insert into caas.currency (casino_id, key, display_unit_name, display_unit_scale)
80
+ values ($1, 'PLAY', 'tokens', 1)
81
+ on conflict (casino_id, key) do nothing
82
+ `,
83
+ values: [casinoId],
84
+ });
85
+ }
@@ -0,0 +1 @@
1
+ export declare const CaasCurrentXPlugin: GraphileConfig.Plugin;
@@ -0,0 +1,62 @@
1
+ import { gql, makeExtendSchemaPlugin } from "graphile-utils";
2
+ import { context, inhibitOnNull, lambda } from "postgraphile/grafast";
3
+ export const CaasCurrentXPlugin = makeExtendSchemaPlugin((build) => {
4
+ const userTable = build.input.pgRegistry.pgResources.caas_user;
5
+ const casinoTable = build.input.pgRegistry.pgResources.caas_casino;
6
+ const experienceTable = build.input.pgRegistry.pgResources.caas_experience;
7
+ const sessionTable = build.input.pgRegistry.pgResources.caas_session;
8
+ return {
9
+ typeDefs: gql `
10
+ extend type Query {
11
+ caasCurrentUser: CaasUser
12
+ caasCurrentCasino: CaasCasino
13
+ caasCurrentExperience: CaasExperience
14
+ caasCurrentSession: CaasSession
15
+ }
16
+ `,
17
+ plans: {
18
+ Query: {
19
+ caasCurrentUser() {
20
+ const $identity = context().get("identity");
21
+ const $userId = lambda($identity, (identity) => {
22
+ if (identity?.kind === "user") {
23
+ return identity.session.user_id;
24
+ }
25
+ return null;
26
+ });
27
+ return userTable.get({ id: inhibitOnNull($userId) });
28
+ },
29
+ caasCurrentCasino() {
30
+ const $identity = context().get("identity");
31
+ const $casinoId = lambda($identity, (identity) => {
32
+ if (identity?.kind === "user") {
33
+ return identity.session.casino_id;
34
+ }
35
+ return null;
36
+ });
37
+ return casinoTable.get({ id: inhibitOnNull($casinoId) });
38
+ },
39
+ caasCurrentExperience() {
40
+ const $identity = context().get("identity");
41
+ const $experienceId = lambda($identity, (identity) => {
42
+ if (identity?.kind === "user") {
43
+ return identity.session.experience_id;
44
+ }
45
+ return null;
46
+ });
47
+ return experienceTable.get({ id: inhibitOnNull($experienceId) });
48
+ },
49
+ caasCurrentSession() {
50
+ const $identity = context().get("identity");
51
+ const $sessionId = lambda($identity, (identity) => {
52
+ if (identity?.kind === "user") {
53
+ return identity.session.session_id;
54
+ }
55
+ return null;
56
+ });
57
+ return sessionTable.get({ id: inhibitOnNull($sessionId) });
58
+ },
59
+ },
60
+ },
61
+ };
62
+ });
@@ -0,0 +1 @@
1
+ export declare const CaasPrefixPlugin: GraphileConfig.Plugin;
@@ -0,0 +1,25 @@
1
+ export const CaasPrefixPlugin = {
2
+ name: "CaasPrefixPlugin",
3
+ version: "1.0.0",
4
+ after: ["PgTablesPlugin"],
5
+ inflection: {
6
+ replace: {
7
+ _schemaPrefix(previous, options, { pgNamespace, serviceName, }) {
8
+ const pgService = options.pgServices?.find((db) => db.name === serviceName);
9
+ const databasePrefix = serviceName === "main" ? "" : `${serviceName}_`;
10
+ let schemaPrefix;
11
+ if (pgNamespace.nspname === "caas" ||
12
+ pgNamespace.nspname.startsWith("caas_")) {
13
+ schemaPrefix = `${pgNamespace.nspname}_`;
14
+ }
15
+ else if (pgNamespace.nspname === pgService?.schemas?.[0]) {
16
+ schemaPrefix = "";
17
+ }
18
+ else {
19
+ schemaPrefix = `${pgNamespace.nspname}_`;
20
+ }
21
+ return `${databasePrefix}${schemaPrefix}`;
22
+ },
23
+ },
24
+ },
25
+ };
@@ -0,0 +1 @@
1
+ export declare const CaasUserBalanceByCurrencyPlugin: GraphileConfig.Plugin;
@@ -0,0 +1,55 @@
1
+ import { access, context, loadOne, object, } from "postgraphile/grafast";
2
+ import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
3
+ import { superuserPool } from "../db/index.js";
4
+ import { pgSelectSingleFromRecord, } from "postgraphile/@dataplan/pg";
5
+ export const CaasUserBalanceByCurrencyPlugin = makeExtendSchemaPlugin((build) => {
6
+ const balances = build.input.pgRegistry.pgResources.caas_balance;
7
+ return {
8
+ typeDefs: gql `
9
+ extend type CaasUser {
10
+ balanceByCurrency(currency: String!): CaasBalance
11
+ }
12
+ `,
13
+ plans: {
14
+ CaasUser: {
15
+ balanceByCurrency: ($record, { $currency }) => {
16
+ const $identity = context().get("identity");
17
+ const $params = object({
18
+ currency: $currency,
19
+ targetUserId: $record.get("id"),
20
+ casino_id: access($identity, ["session", "casino_id"]),
21
+ experience_id: access($identity, ["session", "experience_id"]),
22
+ });
23
+ const $balance = loadOne($params, batchGetUserBalanceByCurrency);
24
+ return pgSelectSingleFromRecord(balances, $balance);
25
+ },
26
+ },
27
+ },
28
+ };
29
+ });
30
+ async function batchGetUserBalanceByCurrency(paramsArray) {
31
+ const values = [];
32
+ const valuePlaceholders = [];
33
+ paramsArray.forEach((p, index) => {
34
+ const baseIndex = index * 4 + 1;
35
+ valuePlaceholders.push(`($${baseIndex}, $${baseIndex + 1}::uuid, $${baseIndex + 2}::uuid, $${baseIndex + 3}::uuid)`);
36
+ values.push(p.currency, p.targetUserId, p.casino_id, p.experience_id);
37
+ });
38
+ const sql = `
39
+ SELECT b.*
40
+ FROM caas.balance b
41
+ JOIN (
42
+ VALUES
43
+ ${valuePlaceholders.join(",\n ")}
44
+ ) AS vals(currency_key, user_id, casino_id, experience_id)
45
+ ON b.currency_key = vals.currency_key
46
+ AND b.user_id = vals.user_id
47
+ AND b.casino_id = vals.casino_id
48
+ AND b.experience_id = vals.experience_id
49
+ `;
50
+ const { rows } = await superuserPool.query(sql, values);
51
+ return paramsArray.map((p) => rows.find((row) => row.currency_key === p.currency &&
52
+ row.user_id === p.targetUserId &&
53
+ row.casino_id === p.casino_id &&
54
+ row.experience_id === p.experience_id));
55
+ }
@@ -0,0 +1 @@
1
+ export declare const CaasWithdrawPlugin: GraphileConfig.Plugin;