pockethost 1.0.0-rc.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/LICENSE.md +16 -0
  2. package/dist/index.mjs +3156 -0
  3. package/dist/instance-app/migrations/1699198734_pockethost_defaults.js +39 -0
  4. package/dist/instance-app/pb_hooks/_ph_admin_sync.pb.js +71 -0
  5. package/dist/instance-app/pb_hooks/_ph_lib.js +19 -0
  6. package/dist/instance-app/tsconfig.json +8 -0
  7. package/dist/instance-app/types/goja.d.ts +58 -0
  8. package/dist/instance-app/types/lib.d.ts +5 -0
  9. package/dist/instance-app/types/types.d.ts +19573 -0
  10. package/dist/mothership-app/migrations/1705062576_collections_snapshot.js +1863 -0
  11. package/dist/mothership-app/migrations/1705083826_updated_stats.js +721 -0
  12. package/dist/mothership-app/migrations/1706060446_updated_instances.js +44 -0
  13. package/dist/mothership-app/pb_hooks/src/instances-create.pb.js +65 -0
  14. package/dist/mothership-app/pb_hooks/src/instances-delete.pb.js +69 -0
  15. package/dist/mothership-app/pb_hooks/src/instances-migrate-versions.pb.js +33 -0
  16. package/dist/mothership-app/pb_hooks/src/instances-notify-discord-after-create.pb.js +31 -0
  17. package/dist/mothership-app/pb_hooks/src/instances-notify-on-maintenance-mode.pb.js +52 -0
  18. package/dist/mothership-app/pb_hooks/src/instances-reset-idle.pb.js +7 -0
  19. package/dist/mothership-app/pb_hooks/src/instances-update.pb.js +121 -0
  20. package/dist/mothership-app/pb_hooks/src/instances-validate-before-create.pb.js +16 -0
  21. package/dist/mothership-app/pb_hooks/src/instances-validate-before-update.pb.js +43 -0
  22. package/dist/mothership-app/pb_hooks/src/lib.js +171 -0
  23. package/dist/mothership-app/pb_hooks/src/ls.pb.js +159 -0
  24. package/dist/mothership-app/pb_hooks/src/mail.pb.js +49 -0
  25. package/dist/mothership-app/pb_hooks/src/notifications.pb.js +62 -0
  26. package/dist/mothership-app/pb_hooks/src/random-words.js +2085 -0
  27. package/dist/mothership-app/pb_hooks/src/signup.pb.js +214 -0
  28. package/dist/mothership-app/pb_hooks/src/sns.pb.js +133 -0
  29. package/dist/mothership-app/pb_hooks/src/unsubscribe.pb.js +33 -0
  30. package/dist/mothership-app/pb_hooks/src/user-token.pb.js +33 -0
  31. package/dist/mothership-app/pb_hooks/src/user-welcome-msg.pb.js +32 -0
  32. package/dist/mothership-app/pb_hooks/src/versions-route.pb.js +12 -0
  33. package/dist/mothership-app/pb_hooks/src/versions.js +0 -0
  34. package/dist/mothership-app/pb_hooks/tsconfig.json +8 -0
  35. package/dist/mothership-app/pb_hooks/types/global.d.ts +1 -0
  36. package/dist/mothership-app/pb_hooks/types/goja.d.ts +58 -0
  37. package/dist/mothership-app/pb_hooks/types/lemon.d.ts +12 -0
  38. package/dist/mothership-app/pb_hooks/types/lib.d.ts +55 -0
  39. package/dist/mothership-app/pb_hooks/types/types.d.ts +19573 -0
  40. package/dist/mothership-app/ph_app/index.js +11 -0
  41. package/dist/mothership-app/ph_app/package-lock.json +657 -0
  42. package/dist/mothership-app/ph_app/package.json +14 -0
  43. package/package.json +144 -0
  44. package/readme.md +168 -0
