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