Compare commits

...

16 Commits

Author SHA1 Message Date
standardci
2e82be47ed chore(release): publish new version
- @standardnotes/analytics@2.10.2
2022-11-14 13:01:32 +00:00
Karol Sójko
15dfd6dcba fix(analytics): imports from domain-core 2022-11-14 13:59:06 +01:00
standardci
dfd38943b0 chore(release): publish new version
- @standardnotes/syncing-server@1.13.11
2022-11-14 12:51:16 +00:00
Karol Sójko
500756d582 fix(syncing-server): decrease logs severity for content recalculation 2022-11-14 13:49:28 +01:00
standardci
f855f541d8 chore(release): publish new version
- @standardnotes/auth-server@1.60.0
2022-11-14 12:48:49 +00:00
Karol Sójko
590ec6643d feat(auth): add content size recalculation procedure trigger 2022-11-14 13:46:40 +01:00
standardci
b9efd35b50 chore(release): publish new version
- @standardnotes/syncing-server@1.13.10
2022-11-14 12:32:48 +00:00
Karol Sójko
3be1bfe58a fix(syncing-server): linter issues 2022-11-14 13:30:41 +01:00
standardci
bfbd2de778 chore(release): publish new version
- @standardnotes/analytics@2.10.1
 - @standardnotes/domain-core@1.1.1
 - @standardnotes/syncing-server@1.13.9
2022-11-14 12:25:09 +00:00
Karol Sójko
50f7ae338a fix(syncing-server): retrieving revisions 2022-11-14 13:23:12 +01:00
standardci
280fdc89c1 chore(release): publish new version
- @standardnotes/analytics@2.10.0
 - @standardnotes/api-gateway@1.38.5
 - @standardnotes/auth-server@1.59.11
 - @standardnotes/common@1.45.0
 - @standardnotes/domain-core@1.1.0
 - @standardnotes/domain-events-infra@1.9.27
 - @standardnotes/domain-events@2.87.0
 - @standardnotes/event-store@1.6.22
 - @standardnotes/files-server@1.8.22
 - @standardnotes/predicates@1.6.0
 - @standardnotes/scheduler-server@1.13.23
 - @standardnotes/security@1.7.0
 - @standardnotes/sncrypto-node@1.13.0
 - @standardnotes/syncing-server@1.13.8
 - @standardnotes/time@1.14.0
 - @standardnotes/websockets-server@1.4.24
 - @standardnotes/workspace-server@1.17.22
2022-11-14 10:35:04 +00:00
Karol Sójko
0f94e2ad0c feat(analytics): extract domain core into a separate package 2022-11-14 11:32:31 +01:00
standardci
d0036600e9 chore(release): publish new version
- @standardnotes/syncing-server@1.13.7
2022-11-14 10:08:04 +00:00
Karol Sójko
f766fefbf0 fix(syncing-server): content recalculation missing await 2022-11-14 11:06:15 +01:00
standardci
2178ed2a31 chore(release): publish new version
- @standardnotes/syncing-server@1.13.6
2022-11-14 09:42:58 +00:00
Karol Sójko
79511aea5f fix(syncing-server): add missing content size recalculation handler binding 2022-11-14 10:40:51 +01:00
107 changed files with 631 additions and 614 deletions

39
.pnp.cjs generated
View File

