Compare commits

...

116 Commits

Author SHA1 Message Date
standardci
2e82be47ed chore(release): publish new version
- @standardnotes/analytics@2.10.2
2022-11-14 13:01:32 +00:00
Karol Sójko
15dfd6dcba fix(analytics): imports from domain-core 2022-11-14 13:59:06 +01:00
standardci
dfd38943b0 chore(release): publish new version
- @standardnotes/syncing-server@1.13.11
2022-11-14 12:51:16 +00:00
Karol Sójko
500756d582 fix(syncing-server): decrease logs severity for content recalculation 2022-11-14 13:49:28 +01:00
standardci
f855f541d8 chore(release): publish new version
- @standardnotes/auth-server@1.60.0
2022-11-14 12:48:49 +00:00
Karol Sójko
590ec6643d feat(auth): add content size recalculation procedure trigger 2022-11-14 13:46:40 +01:00
standardci
b9efd35b50 chore(release): publish new version
- @standardnotes/syncing-server@1.13.10
2022-11-14 12:32:48 +00:00
Karol Sójko
3be1bfe58a fix(syncing-server): linter issues 2022-11-14 13:30:41 +01:00
standardci
bfbd2de778 chore(release): publish new version
- @standardnotes/analytics@2.10.1
 - @standardnotes/domain-core@1.1.1
 - @standardnotes/syncing-server@1.13.9
2022-11-14 12:25:09 +00:00
Karol Sójko
50f7ae338a fix(syncing-server): retrieving revisions 2022-11-14 13:23:12 +01:00
standardci
280fdc89c1 chore(release): publish new version
- @standardnotes/analytics@2.10.0
 - @standardnotes/api-gateway@1.38.5
 - @standardnotes/auth-server@1.59.11
 - @standardnotes/common@1.45.0
 - @standardnotes/domain-core@1.1.0
 - @standardnotes/domain-events-infra@1.9.27
 - @standardnotes/domain-events@2.87.0
 - @standardnotes/event-store@1.6.22
 - @standardnotes/files-server@1.8.22
 - @standardnotes/predicates@1.6.0
 - @standardnotes/scheduler-server@1.13.23
 - @standardnotes/security@1.7.0
 - @standardnotes/sncrypto-node@1.13.0
 - @standardnotes/syncing-server@1.13.8
 - @standardnotes/time@1.14.0
 - @standardnotes/websockets-server@1.4.24
 - @standardnotes/workspace-server@1.17.22
2022-11-14 10:35:04 +00:00
Karol Sójko
0f94e2ad0c feat(analytics): extract domain core into a separate package 2022-11-14 11:32:31 +01:00
standardci
d0036600e9 chore(release): publish new version
- @standardnotes/syncing-server@1.13.7
2022-11-14 10:08:04 +00:00
Karol Sójko
f766fefbf0 fix(syncing-server): content recalculation missing await 2022-11-14 11:06:15 +01:00
standardci
2178ed2a31 chore(release): publish new version
- @standardnotes/syncing-server@1.13.6
2022-11-14 09:42:58 +00:00
Karol Sójko
79511aea5f fix(syncing-server): add missing content size recalculation handler binding 2022-11-14 10:40:51 +01:00
standardci
19bb77273b chore(release): publish new version
- @standardnotes/analytics@2.9.9
 - @standardnotes/api-gateway@1.38.4
 - @standardnotes/auth-server@1.59.10
 - @standardnotes/common@1.44.4
 - @standardnotes/domain-events-infra@1.9.26
 - @standardnotes/domain-events@2.86.3
 - @standardnotes/event-store@1.6.21
 - @standardnotes/files-server@1.8.21
 - @standardnotes/predicates@1.5.7
 - @standardnotes/scheduler-server@1.13.22
 - @standardnotes/security@1.6.4
 - @standardnotes/settings@1.18.3
 - @standardnotes/sncrypto-node@1.12.3
 - @standardnotes/syncing-server@1.13.5
 - @standardnotes/time@1.13.3
 - @standardnotes/websockets-server@1.4.23
 - @standardnotes/workspace-server@1.17.21
2022-11-14 09:39:52 +00:00
Karol Sójko
7ca377f1b8 fix: versioning issue 2022-11-14 10:37:27 +01:00
Karol Sójko
6f5e9b7b5a fix(api-gateway): bump version 2022-11-14 10:32:54 +01:00
Karol Sójko
f03a58079d chore(deps): upgrade node types 2022-11-14 10:29:20 +01:00
Karol Sójko
8715fe1822 fix(analytics): bump version 2022-11-14 10:27:20 +01:00
Karol Sójko
e10cb9adaf chore(deps): upgrade to latest node LTS 2022-11-14 10:21:18 +01:00
Karol Sójko
3030832711 chore(deps): upgrade typeorm 2022-11-14 10:13:12 +01:00
Karol Sójko
7c638ef28a chore(deps): add missing sentry deps 2022-11-14 10:11:32 +01:00
Karol Sójko
447a4b5e04 chore(deps): upgrade sentry 2022-11-14 10:11:00 +01:00
Karol Sójko
dd1ba6e302 chore(deps): upgrade aws-sdk 2022-11-14 10:10:18 +01:00
Karol Sójko
08556b751f chore(deps): upgrade express 2022-11-14 10:09:42 +01:00
Karol Sójko
11d2190310 chore(deps): upgrade ioredis 2022-11-14 10:08:54 +01:00
Karol Sójko
46519bb710 chore(deps): add newrelic native metrics to measure oom issues 2022-11-14 10:06:49 +01:00
standardci
7b9290382d chore(release): publish new version
- @standardnotes/analytics@2.9.6
 - @standardnotes/api-gateway@1.38.1
 - @standardnotes/auth-server@1.59.7
 - @standardnotes/domain-events-infra@1.9.23
 - @standardnotes/event-store@1.6.18
 - @standardnotes/files-server@1.8.18
 - @standardnotes/scheduler-server@1.13.19
 - @standardnotes/syncing-server@1.13.2
 - @standardnotes/websockets-server@1.4.20
 - @standardnotes/workspace-server@1.17.18
