@nlabs/reaktor 0.1.2 → 0.1.4

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 (145) hide show
  1. package/.DS_Store +0 -0
  2. package/.eslintrc +18 -0
  3. package/lib/config.d.ts +21 -0
  4. package/lib/config.js +130 -0
  5. package/lib/data/conversations.d.ts +6 -0
  6. package/lib/data/conversations.js +197 -0
  7. package/lib/data/dynamodb.d.ts +8 -0
  8. package/lib/data/dynamodb.js +139 -0
  9. package/lib/data/email.d.ts +7 -0
  10. package/lib/data/email.js +163 -0
  11. package/lib/data/files.d.ts +16 -0
  12. package/lib/data/files.js +406 -0
  13. package/lib/data/groups.d.ts +13 -0
  14. package/lib/data/groups.js +354 -0
  15. package/lib/data/images.d.ts +12 -0
  16. package/lib/data/images.js +667 -0
  17. package/{src/data/index.ts → lib/data/index.d.ts} +1 -5
  18. package/lib/data/index.js +24 -0
  19. package/lib/data/ios.d.ts +6 -0
  20. package/lib/data/ios.js +302 -0
  21. package/lib/data/locations.d.ts +3 -0
  22. package/lib/data/locations.js +132 -0
  23. package/lib/data/messages.d.ts +9 -0
  24. package/lib/data/messages.js +248 -0
  25. package/lib/data/notifications.d.ts +5 -0
  26. package/lib/data/notifications.js +42 -0
  27. package/lib/data/payments.d.ts +11 -0
  28. package/lib/data/payments.js +748 -0
  29. package/lib/data/posts.d.ts +22 -0
  30. package/lib/data/posts.js +579 -0
  31. package/lib/data/reactions.d.ts +6 -0
  32. package/lib/data/reactions.js +218 -0
  33. package/lib/data/s3.d.ts +6 -0
  34. package/lib/data/s3.js +103 -0
  35. package/lib/data/search.d.ts +3 -0
  36. package/lib/data/search.js +98 -0
  37. package/lib/data/sms.d.ts +3 -0
  38. package/lib/data/sms.js +59 -0
  39. package/lib/data/subscription.d.ts +7 -0
  40. package/lib/data/subscription.js +284 -0
  41. package/lib/data/tags.d.ts +14 -0
  42. package/lib/data/tags.js +304 -0
  43. package/lib/data/users.d.ts +12 -0
  44. package/lib/data/users.js +310 -0
  45. package/lib/index.d.ts +3 -0
  46. package/lib/index.js +8 -0
  47. package/lib/types/apps.d.ts +43 -0
  48. package/lib/types/apps.js +2 -0
  49. package/lib/types/arangodb.d.ts +17 -0
  50. package/lib/types/arangodb.js +2 -0
  51. package/lib/types/auth.d.ts +10 -0
  52. package/lib/types/auth.js +2 -0
  53. package/lib/types/conversations.d.ts +6 -0
  54. package/lib/types/conversations.js +2 -0
  55. package/lib/types/email.d.ts +12 -0
  56. package/lib/types/email.js +2 -0
  57. package/lib/types/files.d.ts +26 -0
  58. package/lib/types/files.js +2 -0
  59. package/lib/types/google.d.ts +27 -0
  60. package/lib/types/google.js +2 -0
  61. package/lib/types/groups.d.ts +21 -0
  62. package/lib/types/groups.js +2 -0
  63. package/lib/types/images.d.ts +24 -0
  64. package/lib/types/images.js +2 -0
  65. package/{src/types/index.ts → lib/types/index.d.ts} +0 -4
  66. package/lib/types/index.js +22 -0
  67. package/lib/types/locations.d.ts +20 -0
  68. package/lib/types/locations.js +2 -0
  69. package/lib/types/messages.d.ts +12 -0
  70. package/lib/types/messages.js +2 -0
  71. package/lib/types/notifications.d.ts +19 -0
  72. package/lib/types/notifications.js +2 -0
  73. package/lib/types/payments.d.ts +114 -0
  74. package/lib/types/payments.js +2 -0
  75. package/lib/types/posts.d.ts +28 -0
  76. package/lib/types/posts.js +2 -0
  77. package/lib/types/reactions.d.ts +4 -0
  78. package/lib/types/reactions.js +2 -0
  79. package/lib/types/tags.d.ts +9 -0
  80. package/lib/types/tags.js +2 -0
  81. package/lib/types/users.d.ts +78 -0
  82. package/lib/types/users.js +2 -0
  83. package/lib/utils/analytics.d.ts +3 -0
  84. package/lib/utils/analytics.js +47 -0
  85. package/lib/utils/arangodb.d.ts +9 -0
  86. package/lib/utils/arangodb.js +98 -0
  87. package/lib/utils/auth.d.ts +7 -0
  88. package/lib/utils/auth.js +80 -0
  89. package/lib/utils/graphql.d.ts +1 -0
  90. package/lib/utils/graphql.js +7 -0
  91. package/{src/utils/index.ts → lib/utils/index.d.ts} +0 -4
  92. package/lib/utils/index.js +11 -0
  93. package/lib/utils/objects.d.ts +3 -0
  94. package/lib/utils/objects.js +34 -0
  95. package/lib/utils/redis.d.ts +1 -0
  96. package/lib/utils/redis.js +15 -0
  97. package/package.json +8 -7
  98. package/.vscode/extensions.json +0 -15
  99. package/.vscode/settings.json +0 -82
  100. package/lex.config.js +0 -4
  101. package/src/config.ts +0 -127
  102. package/src/data/conversations.ts +0 -181
  103. package/src/data/dynamodb.ts +0 -157
  104. package/src/data/email.ts +0 -163
  105. package/src/data/files.ts +0 -352
  106. package/src/data/groups.ts +0 -308
  107. package/src/data/images.ts +0 -606
  108. package/src/data/ios.ts +0 -249
  109. package/src/data/locations.ts +0 -114
  110. package/src/data/messages.ts +0 -237
  111. package/src/data/notifications.ts +0 -48
  112. package/src/data/payments.ts +0 -675
  113. package/src/data/posts.ts +0 -580
  114. package/src/data/reactions.ts +0 -186
  115. package/src/data/s3.ts +0 -117
  116. package/src/data/search.ts +0 -74
  117. package/src/data/sms.ts +0 -60
  118. package/src/data/subscription.ts +0 -228
  119. package/src/data/tags.ts +0 -230
  120. package/src/data/users.ts +0 -254
  121. package/src/index.ts +0 -7
  122. package/src/types/apps.ts +0 -56
  123. package/src/types/arangodb.ts +0 -23
  124. package/src/types/auth.ts +0 -20
  125. package/src/types/conversations.ts +0 -11
  126. package/src/types/email.ts +0 -17
  127. package/src/types/files.ts +0 -31
  128. package/src/types/google.ts +0 -37
  129. package/src/types/groups.ts +0 -27
  130. package/src/types/images.ts +0 -32
  131. package/src/types/locations.ts +0 -24
  132. package/src/types/messages.ts +0 -16
  133. package/src/types/notifications.ts +0 -26
  134. package/src/types/payments.ts +0 -129
  135. package/src/types/posts.ts +0 -34
  136. package/src/types/reactions.ts +0 -8
  137. package/src/types/tags.ts +0 -13
  138. package/src/types/users.ts +0 -89
  139. package/src/utils/analytics.ts +0 -41
  140. package/src/utils/arangodb.ts +0 -100
  141. package/src/utils/auth.ts +0 -61
  142. package/src/utils/graphql.ts +0 -7
  143. package/src/utils/objects.ts +0 -34
  144. package/src/utils/redis.ts +0 -17
  145. package/tsconfig.json +0 -45
