mirror of
https://github.com/standardnotes/server
synced 2026-01-17 05:04:27 -05:00
Compare commits
407 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29c56c6919 | ||
|
|
c98ed9cc85 | ||
|
|
88f7530c13 | ||
|
|
bb820437af | ||
|
|
d1a4bd38e0 | ||
|
|
d18f6ccd32 | ||
|
|
aa317c964e | ||
|
|
7ae8845ae9 | ||
|
|
123a6dbe0c | ||
|
|
dda8d79526 | ||
|
|
de5293955a | ||
|
|
96669bff5b | ||
|
|
a99762f004 | ||
|
|
1fc3c9b83e | ||
|
|
af86b6f664 | ||
|
|
a0208dd5b3 | ||
|
|
1c5c8b81d5 | ||
|
|
79c3e33434 | ||
|
|
5ab8729a31 | ||
|
|
db0baf92f1 | ||
|
|
a8974094db | ||
|
|
13c5c97ba7 | ||
|
|
894ebb3edd | ||
|
|
cac899a7e5 | ||
|
|
901e0dd93b | ||
|
|
a360231fd0 | ||
|
|
6ccc6ee42f | ||
|
|
9c72ad85a0 | ||
|
|
fa6d80a753 | ||
|
|
f6ab2ca9ba | ||
|
|
ba1e1ad5ad | ||
|
|
02705ea3ad | ||
|
|
df6e3f06a6 | ||
|
|
1cb5ee9fd6 | ||
|
|
893d6176c3 | ||
|
|
2c1b512e40 | ||
|
|
de50d76800 | ||
|
|
401b78e477 | ||
|
|
01837eaea9 | ||
|
|
7df699353c | ||
|
|
5455972be2 | ||
|
|
57488bcd16 | ||
|
|
b6fda901ef | ||
|
|
14669df890 | ||
|
|
64525a65f2 | ||
|
|
61fc7efecb | ||
|
|
8c7c1e4745 | ||
|
|
f64d30ec88 | ||
|
|
384dfc8da4 | ||
|
|
841784ae8c | ||
|
|
f5683cfd94 | ||
|
|
0a420ce30e | ||
|
|
a5e7132d3c | ||
|
|
6dfb2be4a2 | ||
|
|
d81cbad550 | ||
|
|
51ad06b303 | ||
|
|
27048ad95c | ||
|
|
fa9bf0b448 | ||
|
|
305190b64e | ||
|
|
98e3d18335 | ||
|
|
72e398956b | ||
|
|
1e69a13a97 | ||
|
|
7f9e6e2f44 | ||
|
|
d3c6c0d48e | ||
|
|
6c83476fd2 | ||
|
|
9cdf7e2c51 | ||
|
|
599119e14e | ||
|
|
a2c484e0f3 | ||
|
|
97ff4d5ac2 | ||
|
|
5255cfbb25 | ||
|
|
780358368b | ||
|
|
cf0b918913 | ||
|
|
4ea690204e | ||
|
|
14eb775749 | ||
|
|
bf4a3be6d9 | ||
|
|
b9e1e47871 | ||
|
|
ff532ecb22 | ||
|
|
eb21872db1 | ||
|
|
8e3df184dc | ||
|
|
b34bbcac8b | ||
|
|
226965a1d7 | ||
|
|
17b2ea126c | ||
|
|
59fc4a089c | ||
|
|
ef26dc8cbb | ||
|
|
8a0fbb28b0 | ||
|
|
618d8d5b1a | ||
|
|
3a936dc9c1 | ||
|
|
031fcd75ee | ||
|
|
c8cd23cb32 | ||
|
|
a3049938a3 | ||
|
|
b23488e862 | ||
|
|
c8203cf04c | ||
|
|
4f2616ef0a | ||
|
|
04ffc69e00 | ||
|
|
5b4bb6e7a7 | ||
|
|
2e953ba998 | ||
|
|
ed5a4eb960 | ||
|
|
31b2c05084 | ||
|
|
6e1662038c | ||
|
|
df78d88f79 | ||
|
|
addedb3091 | ||
|
|
2ea17b2dea | ||
|
|
85d2f42f47 | ||
|
|
cdb655c1bd | ||
|
|
3064d03aa9 | ||
|
|
6af6417ca2 | ||
|
|
a35271fbb3 | ||
|
|
63aef71f60 | ||
|
|
0f8457534c | ||
|
|
2984582e62 | ||
|
|
147d8fd9af | ||
|
|
c12d354900 | ||
|
|
8bcb552783 | ||
|
|
f504a8288c | ||
|
|
79f5b54228 | ||
|
|
669a9855e6 | ||
|
|
e3b96c3a1f | ||
|
|
7e0d4bef20 | ||
|
|
0bd0f48df3 | ||
|
|
ae56126585 | ||
|
|
6dcf0ac124 | ||
|
|
63e2ce43c2 | ||
|
|
f27aa21eb5 | ||
|
|
42926c663b | ||
|
|
d38116183c | ||
|
|
9ca373e208 | ||
|
|
4084f2f5ec | ||
|
|
684ffbadbc | ||
|
|
1c4d4c57de | ||
|
|
d83111a199 | ||
|
|
f10fa839fb | ||
|
|
1f20395ff3 | ||
|
|
bfe6f4255a | ||
|
|
b9032f3012 | ||
|
|
ce53c459e6 | ||
|
|
6df42fb0d5 | ||
|
|
1e2b496f4f | ||
|
|
528c1b0d57 | ||
|
|
22fba8ba80 | ||
|
|
6f26261ebe | ||
|
|
4b1fe3ba91 | ||
|
|
9f95262bd4 | ||
|
|
2ec28e541e | ||
|
|
4764d4b19a | ||
|
|
9b27547dae | ||
|
|
a96f2c9153 | ||
|
|
225e0aaf88 | ||
|
|
f0c85910bc | ||
|
|
124c443528 | ||
|
|
37c7f8d39f | ||
|
|
c419f1ce22 | ||
|
|
4949cdfe2f | ||
|
|
cd101b96ea | ||
|
|
40d0e4631f | ||
|
|
a55a995660 | ||
|
|
1d576d48ad | ||
|
|
4ff8030f87 | ||
|
|
c15e2e2c8f | ||
|
|
41d31a8d75 | ||
|
|
10e2a26352 | ||
|
|
6e547f77d0 | ||
|
|
530a426601 | ||
|
|
642d6bab77 | ||
|
|
7980af3d82 | ||
|
|
2980c42e88 | ||
|
|
b03994f9db | ||
|
|
41906ec2f9 | ||
|
|
4d1e7ff2a5 | ||
|
|
7f18fcfc13 | ||
|
|
ff02ce0747 | ||
|
|
a6056600eb | ||
|
|
24c94326d5 | ||
|
|
48c0cb5e62 | ||
|
|
9968efe1b2 | ||
|
|
6368342149 | ||
|
|
b5f73db210 | ||
|
|
22d6a02d04 | ||
|
|
4e0bcfcccf | ||
|
|
104313c15d | ||
|
|
814289af46 | ||
|
|
3096cd98d5 | ||
|
|
45dfefbc7a | ||
|
|
20d92149a8 | ||
|
|
9c01fffca5 | ||
|
|
61c1cfff4b | ||
|
|
7e74261f62 | ||
|
|
32601f34f1 | ||
|
|
aef69a1a96 | ||
|
|
130f90bdb6 | ||
|
|
851c7de87f | ||
|
|
118156c62d | ||
|
|
cdad3143c9 | ||
|
|
00fe32136e | ||
|
|
52f56eeb68 | ||
|
|
b595264e31 | ||
|
|
bf04262170 | ||
|
|
fd589922bb | ||
|
|
fb7029f5c1 | ||
|
|
cc4b4f9bf8 | ||
|
|
b048d6d7e3 | ||
|
|
cffc1f442f | ||
|
|
91fe710741 | ||
|
|
5a1eb9fdac | ||
|
|
a64ef6e750 | ||
|
|
47d2012b3d | ||
|
|
2c99cd2e21 | ||
|
|
435cd2f66a | ||
|
|
372b12dfc2 | ||
|
|
3a12f5c1c4 | ||
|
|
781de224b6 | ||
|
|
eff09454c3 | ||
|
|
473feba6a8 | ||
|
|
e9f0704fb0 | ||
|
|
8c99469d88 | ||
|
|
8ec1311dfc | ||
|
|
e48cca6b45 | ||
|
|
d660721f95 | ||
|
|
c52bb93d79 | ||
|
|
ffb6bfd0c9 | ||
|
|
6e0855f9b3 | ||
|
|
ec9e9ec387 | ||
|
|
fa75aa40f0 | ||
|
|
b865953c22 | ||
|
|
2542cf6f9a | ||
|
|
cb9499b87f | ||
|
|
c351f01f67 | ||
|
|
c87561fca7 | ||
|
|
a363c143fa | ||
|
|
fb81d2b926 | ||
|
|
05b1b8f079 | ||
|
|
7848dc06d4 | ||
|
|
3a005719b7 | ||
|
|
6928988f78 | ||
|
|
a521894d7c | ||
|
|
b7fb1d9c08 | ||
|
|
5f67e45911 | ||
|
|
fddf9fccbd | ||
|
|
2bedbd7bd2 | ||
|
|
02f3c85796 | ||
|
|
3b5bd6a47f | ||
|
|
06fd404d44 | ||
|
|
d931c52508 | ||
|
|
800fe9e4c8 | ||
|
|
8b3d78678f | ||
|
|
2351cd3ad6 | ||
|
|
dd86c5bcdf | ||
|
|
d0c00e306e | ||
|
|
6cd68ddd6a | ||
|
|
02639cddb2 | ||
|
|
0f67aa4058 | ||
|
|
78c3403d5f | ||
|
|
fc8f8c574d | ||
|
|
3972ee580d | ||
|
|
b0a994d5be | ||
|
|
80df28a0c4 | ||
|
|
1c6c6a9296 | ||
|
|
7bb698e442 | ||
|
|
784728cd54 | ||
|
|
4b883b68de | ||
|
|
dec2cc2aaf | ||
|
|
b4e8971ad2 | ||
|
|
84e436265e | ||
|
|
ac8a69f8d4 | ||
|
|
b912e050ea | ||
|
|
284561d093 | ||
|
|
efc355982c | ||
|
|
8907879a19 | ||
|
|
86f6057207 | ||
|
|
4c92698c73 | ||
|
|
8407c3b649 | ||
|
|
ed8f82617d | ||
|
|
31d040d1b6 | ||
|
|
25a6796e63 | ||
|
|
ff091918aa | ||
|
|
91b76edce1 | ||
|
|
5ae5c83bf5 | ||
|
|
9d90f276de | ||
|
|
245f091e22 | ||
|
|
ae2f8f086b | ||
|
|
5e5eb7f937 | ||
|
|
748630e1f1 | ||
|
|
43064c8c55 | ||
|
|
4559a3047c | ||
|
|
de8064ee5c | ||
|
|
48c8dba342 | ||
|
|
31a515b2f1 | ||
|
|
294f56e189 | ||
|
|
70596a0aac | ||
|
|
74bc79116b | ||
|
|
e6bd50ae77 | ||
|
|
308662550f | ||
|
|
d94a7e7157 | ||
|
|
630b264754 | ||
|
|
5f2be44b85 | ||
|
|
f68ece68af | ||
|
|
70c829a2c9 | ||
|
|
e3b6ac4874 | ||
|
|
a762d5a22c | ||
|
|
3686a26019 | ||
|
|
80daec748d | ||
|
|
94359f1299 | ||
|
|
59dda1bb99 | ||
|
|
806a732cbc | ||
|
|
7816be7ba7 | ||
|
|
5f3bd5137f | ||
|
|
6c9fc5fb86 | ||
|
|
f7e0b68643 | ||
|
|
b283bbaca9 | ||
|
|
92ba759b1c | ||
|
|
0acc9d8d68 | ||
|
|
daa7a9ff61 | ||
|
|
455f35e0c1 | ||
|
|
1fa655b56e | ||
|
|
e553222b4b | ||
|
|
f1b6f48926 | ||
|
|
14ab1cae69 | ||
|
|
5f9cf90b16 | ||
|
|
97b367d4ee | ||
|
|
47119fb346 | ||
|
|
d77eb7f5f1 | ||
|
|
1b0a2bb34c | ||
|
|
a363039fa1 | ||
|
|
32c740b58e | ||
|
|
822ee890af | ||
|
|
b0406dd8aa | ||
|
|
8d152ddfcb | ||
|
|
1a16d2e4f4 | ||
|
|
1ca8531305 | ||
|
|
6190e7d092 | ||
|
|
a6542dd638 | ||
|
|
840777a851 | ||
|
|
5c9dff38c9 | ||
|
|
abfbacb8c2 | ||
|
|
03afdbf431 | ||
|
|
507d43b328 | ||
|
|
be214c0599 | ||
|
|
91f36c3a3f | ||
|
|
f60c15ed2e | ||
|
|
1ec072373d | ||
|
|
a7d039082e | ||
|
|
d5c06bfa58 | ||
|
|
c8f3a0ce7b | ||
|
|
edbedc181b | ||
|
|
94afa34780 | ||
|
|
74dd0ab6cd | ||
|
|
6c43a331d0 | ||
|
|
67835ba0c0 | ||
|
|
fe1b2a0e07 | ||
|
|
2e82be47ed | ||
|
|
15dfd6dcba | ||
|
|
dfd38943b0 | ||
|
|
500756d582 | ||
|
|
f855f541d8 | ||
|
|
590ec6643d | ||
|
|
b9efd35b50 | ||
|
|
3be1bfe58a | ||
|
|
bfbd2de778 | ||
|
|
50f7ae338a | ||
|
|
280fdc89c1 | ||
|
|
0f94e2ad0c | ||
|
|
d0036600e9 | ||
|
|
f766fefbf0 | ||
|
|
2178ed2a31 | ||
|
|
79511aea5f | ||
|
|
19bb77273b | ||
|
|
7ca377f1b8 | ||
|
|
6f5e9b7b5a | ||
|
|
f03a58079d | ||
|
|
8715fe1822 | ||
|
|
e10cb9adaf | ||
|
|
3030832711 | ||
|
|
7c638ef28a | ||
|
|
447a4b5e04 | ||
|
|
dd1ba6e302 | ||
|
|
08556b751f | ||
|
|
11d2190310 | ||
|
|
46519bb710 | ||
|
|
7b9290382d | ||
|
|
85e55cf0e4 | ||
|
|
7016854b7f | ||
|
|
01a4151763 | ||
|
|
311f758cd8 | ||
|
|
3bba36742a | ||
|
|
ea52ba51ca | ||
|
|
7e404ae71a | ||
|
|
3ad95afa84 | ||
|
|
1a13861647 | ||
|
|
6d84c819c0 | ||
|
|
36ec39d2fb | ||
|
|
eaafc12c8a | ||
|
|
a03c5bceea | ||
|
|
53c51fd204 | ||
|
|
9b593f2a6b | ||
|
|
363609cb1b | ||
|
|
68e6d30093 | ||
|
|
c53a40ef8d | ||
|
|
3c2ac05c60 | ||
|
|
bffab433f6 | ||
|
|
200b6ce01f | ||
|
|
0d29dc1012 | ||
|
|
b92c4ae650 | ||
|
|
e15d1e52bd | ||
|
|
ce3e259bde | ||
|
|
87361f90b1 | ||
|
|
81be06598c | ||
|
|
9492da6789 | ||
|
|
fce47a0a37 |
@@ -187,12 +187,12 @@ jobs:
|
||||
tags: standardnotes/${{ inputs.service_name }}:${{ github.sha }}
|
||||
|
||||
- name: Run E2E test suite
|
||||
uses: convictional/trigger-workflow-and-wait@v1.6.3
|
||||
uses: convictional/trigger-workflow-and-wait@master
|
||||
with:
|
||||
owner: standardnotes
|
||||
repo: e2e
|
||||
repo: self-hosted
|
||||
github_token: ${{ secrets.CI_PAT_TOKEN }}
|
||||
workflow_file_name: testing-with-stable-client.yml
|
||||
workflow_file_name: testing-with-updating-client-and-server.yml
|
||||
wait_interval: 30
|
||||
client_payload: '{"${{ inputs.e2e_tag_parameter_name }}": "${{ github.sha }}"}'
|
||||
propagate_failure: true
|
||||
|
||||
46
.github/workflows/revisions.yml
vendored
Normal file
46
.github/workflows/revisions.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Revisions Server
|
||||
|
||||
concurrency:
|
||||
group: revisions_server
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*standardnotes/revisions-server*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call_server_application_workflow:
|
||||
name: Server Application
|
||||
uses: standardnotes/server/.github/workflows/common-server-application.yml@main
|
||||
with:
|
||||
service_name: revisions
|
||||
workspace_name: "@standardnotes/revisions-server"
|
||||
e2e_tag_parameter_name: revisions_image_tag
|
||||
package_path: packages/revisions
|
||||
secrets: inherit
|
||||
|
||||
newrelic:
|
||||
needs: call_server_application_workflow
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Create New Relic deployment marker for Web
|
||||
uses: newrelic/deployment-marker-action@v1
|
||||
with:
|
||||
accountId: ${{ secrets.NEW_RELIC_ACCOUNT_ID }}
|
||||
apiKey: ${{ secrets.NEW_RELIC_API_KEY }}
|
||||
applicationId: ${{ secrets.NEW_RELIC_APPLICATION_ID_REVISIONS_WEB_PROD }}
|
||||
revision: "${{ github.sha }}"
|
||||
description: "Automated Deployment via Github Actions"
|
||||
user: "${{ github.actor }}"
|
||||
- name: Create New Relic deployment marker for Worker
|
||||
uses: newrelic/deployment-marker-action@v1
|
||||
with:
|
||||
accountId: ${{ secrets.NEW_RELIC_ACCOUNT_ID }}
|
||||
apiKey: ${{ secrets.NEW_RELIC_API_KEY }}
|
||||
applicationId: ${{ secrets.NEW_RELIC_APPLICATION_ID_REVISIONS_WORKER_PROD }}
|
||||
revision: "${{ github.sha }}"
|
||||
description: "Automated Deployment via Github Actions"
|
||||
user: "${{ github.actor }}"
|
||||
6
.prettierrc
Normal file
6
.prettierrc
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 120,
|
||||
"semi": false
|
||||
}
|
||||
BIN
.yarn/cache/@noble-ed25519-npm-1.7.1-177d9beb01-b1aa4b9264.zip
vendored
Normal file
BIN
.yarn/cache/@noble-ed25519-npm-1.7.1-177d9beb01-b1aa4b9264.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@peculiar-asn1-android-npm-2.3.3-28df67d7a3-0c7cad544e.zip
vendored
Normal file
BIN
.yarn/cache/@peculiar-asn1-android-npm-2.3.3-28df67d7a3-0c7cad544e.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@peculiar-asn1-schema-npm-2.3.3-7c2b9469c4-f584f79d5a.zip
vendored
Normal file
BIN
.yarn/cache/@peculiar-asn1-schema-npm-2.3.3-7c2b9469c4-f584f79d5a.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@peculiar-asn1-x509-npm-2.3.4-a579005836-10a8659980.zip
vendored
Normal file
BIN
.yarn/cache/@peculiar-asn1-x509-npm-2.3.4-a579005836-10a8659980.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@sentry-core-npm-7.28.1-a468033ea8-f29d747d3e.zip
vendored
Normal file
BIN
.yarn/cache/@sentry-core-npm-7.28.1-a468033ea8-f29d747d3e.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@sentry-node-npm-7.28.1-b0e124fdfc-b4922d1f0a.zip
vendored
Normal file
BIN
.yarn/cache/@sentry-node-npm-7.28.1-b0e124fdfc-b4922d1f0a.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@sentry-tracing-npm-7.28.1-e15d453d8e-be501ca9d7.zip
vendored
Normal file
BIN
.yarn/cache/@sentry-tracing-npm-7.28.1-e15d453d8e-be501ca9d7.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@sentry-types-npm-7.28.1-42d9a8574c-7dc6639cb7.zip
vendored
Normal file
BIN
.yarn/cache/@sentry-types-npm-7.28.1-42d9a8574c-7dc6639cb7.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@sentry-utils-npm-7.28.1-71eaeb767f-a4b5f73db0.zip
vendored
Normal file
BIN
.yarn/cache/@sentry-utils-npm-7.28.1-71eaeb767f-a4b5f73db0.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@simplewebauthn-server-npm-6.2.2-ca870b05c2-5ffb9b1c15.zip
vendored
Normal file
BIN
.yarn/cache/@simplewebauthn-server-npm-6.2.2-ca870b05c2-5ffb9b1c15.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@simplewebauthn-typescript-types-npm-6.3.0-alpha.1-629da05c10-5667c214e9.zip
vendored
Normal file
BIN
.yarn/cache/@simplewebauthn-typescript-types-npm-6.3.0-alpha.1-629da05c10-5667c214e9.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@types-ioredis-npm-5.0.0-6efa70abfa-439770c9da.zip
vendored
Normal file
BIN
.yarn/cache/@types-ioredis-npm-5.0.0-6efa70abfa-439770c9da.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@types-jsonwebtoken-npm-9.0.1-5f660fdf38-44d3fccc6b.zip
vendored
Normal file
BIN
.yarn/cache/@types-jsonwebtoken-npm-9.0.1-5f660fdf38-44d3fccc6b.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@types-mixpanel-npm-2.14.4-34bd98306f-a2bf6e633e.zip
vendored
Normal file
BIN
.yarn/cache/@types-mixpanel-npm-2.14.4-34bd98306f-a2bf6e633e.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@types-newrelic-npm-7.0.4-4f0b179b51-b44215b3ab.zip
vendored
Normal file
BIN
.yarn/cache/@types-newrelic-npm-7.0.4-4f0b179b51-b44215b3ab.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@types-node-npm-18.11.9-d21dd6ec05-7b7d90894d.zip
vendored
Normal file
BIN
.yarn/cache/@types-node-npm-18.11.9-d21dd6ec05-7b7d90894d.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/asn1.js-npm-5.4.1-37c7edbcb0-5c36f81388.zip
vendored
Normal file
BIN
.yarn/cache/asn1.js-npm-5.4.1-37c7edbcb0-5c36f81388.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/asn1js-npm-3.0.5-cf5558af33-d0bc57da97.zip
vendored
Normal file
BIN
.yarn/cache/asn1js-npm-3.0.5-cf5558af33-d0bc57da97.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/axios-npm-1.1.3-4b63965ac1-2e28acd01c.zip
vendored
Normal file
BIN
.yarn/cache/axios-npm-1.1.3-4b63965ac1-2e28acd01c.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/base64url-npm-3.0.1-4c171c4917-72e1401ffe.zip
vendored
Normal file
BIN
.yarn/cache/base64url-npm-3.0.1-4c171c4917-72e1401ffe.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/bignumber.js-npm-9.1.1-5929e8d8dc-e44d008049.zip
vendored
Normal file
BIN
.yarn/cache/bignumber.js-npm-9.1.1-5929e8d8dc-e44d008049.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/bn.js-npm-4.12.0-3ec6c884f6-bfb4590775.zip
vendored
Normal file
BIN
.yarn/cache/bn.js-npm-4.12.0-3ec6c884f6-bfb4590775.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/brorand-npm-1.1.0-ea86634c4b-f736e127fb.zip
vendored
Normal file
BIN
.yarn/cache/brorand-npm-1.1.0-ea86634c4b-f736e127fb.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/cbor-npm-5.2.0-4f6440587f-d60986b9d0.zip
vendored
Normal file
BIN
.yarn/cache/cbor-npm-5.2.0-4f6440587f-d60986b9d0.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/elliptic-npm-6.5.4-0ca8204a86-4453b008cf.zip
vendored
Normal file
BIN
.yarn/cache/elliptic-npm-6.5.4-0ca8204a86-4453b008cf.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/express-robots-txt-npm-1.0.0-dcc8bd8f0a-54f066f6c3.zip
vendored
Normal file
BIN
.yarn/cache/express-robots-txt-npm-1.0.0-dcc8bd8f0a-54f066f6c3.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/hash.js-npm-1.1.7-f1ad187358-e4266370d1.zip
vendored
Normal file
BIN
.yarn/cache/hash.js-npm-1.1.7-f1ad187358-e4266370d1.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/hmac-drbg-npm-1.0.1-3499ad31cd-4e88d58ffc.zip
vendored
Normal file
BIN
.yarn/cache/hmac-drbg-npm-1.0.1-3499ad31cd-4e88d58ffc.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/https-proxy-agent-npm-5.0.0-bb777903c3-77d11b0e2c.zip
vendored
Normal file
BIN
.yarn/cache/https-proxy-agent-npm-5.0.0-bb777903c3-77d11b0e2c.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/ipaddr.js-npm-2.0.1-04e97280d7-04ce6c896c.zip
vendored
Normal file
BIN
.yarn/cache/ipaddr.js-npm-2.0.1-04e97280d7-04ce6c896c.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/jsonwebtoken-npm-9.0.0-36fd1594c0-7ccbd0b7bf.zip
vendored
Normal file
BIN
.yarn/cache/jsonwebtoken-npm-9.0.0-36fd1594c0-7ccbd0b7bf.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/jsrsasign-npm-10.6.1-a8fa295369-e8e9c1b24f.zip
vendored
Normal file
BIN
.yarn/cache/jsrsasign-npm-10.6.1-a8fa295369-e8e9c1b24f.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/jwk-to-pem-npm-2.0.5-aff7d9f125-fced3a75b0.zip
vendored
Normal file
BIN
.yarn/cache/jwk-to-pem-npm-2.0.5-aff7d9f125-fced3a75b0.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/minimalistic-assert-npm-1.0.1-dc8bb23d29-e2310081d8.zip
vendored
Normal file
BIN
.yarn/cache/minimalistic-assert-npm-1.0.1-dc8bb23d29-e2310081d8.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/minimalistic-crypto-utils-npm-1.0.1-e66b10822e-7d909decd2.zip
vendored
Normal file
BIN
.yarn/cache/minimalistic-crypto-utils-npm-1.0.1-e66b10822e-7d909decd2.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/mixpanel-npm-0.17.0-3073ce9949-5a945bdbdd.zip
vendored
Normal file
BIN
.yarn/cache/mixpanel-npm-0.17.0-3073ce9949-5a945bdbdd.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/newrelic-npm-9.6.0-f10080c2de-eb378acde1.zip
vendored
Normal file
BIN
.yarn/cache/newrelic-npm-9.6.0-f10080c2de-eb378acde1.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/nofilter-npm-1.0.4-1cbdc6c03a-9a26874e7d.zip
vendored
Normal file
BIN
.yarn/cache/nofilter-npm-1.0.4-1cbdc6c03a-9a26874e7d.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/proxy-from-env-npm-1.1.0-c13d07f26b-0bba2ef7c8.zip
vendored
Normal file
BIN
.yarn/cache/proxy-from-env-npm-1.1.0-c13d07f26b-0bba2ef7c8.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/pvtsutils-npm-1.3.2-e1483da905-eb22d3df60.zip
vendored
Normal file
BIN
.yarn/cache/pvtsutils-npm-1.3.2-e1483da905-eb22d3df60.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/pvutils-npm-1.1.3-da8b07d6cf-0cb4f4878f.zip
vendored
Normal file
BIN
.yarn/cache/pvutils-npm-1.1.3-da8b07d6cf-0cb4f4878f.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/semver-npm-7.3.8-25a996cb4f-94ad80ee14.zip
vendored
Normal file
BIN
.yarn/cache/semver-npm-7.3.8-25a996cb4f-94ad80ee14.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/tslib-npm-2.4.1-36f0ed04db-a739a21e3f.zip
vendored
Normal file
BIN
.yarn/cache/tslib-npm-2.4.1-36f0ed04db-a739a21e3f.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/ua-parser-js-npm-1.0.32-95b0b6a78d-9d320c6742.zip
vendored
Normal file
BIN
.yarn/cache/ua-parser-js-npm-1.0.32-95b0b6a78d-9d320c6742.zip
vendored
Normal file
Binary file not shown.
@@ -326,8 +326,8 @@ ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
|
||||
endif
|
||||
|
||||
quiet_cmd_regen_makefile = ACTION Regenerating $@
|
||||
cmd_regen_makefile = cd $(srcdir); /Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/karolsojko/Library/Caches/node-gyp/16.15.1" "-Dnode_gyp_dir=/Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp" "-Dnode_lib_file=/Users/karolsojko/Library/Caches/node-gyp/16.15.1/<(target_arch)/node.lib" "-Dmodule_root_dir=/Users/karolsojko/workspace/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics" "-Dnode_engine=v8" "--depth=." "-Goutput_dir=." "--generator-output=build" -I/Users/karolsojko/workspace/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics/build/config.gypi -I/Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/addon.gypi -I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node/common.gypi "--toplevel-dir=." binding.gyp
|
||||
Makefile: $(srcdir)/binding.gyp $(srcdir)/../../../../node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/addon.gypi $(srcdir)/../../../../../../../../Library/Caches/node-gyp/16.15.1/include/node/common.gypi $(srcdir)/build/config.gypi
|
||||
cmd_regen_makefile = cd $(srcdir); /Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/Users/karolsojko/Library/Caches/node-gyp/18.12.1" "-Dnode_gyp_dir=/Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp" "-Dnode_lib_file=/Users/karolsojko/Library/Caches/node-gyp/18.12.1/<(target_arch)/node.lib" "-Dmodule_root_dir=/Users/karolsojko/workspace/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics" "-Dnode_engine=v8" "--depth=." "-Goutput_dir=." "--generator-output=build" -I/Users/karolsojko/workspace/server/.yarn/unplugged/@newrelic-native-metrics-npm-9.0.0-590d2e713a/node_modules/@newrelic/native-metrics/build/config.gypi -I/Users/karolsojko/workspace/server/.yarn/unplugged/node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/addon.gypi -I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/include/node/common.gypi "--toplevel-dir=." binding.gyp
|
||||
Makefile: $(srcdir)/build/config.gypi $(srcdir)/../../../../node-gyp-npm-9.0.0-0eccfca4d1/node_modules/node-gyp/addon.gypi $(srcdir)/../../../../../../../../Library/Caches/node-gyp/18.12.1/include/node/common.gypi $(srcdir)/binding.gyp
|
||||
$(call do_cmd,regen_makefile)
|
||||
|
||||
# "all" is a concatenation of the "all" targets from all the included
|
||||
|
||||
@@ -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:
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -19,293 +19,316 @@
|
||||
"error_on_warn": "false",
|
||||
"force_dynamic_crt": 0,
|
||||
"host_arch": "x64",
|
||||
"icu_data_in": "../../deps/icu-tmp/icudt70l.dat",
|
||||
"icu_data_in": "../../deps/icu-tmp/icudt71l.dat",
|
||||
"icu_endianness": "l",
|
||||
"icu_gyp_path": "tools/icu/icu-generic.gyp",
|
||||
"icu_path": "deps/icu-small",
|
||||
"icu_small": "false",
|
||||
"icu_ver_major": "70",
|
||||
"icu_ver_major": "71",
|
||||
"is_debug": 0,
|
||||
"libdir": "lib",
|
||||
"llvm_version": "11.0",
|
||||
"napi_build_version": "8",
|
||||
"node_byteorder": "little",
|
||||
"node_debug_lib": "false",
|
||||
"node_enable_d8": "false",
|
||||
"node_fipsinstall": "false",
|
||||
"node_install_corepack": "true",
|
||||
"node_install_npm": "true",
|
||||
"node_library_files": [
|
||||
"lib/constants.js",
|
||||
"lib/net.js",
|
||||
"lib/trace_events.js",
|
||||
"lib/events.js",
|
||||
"lib/repl.js",
|
||||
"lib/util.js",
|
||||
"lib/dgram.js",
|
||||
"lib/vm.js",
|
||||
"lib/stream.js",
|
||||
"lib/child_process.js",
|
||||
"lib/assert.js",
|
||||
"lib/_tls_wrap.js",
|
||||
"lib/http2.js",
|
||||
"lib/inspector.js",
|
||||
"lib/os.js",
|
||||
"lib/_http_server.js",
|
||||
"lib/console.js",
|
||||
"lib/perf_hooks.js",
|
||||
"lib/readline.js",
|
||||
"lib/punycode.js",
|
||||
"lib/_http_incoming.js",
|
||||
"lib/https.js",
|
||||
"lib/_stream_wrap.js",
|
||||
"lib/domain.js",
|
||||
"lib/dns.js",
|
||||
"lib/_http_client.js",
|
||||
"lib/diagnostics_channel.js",
|
||||
"lib/tty.js",
|
||||
"lib/_http_agent.js",
|
||||
"lib/timers.js",
|
||||
"lib/_http_outgoing.js",
|
||||
"lib/querystring.js",
|
||||
"lib/_tls_common.js",
|
||||
"lib/module.js",
|
||||
"lib/_stream_passthrough.js",
|
||||
"lib/_stream_transform.js",
|
||||
"lib/worker_threads.js",
|
||||
"lib/sys.js",
|
||||
"lib/_stream_duplex.js",
|
||||
"lib/path.js",
|
||||
"lib/_http_client.js",
|
||||
"lib/_http_common.js",
|
||||
"lib/string_decoder.js",
|
||||
"lib/cluster.js",
|
||||
"lib/v8.js",
|
||||
"lib/crypto.js",
|
||||
"lib/wasi.js",
|
||||
"lib/_http_incoming.js",
|
||||
"lib/_http_outgoing.js",
|
||||
"lib/_http_server.js",
|
||||
"lib/_stream_duplex.js",
|
||||
"lib/_stream_passthrough.js",
|
||||
"lib/_stream_readable.js",
|
||||
"lib/zlib.js",
|
||||
"lib/url.js",
|
||||
"lib/tls.js",
|
||||
"lib/_stream_transform.js",
|
||||
"lib/_stream_wrap.js",
|
||||
"lib/_stream_writable.js",
|
||||
"lib/_tls_common.js",
|
||||
"lib/_tls_wrap.js",
|
||||
"lib/assert.js",
|
||||
"lib/assert/strict.js",
|
||||
"lib/async_hooks.js",
|
||||
"lib/process.js",
|
||||
"lib/http.js",
|
||||
"lib/buffer.js",
|
||||
"lib/child_process.js",
|
||||
"lib/cluster.js",
|
||||
"lib/console.js",
|
||||
"lib/constants.js",
|
||||
"lib/crypto.js",
|
||||
"lib/dgram.js",
|
||||
"lib/diagnostics_channel.js",
|
||||
"lib/dns.js",
|
||||
"lib/dns/promises.js",
|
||||
"lib/domain.js",
|
||||
"lib/events.js",
|
||||
"lib/fs.js",
|
||||
"lib/util/types.js",
|
||||
"lib/timers/promises.js",
|
||||
"lib/path/win32.js",
|
||||
"lib/path/posix.js",
|
||||
"lib/stream/consumers.js",
|
||||
"lib/stream/promises.js",
|
||||
"lib/stream/web.js",
|
||||
"lib/internal/constants.js",
|
||||
"lib/fs/promises.js",
|
||||
"lib/http.js",
|
||||
"lib/http2.js",
|
||||
"lib/https.js",
|
||||
"lib/inspector.js",
|
||||
"lib/internal/abort_controller.js",
|
||||
"lib/internal/net.js",
|
||||
"lib/internal/v8_prof_processor.js",
|
||||
"lib/internal/event_target.js",
|
||||
"lib/internal/inspector_async_hook.js",
|
||||
"lib/internal/validators.js",
|
||||
"lib/internal/linkedlist.js",
|
||||
"lib/internal/cli_table.js",
|
||||
"lib/internal/repl.js",
|
||||
"lib/internal/util.js",
|
||||
"lib/internal/histogram.js",
|
||||
"lib/internal/error_serdes.js",
|
||||
"lib/internal/dgram.js",
|
||||
"lib/internal/child_process.js",
|
||||
"lib/internal/assert.js",
|
||||
"lib/internal/fixed_queue.js",
|
||||
"lib/internal/blocklist.js",
|
||||
"lib/internal/v8_prof_polyfill.js",
|
||||
"lib/internal/options.js",
|
||||
"lib/internal/worker.js",
|
||||
"lib/internal/dtrace.js",
|
||||
"lib/internal/idna.js",
|
||||
"lib/internal/watchdog.js",
|
||||
"lib/internal/encoding.js",
|
||||
"lib/internal/tty.js",
|
||||
"lib/internal/freeze_intrinsics.js",
|
||||
"lib/internal/timers.js",
|
||||
"lib/internal/heap_utils.js",
|
||||
"lib/internal/querystring.js",
|
||||
"lib/internal/js_stream_socket.js",
|
||||
"lib/internal/errors.js",
|
||||
"lib/internal/priority_queue.js",
|
||||
"lib/internal/freelist.js",
|
||||
"lib/internal/blob.js",
|
||||
"lib/internal/socket_list.js",
|
||||
"lib/internal/socketaddress.js",
|
||||
"lib/internal/promise_hooks.js",
|
||||
"lib/internal/stream_base_commons.js",
|
||||
"lib/internal/url.js",
|
||||
"lib/internal/assert/assertion_error.js",
|
||||
"lib/internal/assert/calltracker.js",
|
||||
"lib/internal/assert/snapshot.js",
|
||||
"lib/internal/async_hooks.js",
|
||||
"lib/internal/http.js",
|
||||
"lib/internal/buffer.js",
|
||||
"lib/internal/trace_events_async_hooks.js",
|
||||
"lib/internal/crypto/sig.js",
|
||||
"lib/internal/crypto/rsa.js",
|
||||
"lib/internal/crypto/aes.js",
|
||||
"lib/internal/crypto/util.js",
|
||||
"lib/internal/crypto/scrypt.js",
|
||||
"lib/internal/crypto/random.js",
|
||||
"lib/internal/crypto/keys.js",
|
||||
"lib/internal/crypto/x509.js",
|
||||
"lib/internal/crypto/certificate.js",
|
||||
"lib/internal/crypto/ec.js",
|
||||
"lib/internal/crypto/keygen.js",
|
||||
"lib/internal/crypto/mac.js",
|
||||
"lib/internal/crypto/diffiehellman.js",
|
||||
"lib/internal/crypto/hkdf.js",
|
||||
"lib/internal/crypto/cipher.js",
|
||||
"lib/internal/crypto/hash.js",
|
||||
"lib/internal/crypto/pbkdf2.js",
|
||||
"lib/internal/crypto/webcrypto.js",
|
||||
"lib/internal/crypto/dsa.js",
|
||||
"lib/internal/crypto/hashnames.js",
|
||||
"lib/internal/cluster/shared_handle.js",
|
||||
"lib/internal/cluster/round_robin_handle.js",
|
||||
"lib/internal/cluster/worker.js",
|
||||
"lib/internal/cluster/primary.js",
|
||||
"lib/internal/cluster/utils.js",
|
||||
"lib/internal/cluster/child.js",
|
||||
"lib/internal/webstreams/compression.js",
|
||||
"lib/internal/webstreams/util.js",
|
||||
"lib/internal/webstreams/writablestream.js",
|
||||
"lib/internal/webstreams/readablestream.js",
|
||||
"lib/internal/webstreams/queuingstrategies.js",
|
||||
"lib/internal/webstreams/encoding.js",
|
||||
"lib/internal/webstreams/transformstream.js",
|
||||
"lib/internal/webstreams/adapters.js",
|
||||
"lib/internal/webstreams/transfer.js",
|
||||
"lib/internal/blob.js",
|
||||
"lib/internal/blocklist.js",
|
||||
"lib/internal/bootstrap/browser.js",
|
||||
"lib/internal/bootstrap/loaders.js",
|
||||
"lib/internal/bootstrap/pre_execution.js",
|
||||
"lib/internal/bootstrap/node.js",
|
||||
"lib/internal/bootstrap/environment.js",
|
||||
"lib/internal/bootstrap/switches/does_not_own_process_state.js",
|
||||
"lib/internal/bootstrap/switches/is_not_main_thread.js",
|
||||
"lib/internal/bootstrap/switches/does_own_process_state.js",
|
||||
"lib/internal/bootstrap/switches/is_main_thread.js",
|
||||
"lib/internal/test/binding.js",
|
||||
"lib/internal/test/transfer.js",
|
||||
"lib/internal/util/types.js",
|
||||
"lib/internal/util/inspector.js",
|
||||
"lib/internal/util/comparisons.js",
|
||||
"lib/internal/util/debuglog.js",
|
||||
"lib/internal/util/inspect.js",
|
||||
"lib/internal/util/iterable_weak_map.js",
|
||||
"lib/internal/streams/add-abort-signal.js",
|
||||
"lib/internal/streams/compose.js",
|
||||
"lib/internal/streams/duplexify.js",
|
||||
"lib/internal/streams/destroy.js",
|
||||
"lib/internal/streams/legacy.js",
|
||||
"lib/internal/streams/passthrough.js",
|
||||
"lib/internal/streams/operators.js",
|
||||
"lib/internal/streams/readable.js",
|
||||
"lib/internal/streams/from.js",
|
||||
"lib/internal/streams/writable.js",
|
||||
"lib/internal/streams/state.js",
|
||||
"lib/internal/streams/buffer_list.js",
|
||||
"lib/internal/streams/end-of-stream.js",
|
||||
"lib/internal/streams/utils.js",
|
||||
"lib/internal/streams/transform.js",
|
||||
"lib/internal/streams/lazy_transform.js",
|
||||
"lib/internal/streams/duplex.js",
|
||||
"lib/internal/streams/pipeline.js",
|
||||
"lib/internal/readline/interface.js",
|
||||
"lib/internal/readline/utils.js",
|
||||
"lib/internal/readline/emitKeypressEvents.js",
|
||||
"lib/internal/readline/callbacks.js",
|
||||
"lib/internal/repl/history.js",
|
||||
"lib/internal/repl/utils.js",
|
||||
"lib/internal/repl/await.js",
|
||||
"lib/internal/legacy/processbinding.js",
|
||||
"lib/internal/assert/calltracker.js",
|
||||
"lib/internal/assert/assertion_error.js",
|
||||
"lib/internal/http2/util.js",
|
||||
"lib/internal/http2/core.js",
|
||||
"lib/internal/http2/compat.js",
|
||||
"lib/internal/per_context/messageport.js",
|
||||
"lib/internal/per_context/primordials.js",
|
||||
"lib/internal/per_context/domexception.js",
|
||||
"lib/internal/vm/module.js",
|
||||
"lib/internal/tls/secure-pair.js",
|
||||
"lib/internal/tls/parse-cert-string.js",
|
||||
"lib/internal/tls/secure-context.js",
|
||||
"lib/internal/bootstrap/switches/is_not_main_thread.js",
|
||||
"lib/internal/buffer.js",
|
||||
"lib/internal/child_process.js",
|
||||
"lib/internal/child_process/serialization.js",
|
||||
"lib/internal/debugger/inspect_repl.js",
|
||||
"lib/internal/debugger/inspect_client.js",
|
||||
"lib/internal/cli_table.js",
|
||||
"lib/internal/cluster/child.js",
|
||||
"lib/internal/cluster/primary.js",
|
||||
"lib/internal/cluster/round_robin_handle.js",
|
||||
"lib/internal/cluster/shared_handle.js",
|
||||
"lib/internal/cluster/utils.js",
|
||||
"lib/internal/cluster/worker.js",
|
||||
"lib/internal/console/constructor.js",
|
||||
"lib/internal/console/global.js",
|
||||
"lib/internal/constants.js",
|
||||
"lib/internal/crypto/aes.js",
|
||||
"lib/internal/crypto/certificate.js",
|
||||
"lib/internal/crypto/cfrg.js",
|
||||
"lib/internal/crypto/cipher.js",
|
||||
"lib/internal/crypto/diffiehellman.js",
|
||||
"lib/internal/crypto/ec.js",
|
||||
"lib/internal/crypto/hash.js",
|
||||
"lib/internal/crypto/hashnames.js",
|
||||
"lib/internal/crypto/hkdf.js",
|
||||
"lib/internal/crypto/keygen.js",
|
||||
"lib/internal/crypto/keys.js",
|
||||
"lib/internal/crypto/mac.js",
|
||||
"lib/internal/crypto/pbkdf2.js",
|
||||
"lib/internal/crypto/random.js",
|
||||
"lib/internal/crypto/rsa.js",
|
||||
"lib/internal/crypto/scrypt.js",
|
||||
"lib/internal/crypto/sig.js",
|
||||
"lib/internal/crypto/util.js",
|
||||
"lib/internal/crypto/webcrypto.js",
|
||||
"lib/internal/crypto/x509.js",
|
||||
"lib/internal/debugger/inspect.js",
|
||||
"lib/internal/worker/io.js",
|
||||
"lib/internal/worker/js_transferable.js",
|
||||
"lib/internal/main/repl.js",
|
||||
"lib/internal/main/print_help.js",
|
||||
"lib/internal/main/eval_string.js",
|
||||
"lib/internal/main/check_syntax.js",
|
||||
"lib/internal/main/prof_process.js",
|
||||
"lib/internal/main/worker_thread.js",
|
||||
"lib/internal/main/inspect.js",
|
||||
"lib/internal/main/eval_stdin.js",
|
||||
"lib/internal/main/run_main_module.js",
|
||||
"lib/internal/modules/run_main.js",
|
||||
"lib/internal/modules/package_json_reader.js",
|
||||
"lib/internal/modules/esm/module_job.js",
|
||||
"lib/internal/modules/esm/assert.js",
|
||||
"lib/internal/modules/esm/fetch_module.js",
|
||||
"lib/internal/modules/esm/get_source.js",
|
||||
"lib/internal/modules/esm/translators.js",
|
||||
"lib/internal/modules/esm/resolve.js",
|
||||
"lib/internal/modules/esm/create_dynamic_module.js",
|
||||
"lib/internal/modules/esm/load.js",
|
||||
"lib/internal/modules/esm/handle_process_exit.js",
|
||||
"lib/internal/modules/esm/initialize_import_meta.js",
|
||||
"lib/internal/modules/esm/module_map.js",
|
||||
"lib/internal/modules/esm/get_format.js",
|
||||
"lib/internal/modules/esm/formats.js",
|
||||
"lib/internal/modules/esm/loader.js",
|
||||
"lib/internal/modules/cjs/helpers.js",
|
||||
"lib/internal/modules/cjs/loader.js",
|
||||
"lib/internal/source_map/source_map.js",
|
||||
"lib/internal/source_map/prepare_stack_trace.js",
|
||||
"lib/internal/source_map/source_map_cache.js",
|
||||
"lib/internal/debugger/inspect_client.js",
|
||||
"lib/internal/debugger/inspect_repl.js",
|
||||
"lib/internal/dgram.js",
|
||||
"lib/internal/dns/callback_resolver.js",
|
||||
"lib/internal/dns/promises.js",
|
||||
"lib/internal/dns/utils.js",
|
||||
"lib/internal/fs/watchers.js",
|
||||
"lib/internal/dtrace.js",
|
||||
"lib/internal/encoding.js",
|
||||
"lib/internal/error_serdes.js",
|
||||
"lib/internal/errors.js",
|
||||
"lib/internal/event_target.js",
|
||||
"lib/internal/fixed_queue.js",
|
||||
"lib/internal/freelist.js",
|
||||
"lib/internal/freeze_intrinsics.js",
|
||||
"lib/internal/fs/cp/cp-sync.js",
|
||||
"lib/internal/fs/cp/cp.js",
|
||||
"lib/internal/fs/dir.js",
|
||||
"lib/internal/fs/promises.js",
|
||||
"lib/internal/fs/read_file_context.js",
|
||||
"lib/internal/fs/rimraf.js",
|
||||
"lib/internal/fs/sync_write_stream.js",
|
||||
"lib/internal/fs/dir.js",
|
||||
"lib/internal/fs/streams.js",
|
||||
"lib/internal/fs/sync_write_stream.js",
|
||||
"lib/internal/fs/utils.js",
|
||||
"lib/internal/fs/cp/cp.js",
|
||||
"lib/internal/fs/cp/cp-sync.js",
|
||||
"lib/internal/perf/nodetiming.js",
|
||||
"lib/internal/perf/usertiming.js",
|
||||
"lib/internal/perf/performance_entry.js",
|
||||
"lib/internal/perf/performance.js",
|
||||
"lib/internal/perf/timerify.js",
|
||||
"lib/internal/perf/utils.js",
|
||||
"lib/internal/perf/observe.js",
|
||||
"lib/internal/fs/watchers.js",
|
||||
"lib/internal/heap_utils.js",
|
||||
"lib/internal/histogram.js",
|
||||
"lib/internal/http.js",
|
||||
"lib/internal/http2/compat.js",
|
||||
"lib/internal/http2/core.js",
|
||||
"lib/internal/http2/util.js",
|
||||
"lib/internal/idna.js",
|
||||
"lib/internal/inspector_async_hook.js",
|
||||
"lib/internal/js_stream_socket.js",
|
||||
"lib/internal/legacy/processbinding.js",
|
||||
"lib/internal/linkedlist.js",
|
||||
"lib/internal/main/check_syntax.js",
|
||||
"lib/internal/main/environment.js",
|
||||
"lib/internal/main/eval_stdin.js",
|
||||
"lib/internal/main/eval_string.js",
|
||||
"lib/internal/main/inspect.js",
|
||||
"lib/internal/main/mksnapshot.js",
|
||||
"lib/internal/main/print_help.js",
|
||||
"lib/internal/main/prof_process.js",
|
||||
"lib/internal/main/repl.js",
|
||||
"lib/internal/main/run_main_module.js",
|
||||
"lib/internal/main/test_runner.js",
|
||||
"lib/internal/main/watch_mode.js",
|
||||
"lib/internal/main/worker_thread.js",
|
||||
"lib/internal/modules/cjs/helpers.js",
|
||||
"lib/internal/modules/cjs/loader.js",
|
||||
"lib/internal/modules/esm/assert.js",
|
||||
"lib/internal/modules/esm/create_dynamic_module.js",
|
||||
"lib/internal/modules/esm/fetch_module.js",
|
||||
"lib/internal/modules/esm/formats.js",
|
||||
"lib/internal/modules/esm/get_format.js",
|
||||
"lib/internal/modules/esm/handle_process_exit.js",
|
||||
"lib/internal/modules/esm/initialize_import_meta.js",
|
||||
"lib/internal/modules/esm/load.js",
|
||||
"lib/internal/modules/esm/loader.js",
|
||||
"lib/internal/modules/esm/module_job.js",
|
||||
"lib/internal/modules/esm/module_map.js",
|
||||
"lib/internal/modules/esm/package_config.js",
|
||||
"lib/internal/modules/esm/resolve.js",
|
||||
"lib/internal/modules/esm/translators.js",
|
||||
"lib/internal/modules/package_json_reader.js",
|
||||
"lib/internal/modules/run_main.js",
|
||||
"lib/internal/net.js",
|
||||
"lib/internal/options.js",
|
||||
"lib/internal/per_context/domexception.js",
|
||||
"lib/internal/per_context/messageport.js",
|
||||
"lib/internal/per_context/primordials.js",
|
||||
"lib/internal/perf/event_loop_delay.js",
|
||||
"lib/internal/perf/event_loop_utilization.js",
|
||||
"lib/internal/perf/nodetiming.js",
|
||||
"lib/internal/perf/observe.js",
|
||||
"lib/internal/perf/performance.js",
|
||||
"lib/internal/perf/performance_entry.js",
|
||||
"lib/internal/perf/resource_timing.js",
|
||||
"lib/internal/perf/timerify.js",
|
||||
"lib/internal/perf/usertiming.js",
|
||||
"lib/internal/perf/utils.js",
|
||||
"lib/internal/policy/manifest.js",
|
||||
"lib/internal/policy/sri.js",
|
||||
"lib/internal/process/task_queues.js",
|
||||
"lib/internal/process/per_thread.js",
|
||||
"lib/internal/process/warning.js",
|
||||
"lib/internal/process/policy.js",
|
||||
"lib/internal/process/promises.js",
|
||||
"lib/internal/process/signal.js",
|
||||
"lib/internal/process/execution.js",
|
||||
"lib/internal/priority_queue.js",
|
||||
"lib/internal/process/esm_loader.js",
|
||||
"lib/internal/process/execution.js",
|
||||
"lib/internal/process/per_thread.js",
|
||||
"lib/internal/process/policy.js",
|
||||
"lib/internal/process/pre_execution.js",
|
||||
"lib/internal/process/promises.js",
|
||||
"lib/internal/process/report.js",
|
||||
"lib/internal/process/signal.js",
|
||||
"lib/internal/process/task_queues.js",
|
||||
"lib/internal/process/warning.js",
|
||||
"lib/internal/process/worker_thread_only.js",
|
||||
"lib/internal/console/constructor.js",
|
||||
"lib/internal/console/global.js",
|
||||
"lib/assert/strict.js",
|
||||
"lib/dns/promises.js",
|
||||
"lib/fs/promises.js"
|
||||
"lib/internal/promise_hooks.js",
|
||||
"lib/internal/querystring.js",
|
||||
"lib/internal/readline/callbacks.js",
|
||||
"lib/internal/readline/emitKeypressEvents.js",
|
||||
"lib/internal/readline/interface.js",
|
||||
"lib/internal/readline/promises.js",
|
||||
"lib/internal/readline/utils.js",
|
||||
"lib/internal/repl.js",
|
||||
"lib/internal/repl/await.js",
|
||||
"lib/internal/repl/history.js",
|
||||
"lib/internal/repl/utils.js",
|
||||
"lib/internal/socket_list.js",
|
||||
"lib/internal/socketaddress.js",
|
||||
"lib/internal/source_map/prepare_stack_trace.js",
|
||||
"lib/internal/source_map/source_map.js",
|
||||
"lib/internal/source_map/source_map_cache.js",
|
||||
"lib/internal/stream_base_commons.js",
|
||||
"lib/internal/streams/add-abort-signal.js",
|
||||
"lib/internal/streams/buffer_list.js",
|
||||
"lib/internal/streams/compose.js",
|
||||
"lib/internal/streams/destroy.js",
|
||||
"lib/internal/streams/duplex.js",
|
||||
"lib/internal/streams/duplexify.js",
|
||||
"lib/internal/streams/end-of-stream.js",
|
||||
"lib/internal/streams/from.js",
|
||||
"lib/internal/streams/lazy_transform.js",
|
||||
"lib/internal/streams/legacy.js",
|
||||
"lib/internal/streams/operators.js",
|
||||
"lib/internal/streams/passthrough.js",
|
||||
"lib/internal/streams/pipeline.js",
|
||||
"lib/internal/streams/readable.js",
|
||||
"lib/internal/streams/state.js",
|
||||
"lib/internal/streams/transform.js",
|
||||
"lib/internal/streams/utils.js",
|
||||
"lib/internal/streams/writable.js",
|
||||
"lib/internal/structured_clone.js",
|
||||
"lib/internal/test/binding.js",
|
||||
"lib/internal/test/transfer.js",
|
||||
"lib/internal/test_runner/harness.js",
|
||||
"lib/internal/test_runner/runner.js",
|
||||
"lib/internal/test_runner/tap_stream.js",
|
||||
"lib/internal/test_runner/test.js",
|
||||
"lib/internal/test_runner/utils.js",
|
||||
"lib/internal/timers.js",
|
||||
"lib/internal/tls/secure-context.js",
|
||||
"lib/internal/tls/secure-pair.js",
|
||||
"lib/internal/trace_events_async_hooks.js",
|
||||
"lib/internal/tty.js",
|
||||
"lib/internal/url.js",
|
||||
"lib/internal/util.js",
|
||||
"lib/internal/util/colors.js",
|
||||
"lib/internal/util/comparisons.js",
|
||||
"lib/internal/util/debuglog.js",
|
||||
"lib/internal/util/inspect.js",
|
||||
"lib/internal/util/inspector.js",
|
||||
"lib/internal/util/iterable_weak_map.js",
|
||||
"lib/internal/util/parse_args/parse_args.js",
|
||||
"lib/internal/util/parse_args/utils.js",
|
||||
"lib/internal/util/types.js",
|
||||
"lib/internal/v8/startup_snapshot.js",
|
||||
"lib/internal/v8_prof_polyfill.js",
|
||||
"lib/internal/v8_prof_processor.js",
|
||||
"lib/internal/validators.js",
|
||||
"lib/internal/vm/module.js",
|
||||
"lib/internal/wasm_web_api.js",
|
||||
"lib/internal/watch_mode/files_watcher.js",
|
||||
"lib/internal/watchdog.js",
|
||||
"lib/internal/webstreams/adapters.js",
|
||||
"lib/internal/webstreams/compression.js",
|
||||
"lib/internal/webstreams/encoding.js",
|
||||
"lib/internal/webstreams/queuingstrategies.js",
|
||||
"lib/internal/webstreams/readablestream.js",
|
||||
"lib/internal/webstreams/transfer.js",
|
||||
"lib/internal/webstreams/transformstream.js",
|
||||
"lib/internal/webstreams/util.js",
|
||||
"lib/internal/webstreams/writablestream.js",
|
||||
"lib/internal/worker.js",
|
||||
"lib/internal/worker/io.js",
|
||||
"lib/internal/worker/js_transferable.js",
|
||||
"lib/module.js",
|
||||
"lib/net.js",
|
||||
"lib/os.js",
|
||||
"lib/path.js",
|
||||
"lib/path/posix.js",
|
||||
"lib/path/win32.js",
|
||||
"lib/perf_hooks.js",
|
||||
"lib/process.js",
|
||||
"lib/punycode.js",
|
||||
"lib/querystring.js",
|
||||
"lib/readline.js",
|
||||
"lib/readline/promises.js",
|
||||
"lib/repl.js",
|
||||
"lib/stream.js",
|
||||
"lib/stream/consumers.js",
|
||||
"lib/stream/promises.js",
|
||||
"lib/stream/web.js",
|
||||
"lib/string_decoder.js",
|
||||
"lib/sys.js",
|
||||
"lib/test.js",
|
||||
"lib/timers.js",
|
||||
"lib/timers/promises.js",
|
||||
"lib/tls.js",
|
||||
"lib/trace_events.js",
|
||||
"lib/tty.js",
|
||||
"lib/url.js",
|
||||
"lib/util.js",
|
||||
"lib/util/types.js",
|
||||
"lib/v8.js",
|
||||
"lib/vm.js",
|
||||
"lib/wasi.js",
|
||||
"lib/worker_threads.js",
|
||||
"lib/zlib.js"
|
||||
],
|
||||
"node_module_version": 93,
|
||||
"node_module_version": 108,
|
||||
"node_no_browser_globals": "false",
|
||||
"node_prefix": "/",
|
||||
"node_release_urlbase": "https://nodejs.org/download/release/",
|
||||
@@ -330,20 +353,22 @@
|
||||
"node_use_v8_platform": "true",
|
||||
"node_with_ltcg": "false",
|
||||
"node_without_node_options": "false",
|
||||
"openssl_fips": "",
|
||||
"openssl_is_fips": "false",
|
||||
"openssl_quic": "true",
|
||||
"ossfuzz": "false",
|
||||
"shlib_suffix": "93.dylib",
|
||||
"shlib_suffix": "108.dylib",
|
||||
"target_arch": "x64",
|
||||
"v8_enable_31bit_smis_on_64bit_arch": 0,
|
||||
"v8_enable_gdbjit": 0,
|
||||
"v8_enable_hugepage": 0,
|
||||
"v8_enable_i18n_support": 1,
|
||||
"v8_enable_inspector": 1,
|
||||
"v8_enable_javascript_promise_hooks": 1,
|
||||
"v8_enable_lite_mode": 0,
|
||||
"v8_enable_object_print": 1,
|
||||
"v8_enable_pointer_compression": 0,
|
||||
"v8_enable_shared_ro_heap": 1,
|
||||
"v8_enable_short_builtin_calls": 1,
|
||||
"v8_enable_webassembly": 1,
|
||||
"v8_no_strict_aliasing": 1,
|
||||
"v8_optimized_debug": 1,
|
||||
@@ -353,8 +378,8 @@
|
||||
"v8_use_siphash": 1,
|
||||
"want_separate_host_toolset": 0,
|
||||
"xcode_version": "11.0",
|
||||
"nodedir": "/Users/karolsojko/Library/Caches/node-gyp/16.15.1",
|
||||
"nodedir": "/Users/karolsojko/Library/Caches/node-gyp/18.12.1",
|
||||
"standalone_static_library": 1,
|
||||
"user_agent": "yarn/3.2.1 npm/? node/v16.15.1 darwin x64"
|
||||
"user_agent": "yarn/4.0.0-rc.25 npm/? node/v18.12.1 darwin x64"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ DEFS_Debug := \
|
||||
CFLAGS_Debug := \
|
||||
-O0 \
|
||||
-gdwarf-2 \
|
||||
-mmacosx-version-min=10.13 \
|
||||
-mmacosx-version-min=10.15 \
|
||||
-arch x86_64 \
|
||||
-Wall \
|
||||
-Wendif-labels \
|
||||
@@ -38,7 +38,7 @@ CFLAGS_C_Debug := \
|
||||
|
||||
# Flags passed to only C++ files.
|
||||
CFLAGS_CC_Debug := \
|
||||
-std=gnu++14 \
|
||||
-std=gnu++17 \
|
||||
-stdlib=libc++ \
|
||||
-fno-rtti \
|
||||
-fno-exceptions \
|
||||
@@ -51,13 +51,13 @@ CFLAGS_OBJC_Debug :=
|
||||
CFLAGS_OBJCC_Debug :=
|
||||
|
||||
INCS_Debug := \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/src \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/config \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/openssl/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/uv/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/zlib \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/v8/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/include/node \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/src \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/openssl/config \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/openssl/openssl/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/uv/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/zlib \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/v8/include \
|
||||
-I$(srcdir)/src \
|
||||
-I$(srcdir)/../../../../nan-npm-2.16.0-cac314a230/node_modules/nan
|
||||
|
||||
@@ -81,7 +81,7 @@ DEFS_Release := \
|
||||
CFLAGS_Release := \
|
||||
-O3 \
|
||||
-gdwarf-2 \
|
||||
-mmacosx-version-min=10.13 \
|
||||
-mmacosx-version-min=10.15 \
|
||||
-arch x86_64 \
|
||||
-Wall \
|
||||
-Wendif-labels \
|
||||
@@ -94,7 +94,7 @@ CFLAGS_C_Release := \
|
||||
|
||||
# Flags passed to only C++ files.
|
||||
CFLAGS_CC_Release := \
|
||||
-std=gnu++14 \
|
||||
-std=gnu++17 \
|
||||
-stdlib=libc++ \
|
||||
-fno-rtti \
|
||||
-fno-exceptions \
|
||||
@@ -107,13 +107,13 @@ CFLAGS_OBJC_Release :=
|
||||
CFLAGS_OBJCC_Release :=
|
||||
|
||||
INCS_Release := \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/include/node \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/src \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/config \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/openssl/openssl/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/uv/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/zlib \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/16.15.1/deps/v8/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/include/node \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/src \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/openssl/config \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/openssl/openssl/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/uv/include \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/zlib \
|
||||
-I/Users/karolsojko/Library/Caches/node-gyp/18.12.1/deps/v8/include \
|
||||
-I$(srcdir)/src \
|
||||
-I$(srcdir)/../../../../nan-npm-2.16.0-cac314a230/node_modules/nan
|
||||
|
||||
@@ -151,7 +151,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cpp FORCE_DO_CMD
|
||||
LDFLAGS_Debug := \
|
||||
-undefined dynamic_lookup \
|
||||
-Wl,-search_paths_first \
|
||||
-mmacosx-version-min=10.13 \
|
||||
-mmacosx-version-min=10.15 \
|
||||
-arch x86_64 \
|
||||
-L$(builddir) \
|
||||
-stdlib=libc++
|
||||
@@ -163,7 +163,7 @@ LIBTOOLFLAGS_Debug := \
|
||||
LDFLAGS_Release := \
|
||||
-undefined dynamic_lookup \
|
||||
-Wl,-search_paths_first \
|
||||
-mmacosx-version-min=10.13 \
|
||||
-mmacosx-version-min=10.15 \
|
||||
-arch x86_64 \
|
||||
-L$(builddir) \
|
||||
-stdlib=libc++
|
||||
|
||||
12
package.json
12
package.json
@@ -8,7 +8,7 @@
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "yarn workspaces foreach -p -j 10 --verbose run lint",
|
||||
@@ -21,6 +21,7 @@
|
||||
"lint:websockets": "yarn workspace @standardnotes/websockets-server lint",
|
||||
"lint:workspace": "yarn workspace @standardnotes/workspace-server lint",
|
||||
"lint:analytics": "yarn workspace @standardnotes/analytics lint",
|
||||
"lint:revisions": "yarn workspace @standardnotes/revisions-server lint",
|
||||
"clean": "yarn workspaces foreach -p --verbose run clean",
|
||||
"setup:env": "cp .env.sample .env && yarn workspaces foreach -p --verbose run setup:env",
|
||||
"start:auth": "yarn workspace @standardnotes/auth-server start",
|
||||
@@ -34,6 +35,7 @@
|
||||
"start:websockets": "yarn workspace @standardnotes/websockets-server start",
|
||||
"start:workspace": "yarn workspace @standardnotes/workspace-server start",
|
||||
"start:analytics": "yarn workspace @standardnotes/analytics worker",
|
||||
"start:revisions": "yarn workspace @standardnotes/revisions-server start",
|
||||
"release": "lerna version --conventional-graduate --conventional-commits --yes -m \"chore(release): publish new version\"",
|
||||
"publish": "lerna publish from-git --yes --no-verify-access --loglevel verbose",
|
||||
"postversion": "./scripts/push-tags-one-by-one.sh",
|
||||
@@ -46,8 +48,8 @@
|
||||
"@lerna-lite/list": "^1.5.1",
|
||||
"@lerna-lite/run": "^1.5.1",
|
||||
"@types/jest": "^29.1.1",
|
||||
"@types/newrelic": "^7.0.3",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/newrelic": "^7.0.4",
|
||||
"@types/node": "^18.11.9",
|
||||
"@typescript-eslint/parser": "^5.40.1",
|
||||
"eslint": "^8.17.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
@@ -59,7 +61,7 @@
|
||||
},
|
||||
"packageManager": "yarn@4.0.0-rc.25",
|
||||
"dependencies": {
|
||||
"@sentry/node": "^7.3.0",
|
||||
"newrelic": "^9.0.0"
|
||||
"@sentry/node": "^7.28.1",
|
||||
"newrelic": "^9.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ DB_DATABASE=analytics
|
||||
DB_DEBUG_LEVEL=all # "all" | "query" | "schema" | "error" | "warn" | "info" | "log" | "migration"
|
||||
DB_MIGRATIONS_PATH=dist/migrations/*.js
|
||||
|
||||
ADMIN_EMAILS=test@standardnotes.com
|
||||
|
||||
REDIS_URL=redis://cache
|
||||
REDIS_EVENTS_CHANNEL=events
|
||||
|
||||
@@ -26,3 +28,6 @@ NEW_RELIC_NO_CONFIG_FILE=true
|
||||
NEW_RELIC_DISTRIBUTED_TRACING_ENABLED=false
|
||||
NEW_RELIC_LOG_ENABLED=false
|
||||
NEW_RELIC_LOG_LEVEL=info
|
||||
|
||||
# (Optional) Mixpanel
|
||||
MIXPANEL_TOKEN=
|
||||
|
||||
@@ -3,6 +3,387 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.19.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.1...@standardnotes/analytics@2.19.2) (2023-01-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.19.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.19.0...@standardnotes/analytics@2.19.1) (2022-12-30)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** remove unnecesary context from mixpanel events ([ba1e1ad](https://github.com/standardnotes/server/commit/ba1e1ad5ad82b052be4cc2d1cc2abdaf3b72cf4c))
|
||||
|
||||
# [2.19.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.18.0...@standardnotes/analytics@2.19.0) (2022-12-30)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add mixpanel events tracking ([df6e3f0](https://github.com/standardnotes/server/commit/df6e3f06a6868e30e60dd98431122983724644b4))
|
||||
|
||||
# [2.18.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.8...@standardnotes/analytics@2.18.0) (2022-12-30)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add mixpanel ([893d617](https://github.com/standardnotes/server/commit/893d6176c3b0b56c45e5188fe982232db2ceedc4))
|
||||
|
||||
## [2.17.8](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.7...@standardnotes/analytics@2.17.8) (2022-12-28)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.17.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.6...@standardnotes/analytics@2.17.7) (2022-12-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** monthly numbers of active users ([b34bbca](https://github.com/standardnotes/server/commit/b34bbcac8b9604283b3a5959ab3218c468ce8a00))
|
||||
|
||||
## [2.17.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.5...@standardnotes/analytics@2.17.6) (2022-12-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** filtered counts for user activity check ([17b2ea1](https://github.com/standardnotes/server/commit/17b2ea126c5ad2d7cf07657def63f9977f239a3c))
|
||||
|
||||
## [2.17.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.4...@standardnotes/analytics@2.17.5) (2022-12-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** accessing analytics in report ([ef26dc8](https://github.com/standardnotes/server/commit/ef26dc8cbb967e088ae7387ff6dbec1e60dc3ee4))
|
||||
|
||||
## [2.17.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.3...@standardnotes/analytics@2.17.4) (2022-12-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.17.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.2...@standardnotes/analytics@2.17.3) (2022-12-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** add debug logs for the report ([031fcd7](https://github.com/standardnotes/server/commit/031fcd75eecdcf4c2f17257754a0ba3f24ba6d6e))
|
||||
|
||||
## [2.17.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.1...@standardnotes/analytics@2.17.2) (2022-12-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** calculating active users ([a304993](https://github.com/standardnotes/server/commit/a3049938a31e21a5867a314ac62bee6aa4990d57))
|
||||
|
||||
## [2.17.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.17.0...@standardnotes/analytics@2.17.1) (2022-12-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** container binding ([04ffc69](https://github.com/standardnotes/server/commit/04ffc69e000803107d8834c286de97b3d213a842))
|
||||
* **auth:** replace date object with number timestamp ([5b4bb6e](https://github.com/standardnotes/server/commit/5b4bb6e7a78a1b0f4e663bb990619f65f6a5c757))
|
||||
|
||||
# [2.17.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.16.0...@standardnotes/analytics@2.17.0) (2022-12-20)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add users activit to the report email ([ed5a4eb](https://github.com/standardnotes/server/commit/ed5a4eb960a6c8fe9d0c77331f29dc3c7ffb9100))
|
||||
|
||||
# [2.16.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.15.1...@standardnotes/analytics@2.16.0) (2022-12-20)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add active users stats to report ([6e16620](https://github.com/standardnotes/server/commit/6e1662038c3340fb60939464616789bab7639160))
|
||||
|
||||
## [2.15.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.15.0...@standardnotes/analytics@2.15.1) (2022-12-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** add persisting statistics for all subscription plans ([addedb3](https://github.com/standardnotes/server/commit/addedb3091ddae81618d56663e18f2ae76a43c4e))
|
||||
|
||||
# [2.15.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.14.0...@standardnotes/analytics@2.15.0) (2022-12-19)
|
||||
|
||||
### Features
|
||||
|
||||
* **auth:** add requesting persisting statistics ([a35271f](https://github.com/standardnotes/server/commit/a35271fbb399b68a3ac7021395d8063707fba222))
|
||||
|
||||
# [2.14.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.13.0...@standardnotes/analytics@2.14.0) (2022-12-19)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add persisting statistics on demand ([0f84575](https://github.com/standardnotes/server/commit/0f8457534c1829c58f3c036749d262307ddeb779))
|
||||
|
||||
# [2.13.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.27...@standardnotes/analytics@2.13.0) (2022-12-19)
|
||||
|
||||
### Features
|
||||
|
||||
* **auth:** add session traces ([8bcb552](https://github.com/standardnotes/server/commit/8bcb552783b2d12f3296b3195752168482790bc8))
|
||||
|
||||
## [2.12.27](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.26...@standardnotes/analytics@2.12.27) (2022-12-15)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.26](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.25...@standardnotes/analytics@2.12.26) (2022-12-15)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.25](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.24...@standardnotes/analytics@2.12.25) (2022-12-12)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.24](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.23...@standardnotes/analytics@2.12.24) (2022-12-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** daily analytics report template ([41906ec](https://github.com/standardnotes/server/commit/41906ec2f9fd4d605b1c002826173e14fb534e00))
|
||||
|
||||
## [2.12.23](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.22...@standardnotes/analytics@2.12.23) (2022-12-12)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.22](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.21...@standardnotes/analytics@2.12.22) (2022-12-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** report event publishing ([a605660](https://github.com/standardnotes/server/commit/a6056600eb96bf175189ad6d62870c9d736f331b))
|
||||
|
||||
## [2.12.21](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.20...@standardnotes/analytics@2.12.21) (2022-12-12)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** add debug logs for report ([48c0cb5](https://github.com/standardnotes/server/commit/48c0cb5e62dc8af930de191deaa1eb3ff6c5a29f))
|
||||
|
||||
## [2.12.20](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.19...@standardnotes/analytics@2.12.20) (2022-12-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.19](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.18...@standardnotes/analytics@2.12.19) (2022-12-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.18](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.17...@standardnotes/analytics@2.12.18) (2022-12-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.17](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.16...@standardnotes/analytics@2.12.17) (2022-12-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.16](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.15...@standardnotes/analytics@2.12.16) (2022-12-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.15](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.14...@standardnotes/analytics@2.12.15) (2022-12-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.14](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.13...@standardnotes/analytics@2.12.14) (2022-12-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.13](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.12...@standardnotes/analytics@2.12.13) (2022-12-09)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.12](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.11...@standardnotes/analytics@2.12.12) (2022-12-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.11](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.10...@standardnotes/analytics@2.12.11) (2022-12-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.10](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.9...@standardnotes/analytics@2.12.10) (2022-12-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.9](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.8...@standardnotes/analytics@2.12.9) (2022-12-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.8](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.7...@standardnotes/analytics@2.12.8) (2022-12-08)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.6...@standardnotes/analytics@2.12.7) (2022-12-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.5...@standardnotes/analytics@2.12.6) (2022-12-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.4...@standardnotes/analytics@2.12.5) (2022-12-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.3...@standardnotes/analytics@2.12.4) (2022-12-07)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.2...@standardnotes/analytics@2.12.3) (2022-12-06)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.1...@standardnotes/analytics@2.12.2) (2022-12-05)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.12.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.12.0...@standardnotes/analytics@2.12.1) (2022-12-05)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
# [2.12.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.17...@standardnotes/analytics@2.12.0) (2022-12-05)
|
||||
|
||||
### Features
|
||||
|
||||
* **domain-core:** distinguish between username and email ([06fd404](https://github.com/standardnotes/server/commit/06fd404d44b44a53733f889aabd4da63f21e2f36))
|
||||
|
||||
## [2.11.17](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.16...@standardnotes/analytics@2.11.17) (2022-12-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.16](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.15...@standardnotes/analytics@2.11.16) (2022-12-02)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.15](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.14...@standardnotes/analytics@2.11.15) (2022-11-30)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.14](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.13...@standardnotes/analytics@2.11.14) (2022-11-28)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.13](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.12...@standardnotes/analytics@2.11.13) (2022-11-25)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.12](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.11...@standardnotes/analytics@2.11.12) (2022-11-24)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.11](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.10...@standardnotes/analytics@2.11.11) (2022-11-24)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.10](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.9...@standardnotes/analytics@2.11.10) (2022-11-24)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.9](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.8...@standardnotes/analytics@2.11.9) (2022-11-24)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.8](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.7...@standardnotes/analytics@2.11.8) (2022-11-23)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.6...@standardnotes/analytics@2.11.7) (2022-11-23)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* binding of sns and sqs with additional config ([74bc791](https://github.com/standardnotes/server/commit/74bc79116bc50d9a5af1a558db1b7108dcda6d0e))
|
||||
|
||||
## [2.11.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.5...@standardnotes/analytics@2.11.6) (2022-11-22)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.4...@standardnotes/analytics@2.11.5) (2022-11-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.3...@standardnotes/analytics@2.11.4) (2022-11-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.2...@standardnotes/analytics@2.11.3) (2022-11-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.11.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.1...@standardnotes/analytics@2.11.2) (2022-11-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** specs ([507d43b](https://github.com/standardnotes/server/commit/507d43b3289d1e178644df6d3e15d1d55e56c7bb))
|
||||
|
||||
## [2.11.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.11.0...@standardnotes/analytics@2.11.1) (2022-11-18)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* mapper interface imports ([1ec0723](https://github.com/standardnotes/server/commit/1ec072373d640c4e2f24b9bb12fec0c678b48032))
|
||||
|
||||
# [2.11.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.10.3...@standardnotes/analytics@2.11.0) (2022-11-16)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add publishing churn calculation values in the report ([6c43a33](https://github.com/standardnotes/server/commit/6c43a331d09c2dcf1300742509da6a1d8ef2f5b7))
|
||||
|
||||
## [2.10.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.10.2...@standardnotes/analytics@2.10.3) (2022-11-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** exclude five year plans from mrr stats ([fe1b2a0](https://github.com/standardnotes/server/commit/fe1b2a0e0744417e592f3f61f42610765b416ce6))
|
||||
|
||||
## [2.10.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.10.1...@standardnotes/analytics@2.10.2) (2022-11-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** imports from domain-core ([15dfd6d](https://github.com/standardnotes/server/commit/15dfd6dcba75a772000eeb01b78a532067b01d5b))
|
||||
|
||||
## [2.10.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.10.0...@standardnotes/analytics@2.10.1) (2022-11-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **syncing-server:** retrieving revisions ([50f7ae3](https://github.com/standardnotes/server/commit/50f7ae338ad66d3465fa16c31e7c47c57b1e0c3c))
|
||||
|
||||
# [2.10.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.9...@standardnotes/analytics@2.10.0) (2022-11-14)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** extract domain core into a separate package ([0f94e2a](https://github.com/standardnotes/server/commit/0f94e2ad0c8927733eac31f130cbe649dce765f9))
|
||||
|
||||
## [2.9.9](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.6...@standardnotes/analytics@2.9.9) (2022-11-14)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** bump version ([8715fe1](https://github.com/standardnotes/server/commit/8715fe182221f67f02b5f49e566366db3db581f4))
|
||||
|
||||
## [2.9.6](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.5...@standardnotes/analytics@2.9.6) (2022-11-14)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.9.5](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.4...@standardnotes/analytics@2.9.5) (2022-11-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.9.4](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.3...@standardnotes/analytics@2.9.4) (2022-11-11)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.9.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.2...@standardnotes/analytics@2.9.3) (2022-11-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** add five year plans mrr calculation ([a03c5bc](https://github.com/standardnotes/server/commit/a03c5bceea2a9b166b1d5ad75181021462a86627))
|
||||
|
||||
## [2.9.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.1...@standardnotes/analytics@2.9.2) (2022-11-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** add missing period for stats report ([9b593f2](https://github.com/standardnotes/server/commit/9b593f2a6b105ab8f9c7cef8bdda6892c42e20ef))
|
||||
|
||||
## [2.9.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.0...@standardnotes/analytics@2.9.1) (2022-11-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** generate mrr stats for last 30 days including Today ([b92c4ae](https://github.com/standardnotes/server/commit/b92c4ae650b53db5c0bb2a9cf9afb01caeb8d822))
|
||||
|
||||
# [2.9.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.8.3...@standardnotes/analytics@2.9.0) (2022-11-10)
|
||||
|
||||
### Features
|
||||
|
||||
* **analytics:** add mrr for annual, monthly, pro and plus subscription plans ([ce3e259](https://github.com/standardnotes/server/commit/ce3e259bdedd10796fb4469f0eabd64bc326a115))
|
||||
|
||||
## [2.8.3](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.8.2...@standardnotes/analytics@2.8.3) (2022-11-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** add subscription id to error logs ([81be065](https://github.com/standardnotes/server/commit/81be06598c918279f98a8ba6b59ea1b3803c949c))
|
||||
|
||||
## [2.8.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.8.1...@standardnotes/analytics@2.8.2) (2022-11-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **analytics:** add monthly mrr to the report ([fce47a0](https://github.com/standardnotes/server/commit/fce47a0a37a67b3edf3ea0b6ccda43c54dbd9870))
|
||||
|
||||
## [2.8.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.8.0...@standardnotes/analytics@2.8.1) (2022-11-10)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:16.15.1-alpine
|
||||
FROM node:18.12.1-alpine
|
||||
|
||||
RUN apk add --update \
|
||||
curl \
|
||||
|
||||
@@ -4,10 +4,10 @@ import 'newrelic'
|
||||
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import { EmailLevel } from '@standardnotes/domain-core'
|
||||
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
|
||||
import { AnalyticsActivity } from '../src/Domain/Analytics/AnalyticsActivity'
|
||||
import { Period } from '../src/Domain/Time/Period'
|
||||
import { StatisticsMeasure } from '../src/Domain/Statistics/StatisticsMeasure'
|
||||
import { AnalyticsStoreInterface } from '../src/Domain/Analytics/AnalyticsStoreInterface'
|
||||
import { StatisticsStoreInterface } from '../src/Domain/Statistics/StatisticsStoreInterface'
|
||||
import { PeriodKeyGeneratorInterface } from '../src/Domain/Time/PeriodKeyGeneratorInterface'
|
||||
@@ -16,6 +16,9 @@ import TYPES from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
|
||||
import { CalculateMonthlyRecurringRevenue } from '../src/Domain/UseCase/CalculateMonthlyRecurringRevenue/CalculateMonthlyRecurringRevenue'
|
||||
import { getBody, getSubject } from '../src/Domain/Email/DailyAnalyticsReport'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { StatisticMeasureName } from '../src/Domain/Statistics/StatisticMeasureName'
|
||||
|
||||
const requestReport = async (
|
||||
analyticsStore: AnalyticsStoreInterface,
|
||||
@@ -24,6 +27,8 @@ const requestReport = async (
|
||||
domainEventPublisher: DomainEventPublisherInterface,
|
||||
periodKeyGenerator: PeriodKeyGeneratorInterface,
|
||||
calculateMonthlyRecurringRevenue: CalculateMonthlyRecurringRevenue,
|
||||
timer: TimerInterface,
|
||||
adminEmails: string[],
|
||||
): Promise<void> => {
|
||||
await calculateMonthlyRecurringRevenue.execute({})
|
||||
|
||||
@@ -100,8 +105,6 @@ const requestReport = async (
|
||||
})
|
||||
}
|
||||
|
||||
const thirtyDaysStatisticsNames = [StatisticsMeasure.MRR]
|
||||
|
||||
const statisticsOverTime: Array<{
|
||||
name: string
|
||||
period: number
|
||||
@@ -110,31 +113,53 @@ const requestReport = async (
|
||||
totalCount: number
|
||||
}>
|
||||
}> = []
|
||||
|
||||
const thirtyDaysStatisticsNames = [
|
||||
StatisticMeasureName.NAMES.MRR,
|
||||
StatisticMeasureName.NAMES.AnnualPlansMRR,
|
||||
StatisticMeasureName.NAMES.MonthlyPlansMRR,
|
||||
StatisticMeasureName.NAMES.FiveYearPlansMRR,
|
||||
StatisticMeasureName.NAMES.PlusPlansMRR,
|
||||
StatisticMeasureName.NAMES.ProPlansMRR,
|
||||
StatisticMeasureName.NAMES.ActiveUsers,
|
||||
StatisticMeasureName.NAMES.ActiveFreeUsers,
|
||||
StatisticMeasureName.NAMES.ActivePlusUsers,
|
||||
StatisticMeasureName.NAMES.ActiveProUsers,
|
||||
]
|
||||
for (const statisticName of thirtyDaysStatisticsNames) {
|
||||
statisticsOverTime.push({
|
||||
name: statisticName,
|
||||
period: Period.Last30Days,
|
||||
counts: await statisticsStore.calculateTotalCountOverPeriod(statisticName, Period.Last30Days),
|
||||
period: Period.Last30DaysIncludingToday,
|
||||
counts: await statisticsStore.calculateTotalCountOverPeriod(statisticName, Period.Last30DaysIncludingToday),
|
||||
})
|
||||
}
|
||||
|
||||
const monthlyStatisticsNames = [StatisticMeasureName.NAMES.MRR]
|
||||
for (const statisticName of monthlyStatisticsNames) {
|
||||
statisticsOverTime.push({
|
||||
name: statisticName,
|
||||
period: Period.ThisYear,
|
||||
counts: await statisticsStore.calculateTotalCountOverPeriod(statisticName, Period.ThisYear),
|
||||
})
|
||||
}
|
||||
|
||||
const statisticMeasureNames = [
|
||||
StatisticsMeasure.Income,
|
||||
StatisticsMeasure.PlusSubscriptionInitialAnnualPaymentsIncome,
|
||||
StatisticsMeasure.PlusSubscriptionInitialMonthlyPaymentsIncome,
|
||||
StatisticsMeasure.PlusSubscriptionRenewingAnnualPaymentsIncome,
|
||||
StatisticsMeasure.PlusSubscriptionRenewingMonthlyPaymentsIncome,
|
||||
StatisticsMeasure.ProSubscriptionInitialAnnualPaymentsIncome,
|
||||
StatisticsMeasure.ProSubscriptionInitialMonthlyPaymentsIncome,
|
||||
StatisticsMeasure.ProSubscriptionRenewingAnnualPaymentsIncome,
|
||||
StatisticsMeasure.ProSubscriptionRenewingMonthlyPaymentsIncome,
|
||||
StatisticsMeasure.Refunds,
|
||||
StatisticsMeasure.RegistrationLength,
|
||||
StatisticsMeasure.SubscriptionLength,
|
||||
StatisticsMeasure.RegistrationToSubscriptionTime,
|
||||
StatisticsMeasure.RemainingSubscriptionTimePercentage,
|
||||
StatisticsMeasure.NewCustomers,
|
||||
StatisticsMeasure.TotalCustomers,
|
||||
StatisticMeasureName.NAMES.Income,
|
||||
StatisticMeasureName.NAMES.PlusSubscriptionInitialAnnualPaymentsIncome,
|
||||
StatisticMeasureName.NAMES.PlusSubscriptionInitialMonthlyPaymentsIncome,
|
||||
StatisticMeasureName.NAMES.PlusSubscriptionRenewingAnnualPaymentsIncome,
|
||||
StatisticMeasureName.NAMES.PlusSubscriptionRenewingMonthlyPaymentsIncome,
|
||||
StatisticMeasureName.NAMES.ProSubscriptionInitialAnnualPaymentsIncome,
|
||||
StatisticMeasureName.NAMES.ProSubscriptionInitialMonthlyPaymentsIncome,
|
||||
StatisticMeasureName.NAMES.ProSubscriptionRenewingAnnualPaymentsIncome,
|
||||
StatisticMeasureName.NAMES.ProSubscriptionRenewingMonthlyPaymentsIncome,
|
||||
StatisticMeasureName.NAMES.Refunds,
|
||||
StatisticMeasureName.NAMES.RegistrationLength,
|
||||
StatisticMeasureName.NAMES.SubscriptionLength,
|
||||
StatisticMeasureName.NAMES.RegistrationToSubscriptionTime,
|
||||
StatisticMeasureName.NAMES.RemainingSubscriptionTimePercentage,
|
||||
StatisticMeasureName.NAMES.NewCustomers,
|
||||
StatisticMeasureName.NAMES.TotalCustomers,
|
||||
]
|
||||
const statisticMeasures: Array<{
|
||||
name: string
|
||||
@@ -159,6 +184,9 @@ const requestReport = async (
|
||||
const churnRates: Array<{
|
||||
rate: number
|
||||
periodKey: string
|
||||
averageCustomersCount: number
|
||||
existingCustomersChurn: number
|
||||
newCustomersChurn: number
|
||||
}> = []
|
||||
for (const monthPeriodKey of monthlyPeriodKeys) {
|
||||
const monthPeriod = periodKeyGenerator.convertPeriodKeyToPeriod(monthPeriodKey)
|
||||
@@ -166,7 +194,10 @@ const requestReport = async (
|
||||
|
||||
const totalCustomerCounts: Array<number> = []
|
||||
for (const dailyPeriodKey of dailyPeriodKeys) {
|
||||
const customersCount = await statisticsStore.getMeasureTotal(StatisticsMeasure.TotalCustomers, dailyPeriodKey)
|
||||
const customersCount = await statisticsStore.getMeasureTotal(
|
||||
StatisticMeasureName.NAMES.TotalCustomers,
|
||||
dailyPeriodKey,
|
||||
)
|
||||
totalCustomerCounts.push(customersCount)
|
||||
}
|
||||
const filteredTotalCustomerCounts = totalCustomerCounts.filter((count) => !!count)
|
||||
@@ -188,21 +219,35 @@ const requestReport = async (
|
||||
churnRates.push({
|
||||
periodKey: monthPeriodKey,
|
||||
rate: averageCustomersCount ? (totalChurn / averageCustomersCount) * 100 : 0,
|
||||
averageCustomersCount,
|
||||
existingCustomersChurn,
|
||||
newCustomersChurn,
|
||||
})
|
||||
}
|
||||
|
||||
const event = domainEventFactory.createDailyAnalyticsReportGeneratedEvent({
|
||||
activityStatistics: yesterdayActivityStatistics,
|
||||
activityStatisticsOverTime: analyticsOverTime,
|
||||
statisticsOverTime,
|
||||
statisticMeasures,
|
||||
churn: {
|
||||
periodKeys: monthlyPeriodKeys,
|
||||
values: churnRates,
|
||||
},
|
||||
})
|
||||
|
||||
await domainEventPublisher.publish(event)
|
||||
for (const adminEmail of adminEmails) {
|
||||
await domainEventPublisher.publish(
|
||||
domainEventFactory.createEmailRequestedEvent({
|
||||
messageIdentifier: 'VERSION_ADOPTION_REPORT',
|
||||
subject: getSubject(),
|
||||
body: getBody(
|
||||
{
|
||||
activityStatistics: yesterdayActivityStatistics,
|
||||
activityStatisticsOverTime: analyticsOverTime,
|
||||
statisticsOverTime,
|
||||
statisticMeasures,
|
||||
churn: {
|
||||
periodKeys: monthlyPeriodKeys,
|
||||
values: churnRates,
|
||||
},
|
||||
},
|
||||
timer,
|
||||
),
|
||||
level: EmailLevel.LEVELS.System,
|
||||
userEmail: adminEmail,
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const container = new ContainerConfigLoader()
|
||||
@@ -219,9 +264,13 @@ void container.load().then((container) => {
|
||||
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.DomainEventFactory)
|
||||
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.DomainEventPublisher)
|
||||
const periodKeyGenerator: PeriodKeyGeneratorInterface = container.get(TYPES.PeriodKeyGenerator)
|
||||
const timer: TimerInterface = container.get(TYPES.Timer)
|
||||
const calculateMonthlyRecurringRevenue: CalculateMonthlyRecurringRevenue = container.get(
|
||||
TYPES.CalculateMonthlyRecurringRevenue,
|
||||
)
|
||||
const adminEmails = container.get(TYPES.ADMIN_EMAILS) as string[]
|
||||
|
||||
logger.info(`Sending report to following admins: ${adminEmails}`)
|
||||
|
||||
Promise.resolve(
|
||||
requestReport(
|
||||
@@ -231,6 +280,8 @@ void container.load().then((container) => {
|
||||
domainEventPublisher,
|
||||
periodKeyGenerator,
|
||||
calculateMonthlyRecurringRevenue,
|
||||
timer,
|
||||
adminEmails,
|
||||
),
|
||||
)
|
||||
.then(() => {
|
||||
|
||||
@@ -5,17 +5,17 @@ COMMAND=$1 && shift 1
|
||||
|
||||
case "$COMMAND" in
|
||||
'start-worker' )
|
||||
echo "Starting Worker..."
|
||||
echo "[Docker] Starting Worker..."
|
||||
yarn workspace @standardnotes/analytics worker
|
||||
;;
|
||||
|
||||
'report' )
|
||||
echo "Starting Usage Report Generation..."
|
||||
echo "[Docker] Starting Usage Report Generation..."
|
||||
yarn workspace @standardnotes/analytics report
|
||||
;;
|
||||
|
||||
* )
|
||||
echo "Unknown command"
|
||||
echo "[Docker] Unknown command"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
@@ -7,5 +7,5 @@ module.exports = {
|
||||
transform: {
|
||||
...tsjPreset.transform,
|
||||
},
|
||||
coveragePathIgnorePatterns: ['/Infra/'],
|
||||
coveragePathIgnorePatterns: ['/Infra/', '/Domain/Email/', '/Handler/'],
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "@standardnotes/analytics",
|
||||
"version": "2.8.1",
|
||||
"version": "2.19.2",
|
||||
"engines": {
|
||||
"node": ">=14.0.0 <17.0.0"
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
"private": true,
|
||||
"description": "Analytics tools for Standard Notes projects",
|
||||
@@ -25,11 +25,11 @@
|
||||
"typeorm": "typeorm-ts-node-commonjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/ioredis": "^4.28.10",
|
||||
"@types/ioredis": "^5.0.0",
|
||||
"@types/jest": "^29.1.1",
|
||||
"@types/newrelic": "^7.0.3",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/uuid": "^8.3.0",
|
||||
"@types/mixpanel": "^2.14.4",
|
||||
"@types/newrelic": "^7.0.4",
|
||||
"@types/node": "^18.11.9",
|
||||
"@typescript-eslint/eslint-plugin": "^5.30.0",
|
||||
"eslint": "^8.14.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
@@ -39,22 +39,22 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@newrelic/winston-enricher": "^4.0.0",
|
||||
"@sentry/node": "^7.3.0",
|
||||
"@sentry/node": "^7.28.1",
|
||||
"@standardnotes/common": "workspace:*",
|
||||
"@standardnotes/domain-core": "workspace:^",
|
||||
"@standardnotes/domain-events": "workspace:*",
|
||||
"@standardnotes/domain-events-infra": "workspace:*",
|
||||
"@standardnotes/time": "workspace:*",
|
||||
"aws-sdk": "^2.1158.0",
|
||||
"aws-sdk": "^2.1260.0",
|
||||
"dayjs": "^1.11.6",
|
||||
"dotenv": "^16.0.1",
|
||||
"inversify": "^6.0.1",
|
||||
"ioredis": "^5.2.3",
|
||||
"ioredis": "^5.2.4",
|
||||
"mixpanel": "^0.17.0",
|
||||
"mysql2": "^2.3.3",
|
||||
"newrelic": "^9.0.0",
|
||||
"newrelic": "^9.6.0",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"shallow-equal-object": "^1.1.1",
|
||||
"typeorm": "^0.3.6",
|
||||
"uuid": "^9.0.0",
|
||||
"typeorm": "^0.3.10",
|
||||
"winston": "^3.8.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ import {
|
||||
DomainEventMessageHandlerInterface,
|
||||
DomainEventSubscriberFactoryInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { MapperInterface } from '@standardnotes/domain-core'
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const Mixpanel = require('mixpanel')
|
||||
|
||||
import { Env } from './Env'
|
||||
import TYPES from './Types'
|
||||
@@ -47,11 +50,13 @@ import { RefundProcessedEventHandler } from '../Domain/Handler/RefundProcessedEv
|
||||
import { RevenueModificationRepositoryInterface } from '../Domain/Revenue/RevenueModificationRepositoryInterface'
|
||||
import { MySQLRevenueModificationRepository } from '../Infra/MySQL/MySQLRevenueModificationRepository'
|
||||
import { TypeORMRevenueModification } from '../Infra/TypeORM/TypeORMRevenueModification'
|
||||
import { MapInterface } from '../Domain/Map/MapInterface'
|
||||
import { RevenueModification } from '../Domain/Revenue/RevenueModification'
|
||||
import { RevenueModificationMap } from '../Domain/Map/RevenueModificationMap'
|
||||
import { SaveRevenueModification } from '../Domain/UseCase/SaveRevenueModification/SaveRevenueModification'
|
||||
import { CalculateMonthlyRecurringRevenue } from '../Domain/UseCase/CalculateMonthlyRecurringRevenue/CalculateMonthlyRecurringRevenue'
|
||||
import { PersistStatistic } from '../Domain/UseCase/PersistStatistic/PersistStatistic'
|
||||
import { StatisticMeasureRepositoryInterface } from '../Domain/Statistics/StatisticMeasureRepositoryInterface'
|
||||
import { StatisticPersistenceRequestedEventHandler } from '../Domain/Handler/StatisticPersistenceRequestedEventHandler'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const newrelicFormatter = require('@newrelic/winston-enricher')
|
||||
@@ -89,13 +94,24 @@ export class ContainerConfigLoader {
|
||||
})
|
||||
container.bind<winston.Logger>(TYPES.Logger).toConstantValue(logger)
|
||||
|
||||
if (env.get('SNS_AWS_REGION', true)) {
|
||||
container.bind<AWS.SNS>(TYPES.SNS).toConstantValue(
|
||||
new AWS.SNS({
|
||||
apiVersion: 'latest',
|
||||
region: env.get('SNS_AWS_REGION', true),
|
||||
}),
|
||||
)
|
||||
if (env.get('SNS_TOPIC_ARN', true)) {
|
||||
const snsConfig: AWS.SNS.Types.ClientConfiguration = {
|
||||
apiVersion: 'latest',
|
||||
region: env.get('SNS_AWS_REGION', true),
|
||||
}
|
||||
if (env.get('SNS_ENDPOINT', true)) {
|
||||
snsConfig.endpoint = env.get('SNS_ENDPOINT', true)
|
||||
}
|
||||
if (env.get('SNS_DISABLE_SSL', true) === 'true') {
|
||||
snsConfig.sslEnabled = false
|
||||
}
|
||||
if (env.get('SNS_ACCESS_KEY_ID', true) && env.get('SNS_SECRET_ACCESS_KEY', true)) {
|
||||
snsConfig.credentials = {
|
||||
accessKeyId: env.get('SNS_ACCESS_KEY_ID', true),
|
||||
secretAccessKey: env.get('SNS_SECRET_ACCESS_KEY', true),
|
||||
}
|
||||
}
|
||||
container.bind<AWS.SNS>(TYPES.SNS).toConstantValue(new AWS.SNS(snsConfig))
|
||||
}
|
||||
|
||||
if (env.get('SQS_QUEUE_URL', true)) {
|
||||
@@ -119,6 +135,34 @@ export class ContainerConfigLoader {
|
||||
container.bind(TYPES.SQS_QUEUE_URL).toConstantValue(env.get('SQS_QUEUE_URL', true))
|
||||
container.bind(TYPES.REDIS_EVENTS_CHANNEL).toConstantValue(env.get('REDIS_EVENTS_CHANNEL'))
|
||||
container.bind(TYPES.NEW_RELIC_ENABLED).toConstantValue(env.get('NEW_RELIC_ENABLED', true))
|
||||
container.bind(TYPES.ADMIN_EMAILS).toConstantValue(env.get('ADMIN_EMAILS').split(','))
|
||||
container.bind(TYPES.MIXPANEL_TOKEN).toConstantValue(env.get('MIXPANEL_TOKEN', true))
|
||||
|
||||
// Services
|
||||
container.bind<DomainEventFactory>(TYPES.DomainEventFactory).to(DomainEventFactory)
|
||||
container.bind<PeriodKeyGeneratorInterface>(TYPES.PeriodKeyGenerator).toConstantValue(new PeriodKeyGenerator())
|
||||
container
|
||||
.bind<AnalyticsStoreInterface>(TYPES.AnalyticsStore)
|
||||
.toConstantValue(new RedisAnalyticsStore(container.get(TYPES.PeriodKeyGenerator), container.get(TYPES.Redis)))
|
||||
container
|
||||
.bind<StatisticsStoreInterface>(TYPES.StatisticsStore)
|
||||
.toConstantValue(new RedisStatisticsStore(container.get(TYPES.PeriodKeyGenerator), container.get(TYPES.Redis)))
|
||||
container.bind<TimerInterface>(TYPES.Timer).toConstantValue(new Timer())
|
||||
|
||||
if (env.get('SNS_TOPIC_ARN', true)) {
|
||||
container
|
||||
.bind<SNSDomainEventPublisher>(TYPES.DomainEventPublisher)
|
||||
.toConstantValue(new SNSDomainEventPublisher(container.get(TYPES.SNS), container.get(TYPES.SNS_TOPIC_ARN)))
|
||||
} else {
|
||||
container
|
||||
.bind<RedisDomainEventPublisher>(TYPES.DomainEventPublisher)
|
||||
.toConstantValue(
|
||||
new RedisDomainEventPublisher(container.get(TYPES.Redis), container.get(TYPES.REDIS_EVENTS_CHANNEL)),
|
||||
)
|
||||
}
|
||||
if (env.get('MIXPANEL_TOKEN', true)) {
|
||||
container.bind<Mixpanel>(TYPES.MixpanelClient).toConstantValue(Mixpanel.init(env.get('MIXPANEL_TOKEN', true)))
|
||||
}
|
||||
|
||||
// Repositories
|
||||
container
|
||||
@@ -127,6 +171,9 @@ export class ContainerConfigLoader {
|
||||
container
|
||||
.bind<RevenueModificationRepositoryInterface>(TYPES.RevenueModificationRepository)
|
||||
.to(MySQLRevenueModificationRepository)
|
||||
container
|
||||
.bind<StatisticMeasureRepositoryInterface>(TYPES.StatisticMeasureRepository)
|
||||
.toConstantValue(new RedisStatisticsStore(container.get(TYPES.PeriodKeyGenerator), container.get(TYPES.Redis)))
|
||||
|
||||
// ORM
|
||||
container
|
||||
@@ -142,6 +189,9 @@ export class ContainerConfigLoader {
|
||||
container
|
||||
.bind<CalculateMonthlyRecurringRevenue>(TYPES.CalculateMonthlyRecurringRevenue)
|
||||
.to(CalculateMonthlyRecurringRevenue)
|
||||
container
|
||||
.bind<PersistStatistic>(TYPES.PersistStatistic)
|
||||
.toConstantValue(new PersistStatistic(container.get(TYPES.StatisticMeasureRepository)))
|
||||
|
||||
// Hanlders
|
||||
container.bind<UserRegisteredEventHandler>(TYPES.UserRegisteredEventHandler).to(UserRegisteredEventHandler)
|
||||
@@ -169,35 +219,22 @@ export class ContainerConfigLoader {
|
||||
.bind<SubscriptionReactivatedEventHandler>(TYPES.SubscriptionReactivatedEventHandler)
|
||||
.to(SubscriptionReactivatedEventHandler)
|
||||
container.bind<RefundProcessedEventHandler>(TYPES.RefundProcessedEventHandler).to(RefundProcessedEventHandler)
|
||||
container
|
||||
.bind<StatisticPersistenceRequestedEventHandler>(TYPES.StatisticPersistenceRequestedEventHandler)
|
||||
.toConstantValue(
|
||||
new StatisticPersistenceRequestedEventHandler(
|
||||
container.get(TYPES.PersistStatistic),
|
||||
container.get(TYPES.Timer),
|
||||
container.get(TYPES.Logger),
|
||||
env.get('MIXPANEL_TOKEN', true) ? container.get(TYPES.MixpanelClient) : null,
|
||||
),
|
||||
)
|
||||
|
||||
// Maps
|
||||
container
|
||||
.bind<MapInterface<RevenueModification, TypeORMRevenueModification>>(TYPES.RevenueModificationMap)
|
||||
.bind<MapperInterface<RevenueModification, TypeORMRevenueModification>>(TYPES.RevenueModificationMap)
|
||||
.to(RevenueModificationMap)
|
||||
|
||||
// Services
|
||||
container.bind<DomainEventFactory>(TYPES.DomainEventFactory).to(DomainEventFactory)
|
||||
container.bind<PeriodKeyGeneratorInterface>(TYPES.PeriodKeyGenerator).toConstantValue(new PeriodKeyGenerator())
|
||||
container
|
||||
.bind<AnalyticsStoreInterface>(TYPES.AnalyticsStore)
|
||||
.toConstantValue(new RedisAnalyticsStore(container.get(TYPES.PeriodKeyGenerator), container.get(TYPES.Redis)))
|
||||
container
|
||||
.bind<StatisticsStoreInterface>(TYPES.StatisticsStore)
|
||||
.toConstantValue(new RedisStatisticsStore(container.get(TYPES.PeriodKeyGenerator), container.get(TYPES.Redis)))
|
||||
container.bind<TimerInterface>(TYPES.Timer).toConstantValue(new Timer())
|
||||
|
||||
if (env.get('SNS_TOPIC_ARN', true)) {
|
||||
container
|
||||
.bind<SNSDomainEventPublisher>(TYPES.DomainEventPublisher)
|
||||
.toConstantValue(new SNSDomainEventPublisher(container.get(TYPES.SNS), container.get(TYPES.SNS_TOPIC_ARN)))
|
||||
} else {
|
||||
container
|
||||
.bind<RedisDomainEventPublisher>(TYPES.DomainEventPublisher)
|
||||
.toConstantValue(
|
||||
new RedisDomainEventPublisher(container.get(TYPES.Redis), container.get(TYPES.REDIS_EVENTS_CHANNEL)),
|
||||
)
|
||||
}
|
||||
|
||||
const eventHandlers: Map<string, DomainEventHandlerInterface> = new Map([
|
||||
['USER_REGISTERED', container.get(TYPES.UserRegisteredEventHandler)],
|
||||
['ACCOUNT_DELETION_REQUESTED', container.get(TYPES.AccountDeletionRequestedEventHandler)],
|
||||
@@ -210,6 +247,7 @@ export class ContainerConfigLoader {
|
||||
['SUBSCRIPTION_EXPIRED', container.get(TYPES.SubscriptionExpiredEventHandler)],
|
||||
['SUBSCRIPTION_REACTIVATED', container.get(TYPES.SubscriptionReactivatedEventHandler)],
|
||||
['REFUND_PROCESSED', container.get(TYPES.RefundProcessedEventHandler)],
|
||||
['STATISTIC_PERSISTENCE_REQUESTED', container.get(TYPES.StatisticPersistenceRequestedEventHandler)],
|
||||
])
|
||||
|
||||
if (env.get('SQS_QUEUE_URL', true)) {
|
||||
|
||||
@@ -11,9 +11,12 @@ const TYPES = {
|
||||
SQS_AWS_REGION: Symbol.for('SQS_AWS_REGION'),
|
||||
REDIS_EVENTS_CHANNEL: Symbol.for('REDIS_EVENTS_CHANNEL'),
|
||||
NEW_RELIC_ENABLED: Symbol.for('NEW_RELIC_ENABLED'),
|
||||
ADMIN_EMAILS: Symbol.for('ADMIN_EMAILS'),
|
||||
MIXPANEL_TOKEN: Symbol.for('MIXPANEL_TOKEN'),
|
||||
// Repositories
|
||||
AnalyticsEntityRepository: Symbol.for('AnalyticsEntityRepository'),
|
||||
RevenueModificationRepository: Symbol.for('RevenueModificationRepository'),
|
||||
StatisticMeasureRepository: Symbol.for('StatisticMeasureRepository'),
|
||||
// ORM
|
||||
ORMAnalyticsEntityRepository: Symbol.for('ORMAnalyticsEntityRepository'),
|
||||
ORMRevenueModificationRepository: Symbol.for('ORMRevenueModificationRepository'),
|
||||
@@ -21,6 +24,7 @@ const TYPES = {
|
||||
GetUserAnalyticsId: Symbol.for('GetUserAnalyticsId'),
|
||||
SaveRevenueModification: Symbol.for('SaveRevenueModification'),
|
||||
CalculateMonthlyRecurringRevenue: Symbol.for('CalculateMonthlyRecurringRevenue'),
|
||||
PersistStatistic: Symbol.for('PersistStatistic'),
|
||||
// Handlers
|
||||
UserRegisteredEventHandler: Symbol.for('UserRegisteredEventHandler'),
|
||||
AccountDeletionRequestedEventHandler: Symbol.for('AccountDeletionRequestedEventHandler'),
|
||||
@@ -33,6 +37,7 @@ const TYPES = {
|
||||
SubscriptionExpiredEventHandler: Symbol.for('SubscriptionExpiredEventHandler'),
|
||||
SubscriptionReactivatedEventHandler: Symbol.for('SubscriptionReactivatedEventHandler'),
|
||||
RefundProcessedEventHandler: Symbol.for('RefundProcessedEventHandler'),
|
||||
StatisticPersistenceRequestedEventHandler: Symbol.for('StatisticPersistenceRequestedEventHandler'),
|
||||
// Maps
|
||||
RevenueModificationMap: Symbol.for('RevenueModificationMap'),
|
||||
// Services
|
||||
@@ -44,6 +49,7 @@ const TYPES = {
|
||||
StatisticsStore: Symbol.for('StatisticsStore'),
|
||||
Timer: Symbol.for('Timer'),
|
||||
PeriodKeyGenerator: Symbol.for('PeriodKeyGenerator'),
|
||||
MixpanelClient: Symbol.for('MixpanelClient'),
|
||||
}
|
||||
|
||||
export default TYPES
|
||||
|
||||
11
packages/analytics/src/Domain/Email/DailyAnalyticsReport.ts
Normal file
11
packages/analytics/src/Domain/Email/DailyAnalyticsReport.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
|
||||
import { html } from './daily-analytics-report.html'
|
||||
|
||||
export function getSubject(): string {
|
||||
return `Daily analytics report ${new Date().toLocaleDateString('en-US')}`
|
||||
}
|
||||
|
||||
export function getBody(data: unknown, timer: TimerInterface): string {
|
||||
return html(data, timer)
|
||||
}
|
||||
@@ -0,0 +1,979 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
|
||||
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
||||
import { StatisticMeasureName } from '../Statistics/StatisticMeasureName'
|
||||
import { Period } from '../Time/Period'
|
||||
|
||||
const countActiveUsers = (measureName: string, data: any): { yesterday: number; last30Days: number } => {
|
||||
const totalActiveUsersLast30DaysIncludingToday = data.statisticsOverTime.find(
|
||||
(a: { name: string; period: number }) => a.name === measureName && a.period === 27,
|
||||
)
|
||||
|
||||
const totalActiveUsersYesterday =
|
||||
totalActiveUsersLast30DaysIncludingToday.counts[totalActiveUsersLast30DaysIncludingToday.counts.length - 2]
|
||||
.totalCount
|
||||
|
||||
const filteredCounts = totalActiveUsersLast30DaysIncludingToday.counts.filter(
|
||||
(count: { totalCount: number }) => count.totalCount !== 0,
|
||||
)
|
||||
if (filteredCounts.length === 0) {
|
||||
return {
|
||||
yesterday: 0,
|
||||
last30Days: 0,
|
||||
}
|
||||
}
|
||||
|
||||
const last30DaysNumbers = filteredCounts.map((count: { totalCount: number }) => count.totalCount)
|
||||
const last30DaysCount = last30DaysNumbers.reduce((previousValue: number, currentValue: number) => {
|
||||
return previousValue + currentValue
|
||||
})
|
||||
|
||||
const averageActiveUsersLast30Days = Math.floor(last30DaysCount / last30DaysNumbers.length)
|
||||
|
||||
return {
|
||||
yesterday: totalActiveUsersYesterday,
|
||||
last30Days: averageActiveUsersLast30Days,
|
||||
}
|
||||
}
|
||||
|
||||
const getChartUrls = (
|
||||
data: any,
|
||||
): {
|
||||
subscriptions: string
|
||||
users: string
|
||||
quarterlyPerformance: string
|
||||
churn: string
|
||||
mrrMonthly: string
|
||||
} => {
|
||||
const subscriptionPurchasingOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.SubscriptionPurchased && a.period === Period.Last30Days,
|
||||
)
|
||||
const subscriptionRenewingOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.SubscriptionRenewed && a.period === Period.Last30Days,
|
||||
)
|
||||
const subscriptionRefundingOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.SubscriptionRefunded && a.period === Period.Last30Days,
|
||||
)
|
||||
const subscriptionCancelledOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.SubscriptionCancelled && a.period === Period.Last30Days,
|
||||
)
|
||||
const subscriptionReactivatedOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.SubscriptionReactivated && a.period === Period.Last30Days,
|
||||
)
|
||||
|
||||
const subscriptionsLinerOverTimeConfig = {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: subscriptionPurchasingOverTime?.counts.map((count: { periodKey: any }) => count.periodKey),
|
||||
datasets: [
|
||||
{
|
||||
label: 'Subscription Purchases',
|
||||
backgroundColor: 'rgb(25, 255, 140)',
|
||||
borderColor: 'rgb(25, 255, 140)',
|
||||
data: subscriptionPurchasingOverTime?.counts.map((count: { totalCount: any }) => count.totalCount),
|
||||
fill: false,
|
||||
pointRadius: 2,
|
||||
},
|
||||
{
|
||||
label: 'Subscription Renewals',
|
||||
backgroundColor: 'rgb(54, 162, 235)',
|
||||
borderColor: 'rgb(54, 162, 235)',
|
||||
data: subscriptionRenewingOverTime?.counts.map((count: { totalCount: any }) => count.totalCount),
|
||||
fill: false,
|
||||
pointRadius: 2,
|
||||
},
|
||||
{
|
||||
label: 'Subscription Refunds',
|
||||
backgroundColor: 'rgb(255, 221, 51)',
|
||||
borderColor: 'rgb(255, 221, 51)',
|
||||
data: subscriptionRefundingOverTime?.counts.map((count: { totalCount: any }) => count.totalCount),
|
||||
fill: false,
|
||||
pointRadius: 2,
|
||||
},
|
||||
{
|
||||
label: 'Subscription Cancels',
|
||||
backgroundColor: 'rgb(255, 99, 132)',
|
||||
borderColor: 'rgb(255, 99, 132)',
|
||||
data: subscriptionCancelledOverTime?.counts.map((count: { totalCount: any }) => count.totalCount),
|
||||
fill: false,
|
||||
pointRadius: 2,
|
||||
},
|
||||
{
|
||||
label: 'Subscription Reactivations',
|
||||
backgroundColor: 'rgb(221, 51, 255)',
|
||||
borderColor: 'rgb(221, 51, 255)',
|
||||
data: subscriptionReactivatedOverTime?.counts.map((count: { totalCount: any }) => count.totalCount),
|
||||
fill: false,
|
||||
pointRadius: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
const userRegistrationOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.Register && a.period === Period.Last30Days,
|
||||
)
|
||||
const userDeletionOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.DeleteAccount && a.period === Period.Last30Days,
|
||||
)
|
||||
|
||||
const usersLinerOverTimeConfig = {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: userRegistrationOverTime?.counts.map((count: { periodKey: any }) => count.periodKey),
|
||||
datasets: [
|
||||
{
|
||||
label: 'User Registrations',
|
||||
backgroundColor: 'rgb(25, 255, 140)',
|
||||
borderColor: 'rgb(25, 255, 140)',
|
||||
data: userRegistrationOverTime?.counts.map((count: { totalCount: any }) => count.totalCount),
|
||||
fill: false,
|
||||
pointRadius: 2,
|
||||
},
|
||||
{
|
||||
label: 'Account Deletions',
|
||||
backgroundColor: 'rgb(255, 99, 132)',
|
||||
borderColor: 'rgb(255, 99, 132)',
|
||||
data: userDeletionOverTime?.counts.map((count: { totalCount: any }) => count.totalCount),
|
||||
fill: false,
|
||||
pointRadius: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
const quarters = [Period.Q1ThisYear, Period.Q2ThisYear, Period.Q3ThisYear, Period.Q4ThisYear]
|
||||
const quarterlyUserRegistrations = []
|
||||
const quarterlySubscriptionPurchases = []
|
||||
const quarterlySubscriptionRenewals = []
|
||||
for (const quarter of quarters) {
|
||||
const registrations =
|
||||
data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.Register && a.period === quarter,
|
||||
)?.totalCount ?? 0
|
||||
const purchases =
|
||||
data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.SubscriptionPurchased && a.period === quarter,
|
||||
)?.totalCount ?? 0
|
||||
const renewals =
|
||||
data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.SubscriptionRenewed && a.period === quarter,
|
||||
)?.totalCount ?? 0
|
||||
quarterlyUserRegistrations.push(registrations)
|
||||
quarterlySubscriptionPurchases.push(purchases)
|
||||
quarterlySubscriptionRenewals.push(renewals)
|
||||
}
|
||||
|
||||
const quarterlyConfig = {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
|
||||
datasets: [
|
||||
{
|
||||
label: 'User Registrations',
|
||||
backgroundColor: 'rgba(255, 99, 132, 0.5)',
|
||||
borderColor: 'rgb(255, 99, 132)',
|
||||
borderWidth: 1,
|
||||
data: quarterlyUserRegistrations,
|
||||
},
|
||||
{
|
||||
label: 'Subscription Purchases',
|
||||
backgroundColor: 'rgba(54, 162, 235, 0.5)',
|
||||
borderColor: 'rgb(54, 162, 235)',
|
||||
borderWidth: 1,
|
||||
data: quarterlySubscriptionPurchases,
|
||||
},
|
||||
{
|
||||
label: 'Subscription Renewals',
|
||||
backgroundColor: 'rgb(25, 255, 140, 0.5)',
|
||||
borderColor: 'rgb(25, 255, 140)',
|
||||
borderWidth: 1,
|
||||
data: quarterlySubscriptionRenewals,
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Quarterly Performance',
|
||||
},
|
||||
plugins: {
|
||||
datalabels: {
|
||||
anchor: 'center',
|
||||
align: 'center',
|
||||
color: '#666',
|
||||
font: {
|
||||
weight: 'normal',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const monthlyChurnRates = data.churn.values.map((value: { rate: number }) => +value.rate.toFixed(2))
|
||||
|
||||
const churnConfig = {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: [
|
||||
'January',
|
||||
'February',
|
||||
'March',
|
||||
'April',
|
||||
'May',
|
||||
'June',
|
||||
'July',
|
||||
'August',
|
||||
'September',
|
||||
'October',
|
||||
'November',
|
||||
'December',
|
||||
],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Churn Percent',
|
||||
backgroundColor: 'rgba(255, 99, 132, 0.5)',
|
||||
borderColor: 'rgb(255, 99, 132)',
|
||||
borderWidth: 1,
|
||||
data: monthlyChurnRates,
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Monthly Churn Rate',
|
||||
},
|
||||
plugins: {
|
||||
datalabels: {
|
||||
anchor: 'center',
|
||||
align: 'center',
|
||||
color: '#666',
|
||||
font: {
|
||||
weight: 'normal',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const mrrMonthlyOverTime = data.statisticsOverTime
|
||||
.find((a: { name: string; period: Period }) => a.name === 'mrr' && a.period === Period.ThisYear)
|
||||
?.counts.map((count: { totalCount: number }) => +count.totalCount.toFixed(2))
|
||||
|
||||
const mrrMonthlyConfig = {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: [
|
||||
'January',
|
||||
'February',
|
||||
'March',
|
||||
'April',
|
||||
'May',
|
||||
'June',
|
||||
'July',
|
||||
'August',
|
||||
'September',
|
||||
'October',
|
||||
'November',
|
||||
'December',
|
||||
],
|
||||
datasets: [
|
||||
{
|
||||
label: 'MRR',
|
||||
backgroundColor: 'rgba(25, 255, 140, 0.5)',
|
||||
borderColor: 'rgb(25, 255, 140)',
|
||||
borderWidth: 1,
|
||||
data: mrrMonthlyOverTime,
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Monthly MRR',
|
||||
},
|
||||
plugins: {
|
||||
datalabels: {
|
||||
anchor: 'center',
|
||||
align: 'center',
|
||||
color: '#666',
|
||||
font: {
|
||||
weight: 'normal',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
subscriptions: `https://quickchart.io/chart?width=800&c=${encodeURIComponent(
|
||||
JSON.stringify(subscriptionsLinerOverTimeConfig),
|
||||
)}`,
|
||||
users: `https://quickchart.io/chart?width=800&c=${encodeURIComponent(JSON.stringify(usersLinerOverTimeConfig))}`,
|
||||
quarterlyPerformance: `https://quickchart.io/chart?width=800&c=${encodeURIComponent(
|
||||
JSON.stringify(quarterlyConfig),
|
||||
)}`,
|
||||
churn: `https://quickchart.io/chart?width=800&c=${encodeURIComponent(JSON.stringify(churnConfig))}`,
|
||||
mrrMonthly: `https://quickchart.io/chart?width=800&c=${encodeURIComponent(JSON.stringify(mrrMonthlyConfig))}`,
|
||||
}
|
||||
}
|
||||
|
||||
export const html = (data: any, timer: TimerInterface) => {
|
||||
const chartUrls = getChartUrls(data)
|
||||
|
||||
const successfullPaymentsActivity = data.activityStatistics.find(
|
||||
(a: { name: AnalyticsActivity }) => a.name === AnalyticsActivity.PaymentSuccess && Period.Yesterday,
|
||||
)
|
||||
const failedPaymentsActivity = data.activityStatistics.find(
|
||||
(a: { name: AnalyticsActivity }) => a.name === AnalyticsActivity.PaymentFailed && Period.Yesterday,
|
||||
)
|
||||
const limitedDiscountPurchasedActivity = data.activityStatistics.find(
|
||||
(a: { name: AnalyticsActivity }) => a.name === AnalyticsActivity.LimitedDiscountOfferPurchased && Period.Yesterday,
|
||||
)
|
||||
const subscriptionPurchasingOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.SubscriptionPurchased && a.period === Period.Last30Days,
|
||||
)
|
||||
const subscriptionRenewingOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.SubscriptionRenewed && a.period === Period.Last30Days,
|
||||
)
|
||||
const subscriptionRefundingOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.SubscriptionRefunded && a.period === Period.Last30Days,
|
||||
)
|
||||
const subscriptionCancelledOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.SubscriptionCancelled && a.period === Period.Last30Days,
|
||||
)
|
||||
const subscriptionReactivatedOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.SubscriptionReactivated && a.period === Period.Last30Days,
|
||||
)
|
||||
const userRegistrationOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.Register && a.period === Period.Last30Days,
|
||||
)
|
||||
const userDeletionOverTime = data.activityStatisticsOverTime.find(
|
||||
(a: { name: AnalyticsActivity; period: Period }) =>
|
||||
a.name === AnalyticsActivity.DeleteAccount && a.period === Period.Last30Days,
|
||||
)
|
||||
const incomeMeasureYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.Income && a.period === Period.Yesterday,
|
||||
)
|
||||
const refundMeasureYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.Refunds && a.period === Period.Yesterday,
|
||||
)
|
||||
const incomeYesterday = incomeMeasureYesterday?.totalValue ?? 0
|
||||
const refundsYesterday = refundMeasureYesterday?.totalValue ?? 0
|
||||
const revenueYesterday = incomeYesterday - refundsYesterday
|
||||
|
||||
const subscriptionLengthMeasureYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.SubscriptionLength && a.period === Period.Yesterday,
|
||||
)
|
||||
const subscriptionLengthDurationYesterday = timer.convertMicrosecondsToTimeStructure(
|
||||
Math.floor(subscriptionLengthMeasureYesterday?.average ?? 0),
|
||||
)
|
||||
|
||||
const subscriptionRemainingTimePercentageMeasureYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.RemainingSubscriptionTimePercentage && a.period === Period.Yesterday,
|
||||
)
|
||||
const subscriptionRemainingTimePercentageYesterday = Math.floor(
|
||||
subscriptionRemainingTimePercentageMeasureYesterday?.average ?? 0,
|
||||
)
|
||||
|
||||
const registrationLengthMeasureYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.RegistrationLength && a.period === Period.Yesterday,
|
||||
)
|
||||
const registrationLengthDurationYesterday = timer.convertMicrosecondsToTimeStructure(
|
||||
Math.floor(registrationLengthMeasureYesterday?.average ?? 0),
|
||||
)
|
||||
|
||||
const registrationToSubscriptionMeasureYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.RegistrationToSubscriptionTime && a.period === Period.Yesterday,
|
||||
)
|
||||
const registrationToSubscriptionDurationYesterday = timer.convertMicrosecondsToTimeStructure(
|
||||
Math.floor(registrationToSubscriptionMeasureYesterday?.average ?? 0),
|
||||
)
|
||||
|
||||
const incomeMeasureThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.Income && a.period === Period.ThisMonth,
|
||||
)
|
||||
const refundMeasureThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.Refunds && a.period === Period.ThisMonth,
|
||||
)
|
||||
const incomeThisMonth = incomeMeasureThisMonth?.totalValue ?? 0
|
||||
const refundsThisMonth = refundMeasureThisMonth?.totalValue ?? 0
|
||||
const revenueThisMonth = incomeThisMonth - refundsThisMonth
|
||||
|
||||
const subscriptionLengthMeasureThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.SubscriptionLength && a.period === Period.ThisMonth,
|
||||
)
|
||||
const subscriptionLengthDurationThisMonth = timer.convertMicrosecondsToTimeStructure(
|
||||
Math.floor(subscriptionLengthMeasureThisMonth?.average ?? 0),
|
||||
)
|
||||
|
||||
const subscriptionRemainingTimePercentageMeasureThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.RemainingSubscriptionTimePercentage && a.period === Period.ThisMonth,
|
||||
)
|
||||
const subscriptionRemainingTimePercentageThisMonth = Math.floor(
|
||||
subscriptionRemainingTimePercentageMeasureThisMonth?.average ?? 0,
|
||||
)
|
||||
|
||||
const registrationLengthMeasureThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.RegistrationLength && a.period === Period.ThisMonth,
|
||||
)
|
||||
const registrationLengthDurationThisMonth = timer.convertMicrosecondsToTimeStructure(
|
||||
Math.floor(registrationLengthMeasureThisMonth?.average ?? 0),
|
||||
)
|
||||
|
||||
const registrationToSubscriptionMeasureThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.RegistrationToSubscriptionTime && a.period === Period.ThisMonth,
|
||||
)
|
||||
const registrationToSubscriptionDurationThisMonth = timer.convertMicrosecondsToTimeStructure(
|
||||
Math.floor(registrationToSubscriptionMeasureThisMonth?.average ?? 0),
|
||||
)
|
||||
|
||||
const plusSubscriptionsInitialAnnualPaymentsYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.PlusSubscriptionInitialAnnualPaymentsIncome &&
|
||||
a.period === Period.Yesterday,
|
||||
)
|
||||
const plusSubscriptionsInitialMonthlyPaymentsYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.PlusSubscriptionInitialMonthlyPaymentsIncome &&
|
||||
a.period === Period.Yesterday,
|
||||
)
|
||||
const plusSubscriptionsRenewingAnnualPaymentsYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.PlusSubscriptionRenewingAnnualPaymentsIncome &&
|
||||
a.period === Period.Yesterday,
|
||||
)
|
||||
const plusSubscriptionsRenewingMonthlyPaymentsYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.PlusSubscriptionRenewingMonthlyPaymentsIncome &&
|
||||
a.period === Period.Yesterday,
|
||||
)
|
||||
const proSubscriptionsInitialAnnualPaymentsYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.ProSubscriptionInitialAnnualPaymentsIncome && a.period === Period.Yesterday,
|
||||
)
|
||||
const proSubscriptionsInitialMonthlyPaymentsYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.ProSubscriptionInitialMonthlyPaymentsIncome &&
|
||||
a.period === Period.Yesterday,
|
||||
)
|
||||
const proSubscriptionsRenewingAnnualPaymentsYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.ProSubscriptionRenewingAnnualPaymentsIncome &&
|
||||
a.period === Period.Yesterday,
|
||||
)
|
||||
const proSubscriptionsRenewingMonthlyPaymentsYesterday = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.ProSubscriptionRenewingMonthlyPaymentsIncome &&
|
||||
a.period === Period.Yesterday,
|
||||
)
|
||||
const plusSubscriptionsInitialAnnualPaymentsThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.PlusSubscriptionInitialAnnualPaymentsIncome &&
|
||||
a.period === Period.ThisMonth,
|
||||
)
|
||||
const plusSubscriptionsInitialMonthlyPaymentsThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.PlusSubscriptionInitialMonthlyPaymentsIncome &&
|
||||
a.period === Period.ThisMonth,
|
||||
)
|
||||
const plusSubscriptionsRenewingAnnualPaymentsThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.PlusSubscriptionRenewingAnnualPaymentsIncome &&
|
||||
a.period === Period.ThisMonth,
|
||||
)
|
||||
const plusSubscriptionsRenewingMonthlyPaymentsThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.PlusSubscriptionRenewingMonthlyPaymentsIncome &&
|
||||
a.period === Period.ThisMonth,
|
||||
)
|
||||
const proSubscriptionsInitialAnnualPaymentsThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.ProSubscriptionInitialAnnualPaymentsIncome && a.period === Period.ThisMonth,
|
||||
)
|
||||
const proSubscriptionsInitialMonthlyPaymentsThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.ProSubscriptionInitialMonthlyPaymentsIncome &&
|
||||
a.period === Period.ThisMonth,
|
||||
)
|
||||
const proSubscriptionsRenewingAnnualPaymentsThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.ProSubscriptionRenewingAnnualPaymentsIncome &&
|
||||
a.period === Period.ThisMonth,
|
||||
)
|
||||
const proSubscriptionsRenewingMonthlyPaymentsThisMonth = data.statisticMeasures.find(
|
||||
(a: { name: string; period: Period }) =>
|
||||
a.name === StatisticMeasureName.NAMES.ProSubscriptionRenewingMonthlyPaymentsIncome &&
|
||||
a.period === Period.ThisMonth,
|
||||
)
|
||||
|
||||
const mrrOverTime = data.statisticsOverTime.find(
|
||||
(a: { name: string; period: number }) => a.name === 'mrr' && a.period === 27,
|
||||
)
|
||||
const monthlyPlansMrrOverTime = data.statisticsOverTime.find(
|
||||
(a: { name: string; period: number }) => a.name === 'monthly-plans-mrr' && a.period === 27,
|
||||
)
|
||||
const annualPlansMrrOverTime = data.statisticsOverTime.find(
|
||||
(a: { name: string; period: number }) => a.name === 'annual-plans-mrr' && a.period === 27,
|
||||
)
|
||||
const fiveYearPlansMrrOverTime = data.statisticsOverTime.find(
|
||||
(a: { name: string; period: number }) => a.name === 'five-year-plans-mrr' && a.period === 27,
|
||||
)
|
||||
const proPlansMrrOverTime = data.statisticsOverTime.find(
|
||||
(a: { name: string; period: number }) => a.name === 'pro-plans-mrr' && a.period === 27,
|
||||
)
|
||||
const plusPlansMrrOverTime = data.statisticsOverTime.find(
|
||||
(a: { name: string; period: number }) => a.name === 'plus-plans-mrr' && a.period === 27,
|
||||
)
|
||||
|
||||
const today = new Date()
|
||||
const thisMonthPeriodKey = `${today.getFullYear().toString()}-${(today.getMonth() + 1).toString()}`
|
||||
const thisMonthChurn = data.churn.values.find(
|
||||
(value: { periodKey: string }) => value.periodKey === thisMonthPeriodKey,
|
||||
)
|
||||
|
||||
const totalActiveUsers = countActiveUsers(StatisticMeasureName.NAMES.ActiveUsers, data)
|
||||
const totalActiveFreeUsers = countActiveUsers(StatisticMeasureName.NAMES.ActiveFreeUsers, data)
|
||||
const totalActivePlusUsers = countActiveUsers(StatisticMeasureName.NAMES.ActivePlusUsers, data)
|
||||
const totalActiveProUsers = countActiveUsers(StatisticMeasureName.NAMES.ActiveProUsers, data)
|
||||
|
||||
return ` <div>
|
||||
<p>Hello,</p>
|
||||
<p>
|
||||
<strong>Here are some statistics from yesterday:</strong>
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Active Users</b>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Total:</b> ${totalActiveUsers.yesterday.toLocaleString('en-US')}
|
||||
</li>
|
||||
<li>
|
||||
<b>By Subscription Type:</b>
|
||||
<ul>
|
||||
<li>
|
||||
<b>FREE:</b> ${totalActiveFreeUsers.yesterday.toLocaleString('en-US')}
|
||||
</li>
|
||||
<li>
|
||||
<b>PLUS:</b> ${totalActivePlusUsers.yesterday.toLocaleString('en-US')}
|
||||
</li>
|
||||
<li>
|
||||
<b>PRO:</b> ${totalActiveProUsers.yesterday.toLocaleString('en-US')}
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>Payments</b>
|
||||
<ul>
|
||||
<li>
|
||||
Revenue: <b>$${revenueYesterday.toLocaleString('en-US')}</b> (Income: $
|
||||
${incomeYesterday.toLocaleString('en-US')}, Refunds: $${refundsYesterday.toLocaleString('en-US')})
|
||||
</li>
|
||||
<li>
|
||||
Successfull payments: <b>${successfullPaymentsActivity?.totalCount.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
Failed payments: <b>${failedPaymentsActivity?.totalCount.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>MRR Breakdown</b>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Total:</b> $${mrrOverTime?.counts[mrrOverTime?.counts.length - 1].totalCount.toLocaleString('en-US')}
|
||||
</li>
|
||||
<li>
|
||||
<b>By Subscription Type:</b>
|
||||
<ul>
|
||||
<li>
|
||||
<b>PLUS:</b> $
|
||||
${plusPlansMrrOverTime?.counts[plusPlansMrrOverTime?.counts.length - 1].totalCount.toLocaleString('en-US')}
|
||||
</li>
|
||||
<li>
|
||||
<b>PRO:</b> $
|
||||
${proPlansMrrOverTime?.counts[proPlansMrrOverTime?.counts.length - 1].totalCount.toLocaleString('en-US')}
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>By Billing Frequency:</b>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Monthly:</b> $
|
||||
${monthlyPlansMrrOverTime?.counts[monthlyPlansMrrOverTime?.counts.length - 1].totalCount.toLocaleString(
|
||||
'en-US',
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
<b>Annual:</b> $
|
||||
${annualPlansMrrOverTime?.counts[annualPlansMrrOverTime?.counts.length - 1].totalCount.toLocaleString(
|
||||
'en-US',
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
<b>5-year:</b> $
|
||||
${fiveYearPlansMrrOverTime?.counts[fiveYearPlansMrrOverTime?.counts.length - 1].totalCount.toLocaleString(
|
||||
'en-US',
|
||||
)}
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>Income Breakdown</b>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Plus Subscription:</b>
|
||||
<ul>
|
||||
<li>
|
||||
<b>${plusSubscriptionsInitialMonthlyPaymentsYesterday?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>initial</i> payments on <u>monhtly</u> plan, totaling${' '}
|
||||
<b>$${plusSubscriptionsInitialMonthlyPaymentsYesterday?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
<b>${plusSubscriptionsInitialAnnualPaymentsYesterday?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>initial</i> payments on <u>annual</u> plan, totaling${' '}
|
||||
<b>$${plusSubscriptionsInitialAnnualPaymentsYesterday?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
<b>${plusSubscriptionsRenewingMonthlyPaymentsYesterday?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>renewing</i> payments on <u>monthly</u> plan, totaling${' '}
|
||||
<b>$${plusSubscriptionsRenewingMonthlyPaymentsYesterday?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
<b>${plusSubscriptionsRenewingAnnualPaymentsYesterday?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>renewing</i> payments on <u>annual</u> plan, totaling${' '}
|
||||
<b>$${plusSubscriptionsRenewingAnnualPaymentsYesterday?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>Pro Subscription:</b>
|
||||
<ul>
|
||||
<li>
|
||||
<b>${proSubscriptionsInitialMonthlyPaymentsYesterday?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>initial</i> payments on <u>monhtly</u> plan, totaling${' '}
|
||||
<b>$${proSubscriptionsInitialMonthlyPaymentsYesterday?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
<b>${proSubscriptionsInitialAnnualPaymentsYesterday?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>initial</i> payments on <u>annual</u> plan, totaling${' '}
|
||||
<b>$${proSubscriptionsInitialAnnualPaymentsYesterday?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
<b>${proSubscriptionsRenewingMonthlyPaymentsYesterday?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>renewing</i> payments on <u>monthly</u> plan, totaling${' '}
|
||||
<b>$${proSubscriptionsRenewingMonthlyPaymentsYesterday?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
<b>${proSubscriptionsRenewingAnnualPaymentsYesterday?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>renewing</i> payments on <u>annual</u> plan, totaling${' '}
|
||||
<b>$${proSubscriptionsRenewingAnnualPaymentsYesterday?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>Users</b>
|
||||
<ul>
|
||||
<li>
|
||||
Number of users registered:${' '}
|
||||
<b>
|
||||
${userRegistrationOverTime?.counts[userRegistrationOverTime?.counts.length - 1]?.totalCount.toLocaleString(
|
||||
'en-US',
|
||||
)}
|
||||
</b>
|
||||
</li>
|
||||
<li>
|
||||
Number of users unregistered:${' '}
|
||||
<b>
|
||||
${userDeletionOverTime?.counts[userDeletionOverTime?.counts.length - 1]?.totalCount.toLocaleString('en-US')}
|
||||
</b>${' '}
|
||||
(average account duration: ${registrationLengthDurationYesterday.days} days${' '}
|
||||
${registrationLengthDurationYesterday.hours} hours ${registrationLengthDurationYesterday.minutes} minutes)
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>Subscriptions</b>
|
||||
<ul>
|
||||
<li>
|
||||
Number of subscriptions purchased:${' '}
|
||||
<b>
|
||||
${subscriptionPurchasingOverTime?.counts[
|
||||
subscriptionPurchasingOverTime?.counts.length - 1
|
||||
]?.totalCount.toLocaleString('en-US')}
|
||||
</b>${' '}
|
||||
(includes <b>${limitedDiscountPurchasedActivity?.totalCount.toLocaleString('en-US')}</b> limited time
|
||||
offer purchases)
|
||||
</li>
|
||||
<li>
|
||||
Number of subscriptions renewed:${' '}
|
||||
<b>
|
||||
${subscriptionRenewingOverTime?.counts[
|
||||
subscriptionRenewingOverTime?.counts.length - 1
|
||||
]?.totalCount.toLocaleString('en-US')}
|
||||
</b>
|
||||
</li>
|
||||
<li>
|
||||
Number of subscriptions refunded:${' '}
|
||||
<b>
|
||||
${subscriptionRefundingOverTime?.counts[
|
||||
subscriptionRefundingOverTime?.counts.length - 1
|
||||
]?.totalCount.toLocaleString('en-US')}
|
||||
</b>
|
||||
</li>
|
||||
<li>
|
||||
Number of subscriptions cancelled:${' '}
|
||||
<b>
|
||||
${subscriptionCancelledOverTime?.counts[
|
||||
subscriptionCancelledOverTime?.counts.length - 1
|
||||
]?.totalCount.toLocaleString('en-US')}
|
||||
</b>${' '}
|
||||
(average subscription duration: ${subscriptionLengthDurationYesterday.days} days${' '}
|
||||
${subscriptionLengthDurationYesterday.hours} hours ${subscriptionLengthDurationYesterday.minutes} minutes,
|
||||
average remaining subscription percentage: ${subscriptionRemainingTimePercentageYesterday}%)
|
||||
</li>
|
||||
<li>
|
||||
Number of subscriptions reactivated:${' '}
|
||||
<b>
|
||||
${subscriptionReactivatedOverTime?.counts[
|
||||
subscriptionReactivatedOverTime?.counts.length - 1
|
||||
]?.totalCount.toLocaleString('en-US')}
|
||||
</b>
|
||||
</li>
|
||||
<li>
|
||||
Average time from registration to subscription purchase:${' '}
|
||||
<b>
|
||||
${registrationToSubscriptionDurationYesterday.days} days${' '}
|
||||
${registrationToSubscriptionDurationYesterday.hours} hours${' '}
|
||||
${registrationToSubscriptionDurationYesterday.minutes} minutes
|
||||
</b>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<strong>Here are some statistics from last 30 days:</strong>
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Active Users (Average)</b>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Total:</b> ${totalActiveUsers.last30Days.toLocaleString('en-US')}
|
||||
</li>
|
||||
<li>
|
||||
<b>By Subscription Type:</b>
|
||||
<ul>
|
||||
<li>
|
||||
<b>FREE:</b> ${totalActiveFreeUsers.last30Days.toLocaleString('en-US')}
|
||||
</li>
|
||||
<li>
|
||||
<b>PLUS:</b> ${totalActivePlusUsers.last30Days.toLocaleString('en-US')}
|
||||
</li>
|
||||
<li>
|
||||
<b>PRO:</b> ${totalActiveProUsers.last30Days.toLocaleString('en-US')}
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>Payments (This Month)</b>
|
||||
<ul>
|
||||
<li>
|
||||
Revenue: <b>$${revenueThisMonth.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
Income: <b>$${incomeThisMonth.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
Refunds: <b>$${refundsThisMonth.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>Income Breakdown (This Month)</b>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Plus Subscription:</b>
|
||||
<ul>
|
||||
<li>
|
||||
<b>${plusSubscriptionsInitialMonthlyPaymentsThisMonth?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>initial</i> payments on <u>monhtly</u> plan, totaling${' '}
|
||||
<b>$${plusSubscriptionsInitialMonthlyPaymentsThisMonth?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
<b>${plusSubscriptionsInitialAnnualPaymentsThisMonth?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>initial</i> payments on <u>annual</u> plan, totaling${' '}
|
||||
<b>$${plusSubscriptionsInitialAnnualPaymentsThisMonth?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
<b>${plusSubscriptionsRenewingMonthlyPaymentsThisMonth?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>renewing</i> payments on <u>monthly</u> plan, totaling${' '}
|
||||
<b>$${plusSubscriptionsRenewingMonthlyPaymentsThisMonth?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
<b>${plusSubscriptionsRenewingAnnualPaymentsThisMonth?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>renewing</i> payments on <u>annual</u> plan, totaling${' '}
|
||||
<b>$${plusSubscriptionsRenewingAnnualPaymentsThisMonth?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>Pro Subscription:</b>
|
||||
<ul>
|
||||
<li>
|
||||
<b>${proSubscriptionsInitialMonthlyPaymentsThisMonth?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>initial</i> payments on <u>monhtly</u> plan, totaling${' '}
|
||||
<b>$${proSubscriptionsInitialMonthlyPaymentsThisMonth?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
<b>${proSubscriptionsInitialAnnualPaymentsThisMonth?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>initial</i> payments on <u>annual</u> plan, totaling${' '}
|
||||
<b>$${proSubscriptionsInitialAnnualPaymentsThisMonth?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
<b>${proSubscriptionsRenewingMonthlyPaymentsThisMonth?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>renewing</i> payments on <u>monthly</u> plan, totaling${' '}
|
||||
<b>$${proSubscriptionsRenewingMonthlyPaymentsThisMonth?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
<b>${proSubscriptionsRenewingAnnualPaymentsThisMonth?.increments.toLocaleString('en-US')}</b>${' '}
|
||||
<i>renewing</i> payments on <u>annual</u> plan, totaling${' '}
|
||||
<b>$${proSubscriptionsRenewingAnnualPaymentsThisMonth?.totalValue.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>Users</b>
|
||||
<ul>
|
||||
<li>
|
||||
Number of users registered: <b>${userRegistrationOverTime?.totalCount.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
Number of users unregistered: <b>${userDeletionOverTime?.totalCount.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
Average account duration this month:${' '}
|
||||
<b>
|
||||
${registrationLengthDurationThisMonth.days} days ${registrationLengthDurationThisMonth.hours} hours${' '}
|
||||
${registrationLengthDurationThisMonth.minutes} minutes
|
||||
</b>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>Subscriptions</b>
|
||||
<ul>
|
||||
<li>
|
||||
Number of subscriptions purchased:${' '}
|
||||
<b>${subscriptionPurchasingOverTime?.totalCount.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
Number of subscriptions renewed:${' '}
|
||||
<b>${subscriptionRenewingOverTime?.totalCount.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
Number of subscriptions refunded:${' '}
|
||||
<b>${subscriptionRefundingOverTime?.totalCount.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
Number of subscriptions cancelled:${' '}
|
||||
<b>${subscriptionCancelledOverTime?.totalCount.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
Number of subscriptions reactivated:${' '}
|
||||
<b>${subscriptionReactivatedOverTime?.totalCount.toLocaleString('en-US')}</b>
|
||||
</li>
|
||||
<li>
|
||||
Average subscription duration this month:${' '}
|
||||
<b>
|
||||
${subscriptionLengthDurationThisMonth.days} days ${subscriptionLengthDurationThisMonth.hours} hours${' '}
|
||||
${subscriptionLengthDurationThisMonth.minutes} minutes
|
||||
</b>
|
||||
</li>
|
||||
<li>
|
||||
Average subscription remaining percentage this month:${' '}
|
||||
<b>${subscriptionRemainingTimePercentageThisMonth}%</b>
|
||||
</li>
|
||||
<li>
|
||||
Average time from registration to subscription purchase this month:${' '}
|
||||
<b>
|
||||
${registrationToSubscriptionDurationThisMonth.days} days${' '}
|
||||
${registrationToSubscriptionDurationThisMonth.hours} hours${' '}
|
||||
${registrationToSubscriptionDurationThisMonth.minutes} minutes
|
||||
</b>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<strong>Here is the MRR Monthly chart this year:</strong>
|
||||
</p>
|
||||
<img src=${chartUrls.mrrMonthly}></img>
|
||||
<p>
|
||||
<strong>Here is the subscription chart over 30 days:</strong>
|
||||
</p>
|
||||
<img src=${chartUrls.subscriptions}></img>
|
||||
<p>
|
||||
<strong>Here is the users chart over 30 days:</strong>
|
||||
</p>
|
||||
<img src=${chartUrls.users}></img>
|
||||
<p>
|
||||
<strong>Here is the monthly churn rate percentage:</strong>
|
||||
</p>
|
||||
<p>✅ GREAT! Up to 7% 🔶 OKAY: 8-10% 🩸 BAD: 11 -15 % 🚨 TERRIBLE! 16-20%</p>
|
||||
<p>Churn is calculated by the following formula:</p>
|
||||
<p>
|
||||
( Existing Customers Churn [${thisMonthChurn?.existingCustomersChurn}] + New Customers Churn [
|
||||
${thisMonthChurn?.newCustomersChurn}] ) * 100 / Average Customers Count This Month [
|
||||
${thisMonthChurn?.averageCustomersCount}]
|
||||
</p>
|
||||
<img src=${chartUrls.churn}></img>
|
||||
<p>
|
||||
<strong>Here is quarterly performance chart:</strong>
|
||||
</p>
|
||||
<img src=${chartUrls.quarterlyPerformance}></img>
|
||||
<p>Thanks,SN</p>
|
||||
</div>`
|
||||
}
|
||||
@@ -18,5 +18,5 @@ export class AnalyticsEntity {
|
||||
nullable: true,
|
||||
})
|
||||
@Index('email')
|
||||
declare userEmail: string
|
||||
declare username: string
|
||||
}
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
|
||||
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
||||
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
||||
import { Period } from '../Time/Period'
|
||||
|
||||
import { DomainEventFactory } from './DomainEventFactory'
|
||||
|
||||
describe('DomainEventFactory', () => {
|
||||
let timer: TimerInterface
|
||||
|
||||
const createFactory = () => new DomainEventFactory(timer)
|
||||
|
||||
beforeEach(() => {
|
||||
timer = {} as jest.Mocked<TimerInterface>
|
||||
timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(1)
|
||||
timer.getUTCDate = jest.fn().mockReturnValue(new Date(1))
|
||||
})
|
||||
|
||||
it('should create a DAILY_ANALYTICS_REPORT_GENERATED event', () => {
|
||||
expect(
|
||||
createFactory().createDailyAnalyticsReportGeneratedEvent({
|
||||
activityStatistics: [
|
||||
{
|
||||
name: AnalyticsActivity.Register,
|
||||
retention: 24,
|
||||
totalCount: 45,
|
||||
},
|
||||
],
|
||||
statisticMeasures: [
|
||||
{
|
||||
name: StatisticsMeasure.Income,
|
||||
totalValue: 43,
|
||||
average: 23,
|
||||
increments: 5,
|
||||
period: Period.Today,
|
||||
},
|
||||
],
|
||||
activityStatisticsOverTime: [
|
||||
{
|
||||
name: AnalyticsActivity.Register,
|
||||
period: Period.Last30Days,
|
||||
counts: [
|
||||
{
|
||||
periodKey: '2022-10-9',
|
||||
totalCount: 3,
|
||||
},
|
||||
],
|
||||
totalCount: 123,
|
||||
},
|
||||
],
|
||||
statisticsOverTime: [
|
||||
{
|
||||
name: StatisticsMeasure.MRR,
|
||||
period: Period.Last30Days,
|
||||
counts: [
|
||||
{
|
||||
periodKey: '2022-10-9',
|
||||
totalCount: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
churn: {
|
||||
periodKeys: ['2022-10-9'],
|
||||
values: [
|
||||
{
|
||||
rate: 12,
|
||||
periodKey: '2022-10-9',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
).toEqual({
|
||||
createdAt: expect.any(Date),
|
||||
meta: {
|
||||
correlation: {
|
||||
userIdentifier: '',
|
||||
userIdentifierType: 'uuid',
|
||||
},
|
||||
origin: 'analytics',
|
||||
},
|
||||
payload: {
|
||||
activityStatistics: [
|
||||
{
|
||||
name: 'register',
|
||||
retention: 24,
|
||||
totalCount: 45,
|
||||
},
|
||||
],
|
||||
activityStatisticsOverTime: [
|
||||
{
|
||||
counts: [
|
||||
{
|
||||
periodKey: '2022-10-9',
|
||||
totalCount: 3,
|
||||
},
|
||||
],
|
||||
name: 'register',
|
||||
period: 9,
|
||||
totalCount: 123,
|
||||
},
|
||||
],
|
||||
statisticsOverTime: [
|
||||
{
|
||||
counts: [
|
||||
{
|
||||
periodKey: '2022-10-9',
|
||||
totalCount: 3,
|
||||
},
|
||||
],
|
||||
name: 'mrr',
|
||||
period: 9,
|
||||
},
|
||||
],
|
||||
churn: {
|
||||
periodKeys: ['2022-10-9'],
|
||||
values: [
|
||||
{
|
||||
periodKey: '2022-10-9',
|
||||
rate: 12,
|
||||
},
|
||||
],
|
||||
},
|
||||
statisticMeasures: [
|
||||
{
|
||||
average: 23,
|
||||
increments: 5,
|
||||
name: 'income',
|
||||
period: 0,
|
||||
totalValue: 43,
|
||||
},
|
||||
],
|
||||
},
|
||||
type: 'DAILY_ANALYTICS_REPORT_GENERATED',
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,4 +1,6 @@
|
||||
import { DomainEventService, DailyAnalyticsReportGeneratedEvent } from '@standardnotes/domain-events'
|
||||
/* istanbul ignore file */
|
||||
|
||||
import { DomainEventService, EmailRequestedEvent } from '@standardnotes/domain-events'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
@@ -7,52 +9,20 @@ import { DomainEventFactoryInterface } from './DomainEventFactoryInterface'
|
||||
@injectable()
|
||||
export class DomainEventFactory implements DomainEventFactoryInterface {
|
||||
constructor(@inject(TYPES.Timer) private timer: TimerInterface) {}
|
||||
|
||||
createDailyAnalyticsReportGeneratedEvent(dto: {
|
||||
activityStatistics: Array<{
|
||||
name: string
|
||||
retention: number
|
||||
totalCount: number
|
||||
}>
|
||||
statisticMeasures: Array<{
|
||||
name: string
|
||||
totalValue: number
|
||||
average: number
|
||||
increments: number
|
||||
period: number
|
||||
}>
|
||||
activityStatisticsOverTime: Array<{
|
||||
name: string
|
||||
period: number
|
||||
counts: Array<{
|
||||
periodKey: string
|
||||
totalCount: number
|
||||
}>
|
||||
totalCount: number
|
||||
}>
|
||||
statisticsOverTime: Array<{
|
||||
name: string
|
||||
period: number
|
||||
counts: Array<{
|
||||
periodKey: string
|
||||
totalCount: number
|
||||
}>
|
||||
}>
|
||||
churn: {
|
||||
periodKeys: Array<string>
|
||||
values: Array<{
|
||||
rate: number
|
||||
periodKey: string
|
||||
}>
|
||||
}
|
||||
}): DailyAnalyticsReportGeneratedEvent {
|
||||
createEmailRequestedEvent(dto: {
|
||||
userEmail: string
|
||||
messageIdentifier: string
|
||||
level: string
|
||||
body: string
|
||||
subject: string
|
||||
}): EmailRequestedEvent {
|
||||
return {
|
||||
type: 'DAILY_ANALYTICS_REPORT_GENERATED',
|
||||
type: 'EMAIL_REQUESTED',
|
||||
createdAt: this.timer.getUTCDate(),
|
||||
meta: {
|
||||
correlation: {
|
||||
userIdentifier: '',
|
||||
userIdentifierType: 'uuid',
|
||||
userIdentifier: dto.userEmail,
|
||||
userIdentifierType: 'email',
|
||||
},
|
||||
origin: DomainEventService.Analytics,
|
||||
},
|
||||
|
||||
@@ -1,42 +1,11 @@
|
||||
import { DailyAnalyticsReportGeneratedEvent } from '@standardnotes/domain-events'
|
||||
import { EmailRequestedEvent } from '@standardnotes/domain-events'
|
||||
|
||||
export interface DomainEventFactoryInterface {
|
||||
createDailyAnalyticsReportGeneratedEvent(dto: {
|
||||
activityStatistics: Array<{
|
||||
name: string
|
||||
retention: number
|
||||
totalCount: number
|
||||
}>
|
||||
statisticMeasures: Array<{
|
||||
name: string
|
||||
totalValue: number
|
||||
average: number
|
||||
increments: number
|
||||
period: number
|
||||
}>
|
||||
activityStatisticsOverTime: Array<{
|
||||
name: string
|
||||
period: number
|
||||
counts: Array<{
|
||||
periodKey: string
|
||||
totalCount: number
|
||||
}>
|
||||
totalCount: number
|
||||
}>
|
||||
statisticsOverTime: Array<{
|
||||
name: string
|
||||
period: number
|
||||
counts: Array<{
|
||||
periodKey: string
|
||||
totalCount: number
|
||||
}>
|
||||
}>
|
||||
churn: {
|
||||
periodKeys: Array<string>
|
||||
values: Array<{
|
||||
rate: number
|
||||
periodKey: string
|
||||
}>
|
||||
}
|
||||
}): DailyAnalyticsReportGeneratedEvent
|
||||
createEmailRequestedEvent(dto: {
|
||||
userEmail: string
|
||||
messageIdentifier: string
|
||||
level: string
|
||||
body: string
|
||||
subject: string
|
||||
}): EmailRequestedEvent
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { AccountDeletionRequestedEvent } from '@standardnotes/domain-events'
|
||||
import { AccountDeletionRequestedEventHandler } from './AccountDeletionRequestedEventHandler'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { Period } from '../Time/Period'
|
||||
import { AnalyticsEntityRepositoryInterface } from '../Entity/AnalyticsEntityRepositoryInterface'
|
||||
|
||||
describe('AccountDeletionRequestedEventHandler', () => {
|
||||
let event: AccountDeletionRequestedEvent
|
||||
let analyticsEntityRepository: AnalyticsEntityRepositoryInterface
|
||||
let analyticsStore: AnalyticsStoreInterface
|
||||
let statisticsStore: StatisticsStoreInterface
|
||||
let timer: TimerInterface
|
||||
|
||||
const createHandler = () =>
|
||||
new AccountDeletionRequestedEventHandler(analyticsEntityRepository, analyticsStore, statisticsStore, timer)
|
||||
|
||||
beforeEach(() => {
|
||||
event = {} as jest.Mocked<AccountDeletionRequestedEvent>
|
||||
event.createdAt = new Date(1)
|
||||
event.payload = {
|
||||
userUuid: '1-2-3',
|
||||
userCreatedAtTimestamp: 1,
|
||||
regularSubscriptionUuid: '2-3-4',
|
||||
}
|
||||
|
||||
analyticsEntityRepository = {} as jest.Mocked<AnalyticsEntityRepositoryInterface>
|
||||
analyticsEntityRepository.findOneByUserUuid = jest.fn().mockReturnValue({ id: 3 })
|
||||
analyticsEntityRepository.remove = jest.fn()
|
||||
|
||||
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
|
||||
analyticsStore.markActivity = jest.fn()
|
||||
|
||||
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
|
||||
statisticsStore.incrementMeasure = jest.fn()
|
||||
|
||||
timer = {} as jest.Mocked<TimerInterface>
|
||||
timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(123)
|
||||
})
|
||||
|
||||
it('should mark account deletion and registration length', async () => {
|
||||
await createHandler().handle(event)
|
||||
|
||||
expect(analyticsStore.markActivity).toHaveBeenCalledWith(['DeleteAccount'], 3, [
|
||||
Period.Today,
|
||||
Period.ThisWeek,
|
||||
Period.ThisMonth,
|
||||
])
|
||||
expect(statisticsStore.incrementMeasure).toHaveBeenCalledWith('registration-length', 122, [
|
||||
Period.Today,
|
||||
Period.ThisWeek,
|
||||
Period.ThisMonth,
|
||||
])
|
||||
expect(analyticsEntityRepository.remove).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not mark anything if entity is not found', async () => {
|
||||
analyticsEntityRepository.findOneByUserUuid = jest.fn().mockReturnValue(null)
|
||||
|
||||
await createHandler().handle(event)
|
||||
|
||||
expect(analyticsStore.markActivity).not.toHaveBeenCalled()
|
||||
expect(statisticsStore.incrementMeasure).not.toHaveBeenCalled()
|
||||
expect(analyticsEntityRepository.remove).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
import { AccountDeletionRequestedEvent, DomainEventHandlerInterface } from '@standardnotes/domain-events'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { inject, injectable, optional } from 'inversify'
|
||||
import { Mixpanel } from 'mixpanel'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
import { AnalyticsEntityRepositoryInterface } from '../Entity/AnalyticsEntityRepositoryInterface'
|
||||
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
||||
import { StatisticMeasureName } from '../Statistics/StatisticMeasureName'
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { Period } from '../Time/Period'
|
||||
|
||||
@@ -17,6 +18,7 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI
|
||||
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
|
||||
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
|
||||
@inject(TYPES.Timer) private timer: TimerInterface,
|
||||
@inject(TYPES.MixpanelClient) @optional() private mixpanelClient: Mixpanel | null,
|
||||
) {}
|
||||
|
||||
async handle(event: AccountDeletionRequestedEvent): Promise<void> {
|
||||
@@ -33,12 +35,19 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI
|
||||
])
|
||||
|
||||
const registrationLength = this.timer.getTimestampInMicroseconds() - event.payload.userCreatedAtTimestamp
|
||||
await this.statisticsStore.incrementMeasure(StatisticsMeasure.RegistrationLength, registrationLength, [
|
||||
await this.statisticsStore.incrementMeasure(StatisticMeasureName.NAMES.RegistrationLength, registrationLength, [
|
||||
Period.Today,
|
||||
Period.ThisWeek,
|
||||
Period.ThisMonth,
|
||||
])
|
||||
|
||||
await this.analyticsEntityRepository.remove(analyticsEntity)
|
||||
|
||||
if (this.mixpanelClient !== null) {
|
||||
this.mixpanelClient.track(event.type, {
|
||||
distinct_id: analyticsEntity.id.toString(),
|
||||
user_created_at: this.timer.convertMicrosecondsToDate(event.payload.userCreatedAtTimestamp),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { PaymentFailedEvent } from '@standardnotes/domain-events'
|
||||
|
||||
import { PaymentFailedEventHandler } from './PaymentFailedEventHandler'
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
|
||||
describe('PaymentFailedEventHandler', () => {
|
||||
let event: PaymentFailedEvent
|
||||
let getUserAnalyticsId: GetUserAnalyticsId
|
||||
let analyticsStore: AnalyticsStoreInterface
|
||||
|
||||
const createHandler = () => new PaymentFailedEventHandler(getUserAnalyticsId, analyticsStore)
|
||||
|
||||
beforeEach(() => {
|
||||
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
|
||||
getUserAnalyticsId.execute = jest.fn().mockReturnValue({ analyticsId: 3 })
|
||||
|
||||
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
|
||||
analyticsStore.markActivity = jest.fn()
|
||||
|
||||
event = {} as jest.Mocked<PaymentFailedEvent>
|
||||
event.payload = {
|
||||
userEmail: 'test@test.com',
|
||||
}
|
||||
})
|
||||
|
||||
it('should mark payment failed for analytics', async () => {
|
||||
await createHandler().handle(event)
|
||||
|
||||
expect(analyticsStore.markActivity).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
@@ -1,5 +1,6 @@
|
||||
import { DomainEventHandlerInterface, PaymentFailedEvent } from '@standardnotes/domain-events'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { inject, injectable, optional } from 'inversify'
|
||||
import { Mixpanel } from 'mixpanel'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
||||
@@ -12,6 +13,7 @@ export class PaymentFailedEventHandler implements DomainEventHandlerInterface {
|
||||
constructor(
|
||||
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
|
||||
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
|
||||
@inject(TYPES.MixpanelClient) @optional() private mixpanelClient: Mixpanel | null,
|
||||
) {}
|
||||
|
||||
async handle(event: PaymentFailedEvent): Promise<void> {
|
||||
@@ -21,5 +23,11 @@ export class PaymentFailedEventHandler implements DomainEventHandlerInterface {
|
||||
Period.ThisWeek,
|
||||
Period.ThisMonth,
|
||||
])
|
||||
|
||||
if (this.mixpanelClient !== null) {
|
||||
this.mixpanelClient.track(event.type, {
|
||||
distinct_id: analyticsId.toString(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { PaymentSuccessEvent } from '@standardnotes/domain-events'
|
||||
|
||||
import { PaymentSuccessEventHandler } from './PaymentSuccessEventHandler'
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
import { Logger } from 'winston'
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
import { Period } from '../Time/Period'
|
||||
|
||||
describe('PaymentSuccessEventHandler', () => {
|
||||
let event: PaymentSuccessEvent
|
||||
let getUserAnalyticsId: GetUserAnalyticsId
|
||||
let analyticsStore: AnalyticsStoreInterface
|
||||
let statisticsStore: StatisticsStoreInterface
|
||||
let logger: Logger
|
||||
|
||||
const createHandler = () =>
|
||||
new PaymentSuccessEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore, logger)
|
||||
|
||||
beforeEach(() => {
|
||||
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
|
||||
getUserAnalyticsId.execute = jest.fn().mockReturnValue({ analyticsId: 3 })
|
||||
|
||||
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
|
||||
analyticsStore.markActivity = jest.fn()
|
||||
|
||||
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
|
||||
statisticsStore.incrementMeasure = jest.fn()
|
||||
|
||||
event = {} as jest.Mocked<PaymentSuccessEvent>
|
||||
event.payload = {
|
||||
userEmail: 'test@test.com',
|
||||
amount: 12.45,
|
||||
billingFrequency: 12,
|
||||
paymentType: 'initial',
|
||||
subscriptionName: 'PRO_PLAN',
|
||||
}
|
||||
|
||||
logger = {} as jest.Mocked<Logger>
|
||||
logger.warn = jest.fn()
|
||||
})
|
||||
|
||||
it('should mark payment success for analytics', async () => {
|
||||
await createHandler().handle(event)
|
||||
|
||||
expect(analyticsStore.markActivity).toHaveBeenCalled()
|
||||
expect(statisticsStore.incrementMeasure).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
'pro-subscription-initial-annual-payments-income',
|
||||
12.45,
|
||||
[Period.Today, Period.ThisWeek, Period.ThisMonth],
|
||||
)
|
||||
})
|
||||
|
||||
it('should mark non-detailed payment success statistics for analytics', async () => {
|
||||
event.payload = {
|
||||
userEmail: 'test@test.com',
|
||||
amount: 12.45,
|
||||
billingFrequency: 13,
|
||||
paymentType: 'initial',
|
||||
subscriptionName: 'PRO_PLAN',
|
||||
}
|
||||
|
||||
await createHandler().handle(event)
|
||||
|
||||
expect(statisticsStore.incrementMeasure).toBeCalledTimes(1)
|
||||
expect(statisticsStore.incrementMeasure).toHaveBeenNthCalledWith(1, 'income', 12.45, [
|
||||
Period.Today,
|
||||
Period.ThisWeek,
|
||||
Period.ThisMonth,
|
||||
])
|
||||
})
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
import { PaymentType, SubscriptionBillingFrequency, SubscriptionName } from '@standardnotes/common'
|
||||
import { DomainEventHandlerInterface, PaymentSuccessEvent } from '@standardnotes/domain-events'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { inject, injectable, optional } from 'inversify'
|
||||
import { Mixpanel } from 'mixpanel'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
||||
import { StatisticMeasureName } from '../Statistics/StatisticMeasureName'
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { Period } from '../Time/Period'
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
@@ -20,15 +21,27 @@ export class PaymentSuccessEventHandler implements DomainEventHandlerInterface {
|
||||
[
|
||||
PaymentType.Initial,
|
||||
new Map([
|
||||
[SubscriptionBillingFrequency.Monthly, StatisticsMeasure.PlusSubscriptionInitialMonthlyPaymentsIncome],
|
||||
[SubscriptionBillingFrequency.Annual, StatisticsMeasure.PlusSubscriptionInitialAnnualPaymentsIncome],
|
||||
[
|
||||
SubscriptionBillingFrequency.Monthly,
|
||||
StatisticMeasureName.NAMES.PlusSubscriptionInitialMonthlyPaymentsIncome,
|
||||
],
|
||||
[
|
||||
SubscriptionBillingFrequency.Annual,
|
||||
StatisticMeasureName.NAMES.PlusSubscriptionInitialAnnualPaymentsIncome,
|
||||
],
|
||||
]),
|
||||
],
|
||||
[
|
||||
PaymentType.Renewal,
|
||||
new Map([
|
||||
[SubscriptionBillingFrequency.Monthly, StatisticsMeasure.PlusSubscriptionRenewingMonthlyPaymentsIncome],
|
||||
[SubscriptionBillingFrequency.Annual, StatisticsMeasure.PlusSubscriptionRenewingAnnualPaymentsIncome],
|
||||
[
|
||||
SubscriptionBillingFrequency.Monthly,
|
||||
StatisticMeasureName.NAMES.PlusSubscriptionRenewingMonthlyPaymentsIncome,
|
||||
],
|
||||
[
|
||||
SubscriptionBillingFrequency.Annual,
|
||||
StatisticMeasureName.NAMES.PlusSubscriptionRenewingAnnualPaymentsIncome,
|
||||
],
|
||||
]),
|
||||
],
|
||||
]),
|
||||
@@ -39,15 +52,27 @@ export class PaymentSuccessEventHandler implements DomainEventHandlerInterface {
|
||||
[
|
||||
PaymentType.Initial,
|
||||
new Map([
|
||||
[SubscriptionBillingFrequency.Monthly, StatisticsMeasure.ProSubscriptionInitialMonthlyPaymentsIncome],
|
||||
[SubscriptionBillingFrequency.Annual, StatisticsMeasure.ProSubscriptionInitialAnnualPaymentsIncome],
|
||||
[
|
||||
SubscriptionBillingFrequency.Monthly,
|
||||
StatisticMeasureName.NAMES.ProSubscriptionInitialMonthlyPaymentsIncome,
|
||||
],
|
||||
[
|
||||
SubscriptionBillingFrequency.Annual,
|
||||
StatisticMeasureName.NAMES.ProSubscriptionInitialAnnualPaymentsIncome,
|
||||
],
|
||||
]),
|
||||
],
|
||||
[
|
||||
PaymentType.Renewal,
|
||||
new Map([
|
||||
[SubscriptionBillingFrequency.Monthly, StatisticsMeasure.ProSubscriptionRenewingMonthlyPaymentsIncome],
|
||||
[SubscriptionBillingFrequency.Annual, StatisticsMeasure.ProSubscriptionRenewingAnnualPaymentsIncome],
|
||||
[
|
||||
SubscriptionBillingFrequency.Monthly,
|
||||
StatisticMeasureName.NAMES.ProSubscriptionRenewingMonthlyPaymentsIncome,
|
||||
],
|
||||
[
|
||||
SubscriptionBillingFrequency.Annual,
|
||||
StatisticMeasureName.NAMES.ProSubscriptionRenewingAnnualPaymentsIncome,
|
||||
],
|
||||
]),
|
||||
],
|
||||
]),
|
||||
@@ -59,6 +84,7 @@ export class PaymentSuccessEventHandler implements DomainEventHandlerInterface {
|
||||
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
|
||||
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
|
||||
@inject(TYPES.Logger) private logger: Logger,
|
||||
@inject(TYPES.MixpanelClient) @optional() private mixpanelClient: Mixpanel | null,
|
||||
) {}
|
||||
|
||||
async handle(event: PaymentSuccessEvent): Promise<void> {
|
||||
@@ -69,7 +95,7 @@ export class PaymentSuccessEventHandler implements DomainEventHandlerInterface {
|
||||
Period.ThisMonth,
|
||||
])
|
||||
|
||||
const statisticMeasures = [StatisticsMeasure.Income]
|
||||
const statisticMeasures = [StatisticMeasureName.NAMES.Income]
|
||||
|
||||
const detailedMeasure = this.DETAILED_MEASURES.get(event.payload.subscriptionName as SubscriptionName)
|
||||
?.get(event.payload.paymentType as PaymentType)
|
||||
@@ -89,5 +115,19 @@ export class PaymentSuccessEventHandler implements DomainEventHandlerInterface {
|
||||
Period.ThisMonth,
|
||||
])
|
||||
}
|
||||
|
||||
if (this.mixpanelClient !== null) {
|
||||
this.mixpanelClient.track(event.type, {
|
||||
distinct_id: analyticsId.toString(),
|
||||
amount: event.payload.amount,
|
||||
billing_frequency: event.payload.billingFrequency,
|
||||
payment_type: event.payload.paymentType,
|
||||
subscription_name: event.payload.subscriptionName,
|
||||
})
|
||||
|
||||
this.mixpanelClient.people.track_charge(analyticsId.toString(), event.payload.amount)
|
||||
|
||||
this.mixpanelClient.people.set(analyticsId.toString(), 'subscription', event.payload.subscriptionName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { RefundProcessedEvent } from '@standardnotes/domain-events'
|
||||
|
||||
import { RefundProcessedEventHandler } from './RefundProcessedEventHandler'
|
||||
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { Period } from '../Time/Period'
|
||||
|
||||
describe('RefundProcessedEventHandler', () => {
|
||||
let event: RefundProcessedEvent
|
||||
let statisticsStore: StatisticsStoreInterface
|
||||
|
||||
const createHandler = () => new RefundProcessedEventHandler(statisticsStore)
|
||||
|
||||
beforeEach(() => {
|
||||
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
|
||||
statisticsStore.incrementMeasure = jest.fn()
|
||||
|
||||
event = {} as jest.Mocked<RefundProcessedEvent>
|
||||
event.payload = {
|
||||
userEmail: 'test@test.com',
|
||||
amount: 12.45,
|
||||
}
|
||||
})
|
||||
|
||||
it('should mark refunds for statistics', async () => {
|
||||
await createHandler().handle(event)
|
||||
|
||||
expect(statisticsStore.incrementMeasure).toHaveBeenCalledWith(StatisticsMeasure.Refunds, 12.45, [
|
||||
Period.Today,
|
||||
Period.ThisWeek,
|
||||
Period.ThisMonth,
|
||||
])
|
||||
})
|
||||
})
|
||||
@@ -1,20 +1,36 @@
|
||||
import { DomainEventHandlerInterface, RefundProcessedEvent } from '@standardnotes/domain-events'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { inject, injectable, optional } from 'inversify'
|
||||
import { Mixpanel } from 'mixpanel'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
||||
import { StatisticMeasureName } from '../Statistics/StatisticMeasureName'
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { Period } from '../Time/Period'
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
|
||||
@injectable()
|
||||
export class RefundProcessedEventHandler implements DomainEventHandlerInterface {
|
||||
constructor(@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface) {}
|
||||
constructor(
|
||||
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
|
||||
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
|
||||
@inject(TYPES.MixpanelClient) @optional() private mixpanelClient: Mixpanel | null,
|
||||
) {}
|
||||
|
||||
async handle(event: RefundProcessedEvent): Promise<void> {
|
||||
await this.statisticsStore.incrementMeasure(StatisticsMeasure.Refunds, event.payload.amount, [
|
||||
const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
|
||||
|
||||
await this.statisticsStore.incrementMeasure(StatisticMeasureName.NAMES.Refunds, event.payload.amount, [
|
||||
Period.Today,
|
||||
Period.ThisWeek,
|
||||
Period.ThisMonth,
|
||||
])
|
||||
|
||||
if (this.mixpanelClient !== null) {
|
||||
this.mixpanelClient.track(event.type, {
|
||||
distinct_id: analyticsId.toString(),
|
||||
amount: event.payload.amount,
|
||||
})
|
||||
this.mixpanelClient.people.track_charge(analyticsId.toString(), -event.payload.amount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import { DomainEventHandlerInterface, StatisticPersistenceRequestedEvent } from '@standardnotes/domain-events'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { Logger } from 'winston'
|
||||
import { PersistStatistic } from '../UseCase/PersistStatistic/PersistStatistic'
|
||||
import { Mixpanel } from 'mixpanel'
|
||||
|
||||
export class StatisticPersistenceRequestedEventHandler implements DomainEventHandlerInterface {
|
||||
constructor(
|
||||
private persistStatistic: PersistStatistic,
|
||||
private timer: TimerInterface,
|
||||
private logger: Logger,
|
||||
private mixpanelClient: Mixpanel | null,
|
||||
) {}
|
||||
|
||||
async handle(event: StatisticPersistenceRequestedEvent): Promise<void> {
|
||||
const result = await this.persistStatistic.execute({
|
||||
date: this.timer.convertMicrosecondsToDate(event.payload.date),
|
||||
statisticMeasureName: event.payload.statisticMeasureName,
|
||||
value: event.payload.value,
|
||||
})
|
||||
|
||||
if (result.isFailed()) {
|
||||
this.logger.error(result.getError())
|
||||
}
|
||||
|
||||
if (this.mixpanelClient !== null) {
|
||||
this.mixpanelClient.track(event.type, {
|
||||
distinct_id: 'global-stats',
|
||||
statistic: event.payload.statisticMeasureName,
|
||||
value: event.payload.value,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
import 'reflect-metadata'
|
||||
|
||||
import { SubscriptionName } from '@standardnotes/common'
|
||||
import { SubscriptionCancelledEvent } from '@standardnotes/domain-events'
|
||||
|
||||
import { SubscriptionCancelledEventHandler } from './SubscriptionCancelledEventHandler'
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { Period } from '../Time/Period'
|
||||
import { Result } from '../Core/Result'
|
||||
import { RevenueModification } from '../Revenue/RevenueModification'
|
||||
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
describe('SubscriptionCancelledEventHandler', () => {
|
||||
let event: SubscriptionCancelledEvent
|
||||
let getUserAnalyticsId: GetUserAnalyticsId
|
||||
let analyticsStore: AnalyticsStoreInterface
|
||||
let statisticsStore: StatisticsStoreInterface
|
||||
let saveRevenueModification: SaveRevenueModification
|
||||
let logger: Logger
|
||||
|
||||
const createHandler = () =>
|
||||
new SubscriptionCancelledEventHandler(
|
||||
getUserAnalyticsId,
|
||||
analyticsStore,
|
||||
statisticsStore,
|
||||
saveRevenueModification,
|
||||
logger,
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
logger = {} as jest.Mocked<Logger>
|
||||
logger.error = jest.fn()
|
||||
|
||||
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
|
||||
getUserAnalyticsId.execute = jest.fn().mockReturnValue({ analyticsId: 3 })
|
||||
|
||||
analyticsStore = {} as jest.Mocked<AnalyticsStoreInterface>
|
||||
analyticsStore.markActivity = jest.fn()
|
||||
|
||||
statisticsStore = {} as jest.Mocked<StatisticsStoreInterface>
|
||||
statisticsStore.incrementMeasure = jest.fn()
|
||||
|
||||
event = {} as jest.Mocked<SubscriptionCancelledEvent>
|
||||
event.createdAt = new Date(1)
|
||||
event.type = 'SUBSCRIPTION_CANCELLED'
|
||||
event.payload = {
|
||||
subscriptionId: 1,
|
||||
userEmail: 'test@test.com',
|
||||
subscriptionName: SubscriptionName.ProPlan,
|
||||
subscriptionCreatedAt: 1642395451515000,
|
||||
subscriptionUpdatedAt: 1642395451515001,
|
||||
lastPayedAt: 1642395451515001,
|
||||
subscriptionEndsAt: 1642395451515000 + 10,
|
||||
timestamp: 1,
|
||||
offline: false,
|
||||
replaced: false,
|
||||
userExistingSubscriptionsCount: 1,
|
||||
billingFrequency: 1,
|
||||
payAmount: 12.99,
|
||||
}
|
||||
|
||||
saveRevenueModification = {} as jest.Mocked<SaveRevenueModification>
|
||||
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.ok<RevenueModification>())
|
||||
})
|
||||
|
||||
it('should track subscription cancelled statistics', async () => {
|
||||
event.payload.timestamp = 1642395451516000
|
||||
|
||||
await createHandler().handle(event)
|
||||
|
||||
expect(analyticsStore.markActivity).toHaveBeenCalled()
|
||||
expect(statisticsStore.incrementMeasure).toHaveBeenCalledWith(StatisticsMeasure.SubscriptionLength, 1000, [
|
||||
Period.Today,
|
||||
Period.ThisWeek,
|
||||
Period.ThisMonth,
|
||||
])
|
||||
expect(saveRevenueModification.execute).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should not track statistics for subscriptions that are in a legacy 5 year plan', async () => {
|
||||
event.payload.timestamp = 1642395451516000
|
||||
event.payload.subscriptionEndsAt = 1642395451515000 + 126_230_400_000_001
|
||||
event.payload.subscriptionCreatedAt = 1642395451515000
|
||||
|
||||
await createHandler().handle(event)
|
||||
|
||||
expect(statisticsStore.incrementMeasure).not.toHaveBeenCalled()
|
||||
expect(saveRevenueModification.execute).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should log failure to save revenue modification', async () => {
|
||||
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.fail('Oops'))
|
||||
|
||||
event.payload.timestamp = 1642395451516000
|
||||
|
||||
await createHandler().handle(event)
|
||||
|
||||
expect(logger.error).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
@@ -1,18 +1,20 @@
|
||||
import { DomainEventHandlerInterface, SubscriptionCancelledEvent } from '@standardnotes/domain-events'
|
||||
import { inject, injectable } from 'inversify'
|
||||
import { inject, injectable, optional } from 'inversify'
|
||||
import { Logger } from 'winston'
|
||||
import { Username } from '@standardnotes/domain-core'
|
||||
import { Mixpanel } from 'mixpanel'
|
||||
|
||||
import TYPES from '../../Bootstrap/Types'
|
||||
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||
import { Email } from '../Common/Email'
|
||||
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
|
||||
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
|
||||
import { Period } from '../Time/Period'
|
||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
|
||||
import { StatisticMeasureName } from '../Statistics/StatisticMeasureName'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
|
||||
@injectable()
|
||||
export class SubscriptionCancelledEventHandler implements DomainEventHandlerInterface {
|
||||
@@ -22,6 +24,8 @@ export class SubscriptionCancelledEventHandler implements DomainEventHandlerInte
|
||||
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
|
||||
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
|
||||
@inject(TYPES.Logger) private logger: Logger,
|
||||
@inject(TYPES.MixpanelClient) @optional() private mixpanelClient: Mixpanel | null,
|
||||
@inject(TYPES.Timer) private timer: TimerInterface,
|
||||
) {}
|
||||
|
||||
async handle(event: SubscriptionCancelledEvent): Promise<void> {
|
||||
@@ -41,12 +45,30 @@ export class SubscriptionCancelledEventHandler implements DomainEventHandlerInte
|
||||
payedAmount: event.payload.payAmount,
|
||||
planName: SubscriptionPlanName.create(event.payload.subscriptionName).getValue(),
|
||||
subscriptionId: event.payload.subscriptionId,
|
||||
userEmail: Email.create(event.payload.userEmail).getValue(),
|
||||
username: Username.create(event.payload.userEmail).getValue(),
|
||||
userUuid,
|
||||
})
|
||||
|
||||
if (result.isFailed()) {
|
||||
this.logger.error(`[${event.type}] Could not save revenue modification: ${result.getError()}`)
|
||||
this.logger.error(
|
||||
`[${event.type}][${event.payload.subscriptionId}] Could not save revenue modification: ${result.getError()}`,
|
||||
)
|
||||
}
|
||||
|
||||
if (this.mixpanelClient !== null) {
|
||||
this.mixpanelClient.track(event.type, {
|
||||
distinct_id: analyticsId.toString(),
|
||||
subscription_name: event.payload.subscriptionName,
|
||||
subscription_created_at: this.timer.convertMicrosecondsToDate(event.payload.subscriptionCreatedAt),
|
||||
subscription_updated_at: this.timer.convertMicrosecondsToDate(event.payload.subscriptionUpdatedAt),
|
||||
last_payed_at: this.timer.convertMicrosecondsToDate(event.payload.lastPayedAt),
|
||||
subscription_ends_at: this.timer.convertMicrosecondsToDate(event.payload.subscriptionEndsAt),
|
||||
offline: event.payload.offline,
|
||||
replaced: event.payload.replaced,
|
||||
user_existing_subscriptions_count: event.payload.userExistingSubscriptionsCount,
|
||||
billing_frequency: event.payload.billingFrequency,
|
||||
pay_amount: event.payload.payAmount,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +78,7 @@ export class SubscriptionCancelledEventHandler implements DomainEventHandlerInte
|
||||
}
|
||||
|
||||
const subscriptionLength = event.payload.timestamp - event.payload.subscriptionCreatedAt
|
||||
await this.statisticsStore.incrementMeasure(StatisticsMeasure.SubscriptionLength, subscriptionLength, [
|
||||
await this.statisticsStore.incrementMeasure(StatisticMeasureName.NAMES.SubscriptionLength, subscriptionLength, [
|
||||
Period.Today,
|
||||
Period.ThisWeek,
|
||||
Period.ThisMonth,
|
||||
@@ -68,7 +90,7 @@ export class SubscriptionCancelledEventHandler implements DomainEventHandlerInte
|
||||
const remainingSubscriptionPercentage = Math.floor((remainingSubscriptionTime / totalSubscriptionTime) * 100)
|
||||
|
||||
await this.statisticsStore.incrementMeasure(
|
||||
StatisticsMeasure.RemainingSubscriptionTimePercentage,
|
||||
StatisticMeasureName.NAMES.RemainingSubscriptionTimePercentage,
|
||||
remainingSubscriptionPercentage,
|
||||
[Period.Today, Period.ThisWeek, Period.ThisMonth],
|
||||
)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user