1
+ {
2
+ "package" : {
3
+ "name" : " @deep-foundation/firebase-push-notification" ,
4
+ "version" : " 3.0.0"
5
+ },
6
+ "data" : [
7
+ {
8
+ "package" : {
9
+ "dependencyId" : 0 ,
10
+ "containValue" : " Tree"
11
+ },
12
+ "id" : 1
13
+ },
14
+ {
15
+ "package" : {
16
+ "dependencyId" : 0 ,
17
+ "containValue" : " HandleInsert"
18
+ },
19
+ "id" : 2
20
+ },
21
+ {
22
+ "package" : {
23
+ "dependencyId" : 0 ,
24
+ "containValue" : " SyncTextFile"
25
+ },
26
+ "id" : 3
27
+ },
28
+ {
29
+ "package" : {
30
+ "dependencyId" : 0 ,
31
+ "containValue" : " Handler"
32
+ },
33
+ "id" : 4
34
+ },
35
+ {
36
+ "package" : {
37
+ "dependencyId" : 0 ,
38
+ "containValue" : " dockerSupportsJs"
39
+ },
40
+ "id" : 5
41
+ },
42
+ {
43
+ "package" : {
44
+ "dependencyId" : 0 ,
45
+ "containValue" : " Type"
46
+ },
47
+ "id" : 6
48
+ },
49
+ {
50
+ "package" : {
51
+ "dependencyId" : 0 ,
52
+ "containValue" : " User"
53
+ },
54
+ "id" : 7
55
+ },
56
+ {
57
+ "package" : {
58
+ "dependencyId" : 0 ,
59
+ "containValue" : " Value"
60
+ },
61
+ "id" : 8
62
+ },
63
+ {
64
+ "package" : {
65
+ "dependencyId" : 0 ,
66
+ "containValue" : " String"
67
+ },
68
+ "id" : 9
69
+ },
70
+ {
71
+ "package" : {
72
+ "dependencyId" : 0 ,
73
+ "containValue" : " Object"
74
+ },
75
+ "id" : 10
76
+ },
77
+ {
78
+ "package" : {
79
+ "dependencyId" : 0 ,
80
+ "containValue" : " TreeIncludeDown"
81
+ },
82
+ "id" : 11
83
+ },
84
+ {
85
+ "package" : {
86
+ "dependencyId" : 0 ,
87
+ "containValue" : " Any"
88
+ },
89
+ "id" : 12
90
+ },
91
+ {
92
+ "package" : {
93
+ "dependencyId" : 0 ,
94
+ "containValue" : " TreeIncludeNode"
95
+ },
96
+ "id" : 13
97
+ },
98
+ {
99
+ "package" : {
100
+ "dependencyId" : 1 ,
101
+ "containValue" : " Notify"
102
+ },
103
+ "id" : 14
104
+ },
105
+ {
106
+ "package" : {
107
+ "dependencyId" : 2 ,
108
+ "containValue" : " Device"
109
+ },
110
+ "id" : 15
111
+ },
112
+ {
113
+ "package" : {
114
+ "dependencyId" : 1 ,
115
+ "containValue" : " Notified"
116
+ },
117
+ "id" : 16
118
+ },
119
+ {
120
+ "id" : " PushNotificationTree" ,
121
+ "type" : 1
122
+ },
123
+ {
124
+ "id" : " HandlePushNotificationNotifyInsert" ,
125
+ "type" : 2 ,
126
+ "from" : " Notify" ,
127
+ "to" : " PushNotificationNotifyInsertHandler"
128
+ },
129
+ {
130
+ "id" : " PushNotificationNotifyInsertHandlerCode" ,
131
+ "type" : 3 ,
132
+ "value" : {
133
+ "value": "async ({ require, deep, data: { newLink: notifyLink, triggeredByLinkId } }) => {\n const firebaseAdmin = require('firebase-admin');\n\n const notificationLinkId = notifyLink.from_id;\n const deviceLinkId = notifyLink.to_id;\n\n const containTypeLinkId = await deep.id('@deep-foundation/core', 'Contain');\n\n const serviceAccount = await getServiceAccount({\n containTypeLinkId,\n triggeredByLinkId,\n });\n\n const firebaseApplication = await getFirebaseApplication({\n firebaseAdmin,\n serviceAccount,\n });\n const deviceRegistrationToken = await getDeviceRegistrationToken({\n containTypeLinkId,\n deviceLinkId,\n });\n const pushNotificationData = await getPushNotificationData({\n containTypeLinkId,\n deviceRegistrationToken,\n notificationLinkId,\n });\n\n await firebaseAdmin.messaging(firebaseApplication).send(pushNotificationData);\n await deep.insert({\n type_id: await deep.id(deep.linkId, 'Notified'),\n in: {\n data: {\n type_id: containTypeLinkId,\n from_id: triggeredByLinkId,\n },\n },\n from_id: notifyLink.id,\n to_id: deviceLinkId,\n });\n\n async function getServiceAccount({ containTypeLinkId, triggeredByLinkId }) {\n const serviceAccountTypeLinkId = await deep.id(\n deep.linkId,\n 'ServiceAccount'\n );\n const usesServiceAccountTypeLinkId = await deep.id(\n deep.linkId,\n 'UsesServiceAccount'\n );\n const selectData = {\n _or: [\n {\n type_id: serviceAccountTypeLinkId,\n in: {\n type_id: containTypeLinkId,\n from_id: triggeredByLinkId,\n },\n },\n {\n type_id: usesServiceAccountTypeLinkId,\n from_id: triggeredByLinkId,\n },\n ],\n };\n const { data } = await deep.select(selectData);\n if (data.length === 0) {\n throw new Error(\n `Select with data ${JSON.stringify(selectData)} returned empty result`\n );\n }\n let serviceAccountLink;\n const usesServiceAccountLinks = data.filter(\n (link) => link.type_id === usesServiceAccountTypeLinkId\n );\n if (usesServiceAccountLinks.length > 1) {\n throw new Error(\n `There must be only one link of type ${usesServiceAccountTypeLinkId} and from ${triggeredByLinkId}, instead there are ${usesServiceAccountLinks\n .map((link) => `##${link.id}`)\n .join(', ')}`\n );\n } else if (usesServiceAccountLinks.length === 1) {\n const usesServiceAccountLink = usesServiceAccountLinks[0];\n serviceAccountLink = data.find(\n (link) => link.id === usesServiceAccountLink.to_id\n );\n } else if (usesServiceAccountLinks.length === 0) {\n const serviceAccountLinks = data.filter(\n (link) => link.type_id === serviceAccountTypeLinkId\n );\n if (serviceAccountLinks.length > 1) {\n throw new Error(\n `There must be only one link of type ##${serviceAccountTypeLinkId} and contained by ##${triggeredByLinkId}, instead there are ${serviceAccountLinks\n .map((link) => `##${link.id}`)\n .join(', ')}`\n );\n } else if (serviceAccountLinks.length === 1) {\n serviceAccountLink = serviceAccountLinks[0];\n } else if (serviceAccountLinks.length === 0) {\n throw new Error(\n `A link of type ##${serviceAccountTypeLinkId} and contained by ##${triggeredByLinkId} is not found`\n );\n }\n }\n if (!serviceAccountLink) {\n throw new Error(\n `A link of type ##${usesServiceAccountTypeLinkId} and from ##${triggeredByLinkId} is not found`\n );\n }\n if (!serviceAccountLink.value?.value) {\n throw new Error(`##${serviceAccountLink.id} must have value`);\n }\n return serviceAccountLink.value.value;\n }\n\n async function getDeviceRegistrationToken({\n containTypeLinkId,\n deviceLinkId,\n }) {\n const deviceRegistrationTokenTypeLinkId = await deep.id(\n deep.linkId,\n 'DeviceRegistrationToken'\n );\n const selectData = {\n type_id: deviceRegistrationTokenTypeLinkId,\n in: {\n type_id: containTypeLinkId,\n from_id: deviceLinkId,\n },\n };\n const {\n data: [deviceRegistrationTokenLink],\n } = await deep.select(selectData);\n if (!deviceRegistrationTokenLink) {\n throw new Error(\n `##${deviceLinkId} must have contained a link of type ##${deviceRegistrationTokenTypeLinkId}. Select with data ${JSON.stringify(\n selectData\n )} returned empty result`\n );\n }\n if (!deviceRegistrationTokenLink.value?.value) {\n throw new Error(`##${deviceRegistrationTokenLink.id} must have value`);\n }\n return deviceRegistrationTokenLink.value.value;\n }\n\n async function getPushNotificationImageUrl({\n containTypeLinkId,\n notificationLinkId,\n }) {\n const notificationImageUrlTypeLinkId = await deep.id(\n deep.linkId,\n 'PushNotificationImageUrl'\n );\n const selectData = {\n type_id: notificationImageUrlTypeLinkId,\n in: {\n type_id: containTypeLinkId,\n from_id: notificationLinkId,\n },\n };\n const {\n data: [linkWithPushNotificationImageUrlString],\n } = await deep.select(selectData);\n if (!linkWithPushNotificationImageUrlString) {\n return undefined;\n }\n if (!linkWithPushNotificationImageUrlString.value?.value) {\n throw new Error(\n `##${linkWithPushNotificationImageUrlString.id} must have value`\n );\n }\n return linkWithPushNotificationImageUrlString.value.value;\n }\n\n async function getPushNotificationBody({ notificationLinkId }) {\n const notificationBodyTypeLinkId = await deep.id(\n deep.linkId,\n 'PushNotificationBody'\n );\n const selectData = {\n in: {\n type_id: notificationBodyTypeLinkId,\n from_id: notificationLinkId,\n },\n };\n const {\n data: [linkWithPushNotificationBodyString],\n } = await deep.select(selectData);\n if (!linkWithPushNotificationBodyString) {\n throw new Error(\n `A link of type ##${notificationBodyTypeLinkId} must exist`\n );\n }\n if (!linkWithPushNotificationBodyString.value?.value) {\n throw new Error(\n `##${linkWithPushNotificationBodyString.id} must have value`\n );\n }\n return linkWithPushNotificationBodyString.value.value;\n }\n\n async function getPushNotificationTitle({ notificationLinkId }) {\n const notificationTitleTypeLinkId = await deep.id(\n deep.linkId,\n 'PushNotificationTitle'\n );\n const selectData = {\n in: {\n type_id: {\n _eq: notificationTitleTypeLinkId,\n },\n from_id: {\n _eq: notificationLinkId,\n },\n },\n };\n const {\n data: [linkWithPushNotificationTitleString],\n } = await deep.select(selectData);\n if (!linkWithPushNotificationTitleString) {\n throw new Error(\n `A link of type ${notificationTitleTypeLinkId} must exist`\n );\n }\n if (!linkWithPushNotificationTitleString.value?.value) {\n throw new Error(\n `##${linkWithPushNotificationTitleString.id} must have value`\n );\n }\n return linkWithPushNotificationTitleString.value.value;\n }\n\n async function getPushNotificationData({\n notificationLinkId,\n containTypeLinkId,\n deviceRegistrationToken,\n }) {\n const pushNotificationData = {\n token: deviceRegistrationToken,\n notification: {\n title: await getPushNotificationTitle({ notificationLinkId }),\n body: await getPushNotificationBody({ notificationLinkId }),\n },\n };\n const imageUrl = await getPushNotificationImageUrl({\n containTypeLinkId,\n notificationLinkId,\n });\n if (imageUrl) {\n pushNotificationData.imageUrl = imageUrl;\n }\n return pushNotificationData;\n }\n\n async function getFirebaseApplication({ firebaseAdmin, serviceAccount }) {\n return firebaseAdmin.apps.length === 0\n ? firebaseAdmin.initializeApp({\n credential: firebaseAdmin.credential.cert(serviceAccount),\n })\n : firebaseAdmin.app();\n }\n};\n"
134
+ }
135
+ },
136
+ {
137
+ "id" : " PushNotificationNotifyInsertHandler" ,
138
+ "type" : 4 ,
139
+ "from" : 5 ,
140
+ "to" : " PushNotificationNotifyInsertHandlerCode"
141
+ },
142
+ {
143
+ "id" : " DeviceRegistrationToken" ,
144
+ "type" : 6
145
+ },
146
+ {
147
+ "id" : " UsesWebPushCertificate" ,
148
+ "type" : 6 ,
149
+ "from" : 7 ,
150
+ "to" : " WebPushCertificate"
151
+ },
152
+ {
153
+ "id" : " TypeOfValueOfWebPushCertificate" ,
154
+ "type" : 8 ,
155
+ "from" : " WebPushCertificate" ,
156
+ "to" : 9
157
+ },
158
+ {
159
+ "id" : " WebPushCertificate" ,
160
+ "type" : 6
161
+ },
162
+ {
163
+ "id" : " ServiceAccount" ,
164
+ "type" : 6
165
+ },
166
+ {
167
+ "id" : " TypeOfValueOfServiceAccount" ,
168
+ "type" : 8 ,
169
+ "from" : " ServiceAccount" ,
170
+ "to" : 10
171
+ },
172
+ {
173
+ "id" : " UsesServiceAccount" ,
174
+ "type" : 6 ,
175
+ "from" : 7 ,
176
+ "to" : " ServiceAccount"
177
+ },
178
+ {
179
+ "id" : " TreeIncludeDownPushNotificationImageUrl" ,
180
+ "type" : 11 ,
181
+ "from" : " PushNotificationTree" ,
182
+ "to" : " PushNotificationImageUrl"
183
+ },
184
+ {
185
+ "id" : " PushNotificationImageUrl" ,
186
+ "type" : 6 ,
187
+ "from" : " PushNotification" ,
188
+ "to" : 12
189
+ },
190
+ {
191
+ "id" : " PushNotification" ,
192
+ "type" : 6
193
+ },
194
+ {
195
+ "id" : " PushNotificationBody" ,
196
+ "type" : 6 ,
197
+ "from" : " PushNotification" ,
198
+ "to" : 12
199
+ },
200
+ {
201
+ "id" : " TreeIncludeDownPushNotificationBody" ,
202
+ "type" : 11 ,
203
+ "from" : " PushNotificationTree" ,
204
+ "to" : " PushNotificationBody"
205
+ },
206
+ {
207
+ "id" : " PushNotificationTitle" ,
208
+ "type" : 6 ,
209
+ "from" : " PushNotification" ,
210
+ "to" : 12
211
+ },
212
+ {
213
+ "id" : " TreeIncludeDownPushNotificationTitle" ,
214
+ "type" : 11 ,
215
+ "from" : " PushNotificationTree" ,
216
+ "to" : " PushNotificationTitle"
217
+ },
218
+ {
219
+ "id" : " TreeIncludeNodePushNotification" ,
220
+ "type" : 13 ,
221
+ "from" : " PushNotificationTree" ,
222
+ "to" : " PushNotification"
223
+ },
224
+ {
225
+ "id" : " Notify" ,
226
+ "type" : 14 ,
227
+ "from" : " PushNotification" ,
228
+ "to" : 15
229
+ },
230
+ {
231
+ "id" : " Notified" ,
232
+ "type" : 16 ,
233
+ "from" : " Notify" ,
234
+ "to" : 15
235
+ }
236
+ ],
237
+ "errors" : [],
238
+ "dependencies" : [
239
+ {
240
+ "name" : " @deep-foundation/core" ,
241
+ "version" : " 0.0.2"
242
+ },
243
+ {
244
+ "name" : " @deep-foundation/notification" ,
245
+ "version" : " 1.0.1"
246
+ },
247
+ {
248
+ "name" : " @deep-foundation/device" ,
249
+ "version" : " 1.0.1"
250
+ }
251
+ ]
252
+ }
0 commit comments