@@ -29,6 +29,10 @@ const RAW_RUNTIME_STATE =
"name": "@standardnotes/common",\
"reference": "workspace:packages/common"\
},\
{\
"name": "@standardnotes/domain-core",\
"reference": "workspace:packages/domain-core"\
},\
{\
"name": "@standardnotes/domain-events",\
"reference": "workspace:packages/domain-events"\
@@ -89,6 +93,7 @@ const RAW_RUNTIME_STATE =
["@standardnotes/api-gateway", ["workspace:packages/api-gateway"]],\
["@standardnotes/auth-server", ["workspace:packages/auth"]],\
["@standardnotes/common", ["workspace:packages/common"]],\
["@standardnotes/domain-core", ["workspace:packages/domain-core"]],\
["@standardnotes/domain-events", ["workspace:packages/domain-events"]],\
["@standardnotes/domain-events-infra", ["workspace:packages/domain-events-infra"]],\
["@standardnotes/event-store", ["workspace:packages/event-store"]],\
@@ -2532,6 +2537,7 @@ const RAW_RUNTIME_STATE =
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/time", "workspace:packages/time"],\
@@ -2539,7 +2545,6 @@ const RAW_RUNTIME_STATE =
["@types/jest", "npm:29.1.1"],\
["@types/newrelic", "npm:7.0.4"],\
["@types/node", "npm:18.11.9"],\
["@types/uuid", "npm:8.3.4"],\
["@typescript-eslint/eslint-plugin", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:5.30.5"],\
["aws-sdk", "npm:2.1253.0"],\
["dayjs", "npm:1.11.6"],\
@@ -2552,11 +2557,9 @@ const RAW_RUNTIME_STATE =
["mysql2", "npm:2.3.3"],\
["newrelic", "npm:9.6.0"],\
["reflect-metadata", "npm:0.1.13"],\
["shallow-equal-object", "npm:1.1.1"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typeorm", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:0.3.10"],\
["typescript", "patch:typescript@npm%3A4.8.4#optional!builtin<compat/typescript>::version=4.8.4&hash=701156"],\
["uuid", "npm:9.0.0"],\
["winston", "npm:3.8.2"]\
],\
"linkType": "SOFT"\
@@ -2701,7 +2704,6 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/common/",\
"packageDependencies": [\
["@standardnotes/common", "workspace:packages/common"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/node", "npm:18.11.9"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\
@@ -2728,12 +2730,34 @@ const RAW_RUNTIME_STATE =
"linkType": "HARD"\
}]\
]],\
["@standardnotes/domain-core", [\
["workspace:packages/domain-core", {\
"packageLocation": "./packages/domain-core/",\
"packageDependencies": [\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/features", "npm:1.53.1"],\
["@standardnotes/predicates", "workspace:packages/predicates"],\
["@standardnotes/security", "workspace:packages/security"],\
["@types/jest", "npm:29.1.1"],\
["@types/uuid", "npm:8.3.4"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\
["eslint-plugin-prettier", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:4.2.1"],\
["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.2"],\
["reflect-metadata", "npm:0.1.13"],\
["shallow-equal-object", "npm:1.1.1"],\
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.0.3"],\
["typescript", "patch:typescript@npm%3A4.8.4#optional!builtin<compat/typescript>::version=4.8.4&hash=701156"],\
["uuid", "npm:9.0.0"]\
],\
"linkType": "SOFT"\
}]\
]],\
["@standardnotes/domain-events", [\
["workspace:packages/domain-events", {\
"packageLocation": "./packages/domain-events/",\
"packageDependencies": [\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/features", "npm:1.53.1"],\
["@standardnotes/predicates", "workspace:packages/predicates"],\
@@ -2944,7 +2968,6 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/predicates/",\
"packageDependencies": [\
["@standardnotes/predicates", "workspace:packages/predicates"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@types/jest", "npm:29.1.1"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\
@@ -3024,7 +3047,6 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/security/",\
"packageDependencies": [\
["@standardnotes/security", "workspace:packages/security"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@types/jest", "npm:29.1.1"],\
["@types/jsonwebtoken", "npm:8.5.9"],\
@@ -3096,7 +3118,6 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/sncrypto-node/",\
"packageDependencies": [\
["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@standardnotes/sncrypto-common", "npm:1.13.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/node", "npm:18.11.9"],\
@@ -3121,6 +3142,7 @@ const RAW_RUNTIME_STATE =
["@newrelic/winston-enricher", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.0.0"],\
["@sentry/node", "npm:7.19.0"],\
["@standardnotes/common", "workspace:packages/common"],\
["@standardnotes/domain-core", "workspace:packages/domain-core"],\
["@standardnotes/domain-events", "workspace:packages/domain-events"],\
["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\
["@standardnotes/payloads", "npm:1.5.1"],\
@@ -3174,7 +3196,6 @@ const RAW_RUNTIME_STATE =
"packageLocation": "./packages/time/",\
"packageDependencies": [\
["@standardnotes/time", "workspace:packages/time"],\
["@newrelic/native-metrics", "npm:9.0.0"],\
["@types/jest", "npm:29.1.1"],\
["@types/microtime", "npm:2.1.0"],\
["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:5.30.5"],\

View File

@@ -3,6 +3,24 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.10.2](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.10.1...@standardnotes/analytics@2.10.2) (2022-11-14)
### Bug Fixes
* **analytics:** imports from domain-core ([15dfd6d](https://github.com/standardnotes/server/commit/15dfd6dcba75a772000eeb01b78a532067b01d5b))
## [2.10.1](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.10.0...@standardnotes/analytics@2.10.1) (2022-11-14)
### Bug Fixes
* **syncing-server:** retrieving revisions ([50f7ae3](https://github.com/standardnotes/server/commit/50f7ae338ad66d3465fa16c31e7c47c57b1e0c3c))
# [2.10.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.9...@standardnotes/analytics@2.10.0) (2022-11-14)
### Features
* **analytics:** extract domain core into a separate package ([0f94e2a](https://github.com/standardnotes/server/commit/0f94e2ad0c8927733eac31f130cbe649dce765f9))
## [2.9.9](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.9.6...@standardnotes/analytics@2.9.9) (2022-11-14)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/analytics",
"version": "2.9.9",
"version": "2.10.2",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -29,7 +29,6 @@
"@types/jest": "^29.1.1",
"@types/newrelic": "^7.0.4",
"@types/node": "^18.11.9",
"@types/uuid": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"eslint": "^8.14.0",
"eslint-plugin-prettier": "^4.2.1",
@@ -42,6 +41,7 @@
"@newrelic/winston-enricher": "^4.0.0",
"@sentry/node": "^7.19.0",
"@standardnotes/common": "workspace:*",
"@standardnotes/domain-core": "workspace:*",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/time": "workspace:*",
@@ -53,9 +53,7 @@
"mysql2": "^2.3.3",
"newrelic": "^9.6.0",
"reflect-metadata": "^0.1.13",
"shallow-equal-object": "^1.1.1",
"typeorm": "^0.3.10",
"uuid": "^9.0.0",
"winston": "^3.8.1"
}
}

View File

@@ -7,6 +7,7 @@ import {
DomainEventMessageHandlerInterface,
DomainEventSubscriberFactoryInterface,
} from '@standardnotes/domain-events'
import { MapInterface } from '@standardnotes/domain-core'
import { Env } from './Env'
import TYPES from './Types'
@@ -47,7 +48,6 @@ 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'

View File

@@ -1,6 +1,7 @@
import 'reflect-metadata'
import { SubscriptionName } from '@standardnotes/common'
import { Result } from '@standardnotes/domain-core'
import { SubscriptionCancelledEvent } from '@standardnotes/domain-events'
import { SubscriptionCancelledEventHandler } from './SubscriptionCancelledEventHandler'
@@ -9,7 +10,6 @@ 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'

View File

@@ -1,11 +1,11 @@
import { DomainEventHandlerInterface, SubscriptionCancelledEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { Email } from '../Common/Email'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'

View File

@@ -2,13 +2,13 @@ import 'reflect-metadata'
import { SubscriptionName } from '@standardnotes/common'
import { SubscriptionExpiredEvent } from '@standardnotes/domain-events'
import { Result } from '@standardnotes/domain-core'
import { SubscriptionExpiredEventHandler } from './SubscriptionExpiredEventHandler'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { Result } from '../Core/Result'
import { RevenueModification } from '../Revenue/RevenueModification'
import { Logger } from 'winston'

View File

@@ -1,11 +1,11 @@
import { DomainEventHandlerInterface, SubscriptionExpiredEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { Email } from '../Common/Email'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'

View File

@@ -2,6 +2,7 @@ import 'reflect-metadata'
import { SubscriptionName } from '@standardnotes/common'
import { SubscriptionPurchasedEvent } from '@standardnotes/domain-events'
import { Result } from '@standardnotes/domain-core'
import { SubscriptionPurchasedEventHandler } from './SubscriptionPurchasedEventHandler'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
@@ -9,7 +10,6 @@ import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { Period } from '../Time/Period'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { Result } from '../Core/Result'
import { RevenueModification } from '../Revenue/RevenueModification'
import { Logger } from 'winston'

View File

@@ -1,11 +1,11 @@
import { DomainEventHandlerInterface, SubscriptionPurchasedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { Email } from '../Common/Email'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'

View File

@@ -2,6 +2,7 @@ import 'reflect-metadata'
import { SubscriptionName } from '@standardnotes/common'
import { SubscriptionRefundedEvent } from '@standardnotes/domain-events'
import { Result } from '@standardnotes/domain-core'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
@@ -10,7 +11,6 @@ import { SubscriptionRefundedEventHandler } from './SubscriptionRefundedEventHan
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
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'

View File

@@ -1,11 +1,11 @@
import { DomainEventHandlerInterface, SubscriptionRefundedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Logger } from 'winston'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types'
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { Email } from '../Common/Email'
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'

View File

@@ -2,13 +2,13 @@ import 'reflect-metadata'
import { SubscriptionName } from '@standardnotes/common'
import { SubscriptionRenewedEvent } from '@standardnotes/domain-events'
import { Result } from '@standardnotes/domain-core'
import { SubscriptionRenewedEventHandler } from './SubscriptionRenewedEventHandler'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { RevenueModification } from '../Revenue/RevenueModification'
import { Result } from '../Core/Result'
import { Logger } from 'winston'
describe('SubscriptionRenewedEventHandler', () => {

View File

@@ -1,5 +1,6 @@
import { DomainEventHandlerInterface, SubscriptionRenewedEvent } from '@standardnotes/domain-events'
import { inject, injectable } from 'inversify'
import { Email } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types'
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
@@ -7,7 +8,6 @@ import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
import { Period } from '../Time/Period'
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
import { Email } from '../Common/Email'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
import { Logger } from 'winston'

View File

@@ -1,13 +1,11 @@
import { injectable } from 'inversify'
import { Email, MapInterface, UniqueEntityId } from '@standardnotes/domain-core'
import { TypeORMRevenueModification } from '../../Infra/TypeORM/TypeORMRevenueModification'
import { UniqueEntityId } from '../Core/UniqueEntityId'
import { MonthlyRevenue } from '../Revenue/MonthlyRevenue'
import { RevenueModification } from '../Revenue/RevenueModification'
import { Subscription } from '../Subscription/Subscription'
import { User } from '../User/User'
import { MapInterface } from './MapInterface'
import { Email } from '../Common/Email'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
@@ -61,7 +59,7 @@ export class RevenueModificationMap implements MapInterface<RevenueModification,
return revenuModificationOrError.getValue()
}
toPersistence(domain: RevenueModification): TypeORMRevenueModification {
toProjection(domain: RevenueModification): TypeORMRevenueModification {
const { subscription, user } = domain.props
const persistence = new TypeORMRevenueModification()
persistence.uuid = domain.id.toString()

View File

@@ -1,5 +1,5 @@
import { ValueObject } from '../Core/ValueObject'
import { Result } from '../Core/Result'
import { Result, ValueObject } from '@standardnotes/domain-core'
import { MonthlyRevenueProps } from './MonthlyRevenueProps'
export class MonthlyRevenue extends ValueObject<MonthlyRevenueProps> {

View File

@@ -1,4 +1,5 @@
import { Email } from '../Common/Email'
import { Email } from '@standardnotes/domain-core'
import { Subscription } from '../Subscription/Subscription'
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'

View File

@@ -1,6 +1,5 @@
import { Aggregate } from '../Core/Aggregate'
import { Result } from '../Core/Result'
import { UniqueEntityId } from '../Core/UniqueEntityId'
import { Aggregate, UniqueEntityId, Result } from '@standardnotes/domain-core'
import { RevenueModificationProps } from './RevenueModificationProps'
export class RevenueModification extends Aggregate<RevenueModificationProps> {

View File

@@ -1,4 +1,5 @@
import { Uuid } from '../Common/Uuid'
import { Uuid } from '@standardnotes/domain-core'
import { RevenueModification } from './RevenueModification'
export interface RevenueModificationRepositoryInterface {

View File

@@ -1,6 +1,5 @@
import { Entity } from '../Core/Entity'
import { Result } from '../Core/Result'
import { UniqueEntityId } from '../Core/UniqueEntityId'
import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { SubscriptionProps } from './SubscriptionProps'
export class Subscription extends Entity<SubscriptionProps> {

View File

@@ -1,5 +1,5 @@
import { ValueObject } from '../Core/ValueObject'
import { Result } from '../Core/Result'
import { ValueObject, Result } from '@standardnotes/domain-core'
import { SubscriptionEventTypeProps } from './SubscriptionEventTypeProps'
export class SubscriptionEventType extends ValueObject<SubscriptionEventTypeProps> {

View File

@@ -1,5 +1,5 @@
import { ValueObject } from '../Core/ValueObject'
import { Result } from '../Core/Result'
import { Result, ValueObject } from '@standardnotes/domain-core'
import { SubscriptionPlanNameProps } from './SubscriptionPlanNameProps'
export class SubscriptionPlanName extends ValueObject<SubscriptionPlanNameProps> {

View File

@@ -1,7 +1,8 @@
import { SubscriptionBillingFrequency, SubscriptionName } from '@standardnotes/common'
import { inject, injectable } from 'inversify'
import { Result } from '@standardnotes/domain-core'
import TYPES from '../../../Bootstrap/Types'
import { Result } from '../../Core/Result'
import { MonthlyRevenue } from '../../Revenue/MonthlyRevenue'
import { RevenueModificationRepositoryInterface } from '../../Revenue/RevenueModificationRepositoryInterface'
import { StatisticsMeasure } from '../../Statistics/StatisticsMeasure'

View File

@@ -1,4 +1,4 @@
import { Result } from '../Core/Result'
import { Result } from '@standardnotes/domain-core'
export interface DomainUseCaseInterface<T> {
execute(...args: any[]): Promise<Result<T>>

View File

@@ -1,7 +1,7 @@
import { inject, injectable } from 'inversify'
import { Email, Uuid } from '@standardnotes/domain-core'
import TYPES from '../../../Bootstrap/Types'
import { Email } from '../../Common/Email'
import { Uuid } from '../../Common/Uuid'
import { AnalyticsEntityRepositoryInterface } from '../../Entity/AnalyticsEntityRepositoryInterface'
import { UseCaseInterface } from '../UseCaseInterface'
import { GetUserAnalyticsIdDTO } from './GetUserAnalyticsIdDTO'

View File

@@ -1,5 +1,4 @@
import { Email } from '../../Common/Email'
import { Uuid } from '../../Common/Uuid'
import { Email, Uuid } from '@standardnotes/domain-core'
export type GetUserAnalyticsIdResponse = {
analyticsId: number

View File

@@ -1,9 +1,8 @@
import 'reflect-metadata'
import { TimerInterface } from '@standardnotes/time'
import { Email, Result, Uuid } from '@standardnotes/domain-core'
import { Email } from '../../Common/Email'
import { Uuid } from '../../Common/Uuid'
import { MonthlyRevenue } from '../../Revenue/MonthlyRevenue'
import { RevenueModification } from '../../Revenue/RevenueModification'
@@ -12,7 +11,6 @@ import { SubscriptionEventType } from '../../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../../Subscription/SubscriptionPlanName'
import { SaveRevenueModification } from './SaveRevenueModification'
import { User } from '../../User/User'
import { Result } from '../../Core/Result'
import { Subscription } from '../../Subscription/Subscription'
describe('SaveRevenueModification', () => {

View File

@@ -1,13 +1,12 @@
import { inject, injectable } from 'inversify'
import { Result, UniqueEntityId } from '@standardnotes/domain-core'
import TYPES from '../../../Bootstrap/Types'
import { UniqueEntityId } from '../../Core/UniqueEntityId'
import { MonthlyRevenue } from '../../Revenue/MonthlyRevenue'
import { RevenueModification } from '../../Revenue/RevenueModification'
import { RevenueModificationRepositoryInterface } from '../../Revenue/RevenueModificationRepositoryInterface'
import { Subscription } from '../../Subscription/Subscription'
import { User } from '../../User/User'
import { Result } from '../../Core/Result'
import { DomainUseCaseInterface } from '../DomainUseCaseInterface'
import { SaveRevenueModificationDTO } from './SaveRevenueModificationDTO'
import { TimerInterface } from '@standardnotes/time'

View File

@@ -1,5 +1,5 @@
import { Email } from '../../Common/Email'
import { Uuid } from '../../Common/Uuid'
import { Email, Uuid } from '@standardnotes/domain-core'
import { SubscriptionEventType } from '../../Subscription/SubscriptionEventType'
import { SubscriptionPlanName } from '../../Subscription/SubscriptionPlanName'

View File

@@ -1,4 +1,5 @@
import { Email } from '../Common/Email'
import { Email } from '@standardnotes/domain-core'
import { User } from './User'
describe('User', () => {

View File

@@ -1,6 +1,5 @@
import { Entity } from '../Core/Entity'
import { Result } from '../Core/Result'
import { UniqueEntityId } from '../Core/UniqueEntityId'
import { Entity, Result, UniqueEntityId } from '@standardnotes/domain-core'
import { UserProps } from './UserProps'
export class User extends Entity<UserProps> {

View File

@@ -1,4 +1,4 @@
import { Email } from '../Common/Email'
import { Email } from '@standardnotes/domain-core'
export interface UserProps {
email: Email

View File

@@ -1,9 +1,8 @@
import { inject, injectable } from 'inversify'
import { Repository } from 'typeorm'
import { MapInterface, Uuid } from '@standardnotes/domain-core'
import TYPES from '../../Bootstrap/Types'
import { Uuid } from '../../Domain/Common/Uuid'
import { MapInterface } from '../../Domain/Map/MapInterface'
import { RevenueModification } from '../../Domain/Revenue/RevenueModification'
import { RevenueModificationRepositoryInterface } from '../../Domain/Revenue/RevenueModificationRepositoryInterface'
import { TypeORMRevenueModification } from '../TypeORM/TypeORMRevenueModification'
@@ -52,7 +51,7 @@ export class MySQLRevenueModificationRepository implements RevenueModificationRe
}
async save(revenueModification: RevenueModification): Promise<RevenueModification> {
let persistence = this.revenueModificationMap.toPersistence(revenueModification)
let persistence = this.revenueModificationMap.toProjection(revenueModification)
persistence = await this.ormRepository.save(persistence)

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.38.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.38.4...@standardnotes/api-gateway@1.38.5) (2022-11-14)
**Note:** Version bump only for package @standardnotes/api-gateway
## [1.38.4](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.38.1...@standardnotes/api-gateway@1.38.4) (2022-11-14)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api-gateway",
"version": "1.38.4",
"version": "1.38.5",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.60.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.59.11...@standardnotes/auth-server@1.60.0) (2022-11-14)
### Features
* **auth:** add content size recalculation procedure trigger ([590ec66](https://github.com/standardnotes/server/commit/590ec6643db57adf3e202c6ccab4bac36aae8b59))
## [1.59.11](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.59.10...@standardnotes/auth-server@1.59.11) (2022-11-14)
**Note:** Version bump only for package @standardnotes/auth-server
## [1.59.10](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.59.7...@standardnotes/auth-server@1.59.10) (2022-11-14)
### Bug Fixes

View File

@@ -0,0 +1,74 @@
import 'reflect-metadata'
import 'newrelic'
import { Logger } from 'winston'
import * as dayjs from 'dayjs'
import * as utc from 'dayjs/plugin/utc'
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
import TYPES from '../src/Bootstrap/Types'
import { Env } from '../src/Bootstrap/Env'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface'
import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface'
import { Stream } from 'stream'
const requestRecalculation = async (
userRepository: UserRepositoryInterface,
domainEventFactory: DomainEventFactoryInterface,
domainEventPublisher: DomainEventPublisherInterface,
logger: Logger,
): Promise<void> => {
const stream = await userRepository.streamAll()
return new Promise((resolve, reject) => {
stream
.pipe(
new Stream.Transform({
objectMode: true,
transform: async (rawUserData, _encoding, callback) => {
try {
await domainEventPublisher.publish(
domainEventFactory.createUserContentSizeRecalculationRequestedEvent(rawUserData.user_uuid),
)
} catch (error) {
logger.error(`Could not process user ${rawUserData.user_uuid}: ${(error as Error).message}`)
}
callback()
},
}),
)
.on('finish', resolve)
.on('error', reject)
})
}
const container = new ContainerConfigLoader()
void container.load().then((container) => {
dayjs.extend(utc)
const env: Env = new Env()
env.load()
const logger: Logger = container.get(TYPES.Logger)
logger.info('Starting content size recalculation requests ...')
const userRepository: UserRepositoryInterface = container.get(TYPES.UserRepository)
const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.DomainEventFactory)
const domainEventPublisher: DomainEventPublisherInterface = container.get(TYPES.DomainEventPublisher)
Promise.resolve(requestRecalculation(userRepository, domainEventFactory, domainEventPublisher, logger))
.then(() => {
logger.info('content size recalculation requesting complete')
process.exit(0)
})
.catch((error) => {
logger.error(`Could not finish content size recalculation requesting : ${error.message}`)
process.exit(1)
})
})

View File

@@ -56,6 +56,11 @@ case "$COMMAND" in
yarn workspace @standardnotes/auth-server email-campaign $MESSAGE_IDENTIFIER
;;
'content-recalculation' )
echo "Starting Content Size Recalculation..."
yarn workspace @standardnotes/auth-server content-recalculation
;;
* )
echo "Unknown command"
;;

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.59.10",
"version": "1.60.0",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -25,6 +25,7 @@
"daily-backup:google_drive": "yarn node dist/bin/backup.js google_drive daily",
"daily-backup:one_drive": "yarn node dist/bin/backup.js one_drive daily",
"weekly-backup:email": "yarn node dist/bin/backup.js email weekly",
"content-recalculation": "yarn node dist/bin/content.js",
"email-campaign": "yarn node dist/bin/email.js",
"typeorm": "typeorm-ts-node-commonjs",
"upgrade:snjs": "yarn ncu -u '@standardnotes/*'"

View File

@@ -1,406 +0,0 @@
import 'reflect-metadata'
import { EmailMessageIdentifier, ProtocolVersion, RoleName } from '@standardnotes/common'
import { PredicateName, PredicateAuthority, PredicateVerificationResult } from '@standardnotes/predicates'
import { TimerInterface } from '@standardnotes/time'
import { DomainEventFactory } from './DomainEventFactory'
import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType'
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 EXIT_DISCOUNT_APPLY_REQUESTED event', () => {
expect(
createFactory().createExitDiscountApplyRequestedEvent({
userEmail: 'test@test.te',
discountCode: 'exit-20',
}),
).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: 'test@test.te',
userIdentifierType: 'email',
},
origin: 'auth',
},
payload: {
userEmail: 'test@test.te',
discountCode: 'exit-20',
},
type: 'EXIT_DISCOUNT_APPLY_REQUESTED',
})
})
it('should create a WEB_SOCKET_MESSAGE_REQUESTED event', () => {
expect(
createFactory().createWebSocketMessageRequestedEvent({
userUuid: '1-2-3',
message: 'foobar',
}),
).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: '1-2-3',
userIdentifierType: 'uuid',
},
origin: 'auth',
},
payload: {
userUuid: '1-2-3',
message: 'foobar',
},
type: 'WEB_SOCKET_MESSAGE_REQUESTED',
})
})
it('should create a EMAIL_MESSAGE_REQUESTED event', () => {
expect(
createFactory().createEmailMessageRequestedEvent({
userEmail: 'test@test.te',
messageIdentifier: EmailMessageIdentifier.ENCOURAGE_EMAIL_BACKUPS,
context: {
foo: 'bar',
},
}),
).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: 'test@test.te',
userIdentifierType: 'email',
},
origin: 'auth',
},
payload: {
messageIdentifier: 'ENCOURAGE_EMAIL_BACKUPS',
userEmail: 'test@test.te',
context: {
foo: 'bar',
},
},
type: 'EMAIL_MESSAGE_REQUESTED',
})
})
it('should create a PREDICATE_VERIFIED event', () => {
expect(
createFactory().createPredicateVerifiedEvent({
predicate: {
authority: PredicateAuthority.Auth,
jobUuid: '1-2-3',
name: PredicateName.EmailBackupsEnabled,
},
predicateVerificationResult: PredicateVerificationResult.Affirmed,
userUuid: '2-3-4',
}),
).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: '2-3-4',
userIdentifierType: 'uuid',
},
origin: 'auth',
},
payload: {
predicate: {
authority: 'auth',
jobUuid: '1-2-3',
name: 'email-backups-enabled',
},
predicateVerificationResult: 'affirmed',
},
type: 'PREDICATE_VERIFIED',
})
})
it('should create a SHARED_SUBSCRIPTION_INVITATION_CANCELED event', () => {
expect(
createFactory().createSharedSubscriptionInvitationCanceledEvent({
inviterEmail: 'test@test.te',
inviterSubscriptionId: 1,
inviterSubscriptionUuid: '2-3-4',
inviteeIdentifier: 'invitee@test.te',
inviteeIdentifierType: InviteeIdentifierType.Email,
sharedSubscriptionInvitationUuid: '1-2-3',
}),
).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: 'test@test.te',
userIdentifierType: 'email',
},
origin: 'auth',
},
payload: {
inviterEmail: 'test@test.te',
inviterSubscriptionId: 1,
inviterSubscriptionUuid: '2-3-4',
inviteeIdentifier: 'invitee@test.te',
inviteeIdentifierType: InviteeIdentifierType.Email,
sharedSubscriptionInvitationUuid: '1-2-3',
},
type: 'SHARED_SUBSCRIPTION_INVITATION_CANCELED',
})
})
it('should create a SHARED_SUBSCRIPTION_INVITATION_CREATED event', () => {
expect(
createFactory().createSharedSubscriptionInvitationCreatedEvent({
inviterEmail: 'test@test.te',
inviterSubscriptionId: 1,
inviteeIdentifier: 'invitee@test.te',
inviteeIdentifierType: InviteeIdentifierType.Email,
sharedSubscriptionInvitationUuid: '1-2-3',
}),
).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: 'test@test.te',
userIdentifierType: 'email',
},
origin: 'auth',
},
payload: {
inviterEmail: 'test@test.te',
inviterSubscriptionId: 1,
inviteeIdentifier: 'invitee@test.te',
inviteeIdentifierType: InviteeIdentifierType.Email,
sharedSubscriptionInvitationUuid: '1-2-3',
},
type: 'SHARED_SUBSCRIPTION_INVITATION_CREATED',
})
})
it('should create a USER_DISABLED_SESSION_USER_AGENT_LOGGING event', () => {
expect(
createFactory().createUserDisabledSessionUserAgentLoggingEvent({
email: 'test@test.te',
userUuid: '1-2-3',
}),
).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: '1-2-3',
userIdentifierType: 'uuid',
},
origin: 'auth',
},
payload: {
userUuid: '1-2-3',
email: 'test@test.te',
},
type: 'USER_DISABLED_SESSION_USER_AGENT_LOGGING',
})
})
it('should create a USER_SIGNED_IN event', () => {
expect(
createFactory().createUserSignedInEvent({
browser: 'Firefox 1',
device: 'iOS 1',
userEmail: 'test@test.te',
userUuid: '1-2-3',
signInAlertEnabled: true,
muteSignInEmailsSettingUuid: '2-3-4',
}),
).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: '1-2-3',
userIdentifierType: 'uuid',
},
origin: 'auth',
},
payload: {
userUuid: '1-2-3',
userEmail: 'test@test.te',
browser: 'Firefox 1',
device: 'iOS 1',
signInAlertEnabled: true,
muteSignInEmailsSettingUuid: '2-3-4',
},
type: 'USER_SIGNED_IN',
})
})
it('should create a LISTED_ACCOUNT_REQUESTED event', () => {
expect(createFactory().createListedAccountRequestedEvent('1-2-3', 'test@test.te')).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: '1-2-3',
userIdentifierType: 'uuid',
},
origin: 'auth',
},
payload: {
userUuid: '1-2-3',
userEmail: 'test@test.te',
},
type: 'LISTED_ACCOUNT_REQUESTED',
})
})
it('should create a USER_REGISTERED event', () => {
expect(
createFactory().createUserRegisteredEvent({
userUuid: '1-2-3',
email: 'test@test.te',
protocolVersion: ProtocolVersion.V004,
}),
).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: '1-2-3',
userIdentifierType: 'uuid',
},
origin: 'auth',
},
payload: {
userUuid: '1-2-3',
email: 'test@test.te',
protocolVersion: '004',
},
type: 'USER_REGISTERED',
})
})
it('should create a OFFLINE_SUBSCRIPTION_TOKEN_CREATED event', () => {
expect(createFactory().createOfflineSubscriptionTokenCreatedEvent('1-2-3', 'test@test.te')).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: 'test@test.te',
userIdentifierType: 'email',
},
origin: 'auth',
},
payload: {
token: '1-2-3',
email: 'test@test.te',
},
type: 'OFFLINE_SUBSCRIPTION_TOKEN_CREATED',
})
})
it('should create a USER_CHANGED_EMAIL event', () => {
expect(createFactory().createUserEmailChangedEvent('1-2-3', 'test@test.te', 'test2@test.te')).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: '1-2-3',
userIdentifierType: 'uuid',
},
origin: 'auth',
},
payload: {
userUuid: '1-2-3',
fromEmail: 'test@test.te',
toEmail: 'test2@test.te',
},
type: 'USER_EMAIL_CHANGED',
})
})
it('should create a CLOUD_BACKUP_REQUESTED event', () => {
expect(createFactory().createCloudBackupRequestedEvent('GOOGLE_DRIVE', 'test', '1-2-3', '2-3-4', true)).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: '1-2-3',
userIdentifierType: 'uuid',
},
origin: 'auth',
},
payload: {
cloudProvider: 'GOOGLE_DRIVE',
cloudProviderToken: 'test',
userUuid: '1-2-3',
muteEmailsSettingUuid: '2-3-4',
userHasEmailsMuted: true,
},
type: 'CLOUD_BACKUP_REQUESTED',
})
})
it('should create a EMAIL_BACKUP_REQUESTED event', () => {
expect(createFactory().createEmailBackupRequestedEvent('1-2-3', '2-3-4', true)).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: '1-2-3',
userIdentifierType: 'uuid',
},
origin: 'auth',
},
payload: {
userUuid: '1-2-3',
muteEmailsSettingUuid: '2-3-4',
userHasEmailsMuted: true,
},
type: 'EMAIL_BACKUP_REQUESTED',
})
})
it('should create a ACCOUNT_DELETION_REQUESTED event', () => {
expect(
createFactory().createAccountDeletionRequestedEvent({
userUuid: '1-2-3',
userCreatedAtTimestamp: 123,
regularSubscriptionUuid: '2-3-4',
}),
).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: '1-2-3',
userIdentifierType: 'uuid',
},
origin: 'auth',
},
payload: {
userUuid: '1-2-3',
userCreatedAtTimestamp: 123,
regularSubscriptionUuid: '2-3-4',
},
type: 'ACCOUNT_DELETION_REQUESTED',
})
})
it('should create a USER_ROLE_CHANGED event', () => {
expect(createFactory().createUserRolesChangedEvent('1-2-3', 'test@test.com', [RoleName.ProUser])).toEqual({
createdAt: expect.any(Date),
meta: {
correlation: {
userIdentifier: '1-2-3',
userIdentifierType: 'uuid',
},
origin: 'auth',
},
payload: {
userUuid: '1-2-3',
email: 'test@test.com',
currentRoles: [RoleName.ProUser],
timestamp: expect.any(Number),
},
type: 'USER_ROLES_CHANGED',
})
})
})