@@ -0,0 +1,159 @@
1
+ routerAdd('POST', '/api/ls', (c) => {
2
+ const dao = $app.dao()
3
+ const { audit, mkLog, enqueueNotification } = /** @type {Lib} */ (
4
+ require(`${__hooks}/lib.js`)
5
+ )
6
+
7
+ const log = mkLog(`ls`)
8
+
9
+ const secret = $os.getenv('LS_WEBHOOK_SECRET')
10
+ log(`Secret`, secret)
11
+
12
+ const raw = readerToString(c.request().body)
13
+ const data = JSON.parse(raw)
14
+ log(`payload`, JSON.stringify(data, null, 2))
15
+
16
+ /** @type {WebHook} */
17
+ let {
18
+ meta: {
19
+ custom_data: { user_id },
20
+ },
21
+ data: {
22
+ type,
23
+ attributes: {
24
+ order_number,
25
+ first_order_item: { product_name, /** @type {number} */ product_id },
26
+ status,
27
+ user_email: email,
28
+ },
29
+ },
30
+ } = data
31
+
32
+ log({ user_id, order_number, product_name, product_id, status, email })
33
+
34
+ try {
35
+ if (!user_id) {
36
+ throw new Error(`No user ID`)
37
+ } else {
38
+ log(`user ID ok`, user_id)
39
+ }
40
+
41
+ if (![`orders`].includes(type)) {
42
+ throw new Error(`Unsupported event: ${type}`)
43
+ } else {
44
+ log(`event type ok`)
45
+ }
46
+
47
+ if (![`active`, `paid`].includes(status)) {
48
+ throw new Error(`Unsupported status: ${status}`)
49
+ } else {
50
+ log(`status ok`, status)
51
+ }
52
+
53
+ if (!order_number) {
54
+ throw new Error(`No order #`)
55
+ } else {
56
+ log(`order # ok`, order_number)
57
+ }
58
+
59
+ const userRec = (() => {
60
+ try {
61
+ return dao.findFirstRecordByData('users', 'id', user_id)
62
+ } catch (e) {}
63
+ })()
64
+ if (!userRec) {
65
+ throw new Error(`User ${user_id} not found`)
66
+ } else {
67
+ log(`user record ok`, userRec)
68
+ }
69
+
70
+ /** @type{{[_:number]: ()=>void}} */
71
+ const editions = {
72
+ // Founder's annual
73
+ 159792: () => {
74
+ userRec.set(`subscription`, `premium`)
75
+ userRec.set(`isFounder`, true)
76
+ },
77
+ // Founder's lifetime
78
+ 159794: () => {
79
+ userRec.set(`subscription`, `lifetime`)
80
+ userRec.set(`isFounder`, true)
81
+ },
82
+ // Pro annual
83
+ 159791: () => {
84
+ userRec.set(`subscription`, `premium`)
85
+ },
86
+ // Pro monthly
87
+ 159790: () => {
88
+ userRec.set(`subscription`, `premium`)
89
+ },
90
+ }
91
+
92
+ const applyEditionSpecifics = editions[product_id]
93
+ if (!applyEditionSpecifics) {
94
+ throw new Error(`Product ID not found: ${product_id}`)
95
+ } else {
96
+ log(`product id ok`, product_id)
97
+ }
98
+ applyEditionSpecifics()
99
+
100
+ const payment = new Record(dao.findCollectionByNameOrId('payments'), {
101
+ user: user_id,
102
+ payment_id: `ls_${order_number}`,
103
+ })
104
+
105
+ dao.runInTransaction((txDao) => {
106
+ log(`transaction started`)
107
+ if (!userRec.getDateTime(`welcome`)) {
108
+ enqueueNotification(`email`, `welcome`, user_id, { log, dao: txDao })
109
+ userRec.set(`welcome`, new DateTime())
110
+ }
111
+ txDao.saveRecord(userRec)
112
+ log(`saved user`)
113
+ txDao.saveRecord(payment)
114
+ log(`saved payment`)
115
+ txDao
116
+ .db()
117
+ .newQuery(
118
+ `update settings set value=value-1 where name='founders-edition-count'`,
119
+ )
120
+ .execute()
121
+ log(`saved founder count`)
122
+
123
+ log(`about to enqueue email`)
124
+ enqueueNotification(`email`, `lemon_order_email`, user_id, {
125
+ dao: txDao,
126
+ log,
127
+ })
128
+ log(`about to enqueue lemonbot`)
129
+ enqueueNotification(`lemonbot`, `lemon_order_discord`, user_id, {
130
+ dao: txDao,
131
+ log,
132
+ })
133
+
134
+ log(`saved discord notice`)
135
+ })
136
+ log(`database updated`)
137
+ audit(`LS`, `Order ${order_number} ${product_name} processed.`, {
138
+ log,
139
+ dao,
140
+ extra: {
141
+ email,
142
+ user: user_id,
143
+ },
144
+ })
145
+ } catch (e) {
146
+ audit(`LS_ERR`, `${e}`, {
147
+ log,
148
+ dao,
149
+ extra: {
150
+ email,
151
+ user: user_id,
152
+ raw_payload: raw,
153
+ },
154
+ })
155
+ return c.json(500, `${e}`)
156
+ }
157
+
158
+ return c.json(200, { status: 'ok' })
159
+ })
@@ -0,0 +1,49 @@
1
+ /// <reference path="../types/types.d.ts" />
2
+
3
+ routerAdd(
4
+ 'POST',
5
+ '/api/mail',
6
+ (c) => {
7
+ const { mkLog, audit } = /** @type {Lib} */ (require(`${__hooks}/lib.js`))
8
+ const log = mkLog(`mail`)
9
+
10
+ let data = /** @type {{ to: string; subject: string; body: string }} */ (
11
+ new DynamicModel({
12
+ to: '',
13
+ subject: '',
14
+ body: '',
15
+ })
16
+ )
17
+
18
+ log(`before bind`)
19
+
20
+ c.bind(data)
21
+
22
+ log(`after bind`)
23
+
24
+ // This is necessary for destructuring to work correctly
25
+ data = JSON.parse(JSON.stringify(data))
26
+
27
+ log(`bind parsed`, JSON.stringify(data))
28
+
29
+ const { to, subject, body } = data
30
+
31
+ const email = new MailerMessage({
32
+ from: {
33
+ address: $app.settings().meta.senderAddress,
34
+ name: $app.settings().meta.senderName,
35
+ },
36
+ to: [{ address: to }],
37
+ subject: subject,
38
+ html: body,
39
+ })
40
+
41
+ $app.newMailClient().send(email)
42
+
43
+ const msg = `Sent to ${to}`
44
+ log(msg)
45
+
46
+ return c.json(200, { status: 'ok' })
47
+ },
48
+ $apis.requireAdminAuth(),
49
+ )
@@ -0,0 +1,62 @@
1
+ /// <reference path="../types/types.d.ts" />
2
+
3
+ routerAdd(`GET`, `api/process_single_notification`, (c) => {
4
+ const { mkLog, processNotification } = /** @type {Lib} */ (
5
+ require(`${__hooks}/lib.js`)
6
+ )
7
+ const log = mkLog(`process_single_notification`)
8
+ log(`start`)
9
+
10
+ const dao = $app.dao()
11
+ try {
12
+ const notification = dao.findFirstRecordByData(
13
+ `notifications`,
14
+ `delivered`,
15
+ ``,
16
+ )
17
+ if (!notification) {
18
+ return c.json(200, `No notifications to send`)
19
+ }
20
+ processNotification(notification, {
21
+ log,
22
+ dao,
23
+ test: !!c.queryParam(`test`),
24
+ })
25
+ } catch (e) {
26
+ c.json(500, `${e}`)
27
+ }
28
+ return c.json(200, { status: 'ok' })
29
+ })
30
+
31
+ onModelAfterCreate((e) => {
32
+ const dao = e.dao || $app.dao()
33
+ return
34
+ const { processNotification, mkLog, audit } = /** @type {Lib} */ (
35
+ require(`${__hooks}/lib.js`)
36
+ )
37
+ const log = mkLog(`notification:sendImmediately`)
38
+
39
+ const notificationRec = /** @type {models.Record} */ (e.model)
40
+
41
+ log({ notificationRec })
42
+
43
+ try {
44
+ dao.expandRecord(notificationRec, ['message_template'], null)
45
+
46
+ const messageTemplateRec = notificationRec.expandedOne(`message_template`)
47
+ if (!messageTemplateRec) {
48
+ throw new Error(`Missing message template`)
49
+ }
50
+ if ([`maintenance-mode`].includes(messageTemplateRec.getString(`slug`))) {
51
+ processNotification(notificationRec, { log, dao })
52
+ }
53
+ } catch (e) {
54
+ audit(`ERROR`, `${e}`, {
55
+ log,
56
+ dao,
57
+ extra: {
58
+ notification: notificationRec.getId(),
59
+ },
60
+ })
61
+ }
62
+ }, `notifications`)