Compare commits

..

69 Commits

Author SHA1 Message Date
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
182 changed files with 2841 additions and 1689 deletions
+1 -1
View File
@@ -1 +1 @@
16.15.1 18.12.1
Generated
+201 -160
View File
@@ -29,6 +29,10 @@ const RAW_RUNTIME_STATE =
"name": "@standardnotes/common",\ "name": "@standardnotes/common",\
"reference": "workspace:packages/common"\ "reference": "workspace:packages/common"\
},\ },\
{\
"name": "@standardnotes/domain-core",\
"reference": "workspace:packages/domain-core"\
},\
{\ {\
"name": "@standardnotes/domain-events",\ "name": "@standardnotes/domain-events",\
"reference": "workspace:packages/domain-events"\ "reference": "workspace:packages/domain-events"\
@@ -89,6 +93,7 @@ const RAW_RUNTIME_STATE =
["@standardnotes/api-gateway", ["workspace:packages/api-gateway"]],\ ["@standardnotes/api-gateway", ["workspace:packages/api-gateway"]],\
["@standardnotes/auth-server", ["workspace:packages/auth"]],\ ["@standardnotes/auth-server", ["workspace:packages/auth"]],\
["@standardnotes/common", ["workspace:packages/common"]],\ ["@standardnotes/common", ["workspace:packages/common"]],\
["@standardnotes/domain-core", ["workspace:packages/domain-core"]],\
["@standardnotes/domain-events", ["workspace:packages/domain-events"]],\ ["@standardnotes/domain-events", ["workspace:packages/domain-events"]],\
["@standardnotes/domain-events-infra", ["workspace:packages/domain-events-infra"]],\ ["@standardnotes/domain-events-infra", ["workspace:packages/domain-events-infra"]],\
["@standardnotes/event-store", ["workspace:packages/event-store"]],\ ["@standardnotes/event-store", ["workspace:packages/event-store"]],\
@@ -116,15 +121,16 @@ const RAW_RUNTIME_STATE =
["@lerna-lite/cli", "npm:1.6.0"],\ ["@lerna-lite/cli", "npm:1.6.0"],\
["@lerna-lite/list", "npm:1.6.0"],\ ["@lerna-lite/list", "npm:1.6.0"],\
["@lerna-lite/run", "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/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\ ["@types/newrelic", "npm:7.0.4"],\
["@types/node", "npm:18.0.3"],\ ["@types/node", "npm:18.11.9"],\
["@typescript-eslint/parser", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:5.40.1"],\ ["@typescript-eslint/parser", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:5.40.1"],\
["eslint", "npm:8.19.0"],\ ["eslint", "npm:8.19.0"],\
["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.5.0"],\ ["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.5.0"],\
["ini", "npm:3.0.0"],\ ["ini", "npm:3.0.0"],\
["newrelic", "npm:9.0.0"],\ ["newrelic", "npm:9.6.0"],\
["npm-check-updates", "npm:16.0.1"],\ ["npm-check-updates", "npm:16.0.1"],\
["prettier", "npm:2.7.1"],\ ["prettier", "npm:2.7.1"],\
["ts-node", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:10.9.1"],\ ["ts-node", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:10.9.1"],\
@@ -1865,12 +1871,12 @@ const RAW_RUNTIME_STATE =
],\ ],\
"linkType": "SOFT"\ "linkType": "SOFT"\
}],\ }],\
["virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:5.0.0", {\ ["virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#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/",\ "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": [\ "packageDependencies": [\
["@newrelic/aws-sdk", "virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:5.0.0"],\ ["@newrelic/aws-sdk", "virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:5.0.0"],\
["@types/newrelic", null],\ ["@types/newrelic", null],\
["newrelic", "npm:9.0.0"]\ ["newrelic", "npm:9.6.0"]\
],\ ],\
"packagePeers": [\ "packagePeers": [\
"@types/newrelic",\ "@types/newrelic",\
@@ -1887,12 +1893,12 @@ const RAW_RUNTIME_STATE =
],\ ],\
"linkType": "SOFT"\ "linkType": "SOFT"\
}],\ }],\
["virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:7.0.0", {\ ["virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#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/",\ "packageLocation": "./.yarn/__virtual__/@newrelic-koa-virtual-613d84b4f1/0/cache/@newrelic-koa-npm-7.0.0-903c251b9f-0fc2298c8b.zip/node_modules/@newrelic/koa/",\
"packageDependencies": [\ "packageDependencies": [\
["@newrelic/koa", "virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:7.0.0"],\ ["@newrelic/koa", "virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:7.0.0"],\
["@types/newrelic", null],\ ["@types/newrelic", null],\
["newrelic", "npm:9.0.0"]\ ["newrelic", "npm:9.6.0"]\
],\ ],\
"packagePeers": [\ "packagePeers": [\
"@types/newrelic",\ "@types/newrelic",\
@@ -1922,12 +1928,12 @@ const RAW_RUNTIME_STATE =
],\ ],\
"linkType": "SOFT"\ "linkType": "SOFT"\
}],\ }],\
["virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:6.0.0", {\ ["virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#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/",\ "packageLocation": "./.yarn/__virtual__/@newrelic-superagent-virtual-37eb7b41a0/0/cache/@newrelic-superagent-npm-6.0.0-db8b77d0f3-b77997b792.zip/node_modules/@newrelic/superagent/",\
"packageDependencies": [\ "packageDependencies": [\
["@newrelic/superagent", "virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:6.0.0"],\ ["@newrelic/superagent", "virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:6.0.0"],\
["@types/newrelic", null],\ ["@types/newrelic", null],\
["newrelic", "npm:9.0.0"]\ ["newrelic", "npm:9.6.0"]\
],\ ],\
"packagePeers": [\ "packagePeers": [\
"@types/newrelic",\ "@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/",\ "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": [\ "packageDependencies": [\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\ ["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@types/newrelic", "npm:7.0.3"],\ ["@types/newrelic", "npm:7.0.4"],\
["newrelic", "npm:9.0.0"]\ ["newrelic", "npm:9.6.0"]\
],\ ],\
"packagePeers": [\ "packagePeers": [\
"@types/newrelic",\ "@types/newrelic",\
@@ -2428,39 +2434,25 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["@sentry/core", [\ ["@sentry/core", [\
["npm:7.5.0", {\ ["npm:7.19.0", {\
"packageLocation": "./.yarn/cache/@sentry-core-npm-7.5.0-984c871a50-99c8e93a6f.zip/node_modules/@sentry/core/",\ "packageLocation": "./.yarn/cache/@sentry-core-npm-7.19.0-151e6173ac-cabd7852ff.zip/node_modules/@sentry/core/",\
"packageDependencies": [\ "packageDependencies": [\
["@sentry/core", "npm:7.5.0"],\ ["@sentry/core", "npm:7.19.0"],\
["@sentry/hub", "npm:7.5.0"],\ ["@sentry/types", "npm:7.19.0"],\
["@sentry/types", "npm:7.5.0"],\ ["@sentry/utils", "npm:7.19.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"],\
["tslib", "npm:1.14.1"]\ ["tslib", "npm:1.14.1"]\
],\ ],\
"linkType": "HARD"\ "linkType": "HARD"\
}]\ }]\
]],\ ]],\
["@sentry/node", [\ ["@sentry/node", [\
["npm:7.5.0", {\ ["npm:7.19.0", {\
"packageLocation": "./.yarn/cache/@sentry-node-npm-7.5.0-a14989f161-9b65bc44d2.zip/node_modules/@sentry/node/",\ "packageLocation": "./.yarn/cache/@sentry-node-npm-7.19.0-fd3d8dbde1-3a69647d2e.zip/node_modules/@sentry/node/",\
"packageDependencies": [\ "packageDependencies": [\
["@sentry/node", "npm:7.5.0"],\ ["@sentry/node", "npm:7.19.0"],\
["@sentry/core", "npm:7.5.0"],\ ["@sentry/core", "npm:7.19.0"],\
["@sentry/hub", "npm:7.5.0"],\ ["@sentry/types", "npm:7.19.0"],\
["@sentry/types", "npm:7.5.0"],\ ["@sentry/utils", "npm:7.19.0"],\
["@sentry/utils", "npm:7.5.0"],\
["cookie", "npm:0.4.2"],\ ["cookie", "npm:0.4.2"],\
["https-proxy-agent", "npm:5.0.1"],\ ["https-proxy-agent", "npm:5.0.1"],\
["lru_map", "npm:0.3.3"],\ ["lru_map", "npm:0.3.3"],\
@@ -2470,20 +2462,20 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["@sentry/types", [\ ["@sentry/types", [\
["npm:7.5.0", {\ ["npm:7.19.0", {\
"packageLocation": "./.yarn/cache/@sentry-types-npm-7.5.0-eea3d326fa-8029b56bae.zip/node_modules/@sentry/types/",\ "packageLocation": "./.yarn/cache/@sentry-types-npm-7.19.0-d6ed1960f2-541e1ef49a.zip/node_modules/@sentry/types/",\
"packageDependencies": [\ "packageDependencies": [\
["@sentry/types", "npm:7.5.0"]\ ["@sentry/types", "npm:7.19.0"]\
],\ ],\
"linkType": "HARD"\ "linkType": "HARD"\
}]\ }]\
]],\ ]],\
["@sentry/utils", [\ ["@sentry/utils", [\
["npm:7.5.0", {\ ["npm:7.19.0", {\
"packageLocation": "./.yarn/cache/@sentry-utils-npm-7.5.0-e8c66594bc-f5045667ea.zip/node_modules/@sentry/utils/",\ "packageLocation": "./.yarn/cache/@sentry-utils-npm-7.19.0-79844d4d90-50e4f391fe.zip/node_modules/@sentry/utils/",\
"packageDependencies": [\ "packageDependencies": [\
["@sentry/utils", "npm:7.5.0"],\ ["@sentry/utils", "npm:7.19.0"],\
["@sentry/types", "npm:7.5.0"],\ ["@sentry/types", "npm:7.19.0"],\
["tslib", "npm:1.14.1"]\ ["tslib", "npm:1.14.1"]\
],\ ],\
"linkType": "HARD"\ "linkType": "HARD"\
@@ -2541,34 +2533,33 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/analytics/",\ "packageLocation": "./packages/analytics/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/analytics", "workspace:packages/analytics"],\ ["@standardnotes/analytics", "workspace:packages/analytics"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.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/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ ["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/time", "workspace:packages/time"],\ ["@standardnotes/time", "workspace:packages/time"],\
["@types/ioredis", "npm:4.28.10"],\ ["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.1.1"],\ ["@types/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\ ["@types/newrelic", "npm:7.0.4"],\
["@types/node", "npm:18.0.3"],\ ["@types/node", "npm:18.11.9"],\
["@types/uuid", "npm:8.3.4"],\
["@typescript-eslint/eslint-plugin", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:5.30.5"],\ ["@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"],\ ["dayjs", "npm:1.11.6"],\
["dotenv", "npm:16.0.1"],\ ["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\ ["eslint", "npm:8.25.0"],\
["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\ ["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\
["inversify", "npm:6.0.1"],\ ["inversify", "npm:6.0.1"],\
["ioredis", "npm:5.2.3"],\ ["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["mysql2", "npm:2.3.3"],\ ["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\ ["newrelic", "npm:9.6.0"],\
["reflect-metadata", "npm:0.1.13"],\ ["reflect-metadata", "npm:0.1.13"],\
["shallow-equal-object", "npm:1.1.1"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\ ["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\ ["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\
["typescript", "patch:typescript@npm%3A4.8.4#optional!builtin<compat/typescript>::version=4.8.4&hash=701156"],\ ["typescript", "patch:typescript@npm%3A4.8.4#optional!builtin<compat/typescript>::version=4.8.4&hash=701156"],\
["uuid", "npm:9.0.0"],\
["winston", "npm:3.8.2"]\ ["winston", "npm:3.8.2"]\
],\ ],\
"linkType": "SOFT"\ "linkType": "SOFT"\
@@ -2595,8 +2586,9 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/api-gateway/",\ "packageLocation": "./packages/api-gateway/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/api-gateway", "workspace:packages/api-gateway"],\ ["@standardnotes/api-gateway", "workspace:packages/api-gateway"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.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/common", "workspace:packages/common"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ ["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
@@ -2604,14 +2596,14 @@ const RAW_RUNTIME_STATE =
["@standardnotes/time", "workspace:packages/time"],\ ["@standardnotes/time", "workspace:packages/time"],\
["@types/cors", "npm:2.8.12"],\ ["@types/cors", "npm:2.8.12"],\
["@types/express", "npm:4.17.14"],\ ["@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/jest", "npm:29.1.1"],\
["@types/jsonwebtoken", "npm:8.5.9"],\ ["@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/prettyjson", "npm:0.0.30"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\ ["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\
["aws-sdk", "npm:2.1234.0"],\ ["aws-sdk", "npm:2.1253.0"],\
["axios", "npm:0.27.2"],\ ["axios", "npm:1.1.3"],\
["cors", "npm:2.8.5"],\ ["cors", "npm:2.8.5"],\
["dotenv", "npm:16.0.1"],\ ["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\ ["eslint", "npm:8.25.0"],\
@@ -2620,10 +2612,10 @@ const RAW_RUNTIME_STATE =
["helmet", "npm:6.0.0"],\ ["helmet", "npm:6.0.0"],\
["inversify", "npm:6.0.1"],\ ["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\ ["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.2.3"],\ ["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["jsonwebtoken", "npm:8.5.1"],\ ["jsonwebtoken", "npm:8.5.1"],\
["newrelic", "npm:9.0.0"],\ ["newrelic", "npm:9.6.0"],\
["nodemon", "npm:2.0.20"],\ ["nodemon", "npm:2.0.20"],\
["npm-check-updates", "npm:16.0.1"],\ ["npm-check-updates", "npm:16.0.1"],\
["prettyjson", "npm:1.2.5"],\ ["prettyjson", "npm:1.2.5"],\
@@ -2651,8 +2643,9 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/auth/",\ "packageLocation": "./packages/auth/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/auth-server", "workspace:packages/auth"],\ ["@standardnotes/auth-server", "workspace:packages/auth"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.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/api", "npm:1.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\ ["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
@@ -2668,16 +2661,16 @@ const RAW_RUNTIME_STATE =
["@types/bcryptjs", "npm:2.4.2"],\ ["@types/bcryptjs", "npm:2.4.2"],\
["@types/cors", "npm:2.8.12"],\ ["@types/cors", "npm:2.8.12"],\
["@types/express", "npm:4.17.14"],\ ["@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/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\ ["@types/newrelic", "npm:7.0.4"],\
["@types/otplib", "npm:10.0.0"],\ ["@types/otplib", "npm:10.0.0"],\
["@types/prettyjson", "npm:0.0.30"],\ ["@types/prettyjson", "npm:0.0.30"],\
["@types/ua-parser-js", "npm:0.7.36"],\ ["@types/ua-parser-js", "npm:0.7.36"],\
["@types/uuid", "npm:8.3.4"],\ ["@types/uuid", "npm:8.3.4"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\ ["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\
["aws-sdk", "npm:2.1234.0"],\ ["aws-sdk", "npm:2.1253.0"],\
["axios", "npm:0.27.2"],\ ["axios", "npm:1.1.3"],\
["bcryptjs", "npm:2.4.3"],\ ["bcryptjs", "npm:2.4.3"],\
["cors", "npm:2.8.5"],\ ["cors", "npm:2.8.5"],\
["dayjs", "npm:1.11.6"],\ ["dayjs", "npm:1.11.6"],\
@@ -2687,10 +2680,10 @@ const RAW_RUNTIME_STATE =
["express", "npm:4.18.2"],\ ["express", "npm:4.18.2"],\
["inversify", "npm:6.0.1"],\ ["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\ ["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.2.3"],\ ["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["mysql2", "npm:2.3.3"],\ ["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\ ["newrelic", "npm:9.6.0"],\
["nodemon", "npm:2.0.20"],\ ["nodemon", "npm:2.0.20"],\
["npm-check-updates", "npm:16.0.1"],\ ["npm-check-updates", "npm:16.0.1"],\
["otplib", "npm:12.0.1"],\ ["otplib", "npm:12.0.1"],\
@@ -2699,7 +2692,7 @@ const RAW_RUNTIME_STATE =
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\ ["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\ ["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\
["typescript", "patch:typescript@npm%3A4.8.4#optional!builtin<compat/typescript>::version=4.8.4&hash=701156"],\ ["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"],\ ["uuid", "npm:9.0.0"],\
["winston", "npm:3.8.2"]\ ["winston", "npm:3.8.2"]\
],\ ],\
@@ -2712,7 +2705,7 @@ const RAW_RUNTIME_STATE =
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/common", "workspace:packages/common"],\ ["@standardnotes/common", "workspace:packages/common"],\
["@types/jest", "npm:29.1.1"],\ ["@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"],\ ["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\
["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:4.2.1"],\ ["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:4.2.1"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
@@ -2737,6 +2730,29 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\ "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", [\ ["@standardnotes/domain-events", [\
["workspace:packages/domain-events", {\ ["workspace:packages/domain-events", {\
"packageLocation": "./packages/domain-events/",\ "packageLocation": "./packages/domain-events/",\
@@ -2762,16 +2778,17 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/domain-events-infra/",\ "packageLocation": "./packages/domain-events-infra/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ ["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@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/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"],\ ["@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"],\ ["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"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["newrelic", "npm:9.0.0"],\ ["newrelic", "npm:9.6.0"],\
["reflect-metadata", "npm:0.1.13"],\ ["reflect-metadata", "npm:0.1.13"],\
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:5.7.0"],\ ["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:5.7.0"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\ ["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
@@ -2801,23 +2818,24 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/event-store/",\ "packageLocation": "./packages/event-store/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/event-store", "workspace:packages/event-store"],\ ["@standardnotes/event-store", "workspace:packages/event-store"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ ["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/time", "workspace:packages/time"],\ ["@standardnotes/time", "workspace:packages/time"],\
["@types/ioredis", "npm:4.28.10"],\ ["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.1.1"],\ ["@types/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\ ["@types/newrelic", "npm:7.0.4"],\
["@types/nodemailer", "npm:6.4.6"],\ ["@types/nodemailer", "npm:6.4.6"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\ ["@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"],\ ["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\ ["eslint", "npm:8.25.0"],\
["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\ ["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\
["inversify", "npm:6.0.1"],\ ["inversify", "npm:6.0.1"],\
["ioredis", "npm:5.2.3"],\ ["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["mysql2", "npm:2.3.3"],\ ["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\ ["newrelic", "npm:9.6.0"],\
["reflect-metadata", "npm:0.1.13"],\ ["reflect-metadata", "npm:0.1.13"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\ ["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\ ["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\
@@ -2856,7 +2874,8 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/files/",\ "packageLocation": "./packages/files/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/files-server", "workspace:packages/files"],\ ["@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/common", "workspace:packages/common"],\
["@standardnotes/config", "npm:2.4.3"],\ ["@standardnotes/config", "npm:2.4.3"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
@@ -2868,14 +2887,14 @@ const RAW_RUNTIME_STATE =
["@types/connect-busboy", "npm:1.0.0"],\ ["@types/connect-busboy", "npm:1.0.0"],\
["@types/cors", "npm:2.8.12"],\ ["@types/cors", "npm:2.8.12"],\
["@types/express", "npm:4.17.14"],\ ["@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/jest", "npm:29.1.1"],\
["@types/jsonwebtoken", "npm:8.5.9"],\ ["@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/prettyjson", "npm:0.0.30"],\
["@types/uuid", "npm:8.3.4"],\ ["@types/uuid", "npm:8.3.4"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\ ["@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"],\ ["connect-busboy", "npm:1.0.0"],\
["cors", "npm:2.8.5"],\ ["cors", "npm:2.8.5"],\
["dayjs", "npm:1.11.6"],\ ["dayjs", "npm:1.11.6"],\
@@ -2887,10 +2906,10 @@ const RAW_RUNTIME_STATE =
["helmet", "npm:6.0.0"],\ ["helmet", "npm:6.0.0"],\
["inversify", "npm:6.0.1"],\ ["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\ ["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.2.3"],\ ["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["jsonwebtoken", "npm:8.5.1"],\ ["jsonwebtoken", "npm:8.5.1"],\
["newrelic", "npm:9.0.0"],\ ["newrelic", "npm:9.6.0"],\
["nodemon", "npm:2.0.20"],\ ["nodemon", "npm:2.0.20"],\
["npm-check-updates", "npm:16.0.1"],\ ["npm-check-updates", "npm:16.0.1"],\
["prettyjson", "npm:1.2.5"],\ ["prettyjson", "npm:1.2.5"],\
@@ -2990,28 +3009,29 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/scheduler/",\ "packageLocation": "./packages/scheduler/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/scheduler-server", "workspace:packages/scheduler"],\ ["@standardnotes/scheduler-server", "workspace:packages/scheduler"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.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/common", "workspace:packages/common"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ ["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/predicates", "workspace:packages/predicates"],\ ["@standardnotes/predicates", "workspace:packages/predicates"],\
["@standardnotes/time", "workspace:packages/time"],\ ["@standardnotes/time", "workspace:packages/time"],\
["@types/ioredis", "npm:4.28.10"],\ ["@types/ioredis", "npm:5.0.0"],\
["@types/jest", "npm:29.1.1"],\ ["@types/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\ ["@types/newrelic", "npm:7.0.4"],\
["@types/node", "npm:18.0.3"],\ ["@types/node", "npm:18.11.9"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\ ["@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"],\ ["dayjs", "npm:1.11.6"],\
["dotenv", "npm:16.0.1"],\ ["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\ ["eslint", "npm:8.25.0"],\
["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\ ["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\
["inversify", "npm:6.0.1"],\ ["inversify", "npm:6.0.1"],\
["ioredis", "npm:5.2.3"],\ ["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["mysql2", "npm:2.3.3"],\ ["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\ ["newrelic", "npm:9.6.0"],\
["npm-check-updates", "npm:16.0.1"],\ ["npm-check-updates", "npm:16.0.1"],\
["reflect-metadata", "npm:0.1.13"],\ ["reflect-metadata", "npm:0.1.13"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\ ["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
@@ -3051,15 +3071,16 @@ const RAW_RUNTIME_STATE =
["@lerna-lite/cli", "npm:1.6.0"],\ ["@lerna-lite/cli", "npm:1.6.0"],\
["@lerna-lite/list", "npm:1.6.0"],\ ["@lerna-lite/list", "npm:1.6.0"],\
["@lerna-lite/run", "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/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.3"],\ ["@types/newrelic", "npm:7.0.4"],\
["@types/node", "npm:18.0.3"],\ ["@types/node", "npm:18.11.9"],\
["@typescript-eslint/parser", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:5.40.1"],\ ["@typescript-eslint/parser", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:5.40.1"],\
["eslint", "npm:8.19.0"],\ ["eslint", "npm:8.19.0"],\
["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.5.0"],\ ["eslint-config-prettier", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:8.5.0"],\
["ini", "npm:3.0.0"],\ ["ini", "npm:3.0.0"],\
["newrelic", "npm:9.0.0"],\ ["newrelic", "npm:9.6.0"],\
["npm-check-updates", "npm:16.0.1"],\ ["npm-check-updates", "npm:16.0.1"],\
["prettier", "npm:2.7.1"],\ ["prettier", "npm:2.7.1"],\
["ts-node", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:10.9.1"],\ ["ts-node", "virtual:8859b278716fedf3e7458b5628625f7e35678c418626878559a0b816445001b7e24c55546f4677ba4c20b521aa0cf52cc33ac07deff171e383ada6eeab69933f#npm:10.9.1"],\
@@ -3073,6 +3094,7 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/settings/",\ "packageLocation": "./packages/settings/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/settings", "workspace:packages/settings"],\ ["@standardnotes/settings", "workspace:packages/settings"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\ ["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\
["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:4.2.1"],\ ["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:4.2.1"],\
["reflect-metadata", "npm:0.1.13"],\ ["reflect-metadata", "npm:0.1.13"],\
@@ -3098,7 +3120,7 @@ const RAW_RUNTIME_STATE =
["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\ ["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\
["@standardnotes/sncrypto-common", "npm:1.13.0"],\ ["@standardnotes/sncrypto-common", "npm:1.13.0"],\
["@types/jest", "npm:29.1.1"],\ ["@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"],\ ["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\
["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:4.2.1"],\ ["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:4.2.1"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
@@ -3116,8 +3138,9 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/syncing-server/",\ "packageLocation": "./packages/syncing-server/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/syncing-server", "workspace:packages/syncing-server"],\ ["@standardnotes/syncing-server", "workspace:packages/syncing-server"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.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/common", "workspace:packages/common"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ ["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
@@ -3130,16 +3153,16 @@ const RAW_RUNTIME_STATE =
["@types/dotenv", "npm:8.2.0"],\ ["@types/dotenv", "npm:8.2.0"],\
["@types/express", "npm:4.17.14"],\ ["@types/express", "npm:4.17.14"],\
["@types/inversify-express-utils", "npm:2.0.0"],\ ["@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/jest", "npm:29.1.1"],\
["@types/jsonwebtoken", "npm:8.5.9"],\ ["@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/prettyjson", "npm:0.0.30"],\
["@types/ua-parser-js", "npm:0.7.36"],\ ["@types/ua-parser-js", "npm:0.7.36"],\
["@types/uuid", "npm:8.3.4"],\ ["@types/uuid", "npm:8.3.4"],\
["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\ ["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\
["aws-sdk", "npm:2.1234.0"],\ ["aws-sdk", "npm:2.1253.0"],\
["axios", "npm:0.27.2"],\ ["axios", "npm:1.1.3"],\
["cors", "npm:2.8.5"],\ ["cors", "npm:2.8.5"],\
["dotenv", "npm:16.0.1"],\ ["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\ ["eslint", "npm:8.25.0"],\
@@ -3148,11 +3171,11 @@ const RAW_RUNTIME_STATE =
["helmet", "npm:6.0.0"],\ ["helmet", "npm:6.0.0"],\
["inversify", "npm:6.0.1"],\ ["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\ ["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.2.3"],\ ["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["jsonwebtoken", "npm:8.5.1"],\ ["jsonwebtoken", "npm:8.5.1"],\
["mysql2", "npm:2.3.3"],\ ["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\ ["newrelic", "npm:9.6.0"],\
["nodemon", "npm:2.0.20"],\ ["nodemon", "npm:2.0.20"],\
["npm-check-updates", "npm:16.0.1"],\ ["npm-check-updates", "npm:16.0.1"],\
["prettyjson", "npm:1.2.5"],\ ["prettyjson", "npm:1.2.5"],\
@@ -3160,7 +3183,7 @@ const RAW_RUNTIME_STATE =
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\ ["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\ ["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\
["typescript", "patch:typescript@npm%3A4.8.4#optional!builtin<compat/typescript>::version=4.8.4&hash=701156"],\ ["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"],\ ["uuid", "npm:9.0.0"],\
["winston", "npm:3.8.2"]\ ["winston", "npm:3.8.2"]\
],\ ],\
@@ -3215,8 +3238,9 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/websockets/",\ "packageLocation": "./packages/websockets/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/websockets-server", "workspace:packages/websockets"],\ ["@standardnotes/websockets-server", "workspace:packages/websockets"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.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/api", "npm:1.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\ ["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
@@ -3224,12 +3248,12 @@ const RAW_RUNTIME_STATE =
["@standardnotes/security", "workspace:packages/security"],\ ["@standardnotes/security", "workspace:packages/security"],\
["@types/cors", "npm:2.8.12"],\ ["@types/cors", "npm:2.8.12"],\
["@types/express", "npm:4.17.14"],\ ["@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/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"],\ ["@typescript-eslint/eslint-plugin", "virtual:04783e12400851b8a3d76e71495851cc94959db6e62f04cb0a31190080629440b182d8c8eb4d7f2b04e281912f2783a5fd4d2c3c6ab68d38b7097246c93f4c19#npm:5.40.1"],\
["aws-sdk", "npm:2.1234.0"],\ ["aws-sdk", "npm:2.1253.0"],\
["axios", "npm:0.27.2"],\ ["axios", "npm:1.1.3"],\
["cors", "npm:2.8.5"],\ ["cors", "npm:2.8.5"],\
["dotenv", "npm:16.0.1"],\ ["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\ ["eslint", "npm:8.25.0"],\
@@ -3237,10 +3261,10 @@ const RAW_RUNTIME_STATE =
["express", "npm:4.18.2"],\ ["express", "npm:4.18.2"],\
["inversify", "npm:6.0.1"],\ ["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\ ["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.2.3"],\ ["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["mysql2", "npm:2.3.3"],\ ["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\ ["newrelic", "npm:9.6.0"],\
["reflect-metadata", "npm:0.1.13"],\ ["reflect-metadata", "npm:0.1.13"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\ ["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\ ["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\
@@ -3255,8 +3279,9 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/workspace/",\ "packageLocation": "./packages/workspace/",\
"packageDependencies": [\ "packageDependencies": [\
["@standardnotes/workspace-server", "workspace:packages/workspace"],\ ["@standardnotes/workspace-server", "workspace:packages/workspace"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.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/api", "npm:1.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\ ["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events", "workspace:packages/domain-events"],\
@@ -3266,11 +3291,11 @@ const RAW_RUNTIME_STATE =
["@standardnotes/time", "workspace:packages/time"],\ ["@standardnotes/time", "workspace:packages/time"],\
["@types/cors", "npm:2.8.12"],\ ["@types/cors", "npm:2.8.12"],\
["@types/express", "npm:4.17.14"],\ ["@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/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"],\ ["@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"],\ ["cors", "npm:2.8.5"],\
["dotenv", "npm:16.0.1"],\ ["dotenv", "npm:16.0.1"],\
["eslint", "npm:8.25.0"],\ ["eslint", "npm:8.25.0"],\
@@ -3278,10 +3303,10 @@ const RAW_RUNTIME_STATE =
["express", "npm:4.18.2"],\ ["express", "npm:4.18.2"],\
["inversify", "npm:6.0.1"],\ ["inversify", "npm:6.0.1"],\
["inversify-express-utils", "npm:6.4.3"],\ ["inversify-express-utils", "npm:6.4.3"],\
["ioredis", "npm:5.2.3"],\ ["ioredis", "npm:5.2.4"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["mysql2", "npm:2.3.3"],\ ["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.0.0"],\ ["newrelic", "npm:9.6.0"],\
["reflect-metadata", "npm:0.1.13"],\ ["reflect-metadata", "npm:0.1.13"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\ ["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\ ["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\
@@ -3530,11 +3555,11 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["@types/ioredis", [\ ["@types/ioredis", [\
["npm:4.28.10", {\ ["npm:5.0.0", {\
"packageLocation": "./.yarn/cache/@types-ioredis-npm-4.28.10-4bdbe26a79-a7f24a8a13.zip/node_modules/@types/ioredis/",\ "packageLocation": "./.yarn/cache/@types-ioredis-npm-5.0.0-6efa70abfa-439770c9da.zip/node_modules/@types/ioredis/",\
"packageDependencies": [\ "packageDependencies": [\
["@types/ioredis", "npm:4.28.10"],\ ["@types/ioredis", "npm:5.0.0"],\
["@types/node", "npm:18.0.3"]\ ["ioredis", "npm:5.2.4"]\
],\ ],\
"linkType": "HARD"\ "linkType": "HARD"\
}]\ }]\
@@ -3663,10 +3688,10 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["@types/newrelic", [\ ["@types/newrelic", [\
["npm:7.0.3", {\ ["npm:7.0.4", {\
"packageLocation": "./.yarn/cache/@types-newrelic-npm-7.0.3-c49600c8f5-f56ebaa21c.zip/node_modules/@types/newrelic/",\ "packageLocation": "./.yarn/cache/@types-newrelic-npm-7.0.4-4f0b179b51-b44215b3ab.zip/node_modules/@types/newrelic/",\
"packageDependencies": [\ "packageDependencies": [\
["@types/newrelic", "npm:7.0.3"]\ ["@types/newrelic", "npm:7.0.4"]\
],\ ],\
"linkType": "HARD"\ "linkType": "HARD"\
}]\ }]\
@@ -3678,6 +3703,13 @@ const RAW_RUNTIME_STATE =
["@types/node", "npm:18.0.3"]\ ["@types/node", "npm:18.0.3"]\
],\ ],\
"linkType": "HARD"\ "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", [\ ["@types/nodemailer", [\
@@ -4730,10 +4762,10 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["aws-sdk", [\ ["aws-sdk", [\
["npm:2.1234.0", {\ ["npm:2.1253.0", {\
"packageLocation": "./.yarn/cache/aws-sdk-npm-2.1234.0-7ee3cd4390-cd4b3e8baf.zip/node_modules/aws-sdk/",\ "packageLocation": "./.yarn/cache/aws-sdk-npm-2.1253.0-2cf60975ab-faa4af2949.zip/node_modules/aws-sdk/",\
"packageDependencies": [\ "packageDependencies": [\
["aws-sdk", "npm:2.1234.0"],\ ["aws-sdk", "npm:2.1253.0"],\
["buffer", "npm:4.9.2"],\ ["buffer", "npm:4.9.2"],\
["events", "npm:1.1.1"],\ ["events", "npm:1.1.1"],\
["ieee754", "npm:1.1.13"],\ ["ieee754", "npm:1.1.13"],\
@@ -4749,12 +4781,13 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["axios", [\ ["axios", [\
["npm:0.27.2", {\ ["npm:1.1.3", {\
"packageLocation": "./.yarn/cache/axios-npm-0.27.2-dbe3a48aea-4cd898afe9.zip/node_modules/axios/",\ "packageLocation": "./.yarn/cache/axios-npm-1.1.3-4b63965ac1-2e28acd01c.zip/node_modules/axios/",\
"packageDependencies": [\ "packageDependencies": [\
["axios", "npm:0.27.2"],\ ["axios", "npm:1.1.3"],\
["follow-redirects", "virtual:dbe3a48aea1dd5649e16abaf23d4ae05582d2149e16141955113766a0f84f681baf358c77ddccfc82eb23e4ccc66c6c912df62a9c01f2a83f1842bf86cc297b1#npm:1.15.2"],\ ["follow-redirects", "virtual:4b63965ac1b2157b91a1875529bea3b0bbc3068d3676d1bef28bff5cf6689705374a86cc3832f95ba8d934037a93cc0e09c3662c13ca0e747800d7ca279a53c0#npm:1.15.2"],\
["form-data", "npm:4.0.0"]\ ["form-data", "npm:4.0.0"],\
["proxy-from-env", "npm:1.1.0"]\
],\ ],\
"linkType": "HARD"\ "linkType": "HARD"\
}]\ }]\
@@ -7299,10 +7332,10 @@ const RAW_RUNTIME_STATE =
],\ ],\
"linkType": "SOFT"\ "linkType": "SOFT"\
}],\ }],\
["virtual:dbe3a48aea1dd5649e16abaf23d4ae05582d2149e16141955113766a0f84f681baf358c77ddccfc82eb23e4ccc66c6c912df62a9c01f2a83f1842bf86cc297b1#npm:1.15.2", {\ ["virtual:4b63965ac1b2157b91a1875529bea3b0bbc3068d3676d1bef28bff5cf6689705374a86cc3832f95ba8d934037a93cc0e09c3662c13ca0e747800d7ca279a53c0#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/",\ "packageLocation": "./.yarn/__virtual__/follow-redirects-virtual-b0bb08d690/0/cache/follow-redirects-npm-1.15.2-1ec1dd82be-930171f8b8.zip/node_modules/follow-redirects/",\
"packageDependencies": [\ "packageDependencies": [\
["follow-redirects", "virtual:dbe3a48aea1dd5649e16abaf23d4ae05582d2149e16141955113766a0f84f681baf358c77ddccfc82eb23e4ccc66c6c912df62a9c01f2a83f1842bf86cc297b1#npm:1.15.2"],\ ["follow-redirects", "virtual:4b63965ac1b2157b91a1875529bea3b0bbc3068d3676d1bef28bff5cf6689705374a86cc3832f95ba8d934037a93cc0e09c3662c13ca0e747800d7ca279a53c0#npm:1.15.2"],\
["@types/debug", null],\ ["@types/debug", null],\
["debug", null]\ ["debug", null]\
],\ ],\
@@ -8250,10 +8283,10 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["ioredis", [\ ["ioredis", [\
["npm:5.2.3", {\ ["npm:5.2.4", {\
"packageLocation": "./.yarn/cache/ioredis-npm-5.2.3-54d9576179-3849fbe54a.zip/node_modules/ioredis/",\ "packageLocation": "./.yarn/cache/ioredis-npm-5.2.4-875ff55d9a-f6572bf619.zip/node_modules/ioredis/",\
"packageDependencies": [\ "packageDependencies": [\
["ioredis", "npm:5.2.3"],\ ["ioredis", "npm:5.2.4"],\
["@ioredis/commands", "npm:1.2.0"],\ ["@ioredis/commands", "npm:1.2.0"],\
["cluster-key-slot", "npm:1.1.1"],\ ["cluster-key-slot", "npm:1.1.1"],\
["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\ ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"],\
@@ -10375,18 +10408,17 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["newrelic", [\ ["newrelic", [\
["npm:9.0.0", {\ ["npm:9.6.0", {\
"packageLocation": "./.yarn/cache/newrelic-npm-9.0.0-65e8703d5d-397f7d2626.zip/node_modules/newrelic/",\ "packageLocation": "./.yarn/cache/newrelic-npm-9.6.0-f10080c2de-eb378acde1.zip/node_modules/newrelic/",\
"packageDependencies": [\ "packageDependencies": [\
["newrelic", "npm:9.0.0"],\ ["newrelic", "npm:9.6.0"],\
["@grpc/grpc-js", "npm:1.6.7"],\ ["@grpc/grpc-js", "npm:1.6.7"],\
["@grpc/proto-loader", "npm:0.6.13"],\ ["@grpc/proto-loader", "npm:0.6.13"],\
["@newrelic/aws-sdk", "virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:5.0.0"],\ ["@newrelic/aws-sdk", "virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:5.0.0"],\
["@newrelic/koa", "virtual:65e8703d5df08d5ff3f7296fcb759f276254ee430ae6f3cc1f03da392ff63066a3c6c59591c38f36f19d3e877285287a834b5c55e22d764dc2cb0938f7128707#npm:7.0.0"],\ ["@newrelic/koa", "virtual:f10080c2deb75096716a913b06010dcd94891c77539a757ab32210a1efc3ff91527b36d6c7c46e890db826160e0724553ca23acd0a8a734b5554c9600c71eb52#npm:7.0.0"],\
["@newrelic/native-metrics", "npm:9.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"],\ ["@tyriar/fibonacci-heap", "npm:2.0.9"],\
["async", "npm:3.2.4"],\
["concat-stream", "npm:2.0.0"],\ ["concat-stream", "npm:2.0.0"],\
["https-proxy-agent", "npm:5.0.1"],\ ["https-proxy-agent", "npm:5.0.1"],\
["json-stringify-safe", "npm:5.0.1"],\ ["json-stringify-safe", "npm:5.0.1"],\
@@ -11479,6 +11511,15 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\ "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", [\ ["pseudomap", [\
["npm:1.0.2", {\ ["npm:1.0.2", {\
"packageLocation": "./.yarn/cache/pseudomap-npm-1.0.2-0d0e40fee0-33cfbb99ac.zip/node_modules/pseudomap/",\ "packageLocation": "./.yarn/cache/pseudomap-npm-1.0.2-0d0e40fee0-33cfbb99ac.zip/node_modules/pseudomap/",\
@@ -12491,7 +12532,7 @@ const RAW_RUNTIME_STATE =
"packageDependencies": [\ "packageDependencies": [\
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:5.7.0"],\ ["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:5.7.0"],\
["@types/aws-sdk", null],\ ["@types/aws-sdk", null],\
["aws-sdk", "npm:2.1234.0"],\ ["aws-sdk", "npm:2.1253.0"],\
["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"]\ ["debug", "virtual:b86a9fb34323a98c6519528ed55faa0d9b44ca8879307c0b29aa384bde47ff59a7d0c9051b31246f14521dfb71ba3c5d6d0b35c29fffc17bf875aa6ad977d9e8#npm:4.3.4"]\
],\ ],\
"packagePeers": [\ "packagePeers": [\
@@ -13106,7 +13147,7 @@ const RAW_RUNTIME_STATE =
["@tsconfig/node12", "npm:1.0.11"],\ ["@tsconfig/node12", "npm:1.0.11"],\
["@tsconfig/node14", "npm:1.0.3"],\ ["@tsconfig/node14", "npm:1.0.3"],\
["@tsconfig/node16", "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__core", null],\
["@types/swc__wasm", null],\ ["@types/swc__wasm", null],\
["@types/typescript", null],\ ["@types/typescript", null],\
@@ -13382,7 +13423,7 @@ const RAW_RUNTIME_STATE =
["@types/better-sqlite3", null],\ ["@types/better-sqlite3", null],\
["@types/google-cloud__spanner", null],\ ["@types/google-cloud__spanner", null],\
["@types/hdb-pool", null],\ ["@types/hdb-pool", null],\
["@types/ioredis", "npm:4.28.10"],\ ["@types/ioredis", "npm:5.0.0"],\
["@types/mongodb", null],\ ["@types/mongodb", null],\
["@types/mssql", null],\ ["@types/mssql", null],\
["@types/mysql2", null],\ ["@types/mysql2", null],\
@@ -13406,7 +13447,7 @@ const RAW_RUNTIME_STATE =
["dotenv", "npm:16.0.3"],\ ["dotenv", "npm:16.0.3"],\
["glob", "npm:7.2.3"],\ ["glob", "npm:7.2.3"],\
["hdb-pool", null],\ ["hdb-pool", null],\
["ioredis", "npm:5.2.3"],\ ["ioredis", "npm:5.2.4"],\
["js-yaml", "npm:4.1.0"],\ ["js-yaml", "npm:4.1.0"],\
["mkdirp", "npm:1.0.4"],\ ["mkdirp", "npm:1.0.4"],\
["mongodb", null],\ ["mongodb", null],\
@@ -13484,10 +13525,10 @@ const RAW_RUNTIME_STATE =
}]\ }]\
]],\ ]],\
["ua-parser-js", [\ ["ua-parser-js", [\
["npm:1.0.2", {\ ["npm:1.0.32", {\
"packageLocation": "./.yarn/cache/ua-parser-js-npm-1.0.2-c3376785e2-5ee14b105c.zip/node_modules/ua-parser-js/",\ "packageLocation": "./.yarn/cache/ua-parser-js-npm-1.0.32-95b0b6a78d-9d320c6742.zip/node_modules/ua-parser-js/",\
"packageDependencies": [\ "packageDependencies": [\
["ua-parser-js", "npm:1.0.2"]\ ["ua-parser-js", "npm:1.0.32"]\
],\ ],\
"linkType": "HARD"\ "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.
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.
@@ -326,8 +326,8 @@ ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
endif endif
quiet_cmd_regen_makefile = ACTION Regenerating $@ 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 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)/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 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) $(call do_cmd,regen_makefile)
# "all" is a concatenation of the "all" targets from all the included # "all" is a concatenation of the "all" targets from all the included
@@ -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
@@ -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:
@@ -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:
@@ -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:
@@ -19,293 +19,316 @@
"error_on_warn": "false", "error_on_warn": "false",
"force_dynamic_crt": 0, "force_dynamic_crt": 0,
"host_arch": "x64", "host_arch": "x64",
"icu_data_in": "../../deps/icu-tmp/icudt70l.dat", "icu_data_in": "../../deps/icu-tmp/icudt71l.dat",
"icu_endianness": "l", "icu_endianness": "l",
"icu_gyp_path": "tools/icu/icu-generic.gyp", "icu_gyp_path": "tools/icu/icu-generic.gyp",
"icu_path": "deps/icu-small", "icu_path": "deps/icu-small",
"icu_small": "false", "icu_small": "false",
"icu_ver_major": "70", "icu_ver_major": "71",
"is_debug": 0, "is_debug": 0,
"libdir": "lib",
"llvm_version": "11.0", "llvm_version": "11.0",
"napi_build_version": "8", "napi_build_version": "8",
"node_byteorder": "little", "node_byteorder": "little",
"node_debug_lib": "false", "node_debug_lib": "false",
"node_enable_d8": "false", "node_enable_d8": "false",
"node_fipsinstall": "false",
"node_install_corepack": "true", "node_install_corepack": "true",
"node_install_npm": "true", "node_install_npm": "true",
"node_library_files": [ "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/_http_agent.js",
"lib/timers.js", "lib/_http_client.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_common.js", "lib/_http_common.js",
"lib/string_decoder.js", "lib/_http_incoming.js",
"lib/cluster.js", "lib/_http_outgoing.js",
"lib/v8.js", "lib/_http_server.js",
"lib/crypto.js", "lib/_stream_duplex.js",
"lib/wasi.js", "lib/_stream_passthrough.js",
"lib/_stream_readable.js", "lib/_stream_readable.js",
"lib/zlib.js", "lib/_stream_transform.js",
"lib/url.js", "lib/_stream_wrap.js",
"lib/tls.js",
"lib/_stream_writable.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/async_hooks.js",
"lib/process.js",
"lib/http.js",
"lib/buffer.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/fs.js",
"lib/util/types.js", "lib/fs/promises.js",
"lib/timers/promises.js", "lib/http.js",
"lib/path/win32.js", "lib/http2.js",
"lib/path/posix.js", "lib/https.js",
"lib/stream/consumers.js", "lib/inspector.js",
"lib/stream/promises.js",
"lib/stream/web.js",
"lib/internal/constants.js",
"lib/internal/abort_controller.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/assert.js",
"lib/internal/fixed_queue.js", "lib/internal/assert/assertion_error.js",
"lib/internal/blocklist.js", "lib/internal/assert/calltracker.js",
"lib/internal/v8_prof_polyfill.js", "lib/internal/assert/snapshot.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/async_hooks.js", "lib/internal/async_hooks.js",
"lib/internal/http.js", "lib/internal/blob.js",
"lib/internal/buffer.js", "lib/internal/blocklist.js",
"lib/internal/trace_events_async_hooks.js", "lib/internal/bootstrap/browser.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/bootstrap/loaders.js", "lib/internal/bootstrap/loaders.js",
"lib/internal/bootstrap/pre_execution.js",
"lib/internal/bootstrap/node.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/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/does_own_process_state.js",
"lib/internal/bootstrap/switches/is_main_thread.js", "lib/internal/bootstrap/switches/is_main_thread.js",
"lib/internal/test/binding.js", "lib/internal/bootstrap/switches/is_not_main_thread.js",
"lib/internal/test/transfer.js", "lib/internal/buffer.js",
"lib/internal/util/types.js", "lib/internal/child_process.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/child_process/serialization.js", "lib/internal/child_process/serialization.js",
"lib/internal/debugger/inspect_repl.js", "lib/internal/cli_table.js",
"lib/internal/debugger/inspect_client.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/debugger/inspect.js",
"lib/internal/worker/io.js", "lib/internal/debugger/inspect_client.js",
"lib/internal/worker/js_transferable.js", "lib/internal/debugger/inspect_repl.js",
"lib/internal/main/repl.js", "lib/internal/dgram.js",
"lib/internal/main/print_help.js", "lib/internal/dns/callback_resolver.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/dns/promises.js", "lib/internal/dns/promises.js",
"lib/internal/dns/utils.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/promises.js",
"lib/internal/fs/read_file_context.js", "lib/internal/fs/read_file_context.js",
"lib/internal/fs/rimraf.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/streams.js",
"lib/internal/fs/sync_write_stream.js",
"lib/internal/fs/utils.js", "lib/internal/fs/utils.js",
"lib/internal/fs/cp/cp.js", "lib/internal/fs/watchers.js",
"lib/internal/fs/cp/cp-sync.js", "lib/internal/heap_utils.js",
"lib/internal/perf/nodetiming.js", "lib/internal/histogram.js",
"lib/internal/perf/usertiming.js", "lib/internal/http.js",
"lib/internal/perf/performance_entry.js", "lib/internal/http2/compat.js",
"lib/internal/perf/performance.js", "lib/internal/http2/core.js",
"lib/internal/perf/timerify.js", "lib/internal/http2/util.js",
"lib/internal/perf/utils.js", "lib/internal/idna.js",
"lib/internal/perf/observe.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_delay.js",
"lib/internal/perf/event_loop_utilization.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/manifest.js",
"lib/internal/policy/sri.js", "lib/internal/policy/sri.js",
"lib/internal/process/task_queues.js", "lib/internal/priority_queue.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/process/esm_loader.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/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/process/worker_thread_only.js",
"lib/internal/console/constructor.js", "lib/internal/promise_hooks.js",
"lib/internal/console/global.js", "lib/internal/querystring.js",
"lib/assert/strict.js", "lib/internal/readline/callbacks.js",
"lib/dns/promises.js", "lib/internal/readline/emitKeypressEvents.js",
"lib/fs/promises.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_no_browser_globals": "false",
"node_prefix": "/", "node_prefix": "/",
"node_release_urlbase": "https://nodejs.org/download/release/", "node_release_urlbase": "https://nodejs.org/download/release/",
@@ -330,20 +353,22 @@
"node_use_v8_platform": "true", "node_use_v8_platform": "true",
"node_with_ltcg": "false", "node_with_ltcg": "false",
"node_without_node_options": "false", "node_without_node_options": "false",
"openssl_fips": "",
"openssl_is_fips": "false", "openssl_is_fips": "false",
"openssl_quic": "true", "openssl_quic": "true",
"ossfuzz": "false", "ossfuzz": "false",
"shlib_suffix": "93.dylib", "shlib_suffix": "108.dylib",
"target_arch": "x64", "target_arch": "x64",
"v8_enable_31bit_smis_on_64bit_arch": 0, "v8_enable_31bit_smis_on_64bit_arch": 0,
"v8_enable_gdbjit": 0, "v8_enable_gdbjit": 0,
"v8_enable_hugepage": 0, "v8_enable_hugepage": 0,
"v8_enable_i18n_support": 1, "v8_enable_i18n_support": 1,
"v8_enable_inspector": 1, "v8_enable_inspector": 1,
"v8_enable_javascript_promise_hooks": 1,
"v8_enable_lite_mode": 0, "v8_enable_lite_mode": 0,
"v8_enable_object_print": 1, "v8_enable_object_print": 1,
"v8_enable_pointer_compression": 0, "v8_enable_pointer_compression": 0,
"v8_enable_shared_ro_heap": 1,
"v8_enable_short_builtin_calls": 1,
"v8_enable_webassembly": 1, "v8_enable_webassembly": 1,
"v8_no_strict_aliasing": 1, "v8_no_strict_aliasing": 1,
"v8_optimized_debug": 1, "v8_optimized_debug": 1,
@@ -353,8 +378,8 @@
"v8_use_siphash": 1, "v8_use_siphash": 1,
"want_separate_host_toolset": 0, "want_separate_host_toolset": 0,
"xcode_version": "11.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, "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"
} }
} }
@@ -25,7 +25,7 @@ DEFS_Debug := \
CFLAGS_Debug := \ CFLAGS_Debug := \
-O0 \ -O0 \
-gdwarf-2 \ -gdwarf-2 \
-mmacosx-version-min=10.13 \ -mmacosx-version-min=10.15 \
-arch x86_64 \ -arch x86_64 \
-Wall \ -Wall \
-Wendif-labels \ -Wendif-labels \
@@ -38,7 +38,7 @@ CFLAGS_C_Debug := \
# Flags passed to only C++ files. # Flags passed to only C++ files.
CFLAGS_CC_Debug := \ CFLAGS_CC_Debug := \
-std=gnu++14 \ -std=gnu++17 \
-stdlib=libc++ \ -stdlib=libc++ \
-fno-rtti \ -fno-rtti \
-fno-exceptions \ -fno-exceptions \
@@ -51,13 +51,13 @@ CFLAGS_OBJC_Debug :=
CFLAGS_OBJCC_Debug := CFLAGS_OBJCC_Debug :=
INCS_Debug := \ INCS_Debug := \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node \ -I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/include/node \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/src \ -I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/src \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/config \ -I/Users/karolsojko/Library/Caches/node-gyp/18.12.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/18.12.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/18.12.1/deps/uv/include \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/zlib \ -I/Users/karolsojko/Library/Caches/node-gyp/18.12.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/deps/v8/include \
-I$(srcdir)/src \ -I$(srcdir)/src \
-I$(srcdir)/../../../../nan-npm-2.16.0-cac314a230/node_modules/nan -I$(srcdir)/../../../../nan-npm-2.16.0-cac314a230/node_modules/nan
@@ -81,7 +81,7 @@ DEFS_Release := \
CFLAGS_Release := \ CFLAGS_Release := \
-O3 \ -O3 \
-gdwarf-2 \ -gdwarf-2 \
-mmacosx-version-min=10.13 \ -mmacosx-version-min=10.15 \
-arch x86_64 \ -arch x86_64 \
-Wall \ -Wall \
-Wendif-labels \ -Wendif-labels \
@@ -94,7 +94,7 @@ CFLAGS_C_Release := \
# Flags passed to only C++ files. # Flags passed to only C++ files.
CFLAGS_CC_Release := \ CFLAGS_CC_Release := \
-std=gnu++14 \ -std=gnu++17 \
-stdlib=libc++ \ -stdlib=libc++ \
-fno-rtti \ -fno-rtti \
-fno-exceptions \ -fno-exceptions \
@@ -107,13 +107,13 @@ CFLAGS_OBJC_Release :=
CFLAGS_OBJCC_Release := CFLAGS_OBJCC_Release :=
INCS_Release := \ INCS_Release := \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node \ -I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/include/node \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/src \ -I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/src \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/config \ -I/Users/karolsojko/Library/Caches/node-gyp/18.12.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/18.12.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/18.12.1/deps/uv/include \
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/zlib \ -I/Users/karolsojko/Library/Caches/node-gyp/18.12.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/deps/v8/include \
-I$(srcdir)/src \ -I$(srcdir)/src \
-I$(srcdir)/../../../../nan-npm-2.16.0-cac314a230/node_modules/nan -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 := \ LDFLAGS_Debug := \
-undefined dynamic_lookup \ -undefined dynamic_lookup \
-Wl,-search_paths_first \ -Wl,-search_paths_first \
-mmacosx-version-min=10.13 \ -mmacosx-version-min=10.15 \
-arch x86_64 \ -arch x86_64 \
-L$(builddir) \ -L$(builddir) \
-stdlib=libc++ -stdlib=libc++
@@ -163,7 +163,7 @@ LIBTOOLFLAGS_Debug := \
LDFLAGS_Release := \ LDFLAGS_Release := \
-undefined dynamic_lookup \ -undefined dynamic_lookup \
-Wl,-search_paths_first \ -Wl,-search_paths_first \
-mmacosx-version-min=10.13 \ -mmacosx-version-min=10.15 \
-arch x86_64 \ -arch x86_64 \
-L$(builddir) \ -L$(builddir) \
-stdlib=libc++ -stdlib=libc++
+6 -5
View File
@@ -8,7 +8,7 @@
] ]
}, },
"engines": { "engines": {
"node": ">=16.0.0 <17.0.0" "node": ">=18.0.0 <19.0.0"
}, },
"scripts": { "scripts": {
"lint": "yarn workspaces foreach -p -j 10 --verbose run lint", "lint": "yarn workspaces foreach -p -j 10 --verbose run lint",
@@ -46,8 +46,8 @@
"@lerna-lite/list": "^1.5.1", "@lerna-lite/list": "^1.5.1",
"@lerna-lite/run": "^1.5.1", "@lerna-lite/run": "^1.5.1",
"@types/jest": "^29.1.1", "@types/jest": "^29.1.1",
"@types/newrelic": "^7.0.3", "@types/newrelic": "^7.0.4",
"@types/node": "^18.0.0", "@types/node": "^18.11.9",
"@typescript-eslint/parser": "^5.40.1", "@typescript-eslint/parser": "^5.40.1",
"eslint": "^8.17.0", "eslint": "^8.17.0",
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^8.5.0",
@@ -59,7 +59,8 @@
}, },
"packageManager": "yarn@4.0.0-rc.25", "packageManager": "yarn@4.0.0-rc.25",
"dependencies": { "dependencies": {
"@sentry/node": "^7.3.0", "@newrelic/native-metrics": "^9.0.0",
"newrelic": "^9.0.0" "@sentry/node": "^7.19.0",
"newrelic": "^9.6.0"
} }
} }
+120
View File
@@ -3,6 +3,126 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [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) # [2.3.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.2.0...@standardnotes/analytics@2.3.0) (2022-11-09)
### Features ### Features
+1 -1
View File
@@ -1,4 +1,4 @@
FROM node:16.15.1-alpine FROM node:18.12.1-alpine
RUN apk add --update \ RUN apk add --update \
curl \ curl \
+50 -5
View File
@@ -15,6 +15,7 @@ import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types' import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env' import { Env } from '../src/Bootstrap/Env'
import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface' import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
import { CalculateMonthlyRecurringRevenue } from '../src/Domain/UseCase/CalculateMonthlyRecurringRevenue/CalculateMonthlyRecurringRevenue'
const requestReport = async ( const requestReport = async (
analyticsStore: AnalyticsStoreInterface, analyticsStore: AnalyticsStoreInterface,
@@ -22,7 +23,10 @@ const requestReport = async (
domainEventFactory: DomainEventFactoryInterface, domainEventFactory: DomainEventFactoryInterface,
domainEventPublisher: DomainEventPublisherInterface, domainEventPublisher: DomainEventPublisherInterface,
periodKeyGenerator: PeriodKeyGeneratorInterface, periodKeyGenerator: PeriodKeyGeneratorInterface,
calculateMonthlyRecurringRevenue: CalculateMonthlyRecurringRevenue,
): Promise<void> => { ): Promise<void> => {
await calculateMonthlyRecurringRevenue.execute({})
const analyticsOverTime: Array<{ const analyticsOverTime: Array<{
name: string name: string
period: number period: number
@@ -96,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 = [ const statisticMeasureNames = [
StatisticsMeasure.Income, StatisticsMeasure.Income,
StatisticsMeasure.PlusSubscriptionInitialAnnualPaymentsIncome, StatisticsMeasure.PlusSubscriptionInitialAnnualPaymentsIncome,
@@ -170,13 +208,10 @@ const requestReport = async (
} }
const event = domainEventFactory.createDailyAnalyticsReportGeneratedEvent({ const event = domainEventFactory.createDailyAnalyticsReportGeneratedEvent({
applicationStatistics: await statisticsStore.getYesterdayApplicationUsage(),
snjsStatistics: await statisticsStore.getYesterdaySNJSUsage(),
outOfSyncIncidents: await statisticsStore.getYesterdayOutOfSyncIncidents(),
activityStatistics: yesterdayActivityStatistics, activityStatistics: yesterdayActivityStatistics,
activityStatisticsOverTime: analyticsOverTime, activityStatisticsOverTime: analyticsOverTime,
statisticsOverTime,
statisticMeasures, statisticMeasures,
retentionStatistics: [],
churn: { churn: {
periodKeys: monthlyPeriodKeys, periodKeys: monthlyPeriodKeys,
values: churnRates, values: churnRates,
@@ -200,9 +235,19 @@ void container.load().then((container) => {
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.DomainEventFactory) const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.DomainEventFactory)
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.DomainEventPublisher) const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.DomainEventPublisher)
const periodKeyGenerator: PeriodKeyGeneratorInterface = container.get(TYPES.PeriodKeyGenerator) const periodKeyGenerator: PeriodKeyGeneratorInterface = container.get(TYPES.PeriodKeyGenerator)
const calculateMonthlyRecurringRevenue: CalculateMonthlyRecurringRevenue = container.get(
TYPES.CalculateMonthlyRecurringRevenue,
)
Promise.resolve( Promise.resolve(
requestReport(analyticsStore, statisticsStore, domainEventFactory, domainEventPublisher, periodKeyGenerator), requestReport(
analyticsStore,
statisticsStore,
domainEventFactory,
domainEventPublisher,
periodKeyGenerator,
calculateMonthlyRecurringRevenue,
),
) )
.then(() => { .then(() => {
logger.info('Usage report generation complete') logger.info('Usage report generation complete')
@@ -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`')
}
}
@@ -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')
}
}
+12 -13
View File
@@ -1,8 +1,8 @@
{ {
"name": "@standardnotes/analytics", "name": "@standardnotes/analytics",
"version": "2.3.0", "version": "2.10.0",
"engines": { "engines": {
"node": ">=14.0.0 <17.0.0" "node": ">=18.0.0 <19.0.0"
}, },
"private": true, "private": true,
"description": "Analytics tools for Standard Notes projects", "description": "Analytics tools for Standard Notes projects",
@@ -25,11 +25,10 @@
"typeorm": "typeorm-ts-node-commonjs" "typeorm": "typeorm-ts-node-commonjs"
}, },
"devDependencies": { "devDependencies": {
"@types/ioredis": "^4.28.10", "@types/ioredis": "^5.0.0",
"@types/jest": "^29.1.1", "@types/jest": "^29.1.1",
"@types/newrelic": "^7.0.3", "@types/newrelic": "^7.0.4",
"@types/node": "^18.0.0", "@types/node": "^18.11.9",
"@types/uuid": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^5.30.0", "@typescript-eslint/eslint-plugin": "^5.30.0",
"eslint": "^8.14.0", "eslint": "^8.14.0",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^4.2.1",
@@ -38,23 +37,23 @@
"typescript": "^4.8.4" "typescript": "^4.8.4"
}, },
"dependencies": { "dependencies": {
"@newrelic/native-metrics": "^9.0.0",
"@newrelic/winston-enricher": "^4.0.0", "@newrelic/winston-enricher": "^4.0.0",
"@sentry/node": "^7.3.0", "@sentry/node": "^7.19.0",
"@standardnotes/common": "workspace:*", "@standardnotes/common": "workspace:*",
"@standardnotes/domain-core": "workspace:*",
"@standardnotes/domain-events": "workspace:*", "@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*", "@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/time": "workspace:*", "@standardnotes/time": "workspace:*",
"aws-sdk": "^2.1158.0", "aws-sdk": "^2.1253.0",
"dayjs": "^1.11.6", "dayjs": "^1.11.6",
"dotenv": "^16.0.1", "dotenv": "^16.0.1",
"inversify": "^6.0.1", "inversify": "^6.0.1",
"ioredis": "^5.2.3", "ioredis": "^5.2.4",
"mysql2": "^2.3.3", "mysql2": "^2.3.3",
"newrelic": "^9.0.0", "newrelic": "^9.6.0",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"shallow-equal-object": "^1.1.1", "typeorm": "^0.3.10",
"typeorm": "^0.3.6",
"uuid": "^9.0.0",
"winston": "^3.8.1" "winston": "^3.8.1"
} }
} }
@@ -51,6 +51,7 @@ import { MapInterface } from '../Domain/Map/MapInterface'
import { RevenueModification } from '../Domain/Revenue/RevenueModification' import { RevenueModification } from '../Domain/Revenue/RevenueModification'
import { RevenueModificationMap } from '../Domain/Map/RevenueModificationMap' import { RevenueModificationMap } from '../Domain/Map/RevenueModificationMap'
import { SaveRevenueModification } from '../Domain/UseCase/SaveRevenueModification/SaveRevenueModification' import { SaveRevenueModification } from '../Domain/UseCase/SaveRevenueModification/SaveRevenueModification'
import { CalculateMonthlyRecurringRevenue } from '../Domain/UseCase/CalculateMonthlyRecurringRevenue/CalculateMonthlyRecurringRevenue'
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
const newrelicFormatter = require('@newrelic/winston-enricher') const newrelicFormatter = require('@newrelic/winston-enricher')
@@ -138,6 +139,9 @@ export class ContainerConfigLoader {
// Use Case // Use Case
container.bind<GetUserAnalyticsId>(TYPES.GetUserAnalyticsId).to(GetUserAnalyticsId) container.bind<GetUserAnalyticsId>(TYPES.GetUserAnalyticsId).to(GetUserAnalyticsId)
container.bind<SaveRevenueModification>(TYPES.SaveRevenueModification).to(SaveRevenueModification) container.bind<SaveRevenueModification>(TYPES.SaveRevenueModification).to(SaveRevenueModification)
container
.bind<CalculateMonthlyRecurringRevenue>(TYPES.CalculateMonthlyRecurringRevenue)
.to(CalculateMonthlyRecurringRevenue)
// Hanlders // Hanlders
container.bind<UserRegisteredEventHandler>(TYPES.UserRegisteredEventHandler).to(UserRegisteredEventHandler) container.bind<UserRegisteredEventHandler>(TYPES.UserRegisteredEventHandler).to(UserRegisteredEventHandler)
@@ -20,6 +20,7 @@ const TYPES = {
// Use Case // Use Case
GetUserAnalyticsId: Symbol.for('GetUserAnalyticsId'), GetUserAnalyticsId: Symbol.for('GetUserAnalyticsId'),
SaveRevenueModification: Symbol.for('SaveRevenueModification'), SaveRevenueModification: Symbol.for('SaveRevenueModification'),
CalculateMonthlyRecurringRevenue: Symbol.for('CalculateMonthlyRecurringRevenue'),
// Handlers // Handlers
UserRegisteredEventHandler: Symbol.for('UserRegisteredEventHandler'), UserRegisteredEventHandler: Symbol.for('UserRegisteredEventHandler'),
AccountDeletionRequestedEventHandler: Symbol.for('AccountDeletionRequestedEventHandler'), AccountDeletionRequestedEventHandler: Symbol.for('AccountDeletionRequestedEventHandler'),
@@ -22,18 +22,6 @@ describe('DomainEventFactory', () => {
it('should create a DAILY_ANALYTICS_REPORT_GENERATED event', () => { it('should create a DAILY_ANALYTICS_REPORT_GENERATED event', () => {
expect( expect(
createFactory().createDailyAnalyticsReportGeneratedEvent({ createFactory().createDailyAnalyticsReportGeneratedEvent({
snjsStatistics: [
{
version: '1-2-3',
count: 2,
},
],
applicationStatistics: [
{
version: '2-3-4',
count: 45,
},
],
activityStatistics: [ activityStatistics: [
{ {
name: AnalyticsActivity.Register, name: AnalyticsActivity.Register,
@@ -63,8 +51,18 @@ describe('DomainEventFactory', () => {
totalCount: 123, totalCount: 123,
}, },
], ],
outOfSyncIncidents: 324, statisticsOverTime: [
retentionStatistics: [], {
name: StatisticsMeasure.MRR,
period: Period.Last30Days,
counts: [
{
periodKey: '2022-10-9',
totalCount: 3,
},
],
},
],
churn: { churn: {
periodKeys: ['2022-10-9'], periodKeys: ['2022-10-9'],
values: [ values: [
@@ -105,10 +103,16 @@ describe('DomainEventFactory', () => {
totalCount: 123, totalCount: 123,
}, },
], ],
applicationStatistics: [ statisticsOverTime: [
{ {
count: 45, counts: [
version: '2-3-4', {
periodKey: '2022-10-9',
totalCount: 3,
},
],
name: 'mrr',
period: 9,
}, },
], ],
churn: { churn: {
@@ -120,14 +124,6 @@ describe('DomainEventFactory', () => {
}, },
], ],
}, },
outOfSyncIncidents: 324,
retentionStatistics: [],
snjsStatistics: [
{
count: 2,
version: '1-2-3',
},
],
statisticMeasures: [ statisticMeasures: [
{ {
average: 23, average: 23,
@@ -9,14 +9,6 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
constructor(@inject(TYPES.Timer) private timer: TimerInterface) {} constructor(@inject(TYPES.Timer) private timer: TimerInterface) {}
createDailyAnalyticsReportGeneratedEvent(dto: { createDailyAnalyticsReportGeneratedEvent(dto: {
snjsStatistics: Array<{
version: string
count: number
}>
applicationStatistics: Array<{
version: string
count: number
}>
activityStatistics: Array<{ activityStatistics: Array<{
name: string name: string
retention: number retention: number
@@ -38,18 +30,13 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
}> }>
totalCount: number totalCount: number
}> }>
outOfSyncIncidents: number statisticsOverTime: Array<{
retentionStatistics: Array<{ name: string
firstActivity: string period: number
secondActivity: string counts: Array<{
retention: { periodKey: string
periodKeys: Array<string> totalCount: number
values: Array<{ }>
firstPeriodKey: string
secondPeriodKey: string
value: number
}>
}
}> }>
churn: { churn: {
periodKeys: Array<string> periodKeys: Array<string>
@@ -2,14 +2,6 @@ import { DailyAnalyticsReportGeneratedEvent } from '@standardnotes/domain-events
export interface DomainEventFactoryInterface { export interface DomainEventFactoryInterface {
createDailyAnalyticsReportGeneratedEvent(dto: { createDailyAnalyticsReportGeneratedEvent(dto: {
snjsStatistics: Array<{
version: string
count: number
}>
applicationStatistics: Array<{
version: string
count: number
}>
activityStatistics: Array<{ activityStatistics: Array<{
name: string name: string
retention: number retention: number
@@ -31,18 +23,13 @@ export interface DomainEventFactoryInterface {
}> }>
totalCount: number totalCount: number
}> }>
outOfSyncIncidents: number statisticsOverTime: Array<{
retentionStatistics: Array<{ name: string
firstActivity: string period: number
secondActivity: string counts: Array<{
retention: { periodKey: string
periodKeys: Array<string> totalCount: number
values: Array<{ }>
firstPeriodKey: string
secondPeriodKey: string
value: number
}>
}
}> }>
churn: { churn: {
periodKeys: Array<string> periodKeys: Array<string>
@@ -9,16 +9,32 @@ import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure' import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface' import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { Period } from '../Time/Period' import { Period } from '../Time/Period'
import { Result } from '../Core/Result'
import { RevenueModification } from '../Revenue/RevenueModification'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { Logger } from 'winston'
describe('SubscriptionCancelledEventHandler', () => { describe('SubscriptionCancelledEventHandler', () => {
let event: SubscriptionCancelledEvent let event: SubscriptionCancelledEvent
let getUserAnalyticsId: GetUserAnalyticsId let getUserAnalyticsId: GetUserAnalyticsId
let analyticsStore: AnalyticsStoreInterface let analyticsStore: AnalyticsStoreInterface
let statisticsStore: StatisticsStoreInterface let statisticsStore: StatisticsStoreInterface
let saveRevenueModification: SaveRevenueModification
let logger: Logger
const createHandler = () => new SubscriptionCancelledEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore) const createHandler = () =>
new SubscriptionCancelledEventHandler(
getUserAnalyticsId,
analyticsStore,
statisticsStore,
saveRevenueModification,
logger,
)
beforeEach(() => { beforeEach(() => {
logger = {} as jest.Mocked<Logger>
logger.error = jest.fn()
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId> getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
getUserAnalyticsId.execute = jest.fn().mockReturnValue({ analyticsId: 3 }) getUserAnalyticsId.execute = jest.fn().mockReturnValue({ analyticsId: 3 })
@@ -30,6 +46,7 @@ describe('SubscriptionCancelledEventHandler', () => {
event = {} as jest.Mocked<SubscriptionCancelledEvent> event = {} as jest.Mocked<SubscriptionCancelledEvent>
event.createdAt = new Date(1) event.createdAt = new Date(1)
event.type = 'SUBSCRIPTION_CANCELLED'
event.payload = { event.payload = {
subscriptionId: 1, subscriptionId: 1,
userEmail: 'test@test.com', userEmail: 'test@test.com',
@@ -41,7 +58,13 @@ describe('SubscriptionCancelledEventHandler', () => {
timestamp: 1, timestamp: 1,
offline: false, offline: false,
replaced: 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 () => { it('should track subscription cancelled statistics', async () => {
@@ -55,6 +78,7 @@ describe('SubscriptionCancelledEventHandler', () => {
Period.ThisWeek, Period.ThisWeek,
Period.ThisMonth, Period.ThisMonth,
]) ])
expect(saveRevenueModification.execute).toHaveBeenCalled()
}) })
it('should not track statistics for subscriptions that are in a legacy 5 year plan', async () => { it('should not track statistics for subscriptions that are in a legacy 5 year plan', async () => {
@@ -65,5 +89,16 @@ describe('SubscriptionCancelledEventHandler', () => {
await createHandler().handle(event) await createHandler().handle(event)
expect(statisticsStore.incrementMeasure).not.toHaveBeenCalled() 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()
}) })
}) })
@@ -1,13 +1,18 @@
import { DomainEventHandlerInterface, SubscriptionCancelledEvent } from '@standardnotes/domain-events' import { DomainEventHandlerInterface, SubscriptionCancelledEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify' import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types' import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity' import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface' import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure' import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface' import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
import { Period } from '../Time/Period' import { Period } from '../Time/Period'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId' import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
@injectable() @injectable()
export class SubscriptionCancelledEventHandler implements DomainEventHandlerInterface { export class SubscriptionCancelledEventHandler implements DomainEventHandlerInterface {
@@ -15,10 +20,12 @@ export class SubscriptionCancelledEventHandler implements DomainEventHandlerInte
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId, @inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface, @inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface, @inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
@inject(TYPES.Logger) private logger: Logger,
) {} ) {}
async handle(event: SubscriptionCancelledEvent): Promise<void> { async handle(event: SubscriptionCancelledEvent): Promise<void> {
const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail }) const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionCancelled], analyticsId, [ await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionCancelled], analyticsId, [
Period.Today, Period.Today,
Period.ThisWeek, Period.ThisWeek,
@@ -26,6 +33,23 @@ export class SubscriptionCancelledEventHandler implements DomainEventHandlerInte
]) ])
await this.trackSubscriptionStatistics(event) 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) { private async trackSubscriptionStatistics(event: SubscriptionCancelledEvent) {
@@ -7,18 +7,35 @@ import { SubscriptionExpiredEventHandler } from './SubscriptionExpiredEventHandl
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId' import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface' import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface' import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { Result } from '../Core/Result'
import { RevenueModification } from '../Revenue/RevenueModification'
import { Logger } from 'winston'
describe('SubscriptionExpiredEventHandler', () => { describe('SubscriptionExpiredEventHandler', () => {
let event: SubscriptionExpiredEvent let event: SubscriptionExpiredEvent
let getUserAnalyticsId: GetUserAnalyticsId let getUserAnalyticsId: GetUserAnalyticsId
let analyticsStore: AnalyticsStoreInterface let analyticsStore: AnalyticsStoreInterface
let statisticsStore: StatisticsStoreInterface let statisticsStore: StatisticsStoreInterface
let saveRevenueModification: SaveRevenueModification
let logger: Logger
const createHandler = () => new SubscriptionExpiredEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore) const createHandler = () =>
new SubscriptionExpiredEventHandler(
getUserAnalyticsId,
analyticsStore,
statisticsStore,
saveRevenueModification,
logger,
)
beforeEach(() => { beforeEach(() => {
logger = {} as jest.Mocked<Logger>
logger.error = jest.fn()
event = {} as jest.Mocked<SubscriptionExpiredEvent> event = {} as jest.Mocked<SubscriptionExpiredEvent>
event.createdAt = new Date(1) event.createdAt = new Date(1)
event.type = 'SUBSCRIPTION_EXPIRED'
event.payload = { event.payload = {
subscriptionId: 1, subscriptionId: 1,
userEmail: 'test@test.com', userEmail: 'test@test.com',
@@ -26,6 +43,9 @@ describe('SubscriptionExpiredEventHandler', () => {
timestamp: 1, timestamp: 1,
offline: false, offline: false,
totalActiveSubscriptionsCount: 123, totalActiveSubscriptionsCount: 123,
userExistingSubscriptionsCount: 2,
billingFrequency: 1,
payAmount: 12.99,
} }
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId> getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
@@ -36,6 +56,9 @@ describe('SubscriptionExpiredEventHandler', () => {
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface> statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
statisticsStore.setMeasure = jest.fn() statisticsStore.setMeasure = jest.fn()
saveRevenueModification = {} as jest.Mocked<SaveRevenueModification>
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.ok<RevenueModification>())
}) })
it('should update analytics and statistics', async () => { it('should update analytics and statistics', async () => {
@@ -43,5 +66,14 @@ describe('SubscriptionExpiredEventHandler', () => {
expect(analyticsStore.markActivity).toHaveBeenCalled() expect(analyticsStore.markActivity).toHaveBeenCalled()
expect(statisticsStore.setMeasure).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()
}) })
}) })
@@ -1,13 +1,18 @@
import { DomainEventHandlerInterface, SubscriptionExpiredEvent } from '@standardnotes/domain-events' import { DomainEventHandlerInterface, SubscriptionExpiredEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify' import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types' import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity' import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface' import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure' import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface' import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
import { Period } from '../Time/Period' import { Period } from '../Time/Period'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId' import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
@injectable() @injectable()
export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterface { export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterface {
@@ -15,10 +20,12 @@ export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterf
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId, @inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface, @inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface, @inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
@inject(TYPES.Logger) private logger: Logger,
) {} ) {}
async handle(event: SubscriptionExpiredEvent): Promise<void> { async handle(event: SubscriptionExpiredEvent): Promise<void> {
const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail }) const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
await this.analyticsStore.markActivity( await this.analyticsStore.markActivity(
[AnalyticsActivity.SubscriptionExpired, AnalyticsActivity.ExistingCustomersChurn], [AnalyticsActivity.SubscriptionExpired, AnalyticsActivity.ExistingCustomersChurn],
analyticsId, analyticsId,
@@ -30,5 +37,22 @@ export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterf
event.payload.totalActiveSubscriptionsCount, event.payload.totalActiveSubscriptionsCount,
[Period.Today, Period.ThisWeek, Period.ThisMonth, Period.ThisYear], [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()}`,
)
}
} }
} }
@@ -11,6 +11,7 @@ import { Period } from '../Time/Period'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification' import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { Result } from '../Core/Result' import { Result } from '../Core/Result'
import { RevenueModification } from '../Revenue/RevenueModification' import { RevenueModification } from '../Revenue/RevenueModification'
import { Logger } from 'winston'
describe('SubscriptionPurchasedEventHandler', () => { describe('SubscriptionPurchasedEventHandler', () => {
let event: SubscriptionPurchasedEvent let event: SubscriptionPurchasedEvent
@@ -19,11 +20,21 @@ describe('SubscriptionPurchasedEventHandler', () => {
let analyticsStore: AnalyticsStoreInterface let analyticsStore: AnalyticsStoreInterface
let statisticsStore: StatisticsStoreInterface let statisticsStore: StatisticsStoreInterface
let saveRevenueModification: SaveRevenueModification let saveRevenueModification: SaveRevenueModification
let logger: Logger
const createHandler = () => const createHandler = () =>
new SubscriptionPurchasedEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore, saveRevenueModification) new SubscriptionPurchasedEventHandler(
getUserAnalyticsId,
analyticsStore,
statisticsStore,
saveRevenueModification,
logger,
)
beforeEach(() => { beforeEach(() => {
logger = {} as jest.Mocked<Logger>
logger.error = jest.fn()
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface> statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
statisticsStore.incrementMeasure = jest.fn() statisticsStore.incrementMeasure = jest.fn()
statisticsStore.setMeasure = jest.fn() statisticsStore.setMeasure = jest.fn()
@@ -80,4 +91,12 @@ describe('SubscriptionPurchasedEventHandler', () => {
expect(analyticsStore.markActivity).toHaveBeenCalledWith(['limited-discount-offer-purchased'], 3, [Period.Today]) 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()
})
}) })
@@ -1,10 +1,11 @@
import { DomainEventHandlerInterface, SubscriptionPurchasedEvent } from '@standardnotes/domain-events' import { DomainEventHandlerInterface, SubscriptionPurchasedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify' import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types' import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity' import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface' import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { Email } from '../Common/Email'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure' import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface' import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType' import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
@@ -20,6 +21,7 @@ export class SubscriptionPurchasedEventHandler implements DomainEventHandlerInte
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface, @inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface, @inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification, @inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
@inject(TYPES.Logger) private logger: Logger,
) {} ) {}
async handle(event: SubscriptionPurchasedEvent): Promise<void> { async handle(event: SubscriptionPurchasedEvent): Promise<void> {
@@ -60,7 +62,7 @@ export class SubscriptionPurchasedEventHandler implements DomainEventHandlerInte
) )
} }
await this.saveRevenueModification.execute({ const result = await this.saveRevenueModification.execute({
billingFrequency: event.payload.billingFrequency, billingFrequency: event.payload.billingFrequency,
eventType: SubscriptionEventType.create(event.type).getValue(), eventType: SubscriptionEventType.create(event.type).getValue(),
newSubscriber: event.payload.newSubscriber, newSubscriber: event.payload.newSubscriber,
@@ -70,5 +72,11 @@ export class SubscriptionPurchasedEventHandler implements DomainEventHandlerInte
userEmail: Email.create(event.payload.userEmail).getValue(), userEmail: Email.create(event.payload.userEmail).getValue(),
userUuid, userUuid,
}) })
if (result.isFailed()) {
this.logger.error(
`[${event.type}][${event.payload.subscriptionId}] Could not save revenue modification: ${result.getError()}`,
)
}
} }
} }
@@ -10,18 +10,35 @@ import { SubscriptionRefundedEventHandler } from './SubscriptionRefundedEventHan
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface' import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity' import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { Period } from '../Time/Period' import { Period } from '../Time/Period'
import { Result } from '../Core/Result'
import { RevenueModification } from '../Revenue/RevenueModification'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { Logger } from 'winston'
describe('SubscriptionRefundedEventHandler', () => { describe('SubscriptionRefundedEventHandler', () => {
let event: SubscriptionRefundedEvent let event: SubscriptionRefundedEvent
let getUserAnalyticsId: GetUserAnalyticsId let getUserAnalyticsId: GetUserAnalyticsId
let analyticsStore: AnalyticsStoreInterface let analyticsStore: AnalyticsStoreInterface
let statisticsStore: StatisticsStoreInterface let statisticsStore: StatisticsStoreInterface
let saveRevenueModification: SaveRevenueModification
let logger: Logger
const createHandler = () => new SubscriptionRefundedEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore) const createHandler = () =>
new SubscriptionRefundedEventHandler(
getUserAnalyticsId,
analyticsStore,
statisticsStore,
saveRevenueModification,
logger,
)
beforeEach(() => { beforeEach(() => {
logger = {} as jest.Mocked<Logger>
logger.error = jest.fn()
event = {} as jest.Mocked<SubscriptionRefundedEvent> event = {} as jest.Mocked<SubscriptionRefundedEvent>
event.createdAt = new Date(1) event.createdAt = new Date(1)
event.type = 'SUBSCRIPTION_REFUNDED'
event.payload = { event.payload = {
subscriptionId: 1, subscriptionId: 1,
userEmail: 'test@test.com', userEmail: 'test@test.com',
@@ -30,6 +47,8 @@ describe('SubscriptionRefundedEventHandler', () => {
offline: false, offline: false,
userExistingSubscriptionsCount: 3, userExistingSubscriptionsCount: 3,
totalActiveSubscriptionsCount: 1, totalActiveSubscriptionsCount: 1,
billingFrequency: 1,
payAmount: 12.99,
} }
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId> getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
@@ -41,6 +60,9 @@ describe('SubscriptionRefundedEventHandler', () => {
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface> statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
statisticsStore.setMeasure = jest.fn() 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 () => { it('should mark churn for new customer', async () => {
@@ -56,6 +78,8 @@ describe('SubscriptionRefundedEventHandler', () => {
expect(analyticsStore.markActivity).toHaveBeenCalledWith([AnalyticsActivity.NewCustomersChurn], 3, [ expect(analyticsStore.markActivity).toHaveBeenCalledWith([AnalyticsActivity.NewCustomersChurn], 3, [
Period.ThisMonth, Period.ThisMonth,
]) ])
expect(saveRevenueModification.execute).toHaveBeenCalled()
}) })
it('should mark churn for existing customer', async () => { it('should mark churn for existing customer', async () => {
@@ -75,4 +99,12 @@ describe('SubscriptionRefundedEventHandler', () => {
Period.ThisMonth, 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()
})
}) })
@@ -1,13 +1,18 @@
import { DomainEventHandlerInterface, SubscriptionRefundedEvent } from '@standardnotes/domain-events' import { DomainEventHandlerInterface, SubscriptionRefundedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify' import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types' import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity' import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface' import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure' import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface' import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
import { Period } from '../Time/Period' import { Period } from '../Time/Period'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId' import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
@injectable() @injectable()
export class SubscriptionRefundedEventHandler implements DomainEventHandlerInterface { export class SubscriptionRefundedEventHandler implements DomainEventHandlerInterface {
@@ -15,10 +20,12 @@ export class SubscriptionRefundedEventHandler implements DomainEventHandlerInter
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId, @inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface, @inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface, @inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
@inject(TYPES.Logger) private logger: Logger,
) {} ) {}
async handle(event: SubscriptionRefundedEvent): Promise<void> { async handle(event: SubscriptionRefundedEvent): Promise<void> {
const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail }) const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionRefunded], analyticsId, [ await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionRefunded], analyticsId, [
Period.Today, Period.Today,
Period.ThisWeek, Period.ThisWeek,
@@ -26,6 +33,23 @@ export class SubscriptionRefundedEventHandler implements DomainEventHandlerInter
]) ])
await this.markChurnActivity(analyticsId, event) 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> { private async markChurnActivity(analyticsId: number, event: SubscriptionRefundedEvent): Promise<void> {
@@ -6,17 +6,28 @@ import { SubscriptionRenewedEvent } from '@standardnotes/domain-events'
import { SubscriptionRenewedEventHandler } from './SubscriptionRenewedEventHandler' import { SubscriptionRenewedEventHandler } from './SubscriptionRenewedEventHandler'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId' import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface' import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { RevenueModification } from '../Revenue/RevenueModification'
import { Result } from '../Core/Result'
import { Logger } from 'winston'
describe('SubscriptionRenewedEventHandler', () => { describe('SubscriptionRenewedEventHandler', () => {
let event: SubscriptionRenewedEvent let event: SubscriptionRenewedEvent
let getUserAnalyticsId: GetUserAnalyticsId let getUserAnalyticsId: GetUserAnalyticsId
let analyticsStore: AnalyticsStoreInterface let analyticsStore: AnalyticsStoreInterface
let saveRevenueModification: SaveRevenueModification
let logger: Logger
const createHandler = () => new SubscriptionRenewedEventHandler(getUserAnalyticsId, analyticsStore) const createHandler = () =>
new SubscriptionRenewedEventHandler(getUserAnalyticsId, analyticsStore, saveRevenueModification, logger)
beforeEach(() => { beforeEach(() => {
logger = {} as jest.Mocked<Logger>
logger.error = jest.fn()
event = {} as jest.Mocked<SubscriptionRenewedEvent> event = {} as jest.Mocked<SubscriptionRenewedEvent>
event.createdAt = new Date(1) event.createdAt = new Date(1)
event.type = 'SUBSCRIPTION_RENEWED'
event.payload = { event.payload = {
subscriptionId: 1, subscriptionId: 1,
userEmail: 'test@test.com', userEmail: 'test@test.com',
@@ -24,6 +35,8 @@ describe('SubscriptionRenewedEventHandler', () => {
subscriptionExpiresAt: 2, subscriptionExpiresAt: 2,
timestamp: 1, timestamp: 1,
offline: false, offline: false,
billingFrequency: 1,
payAmount: 12.99,
} }
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId> getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
@@ -32,6 +45,9 @@ describe('SubscriptionRenewedEventHandler', () => {
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface> analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
analyticsStore.markActivity = jest.fn() analyticsStore.markActivity = jest.fn()
analyticsStore.unmarkActivity = 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 () => { it('should track subscription renewed statistics', async () => {
@@ -39,5 +55,14 @@ describe('SubscriptionRenewedEventHandler', () => {
expect(analyticsStore.markActivity).toHaveBeenCalled() expect(analyticsStore.markActivity).toHaveBeenCalled()
expect(analyticsStore.unmarkActivity).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()
}) })
}) })
@@ -1,21 +1,28 @@
import { DomainEventHandlerInterface, SubscriptionRenewedEvent } from '@standardnotes/domain-events' import { DomainEventHandlerInterface, SubscriptionRenewedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify' import { inject, injectable } from 'inversify'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types' import TYPES from '../../Bootstrap/Types'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId' import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity' import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface' import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { Period } from '../Time/Period' 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() @injectable()
export class SubscriptionRenewedEventHandler implements DomainEventHandlerInterface { export class SubscriptionRenewedEventHandler implements DomainEventHandlerInterface {
constructor( constructor(
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId, @inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface, @inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
@inject(TYPES.Logger) private logger: Logger,
) {} ) {}
async handle(event: SubscriptionRenewedEvent): Promise<void> { async handle(event: SubscriptionRenewedEvent): Promise<void> {
const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail }) const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionRenewed], analyticsId, [ await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionRenewed], analyticsId, [
Period.Today, Period.Today,
Period.ThisWeek, Period.ThisWeek,
@@ -26,5 +33,22 @@ export class SubscriptionRenewedEventHandler implements DomainEventHandlerInterf
analyticsId, analyticsId,
[Period.Today, Period.ThisWeek, Period.ThisMonth], [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()}`,
)
}
} }
} }
@@ -1,23 +1,30 @@
import { injectable } from 'inversify'
import { Email, UniqueEntityId } from '@standardnotes/domain-core'
import { TypeORMRevenueModification } from '../../Infra/TypeORM/TypeORMRevenueModification' import { TypeORMRevenueModification } from '../../Infra/TypeORM/TypeORMRevenueModification'
import { UniqueEntityId } from '../Core/UniqueEntityId'
import { MonthlyRevenue } from '../Revenue/MonthlyRevenue' import { MonthlyRevenue } from '../Revenue/MonthlyRevenue'
import { RevenueModification } from '../Revenue/RevenueModification' import { RevenueModification } from '../Revenue/RevenueModification'
import { Subscription } from '../Subscription/Subscription' import { Subscription } from '../Subscription/Subscription'
import { User } from '../User/User' import { User } from '../User/User'
import { MapInterface } from './MapInterface' import { MapInterface } from './MapInterface'
import { Email } from '../Common/Email'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName' import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType' import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
@injectable()
export class RevenueModificationMap implements MapInterface<RevenueModification, TypeORMRevenueModification> { export class RevenueModificationMap implements MapInterface<RevenueModification, TypeORMRevenueModification> {
toDomain(persistence: TypeORMRevenueModification): RevenueModification { toDomain(persistence: TypeORMRevenueModification): RevenueModification {
const user = User.create( const userOrError = User.create(
{ {
email: Email.create(persistence.userEmail).getValue(), email: Email.create(persistence.userEmail).getValue(),
}, },
new UniqueEntityId(persistence.userUuid), new UniqueEntityId(persistence.userUuid),
) )
const subscription = Subscription.create( if (userOrError.isFailed()) {
throw new Error(`Could not create user: ${userOrError.getError()}`)
}
const user = userOrError.getValue()
const subscriptionOrError = Subscription.create(
{ {
billingFrequency: persistence.billingFrequency, billingFrequency: persistence.billingFrequency,
isFirstSubscriptionForUser: persistence.isNewCustomer, isFirstSubscriptionForUser: persistence.isNewCustomer,
@@ -26,17 +33,31 @@ export class RevenueModificationMap implements MapInterface<RevenueModification,
}, },
new UniqueEntityId(persistence.subscriptionId), new UniqueEntityId(persistence.subscriptionId),
) )
const previousMonthlyRevenueOrError = MonthlyRevenue.create(persistence.previousMonthlyRevenue) if (subscriptionOrError.isFailed()) {
throw new Error(`Could not create subscription: ${subscriptionOrError.getError()}`)
}
const subscription = subscriptionOrError.getValue()
return RevenueModification.create( const previousMonthlyRevenueOrError = MonthlyRevenue.create(persistence.previousMonthlyRevenue)
const newMonthlyRevenueOrError = MonthlyRevenue.create(persistence.newMonthlyRevenue)
const revenuModificationOrError = RevenueModification.create(
{ {
user, user,
subscription, subscription,
eventType: SubscriptionEventType.create(persistence.eventType).getValue(), eventType: SubscriptionEventType.create(persistence.eventType).getValue(),
previousMonthlyRevenue: previousMonthlyRevenueOrError.getValue(), previousMonthlyRevenue: previousMonthlyRevenueOrError.getValue(),
newMonthlyRevenue: newMonthlyRevenueOrError.getValue(),
createdAt: persistence.createdAt,
}, },
new UniqueEntityId(persistence.uuid), new UniqueEntityId(persistence.uuid),
) )
if (revenuModificationOrError.isFailed()) {
throw new Error(`Could not map revenue modification to domain: ${revenuModificationOrError.getError()}`)
}
return revenuModificationOrError.getValue()
} }
toPersistence(domain: RevenueModification): TypeORMRevenueModification { toPersistence(domain: RevenueModification): TypeORMRevenueModification {
@@ -46,12 +67,13 @@ export class RevenueModificationMap implements MapInterface<RevenueModification,
persistence.billingFrequency = subscription.props.billingFrequency persistence.billingFrequency = subscription.props.billingFrequency
persistence.eventType = domain.props.eventType.value persistence.eventType = domain.props.eventType.value
persistence.isNewCustomer = subscription.props.isFirstSubscriptionForUser persistence.isNewCustomer = subscription.props.isFirstSubscriptionForUser
persistence.newMonthlyRevenue = domain.newMonthlyRevenue.value persistence.newMonthlyRevenue = domain.props.newMonthlyRevenue.value
persistence.previousMonthlyRevenue = domain.props.previousMonthlyRevenue.value persistence.previousMonthlyRevenue = domain.props.previousMonthlyRevenue.value
persistence.subscriptionId = subscription.id.toValue() as number persistence.subscriptionId = subscription.id.toValue() as number
persistence.subscriptionPlan = subscription.props.planName.value persistence.subscriptionPlan = subscription.props.planName.value
persistence.userEmail = user.props.email.value persistence.userEmail = user.props.email.value
persistence.userUuid = user.id.toString() persistence.userUuid = user.id.toString()
persistence.createdAt = domain.props.createdAt
return persistence return persistence
} }
@@ -1,5 +1,5 @@
import { ValueObject } from '../Core/ValueObject' import { Result, ValueObject } from '@standardnotes/domain-core'
import { Result } from '../Core/Result'
import { MonthlyRevenueProps } from './MonthlyRevenueProps' import { MonthlyRevenueProps } from './MonthlyRevenueProps'
export class MonthlyRevenue extends ValueObject<MonthlyRevenueProps> { export class MonthlyRevenue extends ValueObject<MonthlyRevenueProps> {
@@ -13,7 +13,7 @@ export class MonthlyRevenue extends ValueObject<MonthlyRevenueProps> {
static create(revenue: number): Result<MonthlyRevenue> { static create(revenue: number): Result<MonthlyRevenue> {
if (isNaN(revenue) || revenue < 0) { if (isNaN(revenue) || revenue < 0) {
return Result.fail<MonthlyRevenue>('Monthly revenue must be a non-negative number') return Result.fail<MonthlyRevenue>(`Monthly revenue must be a non-negative number. Supplied: ${revenue}`)
} else { } else {
return Result.ok<MonthlyRevenue>(new MonthlyRevenue({ value: revenue })) return Result.ok<MonthlyRevenue>(new MonthlyRevenue({ value: revenue }))
} }
@@ -16,46 +16,23 @@ describe('RevenueModification', () => {
isFirstSubscriptionForUser: true, isFirstSubscriptionForUser: true,
payedAmount: 123, payedAmount: 123,
planName: SubscriptionPlanName.create('PRO_PLAN').getValue(), planName: SubscriptionPlanName.create('PRO_PLAN').getValue(),
}) }).getValue()
user = User.create({ user = User.create({
email: Email.create('test@test.te').getValue(), email: Email.create('test@test.te').getValue(),
}) }).getValue()
}) })
it('should create an aggregate for purchased subscription', () => { it('should create an aggregate for purchased subscription', () => {
const revenueModification = RevenueModification.create({ const revenueModification = RevenueModification.create({
createdAt: 2,
eventType: SubscriptionEventType.create('SUBSCRIPTION_PURCHASED').getValue(), eventType: SubscriptionEventType.create('SUBSCRIPTION_PURCHASED').getValue(),
previousMonthlyRevenue: MonthlyRevenue.create(123).getValue(), previousMonthlyRevenue: MonthlyRevenue.create(123).getValue(),
newMonthlyRevenue: MonthlyRevenue.create(45).getValue(),
subscription, subscription,
user, user,
}) }).getValue()
expect(revenueModification.id.toString()).toHaveLength(36) expect(revenueModification.id.toString()).toHaveLength(36)
expect(revenueModification.newMonthlyRevenue.value).toEqual(123 / 12) expect(revenueModification.props.newMonthlyRevenue.value).toEqual(45)
})
it('should create an aggregate for subscription expired', () => {
const revenueModification = RevenueModification.create({
createdAt: new Date(1),
eventType: SubscriptionEventType.create('SUBSCRIPTION_EXPIRED').getValue(),
previousMonthlyRevenue: MonthlyRevenue.create(123).getValue(),
subscription,
user,
})
expect(revenueModification.id.toString()).toHaveLength(36)
expect(revenueModification.newMonthlyRevenue.value).toEqual(0)
})
it('should create an aggregate for subscription cancelled', () => {
const revenueModification = RevenueModification.create({
eventType: SubscriptionEventType.create('SUBSCRIPTION_CANCELLED').getValue(),
previousMonthlyRevenue: MonthlyRevenue.create(123).getValue(),
subscription,
user,
})
expect(revenueModification.id.toString()).toHaveLength(36)
expect(revenueModification.newMonthlyRevenue.value).toEqual(123)
}) })
}) })
@@ -1,6 +1,5 @@
import { Aggregate } from '../Core/Aggregate' import { Aggregate, UniqueEntityId, Result } from '@standardnotes/domain-core'
import { UniqueEntityId } from '../Core/UniqueEntityId'
import { MonthlyRevenue } from './MonthlyRevenue'
import { RevenueModificationProps } from './RevenueModificationProps' import { RevenueModificationProps } from './RevenueModificationProps'
export class RevenueModification extends Aggregate<RevenueModificationProps> { export class RevenueModification extends Aggregate<RevenueModificationProps> {
@@ -8,38 +7,7 @@ export class RevenueModification extends Aggregate<RevenueModificationProps> {
super(props, id) super(props, id)
} }
static create(props: RevenueModificationProps, id?: UniqueEntityId): RevenueModification { static create(props: RevenueModificationProps, id?: UniqueEntityId): Result<RevenueModification> {
const revenueModification = new RevenueModification( return Result.ok<RevenueModification>(new RevenueModification(props, id))
{
...props,
createdAt: props.createdAt ? props.createdAt : new Date(),
},
id,
)
return revenueModification
}
get newMonthlyRevenue(): MonthlyRevenue {
const { subscription } = this.props
let revenue = 0
switch (this.props.eventType.value) {
case 'SUBSCRIPTION_PURCHASED':
case 'SUBSCRIPTION_RENEWED':
revenue = subscription.props.payedAmount / subscription.props.billingFrequency
break
case 'SUBSCRIPTION_EXPIRED':
case 'SUBSCRIPTION_REFUNDED':
revenue = 0
break
case 'SUBSCRIPTION_CANCELLED':
revenue = this.props.previousMonthlyRevenue.value
break
}
const monthlyRevenueOrError = MonthlyRevenue.create(revenue)
return monthlyRevenueOrError.getValue()
} }
} }
@@ -8,5 +8,6 @@ export interface RevenueModificationProps {
subscription: Subscription subscription: Subscription
eventType: SubscriptionEventType eventType: SubscriptionEventType
previousMonthlyRevenue: MonthlyRevenue previousMonthlyRevenue: MonthlyRevenue
createdAt?: Date newMonthlyRevenue: MonthlyRevenue
createdAt: number
} }
@@ -1,7 +1,9 @@
import { Uuid } from '../Common/Uuid' import { Uuid } from '@standardnotes/domain-core'
import { RevenueModification } from './RevenueModification' import { RevenueModification } from './RevenueModification'
export interface RevenueModificationRepositoryInterface { export interface RevenueModificationRepositoryInterface {
findLastByUserUuid(userUuid: Uuid): Promise<RevenueModification | null> findLastByUserUuid(userUuid: Uuid): Promise<RevenueModification | null>
sumMRRDiff(dto: { planName?: string; billingFrequency?: number }): Promise<number>
save(revenueModification: RevenueModification): Promise<RevenueModification> save(revenueModification: RevenueModification): Promise<RevenueModification>
} }
@@ -15,4 +15,10 @@ export enum StatisticsMeasure {
Refunds = 'refunds', Refunds = 'refunds',
NewCustomers = 'new-customers', NewCustomers = 'new-customers',
TotalCustomers = 'total-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',
} }
@@ -13,4 +13,8 @@ export interface StatisticsStoreInterface {
getMeasureAverage(measure: StatisticsMeasure, period: Period): Promise<number> getMeasureAverage(measure: StatisticsMeasure, period: Period): Promise<number>
getMeasureTotal(measure: StatisticsMeasure, periodOrPeriodKey: Period | string): Promise<number> getMeasureTotal(measure: StatisticsMeasure, periodOrPeriodKey: Period | string): Promise<number>
getMeasureIncrementCounts(measure: StatisticsMeasure, period: Period): Promise<number> getMeasureIncrementCounts(measure: StatisticsMeasure, period: Period): Promise<number>
calculateTotalCountOverPeriod(
measure: StatisticsMeasure,
period: Period,
): Promise<Array<{ periodKey: string; totalCount: number }>>
} }
@@ -8,7 +8,7 @@ describe('Subscription', () => {
isFirstSubscriptionForUser: true, isFirstSubscriptionForUser: true,
payedAmount: 12.99, payedAmount: 12.99,
planName: SubscriptionPlanName.create('PRO_PLAN').getValue(), planName: SubscriptionPlanName.create('PRO_PLAN').getValue(),
}) }).getValue()
expect(subscription.id.toString()).toHaveLength(36) expect(subscription.id.toString()).toHaveLength(36)
}) })
@@ -1,5 +1,5 @@
import { Entity } from '../Core/Entity' import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { UniqueEntityId } from '../Core/UniqueEntityId'
import { SubscriptionProps } from './SubscriptionProps' import { SubscriptionProps } from './SubscriptionProps'
export class Subscription extends Entity<SubscriptionProps> { export class Subscription extends Entity<SubscriptionProps> {
@@ -11,7 +11,7 @@ export class Subscription extends Entity<SubscriptionProps> {
super(props, id) super(props, id)
} }
static create(props: SubscriptionProps, id?: UniqueEntityId): Subscription { static create(props: SubscriptionProps, id?: UniqueEntityId): Result<Subscription> {
return new Subscription(props, id) return Result.ok<Subscription>(new Subscription(props, id))
} }
} }
@@ -1,5 +1,5 @@
import { ValueObject } from '../Core/ValueObject' import { ValueObject, Result } from '@standardnotes/domain-core'
import { Result } from '../Core/Result'
import { SubscriptionEventTypeProps } from './SubscriptionEventTypeProps' import { SubscriptionEventTypeProps } from './SubscriptionEventTypeProps'
export class SubscriptionEventType extends ValueObject<SubscriptionEventTypeProps> { export class SubscriptionEventType extends ValueObject<SubscriptionEventTypeProps> {
@@ -19,6 +19,7 @@ export class SubscriptionEventType extends ValueObject<SubscriptionEventTypeProp
'SUBSCRIPTION_EXPIRED', 'SUBSCRIPTION_EXPIRED',
'SUBSCRIPTION_REFUNDED', 'SUBSCRIPTION_REFUNDED',
'SUBSCRIPTION_CANCELLED', 'SUBSCRIPTION_CANCELLED',
'SUBSCRIPTION_DATA_MIGRATED',
].includes(subscriptionEventType) ].includes(subscriptionEventType)
) { ) {
return Result.fail<SubscriptionEventType>(`Invalid subscription event type ${subscriptionEventType}`) return Result.fail<SubscriptionEventType>(`Invalid subscription event type ${subscriptionEventType}`)
@@ -1,5 +1,5 @@
import { ValueObject } from '../Core/ValueObject' import { Result, ValueObject } from '@standardnotes/domain-core'
import { Result } from '../Core/Result'
import { SubscriptionPlanNameProps } from './SubscriptionPlanNameProps' import { SubscriptionPlanNameProps } from './SubscriptionPlanNameProps'
export class SubscriptionPlanName extends ValueObject<SubscriptionPlanNameProps> { export class SubscriptionPlanName extends ValueObject<SubscriptionPlanNameProps> {
@@ -26,4 +26,5 @@ export enum Period {
OctoberThisYear, OctoberThisYear,
NovemberThisYear, NovemberThisYear,
DecemberThisYear, DecemberThisYear,
Last30DaysIncludingToday,
} }
@@ -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', () => { it('should generate period keys for this year', () => {
expect(createGenerator().getDiscretePeriodKeys(Period.ThisYear)).toEqual([ expect(createGenerator().getDiscretePeriodKeys(Period.ThisYear)).toEqual([
'2022-1', '2022-1',
@@ -33,6 +33,12 @@ export class PeriodKeyGenerator implements PeriodKeyGeneratorInterface {
periodKeys.unshift(this.getDailyKey(this.getDateNDaysBefore(i))) 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 return periodKeys
case Period.Last7Days: case Period.Last7Days:
for (let i = 1; i <= 7; i++) { for (let i = 1; i <= 7; i++) {
@@ -0,0 +1,33 @@
import 'reflect-metadata'
import { RevenueModificationRepositoryInterface } from '../../Revenue/RevenueModificationRepositoryInterface'
import { StatisticsMeasure } from '../../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../../Statistics/StatisticsStoreInterface'
import { Period } from '../../Time/Period'
import { CalculateMonthlyRecurringRevenue } from './CalculateMonthlyRecurringRevenue'
describe('CalculateMonthlyRecurringRevenue', () => {
let revenueModificationRepository: RevenueModificationRepositoryInterface
let statisticsStore: StatisticsStoreInterface
const createUseCase = () => new CalculateMonthlyRecurringRevenue(revenueModificationRepository, statisticsStore)
beforeEach(() => {
revenueModificationRepository = {} as jest.Mocked<RevenueModificationRepositoryInterface>
revenueModificationRepository.sumMRRDiff = jest.fn().mockReturnValue(123.45)
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
statisticsStore.setMeasure = jest.fn()
})
it('should calculate the MRR diff and persist it as a statistic', async () => {
await createUseCase().execute({})
expect(statisticsStore.setMeasure).toHaveBeenCalledWith(StatisticsMeasure.MRR, 123.45, [
Period.Today,
Period.ThisMonth,
Period.ThisYear,
])
})
})
@@ -0,0 +1,83 @@
import { SubscriptionBillingFrequency, SubscriptionName } from '@standardnotes/common'
import { inject, injectable } from 'inversify'
import { Result } from '@standardnotes/domain-core'
import TYPES from '../../../Bootstrap/Types'
import { MonthlyRevenue } from '../../Revenue/MonthlyRevenue'
import { RevenueModificationRepositoryInterface } from '../../Revenue/RevenueModificationRepositoryInterface'
import { StatisticsMeasure } from '../../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../../Statistics/StatisticsStoreInterface'
import { Period } from '../../Time/Period'
import { DomainUseCaseInterface } from '../DomainUseCaseInterface'
import { CalculateMonthlyRecurringRevenueDTO } from './CalculateMonthlyRecurringRevenueDTO'
@injectable()
export class CalculateMonthlyRecurringRevenue implements DomainUseCaseInterface<MonthlyRevenue> {
constructor(
@inject(TYPES.RevenueModificationRepository)
private revenueModificationRepository: RevenueModificationRepositoryInterface,
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
) {}
async execute(_dto: CalculateMonthlyRecurringRevenueDTO): Promise<Result<MonthlyRevenue>> {
const mrrDiff = await this.revenueModificationRepository.sumMRRDiff({})
await this.statisticsStore.setMeasure(StatisticsMeasure.MRR, mrrDiff, [
Period.Today,
Period.ThisMonth,
Period.ThisYear,
])
const monthlyPlansMrrDiff = await this.revenueModificationRepository.sumMRRDiff({
billingFrequency: SubscriptionBillingFrequency.Monthly,
})
await this.statisticsStore.setMeasure(StatisticsMeasure.MonthlyPlansMRR, monthlyPlansMrrDiff, [
Period.Today,
Period.ThisMonth,
Period.ThisYear,
])
const annualPlansMrrDiff = await this.revenueModificationRepository.sumMRRDiff({
billingFrequency: SubscriptionBillingFrequency.Annual,
})
await this.statisticsStore.setMeasure(StatisticsMeasure.AnnualPlansMRR, annualPlansMrrDiff, [
Period.Today,
Period.ThisMonth,
Period.ThisYear,
])
const fiveYearPlansMrrDiff = await this.revenueModificationRepository.sumMRRDiff({
billingFrequency: SubscriptionBillingFrequency.FiveYear,
})
await this.statisticsStore.setMeasure(StatisticsMeasure.FiveYearPlansMRR, fiveYearPlansMrrDiff, [
Period.Today,
Period.ThisMonth,
Period.ThisYear,
])
const proPlansMrrDiff = await this.revenueModificationRepository.sumMRRDiff({
planName: SubscriptionName.ProPlan,
})
await this.statisticsStore.setMeasure(StatisticsMeasure.ProPlansMRR, proPlansMrrDiff, [
Period.Today,
Period.ThisMonth,
Period.ThisYear,
])
const plusPlansMrrDiff = await this.revenueModificationRepository.sumMRRDiff({
planName: SubscriptionName.PlusPlan,
})
await this.statisticsStore.setMeasure(StatisticsMeasure.PlusPlansMRR, plusPlansMrrDiff, [
Period.Today,
Period.ThisMonth,
Period.ThisYear,
])
return MonthlyRevenue.create(mrrDiff)
}
}
@@ -0,0 +1,2 @@
/* eslint-disable @typescript-eslint/no-empty-interface */
export interface CalculateMonthlyRecurringRevenueDTO {}
@@ -1,4 +1,4 @@
import { Result } from '../Core/Result' import { Result } from '@standardnotes/domain-core'
export interface DomainUseCaseInterface<T> { export interface DomainUseCaseInterface<T> {
execute(...args: any[]): Promise<Result<T>> execute(...args: any[]): Promise<Result<T>>
@@ -1,7 +1,7 @@
import { inject, injectable } from 'inversify' import { inject, injectable } from 'inversify'
import { Email, Uuid } from '@standardnotes/domain-core'
import TYPES from '../../../Bootstrap/Types' import TYPES from '../../../Bootstrap/Types'
import { Email } from '../../Common/Email'
import { Uuid } from '../../Common/Uuid'
import { AnalyticsEntityRepositoryInterface } from '../../Entity/AnalyticsEntityRepositoryInterface' import { AnalyticsEntityRepositoryInterface } from '../../Entity/AnalyticsEntityRepositoryInterface'
import { UseCaseInterface } from '../UseCaseInterface' import { UseCaseInterface } from '../UseCaseInterface'
import { GetUserAnalyticsIdDTO } from './GetUserAnalyticsIdDTO' import { GetUserAnalyticsIdDTO } from './GetUserAnalyticsIdDTO'
@@ -1,5 +1,4 @@
import { Email } from '../../Common/Email' import { Email, Uuid } from '@standardnotes/domain-core'
import { Uuid } from '../../Common/Uuid'
export type GetUserAnalyticsIdResponse = { export type GetUserAnalyticsIdResponse = {
analyticsId: number analyticsId: number
@@ -1,5 +1,7 @@
import 'reflect-metadata' import 'reflect-metadata'
import { TimerInterface } from '@standardnotes/time'
import { Email } from '../../Common/Email' import { Email } from '../../Common/Email'
import { Uuid } from '../../Common/Uuid' import { Uuid } from '../../Common/Uuid'
import { MonthlyRevenue } from '../../Revenue/MonthlyRevenue' import { MonthlyRevenue } from '../../Revenue/MonthlyRevenue'
@@ -9,24 +11,35 @@ import { RevenueModificationRepositoryInterface } from '../../Revenue/RevenueMod
import { SubscriptionEventType } from '../../Subscription/SubscriptionEventType' import { SubscriptionEventType } from '../../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../../Subscription/SubscriptionPlanName' import { SubscriptionPlanName } from '../../Subscription/SubscriptionPlanName'
import { SaveRevenueModification } from './SaveRevenueModification' import { SaveRevenueModification } from './SaveRevenueModification'
import { User } from '../../User/User'
import { Result } from '../../Core/Result'
import { Subscription } from '../../Subscription/Subscription'
describe('SaveRevenueModification', () => { describe('SaveRevenueModification', () => {
let revenueModificationRepository: RevenueModificationRepositoryInterface let revenueModificationRepository: RevenueModificationRepositoryInterface
let previousMonthlyRevenue: RevenueModification let previousMonthlyRevenueModification: RevenueModification
let timer: TimerInterface
const createUseCase = () => new SaveRevenueModification(revenueModificationRepository) const createUseCase = () => new SaveRevenueModification(revenueModificationRepository, timer)
beforeEach(() => { beforeEach(() => {
previousMonthlyRevenue = { const previousMonthlyRevenue = {
newMonthlyRevenue: MonthlyRevenue.create(2).getValue(), value: 2,
} as jest.Mocked<MonthlyRevenue>
previousMonthlyRevenueModification = {
props: {},
} as jest.Mocked<RevenueModification> } as jest.Mocked<RevenueModification>
previousMonthlyRevenueModification.props.newMonthlyRevenue = previousMonthlyRevenue
revenueModificationRepository = {} as jest.Mocked<RevenueModificationRepositoryInterface> revenueModificationRepository = {} as jest.Mocked<RevenueModificationRepositoryInterface>
revenueModificationRepository.findLastByUserUuid = jest.fn().mockReturnValue(previousMonthlyRevenue) revenueModificationRepository.findLastByUserUuid = jest.fn().mockReturnValue(previousMonthlyRevenueModification)
revenueModificationRepository.save = jest.fn() revenueModificationRepository.save = jest.fn()
timer = {} as jest.Mocked<TimerInterface>
timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(1)
}) })
it('should persist a revenue modification', async () => { it('should persist a revenue modification for subscription purchased event', async () => {
const revenueOrError = await createUseCase().execute({ const revenueOrError = await createUseCase().execute({
billingFrequency: 1, billingFrequency: 1,
eventType: SubscriptionEventType.create('SUBSCRIPTION_PURCHASED').getValue(), eventType: SubscriptionEventType.create('SUBSCRIPTION_PURCHASED').getValue(),
@@ -37,8 +50,166 @@ describe('SaveRevenueModification', () => {
userEmail: Email.create('test@test.te').getValue(), userEmail: Email.create('test@test.te').getValue(),
userUuid: Uuid.create('1-2-3').getValue(), userUuid: Uuid.create('1-2-3').getValue(),
}) })
expect(revenueOrError.isFailed()).toBeFalsy() expect(revenueOrError.isFailed()).toBeFalsy()
const revenue = revenueOrError.getValue() const revenue = revenueOrError.getValue()
expect(revenue.newMonthlyRevenue.value).toEqual(12.99)
expect(revenue.props.newMonthlyRevenue.value).toEqual(12.99)
})
it('should persist a revenue modification for subscription expired event', async () => {
const revenueOrError = await createUseCase().execute({
billingFrequency: 1,
eventType: SubscriptionEventType.create('SUBSCRIPTION_EXPIRED').getValue(),
newSubscriber: true,
payedAmount: 12.99,
planName: SubscriptionPlanName.create('PRO_PLAN').getValue(),
subscriptionId: 1234,
userEmail: Email.create('test@test.te').getValue(),
userUuid: Uuid.create('1-2-3').getValue(),
})
expect(revenueOrError.isFailed()).toBeFalsy()
const revenue = revenueOrError.getValue()
expect(revenue.props.newMonthlyRevenue.value).toEqual(0)
})
it('should persist a revenue modification for subscription cancelled event', async () => {
const revenueOrError = await createUseCase().execute({
billingFrequency: 1,
eventType: SubscriptionEventType.create('SUBSCRIPTION_CANCELLED').getValue(),
newSubscriber: true,
payedAmount: 2,
planName: SubscriptionPlanName.create('PRO_PLAN').getValue(),
subscriptionId: 1234,
userEmail: Email.create('test@test.te').getValue(),
userUuid: Uuid.create('1-2-3').getValue(),
})
expect(revenueOrError.isFailed()).toBeFalsy()
const revenue = revenueOrError.getValue()
expect(revenue.props.newMonthlyRevenue.value).toEqual(2)
})
it('should persist a revenue modification for subscription purchased event if previous revenue modification did not exist', async () => {
revenueModificationRepository.findLastByUserUuid = jest.fn().mockReturnValue(null)
const revenueOrError = await createUseCase().execute({
billingFrequency: 1,
eventType: SubscriptionEventType.create('SUBSCRIPTION_PURCHASED').getValue(),
newSubscriber: true,
payedAmount: 12.99,
planName: SubscriptionPlanName.create('PRO_PLAN').getValue(),
subscriptionId: 1234,
userEmail: Email.create('test@test.te').getValue(),
userUuid: Uuid.create('1-2-3').getValue(),
})
expect(revenueOrError.isFailed()).toBeFalsy()
const revenue = revenueOrError.getValue()
expect(revenue.props.newMonthlyRevenue.value).toEqual(12.99)
})
it('should not persist a revenue modification if failed to create user', async () => {
const mock = jest.spyOn(User, 'create')
mock.mockReturnValue(Result.fail('Oops'))
const revenueOrError = await createUseCase().execute({
billingFrequency: 1,
eventType: SubscriptionEventType.create('SUBSCRIPTION_PURCHASED').getValue(),
newSubscriber: true,
payedAmount: 12.99,
planName: SubscriptionPlanName.create('PRO_PLAN').getValue(),
subscriptionId: 1234,
userEmail: Email.create('test@test.te').getValue(),
userUuid: Uuid.create('1-2-3').getValue(),
})
expect(revenueOrError.isFailed()).toBeTruthy()
mock.mockRestore()
})
it('should not persist a revenue modification if failed to create a subscription', async () => {
const mock = jest.spyOn(Subscription, 'create')
mock.mockReturnValue(Result.fail('Oops'))
const revenueOrError = await createUseCase().execute({
billingFrequency: 1,
eventType: SubscriptionEventType.create('SUBSCRIPTION_PURCHASED').getValue(),
newSubscriber: true,
payedAmount: 12.99,
planName: SubscriptionPlanName.create('PRO_PLAN').getValue(),
subscriptionId: 1234,
userEmail: Email.create('test@test.te').getValue(),
userUuid: Uuid.create('1-2-3').getValue(),
})
expect(revenueOrError.isFailed()).toBeTruthy()
mock.mockRestore()
})
it('should not persist a revenue modification if failed to create a previous monthly revenue', async () => {
const mock = jest.spyOn(MonthlyRevenue, 'create')
mock.mockReturnValue(Result.fail('Oops'))
const revenueOrError = await createUseCase().execute({
billingFrequency: 1,
eventType: SubscriptionEventType.create('SUBSCRIPTION_PURCHASED').getValue(),
newSubscriber: true,
payedAmount: 12.99,
planName: SubscriptionPlanName.create('PRO_PLAN').getValue(),
subscriptionId: 1234,
userEmail: Email.create('test@test.te').getValue(),
userUuid: Uuid.create('1-2-3').getValue(),
})
expect(revenueOrError.isFailed()).toBeTruthy()
mock.mockRestore()
})
it('should not persist a revenue modification if failed to create a next monthly revenue', async () => {
const mock = jest.spyOn(MonthlyRevenue, 'create')
mock.mockReturnValueOnce(Result.ok()).mockReturnValueOnce(Result.fail('Oops'))
const revenueOrError = await createUseCase().execute({
billingFrequency: 1,
eventType: SubscriptionEventType.create('SUBSCRIPTION_PURCHASED').getValue(),
newSubscriber: true,
payedAmount: 12.99,
planName: SubscriptionPlanName.create('PRO_PLAN').getValue(),
subscriptionId: 1234,
userEmail: Email.create('test@test.te').getValue(),
userUuid: Uuid.create('1-2-3').getValue(),
})
expect(revenueOrError.isFailed()).toBeTruthy()
mock.mockRestore()
})
it('should not persist a revenue modification if failed to create it', async () => {
const mock = jest.spyOn(RevenueModification, 'create')
mock.mockReturnValue(Result.fail('Oops'))
const revenueOrError = await createUseCase().execute({
billingFrequency: 1,
eventType: SubscriptionEventType.create('SUBSCRIPTION_PURCHASED').getValue(),
newSubscriber: true,
payedAmount: 12.99,
planName: SubscriptionPlanName.create('PRO_PLAN').getValue(),
subscriptionId: 1234,
userEmail: Email.create('test@test.te').getValue(),
userUuid: Uuid.create('1-2-3').getValue(),
})
expect(revenueOrError.isFailed()).toBeTruthy()
mock.mockRestore()
}) })
}) })
@@ -1,30 +1,38 @@
import { inject, injectable } from 'inversify' import { inject, injectable } from 'inversify'
import { Result, UniqueEntityId } from '@standardnotes/domain-core'
import TYPES from '../../../Bootstrap/Types' import TYPES from '../../../Bootstrap/Types'
import { UniqueEntityId } from '../../Core/UniqueEntityId'
import { MonthlyRevenue } from '../../Revenue/MonthlyRevenue' import { MonthlyRevenue } from '../../Revenue/MonthlyRevenue'
import { RevenueModification } from '../../Revenue/RevenueModification' import { RevenueModification } from '../../Revenue/RevenueModification'
import { RevenueModificationRepositoryInterface } from '../../Revenue/RevenueModificationRepositoryInterface' import { RevenueModificationRepositoryInterface } from '../../Revenue/RevenueModificationRepositoryInterface'
import { Subscription } from '../../Subscription/Subscription' import { Subscription } from '../../Subscription/Subscription'
import { User } from '../../User/User' import { User } from '../../User/User'
import { Result } from '../../Core/Result'
import { DomainUseCaseInterface } from '../DomainUseCaseInterface' import { DomainUseCaseInterface } from '../DomainUseCaseInterface'
import { SaveRevenueModificationDTO } from './SaveRevenueModificationDTO' import { SaveRevenueModificationDTO } from './SaveRevenueModificationDTO'
import { TimerInterface } from '@standardnotes/time'
import { SubscriptionEventType } from '../../Subscription/SubscriptionEventType'
@injectable() @injectable()
export class SaveRevenueModification implements DomainUseCaseInterface<RevenueModification> { export class SaveRevenueModification implements DomainUseCaseInterface<RevenueModification> {
constructor( constructor(
@inject(TYPES.RevenueModificationRepository) @inject(TYPES.RevenueModificationRepository)
private revenueModificationRepository: RevenueModificationRepositoryInterface, private revenueModificationRepository: RevenueModificationRepositoryInterface,
@inject(TYPES.Timer) private timer: TimerInterface,
) {} ) {}
async execute(dto: SaveRevenueModificationDTO): Promise<Result<RevenueModification>> { async execute(dto: SaveRevenueModificationDTO): Promise<Result<RevenueModification>> {
const user = User.create( const userOrError = User.create(
{ {
email: dto.userEmail, email: dto.userEmail,
}, },
new UniqueEntityId(dto.userUuid.value), new UniqueEntityId(dto.userUuid.value),
) )
const subscription = Subscription.create( if (userOrError.isFailed()) {
return Result.fail<RevenueModification>(userOrError.getError())
}
const user = userOrError.getValue()
const subscriptionOrError = Subscription.create(
{ {
isFirstSubscriptionForUser: dto.newSubscriber, isFirstSubscriptionForUser: dto.newSubscriber,
payedAmount: dto.payedAmount, payedAmount: dto.payedAmount,
@@ -33,22 +41,77 @@ export class SaveRevenueModification implements DomainUseCaseInterface<RevenueMo
}, },
new UniqueEntityId(dto.subscriptionId), new UniqueEntityId(dto.subscriptionId),
) )
if (subscriptionOrError.isFailed()) {
return Result.fail<RevenueModification>(subscriptionOrError.getError())
}
const subscription = subscriptionOrError.getValue()
const previousMonthlyRevenueOrError = MonthlyRevenue.create(0)
if (previousMonthlyRevenueOrError.isFailed()) {
return Result.fail<RevenueModification>(previousMonthlyRevenueOrError.getError())
}
let previousMonthlyRevenue = previousMonthlyRevenueOrError.getValue()
let previousMonthlyRevenue = MonthlyRevenue.create(0).getValue()
const previousRevenueModification = await this.revenueModificationRepository.findLastByUserUuid(dto.userUuid) const previousRevenueModification = await this.revenueModificationRepository.findLastByUserUuid(dto.userUuid)
if (previousRevenueModification !== null) { if (previousRevenueModification !== null) {
previousMonthlyRevenue = previousRevenueModification.newMonthlyRevenue previousMonthlyRevenue = previousRevenueModification.props.newMonthlyRevenue
} }
const newMonthlyRevenueOrError = this.calculateNewMonthlyRevenue(
subscription,
previousMonthlyRevenue,
dto.eventType,
)
if (newMonthlyRevenueOrError.isFailed()) {
return Result.fail<RevenueModification>(newMonthlyRevenueOrError.getError())
}
const newMonthlyRevenue = newMonthlyRevenueOrError.getValue()
const revenueModification = RevenueModification.create({ const revenueModificationOrError = RevenueModification.create({
eventType: dto.eventType, eventType: dto.eventType,
subscription, subscription,
user, user,
previousMonthlyRevenue, previousMonthlyRevenue,
newMonthlyRevenue,
createdAt: this.timer.getTimestampInMicroseconds(),
}) })
if (revenueModificationOrError.isFailed()) {
return Result.fail<RevenueModification>(revenueModificationOrError.getError())
}
const revenueModification = revenueModificationOrError.getValue()
await this.revenueModificationRepository.save(revenueModification) await this.revenueModificationRepository.save(revenueModification)
return Result.ok<RevenueModification>(revenueModification) return Result.ok<RevenueModification>(revenueModification)
} }
private calculateNewMonthlyRevenue(
subscription: Subscription,
previousMonthlyRevenue: MonthlyRevenue,
eventType: SubscriptionEventType,
): Result<MonthlyRevenue> {
let revenue = 0
switch (eventType.value) {
case 'SUBSCRIPTION_PURCHASED':
case 'SUBSCRIPTION_RENEWED':
case 'SUBSCRIPTION_DATA_MIGRATED':
revenue = subscription.props.payedAmount / subscription.props.billingFrequency
break
case 'SUBSCRIPTION_EXPIRED':
case 'SUBSCRIPTION_REFUNDED':
revenue = 0
break
case 'SUBSCRIPTION_CANCELLED':
revenue = previousMonthlyRevenue.value
break
}
const monthlyRevenueOrError = MonthlyRevenue.create(revenue)
if (monthlyRevenueOrError.isFailed()) {
return Result.fail<MonthlyRevenue>(monthlyRevenueOrError.getError())
}
return Result.ok<MonthlyRevenue>(monthlyRevenueOrError.getValue())
}
} }
@@ -1,5 +1,5 @@
import { Email } from '../../Common/Email' import { Email, Uuid } from '@standardnotes/domain-core'
import { Uuid } from '../../Common/Uuid'
import { SubscriptionEventType } from '../../Subscription/SubscriptionEventType' import { SubscriptionEventType } from '../../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../../Subscription/SubscriptionPlanName' import { SubscriptionPlanName } from '../../Subscription/SubscriptionPlanName'
@@ -5,7 +5,7 @@ describe('User', () => {
it('should create an entity', () => { it('should create an entity', () => {
const user = User.create({ const user = User.create({
email: Email.create('test@test.te').getValue(), email: Email.create('test@test.te').getValue(),
}) }).getValue()
expect(user.id.toString()).toHaveLength(36) expect(user.id.toString()).toHaveLength(36)
}) })
+4 -4
View File
@@ -1,5 +1,5 @@
import { Entity } from '../Core/Entity' import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { UniqueEntityId } from '../Core/UniqueEntityId'
import { UserProps } from './UserProps' import { UserProps } from './UserProps'
export class User extends Entity<UserProps> { export class User extends Entity<UserProps> {
@@ -11,7 +11,7 @@ export class User extends Entity<UserProps> {
super(props, id) super(props, id)
} }
public static create(props: UserProps, id?: UniqueEntityId): User { public static create(props: UserProps, id?: UniqueEntityId): Result<User> {
return new User(props, id) return Result.ok<User>(new User(props, id))
} }
} }
@@ -1,4 +1,4 @@
import { Email } from '../Common/Email' import { Email } from '@standardnotes/domain-core'
export interface UserProps { export interface UserProps {
email: Email email: Email
@@ -1,8 +1,8 @@
import { inject, injectable } from 'inversify' import { inject, injectable } from 'inversify'
import { Repository } from 'typeorm' import { Repository } from 'typeorm'
import { Uuid } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types' import TYPES from '../../Bootstrap/Types'
import { Uuid } from '../../Domain/Common/Uuid'
import { MapInterface } from '../../Domain/Map/MapInterface' import { MapInterface } from '../../Domain/Map/MapInterface'
import { RevenueModification } from '../../Domain/Revenue/RevenueModification' import { RevenueModification } from '../../Domain/Revenue/RevenueModification'
import { RevenueModificationRepositoryInterface } from '../../Domain/Revenue/RevenueModificationRepositoryInterface' import { RevenueModificationRepositoryInterface } from '../../Domain/Revenue/RevenueModificationRepositoryInterface'
@@ -17,6 +17,25 @@ export class MySQLRevenueModificationRepository implements RevenueModificationRe
private revenueModificationMap: MapInterface<RevenueModification, TypeORMRevenueModification>, private revenueModificationMap: MapInterface<RevenueModification, TypeORMRevenueModification>,
) {} ) {}
async sumMRRDiff(dto: { planName?: string; billingFrequency?: number }): Promise<number> {
const query = this.ormRepository.createQueryBuilder().select('sum(new_mrr - previous_mrr)', 'mrrDiff')
if (dto.planName !== undefined) {
query.where('subscription_plan = :planName', { planName: dto.planName })
}
if (dto.billingFrequency !== undefined) {
query.where('billing_frequency = :billingFrequency', { billingFrequency: dto.billingFrequency })
}
const result = await query.getRawOne()
if (result === undefined) {
return 0
}
return +(+result.mrrDiff).toFixed(2)
}
async findLastByUserUuid(userUuid: Uuid): Promise<RevenueModification | null> { async findLastByUserUuid(userUuid: Uuid): Promise<RevenueModification | null> {
const persistence = await this.ormRepository const persistence = await this.ormRepository
.createQueryBuilder() .createQueryBuilder()
@@ -1,209 +0,0 @@
import * as IORedis from 'ioredis'
import { AnalyticsActivity } from '../../Domain/Analytics/AnalyticsActivity'
import { Period } from '../../Domain/Time/Period'
import { PeriodKeyGeneratorInterface } from '../../Domain/Time/PeriodKeyGeneratorInterface'
import { RedisAnalyticsStore } from './RedisAnalyticsStore'
describe('RedisAnalyticsStore', () => {
let redisClient: IORedis.Redis
let pipeline: IORedis.Pipeline
let periodKeyGenerator: PeriodKeyGeneratorInterface
const createStore = () => new RedisAnalyticsStore(periodKeyGenerator, redisClient)
beforeEach(() => {
pipeline = {} as jest.Mocked<IORedis.Pipeline>
pipeline.incr = jest.fn()
pipeline.setbit = jest.fn()
pipeline.exec = jest.fn()
redisClient = {} as jest.Mocked<IORedis.Redis>
redisClient.pipeline = jest.fn().mockReturnValue(pipeline)
redisClient.incr = jest.fn()
redisClient.setbit = jest.fn()
redisClient.getbit = jest.fn().mockReturnValue(1)
redisClient.bitop = jest.fn()
redisClient.expire = jest.fn()
periodKeyGenerator = {} as jest.Mocked<PeriodKeyGeneratorInterface>
periodKeyGenerator.getPeriodKey = jest.fn().mockReturnValue('period-key')
})
it('should calculate total count over time of activities', async () => {
redisClient.bitcount = jest.fn().mockReturnValue(70)
periodKeyGenerator.getDiscretePeriodKeys = jest.fn().mockReturnValue(['2022-4-24', '2022-4-25', '2022-4-26'])
await createStore().calculateActivityTotalCountOverTime(AnalyticsActivity.Register, Period.Last30Days)
expect(redisClient.bitop).toHaveBeenCalledTimes(1)
expect(redisClient.bitop).toHaveBeenNthCalledWith(
1,
'OR',
'bitmap:action:register:timespan:2022-4-24-2022-4-26',
'bitmap:action:register:timespan:2022-4-24',
'bitmap:action:register:timespan:2022-4-25',
'bitmap:action:register:timespan:2022-4-26',
)
expect(redisClient.bitcount).toHaveBeenCalledWith('bitmap:action:register:timespan:2022-4-24-2022-4-26')
})
it('should not calculate total count over time of activities if period is unsupported', async () => {
let caughtError = null
try {
await createStore().calculateActivityTotalCountOverTime(AnalyticsActivity.Register, Period.LastWeek)
} catch (error) {
caughtError = error
}
expect(caughtError).not.toBeNull()
})
it('should calculate total count changes of activities', async () => {
periodKeyGenerator.getDiscretePeriodKeys = jest.fn().mockReturnValue(['2022-4-24', '2022-4-25', '2022-4-26'])
redisClient.bitcount = jest.fn().mockReturnValueOnce(70).mockReturnValueOnce(71).mockReturnValueOnce(72)
expect(
await createStore().calculateActivityChangesTotalCount(AnalyticsActivity.Register, Period.Last30Days),
).toEqual([
{
periodKey: '2022-4-24',
totalCount: 70,
},
{
periodKey: '2022-4-25',
totalCount: 71,
},
{
periodKey: '2022-4-26',
totalCount: 72,
},
])
expect(redisClient.bitcount).toHaveBeenNthCalledWith(1, 'bitmap:action:register:timespan:2022-4-24')
expect(redisClient.bitcount).toHaveBeenNthCalledWith(2, 'bitmap:action:register:timespan:2022-4-25')
expect(redisClient.bitcount).toHaveBeenNthCalledWith(3, 'bitmap:action:register:timespan:2022-4-26')
})
it('should throw error on calculating total count changes of activities on unsupported period', async () => {
periodKeyGenerator.getDiscretePeriodKeys = jest.fn().mockReturnValue(['2022-4-24', '2022-4-25', '2022-4-26'])
redisClient.bitcount = jest.fn().mockReturnValueOnce(70).mockReturnValueOnce(71).mockReturnValueOnce(72)
let caughtError = null
try {
await createStore().calculateActivityChangesTotalCount(AnalyticsActivity.Register, Period.LastWeek)
} catch (error) {
caughtError = error
}
expect(caughtError).not.toBeNull()
})
it('should calculate total count of activities by period', async () => {
redisClient.bitcount = jest.fn().mockReturnValue(70)
expect(await createStore().calculateActivityTotalCount(AnalyticsActivity.Register, Period.Yesterday)).toEqual(70)
expect(redisClient.bitcount).toHaveBeenCalledWith('bitmap:action:register:timespan:period-key')
})
it('should calculate total count of activities by period key', async () => {
redisClient.bitcount = jest.fn().mockReturnValue(70)
expect(await createStore().calculateActivityTotalCount(AnalyticsActivity.Register, '2022-10-03')).toEqual(70)
expect(redisClient.bitcount).toHaveBeenCalledWith('bitmap:action:register:timespan:2022-10-03')
})
it('should calculate activity retention', async () => {
redisClient.bitcount = jest.fn().mockReturnValueOnce(7).mockReturnValueOnce(10)
expect(
await createStore().calculateActivityRetention(
AnalyticsActivity.Register,
Period.DayBeforeYesterday,
Period.Yesterday,
),
).toEqual(70)
expect(redisClient.bitop).toHaveBeenCalledWith(
'AND',
'bitmap:action:register-register:timespan:period-key',
'bitmap:action:register:timespan:period-key',
'bitmap:action:register:timespan:period-key',
)
})
it('shoud tell if activity was done', async () => {
await createStore().wasActivityDone(AnalyticsActivity.Register, 123, Period.Yesterday)
expect(redisClient.getbit).toHaveBeenCalledWith('bitmap:action:register:timespan:period-key', 123)
})
it('should mark activity as done', async () => {
await createStore().markActivity([AnalyticsActivity.Register], 123, [Period.Today])
expect(pipeline.setbit).toBeCalledTimes(1)
expect(pipeline.setbit).toHaveBeenNthCalledWith(1, 'bitmap:action:register:timespan:period-key', 123, 1)
expect(pipeline.exec).toHaveBeenCalled()
})
it('should mark activities as done', async () => {
await createStore().markActivity([AnalyticsActivity.Register, AnalyticsActivity.SubscriptionPurchased], 123, [
Period.Today,
Period.ThisWeek,
])
expect(pipeline.setbit).toBeCalledTimes(4)
expect(pipeline.setbit).toHaveBeenNthCalledWith(1, 'bitmap:action:register:timespan:period-key', 123, 1)
expect(pipeline.setbit).toHaveBeenNthCalledWith(2, 'bitmap:action:register:timespan:period-key', 123, 1)
expect(pipeline.setbit).toHaveBeenNthCalledWith(
3,
'bitmap:action:subscription-purchased:timespan:period-key',
123,
1,
)
expect(pipeline.setbit).toHaveBeenNthCalledWith(
4,
'bitmap:action:subscription-purchased:timespan:period-key',
123,
1,
)
expect(pipeline.exec).toHaveBeenCalled()
})
it('should unmark activity as done', async () => {
await createStore().unmarkActivity([AnalyticsActivity.Register], 123, [Period.Today])
expect(pipeline.setbit).toBeCalledTimes(1)
expect(pipeline.setbit).toHaveBeenNthCalledWith(1, 'bitmap:action:register:timespan:period-key', 123, 0)
expect(pipeline.exec).toHaveBeenCalled()
})
it('should unmark activities as done', async () => {
await createStore().unmarkActivity([AnalyticsActivity.Register, AnalyticsActivity.SubscriptionPurchased], 123, [
Period.Today,
Period.ThisWeek,
])
expect(pipeline.setbit).toBeCalledTimes(4)
expect(pipeline.setbit).toHaveBeenNthCalledWith(1, 'bitmap:action:register:timespan:period-key', 123, 0)
expect(pipeline.setbit).toHaveBeenNthCalledWith(2, 'bitmap:action:register:timespan:period-key', 123, 0)
expect(pipeline.setbit).toHaveBeenNthCalledWith(
3,
'bitmap:action:subscription-purchased:timespan:period-key',
123,
0,
)
expect(pipeline.setbit).toHaveBeenNthCalledWith(
4,
'bitmap:action:subscription-purchased:timespan:period-key',
123,
0,
)
expect(pipeline.exec).toHaveBeenCalled()
})
})
@@ -1,145 +0,0 @@
import * as IORedis from 'ioredis'
import { StatisticsMeasure } from '../../Domain/Statistics/StatisticsMeasure'
import { Period } from '../../Domain/Time/Period'
import { PeriodKeyGeneratorInterface } from '../../Domain/Time/PeriodKeyGeneratorInterface'
import { RedisStatisticsStore } from './RedisStatisticsStore'
describe('RedisStatisticsStore', () => {
let redisClient: IORedis.Redis
let periodKeyGenerator: PeriodKeyGeneratorInterface
let pipeline: IORedis.Pipeline
const createStore = () => new RedisStatisticsStore(periodKeyGenerator, redisClient)
beforeEach(() => {
pipeline = {} as jest.Mocked<IORedis.Pipeline>
pipeline.incr = jest.fn()
pipeline.incrbyfloat = jest.fn()
pipeline.set = jest.fn()
pipeline.setbit = jest.fn()
pipeline.exec = jest.fn()
redisClient = {} as jest.Mocked<IORedis.Redis>
redisClient.pipeline = jest.fn().mockReturnValue(pipeline)
redisClient.incr = jest.fn()
redisClient.setbit = jest.fn()
redisClient.getbit = jest.fn().mockReturnValue(1)
periodKeyGenerator = {} as jest.Mocked<PeriodKeyGeneratorInterface>
periodKeyGenerator.getPeriodKey = jest.fn().mockReturnValue('period-key')
})
it('should get yesterday out of sync incidents', async () => {
redisClient.get = jest.fn().mockReturnValue(1)
expect(await createStore().getYesterdayOutOfSyncIncidents()).toEqual(1)
})
it('should default to 0 yesterday out of sync incidents', async () => {
redisClient.get = jest.fn().mockReturnValue(null)
expect(await createStore().getYesterdayOutOfSyncIncidents()).toEqual(0)
})
it('should get yesterday application version usage', async () => {
redisClient.keys = jest
.fn()
.mockReturnValue([
'count:action:application-request:1.2.3:timespan:2022-3-10',
'count:action:application-request:2.3.4:timespan:2022-3-10',
])
redisClient.get = jest.fn().mockReturnValueOnce(3).mockReturnValueOnce(4)
expect(await createStore().getYesterdayApplicationUsage()).toEqual([
{ count: 3, version: '1.2.3' },
{ count: 4, version: '2.3.4' },
])
})
it('should get yesterday snjs version usage', async () => {
redisClient.keys = jest
.fn()
.mockReturnValue([
'count:action:snjs-request:1.2.3:timespan:2022-3-10',
'count:action:snjs-request:2.3.4:timespan:2022-3-10',
])
redisClient.get = jest.fn().mockReturnValueOnce(3).mockReturnValueOnce(4)
expect(await createStore().getYesterdaySNJSUsage()).toEqual([
{ count: 3, version: '1.2.3' },
{ count: 4, version: '2.3.4' },
])
})
it('should increment application version usage', async () => {
await createStore().incrementApplicationVersionUsage('1.2.3')
expect(pipeline.incr).toHaveBeenCalled()
expect(pipeline.exec).toHaveBeenCalled()
})
it('should increment snjs version usage', async () => {
await createStore().incrementSNJSVersionUsage('1.2.3')
expect(pipeline.incr).toHaveBeenCalled()
expect(pipeline.exec).toHaveBeenCalled()
})
it('should increment out of sync incedent count', async () => {
await createStore().incrementOutOfSyncIncidents()
expect(pipeline.incr).toHaveBeenCalled()
expect(pipeline.exec).toHaveBeenCalled()
})
it('should set a value to a measure', async () => {
await createStore().setMeasure(StatisticsMeasure.Income, 2, [Period.Today, Period.ThisMonth])
expect(pipeline.set).toHaveBeenCalledTimes(2)
expect(pipeline.exec).toHaveBeenCalled()
})
it('should increment measure by a value', async () => {
await createStore().incrementMeasure(StatisticsMeasure.Income, 2, [Period.Today, Period.ThisMonth])
expect(pipeline.incr).toHaveBeenCalledTimes(2)
expect(pipeline.incrbyfloat).toHaveBeenCalledTimes(2)
expect(pipeline.exec).toHaveBeenCalled()
})
it('should count a measurement average', async () => {
redisClient.get = jest.fn().mockReturnValueOnce('5').mockReturnValueOnce('2')
expect(await createStore().getMeasureAverage(StatisticsMeasure.Income, Period.Today)).toEqual(2 / 5)
})
it('should count a measurement average - 0 increments', async () => {
redisClient.get = jest.fn().mockReturnValueOnce(null).mockReturnValueOnce(null)
expect(await createStore().getMeasureAverage(StatisticsMeasure.Income, Period.Today)).toEqual(0)
})
it('should count a measurement average - 0 total value', async () => {
redisClient.get = jest.fn().mockReturnValueOnce(5).mockReturnValueOnce(null)
expect(await createStore().getMeasureAverage(StatisticsMeasure.Income, Period.Today)).toEqual(0)
})
it('should retrieve a measurement total for period', async () => {
redisClient.get = jest.fn().mockReturnValueOnce(5)
expect(await createStore().getMeasureTotal(StatisticsMeasure.Income, Period.Today)).toEqual(5)
expect(redisClient.get).toHaveBeenCalledWith('count:measure:income:timespan:period-key')
})
it('should retrieve a measurement total for period key', async () => {
redisClient.get = jest.fn().mockReturnValueOnce(5)
expect(await createStore().getMeasureTotal(StatisticsMeasure.Income, '2022-10-03')).toEqual(5)
expect(redisClient.get).toHaveBeenCalledWith('count:measure:income:timespan:2022-10-03')
})
})
@@ -9,6 +9,35 @@ import { PeriodKeyGeneratorInterface } from '../../Domain/Time/PeriodKeyGenerato
export class RedisStatisticsStore implements StatisticsStoreInterface { export class RedisStatisticsStore implements StatisticsStoreInterface {
constructor(private periodKeyGenerator: PeriodKeyGeneratorInterface, private redisClient: IORedis.Redis) {} constructor(private periodKeyGenerator: PeriodKeyGeneratorInterface, private redisClient: IORedis.Redis) {}
async calculateTotalCountOverPeriod(
measure: StatisticsMeasure,
period: Period,
): Promise<{ periodKey: string; totalCount: number }[]> {
if (
![
Period.Last30Days,
Period.Last30DaysIncludingToday,
Period.ThisYear,
Period.Q1ThisYear,
Period.Q2ThisYear,
Period.Q3ThisYear,
Period.Q4ThisYear,
].includes(period)
) {
throw new Error(`Unsuporrted period: ${period}`)
}
const periodKeys = this.periodKeyGenerator.getDiscretePeriodKeys(period)
const counts = []
for (const periodKey of periodKeys) {
counts.push({
periodKey,
totalCount: await this.getMeasureTotal(measure, periodKey),
})
}
return counts
}
async getMeasureIncrementCounts(measure: StatisticsMeasure, period: Period): Promise<number> { async getMeasureIncrementCounts(measure: StatisticsMeasure, period: Period): Promise<number> {
const increments = await this.redisClient.get( const increments = await this.redisClient.get(
`count:increments:${measure}:timespan:${this.periodKeyGenerator.getPeriodKey(period)}`, `count:increments:${measure}:timespan:${this.periodKeyGenerator.getPeriodKey(period)}`,
@@ -49,11 +49,19 @@ export class TypeORMRevenueModification {
@Column({ @Column({
name: 'previous_mrr', name: 'previous_mrr',
type: 'float',
}) })
declare previousMonthlyRevenue: number declare previousMonthlyRevenue: number
@Column({ @Column({
name: 'new_mrr', name: 'new_mrr',
type: 'float',
}) })
declare newMonthlyRevenue: number declare newMonthlyRevenue: number
@Column({
name: 'created_at',
type: 'bigint',
})
declare createdAt: number
} }
+62
View File
@@ -3,6 +3,68 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.38.4...@standardnotes/api-gateway@1.38.5) (2022-11-14)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.38.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.38.1...@standardnotes/api-gateway@1.38.4) (2022-11-14)
### Bug Fixes
* **api-gateway:** bump version ([6f5e9b7](https://github.com/standardnotes/api-gateway/commit/6f5e9b7b5a83a9e8894f1dff5cfc91228d90b7b4))
## [1.38.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.38.0...@standardnotes/api-gateway@1.38.1) (2022-11-14)
**Note:** Version bump only for package @standardnotes/api-gateway
# [1.38.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.11...@standardnotes/api-gateway@1.38.0) (2022-11-13)
### Features
* iap confirm endpoint ([#338](https://github.com/standardnotes/api-gateway/issues/338)) ([3bba367](https://github.com/standardnotes/api-gateway/commit/3bba36742ac00c8756dd69f3a81ea124538d5cbe))
## [1.37.11](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.10...@standardnotes/api-gateway@1.37.11) (2022-11-11)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.37.10](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.9...@standardnotes/api-gateway@1.37.10) (2022-11-11)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.37.9](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.8...@standardnotes/api-gateway@1.37.9) (2022-11-10)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.37.8](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.7...@standardnotes/api-gateway@1.37.8) (2022-11-10)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.37.7](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.6...@standardnotes/api-gateway@1.37.7) (2022-11-10)
### Bug Fixes
* **api-gateway:** setting headers ([3c2ac05](https://github.com/standardnotes/api-gateway/commit/3c2ac05c606371305b76dd368d5fe9287045f380))
## [1.37.6](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.5...@standardnotes/api-gateway@1.37.6) (2022-11-10)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.37.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.4...@standardnotes/api-gateway@1.37.5) (2022-11-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.37.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.3...@standardnotes/api-gateway@1.37.4) (2022-11-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.37.3](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.2...@standardnotes/api-gateway@1.37.3) (2022-11-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.37.2](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.1...@standardnotes/api-gateway@1.37.2) (2022-11-09)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.37.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.0...@standardnotes/api-gateway@1.37.1) (2022-11-09) ## [1.37.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.37.0...@standardnotes/api-gateway@1.37.1) (2022-11-09)
**Note:** Version bump only for package @standardnotes/api-gateway **Note:** Version bump only for package @standardnotes/api-gateway
+1 -1
View File
@@ -1,4 +1,4 @@
FROM node:16.15.1-alpine FROM node:18.12.1-alpine
RUN apk add --update \ RUN apk add --update \
curl \ curl \
+12 -11
View File
@@ -1,8 +1,8 @@
{ {
"name": "@standardnotes/api-gateway", "name": "@standardnotes/api-gateway",
"version": "1.37.1", "version": "1.38.5",
"engines": { "engines": {
"node": ">=16.0.0 <17.0.0" "node": ">=18.0.0 <19.0.0"
}, },
"private": true, "private": true,
"description": "API Gateway For Standard Notes Services", "description": "API Gateway For Standard Notes Services",
@@ -20,35 +20,36 @@
"upgrade:snjs": "yarn ncu -u '@standardnotes/*'" "upgrade:snjs": "yarn ncu -u '@standardnotes/*'"
}, },
"dependencies": { "dependencies": {
"@newrelic/native-metrics": "^9.0.0",
"@newrelic/winston-enricher": "^4.0.0", "@newrelic/winston-enricher": "^4.0.0",
"@sentry/node": "^7.3.0", "@sentry/node": "^7.19.0",
"@standardnotes/common": "workspace:^", "@standardnotes/common": "workspace:^",
"@standardnotes/domain-events": "workspace:*", "@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*", "@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/security": "workspace:*", "@standardnotes/security": "workspace:*",
"@standardnotes/time": "workspace:*", "@standardnotes/time": "workspace:*",
"aws-sdk": "^2.1160.0", "aws-sdk": "^2.1253.0",
"axios": "^0.27.2", "axios": "^1.1.3",
"cors": "2.8.5", "cors": "2.8.5",
"dotenv": "^16.0.1", "dotenv": "^16.0.1",
"express": "^4.18.1", "express": "^4.18.2",
"helmet": "^6.0.0", "helmet": "^6.0.0",
"inversify": "^6.0.1", "inversify": "^6.0.1",
"inversify-express-utils": "^6.4.3", "inversify-express-utils": "^6.4.3",
"ioredis": "^5.2.0", "ioredis": "^5.2.4",
"jsonwebtoken": "8.5.1", "jsonwebtoken": "8.5.1",
"newrelic": "^9.0.0", "newrelic": "^9.6.0",
"prettyjson": "^1.2.5", "prettyjson": "^1.2.5",
"reflect-metadata": "0.1.13", "reflect-metadata": "0.1.13",
"winston": "^3.8.1" "winston": "^3.8.1"
}, },
"devDependencies": { "devDependencies": {
"@types/cors": "^2.8.9", "@types/cors": "^2.8.9",
"@types/express": "^4.17.11", "@types/express": "^4.17.14",
"@types/ioredis": "^4.28.10", "@types/ioredis": "^5.0.0",
"@types/jest": "^29.1.1", "@types/jest": "^29.1.1",
"@types/jsonwebtoken": "^8.5.0", "@types/jsonwebtoken": "^8.5.0",
"@types/newrelic": "^7.0.3", "@types/newrelic": "^7.0.4",
"@types/prettyjson": "^0.0.30", "@types/prettyjson": "^0.0.30",
"@typescript-eslint/eslint-plugin": "^5.29.0", "@typescript-eslint/eslint-plugin": "^5.29.0",
"eslint": "^8.14.0", "eslint": "^8.14.0",
@@ -1,5 +1,7 @@
import * as winston from 'winston' import * as winston from 'winston'
import axios, { AxiosInstance } from 'axios' // eslint-disable-next-line @typescript-eslint/no-var-requires
const axios = require('axios')
import { AxiosInstance } from 'axios'
import Redis from 'ioredis' import Redis from 'ioredis'
import { Container } from 'inversify' import { Container } from 'inversify'
import { Timer, TimerInterface } from '@standardnotes/time' import { Timer, TimerInterface } from '@standardnotes/time'
@@ -60,7 +60,7 @@ export class AuthMiddleware extends BaseMiddleware {
}) })
if (authResponse.status > 200) { if (authResponse.status > 200) {
response.setHeader('content-type', authResponse.headers['content-type']) response.setHeader('content-type', authResponse.headers['content-type'] as string)
response.status(authResponse.status).send(authResponse.data) response.status(authResponse.status).send(authResponse.data)
return return
@@ -20,7 +20,8 @@ export class SubscriptionTokenAuthMiddleware extends BaseMiddleware {
} }
async handler(request: Request, response: Response, next: NextFunction): Promise<void> { async handler(request: Request, response: Response, next: NextFunction): Promise<void> {
const subscriptionToken = request.query.subscription_token const subscriptionToken = request.query.subscription_token || request.body.subscription_token
const email = request.headers['x-offline-email'] const email = request.headers['x-offline-email']
if (!subscriptionToken) { if (!subscriptionToken) {
response.status(401).send({ response.status(401).send({
@@ -58,7 +59,7 @@ export class SubscriptionTokenAuthMiddleware extends BaseMiddleware {
}) })
if (authResponse.status > 200) { if (authResponse.status > 200) {
response.setHeader('content-type', authResponse.headers['content-type']) response.setHeader('content-type', authResponse.headers['content-type'] as string)
response.status(authResponse.status).send(authResponse.data) response.status(authResponse.status).send(authResponse.data)
return return
@@ -48,7 +48,7 @@ export class WebSocketAuthMiddleware extends BaseMiddleware {
}) })
if (authResponse.status > 200) { if (authResponse.status > 200) {
response.setHeader('content-type', authResponse.headers['content-type']) response.setHeader('content-type', authResponse.headers['content-type'] as string)
response.status(authResponse.status).send(authResponse.data) response.status(authResponse.status).send(authResponse.data)
return return
@@ -45,6 +45,11 @@ export class PaymentsController extends BaseHttpController {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/tiered', request.body) await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/tiered', request.body)
} }
@httpPost('/subscriptions/apple_iap_confirm', TYPES.SubscriptionTokenAuthMiddleware)
async appleIAPConfirm(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, 'api/subscriptions/apple_iap_confirm', request.body)
}
@all('/subscriptions(/*)?') @all('/subscriptions(/*)?')
async subscriptions(request: Request, response: Response): Promise<void> { async subscriptions(request: Request, response: Response): Promise<void> {
await this.httpService.callPaymentsServer(request, response, request.path.replace('v1', 'api'), request.body) await this.httpService.callPaymentsServer(request, response, request.path.replace('v1', 'api'), request.body)
+62
View File
@@ -3,6 +3,68 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.59.11](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.59.10...@standardnotes/auth-server@1.59.11) (2022-11-14)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.59.10](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.59.7...@standardnotes/auth-server@1.59.10) (2022-11-14)
### Bug Fixes
* versioning issue ([7ca377f](https://github.com/standardnotes/server/commit/7ca377f1b889379e6a43a66c0134bf266763516d))
## [1.59.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.59.6...@standardnotes/auth-server@1.59.7) (2022-11-14)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.59.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.59.5...@standardnotes/auth-server@1.59.6) (2022-11-11)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.59.5](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.59.4...@standardnotes/auth-server@1.59.5) (2022-11-11)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.59.4](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.59.3...@standardnotes/auth-server@1.59.4) (2022-11-10)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.59.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.59.2...@standardnotes/auth-server@1.59.3) (2022-11-10)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.59.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.59.1...@standardnotes/auth-server@1.59.2) (2022-11-10)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.59.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.59.0...@standardnotes/auth-server@1.59.1) (2022-11-10)
**Note:** Version bump only for package @standardnotes/auth-server
# [1.59.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.58.0...@standardnotes/auth-server@1.59.0) (2022-11-09)
### Features
* **analytics:** add saving revenue modifications upon subscription canceled ([52a257a](https://github.com/standardnotes/server/commit/52a257abb16034134a50474fbbb2493a00c58b99))
# [1.58.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.57.0...@standardnotes/auth-server@1.58.0) (2022-11-09)
### Features
* **analytics:** add saving revenue modifications upon subscription refunded ([0f65c05](https://github.com/standardnotes/server/commit/0f65c051abcff805e920f91d338e5fadda7905a9))
# [1.57.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.56.0...@standardnotes/auth-server@1.57.0) (2022-11-09)
### Features
* **analytics:** add saving revenue modifications upon subscription expired ([5c3db2c](https://github.com/standardnotes/server/commit/5c3db2cb29a929e44b63eb8226ce4ad1d14f8a99))
# [1.56.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.55.0...@standardnotes/auth-server@1.56.0) (2022-11-09)
### Features
* **analytics:** add saving revenue modifications upon subscription renewed ([cdb7fcf](https://github.com/standardnotes/server/commit/cdb7fcf8311fecfabe3ef9eb656cd6ec57b87de0))
# [1.55.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.54.0...@standardnotes/auth-server@1.55.0) (2022-11-09) # [1.55.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.54.0...@standardnotes/auth-server@1.55.0) (2022-11-09)
### Features ### Features
+1 -1
View File
@@ -1,4 +1,4 @@
FROM node:16.15.1-alpine FROM node:18.12.1-alpine
RUN apk add --update \ RUN apk add --update \
curl \ curl \

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