mirror of
https://github.com/standardnotes/server
synced 2026-01-17 05:04:27 -05:00
Compare commits
16 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e82be47ed | ||
|
|
15dfd6dcba | ||
|
|
dfd38943b0 | ||
|
|
500756d582 | ||
|
|
f855f541d8 | ||
|
|
590ec6643d | ||
|
|
b9efd35b50 | ||
|
|
3be1bfe58a | ||
|
|
bfbd2de778 | ||
|
|
50f7ae338a | ||
|
|
280fdc89c1 | ||
|
|
0f94e2ad0c | ||
|
|
d0036600e9 | ||
|
|
f766fefbf0 | ||
|
|
2178ed2a31 | ||
|
|
79511aea5f |
39
.pnp.cjs
generated
39
.pnp.cjs
generated
@@ -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"],\
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Uuid } from '../Common/Uuid'
|
||||
import { Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { RevenueModification } from './RevenueModification'
|
||||
|
||||
export interface RevenueModificationRepositoryInterface {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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>>
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Email } from '../Common/Email'
|
||||
import { Email } from '@standardnotes/domain-core'
|
||||
|
||||
import { User } from './User'
|
||||
|
||||
describe('User', () => {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Email } from '../Common/Email'
|
||||
import { Email } from '@standardnotes/domain-core'
|
||||
|
||||
export interface UserProps {
|
||||
email: Email
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.38.4",
|
||||
"version": "1.38.5",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -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
|
||||
|
||||
74
packages/auth/bin/content.ts
Normal file
74
packages/auth/bin/content.ts
Normal 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)
|
||||
})
|
||||
})
|
||||
@@ -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"
|
||||
;;
|
||||
|
||||
@@ -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/*'"
|
||||
|
||||
@@ -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',
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
1
packages/domain-core/.eslintignore
Normal file
1
packages/domain-core/.eslintignore
Normal file
@@ -0,0 +1 @@
|
||||
dist
|
||||
6
packages/domain-core/.eslintrc
Normal file
6
packages/domain-core/.eslintrc
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "../../.eslintrc",
|
||||
"parserOptions": {
|
||||
"project": "./linter.tsconfig.json"
|
||||
}
|
||||
}
|
||||
16
packages/domain-core/CHANGELOG.md
Normal file
16
packages/domain-core/CHANGELOG.md
Normal 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))
|
||||
10
packages/domain-core/jest.config.js
Normal file
10
packages/domain-core/jest.config.js
Normal 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,
|
||||
},
|
||||
}
|
||||
4
packages/domain-core/linter.tsconfig.json
Normal file
4
packages/domain-core/linter.tsconfig.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"exclude": ["dist"]
|
||||
}
|
||||
43
packages/domain-core/package.json
Normal file
43
packages/domain-core/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
export interface MapInterface<T, U> {
|
||||
toDomain(persistence: U): T
|
||||
toPersistence(domain: T): U
|
||||
toProjection(domain: T): U
|
||||
}
|
||||
14
packages/domain-core/src/Domain/index.ts
Normal file
14
packages/domain-core/src/Domain/index.ts
Normal 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'
|
||||
1
packages/domain-core/src/index.ts
Normal file
1
packages/domain-core/src/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './Domain'
|
||||
11
packages/domain-core/tsconfig.json
Normal file
11
packages/domain-core/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"outDir": "./dist",
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"references": []
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:*",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/files-server",
|
||||
"version": "1.8.21",
|
||||
"version": "1.8.22",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/scheduler-server",
|
||||
"version": "1.13.22",
|
||||
"version": "1.13.23",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <19.0.0"
|
||||
},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface RevisionMetadataProps {
|
||||
contentType: string | null
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
}
|
||||
@@ -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>>
|
||||
}
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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[]
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
@@ -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')
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user