@@ -1,675 +0,0 @@
1
- import {createHash, parseChar, parseId, parseNum, parseString, parseVarChar} from '@nlabs/utils';
2
- import {aql} from 'arangojs';
3
- import {AqlQuery} from 'arangojs/lib/cjs/aql-query';
4
- import {ArrayCursor} from 'arangojs/lib/cjs/cursor';
5
- import {UserError} from 'graphql-errors';
6
- import isEmpty from 'lodash/isEmpty';
7
- import {DateTime} from 'luxon';
8
- import * as stripe from 'stripe';
9
-
10
- import {Config} from '../config';
11
- import {ApiContext, PaymentBankAccount, PaymentCardType, PaymentCharge, PaymentTransfer, UserType} from '../types';
12
- import {logError} from '../utils/analytics';
13
- import {useDb} from '../utils/arangodb';
14
- import {getUser} from './users';
15
-
16
- /**
17
- * Copyright (c) 2019-Present, Nitrogen Labs, Inc.
18
- * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
19
- */
20
- const eventCategory: string = 'payments';
21
-
22
- export const addCustomerAccount = (context: ApiContext): Promise<boolean> => {
23
- const action: string = 'addCustomerAccount';
24
- const {database, userId: sessionId, username} = context;
25
-
26
- // Stripe
27
- const stripeClient = stripe(Config.get('stripe.token'));
28
-
29
- return stripeClient.customers
30
- .create({
31
- metadata: {
32
- userId: sessionId,
33
- username
34
- }
35
- })
36
- .then((customer) => {
37
- // Create session
38
- const now: number = Date.now();
39
- const update: UserType = {
40
- modified: now,
41
- stripeCustomerId: customer.id
42
- };
43
-
44
- const aqlQry: AqlQuery = aql`UPDATE ${sessionId} WITH ${update} IN users LIMIT 1 RETURN NEW`;
45
-
46
- return useDb(database).query(aqlQry)
47
- .then((cursor: ArrayCursor) => cursor.next())
48
- .then((updatedUser: UserType = {}) => !isEmpty(updatedUser))
49
- .catch((error: Error) => logError({
50
- action,
51
- category: eventCategory,
52
- label: 'db_error'
53
- }, error, context).then(() => null));
54
- });
55
- };
56
-
57
- export const addPaymentAccountBank = (context: ApiContext, bankAccount: PaymentBankAccount): Promise<boolean> => {
58
- const action: string = 'addPaymentAccountBank';
59
- const {database, userId: sessionId} = context;
60
-
61
- // Params
62
- const {
63
- accountNumber,
64
- fullName,
65
- routing
66
- } = bankAccount;
67
-
68
- const formatAccount: string = parseString(accountNumber, 32);
69
-
70
- if(formatAccount === '') {
71
- throw new UserError('required_account_number');
72
- }
73
-
74
- const formatFullName: string = parseVarChar(fullName, 128);
75
-
76
- if(formatFullName === '') {
77
- throw new UserError('required_full_name');
78
- }
79
-
80
- const formatRouting: string = parseString(routing, 32);
81
-
82
- if(formatRouting === '') {
83
- throw new UserError('required_routing_number');
84
- }
85
-
86
- return getUser(context, sessionId)
87
- .then((user: UserType) => {
88
- // Stripe
89
- const stripeClient = stripe(Config.get('stripe.token'));
90
-
91
- return stripeClient.customers
92
- .createSource(user.stripeAccountId, {
93
- source: {
94
- account_holder_name: formatFullName,
95
- account_holder_type: 'individual',
96
- account_number: formatAccount,
97
- country: 'US',
98
- currency: 'USD',
99
- object: 'bank_account',
100
- routing_number: formatRouting
101
- }
102
- })
103
- .then((account) => {
104
- const update: any = {
105
- bankAccount: account.last4,
106
- bankFullName: formatFullName,
107
- bankId: account.id,
108
- bankRouting: account.routing_number,
109
- modified: Date.now()
110
- };
111
-
112
- const aqlQry: AqlQuery = aql`UPDATE ${sessionId} WITH ${update} IN users LIMIT 1 RETURN NEW`;
113
-
114
- return useDb(database).query(aqlQry)
115
- .then((cursor: ArrayCursor) => cursor.next())
116
- .then((updatedUser: UserType = {}) => updatedUser);
117
- })
118
- .catch((error: Error) => {
119
- const msg = error.message;
120
-
121
- if(msg === 'A bank account with that routing number and account number ' +
122
- 'already exists for this customer.') {
123
- return logError({
124
- action,
125
- category: eventCategory,
126
- label: 'bank_account_exists'
127
- }, error, context).then(() => null);
128
- }
129
- return logError({
130
- action,
131
- category: eventCategory,
132
- label: 'payment_error'
133
- }, error, context).then(() => null);
134
- });
135
- });
136
- };
137
-
138
- export const addPaymentAccountCard = (context: ApiContext, card: PaymentCardType, requestData): Promise<UserType> => {
139
- const action: string = 'addPaymentAccountCard';
140
- const {database, userId: sessionId} = context;
141
-
142
- return getUser(context, sessionId)
143
- .then((user: UserType) => {
144
- // User
145
- const {
146
- _key: userKey,
147
- country = 'US',
148
- city,
149
- currency = 'USD',
150
- dob,
151
- email,
152
- first,
153
- last,
154
- username
155
- }: UserType = user;
156
-
157
- // Birthday
158
- const dobDay: number = +(DateTime.fromMillis(dob).toFormat('d'));
159
- const dobMonth: number = +(DateTime.fromMillis(dob).toFormat('M'));
160
- const dobYear: number = +(DateTime.fromMillis(dob).toFormat('y'));
161
-
162
- // Card
163
- const {
164
- accountNumber,
165
- acceptedTerms,
166
- expMonth,
167
- expYear,
168
- state,
169
- street1,
170
- zip
171
- }: PaymentCardType = card;
172
-
173
- // Acceptance
174
- const accepted: number = acceptedTerms ? DateTime.local().millisecond : 0;
175
-
176
- // Stripe
177
- const stripeClient = stripe(Config.get('stripe.token'));
178
-
179
- return stripeClient.accounts
180
- .create({
181
- country,
182
- email,
183
- external_account: {
184
- currency,
185
- exp_month: expMonth,
186
- exp_year: expYear,
187
- number: accountNumber,
188
- object: 'card'
189
- },
190
- legal_entity: {
191
- address: {
192
- city,
193
- line1: street1,
194
- postal_code: zip,
195
- state
196
- },
197
- dob: {
198
- day: dobDay,
199
- month: dobMonth,
200
- year: dobYear
201
- },
202
- first_name: first,
203
- last_name: last,
204
- // ssn_last_4: ssn.substr(-4),
205
- // personal_id_number: ssn,
206
- type: 'individual'
207
- },
208
- managed: true,
209
- metadata: {
210
- userId: userKey,
211
- username
212
- },
213
- tos_acceptance: {
214
- date: accepted,
215
- ip: requestData.ip,
216
- user_agent: requestData.userAgent.source
217
- }
218
- })
219
- .then((customer) => {
220
- // Create session
221
- const now: number = Date.now();
222
- const update: UserType = {
223
- modified: now,
224
- stripeAccountId: customer.id
225
- };
226
-
227
- const aqlQry: AqlQuery = aql`UPDATE ${userKey} WITH ${update} IN users LIMIT 1 RETURN NEW`;
228
-
229
- return useDb(database).query(aqlQry)
230
- .then((cursor: ArrayCursor) => cursor.next())
231
- .then((updatedUser: UserType = {}) => !isEmpty(updatedUser))
232
- .catch((error: Error) => logError({
233
- action,
234
- category: eventCategory,
235
- label: 'db_error'
236
- }, error, context).then(() => null));
237
- });
238
- });
239
- };
240
-
241
- export const addCreditCard = (context: ApiContext, card: PaymentCardType): Promise<PaymentCardType> => {
242
- const action: string = 'addCreditCard';
243
- const {database, userId: sessionId} = context;
244
-
245
- const {
246
- accountNumber,
247
- city,
248
- country,
249
- cvc,
250
- expMonth,
251
- expYear,
252
- fullName,
253
- street1,
254
- state,
255
- zip
256
- }: PaymentCardType = card;
257
- const formatNumber: number = parseNum(accountNumber, 16);
258
-
259
- if(!formatNumber) {
260
- throw new UserError('required_credit_card_number');
261
- }
262
-
263
- const formatExpMonth: number = parseNum(expMonth, 2);
264
-
265
- if(!formatExpMonth) {
266
- throw new UserError('required_credit_card_exp_month');
267
- }
268
-
269
- const formatExpYear: number = parseNum(expYear, 2);
270
-
271
- if(!formatExpYear) {
272
- throw new UserError('required_credit_card_exp_year');
273
- }
274
-
275
- const formatCvc: number = parseNum(cvc, 3);
276
-
277
- if(!formatCvc) {
278
- throw new UserError('required_credit_card_cvc');
279
- }
280
-
281
- const paymentCard: PaymentCardType = {};
282
- const formatCity: string = parseVarChar(city, 32);
283
-
284
- if(formatCity) {
285
- paymentCard.city = formatCity;
286
- }
287
-
288
- const formatCountry: string = parseVarChar(country, 32);
289
-
290
- if(formatCountry) {
291
- paymentCard.country = formatCountry;
292
- }
293
-
294
- const formatFullName: string = parseVarChar(fullName, 32);
295
-
296
- if(formatFullName) {
297
- paymentCard.fullName = formatFullName;
298
- }
299
-
300
- const formatStreet: string = parseVarChar(street1, 32);
301
-
302
- if(formatStreet) {
303
- paymentCard.street1 = formatStreet;
304
- }
305
-
306
- const formatState: string = parseVarChar(state, 32);
307
-
308
- if(formatState) {
309
- paymentCard.state = formatState;
310
- }
311
-
312
- const formatZip: string = parseVarChar(zip, 32);
313
-
314
- if(formatZip) {
315
- paymentCard.zip = formatZip;
316
- }
317
-
318
- // Get stripe id
319
- return getUser(context, sessionId)
320
- .then((user: UserType = {}) => {
321
- // Stripe
322
- const stripeClient = stripe(Config.get('stripe.token'));
323
-
324
- return stripeClient.customers
325
- .createSource(user.stripeCustomerId, {
326
- source: {
327
- address_city: formatCity,
328
- address_country: formatCountry,
329
- address_line1: formatStreet,
330
- address_state: formatState,
331
- address_zip: formatZip,
332
- currency: 'usd',
333
- cvc: formatCvc,
334
- exp_month: formatExpMonth,
335
- exp_year: formatExpYear,
336
- name: formatFullName,
337
- number: formatNumber,
338
- object: 'card'
339
- }
340
- })
341
- .then((stripeObj) => {
342
- const now: number = Date.now();
343
- const insert = {
344
- ...paymentCard,
345
- _key: createHash(`user-payment-${sessionId}`),
346
- accountNumber: stripeObj.last4,
347
- added: now,
348
- brand: stripeObj.brand,
349
- cvc: stripeObj.cvc_check,
350
- expMonth,
351
- expYear,
352
- modified: now,
353
- userId: sessionId
354
- };
355
- const insertAqlQry: AqlQuery = aql`INSERT ${insert} IN creditCards RETURN NEW`;
356
-
357
- return useDb(database).query(insertAqlQry)
358
- .then((cursor: ArrayCursor) => cursor.next())
359
- .then((newCard: PaymentCardType = {}) => {
360
- if(!isEmpty(newCard)) {
361
- // Add linked edge
362
- const {_id: cardId, _key: cardKey} = card;
363
- const edgeCollection = useDb(database).edgeCollection('hasPayment');
364
- const edgeId = createHash(`payment-${cardKey}`);
365
- const edge: any = {
366
- _key: edgeId
367
- };
368
-
369
- return edgeCollection.save(edge, `users/${sessionId}`, cardId).then(() => card);
370
- }
371
-
372
- return newCard;
373
- });
374
- })
375
- .catch((error: Error) => logError({
376
- action,
377
- category: eventCategory,
378
- label: 'payment_error'
379
- }, error, context).then(() => null));
380
- });
381
- };
382
-
383
- export const updateCreditCard = (context: ApiContext, card: PaymentCardType): Promise<PaymentCardType> => {
384
- const {database, userId: sessionId} = context;
385
-
386
- const {
387
- city,
388
- country,
389
- expMonth,
390
- expYear,
391
- fullName,
392
- id,
393
- street1,
394
- state,
395
- zip
396
- }: PaymentCardType = card;
397
-
398
- const formatId: string = parseId(id);
399
-
400
- if(formatId) {
401
- throw new UserError('required_credit_card_id');
402
- }
403
-
404
- const paymentCard: PaymentCardType = {};
405
- const formatExpMonth: number = parseNum(expMonth, 2);
406
- const formatExpYear: number = parseNum(expYear, 2);
407
- const formatCity: string = parseVarChar(city, 32);
408
- const formatCountry: string = parseVarChar(country, 2);
409
- const formatFullName: string = parseVarChar(fullName, 32);
410
- const formatStreet1: string = parseString(street1, 32);
411
- const formatState: string = parseVarChar(state, 2);
412
- const formatZip: string = parseVarChar(zip, 10);
413
-
414
- if(formatExpMonth) {
415
- paymentCard.expMonth = formatExpMonth;
416
- }
417
-
418
- if(formatExpYear) {
419
- paymentCard.expYear = formatExpYear;
420
- }
421
-
422
- if(formatCity) {
423
- paymentCard.city = formatCity;
424
- }
425
-
426
- if(formatCountry) {
427
- paymentCard.country = formatCountry;
428
- }
429
-
430
- if(formatFullName) {
431
- paymentCard.fullName = formatFullName;
432
- }
433
-
434
- if(formatStreet1) {
435
- paymentCard.street1 = formatStreet1;
436
- }
437
-
438
- if(formatState) {
439
- paymentCard.state = formatState;
440
- }
441
-
442
- if(formatZip) {
443
- paymentCard.zip = formatZip;
444
- }
445
-
446
- const update: any = paymentCard;
447
- const aqlQry: AqlQuery = aql`
448
- LET updatedCard = FIRST(
449
- FOR c IN creditCards
450
- FILTER c._key == ${formatId} && c.userId == ${sessionId}
451
- UPDATE c WITH ${update} IN creditCards
452
- LIMIT 1
453
- RETURN NEW
454
- )
455
- LET user = FIRST(
456
- FOR u IN users
457
- FILTER u._key == ${sessionId}
458
- LIMIT 1
459
- RETURN u
460
- )
461
- RETURN {user: user, card: updatedCard}`;
462
-
463
- return useDb(database).query(aqlQry)
464
- .then((cursor: ArrayCursor) => cursor.next())
465
- .then((results = {card: {}, user: {}}) => {
466
- const updatedCard: PaymentCardType = results.card;
467
- const {user} = results;
468
-
469
- if(isEmpty(updatedCard)) {
470
- throw new UserError('not_found');
471
- }
472
-
473
- // Stripe
474
- const stripeClient = stripe(Config.get('stripe.token'));
475
-
476
- return stripeClient.customers
477
- .updateCard(user.stripeCustomerId, card.stripeId, {
478
- address_city: formatCity,
479
- address_country: formatCountry,
480
- address_line1: formatStreet1,
481
- address_state: formatState,
482
- address_zip: formatZip,
483
- exp_month: formatExpMonth,
484
- exp_year: formatExpYear,
485
- name: formatFullName
486
- })
487
- .then(() => card)
488
- .catch((error: Error) => {
489
- console.log('payments::updateCard::error', error);
490
- throw new UserError('payment_error');
491
- });
492
- });
493
- };
494
-
495
- export const getCreditCards = (context: ApiContext): Promise<PaymentCardType[]> => {
496
- const action: string = 'getCreditCards';
497
- const {database, userId: sessionId} = context;
498
- const aqlQry: AqlQuery = aql`FOR c IN creditCards
499
- FILTER c.userId == ${sessionId}
500
- RETURN c`;
501
-
502
- return useDb(database).query(aqlQry)
503
- .then((cursor: ArrayCursor) => cursor.all())
504
- .then((list: PaymentCardType[] = []) => list)
505
- .catch((error: Error) => logError({
506
- action,
507
- category: eventCategory,
508
- label: 'db_error'
509
- }, error, context).then(() => null));
510
- };
511
-
512
- export const deleteCreditCard = (context: ApiContext, cardId: string): Promise<boolean> => {
513
- const {database, userId: sessionId} = context;
514
- const formatCardId: string = parseId(cardId);
515
- const aqlQry: AqlQuery = aql`
516
- LET card = FIRST(
517
- FOR c IN creditCards
518
- FILTER c._key == ${formatCardId} && c.userId == ${sessionId}
519
- LIMIT 1
520
- REMOVE c IN creditCards
521
- RETURN OLD
522
- )
523
- LET user = FIRST(
524
- FOR u IN users
525
- FILTER u._key == ${sessionId}
526
- LIMIT 1
527
- RETURN u
528
- )
529
- RETURN {user: user, card: card}`;
530
-
531
- return useDb(database).query(aqlQry)
532
- .then((cursor: ArrayCursor) => cursor.next())
533
- .then((result = {card: {}, user: {}}) => {
534
- if(isEmpty(result)) {
535
- return false;
536
- }
537
-
538
- const {card, user} = result;
539
- const {_key: cardKey} = card;
540
-
541
- // Remove linked edges
542
- const edgeCollection = useDb(database).edgeCollection('hasPayment');
543
-
544
- return edgeCollection.outEdges(cardKey)
545
- .then((edges) => {
546
- if(edges.length) {
547
- return Promise.all(
548
- edges.map((edge) => {
549
- const {_key: edgeKey} = edge;
550
- const removeAqlQry: AqlQuery = aql`REMOVE {_key:${edgeKey}} IN hasPayment`;
551
- return useDb(database).query(removeAqlQry);
552
- }))
553
- .then(() => {
554
- // Stripe
555
- const stripeClient = stripe(Config.get('stripe.token'));
556
-
557
- return stripeClient.customers
558
- .deleteCard(user.stripeCustomerId, card.stripeId)
559
- .then(() => true)
560
- .catch((error: Error) => {
561
- console.log('payments::deleteCard::error', error);
562
- throw new UserError('payment_error');
563
- });
564
- });
565
- }
566
-
567
- return false;
568
- });
569
- });
570
- };
571
-
572
- export const deletePaymentAccountBank = (context: ApiContext, bankId: string): Promise<boolean> => {
573
- const {database, userId: sessionId} = context;
574
-
575
- // Clean db
576
- const update: UserType = {
577
- bankAccount: '',
578
- bankFullName: '',
579
- bankId: '',
580
- bankRouting: '',
581
- modified: Date.now()
582
- };
583
- const aqlQry: AqlQuery = aql`UPDATE ${sessionId} WITH ${update} IN users LIMIT 1 RETURN NEW`;
584
-
585
- return useDb(database).query(aqlQry)
586
- .then((cursor: ArrayCursor) => cursor.next())
587
- .then((user: UserType = {}) => {
588
- // Stripe
589
- const stripeClient = stripe(Config.get('stripe.token'));
590
-
591
- return stripeClient.customers
592
- .deleteSource(user.stripeAccountId, bankId)
593
- .then((response = {deleted: false}) => response.deleted)
594
- .catch(() => Promise.resolve(false));
595
- });
596
- };
597
-
598
- export const createPaymentTransfer = (context: ApiContext, transfer: PaymentTransfer): Promise<PaymentTransfer> => {
599
- const {database, userId: sessionId} = context;
600
- const {amount, currency} = transfer;
601
- const formatAmount: number = parseNum(amount);
602
- const formatCurrency: string = parseChar(currency, 3, 'USD').toUpperCase();
603
-
604
- return getUser(context, sessionId)
605
- .then((user: UserType) => {
606
- // Stripe
607
- const stripeClient = stripe(Config.get('stripe.token'));
608
-
609
- return stripeClient.transfers
610
- .create({
611
- amount: formatAmount,
612
- currency: formatCurrency,
613
- destination: user.stripeAccountId
614
- })
615
- .then((stripeTransfer) => {
616
- console.log(stripeTransfer);
617
- const now: number = Date.now();
618
- const insert: PaymentTransfer = {
619
- added: now,
620
- amount: formatAmount,
621
- currency: formatCurrency,
622
- modified: now,
623
- userId: sessionId
624
- };
625
- const aqlQry: AqlQuery = aql`INSERT ${insert} IN transfers RETURN NEW`;
626
-
627
- return useDb(database).query(aqlQry)
628
- .then((cursor: ArrayCursor) => cursor.next())
629
- .then((newTransfer: PaymentTransfer) => newTransfer);
630
- });
631
- });
632
- };
633
-
634
- export const createPaymentHold = (context: ApiContext, payment: PaymentCharge): Promise<PaymentCharge> => {
635
- const {database, userId: sessionId} = context;
636
- const {amount, capture, cardId, currency, description} = payment;
637
- const formatCurrency = parseChar(currency, 3, 'USD').toUpperCase();
638
-
639
- const stripeClient = stripe(Config.get('stripe.token'));
640
-
641
- return stripeClient.charges
642
- .create({
643
- amount,
644
- capture,
645
- currency: formatCurrency,
646
- description,
647
- source: cardId
648
- })
649
- .then((stripeCharge) => {
650
- const now: number = Date.now();
651
- const insert: PaymentCharge = {
652
- added: now,
653
- amount,
654
- capture,
655
- cardId,
656
- chargeFailCode: stripeCharge.failure_code,
657
- chargeFailMsg: stripeCharge.failure_message,
658
- chargeId: stripeCharge.id,
659
- chargeStatus: stripeCharge.status,
660
- currency: formatCurrency,
661
- description,
662
- modified: now,
663
- userId: sessionId
664
- };
665
- const aqlQry: AqlQuery = aql`INSERT ${insert} IN payments RETURN NEW`;
666
-
667
- return useDb(database).query(aqlQry)
668
- .then((cursor: ArrayCursor) => cursor.next())
669
- .then((newPayment: PaymentCharge) => newPayment);
670
- })
671
- .catch((error: Error) => {
672
- console.log('payments::createHold::error', error);
673
- throw new UserError('payment_error');
674
- });
675
- };