2022-11-14 09:03:07 +00:00
Karol Sójko
85e55cf0e4 chore(deps): upgrade newrelic 2022-11-14 10:01:08 +01:00
standardci
7016854b7f chore(release): publish new version
- @standardnotes/syncing-server@1.13.1
2022-11-14 08:14:00 +00:00
Karol Sójko
01a4151763 fix(syncing-server): add debugs logs for content size recalculation handler 2022-11-14 09:11:33 +01:00
standardci
311f758cd8 chore(release): publish new version
- @standardnotes/api-gateway@1.38.0
2022-11-13 15:06:19 +00:00
Mo
3bba36742a feat: iap confirm endpoint (#338) 2022-11-13 09:04:27 -06:00
standardci
ea52ba51ca chore(release): publish new version
- @standardnotes/syncing-server@1.13.0
2022-11-11 12:57:03 +00:00
Karol Sójko
7e404ae71a feat(syncing-server): add content size recalculation job 2022-11-11 13:54:45 +01:00
standardci
3ad95afa84 chore(release): publish new version
- @standardnotes/analytics@2.9.5
 - @standardnotes/api-gateway@1.37.11
 - @standardnotes/auth-server@1.59.6
 - @standardnotes/domain-events-infra@1.9.22
 - @standardnotes/domain-events@2.86.0
 - @standardnotes/event-store@1.6.17
 - @standardnotes/files-server@1.8.17
 - @standardnotes/scheduler-server@1.13.18
 - @standardnotes/syncing-server@1.12.0
 - @standardnotes/websockets-server@1.4.19
 - @standardnotes/workspace-server@1.17.17
2022-11-11 12:45:17 +00:00
Karol Sójko
1a13861647 feat(syncing-server): add item content size recalculation 2022-11-11 13:43:22 +01:00
standardci
6d84c819c0 chore(release): publish new version
- @standardnotes/analytics@2.9.4
 - @standardnotes/api-gateway@1.37.10
 - @standardnotes/auth-server@1.59.5
 - @standardnotes/domain-events-infra@1.9.21
 - @standardnotes/domain-events@2.85.0
 - @standardnotes/event-store@1.6.16
 - @standardnotes/files-server@1.8.16
 - @standardnotes/scheduler-server@1.13.17
 - @standardnotes/syncing-server@1.11.10
 - @standardnotes/websockets-server@1.4.18
 - @standardnotes/workspace-server@1.17.16
2022-11-11 12:11:40 +00:00
Karol Sójko
36ec39d2fb feat(domain-events): add user content size recalculation requested event 2022-11-11 13:09:33 +01:00
standardci
eaafc12c8a chore(release): publish new version
- @standardnotes/analytics@2.9.3
 - @standardnotes/api-gateway@1.37.9
 - @standardnotes/auth-server@1.59.4
 - @standardnotes/common@1.44.1
 - @standardnotes/domain-events-infra@1.9.20
 - @standardnotes/domain-events@2.84.1
 - @standardnotes/event-store@1.6.15
 - @standardnotes/files-server@1.8.15
 - @standardnotes/predicates@1.5.4
 - @standardnotes/scheduler-server@1.13.16
 - @standardnotes/security@1.6.1
 - @standardnotes/syncing-server@1.11.9
 - @standardnotes/websockets-server@1.4.17
 - @standardnotes/workspace-server@1.17.15
2022-11-10 18:20:16 +00:00
Karol Sójko
a03c5bceea fix(analytics): add five year plans mrr calculation 2022-11-10 19:18:25 +01:00
standardci
53c51fd204 chore(release): publish new version
- @standardnotes/analytics@2.9.2
2022-11-10 15:21:59 +00:00
Karol Sójko
9b593f2a6b fix(analytics): add missing period for stats report 2022-11-10 16:19:45 +01:00
standardci
363609cb1b chore(release): publish new version
- @standardnotes/api-gateway@1.37.8
 - @standardnotes/auth-server@1.59.3
 - @standardnotes/syncing-server@1.11.8
 - @standardnotes/websockets-server@1.4.16
2022-11-10 15:19:21 +00:00
Karol Sójko
68e6d30093 chore(deps): fix axios imports 2022-11-10 16:17:11 +01:00
standardci
c53a40ef8d chore(release): publish new version
- @standardnotes/api-gateway@1.37.7
 - @standardnotes/auth-server@1.59.2
 - @standardnotes/syncing-server@1.11.7
 - @standardnotes/websockets-server@1.4.15
2022-11-10 14:42:52 +00:00
Karol Sójko
3c2ac05c60 fix(api-gateway): setting headers 2022-11-10 15:39:57 +01:00
Karol Sójko
bffab433f6 chore(deps): upgrade ua-parser-js 2022-11-10 15:37:31 +01:00
Karol Sójko
200b6ce01f chore(deps): upgrade axios 2022-11-10 15:35:39 +01:00
standardci
0d29dc1012 chore(release): publish new version
- @standardnotes/analytics@2.9.1
2022-11-10 14:24:45 +00:00
Karol Sójko
b92c4ae650 fix(analytics): generate mrr stats for last 30 days including Today 2022-11-10 15:22:52 +01:00
standardci
e15d1e52bd chore(release): publish new version
- @standardnotes/analytics@2.9.0
2022-11-10 14:19:41 +00:00
Karol Sójko
ce3e259bde feat(analytics): add mrr for annual, monthly, pro and plus subscription plans 2022-11-10 15:17:35 +01:00
standardci
87361f90b1 chore(release): publish new version
- @standardnotes/analytics@2.8.3
2022-11-10 11:27:40 +00:00
Karol Sójko
81be06598c fix(analytics): add subscription id to error logs 2022-11-10 12:25:46 +01:00
standardci
9492da6789 chore(release): publish new version
- @standardnotes/analytics@2.8.2
2022-11-10 10:54:18 +00:00
Karol Sójko
fce47a0a37 fix(analytics): add monthly mrr to the report 2022-11-10 11:52:24 +01:00
standardci
92ba682198 chore(release): publish new version
- @standardnotes/analytics@2.8.1
2022-11-10 10:43:40 +00:00
Karol Sójko
8df0482eb4 fix(analytics): add persisting mrr for this month and this year as well 2022-11-10 11:41:24 +01:00
standardci
37a5cb347d chore(release): publish new version
- @standardnotes/analytics@2.8.0
 - @standardnotes/api-gateway@1.37.6
 - @standardnotes/auth-server@1.59.1
 - @standardnotes/domain-events-infra@1.9.19
 - @standardnotes/domain-events@2.84.0
 - @standardnotes/event-store@1.6.14
 - @standardnotes/files-server@1.8.14
 - @standardnotes/scheduler-server@1.13.15
 - @standardnotes/syncing-server@1.11.6
 - @standardnotes/websockets-server@1.4.14
 - @standardnotes/workspace-server@1.17.14
2022-11-10 10:35:38 +00:00
Karol Sójko
77e50655f6 feat(analytics): add calculating monthly recurring revenue 2022-11-10 11:33:46 +01:00
standardci
eacd2abc00 chore(release): publish new version
- @standardnotes/analytics@2.7.3
2022-11-10 06:55:58 +00:00
Karol Sójko
7393954ff6 fix(analytics): arhcitecture arrangements for use case execution 2022-11-10 07:54:06 +01:00
standardci
68744379a6 chore(release): publish new version
- @standardnotes/analytics@2.7.2
2022-11-09 12:11:11 +00:00
Karol Sójko
90aef905af fix(analytics): mrr column types 2022-11-09 13:09:14 +01:00
standardci
c7cbc8966e chore(release): publish new version
- @standardnotes/analytics@2.7.1
2022-11-09 11:43:39 +00:00
Karol Sójko
89502bed63 fix(analytics): add missing created at column 2022-11-09 12:41:45 +01:00
standardci
4952b48db6 chore(release): publish new version
- @standardnotes/analytics@2.7.0
 - @standardnotes/api-gateway@1.37.5
 - @standardnotes/auth-server@1.59.0
 - @standardnotes/domain-events-infra@1.9.18
 - @standardnotes/domain-events@2.83.0
 - @standardnotes/event-store@1.6.13
 - @standardnotes/files-server@1.8.13
 - @standardnotes/scheduler-server@1.13.14
 - @standardnotes/syncing-server@1.11.5
 - @standardnotes/websockets-server@1.4.13
 - @standardnotes/workspace-server@1.17.13
2022-11-09 10:27:37 +00:00
Karol Sójko
52a257abb1 feat(analytics): add saving revenue modifications upon subscription canceled 2022-11-09 11:25:26 +01:00
standardci
7480fb089b chore(release): publish new version
- @standardnotes/analytics@2.6.0
 - @standardnotes/api-gateway@1.37.4
 - @standardnotes/auth-server@1.58.0
 - @standardnotes/domain-events-infra@1.9.17
 - @standardnotes/domain-events@2.82.0
 - @standardnotes/event-store@1.6.12
 - @standardnotes/files-server@1.8.12
 - @standardnotes/scheduler-server@1.13.13
 - @standardnotes/syncing-server@1.11.4
 - @standardnotes/websockets-server@1.4.12
 - @standardnotes/workspace-server@1.17.12
2022-11-09 10:20:29 +00:00
Karol Sójko
0f65c051ab feat(analytics): add saving revenue modifications upon subscription refunded 2022-11-09 11:17:27 +01:00
standardci
7b62c7a967 chore(release): publish new version
- @standardnotes/analytics@2.5.0
 - @standardnotes/api-gateway@1.37.3
 - @standardnotes/auth-server@1.57.0
 - @standardnotes/domain-events-infra@1.9.16
 - @standardnotes/domain-events@2.81.0
 - @standardnotes/event-store@1.6.11
 - @standardnotes/files-server@1.8.11
 - @standardnotes/scheduler-server@1.13.12
 - @standardnotes/syncing-server@1.11.3
 - @standardnotes/websockets-server@1.4.11
 - @standardnotes/workspace-server@1.17.11
2022-11-09 10:12:01 +00:00
Karol Sójko
5c3db2cb29 feat(analytics): add saving revenue modifications upon subscription expired 2022-11-09 11:09:49 +01:00
standardci
7008cbd363 chore(release): publish new version
- @standardnotes/analytics@2.4.0
 - @standardnotes/api-gateway@1.37.2
 - @standardnotes/auth-server@1.56.0
 - @standardnotes/domain-events-infra@1.9.15
 - @standardnotes/domain-events@2.80.0
 - @standardnotes/event-store@1.6.10
 - @standardnotes/files-server@1.8.10
 - @standardnotes/scheduler-server@1.13.11
 - @standardnotes/syncing-server@1.11.2
 - @standardnotes/websockets-server@1.4.10
 - @standardnotes/workspace-server@1.17.10
2022-11-09 09:59:41 +00:00
Karol Sójko
cdb7fcf831 feat(analytics): add saving revenue modifications upon subscription renewed 2022-11-09 10:57:43 +01:00
standardci
628aafdd42 chore(release): publish new version
- @standardnotes/analytics@2.3.1
2022-11-09 09:49:22 +00:00
Karol Sójko
9d3ef24ba9 fix(analytics): missing injectable annotation 2022-11-09 10:47:27 +01:00
standardci
4189f11fd7 chore(release): publish new version
- @standardnotes/analytics@2.3.0
 - @standardnotes/api-gateway@1.37.1
 - @standardnotes/auth-server@1.55.0
 - @standardnotes/domain-events-infra@1.9.14
 - @standardnotes/domain-events@2.79.0
 - @standardnotes/event-store@1.6.9
 - @standardnotes/files-server@1.8.9
 - @standardnotes/scheduler-server@1.13.10
 - @standardnotes/syncing-server@1.11.1
 - @standardnotes/websockets-server@1.4.9
 - @standardnotes/workspace-server@1.17.9
2022-11-09 07:16:01 +00:00
Karol Sójko
5ea9941519 feat(analytics): add saving revenue modifications upon subscription purchased 2022-11-09 08:14:02 +01:00
standardci
7a64494d07 chore(release): publish new version
- @standardnotes/analytics@2.2.0
2022-11-08 14:16:38 +00:00
Karol Sójko
4928685198 feat(analytics): add persistence for revenue modifications 2022-11-08 15:14:39 +01:00
Karol Sójko
0103233d4a feat(analytics): create new ddd architecture for persisting revenue modifications 2022-11-08 15:14:38 +01:00
standardci
ee7075fe60 chore(release): publish new version
- @standardnotes/auth-server@1.54.0
2022-11-07 10:59:27 +00:00
Karol Sójko
49feadd32a feat(auth): remove analytics table in favor of analytics service 2022-11-07 11:57:39 +01:00
standardci
45758bf554 chore(release): publish new version
- @standardnotes/analytics@2.1.0
 - @standardnotes/api-gateway@1.37.0
 - @standardnotes/auth-server@1.53.0
 - @standardnotes/domain-events-infra@1.9.13
 - @standardnotes/domain-events@2.78.1
 - @standardnotes/event-store@1.6.8
 - @standardnotes/files-server@1.8.8
 - @standardnotes/scheduler-server@1.13.9
 - @standardnotes/security@1.6.0
 - @standardnotes/syncing-server@1.11.0
 - @standardnotes/websockets-server@1.4.8
 - @standardnotes/workspace-server@1.17.8
2022-11-07 10:54:09 +00:00
Karol Sójko
535d566a94 fix: yarn.lock 2022-11-07 11:52:16 +01:00
Karol Sójko
ff1d5db12c feat: remove analytics scope from other services in favor of a separate service 2022-11-07 11:51:38 +01:00
standardci
77a06b2fe7 chore(release): publish new version
- @standardnotes/analytics@1.52.0
 - @standardnotes/api-gateway@1.36.14
 - @standardnotes/auth-server@1.52.1
 - @standardnotes/syncing-server@1.10.25
2022-11-07 09:20:01 +00:00
Karol Sójko
6359030030 feat(analytics): add handling subscription reactivated events 2022-11-07 10:17:49 +01:00
standardci
006f1fccec chore(release): publish new version
- @standardnotes/analytics@1.51.0
 - @standardnotes/api-gateway@1.36.13
 - @standardnotes/auth-server@1.52.0
 - @standardnotes/domain-events-infra@1.9.12
 - @standardnotes/domain-events@2.78.0
 - @standardnotes/event-store@1.6.7
 - @standardnotes/files-server@1.8.7
 - @standardnotes/scheduler-server@1.13.8
 - @standardnotes/syncing-server@1.10.24
 - @standardnotes/websockets-server@1.4.7
 - @standardnotes/workspace-server@1.17.7
2022-11-07 09:16:03 +00:00
Karol Sójko
c0f5817d47 feat(analytics): add handling subscription expired events 2022-11-07 10:14:12 +01:00
standardci
3da952fa52 chore(release): publish new version
- @standardnotes/analytics@1.50.0
 - @standardnotes/api-gateway@1.36.12
 - @standardnotes/auth-server@1.51.0
 - @standardnotes/domain-events-infra@1.9.11
 - @standardnotes/domain-events@2.77.0
 - @standardnotes/event-store@1.6.6
 - @standardnotes/files-server@1.8.6
 - @standardnotes/scheduler-server@1.13.7
 - @standardnotes/syncing-server@1.10.23
 - @standardnotes/websockets-server@1.4.6
 - @standardnotes/workspace-server@1.17.6
2022-11-07 09:03:54 +00:00
Karol Sójko
f1834d58d2 feat(analytics): add handling subscription purchased events 2022-11-07 10:02:07 +01:00
standardci
b0cde4ab75 chore(release): publish new version
- @standardnotes/analytics@1.49.0
 - @standardnotes/api-gateway@1.36.11
 - @standardnotes/auth-server@1.50.0
 - @standardnotes/domain-events-infra@1.9.10
 - @standardnotes/domain-events@2.76.0
 - @standardnotes/event-store@1.6.5
 - @standardnotes/files-server@1.8.5
 - @standardnotes/scheduler-server@1.13.6
 - @standardnotes/syncing-server@1.10.22
 - @standardnotes/websockets-server@1.4.5
 - @standardnotes/workspace-server@1.17.5
2022-11-07 06:45:26 +00:00
Karol Sójko
197c9914ca feat(analytics): add handling subscription refunded event 2022-11-07 07:43:36 +01:00
standardci
d7ef6898be chore(release): publish new version
- @standardnotes/analytics@1.48.0
 - @standardnotes/api-gateway@1.36.10
 - @standardnotes/auth-server@1.49.13
 - @standardnotes/syncing-server@1.10.21
2022-11-07 06:13:47 +00:00
Karol Sójko
2aa57f1f0d feat(analytics): add subscription renewed event handler 2022-11-07 07:11:10 +01:00
standardci
dcc0e38707 chore(release): publish new version
- @standardnotes/analytics@1.47.0
 - @standardnotes/api-gateway@1.36.9
 - @standardnotes/auth-server@1.49.12
 - @standardnotes/domain-events-infra@1.9.9
 - @standardnotes/domain-events@2.75.0
 - @standardnotes/event-store@1.6.4
 - @standardnotes/files-server@1.8.4
 - @standardnotes/scheduler-server@1.13.5
 - @standardnotes/syncing-server@1.10.20
 - @standardnotes/websockets-server@1.4.4
 - @standardnotes/workspace-server@1.17.4
2022-11-04 14:01:17 +00:00
Karol Sójko
037fb2398a feat(analytics): add subscription cancelled event handler 2022-11-04 14:59:30 +01:00
Karol Sójko
182512d07c fix(syncing-server): event specs 2022-11-04 14:59:30 +01:00
Karol Sójko
a3be4b063d fix(auth): event specs 2022-11-04 14:59:30 +01:00
standardci
a97be4c342 chore(release): publish new version
- @standardnotes/analytics@1.46.0
 - @standardnotes/api-gateway@1.36.8
 - @standardnotes/auth-server@1.49.11
 - @standardnotes/syncing-server@1.10.19
2022-11-04 13:28:39 +00:00
Karol Sójko
5902cbb621 feat(analytics): add payment success event handler 2022-11-04 14:26:47 +01:00
standardci
afc26d42ca chore(release): publish new version
- @standardnotes/analytics@1.45.0
 - @standardnotes/api-gateway@1.36.7
 - @standardnotes/auth-server@1.49.10
 - @standardnotes/syncing-server@1.10.18
2022-11-04 13:23:51 +00:00
Karol Sójko
51b12d05d4 feat: add payment failed handler and email to analytics entity 2022-11-04 14:21:34 +01:00
standardci
3fe7b4ae24 chore(release): publish new version
- @standardnotes/analytics@1.44.0
 - @standardnotes/api-gateway@1.36.6
 - @standardnotes/auth-server@1.49.9
 - @standardnotes/syncing-server@1.10.17
2022-11-04 13:02:55 +00:00
Karol Sójko
2720a7c827 feat(analytics): removing analytics entity upon account deletion 2022-11-04 14:01:10 +01:00
standardci
8d89b8ef12 chore(release): publish new version
- @standardnotes/analytics@1.43.0
 - @standardnotes/api-gateway@1.36.5
 - @standardnotes/auth-server@1.49.8
 - @standardnotes/domain-events-infra@1.9.8
 - @standardnotes/domain-events@2.74.1
 - @standardnotes/event-store@1.6.3
 - @standardnotes/files-server@1.8.3
 - @standardnotes/scheduler-server@1.13.4
 - @standardnotes/syncing-server@1.10.16
 - @standardnotes/websockets-server@1.4.3
 - @standardnotes/workspace-server@1.17.3
2022-11-04 12:55:55 +00:00
Karol Sójko
5383e0cf52 feat(analytics): add account deletion event handler 2022-11-04 13:54:07 +01:00
Karol Sójko
7b05bf8991 fix(auth): add user created at timestamp to account deletion event 2022-11-04 13:54:07 +01:00
Karol Sójko
b4c5b5a84e fix(api-gateway): removing sns bindings 2022-11-04 13:54:07 +01:00
standardci
e115523acd chore(release): publish new version
- @standardnotes/analytics@1.42.0
 - @standardnotes/api-gateway@1.36.4
 - @standardnotes/auth-server@1.49.7
 - @standardnotes/syncing-server@1.10.15
2022-11-04 10:20:35 +00:00
Karol Sójko
35611fbc07 fix(analytics): imports 2022-11-04 11:18:03 +01:00
Karol Sójko
034aa38153 feat(analytics): add user registered handler 2022-11-04 11:10:03 +01:00
295 changed files with 5408 additions and 3624 deletions

2
.nvmrc
View File

@@ -1 +1 @@
16.15.1
18.12.1

371
.pnp.cjs generated
View File

@@ -29,6 +29,10 @@ const RAW_RUNTIME_STATE =
"name": "@standardnotes/common",\
"reference": "workspace:packages/common"\
},\
{\
"name": "@standardnotes/domain-core",\
"reference": "workspace:packages/domain-core"\
},\
{\
"name": "@standardnotes/domain-events",\
"reference": "workspace:packages/domain-events"\
@@ -89,6 +93,7 @@ const RAW_RUNTIME_STATE =
["@standardnotes/api-gateway", ["workspace:packages/api-gateway"]],\
["@standardnotes/auth-server", ["workspace:packages/auth"]],\
["@standardnotes/common", ["workspace:packages/common"]],\
["@standardnotes/domain-core", ["workspace:packages/domain-core"]],\
["@standardnotes/domain-events", ["workspace:packages/domain-events"]],\
["@standardnotes/domain-events-infra", ["workspace:packages/domain-events-infra"]],\
["@standardnotes/event-store", ["workspace:packages/event-store"]],\
@@ -116,15 +121,16 @@ const RAW_RUNTIME_STATE =
["@lerna-lite/cli", "npm:1.6.0"],\
["@lerna-lite/list", "npm:1.6.0"],\
["@lerna-lite/run", "npm:1.6.0"],\
["@sentry/node", "npm:7.5.0"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@sentry/node", "npm:7.19.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\
["@types/node", "npm:18.0.3"],\
["@types/newrelic", "npm:7.0.4"],\
["@types/node", "npm:18.11.9"],\
["@typescript-eslint/parser", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:5.40.1"],\
["eslint", "npm:8.19.0"],\
["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.5.0"],\
["ini", "npm:3.0.0"],\
["newrelic", "npm:9.0.0"],\
["newrelic", "npm:9.6.0"],\
["npm-check-updates", "npm:16.0.1"],\
["prettier", "npm:2.7.1"],\
["ts-node", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:10.9.1"],\
@@ -1865,12 +1871,12 @@ const RAW_RUNTIME_STATE =
],\
"linkType": "SOFT"\
}],\
["virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:5.0.0", {\
"packageLocation": "./.yarn/__virtual__/@newrelic-aws-sdk-virtual-e9040e4121/0/cache/@newrelic-aws-sdk-npm-5.0.0-7d9d10d58f-ed1dc3fa16.zip/node_modules/@newrelic/aws-sdk/",\
["virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:5.0.0", {\
"packageLocation": "./.yarn/__virtual__/@newrelic-aws-sdk-virtual-ccf1e948b3/0/cache/@newrelic-aws-sdk-npm-5.0.0-7d9d10d58f-ed1dc3fa16.zip/node_modules/@newrelic/aws-sdk/",\
"packageDependencies": [\
["@newrelic/aws-sdk", "virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:5.0.0"],\
["@newrelic/aws-sdk", "virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:5.0.0"],\
["@types/newrelic", null],\
["newrelic", "npm:9.0.0"]\
["newrelic", "npm:9.6.0"]\
],\
"packagePeers": [\
"@types/newrelic",\
@@ -1887,12 +1893,12 @@ const RAW_RUNTIME_STATE =
],\
"linkType": "SOFT"\
}],\
["virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:7.0.0", {\
"packageLocation": "./.yarn/__virtual__/@newrelic-koa-virtual-d6376894e6/0/cache/@newrelic-koa-npm-7.0.0-903c251b9f-0fc2298c8b.zip/node_modules/@newrelic/koa/",\
["virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:7.0.0", {\
"packageLocation": "./.yarn/__virtual__/@newrelic-koa-virtual-613d84b4f1/0/cache/@newrelic-koa-npm-7.0.0-903c251b9f-0fc2298c8b.zip/node_modules/@newrelic/koa/",\
"packageDependencies": [\
["@newrelic/koa", "virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:7.0.0"],\
["@newrelic/koa", "virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:7.0.0"],\
["@types/newrelic", null],\
["newrelic", "npm:9.0.0"]\
["newrelic", "npm:9.6.0"]\
],\
"packagePeers": [\
"@types/newrelic",\
@@ -1922,12 +1928,12 @@ const RAW_RUNTIME_STATE =
],\
"linkType": "SOFT"\
}],\
["virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:6.0.0", {\
"packageLocation": "./.yarn/__virtual__/@newrelic-superagent-virtual-c2a5d7b8a8/0/cache/@newrelic-superagent-npm-6.0.0-db8b77d0f3-b77997b792.zip/node_modules/@newrelic/superagent/",\
["virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:6.0.0", {\
"packageLocation": "./.yarn/__virtual__/@newrelic-superagent-virtual-37eb7b41a0/0/cache/@newrelic-superagent-npm-6.0.0-db8b77d0f3-b77997b792.zip/node_modules/@newrelic/superagent/",\
"packageDependencies": [\
["@newrelic/superagent", "virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:6.0.0"],\
["@newrelic/superagent", "virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:6.0.0"],\
["@types/newrelic", null],\
["newrelic", "npm:9.0.0"]\
["newrelic", "npm:9.6.0"]\
],\
"packagePeers": [\
"@types/newrelic",\
@@ -1948,8 +1954,8 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./.yarn/__virtual__/@newrelic-winston-enricher-virtual-6b8c53ab3d/0/cache/@newrelic-winston-enricher-npm-4.0.0-ebaf2d0d28-3fc901cded.zip/node_modules/@newrelic/winston-enricher/",\
"packageDependencies": [\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@types/newrelic", "npm:7.0.3"],\
["newrelic", "npm:9.0.0"]\
["@types/newrelic", "npm:7.0.4"],\
["newrelic", "npm:9.6.0"]\
],\
"packagePeers": [\
"@types/newrelic",\
@@ -2428,39 +2434,25 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@sentry/core", [\
["npm:7.5.0", {\
"packageLocation": "./.yarn/cache/@sentry-core-npm-7.5.0-984c871a50-99c8e93a6f.zip/node_modules/@sentry/core/",\
["npm:7.19.0", {\
"packageLocation": "./.yarn/cache/@sentry-core-npm-7.19.0-151e6173ac-cabd7852ff.zip/node_modules/@sentry/core/",\
"packageDependencies": [\
["@sentry/core", "npm:7.5.0"],\
["@sentry/hub", "npm:7.5.0"],\
["@sentry/types", "npm:7.5.0"],\
["@sentry/utils", "npm:7.5.0"],\
["tslib", "npm:1.14.1"]\
],\
"linkType": "HARD"\
}]\
]],\
["@sentry/hub", [\
["npm:7.5.0", {\
"packageLocation": "./.yarn/cache/@sentry-hub-npm-7.5.0-993573a68c-27e240423e.zip/node_modules/@sentry/hub/",\
"packageDependencies": [\
["@sentry/hub", "npm:7.5.0"],\
["@sentry/types", "npm:7.5.0"],\
["@sentry/utils", "npm:7.5.0"],\
["@sentry/core", "npm:7.19.0"],\
["@sentry/types", "npm:7.19.0"],\
["@sentry/utils", "npm:7.19.0"],\
["tslib", "npm:1.14.1"]\
],\
"linkType": "HARD"\
}]\
]],\
["@sentry/node", [\
["npm:7.5.0", {\
"packageLocation": "./.yarn/cache/@sentry-node-npm-7.5.0-a14989f161-9b65bc44d2.zip/node_modules/@sentry/node/",\
["npm:7.19.0", {\
"packageLocation": "./.yarn/cache/@sentry-node-npm-7.19.0-fd3d8dbde1-3a69647d2e.zip/node_modules/@sentry/node/",\
"packageDependencies": [\
["@sentry/node", "npm:7.5.0"],\
["@sentry/core", "npm:7.5.0"],\
["@sentry/hub", "npm:7.5.0"],\
["@sentry/types", "npm:7.5.0"],\
["@sentry/utils", "npm:7.5.0"],\
["@sentry/node", "npm:7.19.0"],\
["@sentry/core", "npm:7.19.0"],\
["@sentry/types", "npm:7.19.0"],\
["@sentry/utils", "npm:7.19.0"],\
["cookie", "npm:0.4.2"],\
["https-proxy-agent", "npm:5.0.1"],\
["lru_map", "npm:0.3.3"],\
@@ -2470,20 +2462,20 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@sentry/types", [\
["npm:7.5.0", {\
"packageLocation": "./.yarn/cache/@sentry-types-npm-7.5.0-eea3d326fa-8029b56bae.zip/node_modules/@sentry/types/",\
["npm:7.19.0", {\
"packageLocation": "./.yarn/cache/@sentry-types-npm-7.19.0-d6ed1960f2-541e1ef49a.zip/node_modules/@sentry/types/",\
"packageDependencies": [\
["@sentry/types", "npm:7.5.0"]\
["@sentry/types", "npm:7.19.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["@sentry/utils", [\
["npm:7.5.0", {\
"packageLocation": "./.yarn/cache/@sentry-utils-npm-7.5.0-e8c66594bc-f5045667ea.zip/node_modules/@sentry/utils/",\
["npm:7.19.0", {\
"packageLocation": "./.yarn/cache/@sentry-utils-npm-7.19.0-79844d4d90-50e4f391fe.zip/node_modules/@sentry/utils/",\
"packageDependencies": [\
["@sentry/utils", "npm:7.5.0"],\
["@sentry/types", "npm:7.5.0"],\
["@sentry/utils", "npm:7.19.0"],\
["@sentry/types", "npm:7.19.0"],\
["tslib", "npm:1.14.1"]\
],\
"linkType": "HARD"\
@@ -2541,27 +2533,29 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/analytics/",\
"packageDependencies": [\
["@standardnotes/analytics", "workspace:packages/analytics"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.5.0"],\
["@sentry/node", "npm:7.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/time", "workspace:packages/time"],\
["@types/ioredis", "npm:4.28.10"],\
["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\
["@types/node", "npm:18.0.3"],\
["@types/newrelic", "npm:7.0.4"],\
["@types/node", "npm:18.11.9"],\
["@typescript-eslint/eslint-plugin", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:5.30.5"],\
["aws-sdk", "npm:2.1234.0"],\
["aws-sdk", "npm:2.1253.0"],\
["dayjs", "npm:1.11.6"],\
["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\
["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\
["inversify", "npm:6.0.1"],\
["ioredis", "npm:5.2.3"],\
["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\
["newrelic", "npm:9.6.0"],\
["reflect-metadata", "npm:0.1.13"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\
@@ -2592,9 +2586,9 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/api-gateway/",\
"packageDependencies": [\
["@standardnotes/api-gateway", "workspace:packages/api-gateway"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.5.0"],\
["@standardnotes/analytics", "workspace:packages/analytics"],\
["@sentry/node", "npm:7.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
@@ -2602,14 +2596,14 @@ const RAW_RUNTIME_STATE =
["@standardnotes/time", "workspace:packages/time"],\
["@types/cors", "npm:2.8.12"],\
["@types/express", "npm:4.17.14"],\
["@types/ioredis", "npm:4.28.10"],\
["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/jsonwebtoken", "npm:8.5.9"],\
["@types/newrelic", "npm:7.0.3"],\
["@types/newrelic", "npm:7.0.4"],\
["@types/prettyjson", "npm:0.0.30"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\
["aws-sdk", "npm:2.1234.0"],\
["axios", "npm:0.27.2"],\
["aws-sdk", "npm:2.1253.0"],\
["axios", "npm:1.1.3"],\
["cors", "npm:2.8.5"],\
["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\
@@ -2618,10 +2612,10 @@ const RAW_RUNTIME_STATE =
["helmet", "npm:6.0.0"],\
["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.2.3"],\
["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["jsonwebtoken", "npm:8.5.1"],\
["newrelic", "npm:9.0.0"],\
["newrelic", "npm:9.6.0"],\
["nodemon", "npm:2.0.20"],\
["npm-check-updates", "npm:16.0.1"],\
["prettyjson", "npm:1.2.5"],\
@@ -2649,9 +2643,9 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/auth/",\
"packageDependencies": [\
["@standardnotes/auth-server", "workspace:packages/auth"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.5.0"],\
["@standardnotes/analytics", "workspace:packages/analytics"],\
["@sentry/node", "npm:7.19.0"],\
["@standardnotes/api", "npm:1.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
@@ -2667,16 +2661,16 @@ const RAW_RUNTIME_STATE =
["@types/bcryptjs", "npm:2.4.2"],\
["@types/cors", "npm:2.8.12"],\
["@types/express", "npm:4.17.14"],\
["@types/ioredis", "npm:4.28.10"],\
["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\
["@types/newrelic", "npm:7.0.4"],\
["@types/otplib", "npm:10.0.0"],\
["@types/prettyjson", "npm:0.0.30"],\
["@types/ua-parser-js", "npm:0.7.36"],\
["@types/uuid", "npm:8.3.4"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\
["aws-sdk", "npm:2.1234.0"],\
["axios", "npm:0.27.2"],\
["aws-sdk", "npm:2.1253.0"],\
["axios", "npm:1.1.3"],\
["bcryptjs", "npm:2.4.3"],\
["cors", "npm:2.8.5"],\
["dayjs", "npm:1.11.6"],\
@@ -2686,10 +2680,10 @@ const RAW_RUNTIME_STATE =
["express", "npm:4.18.2"],\
["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.2.3"],\
["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\
["newrelic", "npm:9.6.0"],\
["nodemon", "npm:2.0.20"],\
["npm-check-updates", "npm:16.0.1"],\
["otplib", "npm:12.0.1"],\
@@ -2698,7 +2692,7 @@ const RAW_RUNTIME_STATE =
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\
["typescript", "patch:typescript@npm%3A4.8.4#optional!builtin<compat/typescript>::version=4.8.4&hash=701156"],\
["ua-parser-js", "npm:1.0.2"],\
["ua-parser-js", "npm:1.0.32"],\
["uuid", "npm:9.0.0"],\
["winston", "npm:3.8.2"]\
],\
@@ -2711,7 +2705,7 @@ const RAW_RUNTIME_STATE =
"packageDependencies": [\
["@standardnotes/common", "workspace:packages/common"],\
["@types/jest", "npm:29.1.1"],\
["@types/node", "npm:18.0.3"],\
["@types/node", "npm:18.11.9"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\
["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:4.2.1"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
@@ -2736,6 +2730,29 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["@standardnotes/domain-core", [\
["workspace:packages/domain-core", {\
"packageLocation": "./packages/domain-core/",\
"packageDependencies": [\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/features", "npm:1.53.1"],\
["@standardnotes/predicates", "workspace:packages/predicates"],\
["@standardnotes/security", "workspace:packages/security"],\
["@types/jest", "npm:29.1.1"],\
["@types/uuid", "npm:8.3.4"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\
["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:4.2.1"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["reflect-metadata", "npm:0.1.13"],\
["shallow-equal-object", "npm:1.1.1"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typescript", "patch:typescript@npm%3A4.8.4#optional!builtin<compat/typescript>::version=4.8.4&hash=701156"],\
["uuid", "npm:9.0.0"]\
],\
"linkType": "SOFT"\
}]\
]],\
["@standardnotes/domain-events", [\
["workspace:packages/domain-events", {\
"packageLocation": "./packages/domain-events/",\
@@ -2761,16 +2778,17 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/domain-events-infra/",\
"packageDependencies": [\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@types/ioredis", "npm:4.28.10"],\
["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\
["@types/newrelic", "npm:7.0.4"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\
["aws-sdk", "npm:2.1234.0"],\
["aws-sdk", "npm:2.1253.0"],\
["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:4.2.1"],\
["ioredis", "npm:5.2.3"],\
["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["newrelic", "npm:9.0.0"],\
["newrelic", "npm:9.6.0"],\
["reflect-metadata", "npm:0.1.13"],\
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:5.7.0"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
@@ -2800,23 +2818,24 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/event-store/",\
"packageDependencies": [\
["@standardnotes/event-store", "workspace:packages/event-store"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/time", "workspace:packages/time"],\
["@types/ioredis", "npm:4.28.10"],\
["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\
["@types/newrelic", "npm:7.0.4"],\
["@types/nodemailer", "npm:6.4.6"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\
["aws-sdk", "npm:2.1234.0"],\
["aws-sdk", "npm:2.1253.0"],\
["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\
["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\
["inversify", "npm:6.0.1"],\
["ioredis", "npm:5.2.3"],\
["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\
["newrelic", "npm:9.6.0"],\
["reflect-metadata", "npm:0.1.13"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\
@@ -2855,7 +2874,8 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/files/",\
"packageDependencies": [\
["@standardnotes/files-server", "workspace:packages/files"],\
["@sentry/node", "npm:7.5.0"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@sentry/node", "npm:7.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/config", "npm:2.4.3"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
@@ -2867,14 +2887,14 @@ const RAW_RUNTIME_STATE =
["@types/connect-busboy", "npm:1.0.0"],\
["@types/cors", "npm:2.8.12"],\
["@types/express", "npm:4.17.14"],\
["@types/ioredis", "npm:4.28.10"],\
["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/jsonwebtoken", "npm:8.5.9"],\
["@types/newrelic", "npm:7.0.3"],\
["@types/newrelic", "npm:7.0.4"],\
["@types/prettyjson", "npm:0.0.30"],\
["@types/uuid", "npm:8.3.4"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\
["aws-sdk", "npm:2.1234.0"],\
["aws-sdk", "npm:2.1253.0"],\
["connect-busboy", "npm:1.0.0"],\
["cors", "npm:2.8.5"],\
["dayjs", "npm:1.11.6"],\
@@ -2886,10 +2906,10 @@ const RAW_RUNTIME_STATE =
["helmet", "npm:6.0.0"],\
["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.2.3"],\
["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["jsonwebtoken", "npm:8.5.1"],\
["newrelic", "npm:9.0.0"],\
["newrelic", "npm:9.6.0"],\
["nodemon", "npm:2.0.20"],\
["npm-check-updates", "npm:16.0.1"],\
["prettyjson", "npm:1.2.5"],\
@@ -2989,28 +3009,29 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/scheduler/",\
"packageDependencies": [\
["@standardnotes/scheduler-server", "workspace:packages/scheduler"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.5.0"],\
["@sentry/node", "npm:7.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/predicates", "workspace:packages/predicates"],\
["@standardnotes/time", "workspace:packages/time"],\
["@types/ioredis", "npm:4.28.10"],\
["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\
["@types/node", "npm:18.0.3"],\
["@types/newrelic", "npm:7.0.4"],\
["@types/node", "npm:18.11.9"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\
["aws-sdk", "npm:2.1234.0"],\
["aws-sdk", "npm:2.1253.0"],\
["dayjs", "npm:1.11.6"],\
["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\
["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\
["inversify", "npm:6.0.1"],\
["ioredis", "npm:5.2.3"],\
["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\
["newrelic", "npm:9.6.0"],\
["npm-check-updates", "npm:16.0.1"],\
["reflect-metadata", "npm:0.1.13"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
@@ -3050,15 +3071,16 @@ const RAW_RUNTIME_STATE =
["@lerna-lite/cli", "npm:1.6.0"],\
["@lerna-lite/list", "npm:1.6.0"],\
["@lerna-lite/run", "npm:1.6.0"],\
["@sentry/node", "npm:7.5.0"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@sentry/node", "npm:7.19.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\
["@types/node", "npm:18.0.3"],\
["@types/newrelic", "npm:7.0.4"],\
["@types/node", "npm:18.11.9"],\
["@typescript-eslint/parser", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:5.40.1"],\
["eslint", "npm:8.19.0"],\
["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.5.0"],\
["ini", "npm:3.0.0"],\
["newrelic", "npm:9.0.0"],\
["newrelic", "npm:9.6.0"],\
["npm-check-updates", "npm:16.0.1"],\
["prettier", "npm:2.7.1"],\
["ts-node", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:10.9.1"],\
@@ -3072,6 +3094,7 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/settings/",\
"packageDependencies": [\
["@standardnotes/settings", "workspace:packages/settings"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\
["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:4.2.1"],\
["reflect-metadata", "npm:0.1.13"],\
@@ -3097,7 +3120,7 @@ const RAW_RUNTIME_STATE =
["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\
["@standardnotes/sncrypto-common", "npm:1.13.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/node", "npm:18.0.3"],\
["@types/node", "npm:18.11.9"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\
["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:4.2.1"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
@@ -3115,10 +3138,11 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/syncing-server/",\
"packageDependencies": [\
["@standardnotes/syncing-server", "workspace:packages/syncing-server"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.5.0"],\
["@standardnotes/analytics", "workspace:packages/analytics"],\
["@sentry/node", "npm:7.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/payloads", "npm:1.5.1"],\
@@ -3130,16 +3154,16 @@ const RAW_RUNTIME_STATE =
["@types/dotenv", "npm:8.2.0"],\
["@types/express", "npm:4.17.14"],\
["@types/inversify-express-utils", "npm:2.0.0"],\
["@types/ioredis", "npm:4.28.10"],\
["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/jsonwebtoken", "npm:8.5.9"],\
["@types/newrelic", "npm:7.0.3"],\
["@types/newrelic", "npm:7.0.4"],\
["@types/prettyjson", "npm:0.0.30"],\
["@types/ua-parser-js", "npm:0.7.36"],\
["@types/uuid", "npm:8.3.4"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\
["aws-sdk", "npm:2.1234.0"],\
["axios", "npm:0.27.2"],\
["aws-sdk", "npm:2.1253.0"],\
["axios", "npm:1.1.3"],\
["cors", "npm:2.8.5"],\
["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\
@@ -3148,11 +3172,11 @@ const RAW_RUNTIME_STATE =
["helmet", "npm:6.0.0"],\
["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.2.3"],\
["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["jsonwebtoken", "npm:8.5.1"],\
["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\
["newrelic", "npm:9.6.0"],\
["nodemon", "npm:2.0.20"],\
["npm-check-updates", "npm:16.0.1"],\
["prettyjson", "npm:1.2.5"],\
@@ -3160,7 +3184,7 @@ const RAW_RUNTIME_STATE =
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\
["typescript", "patch:typescript@npm%3A4.8.4#optional!builtin<compat/typescript>::version=4.8.4&hash=701156"],\
["ua-parser-js", "npm:1.0.2"],\
["ua-parser-js", "npm:1.0.32"],\
["uuid", "npm:9.0.0"],\
["winston", "npm:3.8.2"]\
],\
@@ -3215,8 +3239,9 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/websockets/",\
"packageDependencies": [\
["@standardnotes/websockets-server", "workspace:packages/websockets"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.5.0"],\
["@sentry/node", "npm:7.19.0"],\
["@standardnotes/api", "npm:1.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
@@ -3224,12 +3249,12 @@ const RAW_RUNTIME_STATE =
["@standardnotes/security", "workspace:packages/security"],\
["@types/cors", "npm:2.8.12"],\
["@types/express", "npm:4.17.14"],\
["@types/ioredis", "npm:4.28.10"],\
["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\
["@types/newrelic", "npm:7.0.4"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\
["aws-sdk", "npm:2.1234.0"],\
["axios", "npm:0.27.2"],\
["aws-sdk", "npm:2.1253.0"],\
["axios", "npm:1.1.3"],\
["cors", "npm:2.8.5"],\
["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\
@@ -3237,10 +3262,10 @@ const RAW_RUNTIME_STATE =
["express", "npm:4.18.2"],\
["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.2.3"],\
["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\
["newrelic", "npm:9.6.0"],\
["reflect-metadata", "npm:0.1.13"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\
@@ -3255,8 +3280,9 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/workspace/",\
"packageDependencies": [\
["@standardnotes/workspace-server", "workspace:packages/workspace"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.5.0"],\
["@sentry/node", "npm:7.19.0"],\
["@standardnotes/api", "npm:1.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
@@ -3266,11 +3292,11 @@ const RAW_RUNTIME_STATE =
["@standardnotes/time", "workspace:packages/time"],\
["@types/cors", "npm:2.8.12"],\
["@types/express", "npm:4.17.14"],\
["@types/ioredis", "npm:4.28.10"],\
["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\
["@types/newrelic", "npm:7.0.4"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\
["aws-sdk", "npm:2.1234.0"],\
["aws-sdk", "npm:2.1253.0"],\
["cors", "npm:2.8.5"],\
["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\
@@ -3278,10 +3304,10 @@ const RAW_RUNTIME_STATE =
["express", "npm:4.18.2"],\
["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.2.3"],\
["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\
["newrelic", "npm:9.6.0"],\
["reflect-metadata", "npm:0.1.13"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\
@@ -3530,11 +3556,11 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@types/ioredis", [\
["npm:4.28.10", {\
"packageLocation": "./.yarn/cache/@types-ioredis-npm-4.28.10-4bdbe26a79-a7f24a8a13.zip/node_modules/@types/ioredis/",\
["npm:5.0.0", {\
"packageLocation": "./.yarn/cache/@types-ioredis-npm-5.0.0-6efa70abfa-439770c9da.zip/node_modules/@types/ioredis/",\
"packageDependencies": [\
["@types/ioredis", "npm:4.28.10"],\
["@types/node", "npm:18.0.3"]\
["@types/ioredis", "npm:5.0.0"],\
["ioredis", "npm:5.2.4"]\
],\
"linkType": "HARD"\
}]\
@@ -3663,10 +3689,10 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["@types/newrelic", [\
["npm:7.0.3", {\
"packageLocation": "./.yarn/cache/@types-newrelic-npm-7.0.3-c49600c8f5-f56ebaa21c.zip/node_modules/@types/newrelic/",\
["npm:7.0.4", {\
"packageLocation": "./.yarn/cache/@types-newrelic-npm-7.0.4-4f0b179b51-b44215b3ab.zip/node_modules/@types/newrelic/",\
"packageDependencies": [\
["@types/newrelic", "npm:7.0.3"]\
["@types/newrelic", "npm:7.0.4"]\
],\
"linkType": "HARD"\
}]\
@@ -3678,6 +3704,13 @@ const RAW_RUNTIME_STATE =
["@types/node", "npm:18.0.3"]\
],\
"linkType": "HARD"\
}],\
["npm:18.11.9", {\
"packageLocation": "./.yarn/cache/@types-node-npm-18.11.9-d21dd6ec05-7b7d90894d.zip/node_modules/@types/node/",\
"packageDependencies": [\
["@types/node", "npm:18.11.9"]\
],\
"linkType": "HARD"\
}]\
]],\
["@types/nodemailer", [\
@@ -4730,10 +4763,10 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["aws-sdk", [\
["npm:2.1234.0", {\
"packageLocation": "./.yarn/cache/aws-sdk-npm-2.1234.0-7ee3cd4390-cd4b3e8baf.zip/node_modules/aws-sdk/",\
["npm:2.1253.0", {\
"packageLocation": "./.yarn/cache/aws-sdk-npm-2.1253.0-2cf60975ab-faa4af2949.zip/node_modules/aws-sdk/",\
"packageDependencies": [\
["aws-sdk", "npm:2.1234.0"],\
["aws-sdk", "npm:2.1253.0"],\
["buffer", "npm:4.9.2"],\
["events", "npm:1.1.1"],\
["ieee754", "npm:1.1.13"],\
@@ -4749,12 +4782,13 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["axios", [\
["npm:0.27.2", {\
"packageLocation": "./.yarn/cache/axios-npm-0.27.2-dbe3a48aea-4cd898afe9.zip/node_modules/axios/",\
["npm:1.1.3", {\
"packageLocation": "./.yarn/cache/axios-npm-1.1.3-4b63965ac1-2e28acd01c.zip/node_modules/axios/",\
"packageDependencies": [\
["axios", "npm:0.27.2"],\
["follow-redirects", "virtual:dbe3a48aea1dd5649e16abaf23d4ae05582d2149e16141955113766a0f84f681baf358c77ddccfc82eb23e4ccc66c6c912df62a9c01f2a83f1842bf86cc297b1#npm:1.15.2"],\
["form-data", "npm:4.0.0"]\
["axios", "npm:1.1.3"],\
["follow-redirects", "virtual:4b63965ac1b2157b91a1875529bea3b0bbc3068d3676d1bef28bff5cf6689705374a86cc3832f95ba8d934037a93cc0e09c3662c13ca0e747800d7ca279a53c0#npm:1.15.2"],\
["form-data", "npm:4.0.0"],\
["proxy-from-env", "npm:1.1.0"]\
],\
"linkType": "HARD"\
}]\
@@ -7299,10 +7333,10 @@ const RAW_RUNTIME_STATE =
],\
"linkType": "SOFT"\
}],\
["virtual:dbe3a48aea1dd5649e16abaf23d4ae05582d2149e16141955113766a0f84f681baf358c77ddccfc82eb23e4ccc66c6c912df62a9c01f2a83f1842bf86cc297b1#npm:1.15.2", {\
"packageLocation": "./.yarn/__virtual__/follow-redirects-virtual-42073a9d6a/0/cache/follow-redirects-npm-1.15.2-1ec1dd82be-930171f8b8.zip/node_modules/follow-redirects/",\
["virtual:4b63965ac1b2157b91a1875529bea3b0bbc3068d3676d1bef28bff5cf6689705374a86cc3832f95ba8d934037a93cc0e09c3662c13ca0e747800d7ca279a53c0#npm:1.15.2", {\
"packageLocation": "./.yarn/__virtual__/follow-redirects-virtual-b0bb08d690/0/cache/follow-redirects-npm-1.15.2-1ec1dd82be-930171f8b8.zip/node_modules/follow-redirects/",\
"packageDependencies": [\
["follow-redirects", "virtual:dbe3a48aea1dd5649e16abaf23d4ae05582d2149e16141955113766a0f84f681baf358c77ddccfc82eb23e4ccc66c6c912df62a9c01f2a83f1842bf86cc297b1#npm:1.15.2"],\
["follow-redirects", "virtual:4b63965ac1b2157b91a1875529bea3b0bbc3068d3676d1bef28bff5cf6689705374a86cc3832f95ba8d934037a93cc0e09c3662c13ca0e747800d7ca279a53c0#npm:1.15.2"],\
["@types/debug", null],\
["debug", null]\
],\
@@ -8250,10 +8284,10 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["ioredis", [\
["npm:5.2.3", {\
"packageLocation": "./.yarn/cache/ioredis-npm-5.2.3-54d9576179-3849fbe54a.zip/node_modules/ioredis/",\
["npm:5.2.4", {\
"packageLocation": "./.yarn/cache/ioredis-npm-5.2.4-875ff55d9a-f6572bf619.zip/node_modules/ioredis/",\
"packageDependencies": [\
["ioredis", "npm:5.2.3"],\
["ioredis", "npm:5.2.4"],\
["@ioredis/commands", "npm:1.2.0"],\
["cluster-key-slot", "npm:1.1.1"],\
["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\
@@ -10375,18 +10409,17 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["newrelic", [\
["npm:9.0.0", {\
"packageLocation": "./.yarn/cache/newrelic-npm-9.0.0-65e8703d5d-397f7d2626.zip/node_modules/newrelic/",\
["npm:9.6.0", {\
"packageLocation": "./.yarn/cache/newrelic-npm-9.6.0-f10080c2de-eb378acde1.zip/node_modules/newrelic/",\
"packageDependencies": [\
["newrelic", "npm:9.0.0"],\
["newrelic", "npm:9.6.0"],\
["@grpc/grpc-js", "npm:1.6.7"],\
["@grpc/proto-loader", "npm:0.6.13"],\
["@newrelic/aws-sdk", "virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:5.0.0"],\
["@newrelic/koa", "virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:7.0.0"],\
["@newrelic/aws-sdk", "virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:5.0.0"],\
["@newrelic/koa", "virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:7.0.0"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/superagent", "virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:6.0.0"],\
["@newrelic/superagent", "virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:6.0.0"],\
["@tyriar/fibonacci-heap", "npm:2.0.9"],\
["async", "npm:3.2.4"],\
["concat-stream", "npm:2.0.0"],\
["https-proxy-agent", "npm:5.0.1"],\
["json-stringify-safe", "npm:5.0.1"],\
@@ -11479,6 +11512,15 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["proxy-from-env", [\
["npm:1.1.0", {\
"packageLocation": "./.yarn/cache/proxy-from-env-npm-1.1.0-c13d07f26b-0bba2ef7c8.zip/node_modules/proxy-from-env/",\
"packageDependencies": [\
["proxy-from-env", "npm:1.1.0"]\
],\
"linkType": "HARD"\
}]\
]],\
["pseudomap", [\
["npm:1.0.2", {\
"packageLocation": "./.yarn/cache/pseudomap-npm-1.0.2-0d0e40fee0-33cfbb99ac.zip/node_modules/pseudomap/",\
@@ -12216,6 +12258,15 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["shallow-equal-object", [\
["npm:1.1.1", {\
"packageLocation": "./.yarn/cache/shallow-equal-object-npm-1.1.1-a41b289b2e-9e5e0cd10b.zip/node_modules/shallow-equal-object/",\
"packageDependencies": [\
["shallow-equal-object", "npm:1.1.1"]\
],\
"linkType": "HARD"\
}]\
]],\
["shebang-command", [\
["npm:2.0.0", {\
"packageLocation": "./.yarn/cache/shebang-command-npm-2.0.0-eb2b01921d-5907a8d5fa.zip/node_modules/shebang-command/",\
@@ -12482,7 +12533,7 @@ const RAW_RUNTIME_STATE =
"packageDependencies": [\
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:5.7.0"],\
["@types/aws-sdk", null],\
["aws-sdk", "npm:2.1234.0"],\
["aws-sdk", "npm:2.1253.0"],\
["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"]\
],\
"packagePeers": [\
@@ -13097,7 +13148,7 @@ const RAW_RUNTIME_STATE =
["@tsconfig/node12", "npm:1.0.11"],\
["@tsconfig/node14", "npm:1.0.3"],\
["@tsconfig/node16", "npm:1.0.3"],\
["@types/node", "npm:18.0.3"],\
["@types/node", "npm:18.11.9"],\
["@types/swc__core", null],\
["@types/swc__wasm", null],\
["@types/typescript", null],\
@@ -13373,7 +13424,7 @@ const RAW_RUNTIME_STATE =
["@types/better-sqlite3", null],\
["@types/google-cloud__spanner", null],\
["@types/hdb-pool", null],\
["@types/ioredis", "npm:4.28.10"],\
["@types/ioredis", "npm:5.0.0"],\
["@types/mongodb", null],\
["@types/mssql", null],\
["@types/mysql2", null],\
@@ -13397,7 +13448,7 @@ const RAW_RUNTIME_STATE =
["dotenv", "npm:16.0.3"],\
["glob", "npm:7.2.3"],\
["hdb-pool", null],\
["ioredis", "npm:5.2.3"],\
["ioredis", "npm:5.2.4"],\
["js-yaml", "npm:4.1.0"],\
["mkdirp", "npm:1.0.4"],\
["mongodb", null],\
@@ -13475,10 +13526,10 @@ const RAW_RUNTIME_STATE =
}]\
]],\
["ua-parser-js", [\
["npm:1.0.2", {\
"packageLocation": "./.yarn/cache/ua-parser-js-npm-1.0.2-c3376785e2-5ee14b105c.zip/node_modules/ua-parser-js/",\
["npm:1.0.32", {\
"packageLocation": "./.yarn/cache/ua-parser-js-npm-1.0.32-95b0b6a78d-9d320c6742.zip/node_modules/ua-parser-js/",\
"packageDependencies": [\
["ua-parser-js", "npm:1.0.2"]\
["ua-parser-js", "npm:1.0.32"]\
],\
"linkType": "HARD"\
}]\

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -326,8 +326,8 @@ ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
endif
quiet_cmd_regen_makefile = ACTION Regenerating $@
cmd_regen_makefile = cd $(srcdir); /Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/karolsojko/Library/Caches/node-gyp/16.15.1" "-Dnode_gyp_dir=/Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp" "-Dnode_lib_file=/Users/karolsojko/Library/Caches/node-gyp/16.15.1/<(target_arch)/node.lib" "-Dmodule_root_dir=/Users/karolsojko/workspace/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics" "-Dnode_engine=v8" "--depth=." "-Goutput_dir=." "--generator-output=build" -I/Users/karolsojko/workspace/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics/build/config.gypi -I/Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/addon.gypi -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/common.gypi "--toplevel-dir=." binding.gyp
Makefile: $(srcdir)/binding.gyp $(srcdir)/../../../../node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/addon.gypi $(srcdir)/../../../../../../../../Library/Caches/node-gyp/16.15.1/include/node/common.gypi $(srcdir)/build/config.gypi
cmd_regen_makefile = cd $(srcdir); /Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/karolsojko/Library/Caches/node-gyp/18.12.1" "-Dnode_gyp_dir=/Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp" "-Dnode_lib_file=/Users/karolsojko/Library/Caches/node-gyp/18.12.1/<(target_arch)/node.lib" "-Dmodule_root_dir=/Users/karolsojko/workspace/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics" "-Dnode_engine=v8" "--depth=." "-Goutput_dir=." "--generator-output=build" -I/Users/karolsojko/workspace/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics/build/config.gypi -I/Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/addon.gypi -I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/include/node/common.gypi "--toplevel-dir=." binding.gyp
Makefile: $(srcdir)/build/config.gypi $(srcdir)/../../../../node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/addon.gypi $(srcdir)/../../../../../../../../Library/Caches/node-gyp/18.12.1/include/node/common.gypi $(srcdir)/binding.gyp
$(call do_cmd,regen_makefile)
# "all" is a concatenation of the "all" targets from all the included

View File

@@ -1 +0,0 @@
cmd_Release/native_metrics.node := c++ -bundle -undefined dynamic_lookup -Wl,-search_paths_first -mmacosx-version-min=10.13 -arch x86_64 -L./Release -stdlib=libc++ -o Release/native_metrics.node Release/obj.target/native_metrics/src/native_metrics.o Release/obj.target/native_metrics/src/GCBinder.o Release/obj.target/native_metrics/src/LoopChecker.o

View File

@@ -1,69 +0,0 @@
cmd_Release/obj.target/native_metrics/src/GCBinder.o := c++ -o Release/obj.target/native_metrics/src/GCBinder.o ../src/GCBinder.cpp '-DNODE_GYP_MODULE_NAME=native_metrics' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DNOMINMAX' '-DBUILDING_NODE_EXTENSION' -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/src -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/config -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/openssl/include -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/uv/include -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/zlib -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/v8/include -I../src -I../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan -O3 -gdwarf-2 -mmacosx-version-min=10.13 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++14 -stdlib=libc++ -fno-rtti -fno-exceptions -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/native_metrics/src/GCBinder.o.d.raw -c
Release/obj.target/native_metrics/src/GCBinder.o: ../src/GCBinder.cpp \
../src/GCBinder.hpp \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_version.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/errno.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/version.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/unix.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/threadpool.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/darwin.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/cppgc/common.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8config.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-internal.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-version.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-platform.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_buffer.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_object_wrap.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_callbacks.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_callbacks_12_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_maybe_43_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_converters.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_converters_43_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_new.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_implementation_12_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_persistent_12_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_weak.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_object_wrap.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_private.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_typedarray_contents.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_json.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_scriptorigin.h \
../src/Metric.hpp
../src/GCBinder.cpp:
../src/GCBinder.hpp:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_version.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/errno.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/version.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/unix.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/threadpool.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/darwin.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/cppgc/common.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8config.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-internal.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-version.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-platform.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_buffer.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_object_wrap.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_callbacks.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_callbacks_12_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_maybe_43_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_converters.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_converters_43_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_new.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_implementation_12_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_persistent_12_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_weak.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_object_wrap.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_private.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_typedarray_contents.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_json.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_scriptorigin.h:
../src/Metric.hpp:

View File

@@ -1,70 +0,0 @@
cmd_Release/obj.target/native_metrics/src/LoopChecker.o := c++ -o Release/obj.target/native_metrics/src/LoopChecker.o ../src/LoopChecker.cpp '-DNODE_GYP_MODULE_NAME=native_metrics' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DNOMINMAX' '-DBUILDING_NODE_EXTENSION' -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/src -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/config -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/openssl/include -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/uv/include -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/zlib -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/v8/include -I../src -I../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan -O3 -gdwarf-2 -mmacosx-version-min=10.13 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++14 -stdlib=libc++ -fno-rtti -fno-exceptions -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/native_metrics/src/LoopChecker.o.d.raw -c
Release/obj.target/native_metrics/src/LoopChecker.o: \
../src/LoopChecker.cpp \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/errno.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/version.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/unix.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/threadpool.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/darwin.h \
../src/LoopChecker.hpp \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_version.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/cppgc/common.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8config.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-internal.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-version.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-platform.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_buffer.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_object_wrap.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_callbacks.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_callbacks_12_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_maybe_43_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_converters.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_converters_43_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_new.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_implementation_12_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_persistent_12_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_weak.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_object_wrap.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_private.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_typedarray_contents.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_json.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_scriptorigin.h \
../src/Metric.hpp
../src/LoopChecker.cpp:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/errno.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/version.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/unix.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/threadpool.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/darwin.h:
../src/LoopChecker.hpp:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_version.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/cppgc/common.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8config.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-internal.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-version.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-platform.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_buffer.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_object_wrap.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_callbacks.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_callbacks_12_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_maybe_43_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_converters.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_converters_43_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_new.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_implementation_12_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_persistent_12_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_weak.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_object_wrap.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_private.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_typedarray_contents.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_json.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_scriptorigin.h:
../src/Metric.hpp:

View File

@@ -1,70 +0,0 @@
cmd_Release/obj.target/native_metrics/src/native_metrics.o := c++ -o Release/obj.target/native_metrics/src/native_metrics.o ../src/native_metrics.cpp '-DNODE_GYP_MODULE_NAME=native_metrics' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-DV8_DEPRECATION_WARNINGS' '-DV8_IMMINENT_DEPRECATION_WARNINGS' '-D_GLIBCXX_USE_CXX11_ABI=1' '-D_DARWIN_USE_64_BIT_INODE=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DNOMINMAX' '-DBUILDING_NODE_EXTENSION' -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/src -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/config -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/openssl/include -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/uv/include -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/zlib -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/v8/include -I../src -I../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan -O3 -gdwarf-2 -mmacosx-version-min=10.13 -arch x86_64 -Wall -Wendif-labels -W -Wno-unused-parameter -std=gnu++14 -stdlib=libc++ -fno-rtti -fno-exceptions -fno-strict-aliasing -MMD -MF ./Release/.deps/Release/obj.target/native_metrics/src/native_metrics.o.d.raw -c
Release/obj.target/native_metrics/src/native_metrics.o: \
../src/native_metrics.cpp \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_version.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/errno.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/version.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/unix.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/threadpool.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/darwin.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/cppgc/common.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8config.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-internal.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-version.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-platform.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_buffer.h \
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_object_wrap.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_callbacks.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_callbacks_12_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_maybe_43_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_converters.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_converters_43_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_new.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_implementation_12_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_persistent_12_inl.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_weak.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_object_wrap.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_private.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_typedarray_contents.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_json.h \
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_scriptorigin.h \
../src/GCBinder.hpp ../src/Metric.hpp ../src/LoopChecker.hpp
../src/native_metrics.cpp:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_version.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/errno.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/version.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/unix.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/threadpool.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/uv/darwin.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/cppgc/common.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8config.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-internal.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-version.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/v8-platform.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_buffer.h:
/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/node_object_wrap.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_callbacks.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_callbacks_12_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_maybe_43_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_converters.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_converters_43_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_new.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_implementation_12_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_persistent_12_inl.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_weak.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_object_wrap.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_private.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_typedarray_contents.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_json.h:
../../../../../nan-npm-2.16.0-cac314a230/node_modules/nan/nan_scriptorigin.h:
../src/GCBinder.hpp:
../src/Metric.hpp:
../src/LoopChecker.hpp:

View File

@@ -19,293 +19,316 @@
"error_on_warn": "false",
"force_dynamic_crt": 0,
"host_arch": "x64",
"icu_data_in": "../../deps/icu-tmp/icudt70l.dat",
"icu_data_in": "../../deps/icu-tmp/icudt71l.dat",
"icu_endianness": "l",
"icu_gyp_path": "tools/icu/icu-generic.gyp",
"icu_path": "deps/icu-small",
"icu_small": "false",
"icu_ver_major": "70",
"icu_ver_major": "71",
"is_debug": 0,
"libdir": "lib",
"llvm_version": "11.0",
"napi_build_version": "8",
"node_byteorder": "little",
"node_debug_lib": "false",
"node_enable_d8": "false",
"node_fipsinstall": "false",
"node_install_corepack": "true",
"node_install_npm": "true",
"node_library_files": [
"lib/constants.js",
"lib/net.js",
"lib/trace_events.js",
"lib/events.js",
"lib/repl.js",
"lib/util.js",
"lib/dgram.js",
"lib/vm.js",
"lib/stream.js",
"lib/child_process.js",
"lib/assert.js",
"lib/_tls_wrap.js",
"lib/http2.js",
"lib/inspector.js",
"lib/os.js",
"lib/_http_server.js",
"lib/console.js",
"lib/perf_hooks.js",
"lib/readline.js",
"lib/punycode.js",
"lib/_http_incoming.js",
"lib/https.js",
"lib/_stream_wrap.js",
"lib/domain.js",
"lib/dns.js",
"lib/_http_client.js",
"lib/diagnostics_channel.js",
"lib/tty.js",
"lib/_http_agent.js",
"lib/timers.js",
"lib/_http_outgoing.js",
"lib/querystring.js",
"lib/_tls_common.js",
"lib/module.js",
"lib/_stream_passthrough.js",
"lib/_stream_transform.js",
"lib/worker_threads.js",
"lib/sys.js",
"lib/_stream_duplex.js",
"lib/path.js",
"lib/_http_client.js",
"lib/_http_common.js",
"lib/string_decoder.js",
"lib/cluster.js",
"lib/v8.js",
"lib/crypto.js",
"lib/wasi.js",
"lib/_http_incoming.js",
"lib/_http_outgoing.js",
"lib/_http_server.js",
"lib/_stream_duplex.js",
"lib/_stream_passthrough.js",
"lib/_stream_readable.js",
"lib/zlib.js",
"lib/url.js",
"lib/tls.js",
"lib/_stream_transform.js",
"lib/_stream_wrap.js",
"lib/_stream_writable.js",
"lib/_tls_common.js",
"lib/_tls_wrap.js",
"lib/assert.js",
"lib/assert/strict.js",
"lib/async_hooks.js",
"lib/process.js",
"lib/http.js",
"lib/buffer.js",
"lib/child_process.js",
"lib/cluster.js",
"lib/console.js",
"lib/constants.js",
"lib/crypto.js",
"lib/dgram.js",
"lib/diagnostics_channel.js",
"lib/dns.js",
"lib/dns/promises.js",
"lib/domain.js",
"lib/events.js",
"lib/fs.js",
"lib/util/types.js",
"lib/timers/promises.js",
"lib/path/win32.js",
"lib/path/posix.js",
"lib/stream/consumers.js",
"lib/stream/promises.js",
"lib/stream/web.js",
"lib/internal/constants.js",
"lib/fs/promises.js",
"lib/http.js",
"lib/http2.js",
"lib/https.js",
"lib/inspector.js",
"lib/internal/abort_controller.js",
"lib/internal/net.js",
"lib/internal/v8_prof_processor.js",
"lib/internal/event_target.js",
"lib/internal/inspector_async_hook.js",
"lib/internal/validators.js",
"lib/internal/linkedlist.js",
"lib/internal/cli_table.js",
"lib/internal/repl.js",
"lib/internal/util.js",
"lib/internal/histogram.js",
"lib/internal/error_serdes.js",
"lib/internal/dgram.js",
"lib/internal/child_process.js",
"lib/internal/assert.js",
"lib/internal/fixed_queue.js",
"lib/internal/blocklist.js",
"lib/internal/v8_prof_polyfill.js",
"lib/internal/options.js",
"lib/internal/worker.js",
"lib/internal/dtrace.js",
"lib/internal/idna.js",
"lib/internal/watchdog.js",
"lib/internal/encoding.js",
"lib/internal/tty.js",
"lib/internal/freeze_intrinsics.js",
"lib/internal/timers.js",
"lib/internal/heap_utils.js",
"lib/internal/querystring.js",
"lib/internal/js_stream_socket.js",
"lib/internal/errors.js",
"lib/internal/priority_queue.js",
"lib/internal/freelist.js",
"lib/internal/blob.js",
"lib/internal/socket_list.js",
"lib/internal/socketaddress.js",
"lib/internal/promise_hooks.js",
"lib/internal/stream_base_commons.js",
"lib/internal/url.js",
"lib/internal/assert/assertion_error.js",
"lib/internal/assert/calltracker.js",
"lib/internal/assert/snapshot.js",
"lib/internal/async_hooks.js",
"lib/internal/http.js",
"lib/internal/buffer.js",
"lib/internal/trace_events_async_hooks.js",
"lib/internal/crypto/sig.js",
"lib/internal/crypto/rsa.js",
"lib/internal/crypto/aes.js",
"lib/internal/crypto/util.js",
"lib/internal/crypto/scrypt.js",
"lib/internal/crypto/random.js",
"lib/internal/crypto/keys.js",
"lib/internal/crypto/x509.js",
"lib/internal/crypto/certificate.js",
"lib/internal/crypto/ec.js",
"lib/internal/crypto/keygen.js",
"lib/internal/crypto/mac.js",
"lib/internal/crypto/diffiehellman.js",
"lib/internal/crypto/hkdf.js",
"lib/internal/crypto/cipher.js",
"lib/internal/crypto/hash.js",
"lib/internal/crypto/pbkdf2.js",
"lib/internal/crypto/webcrypto.js",
"lib/internal/crypto/dsa.js",
"lib/internal/crypto/hashnames.js",
"lib/internal/cluster/shared_handle.js",
"lib/internal/cluster/round_robin_handle.js",
"lib/internal/cluster/worker.js",
"lib/internal/cluster/primary.js",
"lib/internal/cluster/utils.js",
"lib/internal/cluster/child.js",
"lib/internal/webstreams/compression.js",
"lib/internal/webstreams/util.js",
"lib/internal/webstreams/writablestream.js",
"lib/internal/webstreams/readablestream.js",
"lib/internal/webstreams/queuingstrategies.js",
"lib/internal/webstreams/encoding.js",
"lib/internal/webstreams/transformstream.js",
"lib/internal/webstreams/adapters.js",
"lib/internal/webstreams/transfer.js",
"lib/internal/blob.js",
"lib/internal/blocklist.js",
"lib/internal/bootstrap/browser.js",
"lib/internal/bootstrap/loaders.js",
"lib/internal/bootstrap/pre_execution.js",
"lib/internal/bootstrap/node.js",
"lib/internal/bootstrap/environment.js",
"lib/internal/bootstrap/switches/does_not_own_process_state.js",
"lib/internal/bootstrap/switches/is_not_main_thread.js",
"lib/internal/bootstrap/switches/does_own_process_state.js",
"lib/internal/bootstrap/switches/is_main_thread.js",
"lib/internal/test/binding.js",
"lib/internal/test/transfer.js",
"lib/internal/util/types.js",
"lib/internal/util/inspector.js",
"lib/internal/util/comparisons.js",
"lib/internal/util/debuglog.js",
"lib/internal/util/inspect.js",
"lib/internal/util/iterable_weak_map.js",
"lib/internal/streams/add-abort-signal.js",
"lib/internal/streams/compose.js",
"lib/internal/streams/duplexify.js",
"lib/internal/streams/destroy.js",
"lib/internal/streams/legacy.js",
"lib/internal/streams/passthrough.js",
"lib/internal/streams/operators.js",
"lib/internal/streams/readable.js",
"lib/internal/streams/from.js",
"lib/internal/streams/writable.js",
"lib/internal/streams/state.js",
"lib/internal/streams/buffer_list.js",
"lib/internal/streams/end-of-stream.js",
"lib/internal/streams/utils.js",
"lib/internal/streams/transform.js",
"lib/internal/streams/lazy_transform.js",
"lib/internal/streams/duplex.js",
"lib/internal/streams/pipeline.js",
"lib/internal/readline/interface.js",
"lib/internal/readline/utils.js",
"lib/internal/readline/emitKeypressEvents.js",
"lib/internal/readline/callbacks.js",
"lib/internal/repl/history.js",
"lib/internal/repl/utils.js",
"lib/internal/repl/await.js",
"lib/internal/legacy/processbinding.js",
"lib/internal/assert/calltracker.js",
"lib/internal/assert/assertion_error.js",
"lib/internal/http2/util.js",
"lib/internal/http2/core.js",
"lib/internal/http2/compat.js",
"lib/internal/per_context/messageport.js",
"lib/internal/per_context/primordials.js",
"lib/internal/per_context/domexception.js",
"lib/internal/vm/module.js",
"lib/internal/tls/secure-pair.js",
"lib/internal/tls/parse-cert-string.js",
"lib/internal/tls/secure-context.js",
"lib/internal/bootstrap/switches/is_not_main_thread.js",
"lib/internal/buffer.js",
"lib/internal/child_process.js",
"lib/internal/child_process/serialization.js",
"lib/internal/debugger/inspect_repl.js",
"lib/internal/debugger/inspect_client.js",
"lib/internal/cli_table.js",
"lib/internal/cluster/child.js",
"lib/internal/cluster/primary.js",
"lib/internal/cluster/round_robin_handle.js",
"lib/internal/cluster/shared_handle.js",
"lib/internal/cluster/utils.js",
"lib/internal/cluster/worker.js",
"lib/internal/console/constructor.js",
"lib/internal/console/global.js",
"lib/internal/constants.js",
"lib/internal/crypto/aes.js",
"lib/internal/crypto/certificate.js",
"lib/internal/crypto/cfrg.js",
"lib/internal/crypto/cipher.js",
"lib/internal/crypto/diffiehellman.js",
"lib/internal/crypto/ec.js",
"lib/internal/crypto/hash.js",
"lib/internal/crypto/hashnames.js",
"lib/internal/crypto/hkdf.js",
"lib/internal/crypto/keygen.js",
"lib/internal/crypto/keys.js",
"lib/internal/crypto/mac.js",
"lib/internal/crypto/pbkdf2.js",
"lib/internal/crypto/random.js",
"lib/internal/crypto/rsa.js",
"lib/internal/crypto/scrypt.js",
"lib/internal/crypto/sig.js",
"lib/internal/crypto/util.js",
"lib/internal/crypto/webcrypto.js",
"lib/internal/crypto/x509.js",
"lib/internal/debugger/inspect.js",
"lib/internal/worker/io.js",
"lib/internal/worker/js_transferable.js",
"lib/internal/main/repl.js",
"lib/internal/main/print_help.js",
"lib/internal/main/eval_string.js",
"lib/internal/main/check_syntax.js",
"lib/internal/main/prof_process.js",
"lib/internal/main/worker_thread.js",
"lib/internal/main/inspect.js",
"lib/internal/main/eval_stdin.js",
"lib/internal/main/run_main_module.js",
"lib/internal/modules/run_main.js",
"lib/internal/modules/package_json_reader.js",
"lib/internal/modules/esm/module_job.js",
"lib/internal/modules/esm/assert.js",
"lib/internal/modules/esm/fetch_module.js",
"lib/internal/modules/esm/get_source.js",
"lib/internal/modules/esm/translators.js",
"lib/internal/modules/esm/resolve.js",
"lib/internal/modules/esm/create_dynamic_module.js",
"lib/internal/modules/esm/load.js",
"lib/internal/modules/esm/handle_process_exit.js",
"lib/internal/modules/esm/initialize_import_meta.js",
"lib/internal/modules/esm/module_map.js",
"lib/internal/modules/esm/get_format.js",
"lib/internal/modules/esm/formats.js",
"lib/internal/modules/esm/loader.js",
"lib/internal/modules/cjs/helpers.js",
"lib/internal/modules/cjs/loader.js",
"lib/internal/source_map/source_map.js",
"lib/internal/source_map/prepare_stack_trace.js",
"lib/internal/source_map/source_map_cache.js",
"lib/internal/debugger/inspect_client.js",
"lib/internal/debugger/inspect_repl.js",
"lib/internal/dgram.js",
"lib/internal/dns/callback_resolver.js",
"lib/internal/dns/promises.js",
"lib/internal/dns/utils.js",
"lib/internal/fs/watchers.js",
"lib/internal/dtrace.js",
"lib/internal/encoding.js",
"lib/internal/error_serdes.js",
"lib/internal/errors.js",
"lib/internal/event_target.js",
"lib/internal/fixed_queue.js",
"lib/internal/freelist.js",
"lib/internal/freeze_intrinsics.js",
"lib/internal/fs/cp/cp-sync.js",
"lib/internal/fs/cp/cp.js",
"lib/internal/fs/dir.js",
"lib/internal/fs/promises.js",
"lib/internal/fs/read_file_context.js",
"lib/internal/fs/rimraf.js",
"lib/internal/fs/sync_write_stream.js",
"lib/internal/fs/dir.js",
"lib/internal/fs/streams.js",
"lib/internal/fs/sync_write_stream.js",
"lib/internal/fs/utils.js",
"lib/internal/fs/cp/cp.js",
"lib/internal/fs/cp/cp-sync.js",
"lib/internal/perf/nodetiming.js",
"lib/internal/perf/usertiming.js",
"lib/internal/perf/performance_entry.js",
"lib/internal/perf/performance.js",
"lib/internal/perf/timerify.js",
"lib/internal/perf/utils.js",
"lib/internal/perf/observe.js",
"lib/internal/fs/watchers.js",
"lib/internal/heap_utils.js",
"lib/internal/histogram.js",
"lib/internal/http.js",
"lib/internal/http2/compat.js",
"lib/internal/http2/core.js",
"lib/internal/http2/util.js",
"lib/internal/idna.js",
"lib/internal/inspector_async_hook.js",
"lib/internal/js_stream_socket.js",
"lib/internal/legacy/processbinding.js",
"lib/internal/linkedlist.js",
"lib/internal/main/check_syntax.js",
"lib/internal/main/environment.js",
"lib/internal/main/eval_stdin.js",
"lib/internal/main/eval_string.js",
"lib/internal/main/inspect.js",
"lib/internal/main/mksnapshot.js",
"lib/internal/main/print_help.js",
"lib/internal/main/prof_process.js",
"lib/internal/main/repl.js",
"lib/internal/main/run_main_module.js",
"lib/internal/main/test_runner.js",
"lib/internal/main/watch_mode.js",
"lib/internal/main/worker_thread.js",
"lib/internal/modules/cjs/helpers.js",
"lib/internal/modules/cjs/loader.js",
"lib/internal/modules/esm/assert.js",
"lib/internal/modules/esm/create_dynamic_module.js",
"lib/internal/modules/esm/fetch_module.js",
"lib/internal/modules/esm/formats.js",
"lib/internal/modules/esm/get_format.js",
"lib/internal/modules/esm/handle_process_exit.js",
"lib/internal/modules/esm/initialize_import_meta.js",
"lib/internal/modules/esm/load.js",
"lib/internal/modules/esm/loader.js",
"lib/internal/modules/esm/module_job.js",
"lib/internal/modules/esm/module_map.js",
"lib/internal/modules/esm/package_config.js",
"lib/internal/modules/esm/resolve.js",
"lib/internal/modules/esm/translators.js",
"lib/internal/modules/package_json_reader.js",
"lib/internal/modules/run_main.js",
"lib/internal/net.js",
"lib/internal/options.js",
"lib/internal/per_context/domexception.js",
"lib/internal/per_context/messageport.js",
"lib/internal/per_context/primordials.js",
"lib/internal/perf/event_loop_delay.js",
"lib/internal/perf/event_loop_utilization.js",
"lib/internal/perf/nodetiming.js",
"lib/internal/perf/observe.js",
"lib/internal/perf/performance.js",
"lib/internal/perf/performance_entry.js",
"lib/internal/perf/resource_timing.js",
"lib/internal/perf/timerify.js",
"lib/internal/perf/usertiming.js",
"lib/internal/perf/utils.js",
"lib/internal/policy/manifest.js",
"lib/internal/policy/sri.js",
"lib/internal/process/task_queues.js",
"lib/internal/process/per_thread.js",
"lib/internal/process/warning.js",
"lib/internal/process/policy.js",
"lib/internal/process/promises.js",
"lib/internal/process/signal.js",
"lib/internal/process/execution.js",
"lib/internal/priority_queue.js",
"lib/internal/process/esm_loader.js",
"lib/internal/process/execution.js",
"lib/internal/process/per_thread.js",
"lib/internal/process/policy.js",
"lib/internal/process/pre_execution.js",
"lib/internal/process/promises.js",
"lib/internal/process/report.js",
"lib/internal/process/signal.js",
"lib/internal/process/task_queues.js",
"lib/internal/process/warning.js",
"lib/internal/process/worker_thread_only.js",
"lib/internal/console/constructor.js",
"lib/internal/console/global.js",
"lib/assert/strict.js",
"lib/dns/promises.js",
"lib/fs/promises.js"
"lib/internal/promise_hooks.js",
"lib/internal/querystring.js",
"lib/internal/readline/callbacks.js",
"lib/internal/readline/emitKeypressEvents.js",
"lib/internal/readline/interface.js",
"lib/internal/readline/promises.js",
"lib/internal/readline/utils.js",
"lib/internal/repl.js",
"lib/internal/repl/await.js",
"lib/internal/repl/history.js",
"lib/internal/repl/utils.js",
"lib/internal/socket_list.js",
"lib/internal/socketaddress.js",
"lib/internal/source_map/prepare_stack_trace.js",
"lib/internal/source_map/source_map.js",
"lib/internal/source_map/source_map_cache.js",
"lib/internal/stream_base_commons.js",
"lib/internal/streams/add-abort-signal.js",
"lib/internal/streams/buffer_list.js",
"lib/internal/streams/compose.js",
"lib/internal/streams/destroy.js",
"lib/internal/streams/duplex.js",
"lib/internal/streams/duplexify.js",
"lib/internal/streams/end-of-stream.js",
"lib/internal/streams/from.js",
"lib/internal/streams/lazy_transform.js",
"lib/internal/streams/legacy.js",
"lib/internal/streams/operators.js",
"lib/internal/streams/passthrough.js",
"lib/internal/streams/pipeline.js",
"lib/internal/streams/readable.js",
"lib/internal/streams/state.js",
"lib/internal/streams/transform.js",
"lib/internal/streams/utils.js",
"lib/internal/streams/writable.js",
"lib/internal/structured_clone.js",
"lib/internal/test/binding.js",
"lib/internal/test/transfer.js",
"lib/internal/test_runner/harness.js",
"lib/internal/test_runner/runner.js",
"lib/internal/test_runner/tap_stream.js",
"lib/internal/test_runner/test.js",
"lib/internal/test_runner/utils.js",
"lib/internal/timers.js",
"lib/internal/tls/secure-context.js",
"lib/internal/tls/secure-pair.js",
"lib/internal/trace_events_async_hooks.js",
"lib/internal/tty.js",
"lib/internal/url.js",
"lib/internal/util.js",
"lib/internal/util/colors.js",
"lib/internal/util/comparisons.js",
"lib/internal/util/debuglog.js",
"lib/internal/util/inspect.js",
"lib/internal/util/inspector.js",
"lib/internal/util/iterable_weak_map.js",
"lib/internal/util/parse_args/parse_args.js",
"lib/internal/util/parse_args/utils.js",
"lib/internal/util/types.js",
"lib/internal/v8/startup_snapshot.js",
"lib/internal/v8_prof_polyfill.js",
"lib/internal/v8_prof_processor.js",
"lib/internal/validators.js",
"lib/internal/vm/module.js",
"lib/internal/wasm_web_api.js",
"lib/internal/watch_mode/files_watcher.js",
"lib/internal/watchdog.js",
"lib/internal/webstreams/adapters.js",
"lib/internal/webstreams/compression.js",
"lib/internal/webstreams/encoding.js",
"lib/internal/webstreams/queuingstrategies.js",
"lib/internal/webstreams/readablestream.js",
"lib/internal/webstreams/transfer.js",
"lib/internal/webstreams/transformstream.js",
"lib/internal/webstreams/util.js",
"lib/internal/webstreams/writablestream.js",
"lib/internal/worker.js",
"lib/internal/worker/io.js",
"lib/internal/worker/js_transferable.js",
"lib/module.js",
"lib/net.js",
"lib/os.js",
"lib/path.js",
"lib/path/posix.js",
"lib/path/win32.js",
"lib/perf_hooks.js",
"lib/process.js",
"lib/punycode.js",
"lib/querystring.js",
"lib/readline.js",
"lib/readline/promises.js",
"lib/repl.js",
"lib/stream.js",
"lib/stream/consumers.js",
"lib/stream/promises.js",
"lib/stream/web.js",
"lib/string_decoder.js",
"lib/sys.js",
"lib/test.js",
"lib/timers.js",
"lib/timers/promises.js",
"lib/tls.js",
"lib/trace_events.js",
"lib/tty.js",
"lib/url.js",
"lib/util.js",
"lib/util/types.js",
"lib/v8.js",
"lib/vm.js",
"lib/wasi.js",
"lib/worker_threads.js",
"lib/zlib.js"
],
"node_module_version": 93,
"node_module_version": 108,
"node_no_browser_globals": "false",
"node_prefix": "/",
"node_release_urlbase": "https://nodejs.org/download/release/",
@@ -330,20 +353,22 @@
"node_use_v8_platform": "true",
"node_with_ltcg": "false",
"node_without_node_options": "false",
"openssl_fips": "",
"openssl_is_fips": "false",
"openssl_quic": "true",
"ossfuzz": "false",
"shlib_suffix": "93.dylib",
"shlib_suffix": "108.dylib",
"target_arch": "x64",
"v8_enable_31bit_smis_on_64bit_arch": 0,
"v8_enable_gdbjit": 0,
"v8_enable_hugepage": 0,
"v8_enable_i18n_support": 1,
"v8_enable_inspector": 1,
"v8_enable_javascript_promise_hooks": 1,
"v8_enable_lite_mode": 0,
"v8_enable_object_print": 1,
"v8_enable_pointer_compression": 0,
"v8_enable_shared_ro_heap": 1,
"v8_enable_short_builtin_calls": 1,
"v8_enable_webassembly": 1,
"v8_no_strict_aliasing": 1,
"v8_optimized_debug": 1,
@@ -353,8 +378,8 @@
"v8_use_siphash": 1,
"want_separate_host_toolset": 0,
"xcode_version": "11.0",
"nodedir": "/Users/karolsojko/Library/Caches/node-gyp/16.15.1",
"nodedir": "/Users/karolsojko/Library/Caches/node-gyp/18.12.1",
"standalone_static_library": 1,
"user_agent": "yarn/3.2.1 npm/? node/v16.15.1 darwin x64"
"user_agent": "yarn/4.0.0-rc.25 npm/? node/v18.12.1 darwin x64"
}
}

View File

@@ -25,7 +25,7 @@ DEFS_Debug := \
CFLAGS_Debug := \
-O0 \
-gdwarf-2 \
-mmacosx-version-min=10.13 \
-mmacosx-version-min=10.15 \
-arch x86_64 \
-Wall \
-Wendif-labels \
@@ -38,7 +38,7 @@ CFLAGS_C_Debug := \
# Flags passed to only C++ files.
CFLAGS_CC_Debug := \
-std=gnu++14 \
-std=gnu++17 \
-stdlib=libc++ \
-fno-rtti \
-fno-exceptions \
@@ -51,13 +51,13 @@ CFLAGS_OBJC_Debug :=
CFLAGS_OBJCC_Debug :=
INCS_Debug := \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/src \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/config \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/openssl/include \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/uv/include \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/zlib \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/v8/include \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/include/node \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/src \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/openssl/config \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/openssl/openssl/include \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/uv/include \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/zlib \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/v8/include \
-I$(srcdir)/src \
-I$(srcdir)/../../../../nan-npm-2.16.0-cac314a230/node_modules/nan
@@ -81,7 +81,7 @@ DEFS_Release := \
CFLAGS_Release := \
-O3 \
-gdwarf-2 \
-mmacosx-version-min=10.13 \
-mmacosx-version-min=10.15 \
-arch x86_64 \
-Wall \
-Wendif-labels \
@@ -94,7 +94,7 @@ CFLAGS_C_Release := \
# Flags passed to only C++ files.
CFLAGS_CC_Release := \
-std=gnu++14 \
-std=gnu++17 \
-stdlib=libc++ \
-fno-rtti \
-fno-exceptions \
@@ -107,13 +107,13 @@ CFLAGS_OBJC_Release :=
CFLAGS_OBJCC_Release :=
INCS_Release := \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/src \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/config \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/openssl/include \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/uv/include \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/zlib \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/v8/include \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/include/node \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/src \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/openssl/config \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/openssl/openssl/include \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/uv/include \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/zlib \
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/v8/include \
-I$(srcdir)/src \
-I$(srcdir)/../../../../nan-npm-2.16.0-cac314a230/node_modules/nan
@@ -151,7 +151,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cpp FORCE_DO_CMD
LDFLAGS_Debug := \
-undefined dynamic_lookup \
-Wl,-search_paths_first \
-mmacosx-version-min=10.13 \
-mmacosx-version-min=10.15 \
-arch x86_64 \
-L$(builddir) \
-stdlib=libc++
@@ -163,7 +163,7 @@ LIBTOOLFLAGS_Debug := \
LDFLAGS_Release := \
-undefined dynamic_lookup \
-Wl,-search_paths_first \
-mmacosx-version-min=10.13 \
-mmacosx-version-min=10.15 \
-arch x86_64 \
-L$(builddir) \
-stdlib=libc++

View File

@@ -8,7 +8,7 @@
]
},
"engines": {
"node": ">=16.0.0 <17.0.0"
"node": ">=18.0.0 <19.0.0"
},
"scripts": {
"lint": "yarn workspaces foreach -p -j 10 --verbose run lint",
@@ -46,8 +46,8 @@
"@lerna-lite/list": "^1.5.1",
"@lerna-lite/run": "^1.5.1",
"@types/jest": "^29.1.1",
"@types/newrelic": "^7.0.3",
"@types/node": "^18.0.0",
"@types/newrelic": "^7.0.4",
"@types/node": "^18.11.9",
"@typescript-eslint/parser": "^5.40.1",
"eslint": "^8.17.0",
"eslint-config-prettier": "^8.5.0",
@@ -59,7 +59,8 @@
},
"packageManager": "yarn@4.0.0-rc.25",
"dependencies": {
"@sentry/node": "^7.3.0",
"newrelic": "^9.0.0"
"@newrelic/native-metrics": "^9.0.0",
"@sentry/node": "^7.19.0",
"newrelic": "^9.6.0"
}
}

View File

@@ -3,6 +3,227 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.10.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.10.1...@standardnotes/analytics@2.10.2) (2022-11-14)
### Bug Fixes
* **analytics:** imports from domain-core ([15dfd6d](https://github.com/standardnotes/server/commit/15dfd6dcba75a772000eeb01b78a532067b01d5b))
## [2.10.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.10.0...@standardnotes/analytics@2.10.1) (2022-11-14)
### Bug Fixes
* **syncing-server:** retrieving revisions ([50f7ae3](https://github.com/standardnotes/server/commit/50f7ae338ad66d3465fa16c31e7c47c57b1e0c3c))
# [2.10.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.9...@standardnotes/analytics@2.10.0) (2022-11-14)
### Features
* **analytics:** extract domain core into a separate package ([0f94e2a](https://github.com/standardnotes/server/commit/0f94e2ad0c8927733eac31f130cbe649dce765f9))
## [2.9.9](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.6...@standardnotes/analytics@2.9.9) (2022-11-14)
### Bug Fixes
* **analytics:** bump version ([8715fe1](https://github.com/standardnotes/server/commit/8715fe182221f67f02b5f49e566366db3db581f4))
## [2.9.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.5...@standardnotes/analytics@2.9.6) (2022-11-14)
**Note:** Version bump only for package @standardnotes/analytics
## [2.9.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.4...@standardnotes/analytics@2.9.5) (2022-11-11)
**Note:** Version bump only for package @standardnotes/analytics
## [2.9.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.3...@standardnotes/analytics@2.9.4) (2022-11-11)
**Note:** Version bump only for package @standardnotes/analytics
## [2.9.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.2...@standardnotes/analytics@2.9.3) (2022-11-10)
### Bug Fixes
* **analytics:** add five year plans mrr calculation ([a03c5bc](https://github.com/standardnotes/server/commit/a03c5bceea2a9b166b1d5ad75181021462a86627))
## [2.9.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.1...@standardnotes/analytics@2.9.2) (2022-11-10)
### Bug Fixes
* **analytics:** add missing period for stats report ([9b593f2](https://github.com/standardnotes/server/commit/9b593f2a6b105ab8f9c7cef8bdda6892c42e20ef))
## [2.9.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.0...@standardnotes/analytics@2.9.1) (2022-11-10)
### Bug Fixes
* **analytics:** generate mrr stats for last 30 days including Today ([b92c4ae](https://github.com/standardnotes/server/commit/b92c4ae650b53db5c0bb2a9cf9afb01caeb8d822))
# [2.9.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.8.3...@standardnotes/analytics@2.9.0) (2022-11-10)
### Features
* **analytics:** add mrr for annual, monthly, pro and plus subscription plans ([ce3e259](https://github.com/standardnotes/server/commit/ce3e259bdedd10796fb4469f0eabd64bc326a115))
## [2.8.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.8.2...@standardnotes/analytics@2.8.3) (2022-11-10)
### Bug Fixes
* **analytics:** add subscription id to error logs ([81be065](https://github.com/standardnotes/server/commit/81be06598c918279f98a8ba6b59ea1b3803c949c))
## [2.8.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.8.1...@standardnotes/analytics@2.8.2) (2022-11-10)
### Bug Fixes
* **analytics:** add monthly mrr to the report ([fce47a0](https://github.com/standardnotes/server/commit/fce47a0a37a67b3edf3ea0b6ccda43c54dbd9870))
## [2.8.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.8.0...@standardnotes/analytics@2.8.1) (2022-11-10)
### Bug Fixes
* **analytics:** add persisting mrr for this month and this year as well ([8df0482](https://github.com/standardnotes/server/commit/8df0482eb4bfd63b9639fd786c9b6952ad7f801d))
# [2.8.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.7.3...@standardnotes/analytics@2.8.0) (2022-11-10)
### Features
* **analytics:** add calculating monthly recurring revenue ([77e5065](https://github.com/standardnotes/server/commit/77e50655f6fa7f9c28e13f8b8bc6de246c0454f0))
## [2.7.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.7.2...@standardnotes/analytics@2.7.3) (2022-11-10)
### Bug Fixes
* **analytics:** arhcitecture arrangements for use case execution ([7393954](https://github.com/standardnotes/server/commit/7393954ff6ece6143f7661104299172548db90ee))
## [2.7.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.7.1...@standardnotes/analytics@2.7.2) (2022-11-09)
### Bug Fixes
* **analytics:** mrr column types ([90aef90](https://github.com/standardnotes/server/commit/90aef905af05b8c1c86c7bd383df6b2b502f7c91))
## [2.7.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.7.0...@standardnotes/analytics@2.7.1) (2022-11-09)
### Bug Fixes
* **analytics:** add missing created at column ([89502be](https://github.com/standardnotes/server/commit/89502bed638b17301e42e0d5916635b0a59f585d))
# [2.7.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.6.0...@standardnotes/analytics@2.7.0) (2022-11-09)
### Features
* **analytics:** add saving revenue modifications upon subscription canceled ([52a257a](https://github.com/standardnotes/server/commit/52a257abb16034134a50474fbbb2493a00c58b99))
# [2.6.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.5.0...@standardnotes/analytics@2.6.0) (2022-11-09)
### Features
* **analytics:** add saving revenue modifications upon subscription refunded ([0f65c05](https://github.com/standardnotes/server/commit/0f65c051abcff805e920f91d338e5fadda7905a9))
# [2.5.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.4.0...@standardnotes/analytics@2.5.0) (2022-11-09)
### Features
* **analytics:** add saving revenue modifications upon subscription expired ([5c3db2c](https://github.com/standardnotes/server/commit/5c3db2cb29a929e44b63eb8226ce4ad1d14f8a99))
# [2.4.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.3.1...@standardnotes/analytics@2.4.0) (2022-11-09)
### Features
* **analytics:** add saving revenue modifications upon subscription renewed ([cdb7fcf](https://github.com/standardnotes/server/commit/cdb7fcf8311fecfabe3ef9eb656cd6ec57b87de0))
## [2.3.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.3.0...@standardnotes/analytics@2.3.1) (2022-11-09)
### Bug Fixes
* **analytics:** missing injectable annotation ([9d3ef24](https://github.com/standardnotes/server/commit/9d3ef24ba94ad28976a211d40f94f1bce8d0d305))
# [2.3.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.2.0...@standardnotes/analytics@2.3.0) (2022-11-09)
### Features
* **analytics:** add saving revenue modifications upon subscription purchased ([5ea9941](https://github.com/standardnotes/server/commit/5ea9941519ffb3027527130ec869da14abc5e994))
# [2.2.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.1.0...@standardnotes/analytics@2.2.0) (2022-11-08)
### Features
* **analytics:** add persistence for revenue modifications ([4928685](https://github.com/standardnotes/server/commit/49286851989f557d3b391b6b535a9aa307fbef50))
* **analytics:** create new ddd architecture for persisting revenue modifications ([0103233](https://github.com/standardnotes/server/commit/0103233d4a1e222e7c9b059475c1cdc3b2617455))
# [2.1.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.52.0...@standardnotes/analytics@2.1.0) (2022-11-07)
### Features
* remove analytics scope from other services in favor of a separate service ([ff1d5db](https://github.com/standardnotes/server/commit/ff1d5db12c93f8e51c07c3aecb9fed4be48ea96a))
# [1.52.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.51.0...@standardnotes/analytics@1.52.0) (2022-11-07)
### Features
* **analytics:** add handling subscription reactivated events ([6359030](https://github.com/standardnotes/server/commit/63590300308975097f4d092a4f140f479093a1ae))
# [1.51.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.50.0...@standardnotes/analytics@1.51.0) (2022-11-07)
### Features
* **analytics:** add handling subscription expired events ([c0f5817](https://github.com/standardnotes/server/commit/c0f5817d4753410ee5d997c1b94e340b400cb5d9))
# [1.50.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.49.0...@standardnotes/analytics@1.50.0) (2022-11-07)
### Features
* **analytics:** add handling subscription purchased events ([f1834d5](https://github.com/standardnotes/server/commit/f1834d58d2215c81322e82a0ec279617103b3260))
# [1.49.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.48.0...@standardnotes/analytics@1.49.0) (2022-11-07)
### Features
* **analytics:** add handling subscription refunded event ([197c991](https://github.com/standardnotes/server/commit/197c9914caf8fb31ce3ee69d05381d2a6416b366))
# [1.48.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.47.0...@standardnotes/analytics@1.48.0) (2022-11-07)
### Features
* **analytics:** add subscription renewed event handler ([2aa57f1](https://github.com/standardnotes/server/commit/2aa57f1f0ddace741b79e9375b87464eaaba6320))
# [1.47.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.46.0...@standardnotes/analytics@1.47.0) (2022-11-04)
### Features
* **analytics:** add subscription cancelled event handler ([037fb23](https://github.com/standardnotes/server/commit/037fb2398ae9aaa11682e1a8576bab28c69e0f9b))
# [1.46.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.45.0...@standardnotes/analytics@1.46.0) (2022-11-04)
### Features
* **analytics:** add payment success event handler ([5902cbb](https://github.com/standardnotes/server/commit/5902cbb6218a5b3982b4c56f8d6644f4f5bc6d32))
# [1.45.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.44.0...@standardnotes/analytics@1.45.0) (2022-11-04)
### Features
* add payment failed handler and email to analytics entity ([51b12d0](https://github.com/standardnotes/server/commit/51b12d05d49868db1d61313c4d8b3829994e7eb3))
# [1.44.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.43.0...@standardnotes/analytics@1.44.0) (2022-11-04)
### Features
* **analytics:** removing analytics entity upon account deletion ([2720a7c](https://github.com/standardnotes/server/commit/2720a7c827a6352cb5254e88d42d45c385921448))
# [1.43.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.42.0...@standardnotes/analytics@1.43.0) (2022-11-04)
### Features
* **analytics:** add account deletion event handler ([5383e0c](https://github.com/standardnotes/server/commit/5383e0cf525ddd203beee451f1cfd5fd8600b522))
# [1.42.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.41.0...@standardnotes/analytics@1.42.0) (2022-11-04)
### Bug Fixes
* **analytics:** imports ([35611fb](https://github.com/standardnotes/server/commit/35611fbc07e50efbba954d7c96db9917e0dddd7d))
### Features
* **analytics:** add user registered handler ([034aa38](https://github.com/standardnotes/server/commit/034aa381539cf4b46769cfd1646dec2051d836c3))
# [1.41.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@1.40.0...@standardnotes/analytics@1.41.0) (2022-11-04)
### Bug Fixes

View File

@@ -1,4 +1,4 @@
FROM node:16.15.1-alpine
FROM node:18.12.1-alpine
RUN apk add --update \
curl \

View File

@@ -15,6 +15,7 @@ import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env'
import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
import { CalculateMonthlyRecurringRevenue } from '../src/Domain/UseCase/CalculateMonthlyRecurringRevenue/CalculateMonthlyRecurringRevenue'
const requestReport = async (
analyticsStore: AnalyticsStoreInterface,
@@ -22,7 +23,10 @@ const requestReport = async (
domainEventFactory: DomainEventFactoryInterface,
domainEventPublisher: DomainEventPublisherInterface,
periodKeyGenerator: PeriodKeyGeneratorInterface,
calculateMonthlyRecurringRevenue: CalculateMonthlyRecurringRevenue,
): Promise<void> => {
await calculateMonthlyRecurringRevenue.execute({})
const analyticsOverTime: Array<{
name: string
period: number
@@ -34,8 +38,6 @@ const requestReport = async (
}> = []
const thirtyDaysAnalyticsNames = [
AnalyticsActivity.GeneralActivity,
AnalyticsActivity.EditingItems,
AnalyticsActivity.SubscriptionPurchased,
AnalyticsActivity.Register,
AnalyticsActivity.SubscriptionRenewed,
@@ -80,9 +82,6 @@ const requestReport = async (
}> = []
const yesterdayActivityNames = [
AnalyticsActivity.LimitedDiscountOfferPurchased,
AnalyticsActivity.GeneralActivity,
AnalyticsActivity.GeneralActivityFreeUsers,
AnalyticsActivity.GeneralActivityPaidUsers,
AnalyticsActivity.PaymentFailed,
AnalyticsActivity.PaymentSuccess,
AnalyticsActivity.NewCustomersChurn,
@@ -101,6 +100,40 @@ const requestReport = async (
})
}
const statisticsOverTime: Array<{
name: string
period: number
counts: Array<{
periodKey: string
totalCount: number
}>
}> = []
const thirtyDaysStatisticsNames = [
StatisticsMeasure.MRR,
StatisticsMeasure.AnnualPlansMRR,
StatisticsMeasure.MonthlyPlansMRR,
StatisticsMeasure.FiveYearPlansMRR,
StatisticsMeasure.PlusPlansMRR,
StatisticsMeasure.ProPlansMRR,
]
for (const statisticName of thirtyDaysStatisticsNames) {
statisticsOverTime.push({
name: statisticName,
period: Period.Last30DaysIncludingToday,
counts: await statisticsStore.calculateTotalCountOverPeriod(statisticName, Period.Last30DaysIncludingToday),
})
}
const monthlyStatisticsNames = [StatisticsMeasure.MRR]
for (const statisticName of monthlyStatisticsNames) {
statisticsOverTime.push({
name: statisticName,
period: Period.ThisYear,
counts: await statisticsStore.calculateTotalCountOverPeriod(statisticName, Period.ThisYear),
})
}
const statisticMeasureNames = [
StatisticsMeasure.Income,
StatisticsMeasure.PlusSubscriptionInitialAnnualPaymentsIncome,
@@ -116,9 +149,6 @@ const requestReport = async (
StatisticsMeasure.SubscriptionLength,
StatisticsMeasure.RegistrationToSubscriptionTime,
StatisticsMeasure.RemainingSubscriptionTimePercentage,
StatisticsMeasure.NotesCountFreeUsers,
StatisticsMeasure.NotesCountPaidUsers,
StatisticsMeasure.FilesCount,
StatisticsMeasure.NewCustomers,
StatisticsMeasure.TotalCustomers,
]
@@ -141,29 +171,6 @@ const requestReport = async (
}
}
const periodKeys = periodKeyGenerator.getDiscretePeriodKeys(Period.Last7Days)
const retentionOverDays: Array<{
firstPeriodKey: string
secondPeriodKey: string
value: number
}> = []
for (let i = 0; i < periodKeys.length; i++) {
for (let j = 0; j < periodKeys.length - i; j++) {
const dailyRetention = await analyticsStore.calculateActivitiesRetention({
firstActivity: AnalyticsActivity.Register,
firstActivityPeriodKey: periodKeys[i],
secondActivity: AnalyticsActivity.GeneralActivity,
secondActivityPeriodKey: periodKeys[i + j],
})
retentionOverDays.push({
firstPeriodKey: periodKeys[i],
secondPeriodKey: periodKeys[i + j],
value: dailyRetention,
})
}
}
const monthlyPeriodKeys = periodKeyGenerator.getDiscretePeriodKeys(Period.ThisYear)
const churnRates: Array<{
rate: number
@@ -201,22 +208,10 @@ const requestReport = async (
}
const event = domainEventFactory.createDailyAnalyticsReportGeneratedEvent({
applicationStatistics: await statisticsStore.getYesterdayApplicationUsage(),
snjsStatistics: await statisticsStore.getYesterdaySNJSUsage(),
outOfSyncIncidents: await statisticsStore.getYesterdayOutOfSyncIncidents(),
activityStatistics: yesterdayActivityStatistics,
activityStatisticsOverTime: analyticsOverTime,
statisticsOverTime,
statisticMeasures,
retentionStatistics: [
{
firstActivity: AnalyticsActivity.Register,
secondActivity: AnalyticsActivity.GeneralActivity,
retention: {
periodKeys,
values: retentionOverDays,
},
},
],
churn: {
periodKeys: monthlyPeriodKeys,
values: churnRates,
@@ -240,9 +235,19 @@ void container.load().then((container) => {
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.DomainEventFactory)
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.DomainEventPublisher)
const periodKeyGenerator: PeriodKeyGeneratorInterface = container.get(TYPES.PeriodKeyGenerator)
const calculateMonthlyRecurringRevenue: CalculateMonthlyRecurringRevenue = container.get(
TYPES.CalculateMonthlyRecurringRevenue,
)
Promise.resolve(
requestReport(analyticsStore, statisticsStore, domainEventFactory, domainEventPublisher, periodKeyGenerator),
requestReport(
analyticsStore,
statisticsStore,
domainEventFactory,
domainEventPublisher,
periodKeyGenerator,
calculateMonthlyRecurringRevenue,
),
)
.then(() => {
logger.info('Usage report generation complete')

View File

@@ -7,4 +7,5 @@ module.exports = {
transform: {
...tsjPreset.transform,
},
coveragePathIgnorePatterns: ['/Infra/'],
}

View File

@@ -0,0 +1,15 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class addEmailToAnalyticsEntity1667568051894 implements MigrationInterface {
name = 'addEmailToAnalyticsEntity1667568051894'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('ALTER TABLE `analytics_entities` ADD `user_email` varchar(255) NULL')
await queryRunner.query('CREATE INDEX `email` ON `analytics_entities` (`user_email`)')
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('DROP INDEX `email` ON `analytics_entities`')
await queryRunner.query('ALTER TABLE `analytics_entities` DROP COLUMN `user_email`')
}
}

View File

@@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class addRevenueModifications1667912580964 implements MigrationInterface {
name = 'addRevenueModifications1667912580964'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
'CREATE TABLE `revenue_modifications` (`uuid` varchar(36) NOT NULL, `subscription_id` int NOT NULL, `user_email` varchar(255) NOT NULL, `user_uuid` varchar(36) NOT NULL, `event_type` varchar(255) NOT NULL, `subscription_plan` varchar(255) NOT NULL, `billing_frequency` int NOT NULL, `new_customer` tinyint NOT NULL, `previous_mrr` int NOT NULL, `new_mrr` int NOT NULL, INDEX `email` (`user_email`), INDEX `user_uuid` (`user_uuid`), PRIMARY KEY (`uuid`)) ENGINE=InnoDB',
)
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('DROP INDEX `user_uuid` ON `revenue_modifications`')
await queryRunner.query('DROP INDEX `email` ON `revenue_modifications`')
await queryRunner.query('DROP TABLE `revenue_modifications`')
}
}

View File

@@ -0,0 +1,13 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class addMissingCreatedAt1667994036734 implements MigrationInterface {
name = 'addMissingCreatedAt1667994036734'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('ALTER TABLE `revenue_modifications` ADD `created_at` bigint NOT NULL')
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('ALTER TABLE `revenue_modifications` DROP COLUMN `created_at`')
}
}

View File

@@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from 'typeorm'
export class fixMrrFloatingColumns1667995681714 implements MigrationInterface {
name = 'fixMrrFloatingColumns1667995681714'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('ALTER TABLE `revenue_modifications` DROP COLUMN `previous_mrr`')
await queryRunner.query('ALTER TABLE `revenue_modifications` ADD `previous_mrr` float NOT NULL')
await queryRunner.query('ALTER TABLE `revenue_modifications` DROP COLUMN `new_mrr`')
await queryRunner.query('ALTER TABLE `revenue_modifications` ADD `new_mrr` float NOT NULL')
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query('ALTER TABLE `revenue_modifications` DROP COLUMN `new_mrr`')
await queryRunner.query('ALTER TABLE `revenue_modifications` ADD `new_mrr` int NOT NULL')
await queryRunner.query('ALTER TABLE `revenue_modifications` DROP COLUMN `previous_mrr`')
await queryRunner.query('ALTER TABLE `revenue_modifications` ADD `previous_mrr` int NOT NULL')
}
}

View File

@@ -1,17 +1,14 @@
{
"name": "@standardnotes/analytics",
"version": "1.41.0",
"version": "2.10.2",
"engines": {
"node": ">=14.0.0 <17.0.0"
"node": ">=18.0.0 <19.0.0"
},
"private": true,
"description": "Analytics tools for Standard Notes projects",
"main": "dist/src/index.js",
"author": "Standard Notes",
"types": "dist/src/index.d.ts",
"files": [
"dist/src/**/*.js",
"dist/src/**/*.d.ts"
],
"publishConfig": {
"access": "public"
},
@@ -28,10 +25,10 @@
"typeorm": "typeorm-ts-node-commonjs"
},
"devDependencies": {
"@types/ioredis": "^4.28.10",
"@types/ioredis": "^5.0.0",
"@types/jest": "^29.1.1",
"@types/newrelic": "^7.0.3",
"@types/node": "^18.0.0",
"@types/newrelic": "^7.0.4",
"@types/node": "^18.11.9",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"eslint": "^8.14.0",
"eslint-plugin-prettier": "^4.2.1",
@@ -40,21 +37,23 @@
"typescript": "^4.8.4"
},
"dependencies": {
"@newrelic/native-metrics": "^9.0.0",
"@newrelic/winston-enricher": "^4.0.0",
"@sentry/node": "^7.3.0",
"@sentry/node": "^7.19.0",
"@standardnotes/common": "workspace:*",
"@standardnotes/domain-core": "workspace:*",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/time": "workspace:*",
"aws-sdk": "^2.1158.0",
"aws-sdk": "^2.1253.0",
"dayjs": "^1.11.6",
"dotenv": "^16.0.1",
"inversify": "^6.0.1",
"ioredis": "^5.2.3",
"ioredis": "^5.2.4",
"mysql2": "^2.3.3",
"newrelic": "^9.0.0",
"newrelic": "^9.6.0",
"reflect-metadata": "^0.1.13",
"typeorm": "^0.3.6",
"typeorm": "^0.3.10",
"winston": "^3.8.1"
}
}

View File

@@ -7,6 +7,7 @@ import {
DomainEventMessageHandlerInterface,
DomainEventSubscriberFactoryInterface,
} from '@standardnotes/domain-events'
import { MapInterface } from '@standardnotes/domain-core'
import { Env } from './Env'
import TYPES from './Types'
@@ -33,6 +34,24 @@ import { MySQLAnalyticsEntityRepository } from '../Infra/MySQL/MySQLAnalyticsEnt
import { Repository } from 'typeorm'
import { AnalyticsEntity } from '../Domain/Entity/AnalyticsEntity'
import { GetUserAnalyticsId } from '../Domain/UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { UserRegisteredEventHandler } from '../Domain/Handler/UserRegisteredEventHandler'
import { AccountDeletionRequestedEventHandler } from '../Domain/Handler/AccountDeletionRequestedEventHandler'
import { PaymentFailedEventHandler } from '../Domain/Handler/PaymentFailedEventHandler'
import { PaymentSuccessEventHandler } from '../Domain/Handler/PaymentSuccessEventHandler'
import { SubscriptionCancelledEventHandler } from '../Domain/Handler/SubscriptionCancelledEventHandler'
import { SubscriptionRenewedEventHandler } from '../Domain/Handler/SubscriptionRenewedEventHandler'
import { SubscriptionRefundedEventHandler } from '../Domain/Handler/SubscriptionRefundedEventHandler'
import { SubscriptionPurchasedEventHandler } from '../Domain/Handler/SubscriptionPurchasedEventHandler'
import { SubscriptionExpiredEventHandler } from '../Domain/Handler/SubscriptionExpiredEventHandler'
import { SubscriptionReactivatedEventHandler } from '../Domain/Handler/SubscriptionReactivatedEventHandler'
import { RefundProcessedEventHandler } from '../Domain/Handler/RefundProcessedEventHandler'
import { RevenueModificationRepositoryInterface } from '../Domain/Revenue/RevenueModificationRepositoryInterface'
import { MySQLRevenueModificationRepository } from '../Infra/MySQL/MySQLRevenueModificationRepository'
import { TypeORMRevenueModification } from '../Infra/TypeORM/TypeORMRevenueModification'
import { RevenueModification } from '../Domain/Revenue/RevenueModification'
import { RevenueModificationMap } from '../Domain/Map/RevenueModificationMap'
import { SaveRevenueModification } from '../Domain/UseCase/SaveRevenueModification/SaveRevenueModification'
import { CalculateMonthlyRecurringRevenue } from '../Domain/UseCase/CalculateMonthlyRecurringRevenue/CalculateMonthlyRecurringRevenue'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const newrelicFormatter = require('@newrelic/winston-enricher')
@@ -105,16 +124,56 @@ export class ContainerConfigLoader {
container
.bind<AnalyticsEntityRepositoryInterface>(TYPES.AnalyticsEntityRepository)
.to(MySQLAnalyticsEntityRepository)
container
.bind<RevenueModificationRepositoryInterface>(TYPES.RevenueModificationRepository)
.to(MySQLRevenueModificationRepository)
// ORM
container
.bind<Repository<AnalyticsEntity>>(TYPES.ORMAnalyticsEntityRepository)
.toConstantValue(AppDataSource.getRepository(AnalyticsEntity))
container
.bind<Repository<TypeORMRevenueModification>>(TYPES.ORMRevenueModificationRepository)
.toConstantValue(AppDataSource.getRepository(TypeORMRevenueModification))
// Use Case
container.bind<GetUserAnalyticsId>(TYPES.GetUserAnalyticsId).to(GetUserAnalyticsId)
container.bind<SaveRevenueModification>(TYPES.SaveRevenueModification).to(SaveRevenueModification)
container
.bind<CalculateMonthlyRecurringRevenue>(TYPES.CalculateMonthlyRecurringRevenue)
.to(CalculateMonthlyRecurringRevenue)
// Hanlders
container.bind<UserRegisteredEventHandler>(TYPES.UserRegisteredEventHandler).to(UserRegisteredEventHandler)
container
.bind<AccountDeletionRequestedEventHandler>(TYPES.AccountDeletionRequestedEventHandler)
.to(AccountDeletionRequestedEventHandler)
container.bind<PaymentFailedEventHandler>(TYPES.PaymentFailedEventHandler).to(PaymentFailedEventHandler)
container.bind<PaymentSuccessEventHandler>(TYPES.PaymentSuccessEventHandler).to(PaymentSuccessEventHandler)
container
.bind<SubscriptionCancelledEventHandler>(TYPES.SubscriptionCancelledEventHandler)
.to(SubscriptionCancelledEventHandler)
container
.bind<SubscriptionRenewedEventHandler>(TYPES.SubscriptionRenewedEventHandler)
.to(SubscriptionRenewedEventHandler)
container
.bind<SubscriptionRefundedEventHandler>(TYPES.SubscriptionRefundedEventHandler)
.to(SubscriptionRefundedEventHandler)
container
.bind<SubscriptionPurchasedEventHandler>(TYPES.SubscriptionPurchasedEventHandler)
.to(SubscriptionPurchasedEventHandler)
container
.bind<SubscriptionExpiredEventHandler>(TYPES.SubscriptionExpiredEventHandler)
.to(SubscriptionExpiredEventHandler)
container
.bind<SubscriptionReactivatedEventHandler>(TYPES.SubscriptionReactivatedEventHandler)
.to(SubscriptionReactivatedEventHandler)
container.bind<RefundProcessedEventHandler>(TYPES.RefundProcessedEventHandler).to(RefundProcessedEventHandler)
// Maps
container
.bind<MapInterface<RevenueModification, TypeORMRevenueModification>>(TYPES.RevenueModificationMap)
.to(RevenueModificationMap)
// Services
container.bind<DomainEventFactory>(TYPES.DomainEventFactory).to(DomainEventFactory)
@@ -139,7 +198,19 @@ export class ContainerConfigLoader {
)
}
const eventHandlers: Map<string, DomainEventHandlerInterface> = new Map([])
const eventHandlers: Map<string, DomainEventHandlerInterface> = new Map([
['USER_REGISTERED', container.get(TYPES.UserRegisteredEventHandler)],
['ACCOUNT_DELETION_REQUESTED', container.get(TYPES.AccountDeletionRequestedEventHandler)],
['PAYMENT_FAILED', container.get(TYPES.PaymentFailedEventHandler)],
['PAYMENT_SUCCESS', container.get(TYPES.PaymentSuccessEventHandler)],
['SUBSCRIPTION_CANCELLED', container.get(TYPES.SubscriptionCancelledEventHandler)],
['SUBSCRIPTION_RENEWED', container.get(TYPES.SubscriptionRenewedEventHandler)],
['SUBSCRIPTION_REFUNDED', container.get(TYPES.SubscriptionRefundedEventHandler)],
['SUBSCRIPTION_PURCHASED', container.get(TYPES.SubscriptionPurchasedEventHandler)],
['SUBSCRIPTION_EXPIRED', container.get(TYPES.SubscriptionExpiredEventHandler)],
['SUBSCRIPTION_REACTIVATED', container.get(TYPES.SubscriptionReactivatedEventHandler)],
['REFUND_PROCESSED', container.get(TYPES.RefundProcessedEventHandler)],
])
if (env.get('SQS_QUEUE_URL', true)) {
container

View File

@@ -1,6 +1,7 @@
import { DataSource, LoggerOptions } from 'typeorm'
import { AnalyticsEntity } from '../Domain/Entity/AnalyticsEntity'
import { TypeORMRevenueModification } from '../Infra/TypeORM/TypeORMRevenueModification'
import { Env } from './Env'
@@ -36,7 +37,7 @@ export const AppDataSource = new DataSource({
],
removeNodeErrorCount: 10,
},
entities: [AnalyticsEntity],
entities: [AnalyticsEntity, TypeORMRevenueModification],
migrations: [env.get('DB_MIGRATIONS_PATH', true) ?? 'dist/migrations/*.js'],
migrationsRun: true,
logging: <LoggerOptions>env.get('DB_DEBUG_LEVEL'),

View File

@@ -13,11 +13,28 @@ const TYPES = {
NEW_RELIC_ENABLED: Symbol.for('NEW_RELIC_ENABLED'),
// Repositories
AnalyticsEntityRepository: Symbol.for('AnalyticsEntityRepository'),
RevenueModificationRepository: Symbol.for('RevenueModificationRepository'),
// ORM
ORMAnalyticsEntityRepository: Symbol.for('ORMAnalyticsEntityRepository'),
ORMRevenueModificationRepository: Symbol.for('ORMRevenueModificationRepository'),
// Use Case
GetUserAnalyticsId: Symbol.for('GetUserAnalyticsId'),
SaveRevenueModification: Symbol.for('SaveRevenueModification'),
CalculateMonthlyRecurringRevenue: Symbol.for('CalculateMonthlyRecurringRevenue'),
// Handlers
UserRegisteredEventHandler: Symbol.for('UserRegisteredEventHandler'),
AccountDeletionRequestedEventHandler: Symbol.for('AccountDeletionRequestedEventHandler'),
PaymentFailedEventHandler: Symbol.for('PaymentFailedEventHandler'),
PaymentSuccessEventHandler: Symbol.for('PaymentSuccessEventHandler'),
SubscriptionCancelledEventHandler: Symbol.for('SubscriptionCancelledEventHandler'),
SubscriptionRenewedEventHandler: Symbol.for('SubscriptionRenewedEventHandler'),
SubscriptionRefundedEventHandler: Symbol.for('SubscriptionRefundedEventHandler'),
SubscriptionPurchasedEventHandler: Symbol.for('SubscriptionPurchasedEventHandler'),
SubscriptionExpiredEventHandler: Symbol.for('SubscriptionExpiredEventHandler'),
SubscriptionReactivatedEventHandler: Symbol.for('SubscriptionReactivatedEventHandler'),
RefundProcessedEventHandler: Symbol.for('RefundProcessedEventHandler'),
// Maps
RevenueModificationMap: Symbol.for('RevenueModificationMap'),
// Services
DomainEventPublisher: Symbol.for('DomainEventPublisher'),
DomainEventSubscriberFactory: Symbol.for('DomainEventSubscriberFactory'),

View File

@@ -1,10 +1,4 @@
export enum AnalyticsActivity {
GeneralActivity = 'general-activity',
GeneralActivityFreeUsers = 'general-activity-free-users',
GeneralActivityPaidUsers = 'general-activity-paid-users',
EditingItems = 'editing-items',
CheckingIntegrity = 'checking-integrity',
Login = 'login',
Register = 'register',
DeleteAccount = 'DeleteAccount',
SubscriptionPurchased = 'subscription-purchased',
@@ -13,8 +7,6 @@ export enum AnalyticsActivity {
SubscriptionCancelled = 'subscription-cancelled',
SubscriptionExpired = 'subscription-expired',
SubscriptionReactivated = 'subscription-reactivated',
EmailUnbackedUpData = 'email-unbacked-up-data',
EmailBackup = 'email-backup',
LimitedDiscountOfferPurchased = 'limited-discount-offer-purchased',
PaymentFailed = 'payment-failed',
PaymentSuccess = 'payment-success',

View File

@@ -11,4 +11,12 @@ export class AnalyticsEntity {
})
@Index('user_uuid')
declare userUuid: string
@Column({
name: 'user_email',
length: 255,
nullable: true,
})
@Index('email')
declare userEmail: string
}

View File

@@ -3,5 +3,7 @@ import { AnalyticsEntity } from './AnalyticsEntity'
export interface AnalyticsEntityRepositoryInterface {
save(analyticsEntity: AnalyticsEntity): Promise<AnalyticsEntity>
remove(analyticsEntity: AnalyticsEntity): Promise<void>
findOneByUserUuid(userUuid: Uuid): Promise<AnalyticsEntity | null>
findOneByUserEmail(email: string): Promise<AnalyticsEntity | null>
}

View File

@@ -22,18 +22,6 @@ describe('DomainEventFactory', () => {
it('should create a DAILY_ANALYTICS_REPORT_GENERATED event', () => {
expect(
createFactory().createDailyAnalyticsReportGeneratedEvent({
snjsStatistics: [
{
version: '1-2-3',
count: 2,
},
],
applicationStatistics: [
{
version: '2-3-4',
count: 45,
},
],
activityStatistics: [
{
name: AnalyticsActivity.Register,
@@ -63,21 +51,16 @@ describe('DomainEventFactory', () => {
totalCount: 123,
},
],
outOfSyncIncidents: 324,
retentionStatistics: [
statisticsOverTime: [
{
firstActivity: AnalyticsActivity.Register,
secondActivity: AnalyticsActivity.Login,
retention: {
periodKeys: ['2022-10-9'],
values: [
{
firstPeriodKey: AnalyticsActivity.Register,
secondPeriodKey: AnalyticsActivity.Login,
value: 12,
},
],
},
name: StatisticsMeasure.MRR,
period: Period.Last30Days,
counts: [
{
periodKey: '2022-10-9',
totalCount: 3,
},
],
},
],
churn: {
@@ -120,10 +103,16 @@ describe('DomainEventFactory', () => {
totalCount: 123,
},
],
applicationStatistics: [
statisticsOverTime: [
{
count: 45,
version: '2-3-4',
counts: [
{
periodKey: '2022-10-9',
totalCount: 3,
},
],
name: 'mrr',
period: 9,
},
],
churn: {
@@ -135,29 +124,6 @@ describe('DomainEventFactory', () => {
},
],
},
outOfSyncIncidents: 324,
retentionStatistics: [
{
firstActivity: 'register',
retention: {
periodKeys: ['2022-10-9'],
values: [
{
firstPeriodKey: 'register',
secondPeriodKey: 'login',
value: 12,
},
],
},
secondActivity: 'login',
},
],
snjsStatistics: [
{
count: 2,
version: '1-2-3',
},
],
statisticMeasures: [
{
average: 23,

View File

@@ -9,14 +9,6 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
constructor(@inject(TYPES.Timer) private timer: TimerInterface) {}
createDailyAnalyticsReportGeneratedEvent(dto: {
snjsStatistics: Array<{
version: string
count: number
}>
applicationStatistics: Array<{
version: string
count: number
}>
activityStatistics: Array<{
name: string
retention: number
@@ -38,18 +30,13 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
}>
totalCount: number
}>
outOfSyncIncidents: number
retentionStatistics: Array<{
firstActivity: string
secondActivity: string
retention: {
periodKeys: Array<string>
values: Array<{
firstPeriodKey: string
secondPeriodKey: string
value: number
}>
}
statisticsOverTime: Array<{
name: string
period: number
counts: Array<{
periodKey: string
totalCount: number
}>
}>
churn: {
periodKeys: Array<string>

View File

@@ -2,14 +2,6 @@ import { DailyAnalyticsReportGeneratedEvent } from '@standardnotes/domain-events
export interface DomainEventFactoryInterface {
createDailyAnalyticsReportGeneratedEvent(dto: {
snjsStatistics: Array<{
version: string
count: number
}>
applicationStatistics: Array<{
version: string
count: number
}>
activityStatistics: Array<{
name: string
retention: number
@@ -31,18 +23,13 @@ export interface DomainEventFactoryInterface {
}>
totalCount: number
}>
outOfSyncIncidents: number
retentionStatistics: Array<{
firstActivity: string
secondActivity: string
retention: {
periodKeys: Array<string>
values: Array<{
firstPeriodKey: string
secondPeriodKey: string
value: number
}>
}
statisticsOverTime: Array<{
name: string
period: number
counts: Array<{
periodKey: string
totalCount: number
}>
}>
churn: {
periodKeys: Array<string>

View File

@@ -0,0 +1,69 @@
import 'reflect-metadata'
import { AccountDeletionRequestedEvent } from '@standardnotes/domain-events'
import { AccountDeletionRequestedEventHandler } from './AccountDeletionRequestedEventHandler'
import { TimerInterface } from '@standardnotes/time'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { Period } from '../Time/Period'
import { AnalyticsEntityRepositoryInterface } from '../Entity/AnalyticsEntityRepositoryInterface'
describe('AccountDeletionRequestedEventHandler', () => {
let event: AccountDeletionRequestedEvent
let analyticsEntityRepository: AnalyticsEntityRepositoryInterface
let analyticsStore: AnalyticsStoreInterface
let statisticsStore: StatisticsStoreInterface
let timer: TimerInterface
const createHandler = () =>
new AccountDeletionRequestedEventHandler(analyticsEntityRepository, analyticsStore, statisticsStore, timer)
beforeEach(() => {
event = {} as jest.Mocked<AccountDeletionRequestedEvent>
event.createdAt = new Date(1)
event.payload = {
userUuid: '1-2-3',
userCreatedAtTimestamp: 1,
regularSubscriptionUuid: '2-3-4',
}
analyticsEntityRepository = {} as jest.Mocked<AnalyticsEntityRepositoryInterface>
analyticsEntityRepository.findOneByUserUuid = jest.fn().mockReturnValue({ id: 3 })
analyticsEntityRepository.remove = jest.fn()
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
analyticsStore.markActivity = jest.fn()
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
statisticsStore.incrementMeasure = jest.fn()
timer = {} as jest.Mocked<TimerInterface>
timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(123)
})
it('should mark account deletion and registration length', async () => {
await createHandler().handle(event)
expect(analyticsStore.markActivity).toHaveBeenCalledWith(['DeleteAccount'], 3, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
expect(statisticsStore.incrementMeasure).toHaveBeenCalledWith('registration-length', 122, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
expect(analyticsEntityRepository.remove).toHaveBeenCalled()
})
it('should not mark anything if entity is not found', async () => {
analyticsEntityRepository.findOneByUserUuid = jest.fn().mockReturnValue(null)
await createHandler().handle(event)
expect(analyticsStore.markActivity).not.toHaveBeenCalled()
expect(statisticsStore.incrementMeasure).not.toHaveBeenCalled()
expect(analyticsEntityRepository.remove).not.toHaveBeenCalled()
})
})

View File

@@ -0,0 +1,44 @@
import { AccountDeletionRequestedEvent, DomainEventHandlerInterface } from '@standardnotes/domain-events'
import { TimerInterface } from '@standardnotes/time'
import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { AnalyticsEntityRepositoryInterface } from '../Entity/AnalyticsEntityRepositoryInterface'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { Period } from '../Time/Period'
@injectable()
export class AccountDeletionRequestedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.AnalyticsEntityRepository) private analyticsEntityRepository: AnalyticsEntityRepositoryInterface,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
@inject(TYPES.Timer) private timer: TimerInterface,
) {}
async handle(event: AccountDeletionRequestedEvent): Promise<void> {
const analyticsEntity = await this.analyticsEntityRepository.findOneByUserUuid(event.payload.userUuid)
if (analyticsEntity === null) {
return
}
await this.analyticsStore.markActivity([AnalyticsActivity.DeleteAccount], analyticsEntity.id, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
const registrationLength = this.timer.getTimestampInMicroseconds() - event.payload.userCreatedAtTimestamp
await this.statisticsStore.incrementMeasure(StatisticsMeasure.RegistrationLength, registrationLength, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
await this.analyticsEntityRepository.remove(analyticsEntity)
}
}

View File

@@ -1,28 +1,19 @@
import 'reflect-metadata'
import { PaymentFailedEvent } from '@standardnotes/domain-events'
import { AnalyticsStoreInterface } from '@standardnotes/analytics'
import { PaymentFailedEventHandler } from './PaymentFailedEventHandler'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { User } from '../User/User'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
describe('PaymentFailedEventHandler', () => {
let userRepository: UserRepositoryInterface
let event: PaymentFailedEvent
let user: User
let getUserAnalyticsId: GetUserAnalyticsId
let analyticsStore: AnalyticsStoreInterface
const createHandler = () => new PaymentFailedEventHandler(userRepository, getUserAnalyticsId, analyticsStore)
const createHandler = () => new PaymentFailedEventHandler(getUserAnalyticsId, analyticsStore)
beforeEach(() => {
user = {} as jest.Mocked<User>
userRepository = {} as jest.Mocked<UserRepositoryInterface>
userRepository.findOneByEmail = jest.fn().mockReturnValue(user)
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
getUserAnalyticsId.execute = jest.fn().mockReturnValue({ analyticsId: 3 })
@@ -40,12 +31,4 @@ describe('PaymentFailedEventHandler', () => {
expect(analyticsStore.markActivity).toHaveBeenCalled()
})
it('should not mark payment failed for analytics if user is not found', async () => {
userRepository.findOneByEmail = jest.fn().mockReturnValue(null)
await createHandler().handle(event)
expect(analyticsStore.markActivity).not.toHaveBeenCalled()
})
})

View File

@@ -1,26 +1,21 @@
import { AnalyticsActivity, AnalyticsStoreInterface, Period } from '@standardnotes/analytics'
import { DomainEventHandlerInterface, PaymentFailedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { Period } from '../Time/Period'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
@injectable()
export class PaymentFailedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
) {}
async handle(event: PaymentFailedEvent): Promise<void> {
const user = await this.userRepository.findOneByEmail(event.payload.userEmail)
if (user === null) {
return
}
const { analyticsId } = await this.getUserAnalyticsId.execute({ userUuid: user.uuid })
const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
await this.analyticsStore.markActivity([AnalyticsActivity.PaymentFailed], analyticsId, [
Period.Today,
Period.ThisWeek,

View File

@@ -1,32 +1,25 @@
import 'reflect-metadata'
import { PaymentSuccessEvent } from '@standardnotes/domain-events'
import { AnalyticsStoreInterface, Period, StatisticsStoreInterface } from '@standardnotes/analytics'
import { PaymentSuccessEventHandler } from './PaymentSuccessEventHandler'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { User } from '../User/User'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { Logger } from 'winston'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { Period } from '../Time/Period'
describe('PaymentSuccessEventHandler', () => {
let userRepository: UserRepositoryInterface
let event: PaymentSuccessEvent
let user: User
let getUserAnalyticsId: GetUserAnalyticsId
let analyticsStore: AnalyticsStoreInterface
let statisticsStore: StatisticsStoreInterface
let logger: Logger
const createHandler = () =>
new PaymentSuccessEventHandler(userRepository, getUserAnalyticsId, analyticsStore, statisticsStore, logger)
new PaymentSuccessEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore, logger)
beforeEach(() => {
user = {} as jest.Mocked<User>
userRepository = {} as jest.Mocked<UserRepositoryInterface>
userRepository.findOneByEmail = jest.fn().mockReturnValue(user)
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
getUserAnalyticsId.execute = jest.fn().mockReturnValue({ analyticsId: 3 })
@@ -79,12 +72,4 @@ describe('PaymentSuccessEventHandler', () => {
Period.ThisMonth,
])
})
it('should not mark payment failed for analytics if user is not found', async () => {
userRepository.findOneByEmail = jest.fn().mockReturnValue(null)
await createHandler().handle(event)
expect(analyticsStore.markActivity).not.toHaveBeenCalled()
})
})

View File

@@ -1,18 +1,15 @@
import {
AnalyticsActivity,
AnalyticsStoreInterface,
Period,
StatisticsMeasure,
StatisticsStoreInterface,
} from '@standardnotes/analytics'
import { PaymentType, SubscriptionBillingFrequency, SubscriptionName } from '@standardnotes/common'
import { DomainEventHandlerInterface, PaymentSuccessEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { Period } from '../Time/Period'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
@injectable()
export class PaymentSuccessEventHandler implements DomainEventHandlerInterface {
@@ -58,7 +55,6 @@ export class PaymentSuccessEventHandler implements DomainEventHandlerInterface {
])
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
@@ -66,12 +62,7 @@ export class PaymentSuccessEventHandler implements DomainEventHandlerInterface {
) {}
async handle(event: PaymentSuccessEvent): Promise<void> {
const user = await this.userRepository.findOneByEmail(event.payload.userEmail)
if (user === null) {
return
}
const { analyticsId } = await this.getUserAnalyticsId.execute({ userUuid: user.uuid })
const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
await this.analyticsStore.markActivity([AnalyticsActivity.PaymentSuccess], analyticsId, [
Period.Today,
Period.ThisWeek,

View File

@@ -1,9 +1,11 @@
import 'reflect-metadata'
import { RefundProcessedEvent } from '@standardnotes/domain-events'
import { Period, StatisticsMeasure, StatisticsStoreInterface } from '@standardnotes/analytics'
import { RefundProcessedEventHandler } from './RefundProcessedEventHandler'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { Period } from '../Time/Period'
describe('RefundProcessedEventHandler', () => {
let event: RefundProcessedEvent

View File

@@ -1,8 +1,10 @@
import { Period, StatisticsMeasure, StatisticsStoreInterface } from '@standardnotes/analytics'
import { DomainEventHandlerInterface, RefundProcessedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { Period } from '../Time/Period'
@injectable()
export class RefundProcessedEventHandler implements DomainEventHandlerInterface {

View File

@@ -0,0 +1,104 @@
import 'reflect-metadata'
import { SubscriptionName } from '@standardnotes/common'
import { Result } from '@standardnotes/domain-core'
import { SubscriptionCancelledEvent } from '@standardnotes/domain-events'
import { SubscriptionCancelledEventHandler } from './SubscriptionCancelledEventHandler'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { Period } from '../Time/Period'
import { RevenueModification } from '../Revenue/RevenueModification'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { Logger } from 'winston'
describe('SubscriptionCancelledEventHandler', () => {
let event: SubscriptionCancelledEvent
let getUserAnalyticsId: GetUserAnalyticsId
let analyticsStore: AnalyticsStoreInterface
let statisticsStore: StatisticsStoreInterface
let saveRevenueModification: SaveRevenueModification
let logger: Logger
const createHandler = () =>
new SubscriptionCancelledEventHandler(
getUserAnalyticsId,
analyticsStore,
statisticsStore,
saveRevenueModification,
logger,
)
beforeEach(() => {
logger = {} as jest.Mocked<Logger>
logger.error = jest.fn()
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
getUserAnalyticsId.execute = jest.fn().mockReturnValue({ analyticsId: 3 })
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
analyticsStore.markActivity = jest.fn()
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
statisticsStore.incrementMeasure = jest.fn()
event = {} as jest.Mocked<SubscriptionCancelledEvent>
event.createdAt = new Date(1)
event.type = 'SUBSCRIPTION_CANCELLED'
event.payload = {
subscriptionId: 1,
userEmail: 'test@test.com',
subscriptionName: SubscriptionName.ProPlan,
subscriptionCreatedAt: 1642395451515000,
subscriptionUpdatedAt: 1642395451515001,
lastPayedAt: 1642395451515001,
subscriptionEndsAt: 1642395451515000 + 10,
timestamp: 1,
offline: false,
replaced: false,
userExistingSubscriptionsCount: 1,
billingFrequency: 1,
payAmount: 12.99,
}
saveRevenueModification = {} as jest.Mocked<SaveRevenueModification>
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.ok<RevenueModification>())
})
it('should track subscription cancelled statistics', async () => {
event.payload.timestamp = 1642395451516000
await createHandler().handle(event)
expect(analyticsStore.markActivity).toHaveBeenCalled()
expect(statisticsStore.incrementMeasure).toHaveBeenCalledWith(StatisticsMeasure.SubscriptionLength, 1000, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
expect(saveRevenueModification.execute).toHaveBeenCalled()
})
it('should not track statistics for subscriptions that are in a legacy 5 year plan', async () => {
event.payload.timestamp = 1642395451516000
event.payload.subscriptionEndsAt = 1642395451515000 + 126_230_400_000_001
event.payload.subscriptionCreatedAt = 1642395451515000
await createHandler().handle(event)
expect(statisticsStore.incrementMeasure).not.toHaveBeenCalled()
expect(saveRevenueModification.execute).toHaveBeenCalled()
})
it('should log failure to save revenue modification', async () => {
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.fail('Oops'))
event.payload.timestamp = 1642395451516000
await createHandler().handle(event)
expect(logger.error).toHaveBeenCalled()
})
})

View File

@@ -0,0 +1,84 @@
import { DomainEventHandlerInterface, SubscriptionCancelledEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
import { Period } from '../Time/Period'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
@injectable()
export class SubscriptionCancelledEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
@inject(TYPES.Logger) private logger: Logger,
) {}
async handle(event: SubscriptionCancelledEvent): Promise<void> {
const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionCancelled], analyticsId, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
await this.trackSubscriptionStatistics(event)
const result = await this.saveRevenueModification.execute({
billingFrequency: event.payload.billingFrequency,
eventType: SubscriptionEventType.create(event.type).getValue(),
newSubscriber: event.payload.userExistingSubscriptionsCount === 1,
payedAmount: event.payload.payAmount,
planName: SubscriptionPlanName.create(event.payload.subscriptionName).getValue(),
subscriptionId: event.payload.subscriptionId,
userEmail: Email.create(event.payload.userEmail).getValue(),
userUuid,
})
if (result.isFailed()) {
this.logger.error(
`[${event.type}][${event.payload.subscriptionId}] Could not save revenue modification: ${result.getError()}`,
)
}
}
private async trackSubscriptionStatistics(event: SubscriptionCancelledEvent) {
if (this.isLegacy5yearSubscriptionPlan(event.payload.subscriptionEndsAt, event.payload.subscriptionCreatedAt)) {
return
}
const subscriptionLength = event.payload.timestamp - event.payload.subscriptionCreatedAt
await this.statisticsStore.incrementMeasure(StatisticsMeasure.SubscriptionLength, subscriptionLength, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
const remainingSubscriptionTime = event.payload.subscriptionEndsAt - event.payload.timestamp
const totalSubscriptionTime = event.payload.subscriptionEndsAt - event.payload.lastPayedAt
const remainingSubscriptionPercentage = Math.floor((remainingSubscriptionTime / totalSubscriptionTime) * 100)
await this.statisticsStore.incrementMeasure(
StatisticsMeasure.RemainingSubscriptionTimePercentage,
remainingSubscriptionPercentage,
[Period.Today, Period.ThisWeek, Period.ThisMonth],
)
}
private isLegacy5yearSubscriptionPlan(subscriptionEndsAt: number, subscriptionCreatedAt: number) {
const fourYearsInMicroseconds = 126_230_400_000_000
return subscriptionEndsAt - subscriptionCreatedAt > fourYearsInMicroseconds
}
}

View File

@@ -0,0 +1,79 @@
import 'reflect-metadata'
import { SubscriptionName } from '@standardnotes/common'
import { SubscriptionExpiredEvent } from '@standardnotes/domain-events'
import { Result } from '@standardnotes/domain-core'
import { SubscriptionExpiredEventHandler } from './SubscriptionExpiredEventHandler'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { RevenueModification } from '../Revenue/RevenueModification'
import { Logger } from 'winston'
describe('SubscriptionExpiredEventHandler', () => {
let event: SubscriptionExpiredEvent
let getUserAnalyticsId: GetUserAnalyticsId
let analyticsStore: AnalyticsStoreInterface
let statisticsStore: StatisticsStoreInterface
let saveRevenueModification: SaveRevenueModification
let logger: Logger
const createHandler = () =>
new SubscriptionExpiredEventHandler(
getUserAnalyticsId,
analyticsStore,
statisticsStore,
saveRevenueModification,
logger,
)
beforeEach(() => {
logger = {} as jest.Mocked<Logger>
logger.error = jest.fn()
event = {} as jest.Mocked<SubscriptionExpiredEvent>
event.createdAt = new Date(1)
event.type = 'SUBSCRIPTION_EXPIRED'
event.payload = {
subscriptionId: 1,
userEmail: 'test@test.com',
subscriptionName: SubscriptionName.PlusPlan,
timestamp: 1,
offline: false,
totalActiveSubscriptionsCount: 123,
userExistingSubscriptionsCount: 2,
billingFrequency: 1,
payAmount: 12.99,
}
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
getUserAnalyticsId.execute = jest.fn().mockReturnValue({ analyticsId: 3 })
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
analyticsStore.markActivity = jest.fn()
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
statisticsStore.setMeasure = jest.fn()
saveRevenueModification = {} as jest.Mocked<SaveRevenueModification>
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.ok<RevenueModification>())
})
it('should update analytics and statistics', async () => {
await createHandler().handle(event)
expect(analyticsStore.markActivity).toHaveBeenCalled()
expect(statisticsStore.setMeasure).toHaveBeenCalled()
expect(saveRevenueModification.execute).toHaveBeenCalled()
})
it('should log failure to save revenue modification', async () => {
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.fail('Oops'))
await createHandler().handle(event)
expect(logger.error).toHaveBeenCalled()
})
})

View File

@@ -0,0 +1,58 @@
import { DomainEventHandlerInterface, SubscriptionExpiredEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
import { Period } from '../Time/Period'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
@injectable()
export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
@inject(TYPES.Logger) private logger: Logger,
) {}
async handle(event: SubscriptionExpiredEvent): Promise<void> {
const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
await this.analyticsStore.markActivity(
[AnalyticsActivity.SubscriptionExpired, AnalyticsActivity.ExistingCustomersChurn],
analyticsId,
[Period.Today, Period.ThisWeek, Period.ThisMonth],
)
await this.statisticsStore.setMeasure(
StatisticsMeasure.TotalCustomers,
event.payload.totalActiveSubscriptionsCount,
[Period.Today, Period.ThisWeek, Period.ThisMonth, Period.ThisYear],
)
const result = await this.saveRevenueModification.execute({
billingFrequency: event.payload.billingFrequency,
eventType: SubscriptionEventType.create(event.type).getValue(),
newSubscriber: event.payload.userExistingSubscriptionsCount === 1,
payedAmount: event.payload.payAmount,
planName: SubscriptionPlanName.create(event.payload.subscriptionName).getValue(),
subscriptionId: event.payload.subscriptionId,
userEmail: Email.create(event.payload.userEmail).getValue(),
userUuid,
})
if (result.isFailed()) {
this.logger.error(
`[${event.type}][${event.payload.subscriptionId}] Could not save revenue modification: ${result.getError()}`,
)
}
}
}

View File

@@ -0,0 +1,102 @@
import 'reflect-metadata'
import { SubscriptionName } from '@standardnotes/common'
import { SubscriptionPurchasedEvent } from '@standardnotes/domain-events'
import { Result } from '@standardnotes/domain-core'
import { SubscriptionPurchasedEventHandler } from './SubscriptionPurchasedEventHandler'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { Period } from '../Time/Period'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { RevenueModification } from '../Revenue/RevenueModification'
import { Logger } from 'winston'
describe('SubscriptionPurchasedEventHandler', () => {
let event: SubscriptionPurchasedEvent
let subscriptionExpiresAt: number
let getUserAnalyticsId: GetUserAnalyticsId
let analyticsStore: AnalyticsStoreInterface
let statisticsStore: StatisticsStoreInterface
let saveRevenueModification: SaveRevenueModification
let logger: Logger
const createHandler = () =>
new SubscriptionPurchasedEventHandler(
getUserAnalyticsId,
analyticsStore,
statisticsStore,
saveRevenueModification,
logger,
)
beforeEach(() => {
logger = {} as jest.Mocked<Logger>
logger.error = jest.fn()
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
statisticsStore.incrementMeasure = jest.fn()
statisticsStore.setMeasure = jest.fn()
event = {} as jest.Mocked<SubscriptionPurchasedEvent>
event.createdAt = new Date(1)
event.type = 'SUBSCRIPTION_PURCHASED'
event.payload = {
subscriptionId: 1,
userEmail: 'test@test.com',
subscriptionName: SubscriptionName.ProPlan,
subscriptionExpiresAt,
timestamp: 60,
offline: false,
discountCode: null,
limitedDiscountPurchased: false,
newSubscriber: true,
totalActiveSubscriptionsCount: 123,
userRegisteredAt: 23,
billingFrequency: 12,
payAmount: 29.99,
}
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
getUserAnalyticsId.execute = jest.fn().mockReturnValue({ analyticsId: 3 })
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
analyticsStore.markActivity = jest.fn()
analyticsStore.unmarkActivity = jest.fn()
saveRevenueModification = {} as jest.Mocked<SaveRevenueModification>
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.ok<RevenueModification>())
})
it('should mark subscription creation statistics', async () => {
await createHandler().handle(event)
expect(statisticsStore.incrementMeasure).toHaveBeenCalled()
expect(saveRevenueModification.execute).toHaveBeenCalled()
})
it("should not measure registration to subscription time if this is not user's first subscription", async () => {
event.payload.newSubscriber = false
await createHandler().handle(event)
expect(statisticsStore.incrementMeasure).not.toHaveBeenCalled()
})
it('should update analytics on limited discount offer purchasing', async () => {
event.payload.limitedDiscountPurchased = true
await createHandler().handle(event)
expect(analyticsStore.markActivity).toHaveBeenCalledWith(['limited-discount-offer-purchased'], 3, [Period.Today])
})
it('should log failure to save revenue modification', async () => {
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.fail('Oops'))
await createHandler().handle(event)
expect(logger.error).toHaveBeenCalled()
})
})

View File

@@ -0,0 +1,82 @@
import { DomainEventHandlerInterface, SubscriptionPurchasedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
import { Period } from '../Time/Period'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
@injectable()
export class SubscriptionPurchasedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
@inject(TYPES.Logger) private logger: Logger,
) {}
async handle(event: SubscriptionPurchasedEvent): Promise<void> {
const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionPurchased], analyticsId, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
await this.analyticsStore.unmarkActivity(
[AnalyticsActivity.ExistingCustomersChurn, AnalyticsActivity.NewCustomersChurn],
analyticsId,
[Period.Today, Period.ThisWeek, Period.ThisMonth],
)
if (event.payload.limitedDiscountPurchased) {
await this.analyticsStore.markActivity([AnalyticsActivity.LimitedDiscountOfferPurchased], analyticsId, [
Period.Today,
])
}
if (event.payload.newSubscriber) {
await this.statisticsStore.incrementMeasure(
StatisticsMeasure.RegistrationToSubscriptionTime,
event.payload.timestamp - event.payload.userRegisteredAt,
[Period.Today, Period.ThisWeek, Period.ThisMonth],
)
await this.statisticsStore.incrementMeasure(StatisticsMeasure.NewCustomers, 1, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
Period.ThisYear,
])
await this.statisticsStore.setMeasure(
StatisticsMeasure.TotalCustomers,
event.payload.totalActiveSubscriptionsCount,
[Period.Today, Period.ThisWeek, Period.ThisMonth, Period.ThisYear],
)
}
const result = await this.saveRevenueModification.execute({
billingFrequency: event.payload.billingFrequency,
eventType: SubscriptionEventType.create(event.type).getValue(),
newSubscriber: event.payload.newSubscriber,
payedAmount: event.payload.payAmount,
planName: SubscriptionPlanName.create(event.payload.subscriptionName).getValue(),
subscriptionId: event.payload.subscriptionId,
userEmail: Email.create(event.payload.userEmail).getValue(),
userUuid,
})
if (result.isFailed()) {
this.logger.error(
`[${event.type}][${event.payload.subscriptionId}] Could not save revenue modification: ${result.getError()}`,
)
}
}
}

View File

@@ -1,41 +1,21 @@
import 'reflect-metadata'
import { RoleName, SubscriptionName } from '@standardnotes/common'
import { SubscriptionName } from '@standardnotes/common'
import { SubscriptionReactivatedEvent } from '@standardnotes/domain-events'
import { Logger } from 'winston'
import { User } from '../User/User'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
import { SubscriptionReactivatedEventHandler } from './SubscriptionReactivatedEventHandler'
import { AnalyticsStoreInterface, Period } from '@standardnotes/analytics'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { Period } from '../Time/Period'
describe('SubscriptionReactivatedEventHandler', () => {
let userRepository: UserRepositoryInterface
let logger: Logger
let user: User
let event: SubscriptionReactivatedEvent
let getUserAnalyticsId: GetUserAnalyticsId
let analyticsStore: AnalyticsStoreInterface
const createHandler = () =>
new SubscriptionReactivatedEventHandler(userRepository, analyticsStore, getUserAnalyticsId, logger)
const createHandler = () => new SubscriptionReactivatedEventHandler(analyticsStore, getUserAnalyticsId)
beforeEach(() => {
user = {
uuid: '123',
email: 'test@test.com',
roles: Promise.resolve([
{
name: RoleName.ProUser,
},
]),
} as jest.Mocked<User>
userRepository = {} as jest.Mocked<UserRepositoryInterface>
userRepository.findOneByEmail = jest.fn().mockReturnValue(user)
userRepository.save = jest.fn().mockReturnValue(user)
event = {} as jest.Mocked<SubscriptionReactivatedEvent>
event.createdAt = new Date(1)
event.payload = {
@@ -52,10 +32,6 @@ describe('SubscriptionReactivatedEventHandler', () => {
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
analyticsStore.markActivity = jest.fn()
logger = {} as jest.Mocked<Logger>
logger.info = jest.fn()
logger.warn = jest.fn()
})
it('should mark subscription reactivated activity for analytics', async () => {
@@ -67,12 +43,4 @@ describe('SubscriptionReactivatedEventHandler', () => {
Period.ThisMonth,
])
})
it('should not do anything if no user is found for specified email', async () => {
userRepository.findOneByEmail = jest.fn().mockReturnValue(null)
await createHandler().handle(event)
expect(analyticsStore.markActivity).not.toHaveBeenCalled()
})
})

View File

@@ -1,30 +1,21 @@
import { AnalyticsActivity, AnalyticsStoreInterface, Period } from '@standardnotes/analytics'
import { DomainEventHandlerInterface, SubscriptionReactivatedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { Period } from '../Time/Period'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
@injectable()
export class SubscriptionReactivatedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.UserRepository) private userRepository: UserRepositoryInterface,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
@inject(TYPES.Logger) private logger: Logger,
) {}
async handle(event: SubscriptionReactivatedEvent): Promise<void> {
const user = await this.userRepository.findOneByEmail(event.payload.userEmail)
if (user === null) {
this.logger.warn(`Could not find user with email: ${event.payload.userEmail}`)
return
}
const { analyticsId } = await this.getUserAnalyticsId.execute({ userUuid: user.uuid })
const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionReactivated], analyticsId, [
Period.Today,
Period.ThisWeek,

View File

@@ -0,0 +1,110 @@
import 'reflect-metadata'
import { SubscriptionName } from '@standardnotes/common'
import { SubscriptionRefundedEvent } from '@standardnotes/domain-events'
import { Result } from '@standardnotes/domain-core'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { SubscriptionRefundedEventHandler } from './SubscriptionRefundedEventHandler'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { Period } from '../Time/Period'
import { RevenueModification } from '../Revenue/RevenueModification'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { Logger } from 'winston'
describe('SubscriptionRefundedEventHandler', () => {
let event: SubscriptionRefundedEvent
let getUserAnalyticsId: GetUserAnalyticsId
let analyticsStore: AnalyticsStoreInterface
let statisticsStore: StatisticsStoreInterface
let saveRevenueModification: SaveRevenueModification
let logger: Logger
const createHandler = () =>
new SubscriptionRefundedEventHandler(
getUserAnalyticsId,
analyticsStore,
statisticsStore,
saveRevenueModification,
logger,
)
beforeEach(() => {
logger = {} as jest.Mocked<Logger>
logger.error = jest.fn()
event = {} as jest.Mocked<SubscriptionRefundedEvent>
event.createdAt = new Date(1)
event.type = 'SUBSCRIPTION_REFUNDED'
event.payload = {
subscriptionId: 1,
userEmail: 'test@test.com',
subscriptionName: SubscriptionName.PlusPlan,
timestamp: 1,
offline: false,
userExistingSubscriptionsCount: 3,
totalActiveSubscriptionsCount: 1,
billingFrequency: 1,
payAmount: 12.99,
}
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
getUserAnalyticsId.execute = jest.fn().mockReturnValue({ analyticsId: 3 })
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
analyticsStore.markActivity = jest.fn()
analyticsStore.wasActivityDone = jest.fn().mockReturnValue(true)
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
statisticsStore.setMeasure = jest.fn()
saveRevenueModification = {} as jest.Mocked<SaveRevenueModification>
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.ok<RevenueModification>())
})
it('should mark churn for new customer', async () => {
event.payload.userExistingSubscriptionsCount = 1
await createHandler().handle(event)
expect(analyticsStore.markActivity).toHaveBeenCalledWith([AnalyticsActivity.SubscriptionRefunded], 3, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
expect(analyticsStore.markActivity).toHaveBeenCalledWith([AnalyticsActivity.NewCustomersChurn], 3, [
Period.ThisMonth,
])
expect(saveRevenueModification.execute).toHaveBeenCalled()
})
it('should mark churn for existing customer', async () => {
await createHandler().handle(event)
expect(analyticsStore.markActivity).toHaveBeenCalledWith([AnalyticsActivity.ExistingCustomersChurn], 3, [
Period.ThisMonth,
])
})
it('should not mark churn if customer did not purchase subscription in defined analytic periods', async () => {
analyticsStore.wasActivityDone = jest.fn().mockReturnValue(false)
await createHandler().handle(event)
expect(analyticsStore.markActivity).not.toHaveBeenCalledWith([AnalyticsActivity.ExistingCustomersChurn], 3, [
Period.ThisMonth,
])
})
it('should log failure to save revenue modification', async () => {
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.fail('Oops'))
await createHandler().handle(event)
expect(logger.error).toHaveBeenCalled()
})
})

View File

@@ -0,0 +1,78 @@
import { DomainEventHandlerInterface, SubscriptionRefundedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
import { Period } from '../Time/Period'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
@injectable()
export class SubscriptionRefundedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
@inject(TYPES.Logger) private logger: Logger,
) {}
async handle(event: SubscriptionRefundedEvent): Promise<void> {
const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionRefunded], analyticsId, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
await this.markChurnActivity(analyticsId, event)
const result = await this.saveRevenueModification.execute({
billingFrequency: event.payload.billingFrequency,
eventType: SubscriptionEventType.create(event.type).getValue(),
newSubscriber: event.payload.userExistingSubscriptionsCount === 1,
payedAmount: event.payload.payAmount,
planName: SubscriptionPlanName.create(event.payload.subscriptionName).getValue(),
subscriptionId: event.payload.subscriptionId,
userEmail: Email.create(event.payload.userEmail).getValue(),
userUuid,
})
if (result.isFailed()) {
this.logger.error(
`[${event.type}][${event.payload.subscriptionId}] Could not save revenue modification: ${result.getError()}`,
)
}
}
private async markChurnActivity(analyticsId: number, event: SubscriptionRefundedEvent): Promise<void> {
const churnActivity =
event.payload.userExistingSubscriptionsCount > 1
? AnalyticsActivity.ExistingCustomersChurn
: AnalyticsActivity.NewCustomersChurn
for (const period of [Period.ThisMonth, Period.ThisWeek, Period.Today]) {
const customerPurchasedInPeriod = await this.analyticsStore.wasActivityDone(
AnalyticsActivity.SubscriptionPurchased,
analyticsId,
period,
)
if (customerPurchasedInPeriod) {
await this.analyticsStore.markActivity([churnActivity], analyticsId, [period])
}
}
await this.statisticsStore.setMeasure(
StatisticsMeasure.TotalCustomers,
event.payload.totalActiveSubscriptionsCount,
[Period.Today, Period.ThisWeek, Period.ThisMonth, Period.ThisYear],
)
}
}

View File

@@ -0,0 +1,68 @@
import 'reflect-metadata'
import { SubscriptionName } from '@standardnotes/common'
import { SubscriptionRenewedEvent } from '@standardnotes/domain-events'
import { Result } from '@standardnotes/domain-core'
import { SubscriptionRenewedEventHandler } from './SubscriptionRenewedEventHandler'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { RevenueModification } from '../Revenue/RevenueModification'
import { Logger } from 'winston'
describe('SubscriptionRenewedEventHandler', () => {
let event: SubscriptionRenewedEvent
let getUserAnalyticsId: GetUserAnalyticsId
let analyticsStore: AnalyticsStoreInterface
let saveRevenueModification: SaveRevenueModification
let logger: Logger
const createHandler = () =>
new SubscriptionRenewedEventHandler(getUserAnalyticsId, analyticsStore, saveRevenueModification, logger)
beforeEach(() => {
logger = {} as jest.Mocked<Logger>
logger.error = jest.fn()
event = {} as jest.Mocked<SubscriptionRenewedEvent>
event.createdAt = new Date(1)
event.type = 'SUBSCRIPTION_RENEWED'
event.payload = {
subscriptionId: 1,
userEmail: 'test@test.com',
subscriptionName: SubscriptionName.ProPlan,
subscriptionExpiresAt: 2,
timestamp: 1,
offline: false,
billingFrequency: 1,
payAmount: 12.99,
}
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
getUserAnalyticsId.execute = jest.fn().mockReturnValue({ analyticsId: 3 })
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
analyticsStore.markActivity = jest.fn()
analyticsStore.unmarkActivity = jest.fn()
saveRevenueModification = {} as jest.Mocked<SaveRevenueModification>
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.ok<RevenueModification>())
})
it('should track subscription renewed statistics', async () => {
await createHandler().handle(event)
expect(analyticsStore.markActivity).toHaveBeenCalled()
expect(analyticsStore.unmarkActivity).toHaveBeenCalled()
expect(saveRevenueModification.execute).toHaveBeenCalled()
})
it('should log failure to save revenue modification', async () => {
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.fail('Oops'))
await createHandler().handle(event)
expect(logger.error).toHaveBeenCalled()
})
})

View File

@@ -0,0 +1,54 @@
import { DomainEventHandlerInterface, SubscriptionRenewedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { Period } from '../Time/Period'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
import { Logger } from 'winston'
@injectable()
export class SubscriptionRenewedEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
@inject(TYPES.Logger) private logger: Logger,
) {}
async handle(event: SubscriptionRenewedEvent): Promise<void> {
const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionRenewed], analyticsId, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
await this.analyticsStore.unmarkActivity(
[AnalyticsActivity.ExistingCustomersChurn, AnalyticsActivity.NewCustomersChurn],
analyticsId,
[Period.Today, Period.ThisWeek, Period.ThisMonth],
)
const result = await this.saveRevenueModification.execute({
billingFrequency: event.payload.billingFrequency,
eventType: SubscriptionEventType.create(event.type).getValue(),
newSubscriber: false,
payedAmount: event.payload.payAmount,
planName: SubscriptionPlanName.create(event.payload.subscriptionName).getValue(),
subscriptionId: event.payload.subscriptionId,
userEmail: Email.create(event.payload.userEmail).getValue(),
userUuid,
})
if (result.isFailed()) {
this.logger.error(
`[${event.type}][${event.payload.subscriptionId}] Could not save revenue modification: ${result.getError()}`,
)
}
}
}

View File

@@ -0,0 +1,47 @@
import 'reflect-metadata'
import { UserRegisteredEvent } from '@standardnotes/domain-events'
import { ProtocolVersion } from '@standardnotes/common'
import { UserRegisteredEventHandler } from './UserRegisteredEventHandler'
import { AnalyticsEntityRepositoryInterface } from '../Entity/AnalyticsEntityRepositoryInterface'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { Period } from '../Time/Period'
describe('UserRegisteredEventHandler', () => {
let analyticsEntityRepository: AnalyticsEntityRepositoryInterface
let event: UserRegisteredEvent
let analyticsStore: AnalyticsStoreInterface
const createHandler = () => new UserRegisteredEventHandler(analyticsEntityRepository, analyticsStore)
beforeEach(() => {
event = {} as jest.Mocked<UserRegisteredEvent>
event.createdAt = new Date(1)
event.payload = {
userUuid: '1-2-3',
email: 'test@test.te',
protocolVersion: ProtocolVersion.V004,
}
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
analyticsStore.markActivity = jest.fn()
analyticsEntityRepository = {} as jest.Mocked<AnalyticsEntityRepositoryInterface>
analyticsEntityRepository.save = jest.fn().mockImplementation((entity) => ({
...entity,
id: 1,
}))
})
it('should save analytics entity upon user registration', async () => {
await createHandler().handle(event)
expect(analyticsEntityRepository.save).toHaveBeenCalled()
expect(analyticsStore.markActivity).toHaveBeenCalledWith(['register'], 1, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
})
})

View File

@@ -0,0 +1,30 @@
import { DomainEventHandlerInterface, UserRegisteredEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { AnalyticsEntity } from '../Entity/AnalyticsEntity'
import { AnalyticsEntityRepositoryInterface } from '../Entity/AnalyticsEntityRepositoryInterface'
import { Period } from '../Time/Period'
@injectable()
export class UserRegisteredEventHandler implements DomainEventHandlerInterface {
constructor(
@inject(TYPES.AnalyticsEntityRepository) private analyticsEntityRepository: AnalyticsEntityRepositoryInterface,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
) {}
async handle(event: UserRegisteredEvent): Promise<void> {
let analyticsEntity = new AnalyticsEntity()
analyticsEntity.userUuid = event.payload.userUuid
analyticsEntity.userEmail = event.payload.email
analyticsEntity = await this.analyticsEntityRepository.save(analyticsEntity)
await this.analyticsStore.markActivity([AnalyticsActivity.Register], analyticsEntity.id, [
Period.Today,
Period.ThisWeek,
Period.ThisMonth,
])
}
}

View File

@@ -0,0 +1,79 @@
import { injectable } from 'inversify'
import { Email, MapInterface, UniqueEntityId } from '@standardnotes/domain-core'
import { TypeORMRevenueModification } from '../../Infra/TypeORM/TypeORMRevenueModification'
import { MonthlyRevenue } from '../Revenue/MonthlyRevenue'
import { RevenueModification } from '../Revenue/RevenueModification'
import { Subscription } from '../Subscription/Subscription'
import { User } from '../User/User'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
@injectable()
export class RevenueModificationMap implements MapInterface<RevenueModification, TypeORMRevenueModification> {
toDomain(persistence: TypeORMRevenueModification): RevenueModification {
const userOrError = User.create(
{
email: Email.create(persistence.userEmail).getValue(),
},
new UniqueEntityId(persistence.userUuid),
)
if (userOrError.isFailed()) {
throw new Error(`Could not create user: ${userOrError.getError()}`)
}
const user = userOrError.getValue()
const subscriptionOrError = Subscription.create(
{
billingFrequency: persistence.billingFrequency,
isFirstSubscriptionForUser: persistence.isNewCustomer,
payedAmount: persistence.billingFrequency * persistence.newMonthlyRevenue,
planName: SubscriptionPlanName.create(persistence.subscriptionPlan).getValue(),
},
new UniqueEntityId(persistence.subscriptionId),
)
if (subscriptionOrError.isFailed()) {
throw new Error(`Could not create subscription: ${subscriptionOrError.getError()}`)
}
const subscription = subscriptionOrError.getValue()
const previousMonthlyRevenueOrError = MonthlyRevenue.create(persistence.previousMonthlyRevenue)
const newMonthlyRevenueOrError = MonthlyRevenue.create(persistence.newMonthlyRevenue)
const revenuModificationOrError = RevenueModification.create(
{
user,
subscription,
eventType: SubscriptionEventType.create(persistence.eventType).getValue(),
previousMonthlyRevenue: previousMonthlyRevenueOrError.getValue(),
newMonthlyRevenue: newMonthlyRevenueOrError.getValue(),
createdAt: persistence.createdAt,
},
new UniqueEntityId(persistence.uuid),
)
if (revenuModificationOrError.isFailed()) {
throw new Error(`Could not map revenue modification to domain: ${revenuModificationOrError.getError()}`)
}
return revenuModificationOrError.getValue()
}
toProjection(domain: RevenueModification): TypeORMRevenueModification {
const { subscription, user } = domain.props
const persistence = new TypeORMRevenueModification()
persistence.uuid = domain.id.toString()
persistence.billingFrequency = subscription.props.billingFrequency
persistence.eventType = domain.props.eventType.value
persistence.isNewCustomer = subscription.props.isFirstSubscriptionForUser
persistence.newMonthlyRevenue = domain.props.newMonthlyRevenue.value
persistence.previousMonthlyRevenue = domain.props.previousMonthlyRevenue.value
persistence.subscriptionId = subscription.id.toValue() as number
persistence.subscriptionPlan = subscription.props.planName.value
persistence.userEmail = user.props.email.value
persistence.userUuid = user.id.toString()
persistence.createdAt = domain.props.createdAt
return persistence
}
}

View File

@@ -0,0 +1,16 @@
import { MonthlyRevenue } from './MonthlyRevenue'
describe('MonthlyRevenue', () => {
it('should create a value object', () => {
const valueOrError = MonthlyRevenue.create(123)
expect(valueOrError.isFailed()).toBeFalsy()
expect(valueOrError.getValue().value).toEqual(123)
})
it('should not create an invalid value object', () => {
const valueOrError = MonthlyRevenue.create(-3)
expect(valueOrError.isFailed()).toBeTruthy()
})
})

View File

@@ -0,0 +1,21 @@
import { Result, ValueObject } from '@standardnotes/domain-core'
import { MonthlyRevenueProps } from './MonthlyRevenueProps'
export class MonthlyRevenue extends ValueObject<MonthlyRevenueProps> {
get value(): number {
return this.props.value
}
private constructor(props: MonthlyRevenueProps) {
super(props)
}
static create(revenue: number): Result<MonthlyRevenue> {
if (isNaN(revenue) || revenue < 0) {
return Result.fail<MonthlyRevenue>(`Monthly revenue must be a non-negative number. Supplied: ${revenue}`)
} else {
return Result.ok<MonthlyRevenue>(new MonthlyRevenue({ value: revenue }))
}
}
}

View File

@@ -0,0 +1,3 @@
export interface MonthlyRevenueProps {
value: number
}

View File

@@ -0,0 +1,39 @@
import { Email } from '@standardnotes/domain-core'
import { Subscription } from '../Subscription/Subscription'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
import { User } from '../User/User'
import { MonthlyRevenue } from './MonthlyRevenue'
import { RevenueModification } from './RevenueModification'
describe('RevenueModification', () => {
let user: User
let subscription: Subscription
beforeEach(() => {
subscription = Subscription.create({
billingFrequency: 12,
isFirstSubscriptionForUser: true,
payedAmount: 123,
planName: SubscriptionPlanName.create('PRO_PLAN').getValue(),
}).getValue()
user = User.create({
email: Email.create('test@test.te').getValue(),
}).getValue()
})
it('should create an aggregate for purchased subscription', () => {
const revenueModification = RevenueModification.create({
createdAt: 2,
eventType: SubscriptionEventType.create('SUBSCRIPTION_PURCHASED').getValue(),
previousMonthlyRevenue: MonthlyRevenue.create(123).getValue(),
newMonthlyRevenue: MonthlyRevenue.create(45).getValue(),
subscription,
user,
}).getValue()
expect(revenueModification.id.toString()).toHaveLength(36)
expect(revenueModification.props.newMonthlyRevenue.value).toEqual(45)
})
})

View File

@@ -0,0 +1,13 @@
import { Aggregate, UniqueEntityId, Result } from '@standardnotes/domain-core'
import { RevenueModificationProps } from './RevenueModificationProps'
export class RevenueModification extends Aggregate<RevenueModificationProps> {
private constructor(props: RevenueModificationProps, id?: UniqueEntityId) {
super(props, id)
}
static create(props: RevenueModificationProps, id?: UniqueEntityId): Result<RevenueModification> {
return Result.ok<RevenueModification>(new RevenueModification(props, id))
}
}

View File

@@ -0,0 +1,13 @@
import { MonthlyRevenue } from './MonthlyRevenue'
import { Subscription } from '../Subscription/Subscription'
import { User } from '../User/User'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
export interface RevenueModificationProps {
user: User
subscription: Subscription
eventType: SubscriptionEventType
previousMonthlyRevenue: MonthlyRevenue
newMonthlyRevenue: MonthlyRevenue
createdAt: number
}

View File

@@ -0,0 +1,9 @@
import { Uuid } from '@standardnotes/domain-core'
import { RevenueModification } from './RevenueModification'
export interface RevenueModificationRepositoryInterface {
findLastByUserUuid(userUuid: Uuid): Promise<RevenueModification | null>
sumMRRDiff(dto: { planName?: string; billingFrequency?: number }): Promise<number>
save(revenueModification: RevenueModification): Promise<RevenueModification>
}

View File

@@ -13,9 +13,12 @@ export enum StatisticsMeasure {
RegistrationToSubscriptionTime = 'registration-to-subscription-time',
RemainingSubscriptionTimePercentage = 'remaining-subscription-time-percentage',
Refunds = 'refunds',
NotesCountFreeUsers = 'notes-count-free-users',
NotesCountPaidUsers = 'notes-count-paid-users',
FilesCount = 'files-count',
NewCustomers = 'new-customers',
TotalCustomers = 'total-customers',
MRR = 'mrr',
MonthlyPlansMRR = 'monthly-plans-mrr',
AnnualPlansMRR = 'annual-plans-mrr',
FiveYearPlansMRR = 'five-year-plans-mrr',
ProPlansMRR = 'pro-plans-mrr',
PlusPlansMRR = 'plus-plans-mrr',
}

View File

@@ -13,4 +13,8 @@ export interface StatisticsStoreInterface {
getMeasureAverage(measure: StatisticsMeasure, period: Period): Promise<number>
getMeasureTotal(measure: StatisticsMeasure, periodOrPeriodKey: Period | string): Promise<number>
getMeasureIncrementCounts(measure: StatisticsMeasure, period: Period): Promise<number>
calculateTotalCountOverPeriod(
measure: StatisticsMeasure,
period: Period,
): Promise<Array<{ periodKey: string; totalCount: number }>>
}

View File

@@ -0,0 +1,15 @@
import { Subscription } from './Subscription'
import { SubscriptionPlanName } from './SubscriptionPlanName'
describe('Subscription', () => {
it('should create an entity', () => {
const subscription = Subscription.create({
billingFrequency: 1,
isFirstSubscriptionForUser: true,
payedAmount: 12.99,
planName: SubscriptionPlanName.create('PRO_PLAN').getValue(),
}).getValue()
expect(subscription.id.toString()).toHaveLength(36)
})
})

View File

@@ -0,0 +1,17 @@
import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { SubscriptionProps } from './SubscriptionProps'
export class Subscription extends Entity<SubscriptionProps> {
get id(): UniqueEntityId {
return this._id
}
private constructor(props: SubscriptionProps, id?: UniqueEntityId) {
super(props, id)
}
static create(props: SubscriptionProps, id?: UniqueEntityId): Result<Subscription> {
return Result.ok<Subscription>(new Subscription(props, id))
}
}

View File

@@ -0,0 +1,16 @@
import { SubscriptionEventType } from './SubscriptionEventType'
describe('SubscriptionEventType', () => {
it('should create a value object', () => {
const valueOrError = SubscriptionEventType.create('SUBSCRIPTION_PURCHASED')
expect(valueOrError.isFailed()).toBeFalsy()
expect(valueOrError.getValue().value).toEqual('SUBSCRIPTION_PURCHASED')
})
it('should not create an invalid value object', () => {
const valueOrError = SubscriptionEventType.create('SUBSCRIPTION_REACTIVATED')
expect(valueOrError.isFailed()).toBeTruthy()
})
})

View File

@@ -0,0 +1,30 @@
import { ValueObject, Result } from '@standardnotes/domain-core'
import { SubscriptionEventTypeProps } from './SubscriptionEventTypeProps'
export class SubscriptionEventType extends ValueObject<SubscriptionEventTypeProps> {
get value(): string {
return this.props.value
}
private constructor(props: SubscriptionEventTypeProps) {
super(props)
}
static create(subscriptionEventType: string): Result<SubscriptionEventType> {
if (
![
'SUBSCRIPTION_PURCHASED',
'SUBSCRIPTION_RENEWED',
'SUBSCRIPTION_EXPIRED',
'SUBSCRIPTION_REFUNDED',
'SUBSCRIPTION_CANCELLED',
'SUBSCRIPTION_DATA_MIGRATED',
].includes(subscriptionEventType)
) {
return Result.fail<SubscriptionEventType>(`Invalid subscription event type ${subscriptionEventType}`)
} else {
return Result.ok<SubscriptionEventType>(new SubscriptionEventType({ value: subscriptionEventType }))
}
}
}

View File

@@ -0,0 +1,3 @@
export interface SubscriptionEventTypeProps {
value: string
}

View File

@@ -0,0 +1,16 @@
import { SubscriptionPlanName } from './SubscriptionPlanName'
describe('SubscriptionPlanName', () => {
it('should create a value object', () => {
const valueOrError = SubscriptionPlanName.create('PRO_PLAN')
expect(valueOrError.isFailed()).toBeFalsy()
expect(valueOrError.getValue().value).toEqual('PRO_PLAN')
})
it('should not create an invalid value object', () => {
const valueOrError = SubscriptionPlanName.create('TEST')
expect(valueOrError.isFailed()).toBeTruthy()
})
})

View File

@@ -0,0 +1,21 @@
import { Result, ValueObject } from '@standardnotes/domain-core'
import { SubscriptionPlanNameProps } from './SubscriptionPlanNameProps'
export class SubscriptionPlanName extends ValueObject<SubscriptionPlanNameProps> {
get value(): string {
return this.props.value
}
private constructor(props: SubscriptionPlanNameProps) {
super(props)
}
static create(subscriptionPlanName: string): Result<SubscriptionPlanName> {
if (!['PRO_PLAN', 'PLUS_PLAN'].includes(subscriptionPlanName)) {
return Result.fail<SubscriptionPlanName>(`Invalid subscription plan name ${subscriptionPlanName}`)
} else {
return Result.ok<SubscriptionPlanName>(new SubscriptionPlanName({ value: subscriptionPlanName }))
}
}
}

View File

@@ -0,0 +1,3 @@
export interface SubscriptionPlanNameProps {
value: string
}

View File

@@ -0,0 +1,8 @@
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
export interface SubscriptionProps {
planName: SubscriptionPlanName
isFirstSubscriptionForUser: boolean
payedAmount: number
billingFrequency: number
}

View File

@@ -26,4 +26,5 @@ export enum Period {
OctoberThisYear,
NovemberThisYear,
DecemberThisYear,
Last30DaysIncludingToday,
}

View File

@@ -62,6 +62,41 @@ describe('PeriodKeyGenerator', () => {
])
})
it('should generate period keys for last 30 days including Today', () => {
expect(createGenerator().getDiscretePeriodKeys(Period.Last30DaysIncludingToday)).toEqual([
'2022-4-25',
'2022-4-26',
'2022-4-27',
'2022-4-28',
'2022-4-29',
'2022-4-30',
'2022-5-1',
'2022-5-2',
'2022-5-3',
'2022-5-4',
'2022-5-5',
'2022-5-6',
'2022-5-7',
'2022-5-8',
'2022-5-9',
'2022-5-10',
'2022-5-11',
'2022-5-12',
'2022-5-13',
'2022-5-14',
'2022-5-15',
'2022-5-16',
'2022-5-17',
'2022-5-18',
'2022-5-19',
'2022-5-20',
'2022-5-21',
'2022-5-22',
'2022-5-23',
'2022-5-24',
])
})
it('should generate period keys for this year', () => {
expect(createGenerator().getDiscretePeriodKeys(Period.ThisYear)).toEqual([
'2022-1',

View File

@@ -33,6 +33,12 @@ export class PeriodKeyGenerator implements PeriodKeyGeneratorInterface {
periodKeys.unshift(this.getDailyKey(this.getDateNDaysBefore(i)))
}
return periodKeys
case Period.Last30DaysIncludingToday:
for (let i = 0; i <= 29; i++) {
periodKeys.unshift(this.getDailyKey(this.getDateNDaysBefore(i)))
}
return periodKeys
case Period.Last7Days:
for (let i = 1; i <= 7; i++) {

Some files were not shown because too many files have changed in this diff Show More