View File

@@ -1,3 +1,5 @@
/* istanbul ignore file */
import { EmailMessageIdentifier, JSONString, ProtocolVersion, RoleName, Uuid } from '@standardnotes/common'
import {
AccountDeletionRequestedEvent,
@@ -17,6 +19,7 @@ import {
EmailMessageRequestedEvent,
WebSocketMessageRequestedEvent,
ExitDiscountApplyRequestedEvent,
UserContentSizeRecalculationRequestedEvent,
} from '@standardnotes/domain-events'
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
import { TimerInterface } from '@standardnotes/time'
@@ -29,6 +32,23 @@ import { DomainEventFactoryInterface } from './DomainEventFactoryInterface'
export class DomainEventFactory implements DomainEventFactoryInterface {
constructor(@inject(TYPES.Timer) private timer: TimerInterface) {}
createUserContentSizeRecalculationRequestedEvent(userUuid: string): UserContentSizeRecalculationRequestedEvent {
return {
type: 'USER_CONTENT_SIZE_RECALCULATION_REQUESTED',
createdAt: this.timer.getUTCDate(),
meta: {
correlation: {
userIdentifier: userUuid,
userIdentifierType: 'uuid',
},
origin: DomainEventService.Auth,
},
payload: {
userUuid,
},
}
}
createExitDiscountApplyRequestedEvent(dto: {
userEmail: string
discountCode: string

View File

@@ -17,10 +17,12 @@ import {
EmailMessageRequestedEvent,
WebSocketMessageRequestedEvent,
ExitDiscountApplyRequestedEvent,
UserContentSizeRecalculationRequestedEvent,
} from '@standardnotes/domain-events'
import { InviteeIdentifierType } from '../SharedSubscription/InviteeIdentifierType'
export interface DomainEventFactoryInterface {
createUserContentSizeRecalculationRequestedEvent(userUuid: string): UserContentSizeRecalculationRequestedEvent
createWebSocketMessageRequestedEvent(dto: { userUuid: Uuid; message: JSONString }): WebSocketMessageRequestedEvent
createEmailMessageRequestedEvent(dto: {
userEmail: string

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.45.0](https://github.com/standardnotes/server/compare/@standardnotes/common@1.44.4...@standardnotes/common@1.45.0) (2022-11-14)
### Features
* **analytics:** extract domain core into a separate package ([0f94e2a](https://github.com/standardnotes/server/commit/0f94e2ad0c8927733eac31f130cbe649dce765f9))
## [1.44.4](https://github.com/standardnotes/server/compare/@standardnotes/common@1.44.1...@standardnotes/common@1.44.4) (2022-11-14)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/common",
"version": "1.44.4",
"version": "1.45.0",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -32,7 +32,6 @@
"typescript": "^4.8.4"
},
"dependencies": {
"@newrelic/native-metrics": "^9.0.0",
"reflect-metadata": "^0.1.13"
}
}

View File

@@ -0,0 +1 @@
dist

View File

@@ -0,0 +1,6 @@
{
"extends": "../../.eslintrc",
"parserOptions": {
"project": "./linter.tsconfig.json"
}
}

View File

@@ -0,0 +1,16 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.1.0...@standardnotes/domain-core@1.1.1) (2022-11-14)
### Bug Fixes
* **syncing-server:** retrieving revisions ([50f7ae3](https://github.com/standardnotes/server/commit/50f7ae338ad66d3465fa16c31e7c47c57b1e0c3c))
# 1.1.0 (2022-11-14)
### Features
* **analytics:** extract domain core into a separate package ([0f94e2a](https://github.com/standardnotes/server/commit/0f94e2ad0c8927733eac31f130cbe649dce765f9))

View File

@@ -0,0 +1,10 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const base = require('../../jest.config')
const { defaults: tsjPreset } = require('ts-jest/presets')
module.exports = {
...base,
transform: {
...tsjPreset.transform,
},
}

View File

@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["dist"]
}

View File

@@ -0,0 +1,43 @@
{
"name": "@standardnotes/domain-core",
"version": "1.1.1",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
"description": "Domain Core SDK used in SN projects",
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
"files": [
"dist/src/**/*.js",
"dist/src/**/*.d.ts"
],
"publishConfig": {
"access": "public"
},
"author": "Standard Notes",
"license": "AGPL-3.0-or-later",
"scripts": {
"clean": "rm -fr dist",
"build": "tsc --build",
"lint": "eslint . --ext .ts",
"test": "jest spec --coverage --passWithNoTests"
},
"dependencies": {
"@standardnotes/common": "workspace:*",
"@standardnotes/features": "^1.52.1",
"@standardnotes/predicates": "workspace:*",
"@standardnotes/security": "workspace:*",
"reflect-metadata": "^0.1.13",
"shallow-equal-object": "^1.1.1",
"uuid": "^9.0.0"
},
"devDependencies": {
"@types/jest": "^29.1.1",
"@types/uuid": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^29.1.2",
"ts-jest": "^29.0.3",
"typescript": "^4.8.4"
}
}

View File

@@ -1,4 +1,4 @@
export interface MapInterface<T, U> {
toDomain(persistence: U): T
toPersistence(domain: T): U
toProjection(domain: T): U
}

View File

@@ -0,0 +1,14 @@
export * from './Common/Email'
export * from './Common/EmailProps'
export * from './Common/Uuid'
export * from './Common/UuidProps'
export * from './Core/Aggregate'
export * from './Core/Entity'
export * from './Core/Id'
export * from './Core/Result'
export * from './Core/UniqueEntityId'
export * from './Core/ValueObject'
export * from './Core/ValueObjectProps'
export * from './Map/MapInterface'

View File

@@ -0,0 +1 @@
export * from './Domain'

View File

@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"composite": true,
"outDir": "./dist",
},
"include": [
"src/**/*"
],
"references": []
}

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.9.27](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.26...@standardnotes/domain-events-infra@1.9.27) (2022-11-14)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.9.26](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.9.23...@standardnotes/domain-events-infra@1.9.26) (2022-11-14)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events-infra",
"version": "1.9.26",
"version": "1.9.27",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [2.87.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.86.3...@standardnotes/domain-events@2.87.0) (2022-11-14)
### Features
* **analytics:** extract domain core into a separate package ([0f94e2a](https://github.com/standardnotes/server/commit/0f94e2ad0c8927733eac31f130cbe649dce765f9))
## [2.86.3](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.86.0...@standardnotes/domain-events@2.86.3) (2022-11-14)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events",
"version": "2.86.3",
"version": "2.87.0",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -23,7 +23,6 @@
"test": "jest spec --coverage --passWithNoTests"
},
"dependencies": {
"@newrelic/native-metrics": "^9.0.0",
"@standardnotes/common": "workspace:*",
"@standardnotes/features": "^1.52.1",
"@standardnotes/predicates": "workspace:*",

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.6.22](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.21...@standardnotes/event-store@1.6.22) (2022-11-14)
**Note:** Version bump only for package @standardnotes/event-store
## [1.6.21](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.6.18...@standardnotes/event-store@1.6.21) (2022-11-14)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/event-store",
"version": "1.6.21",
"version": "1.6.22",
"description": "Event Store Service",
"private": true,
"main": "dist/src/index.js",

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.8.22](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.21...@standardnotes/files-server@1.8.22) (2022-11-14)
**Note:** Version bump only for package @standardnotes/files-server
## [1.8.21](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.8.18...@standardnotes/files-server@1.8.21) (2022-11-14)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files-server",
"version": "1.8.21",
"version": "1.8.22",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.6.0](https://github.com/standardnotes/server/compare/@standardnotes/predicates@1.5.7...@standardnotes/predicates@1.6.0) (2022-11-14)
### Features
* **analytics:** extract domain core into a separate package ([0f94e2a](https://github.com/standardnotes/server/commit/0f94e2ad0c8927733eac31f130cbe649dce765f9))
## [1.5.7](https://github.com/standardnotes/server/compare/@standardnotes/predicates@1.5.4...@standardnotes/predicates@1.5.7) (2022-11-14)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/predicates",
"version": "1.5.7",
"version": "1.6.0",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -33,7 +33,6 @@
"typescript": "^4.8.4"
},
"dependencies": {
"@newrelic/native-metrics": "^9.0.0",
"@standardnotes/common": "workspace:*",
"reflect-metadata": "^0.1.13"
}

View File

@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.13.23](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.13.22...@standardnotes/scheduler-server@1.13.23) (2022-11-14)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.13.22](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.13.19...@standardnotes/scheduler-server@1.13.22) (2022-11-14)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/scheduler-server",
"version": "1.13.22",
"version": "1.13.23",
"engines": {
"node": ">=18.0.0 <19.0.0"
},

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.7.0](https://github.com/standardnotes/server/compare/@standardnotes/security@1.6.4...@standardnotes/security@1.7.0) (2022-11-14)
### Features
* **analytics:** extract domain core into a separate package ([0f94e2a](https://github.com/standardnotes/server/commit/0f94e2ad0c8927733eac31f130cbe649dce765f9))
## [1.6.4](https://github.com/standardnotes/server/compare/@standardnotes/security@1.6.1...@standardnotes/security@1.6.4) (2022-11-14)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/security",
"version": "1.6.4",
"version": "1.7.0",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -25,7 +25,6 @@
"test": "jest spec --coverage"
},
"dependencies": {
"@newrelic/native-metrics": "^9.0.0",
"@standardnotes/common": "workspace:*",
"jsonwebtoken": "^8.5.1",
"reflect-metadata": "^0.1.13"

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.13.0](https://github.com/standardnotes/server/compare/@standardnotes/sncrypto-node@1.12.3...@standardnotes/sncrypto-node@1.13.0) (2022-11-14)
### Features
* **analytics:** extract domain core into a separate package ([0f94e2a](https://github.com/standardnotes/server/commit/0f94e2ad0c8927733eac31f130cbe649dce765f9))
## [1.12.3](https://github.com/standardnotes/server/compare/@standardnotes/sncrypto-node@1.12.0...@standardnotes/sncrypto-node@1.12.3) (2022-11-14)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/sncrypto-node",
"version": "1.12.3",
"version": "1.13.0",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -23,7 +23,6 @@
"test": "jest spec"
},
"dependencies": {
"@newrelic/native-metrics": "^9.0.0",
"@standardnotes/sncrypto-common": "^1.9.0",
"reflect-metadata": "^0.1.13"
},

View File

@@ -3,6 +3,40 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.13.11](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.13.10...@standardnotes/syncing-server@1.13.11) (2022-11-14)
### Bug Fixes
* **syncing-server:** decrease logs severity for content recalculation ([500756d](https://github.com/standardnotes/syncing-server-js/commit/500756d58239ea4f639362542476827f9faaa88b))
## [1.13.10](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.13.9...@standardnotes/syncing-server@1.13.10) (2022-11-14)
### Bug Fixes
* **syncing-server:** linter issues ([3be1bfe](https://github.com/standardnotes/syncing-server-js/commit/3be1bfe58a0dcdda4f593cf5327426cbdcee7c45))
## [1.13.9](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.13.8...@standardnotes/syncing-server@1.13.9) (2022-11-14)
### Bug Fixes
* **syncing-server:** retrieving revisions ([50f7ae3](https://github.com/standardnotes/syncing-server-js/commit/50f7ae338ad66d3465fa16c31e7c47c57b1e0c3c))
## [1.13.8](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.13.7...@standardnotes/syncing-server@1.13.8) (2022-11-14)
**Note:** Version bump only for package @standardnotes/syncing-server
## [1.13.7](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.13.6...@standardnotes/syncing-server@1.13.7) (2022-11-14)
### Bug Fixes
* **syncing-server:** content recalculation missing await ([f766fef](https://github.com/standardnotes/syncing-server-js/commit/f766fefbf0d13a9d37b0598c5c3d228fc376c943))
## [1.13.6](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.13.5...@standardnotes/syncing-server@1.13.6) (2022-11-14)
### Bug Fixes
* **syncing-server:** add missing content size recalculation handler binding ([79511ae](https://github.com/standardnotes/syncing-server-js/commit/79511aea5f0fc2114aa7c45851ce4dbe8bc531bb))
## [1.13.5](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.13.2...@standardnotes/syncing-server@1.13.5) (2022-11-14)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/syncing-server",
"version": "1.13.5",
"version": "1.13.11",
"engines": {
"node": ">=18.0.0 <19.0.0"
},
@@ -16,6 +16,7 @@
"setup:env": "cp .env.sample .env",
"build": "tsc --build",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --ext .ts --fix",
"pretest": "yarn lint && yarn build",
"test": "jest --coverage --config=./jest.config.js --maxWorkers=50%",
"start": "yarn node dist/bin/server.js",
@@ -28,6 +29,7 @@
"@newrelic/winston-enricher": "^4.0.0",
"@sentry/node": "^7.19.0",
"@standardnotes/common": "workspace:*",
"@standardnotes/domain-core": "workspace:^",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/payloads": "^1.5.1",

View File

@@ -80,6 +80,10 @@ import { RevisionRepositoryInterface } from '../Domain/Revision/RevisionReposito
import { ItemRepositoryInterface } from '../Domain/Item/ItemRepositoryInterface'
import { Repository } from 'typeorm'
import { UserContentSizeRecalculationRequestedEventHandler } from '../Domain/Handler/UserContentSizeRecalculationRequestedEventHandler'
import { RevisionMetadataMap } from '../Domain/Map/RevisionMetadataMap'
import { MapInterface } from '@standardnotes/domain-core'
import { RevisionMetadata } from '../Domain/Revision/RevisionMetadata'
import { SimpleRevisionProjection } from '../Projection/SimpleRevisionProjection'
// eslint-disable-next-line @typescript-eslint/no-var-requires
const newrelicFormatter = require('@newrelic/winston-enricher')
@@ -225,6 +229,11 @@ export class ContainerConfigLoader {
.bind<UserContentSizeRecalculationRequestedEventHandler>(TYPES.UserContentSizeRecalculationRequestedEventHandler)
.to(UserContentSizeRecalculationRequestedEventHandler)
// Map
container
.bind<MapInterface<RevisionMetadata, SimpleRevisionProjection>>(TYPES.RevisionMetadataMap)
.to(RevisionMetadataMap)
// Services
container.bind<ContentDecoder>(TYPES.ContentDecoder).to(ContentDecoder)
container.bind<DomainEventFactoryInterface>(TYPES.DomainEventFactory).to(DomainEventFactory)
@@ -261,6 +270,10 @@ export class ContainerConfigLoader {
['ACCOUNT_DELETION_REQUESTED', container.get(TYPES.AccountDeletionRequestedEventHandler)],
['EMAIL_BACKUP_REQUESTED', container.get(TYPES.EmailBackupRequestedEventHandler)],
['CLOUD_BACKUP_REQUESTED', container.get(TYPES.CloudBackupRequestedEventHandler)],
[
'USER_CONTENT_SIZE_RECALCULATION_REQUESTED',
container.get(TYPES.UserContentSizeRecalculationRequestedEventHandler),
],
])
if (env.get('SQS_QUEUE_URL', true)) {

View File

@@ -49,6 +49,8 @@ const TYPES = {
EmailBackupRequestedEventHandler: Symbol.for('EmailBackupRequestedEventHandler'),
CloudBackupRequestedEventHandler: Symbol.for('CloudBackupRequestedEventHandler'),
UserContentSizeRecalculationRequestedEventHandler: Symbol.for('UserContentSizeRecalculationRequestedEventHandler'),
// Map
RevisionMetadataMap: Symbol.for('RevisionMetadataMap'),
// Services
ContentDecoder: Symbol.for('ContentDecoder'),
DomainEventPublisher: Symbol.for('DomainEventPublisher'),

View File

@@ -8,23 +8,32 @@ import { results } from 'inversify-express-utils'
import { ProjectorInterface } from '../Projection/ProjectorInterface'
import { RevisionServiceInterface } from '../Domain/Revision/RevisionServiceInterface'
import { RevisionProjection } from '../Projection/RevisionProjection'
import { MapInterface } from '@standardnotes/domain-core'
import { RevisionMetadata } from '../Domain/Revision/RevisionMetadata'
import { SimpleRevisionProjection } from '../Projection/SimpleRevisionProjection'
describe('RevisionsController', () => {
let revisionProjector: ProjectorInterface<Revision, RevisionProjection>
let revisionMap: MapInterface<RevisionMetadata, SimpleRevisionProjection>
let revisionService: RevisionServiceInterface
let revision: Revision
let revisionMetadata: RevisionMetadata
let request: express.Request
let response: express.Response
const createController = () => new RevisionsController(revisionService, revisionProjector)
const createController = () => new RevisionsController(revisionService, revisionProjector, revisionMap)
beforeEach(() => {
revision = {} as jest.Mocked<Revision>
revisionMetadata = {} as jest.Mocked<RevisionMetadata>
revisionMap = {} as jest.Mocked<MapInterface<RevisionMetadata, SimpleRevisionProjection>>
revisionProjector = {} as jest.Mocked<ProjectorInterface<Revision, RevisionProjection>>
revisionService = {} as jest.Mocked<RevisionServiceInterface>
revisionService.getRevisions = jest.fn().mockReturnValue([revision])
revisionService.getRevisionsMetadata = jest.fn().mockReturnValue([revisionMetadata])
revisionService.getRevision = jest.fn().mockReturnValue(revision)
revisionService.removeRevision = jest.fn().mockReturnValue(true)
@@ -42,7 +51,7 @@ describe('RevisionsController', () => {
})
it('should return revisions for an item', async () => {
revisionProjector.projectSimple = jest.fn().mockReturnValue({ foo: 'bar' })
revisionMap.toProjection = jest.fn().mockReturnValue({ foo: 'bar' })
const revisionResponse = await createController().getRevisions(request, response)

View File

@@ -8,26 +8,31 @@ import { Revision } from '../Domain/Revision/Revision'
import { RevisionServiceInterface } from '../Domain/Revision/RevisionServiceInterface'
import { ErrorTag } from '@standardnotes/common'
import { RevisionProjection } from '../Projection/RevisionProjection'
import { MapInterface } from '@standardnotes/domain-core'
import { RevisionMetadata } from '../Domain/Revision/RevisionMetadata'
import { SimpleRevisionProjection } from '../Projection/SimpleRevisionProjection'
@controller('/items/:itemUuid/revisions', TYPES.AuthMiddleware)
export class RevisionsController extends BaseHttpController {
constructor(
@inject(TYPES.RevisionService) private revisionService: RevisionServiceInterface,
@inject(TYPES.RevisionProjector) private revisionProjector: ProjectorInterface<Revision, RevisionProjection>,
@inject(TYPES.RevisionMetadataMap)
private revisionMetadataMap: MapInterface<RevisionMetadata, SimpleRevisionProjection>,
) {
super()
}
@httpGet('/')
public async getRevisions(req: Request, response: Response): Promise<results.JsonResult> {
const revisions = await this.revisionService.getRevisions(response.locals.user.uuid, req.params.itemUuid)
const metadatas = await this.revisionService.getRevisionsMetadata(response.locals.user.uuid, req.params.itemUuid)
const revisionProjections = []
for (const revision of revisions) {
revisionProjections.push(await this.revisionProjector.projectSimple(revision))
const metadataProjections = []
for (const metadata of metadatas) {
metadataProjections.push(this.revisionMetadataMap.toProjection(metadata))
}
return this.json(revisionProjections)
return this.json(metadataProjections)
}
@httpGet('/:uuid')

View File

@@ -19,6 +19,8 @@ export class UserContentSizeRecalculationRequestedEventHandler implements Domain
) {}
async handle(event: UserContentSizeRecalculationRequestedEvent): Promise<void> {
this.logger.debug(`Starting content size recalculation for user: ${event.payload.userUuid}`)
const stream = await this.itemRepository.streamAll({
deleted: false,
userUuid: event.payload.userUuid,
@@ -39,13 +41,15 @@ export class UserContentSizeRecalculationRequestedEventHandler implements Domain
return
}
loggerHandle.info(`Fixing content size for item ${item.item_uuid}`)
loggerHandle.debug(`Fixing content size for item ${item.item_uuid}`)
const modelItem = await this.itemRepository.findByUuid(item.item_uuid)
if (modelItem !== null) {
const fixedContentSize = Buffer.byteLength(JSON.stringify(this.itemProjector.projectFull(modelItem)))
const fixedContentSize = Buffer.byteLength(
JSON.stringify(await this.itemProjector.projectFull(modelItem)),
)
if (modelItem.contentSize !== fixedContentSize) {
loggerHandle.info(`Fixing content size from ${modelItem.contentSize} to ${fixedContentSize}`)
loggerHandle.debug(`Fixing content size from ${modelItem.contentSize} to ${fixedContentSize}`)
modelItem.contentSize = fixedContentSize

View File

@@ -0,0 +1,44 @@
/* istanbul ignore file */
import { ContentType } from '@standardnotes/common'
import { MapInterface, UniqueEntityId } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'
import { SimpleRevisionProjection } from '../../Projection/SimpleRevisionProjection'
import { RevisionMetadata } from '../Revision/RevisionMetadata'
import { RevisionServiceInterface } from '../Revision/RevisionServiceInterface'
@injectable()
export class RevisionMetadataMap implements MapInterface<RevisionMetadata, SimpleRevisionProjection> {
constructor(
@inject(TYPES.RevisionService) private revisionService: RevisionServiceInterface,
@inject(TYPES.Timer) private timer: TimerInterface,
) {}
toDomain(persistence: SimpleRevisionProjection): RevisionMetadata {
const revisionMetadatOrError = RevisionMetadata.create(
{
contentType: persistence.content_type,
createdAt: this.timer.convertStringDateToDate(persistence.created_at),
updatedAt: this.timer.convertStringDateToDate(persistence.updated_at),
},
new UniqueEntityId(persistence.uuid),
)
if (revisionMetadatOrError.isFailed()) {
throw new Error(revisionMetadatOrError.getError())
}
return revisionMetadatOrError.getValue()
}
toProjection(domain: RevisionMetadata): SimpleRevisionProjection {
return {
uuid: domain.id.toString(),
content_type: domain.props.contentType as ContentType | null,
required_role: this.revisionService.calculateRequiredRoleBasedOnRevisionDate(domain.props.createdAt),
created_at: this.timer.convertDateToISOString(domain.props.createdAt),
updated_at: this.timer.convertDateToISOString(domain.props.updatedAt),
}
}
}

View File

@@ -0,0 +1,28 @@
import { UniqueEntityId, Entity, Result } from '@standardnotes/domain-core'
import { RevisionMetadataProps } from './RevisionMetadataProps'
export class RevisionMetadata extends Entity<RevisionMetadataProps> {
get id(): UniqueEntityId {
return this._id
}
private constructor(props: RevisionMetadataProps, id?: UniqueEntityId) {
super(props, id)
}
static create(props: RevisionMetadataProps, id?: UniqueEntityId): Result<RevisionMetadata> {
if (!(props.createdAt instanceof Date)) {
return Result.fail<RevisionMetadata>(
`Could not create Revision Metadata. Creation date should be a date object, given: ${props.createdAt}`,
)
}
if (!(props.updatedAt instanceof Date)) {
return Result.fail<RevisionMetadata>(
`Could not create Revision Metadata. Update date should be a date object, given: ${props.updatedAt}`,
)
}
return Result.ok<RevisionMetadata>(new RevisionMetadata(props, id))
}
}

View File

@@ -0,0 +1,5 @@
export interface RevisionMetadataProps {
contentType: string | null
createdAt: Date
updatedAt: Date
}

View File

@@ -1,8 +1,10 @@
import { Revision } from './Revision'
import { RevisionMetadata } from './RevisionMetadata'
export interface RevisionRepositoryInterface {
findByItemId(parameters: { itemUuid: string; afterDate?: Date }): Promise<Array<Revision>>
findOneById(itemId: string, id: string): Promise<Revision | null>
save(revision: Revision): Promise<Revision>
removeByUuid(itemUuid: string, revisionUuid: string): Promise<void>
findMetadataByItemId(itemUuid: string): Promise<Array<RevisionMetadata>>
}

View File

@@ -4,6 +4,7 @@ import { TimerInterface } from '@standardnotes/time'
import { Item } from '../Item/Item'
import { ItemRepositoryInterface } from '../Item/ItemRepositoryInterface'
import { Revision } from './Revision'
import { RevisionMetadata } from './RevisionMetadata'
import { RevisionRepositoryInterface } from './RevisionRepositoryInterface'
import { RevisionService } from './RevisionService'
@@ -50,6 +51,7 @@ describe('RevisionService', () => {
} as jest.Mocked<Revision>
revisionRepository.findByItemId = jest.fn().mockReturnValue([revision1, revision2])
revisionRepository.findMetadataByItemId = jest.fn().mockReturnValue([{} as jest.Mocked<RevisionMetadata>])
revisionRepository.findOneById = jest.fn().mockReturnValue(revision1)
revisionRepository.removeByUuid = jest.fn()
@@ -177,24 +179,24 @@ describe('RevisionService', () => {
).toBeNull()
})
it('should get revisions for an item', async () => {
await createService().getRevisions('1-2-3', '2-3-4')
it('should get revisions metadata for an item', async () => {
await createService().getRevisionsMetadata('1-2-3', '2-3-4')
expect(revisionRepository.findByItemId).toHaveBeenCalledWith({ itemUuid: '2-3-4' })
expect(revisionRepository.findMetadataByItemId).toHaveBeenCalledWith('2-3-4')
})
it('should not get revisions for an non existing item', async () => {
it('should not get revisions metadata for an non existing item', async () => {
itemRepository.findByUuid = jest.fn().mockReturnValue(null)
expect(await createService().getRevisions('1-2-3', '2-3-4')).toEqual([])
expect(await createService().getRevisionsMetadata('1-2-3', '2-3-4')).toEqual([])
expect(revisionRepository.findByItemId).not.toHaveBeenCalled()
expect(revisionRepository.findMetadataByItemId).not.toHaveBeenCalled()
})
it("should not get revisions for another user's item", async () => {
expect(await createService().getRevisions('3-4-5', '4-5-6')).toEqual([])
it("should not get revisions metadata for another user's item", async () => {
expect(await createService().getRevisionsMetadata('3-4-5', '4-5-6')).toEqual([])
expect(revisionRepository.findByItemId).not.toHaveBeenCalled()
expect(revisionRepository.findMetadataByItemId).not.toHaveBeenCalled()
})
it('should save a revision for a note item', async () => {

View File

@@ -8,6 +8,7 @@ import { Revision } from './Revision'
import { RevisionRepositoryInterface } from './RevisionRepositoryInterface'
import { RevisionServiceInterface } from './RevisionServiceInterface'
import { ItemRepositoryInterface } from '../Item/ItemRepositoryInterface'
import { RevisionMetadata } from './RevisionMetadata'
@injectable()
export class RevisionService implements RevisionServiceInterface {
@@ -28,15 +29,13 @@ export class RevisionService implements RevisionServiceInterface {
return true
}
async getRevisions(userUuid: string, itemUuid: string): Promise<Revision[]> {
async getRevisionsMetadata(userUuid: string, itemUuid: string): Promise<RevisionMetadata[]> {
const userItem = await this.itemRepository.findByUuid(itemUuid)
if (userItem === null || userItem.userUuid !== userUuid) {
return []
}
const revisions = await this.revisionRepository.findByItemId({ itemUuid })
return revisions
return this.revisionRepository.findMetadataByItemId(itemUuid)
}
async getRevision(dto: {

View File

@@ -1,11 +1,12 @@
import { RoleName } from '@standardnotes/common'
import { Item } from '../Item/Item'
import { Revision } from './Revision'
import { RevisionMetadata } from './RevisionMetadata'
export interface RevisionServiceInterface {
createRevision(item: Item): Promise<void>
copyRevisions(fromItemUuid: string, toItemUuid: string): Promise<void>
getRevisions(userUuid: string, itemUuid: string): Promise<Revision[]>
getRevisionsMetadata(userUuid: string, itemUuid: string): Promise<RevisionMetadata[]>
getRevision(dto: {
userUuid: string
userRoles: RoleName[]

View File

@@ -1,89 +0,0 @@
import 'reflect-metadata'
import { Repository, SelectQueryBuilder } from 'typeorm'
import { Revision } from '../../Domain/Revision/Revision'
import { MySQLRevisionRepository } from './MySQLRevisionRepository'
describe('MySQLRevisionRepository', () => {
let ormRepository: Repository<Revision>
let queryBuilder: SelectQueryBuilder<Revision>
let revision: Revision
const createRepository = () => new MySQLRevisionRepository(ormRepository)
beforeEach(() => {
queryBuilder = {} as jest.Mocked<SelectQueryBuilder<Revision>>
revision = {} as jest.Mocked<Revision>
ormRepository = {} as jest.Mocked<Repository<Revision>>
ormRepository.save = jest.fn()
ormRepository.createQueryBuilder = jest.fn().mockImplementation(() => queryBuilder)
})
it('should save', async () => {
await createRepository().save(revision)
expect(ormRepository.save).toHaveBeenCalledWith(revision)
})
it('should delete a revision for an item', async () => {
queryBuilder.where = jest.fn().mockReturnThis()
queryBuilder.delete = jest.fn().mockReturnThis()
queryBuilder.from = jest.fn().mockReturnThis()
queryBuilder.execute = jest.fn()
await createRepository().removeByUuid('1-2-3', '3-4-5')
expect(queryBuilder.delete).toHaveBeenCalled()
expect(queryBuilder.from).toHaveBeenCalledWith('revisions')
expect(queryBuilder.where).toHaveBeenCalledWith('uuid = :revisionUuid AND item_uuid = :itemUuid', {
itemUuid: '1-2-3',
revisionUuid: '3-4-5',
})
expect(queryBuilder.execute).toHaveBeenCalled()
})
it('should find revisions by item id', async () => {
queryBuilder.where = jest.fn().mockReturnThis()
queryBuilder.orderBy = jest.fn().mockReturnThis()
queryBuilder.getMany = jest.fn().mockReturnValue([revision])
const result = await createRepository().findByItemId({ itemUuid: '123' })
expect(queryBuilder.where).toHaveBeenCalledWith('revision.item_uuid = :item_uuid', { item_uuid: '123' })
expect(queryBuilder.orderBy).toHaveBeenCalledWith('revision.created_at', 'DESC')
expect(result).toEqual([revision])
})
it('should find revisions by item id after certain date', async () => {
queryBuilder.where = jest.fn().mockReturnThis()
queryBuilder.andWhere = jest.fn().mockReturnThis()
queryBuilder.orderBy = jest.fn().mockReturnThis()
queryBuilder.getMany = jest.fn().mockReturnValue([revision])
const result = await createRepository().findByItemId({ itemUuid: '123', afterDate: new Date(2) })
expect(queryBuilder.where).toHaveBeenCalledWith('revision.item_uuid = :item_uuid', { item_uuid: '123' })
expect(queryBuilder.andWhere).toHaveBeenCalledWith('revision.creation_date >= :after_date', {
after_date: new Date(2),
})
expect(queryBuilder.orderBy).toHaveBeenCalledWith('revision.created_at', 'DESC')
expect(result).toEqual([revision])
})
it('should find one revision by id and item id', async () => {
queryBuilder.where = jest.fn().mockReturnThis()
queryBuilder.getOne = jest.fn().mockReturnValue(revision)
const result = await createRepository().findOneById('123', '234')
expect(queryBuilder.where).toHaveBeenCalledWith('revision.uuid = :uuid AND revision.item_uuid = :item_uuid', {
uuid: '234',
item_uuid: '123',
})
expect(result).toEqual(revision)
})
})

View File

@@ -1,7 +1,11 @@
/* istanbul ignore file */
import { UniqueEntityId } from '@standardnotes/domain-core'
import { inject, injectable } from 'inversify'
import { Repository } from 'typeorm'
import TYPES from '../../Bootstrap/Types'
import { Revision } from '../../Domain/Revision/Revision'
import { RevisionMetadata } from '../../Domain/Revision/RevisionMetadata'
import { RevisionRepositoryInterface } from '../../Domain/Revision/RevisionRepositoryInterface'
@injectable()
@@ -36,6 +40,40 @@ export class MySQLRevisionRepository implements RevisionRepositoryInterface {
return queryBuilder.orderBy('revision.created_at', 'DESC').getMany()
}
async findMetadataByItemId(itemUuid: string): Promise<Array<RevisionMetadata>> {
const queryBuilder = this.ormRepository
.createQueryBuilder()
.select('uuid', 'uuid')
.addSelect('content_type', 'contentType')
.addSelect('created_at', 'createdAt')
.addSelect('updated_at', 'updatedAt')
.where('item_uuid = :item_uuid', {
item_uuid: itemUuid,
})
const simplifiedRevisions = await queryBuilder.orderBy('created_at', 'DESC').getRawMany()
const metadata = []
for (const simplifiedRevision of simplifiedRevisions) {
const revisionMetadataOrError = RevisionMetadata.create(
{
contentType: simplifiedRevision.contentType,
updatedAt: simplifiedRevision.updatedAt,
createdAt: simplifiedRevision.createdAt,
},
new UniqueEntityId(simplifiedRevision.uuid),
)
if (revisionMetadataOrError.isFailed()) {
throw new Error(revisionMetadataOrError.getError())
}
metadata.push(revisionMetadataOrError.getValue())
}
return metadata
}
async findOneById(itemId: string, id: string): Promise<Revision | null> {
return this.ormRepository
.createQueryBuilder('revision')

View File

@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.14.0](https://github.com/standardnotes/server/compare/@standardnotes/time@1.13.3...@standardnotes/time@1.14.0) (2022-11-14)
### Features
* **analytics:** extract domain core into a separate package ([0f94e2a](https://github.com/standardnotes/server/commit/0f94e2ad0c8927733eac31f130cbe649dce765f9))
## [1.13.3](https://github.com/standardnotes/server/compare/@standardnotes/time@1.13.0...@standardnotes/time@1.13.3) (2022-11-14)
### Bug Fixes

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