Compare commits

..

6 Commits

Author SHA1 Message Date
standardci
a8795defc1 chore(release): publish new version
- @standardnotes/api-gateway@1.4.1
 - @standardnotes/auth-server@1.5.0
 - @standardnotes/domain-events-infra@1.7.2
 - @standardnotes/domain-events@2.37.0
 - @standardnotes/files-server@1.1.13
 - @standardnotes/predicates@1.1.0
 - @standardnotes/scheduler-server@1.3.0
 - @standardnotes/syncing-server@1.2.1
2022-07-06 08:52:19 +00:00
Karol Sójko
1b35cf7a39 fix: scheduler to predicates imports 2022-07-06 10:51:02 +02:00
Karol Sójko
ed62ed516f feat: add predicates package 2022-07-06 10:49:22 +02:00
standardci
b4f1c6f7f8 chore(release): publish new version
- @standardnotes/analytics@1.8.0
 - @standardnotes/api-gateway@1.4.0
 - @standardnotes/auth-server@1.4.0
 - @standardnotes/domain-events-infra@1.7.1
 - @standardnotes/domain-events@2.36.0
 - @standardnotes/files-server@1.1.12
 - @standardnotes/scheduler-server@1.2.7
 - @standardnotes/syncing-server@1.2.0
2022-07-06 08:37:46 +00:00
Karol Sójko
14e4ca70b4 feat: add analytics package 2022-07-06 10:36:32 +02:00
Karol Sójko
12fa94539b fix: build process due to composite packages 2022-07-06 10:29:06 +02:00
78 changed files with 1394 additions and 366 deletions

View File

@@ -32,7 +32,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Build locally
run: yarn build:api-gateway
run: yarn build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
@@ -62,7 +62,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Build locally
run: yarn build:api-gateway
run: yarn build
- name: Login to Docker Hub
uses: docker/login-action@v2
with:

View File

@@ -33,7 +33,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Build locally
run: yarn build:auth
run: yarn build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
@@ -63,7 +63,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Build locally
run: yarn build:auth
run: yarn build
- name: Login to Docker Hub
uses: docker/login-action@v2
with:

View File

@@ -33,7 +33,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Build locally
run: yarn build:files
run: yarn build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
@@ -63,7 +63,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Build locally
run: yarn build:files
run: yarn build
- name: Login to Docker Hub
uses: docker/login-action@v2
with:

View File

@@ -33,7 +33,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Build locally
run: yarn build:scheduler
run: yarn build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
@@ -63,7 +63,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Build locally
run: yarn build:scheduler
run: yarn build
- name: Login to Docker Hub
uses: docker/login-action@v2
with:

View File

@@ -33,7 +33,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Build locally
run: yarn build:syncing-server
run: yarn build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
@@ -63,7 +63,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Build locally
run: yarn build:syncing-server
run: yarn build
- name: Login to Docker Hub
uses: docker/login-action@v2
with:

618
.pnp.cjs generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
dist

View File

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

View File

