|
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