|
1 | 1 | { |
2 | 2 | "package": { |
3 | 3 | "name": "@deep-foundation/firebase-push-notification", |
4 | | - "version": "14.0.3-dev.0" |
| 4 | + "version": "14.0.4" |
5 | 5 | }, |
6 | 6 | "data": [ |
7 | 7 | { |
8 | 8 | "package": { |
9 | 9 | "dependencyId": 0, |
10 | | - "containValue": "Type" |
| 10 | + "containValue": "Handler" |
11 | 11 | }, |
12 | 12 | "id": 1 |
13 | 13 | }, |
14 | 14 | { |
15 | 15 | "package": { |
16 | 16 | "dependencyId": 0, |
17 | | - "containValue": "Value" |
| 17 | + "containValue": "dockerSupportsJs" |
18 | 18 | }, |
19 | 19 | "id": 2 |
20 | 20 | }, |
21 | 21 | { |
22 | 22 | "package": { |
23 | 23 | "dependencyId": 0, |
24 | | - "containValue": "Object" |
| 24 | + "containValue": "Value" |
25 | 25 | }, |
26 | 26 | "id": 3 |
27 | 27 | }, |
28 | 28 | { |
29 | 29 | "package": { |
30 | 30 | "dependencyId": 0, |
31 | | - "containValue": "User" |
| 31 | + "containValue": "String" |
32 | 32 | }, |
33 | 33 | "id": 4 |
34 | 34 | }, |
35 | 35 | { |
36 | 36 | "package": { |
37 | 37 | "dependencyId": 0, |
38 | | - "containValue": "String" |
| 38 | + "containValue": "Type" |
39 | 39 | }, |
40 | 40 | "id": 5 |
41 | 41 | }, |
|
63 | 63 | { |
64 | 64 | "package": { |
65 | 65 | "dependencyId": 0, |
66 | | - "containValue": "Tree" |
| 66 | + "containValue": "HandleInsert" |
67 | 67 | }, |
68 | 68 | "id": 9 |
69 | 69 | }, |
|
84 | 84 | { |
85 | 85 | "package": { |
86 | 86 | "dependencyId": 0, |
87 | | - "containValue": "SyncTextFile" |
| 87 | + "containValue": "HandleUpdate" |
88 | 88 | }, |
89 | 89 | "id": 12 |
90 | 90 | }, |
91 | 91 | { |
92 | 92 | "package": { |
93 | | - "dependencyId": 0, |
94 | | - "containValue": "Handler" |
| 93 | + "dependencyId": 3, |
| 94 | + "containValue": "UpdateHandler" |
95 | 95 | }, |
96 | 96 | "id": 13 |
97 | 97 | }, |
98 | 98 | { |
99 | 99 | "package": { |
100 | 100 | "dependencyId": 0, |
101 | | - "containValue": "dockerSupportsJs" |
| 101 | + "containValue": "Object" |
102 | 102 | }, |
103 | 103 | "id": 14 |
104 | 104 | }, |
105 | 105 | { |
106 | 106 | "package": { |
107 | 107 | "dependencyId": 0, |
108 | | - "containValue": "HandleInsert" |
| 108 | + "containValue": "User" |
109 | 109 | }, |
110 | 110 | "id": 15 |
111 | 111 | }, |
112 | 112 | { |
113 | 113 | "package": { |
114 | 114 | "dependencyId": 0, |
115 | | - "containValue": "HandleUpdate" |
| 115 | + "containValue": "SyncTextFile" |
116 | 116 | }, |
117 | 117 | "id": 16 |
118 | 118 | }, |
119 | 119 | { |
120 | 120 | "package": { |
121 | | - "dependencyId": 3, |
122 | | - "containValue": "UpdateHandler" |
| 121 | + "dependencyId": 0, |
| 122 | + "containValue": "Tree" |
123 | 123 | }, |
124 | 124 | "id": 17 |
125 | 125 | }, |
126 | 126 | { |
127 | | - "id": "ServiceAccount", |
128 | | - "type": 1 |
129 | | - }, |
130 | | - { |
131 | | - "id": "TypeOfValueOfServiceAccount", |
132 | | - "type": 2, |
133 | | - "from": "ServiceAccount", |
134 | | - "to": 3 |
135 | | - }, |
136 | | - { |
137 | | - "id": "UsesServiceAccount", |
138 | | - "type": 1, |
139 | | - "from": 4, |
140 | | - "to": "ServiceAccount" |
141 | | - }, |
142 | | - { |
143 | | - "id": "PushNotification", |
144 | | - "type": 1 |
145 | | - }, |
146 | | - { |
147 | | - "id": "PushNotificationBody", |
| 127 | + "id": "PushNotificationNotifyInsertHandler", |
148 | 128 | "type": 1, |
149 | | - "from": "PushNotification", |
150 | | - "to": "PushNotification" |
| 129 | + "from": 2, |
| 130 | + "to": "PushNotificationNotifyInsertHandlerCode" |
151 | 131 | }, |
152 | 132 | { |
153 | 133 | "id": "TypeOfValueOfPushNotificationBody", |
154 | | - "type": 2, |
| 134 | + "type": 3, |
155 | 135 | "from": "PushNotificationBody", |
156 | | - "to": 5 |
| 136 | + "to": 4 |
157 | 137 | }, |
158 | 138 | { |
159 | 139 | "id": "PushNotificationTitle", |
160 | | - "type": 1, |
| 140 | + "type": 5, |
161 | 141 | "from": "PushNotification", |
162 | 142 | "to": "PushNotification" |
163 | 143 | }, |
164 | 144 | { |
165 | 145 | "id": "TypeOfValueOfPushNotificationTitle", |
166 | | - "type": 2, |
| 146 | + "type": 3, |
167 | 147 | "from": "PushNotificationTitle", |
168 | | - "to": 5 |
| 148 | + "to": 4 |
169 | 149 | }, |
170 | 150 | { |
171 | 151 | "id": "Notify", |
|
180 | 160 | "to": 7 |
181 | 161 | }, |
182 | 162 | { |
183 | | - "id": "WebPushCertificate", |
184 | | - "type": 1 |
185 | | - }, |
186 | | - { |
187 | | - "id": "UsesWebPushCertificate", |
188 | | - "type": 1, |
189 | | - "from": 4, |
190 | | - "to": "WebPushCertificate" |
191 | | - }, |
192 | | - { |
193 | | - "id": "TypeOfValueOfWebPushCertificate", |
194 | | - "type": 2, |
195 | | - "from": "WebPushCertificate", |
196 | | - "to": 5 |
197 | | - }, |
198 | | - { |
199 | | - "id": "DeviceRegistrationToken", |
200 | | - "type": 1 |
201 | | - }, |
202 | | - { |
203 | | - "id": "PushNotificationTree", |
204 | | - "type": 9 |
| 163 | + "id": "HandlePushNotificationNotifyInsert", |
| 164 | + "type": 9, |
| 165 | + "from": "Notify", |
| 166 | + "to": "PushNotificationNotifyInsertHandler" |
205 | 167 | }, |
206 | 168 | { |
207 | 169 | "id": "TreeIncludeFromCurrentPushNotificationBody", |
|
222 | 184 | "to": "PushNotification" |
223 | 185 | }, |
224 | 186 | { |
225 | | - "id": "PushNotificationNotifyInsertHandlerCode", |
| 187 | + "id": "HandleUpdateOfPushNotification", |
226 | 188 | "type": 12, |
227 | | - "value": { |
228 | | - "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" |
229 | | - } |
| 189 | + "from": "PushNotification", |
| 190 | + "to": 13 |
230 | 191 | }, |
231 | 192 | { |
232 | | - "id": "PushNotificationNotifyInsertHandler", |
233 | | - "type": 13, |
234 | | - "from": 14, |
235 | | - "to": "PushNotificationNotifyInsertHandlerCode" |
| 193 | + "id": "ServiceAccount", |
| 194 | + "type": 5 |
236 | 195 | }, |
237 | 196 | { |
238 | | - "id": "HandlePushNotificationNotifyInsert", |
239 | | - "type": 15, |
240 | | - "from": "Notify", |
241 | | - "to": "PushNotificationNotifyInsertHandler" |
| 197 | + "id": "TypeOfValueOfServiceAccount", |
| 198 | + "type": 3, |
| 199 | + "from": "ServiceAccount", |
| 200 | + "to": 14 |
242 | 201 | }, |
243 | 202 | { |
244 | | - "id": "HandleUpdateOfPushNotification", |
245 | | - "type": 16, |
| 203 | + "id": "UsesServiceAccount", |
| 204 | + "type": 5, |
| 205 | + "from": 15, |
| 206 | + "to": "ServiceAccount" |
| 207 | + }, |
| 208 | + { |
| 209 | + "id": "PushNotification", |
| 210 | + "type": 5 |
| 211 | + }, |
| 212 | + { |
| 213 | + "id": "PushNotificationBody", |
| 214 | + "type": 5, |
246 | 215 | "from": "PushNotification", |
247 | | - "to": 17 |
| 216 | + "to": "PushNotification" |
248 | 217 | }, |
249 | 218 | { |
250 | 219 | "id": "TypeOfValueOfPushNotification", |
251 | | - "type": 2, |
| 220 | + "type": 3, |
252 | 221 | "from": "PushNotification", |
253 | | - "to": 3 |
| 222 | + "to": 14 |
| 223 | + }, |
| 224 | + { |
| 225 | + "id": "WebPushCertificate", |
| 226 | + "type": 5 |
| 227 | + }, |
| 228 | + { |
| 229 | + "id": "UsesWebPushCertificate", |
| 230 | + "type": 5, |
| 231 | + "from": 15, |
| 232 | + "to": "WebPushCertificate" |
| 233 | + }, |
| 234 | + { |
| 235 | + "id": "TypeOfValueOfWebPushCertificate", |
| 236 | + "type": 3, |
| 237 | + "from": "WebPushCertificate", |
| 238 | + "to": 4 |
| 239 | + }, |
| 240 | + { |
| 241 | + "id": "DeviceRegistrationToken", |
| 242 | + "type": 5 |
| 243 | + }, |
| 244 | + { |
| 245 | + "id": "PushNotificationNotifyInsertHandlerCode", |
| 246 | + "type": 16, |
| 247 | + "value": { |
| 248 | + "value": "async ({ require, deep, data: { newLink: notifyLink, triggeredByLinkId } }) => {\n const firebaseAdmin = require('firebase-admin');\n\n const notificationLinkId = notifyLink.from_id;\n const {data: [notificationLink]} = await deep.select(notificationLinkId)\n if(!notificationLink.value?.value) {\n throw new Error(`##${notificationLinkId} must have value`)\n }\n const title = notificationLink.value.value.title;\n if(!title) {\n throw new Error(`Object value of ##${notificationLinkId} must have title property`)\n }\n \n const body = notificationLink.value.value.body;\n if(!body) {\n throw new Error(`Object value of ##${notificationLinkId} must have body property`)\n }\n\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\n const deviceRegistrationToken = await getDeviceRegistrationToken({\n containTypeLinkId,\n deviceLinkId,\n });\n \n const pushNotificationData = {\n token: deviceRegistrationToken,\n notification: {\n title: title,\n body: body,\n },\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 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" |
| 249 | + } |
| 250 | + }, |
| 251 | + { |
| 252 | + "id": "PushNotificationTree", |
| 253 | + "type": 17 |
254 | 254 | } |
255 | 255 | ], |
256 | 256 | "errors": [], |
|
0 commit comments