@@ -0,0 +1,92 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# 1.8.0 (2022-07-06)
### Features
* add analytics package ([14e4ca7](https://github.com/standardnotes/server/commit/14e4ca70b438dd3eaaa404bc0ca31d22a62b45be))
## [1.6.1](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.6.0...@standardnotes/analytics@1.6.1) (2022-07-04)
### Bug Fixes
* add missing reflect-metadata package to all packages ([ce3a5bb](https://github.com/standardnotes/snjs/commit/ce3a5bbf3f1d2276ac4abc3eec3c6a44c8c3ba9b))
# [1.6.0](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.5.0...@standardnotes/analytics@1.6.0) (2022-06-02)
### Features
* refactor analytics store to handle different periods of time ([00d4f3f](https://github.com/standardnotes/snjs/commit/00d4f3f2f742b0deb5ef4cd415c672574cb3a911))
# [1.5.0](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.4.1...@standardnotes/analytics@1.5.0) (2022-06-01)
### Features
* add unmarking activities ([09cea1d](https://github.com/standardnotes/snjs/commit/09cea1d8e97dd83f2eaafaef5ff680aef8c5c3ff))
## [1.4.1](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.4.0...@standardnotes/analytics@1.4.1) (2022-06-01)
### Bug Fixes
* rename analytics activity backup to email backup ([30d2db6](https://github.com/standardnotes/snjs/commit/30d2db63e5dec05b3f0976211c661d8aa0e04139))
# [1.4.0](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.3.1...@standardnotes/analytics@1.4.0) (2022-06-01)
### Features
* add calculating total counts of activites in analytics ([6ed659a](https://github.com/standardnotes/snjs/commit/6ed659a7c4411ce2555e4af96dc5473c3d03fd41))
## [1.3.1](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.3.0...@standardnotes/analytics@1.3.1) (2022-05-26)
### Bug Fixes
* add backup analytics activity ([cf7ae68](https://github.com/standardnotes/snjs/commit/cf7ae68e13aa9403702340da8a3bca35e9273784))
# [1.3.0](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.2.0...@standardnotes/analytics@1.3.0) (2022-05-26)
### Features
* add calculating activity retention in analytics ([bc2f26d](https://github.com/standardnotes/snjs/commit/bc2f26d63a8ff0e2750b37bc1ee56297f6a8c98d))
# [1.2.0](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.1.0...@standardnotes/analytics@1.2.0) (2022-05-26)
### Features
* add activity indicators in analytics ([e6f5b5a](https://github.com/standardnotes/snjs/commit/e6f5b5afbff1f5f96adfcba42f4708fa74ac7f80))
# [1.1.0](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.0.7...@standardnotes/analytics@1.1.0) (2022-05-24)
### Features
* add marking activity in analytics ([#750](https://github.com/standardnotes/snjs/issues/750)) ([2a68fa6](https://github.com/standardnotes/snjs/commit/2a68fa6636c24e79443359d31a8427d50ca87cca))
## [1.0.7](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.0.5...@standardnotes/analytics@1.0.7) (2022-05-04)
**Note:** Version bump only for package @standardnotes/analytics
## [1.0.6](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.0.5...@standardnotes/analytics@1.0.6) (2022-05-04)
**Note:** Version bump only for package @standardnotes/analytics
## [1.0.5](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.0.4...@standardnotes/analytics@1.0.5) (2022-04-22)
**Note:** Version bump only for package @standardnotes/analytics
## [1.0.4](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.0.3...@standardnotes/analytics@1.0.4) (2022-04-15)
**Note:** Version bump only for package @standardnotes/analytics
## [1.0.3](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.0.2...@standardnotes/analytics@1.0.3) (2022-04-11)
**Note:** Version bump only for package @standardnotes/analytics
## [1.0.2](https://github.com/standardnotes/snjs/compare/@standardnotes/analytics@1.0.1...@standardnotes/analytics@1.0.2) (2022-03-31)
**Note:** Version bump only for package @standardnotes/analytics
## 1.0.1 (2022-03-10)
**Note:** Version bump only for package @standardnotes/analytics

View File

@@ -0,0 +1,11 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const base = require('../../jest.config');
module.exports = {
...base,
globals: {
'ts-jest': {
tsconfig: 'tsconfig.json',
},
},
};

View File

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

View File

@@ -0,0 +1,39 @@
{
"name": "@standardnotes/analytics",
"version": "1.8.0",
"engines": {
"node": ">=14.0.0 <17.0.0"
},
"description": "Analytics tools for Standard Notes projects",
"main": "dist/src/index.js",
"author": "Standard Notes",
"types": "dist/src/index.d.ts",
"files": [
"dist/src"
],
"publishConfig": {
"access": "public"
},
"license": "AGPL-3.0-or-later",
"scripts": {
"clean": "rm -fr dist",
"prestart": "yarn clean",
"start": "tsc -p tsconfig.json --watch",
"prebuild": "yarn clean",
"build": "tsc -p tsconfig.json",
"lint": "eslint . --ext .ts",
"test:unit": "jest spec --coverage"
},
"devDependencies": {
"@types/ioredis": "^4.28.8",
"@types/jest": "^27.4.1",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"eslint-plugin-prettier": "^4.2.1",
"ioredis": "^4.28.5",
"jest": "^27.5.1",
"ts-jest": "^27.1.3"
},
"dependencies": {
"reflect-metadata": "^0.1.13"
}
}

View File

@@ -0,0 +1,6 @@
export enum AnalyticsActivity {
EditingItems = 'editing-items',
Login = 'login',
EmailUnbackedUpData = 'email-unbacked-up-data',
EmailBackup = 'email-backup',
}

View File

@@ -0,0 +1,10 @@
import { Period } from '../Time/Period'
import { AnalyticsActivity } from './AnalyticsActivity'
export interface AnalyticsStoreInterface {
unmarkActivity(activities: AnalyticsActivity[], analyticsId: number, periods: Period[]): Promise<void>
markActivity(activities: AnalyticsActivity[], analyticsId: number, periods: Period[]): Promise<void>
wasActivityDone(activity: AnalyticsActivity, analyticsId: number, period: Period): Promise<boolean>
calculateActivityRetention(activity: AnalyticsActivity, firstPeriod: Period, secondPeriod: Period): Promise<number>
calculateActivityTotalCount(activity: AnalyticsActivity, period: Period): Promise<number>
}

View File

@@ -0,0 +1,8 @@
export interface StatisticsStoreInterface {
incrementSNJSVersionUsage(snjsVersion: string): Promise<void>
incrementApplicationVersionUsage(applicationVersion: string): Promise<void>
incrementOutOfSyncIncidents(): Promise<void>
getYesterdaySNJSUsage(): Promise<Array<{ version: string; count: number }>>
getYesterdayApplicationUsage(): Promise<Array<{ version: string; count: number }>>
getYesterdayOutOfSyncIncidents(): Promise<number>
}

View File

@@ -0,0 +1,10 @@
export enum Period {
Today,
Yesterday,
DayBeforeYesterday,
ThisWeek,
LastWeek,
WeekBeforeLastWeek,
ThisMonth,
LastMonth,
}

View File

@@ -0,0 +1,58 @@
import { Period } from './Period'
import { PeriodKeyGenerator } from './PeriodKeyGenerator'
describe('PeriodKeyGenerator', () => {
const createGenerator = () => new PeriodKeyGenerator()
beforeEach(() => {
jest.useFakeTimers('modern')
jest.setSystemTime(1653395155000)
})
afterEach(() => {
jest.useRealTimers()
})
it('should generate a period key for today', () => {
expect(createGenerator().getPeriodKey(Period.Today)).toEqual('2022-5-24')
})
it('should generate a period key for yesterday', () => {
expect(createGenerator().getPeriodKey(Period.Yesterday)).toEqual('2022-5-23')
})
it('should generate a period key for the day before yesterday', () => {
expect(createGenerator().getPeriodKey(Period.DayBeforeYesterday)).toEqual('2022-5-22')
})
it('should generate a period key for this week', () => {
expect(createGenerator().getPeriodKey(Period.ThisWeek)).toEqual('2022-week-21')
})
it('should generate a period key for last week', () => {
expect(createGenerator().getPeriodKey(Period.LastWeek)).toEqual('2022-week-20')
})
it('should generate a period key for the week before last week', () => {
expect(createGenerator().getPeriodKey(Period.WeekBeforeLastWeek)).toEqual('2022-week-19')
})
it('should generate a period key for this month', () => {
expect(createGenerator().getPeriodKey(Period.ThisMonth)).toEqual('2022-5')
})
it('should generate a period key for last month', () => {
expect(createGenerator().getPeriodKey(Period.LastMonth)).toEqual('2022-4')
})
it('should throw error on unsupported period', () => {
let error = null
try {
createGenerator().getPeriodKey(42 as Period)
} catch (caughtError) {
error = caughtError
}
expect(error).not.toBeNull()
})
})

View File

@@ -0,0 +1,99 @@
import { Period } from './Period'
import { PeriodKeyGeneratorInterface } from './PeriodKeyGeneratorInterface'
export class PeriodKeyGenerator implements PeriodKeyGeneratorInterface {
getPeriodKey(period: Period): string {
switch (period) {
case Period.Today:
return this.getDailyKey()
case Period.Yesterday:
return this.getDailyKey(this.getYesterdayDate())
case Period.DayBeforeYesterday:
return this.getDailyKey(this.getDayBeforeYesterdayDate())
case Period.ThisWeek:
return this.getWeeklyKey()
case Period.LastWeek:
return this.getWeeklyKey(this.getLastWeekDate())
case Period.WeekBeforeLastWeek:
return this.getWeeklyKey(this.getWeekBeforeLastWeekDate())
case Period.ThisMonth:
return this.getMonthlyKey()
case Period.LastMonth:
return this.getMonthlyKey(this.getLastMonthDate())
default:
throw new Error(`Unsuporrted period: ${period}`)
}
}
private getMonthlyKey(date?: Date): string {
date = date ?? new Date()
return `${this.getYear(date)}-${this.getMonth(date)}`
}
private getDailyKey(date?: Date): string {
date = date ?? new Date()
return `${this.getYear(date)}-${this.getMonth(date)}-${this.getDayOfTheMonth(date)}`
}
private getWeeklyKey(date?: Date): string {
date = date ?? new Date()
const firstJanuary = new Date(date.getFullYear(), 0, 1)
const numberOfDaysPassed = Math.floor((date.getTime() - firstJanuary.getTime()) / (24 * 60 * 60 * 1000))
const weekNumber = Math.ceil((date.getDay() + 1 + numberOfDaysPassed) / 7)
return `${this.getYear(date)}-week-${weekNumber}`
}
private getYear(date: Date): string {
return date.getFullYear().toString()
}
private getMonth(date: Date): string {
return (date.getMonth() + 1).toString()
}
private getDayOfTheMonth(date: Date): string {
return date.getDate().toString()
}
private getYesterdayDate(): Date {
const yesterday = new Date()
yesterday.setDate(new Date().getDate() - 1)
return yesterday
}
private getDayBeforeYesterdayDate(): Date {
const dayBeforeYesterday = new Date()
dayBeforeYesterday.setDate(new Date().getDate() - 2)
return dayBeforeYesterday
}
private getLastWeekDate(): Date {
const yesterday = new Date()
yesterday.setDate(new Date().getDate() - 7)
return yesterday
}
private getLastMonthDate(): Date {
const lastMonth = new Date()
lastMonth.setDate(1)
lastMonth.setMonth(lastMonth.getMonth() - 1)
return lastMonth
}
private getWeekBeforeLastWeekDate(): Date {
const yesterday = new Date()
yesterday.setDate(new Date().getDate() - 14)
return yesterday
}
}

View File

@@ -0,0 +1,5 @@
import { Period } from './Period'
export interface PeriodKeyGeneratorInterface {
getPeriodKey(period: Period): string
}

View File

@@ -0,0 +1,6 @@
export * from './Analytics/AnalyticsActivity'
export * from './Analytics/AnalyticsStoreInterface'
export * from './Statistics/StatisticsStoreInterface'
export * from './Time/Period'
export * from './Time/PeriodKeyGenerator'
export * from './Time/PeriodKeyGeneratorInterface'

View File

@@ -0,0 +1,131 @@
import * as IORedis from 'ioredis'
import { Period } from '../../Domain'
import { AnalyticsActivity } from '../../Domain/Analytics/AnalyticsActivity'
import { PeriodKeyGeneratorInterface } from '../../Domain/Time/PeriodKeyGeneratorInterface'
import { RedisAnalyticsStore } from './RedisAnalyticsStore'
describe('RedisAnalyticsStore', () => {
let redisClient: IORedis.Redis
let pipeline: IORedis.Pipeline
let periodKeyGenerator: PeriodKeyGeneratorInterface
const createStore = () => new RedisAnalyticsStore(periodKeyGenerator, redisClient)
beforeEach(() => {
pipeline = {} as jest.Mocked<IORedis.Pipeline>
pipeline.incr = jest.fn()
pipeline.setbit = jest.fn()
pipeline.exec = jest.fn()
redisClient = {} as jest.Mocked<IORedis.Redis>
redisClient.pipeline = jest.fn().mockReturnValue(pipeline)
redisClient.incr = jest.fn()
redisClient.setbit = jest.fn()
redisClient.getbit = jest.fn().mockReturnValue(1)
redisClient.send_command = jest.fn()
periodKeyGenerator = {} as jest.Mocked<PeriodKeyGeneratorInterface>
periodKeyGenerator.getPeriodKey = jest.fn().mockReturnValue('period-key')
})
it('should calculate total count of activities', async () => {
redisClient.bitcount = jest.fn().mockReturnValue(70)
expect(await createStore().calculateActivityTotalCount(AnalyticsActivity.EditingItems, Period.Yesterday)).toEqual(
70,
)
expect(redisClient.bitcount).toHaveBeenCalledWith('bitmap:action:editing-items:timespan:period-key')
})
it('should calculate activity retention', async () => {
redisClient.bitcount = jest.fn().mockReturnValueOnce(7).mockReturnValueOnce(10)
expect(
await createStore().calculateActivityRetention(
AnalyticsActivity.EditingItems,
Period.DayBeforeYesterday,
Period.Yesterday,
),
).toEqual(70)
expect(redisClient.send_command).toHaveBeenCalledWith(
'BITOP',
'AND',
'bitmap:action:editing-items:timespan:period-key-period-key',
'bitmap:action:editing-items:timespan:period-key',
'bitmap:action:editing-items:timespan:period-key',
)
})
it('shoud tell if activity was done', async () => {
await createStore().wasActivityDone(AnalyticsActivity.EditingItems, 123, Period.Yesterday)
expect(redisClient.getbit).toHaveBeenCalledWith('bitmap:action:editing-items:timespan:period-key', 123)
})
it('should mark activity as done', async () => {
await createStore().markActivity([AnalyticsActivity.EditingItems], 123, [Period.Today])
expect(pipeline.setbit).toBeCalledTimes(1)
expect(pipeline.setbit).toHaveBeenNthCalledWith(1, 'bitmap:action:editing-items:timespan:period-key', 123, 1)
expect(pipeline.exec).toHaveBeenCalled()
})
it('should mark activities as done', async () => {
await createStore().markActivity([AnalyticsActivity.EditingItems, AnalyticsActivity.EmailUnbackedUpData], 123, [
Period.Today,
Period.ThisWeek,
])
expect(pipeline.setbit).toBeCalledTimes(4)
expect(pipeline.setbit).toHaveBeenNthCalledWith(1, 'bitmap:action:editing-items:timespan:period-key', 123, 1)
expect(pipeline.setbit).toHaveBeenNthCalledWith(2, 'bitmap:action:editing-items:timespan:period-key', 123, 1)
expect(pipeline.setbit).toHaveBeenNthCalledWith(
3,
'bitmap:action:email-unbacked-up-data:timespan:period-key',
123,
1,
)
expect(pipeline.setbit).toHaveBeenNthCalledWith(
4,
'bitmap:action:email-unbacked-up-data:timespan:period-key',
123,
1,
)
expect(pipeline.exec).toHaveBeenCalled()
})
it('should unmark activity as done', async () => {
await createStore().unmarkActivity([AnalyticsActivity.EditingItems], 123, [Period.Today])
expect(pipeline.setbit).toBeCalledTimes(1)
expect(pipeline.setbit).toHaveBeenNthCalledWith(1, 'bitmap:action:editing-items:timespan:period-key', 123, 0)
expect(pipeline.exec).toHaveBeenCalled()
})
it('should unmark activities as done', async () => {
await createStore().unmarkActivity([AnalyticsActivity.EditingItems, AnalyticsActivity.EmailUnbackedUpData], 123, [
Period.Today,
Period.ThisWeek,
])
expect(pipeline.setbit).toBeCalledTimes(4)
expect(pipeline.setbit).toHaveBeenNthCalledWith(1, 'bitmap:action:editing-items:timespan:period-key', 123, 0)
expect(pipeline.setbit).toHaveBeenNthCalledWith(2, 'bitmap:action:editing-items:timespan:period-key', 123, 0)
expect(pipeline.setbit).toHaveBeenNthCalledWith(
3,
'bitmap:action:email-unbacked-up-data:timespan:period-key',
123,
0,
)
expect(pipeline.setbit).toHaveBeenNthCalledWith(
4,
'bitmap:action:email-unbacked-up-data:timespan:period-key',
123,
0,
)
expect(pipeline.exec).toHaveBeenCalled()
})
})

View File

@@ -0,0 +1,84 @@
import * as IORedis from 'ioredis'
import { Period } from '../../Domain/Time/Period'
import { PeriodKeyGeneratorInterface } from '../../Domain/Time/PeriodKeyGeneratorInterface'
import { AnalyticsActivity } from '../../Domain/Analytics/AnalyticsActivity'
import { AnalyticsStoreInterface } from '../../Domain/Analytics/AnalyticsStoreInterface'
export class RedisAnalyticsStore implements AnalyticsStoreInterface {
constructor(private periodKeyGenerator: PeriodKeyGeneratorInterface, private redisClient: IORedis.Redis) {}
async markActivity(activities: AnalyticsActivity[], analyticsId: number, periods: Period[]): Promise<void> {
const pipeline = this.redisClient.pipeline()
for (const activity of activities) {
for (const period of periods) {
pipeline.setbit(
`bitmap:action:${activity}:timespan:${this.periodKeyGenerator.getPeriodKey(period)}`,
analyticsId,
1,
)
}
}
await pipeline.exec()
}
async unmarkActivity(activities: AnalyticsActivity[], analyticsId: number, periods: Period[]): Promise<void> {
const pipeline = this.redisClient.pipeline()
for (const activity of activities) {
for (const period of periods) {
pipeline.setbit(
`bitmap:action:${activity}:timespan:${this.periodKeyGenerator.getPeriodKey(period)}`,
analyticsId,
0,
)
}
}
await pipeline.exec()
}
async wasActivityDone(activity: AnalyticsActivity, analyticsId: number, period: Period): Promise<boolean> {
const bitValue = await this.redisClient.getbit(
`bitmap:action:${activity}:timespan:${this.periodKeyGenerator.getPeriodKey(period)}`,
analyticsId,
)
return bitValue === 1
}
async calculateActivityRetention(
activity: AnalyticsActivity,
firstPeriod: Period,
secondPeriod: Period,
): Promise<number> {
const initialPeriodKey = this.periodKeyGenerator.getPeriodKey(firstPeriod)
const subsequentPeriodKey = this.periodKeyGenerator.getPeriodKey(secondPeriod)
const diffKey = `bitmap:action:${activity}:timespan:${initialPeriodKey}-${subsequentPeriodKey}`
await this.redisClient.send_command(
'BITOP',
'AND',
diffKey,
`bitmap:action:${activity}:timespan:${initialPeriodKey}`,
`bitmap:action:${activity}:timespan:${subsequentPeriodKey}`,
)
const retainedTotalInActivity = await this.redisClient.bitcount(diffKey)
const initialTotalInActivity = await this.redisClient.bitcount(
`bitmap:action:${activity}:timespan:${initialPeriodKey}`,
)
return Math.ceil((retainedTotalInActivity * 100) / initialTotalInActivity)
}
async calculateActivityTotalCount(activity: AnalyticsActivity, period: Period): Promise<number> {
return this.redisClient.bitcount(
`bitmap:action:${activity}:timespan:${this.periodKeyGenerator.getPeriodKey(period)}`,
)
}
}

View File

@@ -0,0 +1,92 @@
import * as IORedis from 'ioredis'
import { PeriodKeyGeneratorInterface } from '../../Domain'
import { RedisStatisticsStore } from './RedisStatisticsStore'
describe('RedisStatisticsStore', () => {
let redisClient: IORedis.Redis
let periodKeyGenerator: PeriodKeyGeneratorInterface
let pipeline: IORedis.Pipeline
const createStore = () => new RedisStatisticsStore(periodKeyGenerator, redisClient)
beforeEach(() => {
pipeline = {} as jest.Mocked<IORedis.Pipeline>
pipeline.incr = jest.fn()
pipeline.setbit = jest.fn()
pipeline.exec = jest.fn()
redisClient = {} as jest.Mocked<IORedis.Redis>
redisClient.pipeline = jest.fn().mockReturnValue(pipeline)
redisClient.incr = jest.fn()
redisClient.setbit = jest.fn()
redisClient.getbit = jest.fn().mockReturnValue(1)
redisClient.send_command = jest.fn()
periodKeyGenerator = {} as jest.Mocked<PeriodKeyGeneratorInterface>
periodKeyGenerator.getPeriodKey = jest.fn().mockReturnValue('period-key')
})
it('should get yesterday out of sync incidents', async () => {
redisClient.get = jest.fn().mockReturnValue(1)
expect(await createStore().getYesterdayOutOfSyncIncidents()).toEqual(1)
})
it('should default to 0 yesterday out of sync incidents', async () => {
redisClient.get = jest.fn().mockReturnValue(null)
expect(await createStore().getYesterdayOutOfSyncIncidents()).toEqual(0)
})
it('should get yesterday application version usage', async () => {
redisClient.keys = jest
.fn()
.mockReturnValue([
'count:action:application-request:1.2.3:timespan:2022-3-10',
'count:action:application-request:2.3.4:timespan:2022-3-10',
])
redisClient.get = jest.fn().mockReturnValueOnce(3).mockReturnValueOnce(4)
expect(await createStore().getYesterdayApplicationUsage()).toEqual([
{ count: 3, version: '1.2.3' },
{ count: 4, version: '2.3.4' },
])
})
it('should get yesterday snjs version usage', async () => {
redisClient.keys = jest
.fn()
.mockReturnValue([
'count:action:snjs-request:1.2.3:timespan:2022-3-10',
'count:action:snjs-request:2.3.4:timespan:2022-3-10',
])
redisClient.get = jest.fn().mockReturnValueOnce(3).mockReturnValueOnce(4)
expect(await createStore().getYesterdaySNJSUsage()).toEqual([
{ count: 3, version: '1.2.3' },
{ count: 4, version: '2.3.4' },
])
})
it('should increment application version usage', async () => {
await createStore().incrementApplicationVersionUsage('1.2.3')
expect(pipeline.incr).toHaveBeenCalled()
expect(pipeline.exec).toHaveBeenCalled()
})
it('should increment snjs version usage', async () => {
await createStore().incrementSNJSVersionUsage('1.2.3')
expect(pipeline.incr).toHaveBeenCalled()
expect(pipeline.exec).toHaveBeenCalled()
})
it('should increment out of sync incedent count', async () => {
await createStore().incrementOutOfSyncIncidents()
expect(pipeline.incr).toHaveBeenCalled()
expect(pipeline.exec).toHaveBeenCalled()
})
})

View File

@@ -0,0 +1,99 @@
import * as IORedis from 'ioredis'
import { Period, PeriodKeyGeneratorInterface } from '../../Domain'
import { StatisticsStoreInterface } from '../../Domain/Statistics/StatisticsStoreInterface'
export class RedisStatisticsStore implements StatisticsStoreInterface {
constructor(private periodKeyGenerator: PeriodKeyGeneratorInterface, private redisClient: IORedis.Redis) {}
async getYesterdayOutOfSyncIncidents(): Promise<number> {
const count = await this.redisClient.get(
`count:action:out-of-sync:timespan:${this.periodKeyGenerator.getPeriodKey(Period.Yesterday)}`,
)
if (count === null) {
return 0
}
return +count
}
async incrementOutOfSyncIncidents(): Promise<void> {
const pipeline = this.redisClient.pipeline()
pipeline.incr(`count:action:out-of-sync:timespan:${this.periodKeyGenerator.getPeriodKey(Period.Today)}`)
pipeline.incr(`count:action:out-of-sync:timespan:${this.periodKeyGenerator.getPeriodKey(Period.ThisWeek)}`)
pipeline.incr(`count:action:out-of-sync:timespan:${this.periodKeyGenerator.getPeriodKey(Period.ThisMonth)}`)
await pipeline.exec()
}
async getYesterdaySNJSUsage(): Promise<{ version: string; count: number }[]> {
const keys = await this.redisClient.keys(
`count:action:snjs-request:*:timespan:${this.periodKeyGenerator.getPeriodKey(Period.Yesterday)}`,
)
return this.getRequestCountPerVersion(keys)
}
async getYesterdayApplicationUsage(): Promise<{ version: string; count: number }[]> {
const keys = await this.redisClient.keys(
`count:action:application-request:*:timespan:${this.periodKeyGenerator.getPeriodKey(Period.Yesterday)}`,
)
return this.getRequestCountPerVersion(keys)
}
async incrementApplicationVersionUsage(applicationVersion: string): Promise<void> {
const pipeline = this.redisClient.pipeline()
pipeline.incr(
`count:action:application-request:${applicationVersion}:timespan:${this.periodKeyGenerator.getPeriodKey(
Period.Today,
)}`,
)
pipeline.incr(
`count:action:application-request:${applicationVersion}:timespan:${this.periodKeyGenerator.getPeriodKey(
Period.ThisWeek,
)}`,
)
pipeline.incr(
`count:action:application-request:${applicationVersion}:timespan:${this.periodKeyGenerator.getPeriodKey(
Period.ThisMonth,
)}`,
)
await pipeline.exec()
}
async incrementSNJSVersionUsage(snjsVersion: string): Promise<void> {
const pipeline = this.redisClient.pipeline()
pipeline.incr(
`count:action:snjs-request:${snjsVersion}:timespan:${this.periodKeyGenerator.getPeriodKey(Period.Today)}`,
)
pipeline.incr(
`count:action:snjs-request:${snjsVersion}:timespan:${this.periodKeyGenerator.getPeriodKey(Period.ThisWeek)}`,
)
pipeline.incr(
`count:action:snjs-request:${snjsVersion}:timespan:${this.periodKeyGenerator.getPeriodKey(Period.ThisMonth)}`,
)
await pipeline.exec()
}
private async getRequestCountPerVersion(keys: string[]): Promise<{ version: string; count: number }[]> {
const statistics = []
for (const key of keys) {
const count = await this.redisClient.get(key)
const version = key.split(':')[3]
statistics.push({
version,
count: +(count as string),
})
}
return statistics
}
}

View File

@@ -0,0 +1,2 @@
export * from './Redis/RedisAnalyticsStore'
export * from './Redis/RedisStatisticsStore'

View File

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

View File

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

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.4.1](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.4.0...@standardnotes/api-gateway@1.4.1) (2022-07-06)
**Note:** Version bump only for package @standardnotes/api-gateway
# [1.4.0](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.3.5...@standardnotes/api-gateway@1.4.0) (2022-07-06)
### Features
* add analytics package ([14e4ca7](https://github.com/standardnotes/api-gateway/commit/14e4ca70b438dd3eaaa404bc0ca31d22a62b45be))
## [1.3.5](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.3.4...@standardnotes/api-gateway@1.3.5) (2022-07-06)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/api-gateway",
"version": "1.3.5",
"version": "1.4.1",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -24,7 +24,7 @@
"dependencies": {
"@newrelic/winston-enricher": "^2.1.0",
"@sentry/node": "^7.3.0",
"@standardnotes/analytics": "^1.6.0",
"@standardnotes/analytics": "workspace:*",
"@standardnotes/auth": "3.19.4",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.5.0](https://github.com/standardnotes/auth/compare/@standardnotes/auth-server@1.4.0...@standardnotes/auth-server@1.5.0) (2022-07-06)
### Bug Fixes
* scheduler to predicates imports ([1b35cf7](https://github.com/standardnotes/auth/commit/1b35cf7a392fbe6c4b49889f92ffab6ddd7bb181))
### Features
* add predicates package ([ed62ed5](https://github.com/standardnotes/auth/commit/ed62ed516f5cf8784975f41680366bf0518ce491))
# [1.4.0](https://github.com/standardnotes/auth/compare/@standardnotes/auth-server@1.3.14...@standardnotes/auth-server@1.4.0) (2022-07-06)
### Features
* add analytics package ([14e4ca7](https://github.com/standardnotes/auth/commit/14e4ca70b438dd3eaaa404bc0ca31d22a62b45be))
## [1.3.14](https://github.com/standardnotes/auth/compare/@standardnotes/auth-server@1.3.13...@standardnotes/auth-server@1.3.14) (2022-07-06)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/auth-server",
"version": "1.3.14",
"version": "1.5.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -33,15 +33,15 @@
"dependencies": {
"@newrelic/winston-enricher": "^2.1.0",
"@sentry/node": "^7.3.0",
"@standardnotes/analytics": "^1.6.0",
"@standardnotes/analytics": "workspace:*",
"@standardnotes/api": "^1.1.19",
"@standardnotes/auth": "^3.19.4",
"@standardnotes/common": "^1.23.1",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/features": "^1.47.0",
"@standardnotes/predicates": "workspace:*",
"@standardnotes/responses": "^1.6.39",
"@standardnotes/scheduler": "^1.1.2",
"@standardnotes/settings": "^1.15.0",
"@standardnotes/sncrypto-common": "^1.9.0",
"@standardnotes/sncrypto-node": "^1.8.3",

View File

@@ -1,7 +1,7 @@
import 'reflect-metadata'
import { EmailMessageIdentifier, RoleName } from '@standardnotes/common'
import { PredicateName, PredicateAuthority, PredicateVerificationResult } from '@standardnotes/scheduler'
import { PredicateName, PredicateAuthority, PredicateVerificationResult } from '@standardnotes/predicates'
import { TimerInterface } from '@standardnotes/time'
import { DomainEventFactory } from './DomainEventFactory'

View File

@@ -16,7 +16,7 @@ import {
DomainEventService,
EmailMessageRequestedEvent,
} from '@standardnotes/domain-events'
import { Predicate, PredicateVerificationResult } from '@standardnotes/scheduler'
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
import { TimerInterface } from '@standardnotes/time'
import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'

View File

@@ -1,5 +1,5 @@
import { Uuid, RoleName, EmailMessageIdentifier } from '@standardnotes/common'
import { Predicate, PredicateVerificationResult } from '@standardnotes/scheduler'
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
import {
AccountDeletionRequestedEvent,
CloudBackupRequestedEvent,

View File

@@ -7,7 +7,7 @@ import {
PredicateVerificationRequestedEventPayload,
PredicateVerifiedEvent,
} from '@standardnotes/domain-events'
import { Predicate, PredicateVerificationResult } from '@standardnotes/scheduler'
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
import { Logger } from 'winston'
import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface'

View File

@@ -1,6 +1,6 @@
import 'reflect-metadata'
import { PredicateName, PredicateVerificationResult, PredicateAuthority } from '@standardnotes/scheduler'
import { PredicateName, PredicateVerificationResult, PredicateAuthority } from '@standardnotes/predicates'
import { Setting } from '../../Setting/Setting'
import { SettingRepositoryInterface } from '../../Setting/SettingRepositoryInterface'

View File

@@ -1,5 +1,5 @@
import { Uuid } from '@standardnotes/common'
import { PredicateName, PredicateVerificationResult } from '@standardnotes/scheduler'
import { PredicateName, PredicateVerificationResult } from '@standardnotes/predicates'
import { EmailBackupFrequency, SettingName } from '@standardnotes/settings'
import { inject, injectable } from 'inversify'

View File

@@ -1,5 +1,5 @@
import { Uuid } from '@standardnotes/common'
import { Predicate } from '@standardnotes/scheduler'
import { Predicate } from '@standardnotes/predicates'
export type VerifyPredicateDTO = {
predicate: Predicate

View File

@@ -1,4 +1,4 @@
import { PredicateVerificationResult } from '@standardnotes/scheduler'
import { PredicateVerificationResult } from '@standardnotes/predicates'
export type VerifyPredicateResponse = {
predicateVerificationResult: PredicateVerificationResult

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.7.2](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.7.1...@standardnotes/domain-events-infra@1.7.2) (2022-07-06)
**Note:** Version bump only for package @standardnotes/domain-events-infra
## [1.7.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.7.0...@standardnotes/domain-events-infra@1.7.1) (2022-07-06)
**Note:** Version bump only for package @standardnotes/domain-events-infra
# 1.7.0 (2022-07-06)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events-infra",
"version": "1.7.0",
"version": "1.7.2",
"engines": {
"node": ">=16.0.0 <17.0.0"
},

View File

@@ -1,2 +1 @@
node_modules
dist

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [2.37.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.36.0...@standardnotes/domain-events@2.37.0) (2022-07-06)
### Bug Fixes
* scheduler to predicates imports ([1b35cf7](https://github.com/standardnotes/server/commit/1b35cf7a392fbe6c4b49889f92ffab6ddd7bb181))
### Features
* add predicates package ([ed62ed5](https://github.com/standardnotes/server/commit/ed62ed516f5cf8784975f41680366bf0518ce491))
# [2.36.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events@2.35.0...@standardnotes/domain-events@2.36.0) (2022-07-06)
### Features
* add analytics package ([14e4ca7](https://github.com/standardnotes/server/commit/14e4ca70b438dd3eaaa404bc0ca31d22a62b45be))
# 2.35.0 (2022-07-06)
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/domain-events",
"version": "2.35.0",
"version": "2.37.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -26,7 +26,7 @@
"@standardnotes/auth": "^3.19.4",
"@standardnotes/common": "^1.23.1",
"@standardnotes/features": "^1.47.0",
"@standardnotes/scheduler": "^1.1.2",
"@standardnotes/predicates": "workspace:*",
"reflect-metadata": "^0.1.13"
},
"devDependencies": {

View File

@@ -1,4 +1,4 @@
import { Predicate } from '@standardnotes/scheduler'
import { Predicate } from '@standardnotes/predicates'
export interface PredicateVerificationRequestedEventPayload {
predicate: Predicate

View File

@@ -1,4 +1,4 @@
import { Predicate, PredicateVerificationResult } from '@standardnotes/scheduler'
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
export interface PredicateVerifiedEventPayload {
predicate: Predicate

View File

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

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/files-server",
"version": "1.1.11",
"version": "1.1.13",
"engines": {
"node": ">=16.0.0 <17.0.0"
},

View File

@@ -0,0 +1 @@
dist

View File

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

View File

@@ -0,0 +1,30 @@
# 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.0 (2022-07-06)
### Features
* add predicates package ([ed62ed5](https://github.com/standardnotes/server/commit/ed62ed516f5cf8784975f41680366bf0518ce491))
## [1.1.3](https://github.com/standardnotes/snjs/compare/@standardnotes/scheduler@1.1.2...@standardnotes/scheduler@1.1.3) (2022-07-04)
### Bug Fixes
* add missing reflect-metadata package to all packages ([ce3a5bb](https://github.com/standardnotes/snjs/commit/ce3a5bbf3f1d2276ac4abc3eec3c6a44c8c3ba9b))
## [1.1.2](https://github.com/standardnotes/snjs/compare/@standardnotes/scheduler@1.1.1...@standardnotes/scheduler@1.1.2) (2022-06-27)
**Note:** Version bump only for package @standardnotes/scheduler
## [1.1.1](https://github.com/standardnotes/snjs/compare/@standardnotes/scheduler@1.1.0...@standardnotes/scheduler@1.1.1) (2022-06-15)
**Note:** Version bump only for package @standardnotes/scheduler
# 1.1.0 (2022-06-13)
### Features
* add scheduler package ([251a2b5](https://github.com/standardnotes/snjs/commit/251a2b57937c4fcf3d23efd71dd6762a8df4496c))

View File

@@ -0,0 +1,11 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const base = require('../../jest.config');
module.exports = {
...base,
globals: {
'ts-jest': {
tsconfig: 'tsconfig.json',
},
}
};

View File

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

View File

@@ -0,0 +1,38 @@
{
"name": "@standardnotes/predicates",
"version": "1.1.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
"description": "Utils and models required for scheduling jobs",
"main": "dist/src/index.js",
"author": "Standard Notes",
"types": "dist/src/index.d.ts",
"files": [
"dist/src"
],
"publishConfig": {
"access": "public"
},
"license": "AGPL-3.0-or-later",
"scripts": {
"clean": "rm -fr dist",
"prestart": "yarn clean",
"start": "tsc -p tsconfig.json --watch",
"prebuild": "yarn clean",
"build": "tsc -p tsconfig.json",
"lint": "eslint . --ext .ts",
"test:unit": "jest spec --coverage --passWithNoTests"
},
"devDependencies": {
"@types/jest": "^27.4.1",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^27.5.1",
"ts-jest": "^27.1.3"
},
"dependencies": {
"@standardnotes/common": "^1.23.1",
"reflect-metadata": "^0.1.13"
}
}

View File

@@ -0,0 +1,10 @@
import { Uuid } from '@standardnotes/common'
import { PredicateAuthority } from './PredicateAuthority'
import { PredicateName } from './PredicateName'
export type Predicate = {
jobUuid: Uuid
name: PredicateName
authority: PredicateAuthority
}

View File

@@ -0,0 +1,4 @@
export enum PredicateAuthority {
Auth = 'auth',
SyncingServer = 'syncing-server',
}

View File

@@ -0,0 +1,4 @@
export enum PredicateName {
EmailBackupsEnabled = 'email-backups-enabled',
SubscriptionPurchased = 'subscription-purchased',
}

View File

@@ -0,0 +1,4 @@
export enum PredicateVerificationResult {
Affirmed = 'affirmed',
Denied = 'denied',
}

View File

@@ -0,0 +1,4 @@
export * from './Predicate/Predicate'
export * from './Predicate/PredicateAuthority'
export * from './Predicate/PredicateName'
export * from './Predicate/PredicateVerificationResult'

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,20 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.3.0](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.2.7...@standardnotes/scheduler-server@1.3.0) (2022-07-06)
### Bug Fixes
* scheduler to predicates imports ([1b35cf7](https://github.com/standardnotes/server/commit/1b35cf7a392fbe6c4b49889f92ffab6ddd7bb181))
### Features
* add predicates package ([ed62ed5](https://github.com/standardnotes/server/commit/ed62ed516f5cf8784975f41680366bf0518ce491))
## [1.2.7](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.2.6...@standardnotes/scheduler-server@1.2.7) (2022-07-06)
**Note:** Version bump only for package @standardnotes/scheduler-server
## [1.2.6](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.2.5...@standardnotes/scheduler-server@1.2.6) (2022-07-06)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/scheduler-server",
"version": "1.2.6",
"version": "1.3.0",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -29,7 +29,7 @@
"@standardnotes/common": "^1.23.1",
"@standardnotes/domain-events": "workspace:*",
"@standardnotes/domain-events-infra": "workspace:*",
"@standardnotes/scheduler": "^1.1.2",
"@standardnotes/predicates": "workspace:*",
"@standardnotes/time": "^1.7.1",
"aws-sdk": "^2.1158.0",
"dayjs": "^1.11.3",

View File

@@ -4,7 +4,7 @@ import { EmailMessageIdentifier } from '@standardnotes/common'
import { TimerInterface } from '@standardnotes/time'
import { DomainEventFactory } from './DomainEventFactory'
import { PredicateAuthority, PredicateName } from '@standardnotes/scheduler'
import { PredicateAuthority, PredicateName } from '@standardnotes/predicates'
import { Job } from '../Job/Job'
import { Predicate } from '../Predicate/Predicate'

View File

@@ -4,7 +4,7 @@ import {
EmailMessageRequestedEvent,
PredicateVerificationRequestedEvent,
} from '@standardnotes/domain-events'
import { PredicateAuthority } from '@standardnotes/scheduler'
import { PredicateAuthority } from '@standardnotes/predicates'
import { TimerInterface } from '@standardnotes/time'
import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'

View File

@@ -1,5 +1,5 @@
import { PredicateVerifiedEvent } from '@standardnotes/domain-events'
import { PredicateAuthority, PredicateName, PredicateVerificationResult } from '@standardnotes/scheduler'
import { PredicateAuthority, PredicateName, PredicateVerificationResult } from '@standardnotes/predicates'
import 'reflect-metadata'
import { Logger } from 'winston'
import { UpdatePredicateStatus } from '../UseCase/UpdatePredicateStatus/UpdatePredicateStatus'

View File

@@ -1,5 +1,5 @@
import { DomainEventHandlerInterface, UserRegisteredEvent } from '@standardnotes/domain-events'
import { PredicateAuthority, PredicateName } from '@standardnotes/scheduler'
import { PredicateAuthority, PredicateName } from '@standardnotes/predicates'
import { TimerInterface } from '@standardnotes/time'
import { inject, injectable } from 'inversify'

View File

@@ -1,5 +1,5 @@
import { DomainEventPublisherInterface, EmailMessageRequestedEvent } from '@standardnotes/domain-events'
import { PredicateName } from '@standardnotes/scheduler'
import { PredicateName } from '@standardnotes/predicates'
import 'reflect-metadata'
import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface'
import { Predicate } from '../Predicate/Predicate'

View File

@@ -1,6 +1,6 @@
import { EmailMessageIdentifier } from '@standardnotes/common'
import { DomainEventPublisherInterface } from '@standardnotes/domain-events'
import { PredicateName } from '@standardnotes/scheduler'
import { PredicateName } from '@standardnotes/predicates'
import { inject, injectable } from 'inversify'
import TYPES from '../../Bootstrap/Types'

View File

@@ -1,5 +1,5 @@
/* istanbul ignore file */
import { PredicateAuthority, PredicateName } from '@standardnotes/scheduler'
import { PredicateAuthority, PredicateName } from '@standardnotes/predicates'
import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'
import { Job } from '../Job/Job'

View File

@@ -1,4 +1,4 @@
import { PredicateAuthority, PredicateName, PredicateVerificationResult } from '@standardnotes/scheduler'
import { PredicateAuthority, PredicateName, PredicateVerificationResult } from '@standardnotes/predicates'
import 'reflect-metadata'
import { JobDoneInterpreterInterface } from '../../Job/JobDoneInterpreterInterface'

View File

@@ -1,4 +1,4 @@
import { Predicate, PredicateVerificationResult } from '@standardnotes/scheduler'
import { Predicate, PredicateVerificationResult } from '@standardnotes/predicates'
export type UpdatePredicateStatusDTO = {
predicate: Predicate

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.2.1](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.2.0...@standardnotes/syncing-server@1.2.1) (2022-07-06)
**Note:** Version bump only for package @standardnotes/syncing-server
# [1.2.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.1.11...@standardnotes/syncing-server@1.2.0) (2022-07-06)
### Features
* add analytics package ([14e4ca7](https://github.com/standardnotes/syncing-server-js/commit/14e4ca70b438dd3eaaa404bc0ca31d22a62b45be))
## [1.1.11](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.1.10...@standardnotes/syncing-server@1.1.11) (2022-07-06)
### Bug Fixes

View File

@@ -1,6 +1,6 @@
{
"name": "@standardnotes/syncing-server",
"version": "1.1.11",
"version": "1.2.1",
"engines": {
"node": ">=16.0.0 <17.0.0"
},
@@ -26,7 +26,7 @@
"dependencies": {
"@newrelic/winston-enricher": "^2.1.0",
"@sentry/node": "^7.3.0",
"@standardnotes/analytics": "^1.6.0",
"@standardnotes/analytics": "workspace:*",
"@standardnotes/auth": "^3.19.4",
"@standardnotes/common": "^1.23.1",
"@standardnotes/domain-events": "workspace:*",

View File

@@ -23,7 +23,10 @@
"exclude": ["**/*.spec.ts", "dist", "test-setup.ts"],
"references": [
{
"path": "./packages/scheduler"
"path": "./packages/analytics"
},
{
"path": "./packages/api-gateway"
},
{
"path": "./packages/auth"
@@ -34,14 +37,17 @@
{
"path": "./packages/domain-events-infra"
},
{
"path": "./packages/syncing-server"
},
{
"path": "./packages/files"
},
{
"path": "./packages/api-gateway"
"path": "./packages/predicates"
},
{
"path": "./packages/scheduler"
},
{
"path": "./packages/syncing-server"
}
]
}

View File

@@ -1939,12 +1939,20 @@ __metadata:
languageName: node
linkType: hard
"@standardnotes/analytics@npm:^1.6.0":
version: 1.6.0
resolution: "@standardnotes/analytics@npm:1.6.0"
checksum: 6a5e86152673ce9ddce43c52b5f699a1b3ba5141e58a944bda8eaa88fc2f4169df27239f82633226752bf3f10f9804f426721b9c919d10fbfbb51f952430eb1f
languageName: node
linkType: hard
"@standardnotes/analytics@workspace:*, @standardnotes/analytics@workspace:packages/analytics":
version: 0.0.0-use.local
resolution: "@standardnotes/analytics@workspace:packages/analytics"
dependencies:
"@types/ioredis": ^4.28.8
"@types/jest": ^27.4.1
"@typescript-eslint/eslint-plugin": ^5.30.0
eslint-plugin-prettier: ^4.2.1
ioredis: ^4.28.5
jest: ^27.5.1
reflect-metadata: ^0.1.13
ts-jest: ^27.1.3
languageName: unknown
linkType: soft
"@standardnotes/api-gateway@workspace:packages/api-gateway":
version: 0.0.0-use.local
@@ -1952,7 +1960,7 @@ __metadata:
dependencies:
"@newrelic/winston-enricher": ^2.1.0
"@sentry/node": ^7.3.0
"@standardnotes/analytics": ^1.6.0
"@standardnotes/analytics": "workspace:*"
"@standardnotes/auth": 3.19.4
"@standardnotes/domain-events": "workspace:*"
"@standardnotes/domain-events-infra": "workspace:*"
@@ -2008,15 +2016,15 @@ __metadata:
dependencies:
"@newrelic/winston-enricher": ^2.1.0
"@sentry/node": ^7.3.0
"@standardnotes/analytics": ^1.6.0
"@standardnotes/analytics": "workspace:*"
"@standardnotes/api": ^1.1.19
"@standardnotes/auth": ^3.19.4
"@standardnotes/common": ^1.23.1
"@standardnotes/domain-events": "workspace:*"
"@standardnotes/domain-events-infra": "workspace:*"
"@standardnotes/features": ^1.47.0
"@standardnotes/predicates": "workspace:*"
"@standardnotes/responses": ^1.6.39
"@standardnotes/scheduler": ^1.1.2
"@standardnotes/settings": ^1.15.0
"@standardnotes/sncrypto-common": ^1.9.0
"@standardnotes/sncrypto-node": ^1.8.3
@@ -2119,7 +2127,7 @@ __metadata:
"@standardnotes/auth": ^3.19.4
"@standardnotes/common": ^1.23.1
"@standardnotes/features": ^1.47.0
"@standardnotes/scheduler": ^1.1.2
"@standardnotes/predicates": "workspace:*"
"@types/jest": ^28.1.4
"@typescript-eslint/eslint-plugin": ^5.30.0
eslint-plugin-prettier: ^4.2.1
@@ -2230,6 +2238,20 @@ __metadata:
languageName: node
linkType: hard
"@standardnotes/predicates@workspace:*, @standardnotes/predicates@workspace:packages/predicates":
version: 0.0.0-use.local
resolution: "@standardnotes/predicates@workspace:packages/predicates"
dependencies:
"@standardnotes/common": ^1.23.1
"@types/jest": ^27.4.1
"@typescript-eslint/eslint-plugin": ^5.30.0
eslint-plugin-prettier: ^4.2.1
jest: ^27.5.1
reflect-metadata: ^0.1.13
ts-jest: ^27.1.3
languageName: unknown
linkType: soft
"@standardnotes/responses@npm:^1.6.39":
version: 1.6.39
resolution: "@standardnotes/responses@npm:1.6.39"
@@ -2250,7 +2272,7 @@ __metadata:
"@standardnotes/common": ^1.23.1
"@standardnotes/domain-events": "workspace:*"
"@standardnotes/domain-events-infra": "workspace:*"
"@standardnotes/scheduler": ^1.1.2
"@standardnotes/predicates": "workspace:*"
"@standardnotes/time": ^1.7.1
"@types/ioredis": ^4.28.10
"@types/jest": ^28.1.2
@@ -2274,15 +2296,6 @@ __metadata:
languageName: unknown
linkType: soft
"@standardnotes/scheduler@npm:^1.1.2":
version: 1.1.2
resolution: "@standardnotes/scheduler@npm:1.1.2"
dependencies:
"@standardnotes/common": ^1.23.1
checksum: 68642a08741aeb4936e4a69e43e2b85e5cbfa3ce60006d292cee517d33093edaf35a6a7af61343d85ab3474d6e980a073a2779f6e0b1f11805ab06a407b15ce7
languageName: node
linkType: hard
"@standardnotes/server-monorepo@workspace:.":
version: 0.0.0-use.local
resolution: "@standardnotes/server-monorepo@workspace:."
@@ -2351,7 +2364,7 @@ __metadata:
dependencies:
"@newrelic/winston-enricher": ^2.1.0
"@sentry/node": ^7.3.0
"@standardnotes/analytics": ^1.6.0
"@standardnotes/analytics": "workspace:*"
"@standardnotes/auth": ^3.19.4
"@standardnotes/common": ^1.23.1
"@standardnotes/domain-events": "workspace:*"