mirror of
https://github.com/standardnotes/server
synced 2026-02-22 05:01:11 -05:00
Compare commits
8 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cf84e31b0 | ||
|
|
31e7aaf253 | ||
|
|
8ec3d37c18 | ||
|
|
857c6af946 | ||
|
|
de081fe786 | ||
|
|
0aeeb2d1cf | ||
|
|
e589029722 | ||
|
|
b265a39b63 |
@@ -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.
|
||||
|
||||
## [2.26.18](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.17...@standardnotes/analytics@2.26.18) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.26.17](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.16...@standardnotes/analytics@2.26.17) (2023-09-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
## [2.26.16](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.26.15...@standardnotes/analytics@2.26.16) (2023-09-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/analytics
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/analytics",
|
||||
"version": "2.26.16",
|
||||
"version": "2.26.18",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -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.74.16](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.15...@standardnotes/api-gateway@1.74.16) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.74.15](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.14...@standardnotes/api-gateway@1.74.15) (2023-09-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.74.14](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.74.13...@standardnotes/api-gateway@1.74.14) (2023-09-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.74.14",
|
||||
"version": "1.74.16",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -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.143.8](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.143.7...@standardnotes/auth-server@1.143.8) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
## [1.143.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.143.6...@standardnotes/auth-server@1.143.7) (2023-09-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/auth-server
|
||||
|
||||
## [1.143.6](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.143.4...@standardnotes/auth-server@1.143.6) (2023-09-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/auth-server",
|
||||
"version": "1.143.6",
|
||||
"version": "1.143.8",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.31.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.30.1...@standardnotes/domain-core@1.31.0) (2023-09-20)
|
||||
|
||||
### Features
|
||||
|
||||
* **syncing-server:** add notification for user upon declined shared vault invitation ([#837](https://github.com/standardnotes/server/issues/837)) ([31e7aaf](https://github.com/standardnotes/server/commit/31e7aaf253029a951d8b943d6cffd655cd5ca765))
|
||||
|
||||
## [1.30.1](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.30.0...@standardnotes/domain-core@1.30.1) (2023-09-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **domain-core:** allow any version and variant of the UUID format ([de081fe](https://github.com/standardnotes/server/commit/de081fe78658bdd36c8c5d86b70a16a2880aa3d1))
|
||||
|
||||
# [1.30.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-core@1.29.0...@standardnotes/domain-core@1.30.0) (2023-09-18)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-core",
|
||||
"version": "1.30.0",
|
||||
"version": "1.31.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -5,6 +5,7 @@ describe('Validator', () => {
|
||||
'2221101c-1da9-4d2b-9b32-b8be2a8d1c82',
|
||||
'c08f2f29-a74b-42b4-aefd-98af9832391c',
|
||||
'b453fa64-1493-443b-b5bb-bca7b9c696c7',
|
||||
'fa7350b3-77cf-8c0c-40b2-6046b13254fe',
|
||||
]
|
||||
|
||||
const invalidUuids = [
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { Result } from './Result'
|
||||
|
||||
export class Validator {
|
||||
private static readonly UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i
|
||||
private static readonly UUID_ANY_VERSION_AND_VARIANT_REGEX =
|
||||
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
|
||||
private static readonly EMAIL_REGEX =
|
||||
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
|
||||
static isValidUuid(value: string): Result<string> {
|
||||
const matchesUuidRegex = String(value).toLowerCase().match(Validator.UUID_REGEX) !== null
|
||||
const matchesUuidRegex = String(value).toLowerCase().match(Validator.UUID_ANY_VERSION_AND_VARIANT_REGEX) !== null
|
||||
if (matchesUuidRegex) {
|
||||
return Result.ok()
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ export class NotificationType extends ValueObject<NotificationTypeProps> {
|
||||
SharedVaultItemRemoved: 'shared_vault_item_removed',
|
||||
RemovedFromSharedVault: 'removed_from_shared_vault',
|
||||
UserAddedToSharedVault: 'user_added_to_shared_vault',
|
||||
SharedVaultInviteDeclined: 'shared_vault_invite_declined',
|
||||
SharedVaultFileUploaded: 'shared_vault_file_uploaded',
|
||||
SharedVaultFileRemoved: 'shared_vault_file_removed',
|
||||
}
|
||||
|
||||
@@ -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.11.46](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.45...@standardnotes/event-store@1.11.46) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.11.45](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.44...@standardnotes/event-store@1.11.45) (2023-09-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.11.44](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.11.43...@standardnotes/event-store@1.11.44) (2023-09-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/event-store",
|
||||
"version": "1.11.44",
|
||||
"version": "1.11.46",
|
||||
"description": "Event Store Service",
|
||||
"private": true,
|
||||
"main": "dist/src/index.js",
|
||||
|
||||
@@ -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.22.25](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.22.24...@standardnotes/files-server@1.22.25) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.22.24](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.22.23...@standardnotes/files-server@1.22.24) (2023-09-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
## [1.22.23](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.22.22...@standardnotes/files-server@1.22.23) (2023-09-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/files-server",
|
||||
"version": "1.22.23",
|
||||
"version": "1.22.25",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.15.69](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.68...@standardnotes/home-server@1.15.69) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
## [1.15.68](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.67...@standardnotes/home-server@1.15.68) (2023-09-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
## [1.15.67](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.66...@standardnotes/home-server@1.15.67) (2023-09-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
## [1.15.66](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.15.65...@standardnotes/home-server@1.15.66) (2023-09-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/home-server",
|
||||
"version": "1.15.66",
|
||||
"version": "1.15.69",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,23 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.35.8](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.7...@standardnotes/revisions-server@1.35.8) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/revisions-server
|
||||
|
||||
## [1.35.7](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.6...@standardnotes/revisions-server@1.35.7) (2023-09-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* skip removing already existing content in secondary to pick up where the transition left of ([857c6af](https://github.com/standardnotes/server/commit/857c6af9468ec829ff4dce9a96ba7bf9c14d55a5))
|
||||
|
||||
## [1.35.6](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.5...@standardnotes/revisions-server@1.35.6) (2023-09-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* increase timeout for secondary database to catch up for indexes to be rebuilt ([b265a39](https://github.com/standardnotes/server/commit/b265a39b635373c36ee8c3d8e09f0631159b3574))
|
||||
* logs verbosity during transitions ([e589029](https://github.com/standardnotes/server/commit/e589029722ab9f4debc8aa6cc78913f877eda2e3))
|
||||
|
||||
## [1.35.5](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.35.4...@standardnotes/revisions-server@1.35.5) (2023-09-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/revisions-server",
|
||||
"version": "1.35.5",
|
||||
"version": "1.35.8",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -31,19 +31,16 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
|
||||
let newRevisionsInSecondaryCount = 0
|
||||
let updatedRevisionsInSecondary: string[] = []
|
||||
let alreadyIdenticalInSecondaryAndPrimary: string[] = []
|
||||
if (await this.hasAlreadyDataInSecondaryDatabase(userUuid)) {
|
||||
const { alreadyExistingInPrimary, newRevisionsInSecondary, updatedInSecondary } =
|
||||
const { alreadyExistingInSecondaryAndPrimary, newRevisionsInSecondary, updatedInSecondary } =
|
||||
await this.getNewRevisionsCreatedInSecondaryDatabase(userUuid)
|
||||
|
||||
this.logger.info(
|
||||
`[${dto.userUuid}] Removing ${alreadyExistingInPrimary.length} already existing revisions from secondary database`,
|
||||
`[${dto.userUuid}] ${alreadyExistingInSecondaryAndPrimary.length} already existing identical revisions in primary and secondary.`,
|
||||
)
|
||||
for (const existingRevisionUuid of alreadyExistingInPrimary) {
|
||||
await (this.secondRevisionsRepository as RevisionRepositoryInterface).removeOneByUuid(
|
||||
Uuid.create(existingRevisionUuid).getValue(),
|
||||
userUuid,
|
||||
)
|
||||
}
|
||||
|
||||
alreadyIdenticalInSecondaryAndPrimary = alreadyExistingInSecondaryAndPrimary
|
||||
|
||||
if (newRevisionsInSecondary.length > 0) {
|
||||
this.logger.info(
|
||||
@@ -66,9 +63,13 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
|
||||
const migrationTimeStart = this.timer.getTimestampInMicroseconds()
|
||||
|
||||
this.logger.debug(`[${dto.userUuid}] Transitioning revisions`)
|
||||
this.logger.info(`[${dto.userUuid}] Migrating revisions`)
|
||||
|
||||
const migrationResult = await this.migrateRevisionsForUser(userUuid, updatedRevisionsInSecondary)
|
||||
const migrationResult = await this.migrateRevisionsForUser(
|
||||
userUuid,
|
||||
updatedRevisionsInSecondary,
|
||||
alreadyIdenticalInSecondaryAndPrimary,
|
||||
)
|
||||
if (migrationResult.isFailed()) {
|
||||
if (newRevisionsInSecondaryCount === 0 && updatedRevisionsInSecondaryCount === 0) {
|
||||
const cleanupResult = await this.deleteRevisionsForUser(userUuid, this.secondRevisionsRepository)
|
||||
@@ -88,6 +89,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
userUuid,
|
||||
newRevisionsInSecondaryCount,
|
||||
updatedRevisionsInSecondary,
|
||||
alreadyIdenticalInSecondaryAndPrimary,
|
||||
)
|
||||
if (integrityCheckResult.isFailed()) {
|
||||
if (newRevisionsInSecondaryCount === 0 && updatedRevisionsInSecondaryCount === 0) {
|
||||
@@ -119,10 +121,13 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
return Result.ok()
|
||||
}
|
||||
|
||||
private async migrateRevisionsForUser(userUuid: Uuid, updatedRevisionsInSecondary: string[]): Promise<Result<void>> {
|
||||
private async migrateRevisionsForUser(
|
||||
userUuid: Uuid,
|
||||
updatedRevisionsInSecondary: string[],
|
||||
alreadyExistingInSecondaryAndPrimary: string[],
|
||||
): Promise<Result<void>> {
|
||||
try {
|
||||
const totalRevisionsCountForUser = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
|
||||
let totalRevisionsCountTransitionedToSecondary = 0
|
||||
const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize)
|
||||
for (let currentPage = 1; currentPage <= totalPages; currentPage++) {
|
||||
const query = {
|
||||
@@ -147,17 +152,18 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
continue
|
||||
}
|
||||
|
||||
this.logger.debug(
|
||||
`[${userUuid.value}]Transitioning revision #${
|
||||
totalRevisionsCountTransitionedToSecondary + 1
|
||||
}: ${revision.id.toString()} to secondary database`,
|
||||
)
|
||||
if (
|
||||
alreadyExistingInSecondaryAndPrimary.find(
|
||||
(alreadyExistingRevisionUuid) => alreadyExistingRevisionUuid === revision.id.toString(),
|
||||
)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
const didSave = await (this.secondRevisionsRepository as RevisionRepositoryInterface).insert(revision)
|
||||
if (!didSave) {
|
||||
return Result.fail(`Failed to save revision ${revision.id.toString()} to secondary database`)
|
||||
}
|
||||
totalRevisionsCountTransitionedToSecondary++
|
||||
} catch (error) {
|
||||
return Result.fail(
|
||||
`Errored when saving revision ${revision.id.toString()} to secondary database: ${
|
||||
@@ -168,10 +174,6 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.debug(
|
||||
`[${userUuid.value}] Transitioned ${totalRevisionsCountTransitionedToSecondary} revisions to secondary database`,
|
||||
)
|
||||
|
||||
return Result.ok()
|
||||
} catch (error) {
|
||||
return Result.fail(`Errored when migrating revisions for user ${userUuid.value}: ${(error as Error).message}`)
|
||||
@@ -192,8 +194,8 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
}
|
||||
|
||||
private async allowForSecondaryDatabaseToCatchUp(): Promise<void> {
|
||||
const twoSecondsInMilliseconds = 2_000
|
||||
await this.timer.sleep(twoSecondsInMilliseconds)
|
||||
const tenSecondsInMillisecondsToRebuildIndexes = 10_000
|
||||
await this.timer.sleep(tenSecondsInMillisecondsToRebuildIndexes)
|
||||
}
|
||||
|
||||
private async hasAlreadyDataInSecondaryDatabase(userUuid: Uuid): Promise<boolean> {
|
||||
@@ -212,7 +214,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
}
|
||||
|
||||
private async getNewRevisionsCreatedInSecondaryDatabase(userUuid: Uuid): Promise<{
|
||||
alreadyExistingInPrimary: string[]
|
||||
alreadyExistingInSecondaryAndPrimary: string[]
|
||||
newRevisionsInSecondary: string[]
|
||||
updatedInSecondary: string[]
|
||||
}> {
|
||||
@@ -223,7 +225,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
).countByUserUuid(userUuid)
|
||||
const totalPages = Math.ceil(totalRevisionsCountForUser / this.pageSize)
|
||||
|
||||
const alreadyExistingInPrimary: string[] = []
|
||||
const alreadyExistingInSecondaryAndPrimary: string[] = []
|
||||
const newRevisionsInSecondary: string[] = []
|
||||
const updatedInSecondary: string[] = []
|
||||
|
||||
@@ -236,17 +238,17 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
|
||||
const revisions = await (this.secondRevisionsRepository as RevisionRepositoryInterface).findByUserUuid(query)
|
||||
for (const revision of revisions) {
|
||||
const { revisionInPrimary, newerRevisionInSecondary } =
|
||||
const { identicalRevisionInPrimary, newerRevisionInSecondary } =
|
||||
await this.checkIfRevisionExistsInPrimaryDatabase(revision)
|
||||
if (revisionInPrimary !== null) {
|
||||
alreadyExistingInPrimary.push(revision.id.toString())
|
||||
if (identicalRevisionInPrimary !== null) {
|
||||
alreadyExistingInSecondaryAndPrimary.push(revision.id.toString())
|
||||
continue
|
||||
}
|
||||
if (newerRevisionInSecondary !== null) {
|
||||
updatedInSecondary.push(newerRevisionInSecondary.id.toString())
|
||||
continue
|
||||
}
|
||||
if (revisionInPrimary === null && newerRevisionInSecondary === null) {
|
||||
if (identicalRevisionInPrimary === null && newerRevisionInSecondary === null) {
|
||||
newRevisionsInSecondary.push(revision.id.toString())
|
||||
continue
|
||||
}
|
||||
@@ -254,7 +256,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
}
|
||||
|
||||
return {
|
||||
alreadyExistingInPrimary,
|
||||
alreadyExistingInSecondaryAndPrimary,
|
||||
newRevisionsInSecondary,
|
||||
updatedInSecondary,
|
||||
}
|
||||
@@ -262,7 +264,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
|
||||
private async checkIfRevisionExistsInPrimaryDatabase(
|
||||
revision: Revision,
|
||||
): Promise<{ revisionInPrimary: Revision | null; newerRevisionInSecondary: Revision | null }> {
|
||||
): Promise<{ identicalRevisionInPrimary: Revision | null; newerRevisionInSecondary: Revision | null }> {
|
||||
const revisionInPrimary = await this.primaryRevisionsRepository.findOneByUuid(
|
||||
Uuid.create(revision.id.toString()).getValue(),
|
||||
revision.props.userUuid as Uuid,
|
||||
@@ -271,7 +273,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
|
||||
if (revisionInPrimary === null) {
|
||||
return {
|
||||
revisionInPrimary: null,
|
||||
identicalRevisionInPrimary: null,
|
||||
newerRevisionInSecondary: null,
|
||||
}
|
||||
}
|
||||
@@ -285,14 +287,14 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
)
|
||||
|
||||
return {
|
||||
revisionInPrimary: null,
|
||||
identicalRevisionInPrimary: null,
|
||||
newerRevisionInSecondary:
|
||||
revision.props.dates.updatedAt > revisionInPrimary.props.dates.updatedAt ? revision : null,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
revisionInPrimary: revisionInPrimary,
|
||||
identicalRevisionInPrimary: revisionInPrimary,
|
||||
newerRevisionInSecondary: null,
|
||||
}
|
||||
}
|
||||
@@ -301,6 +303,7 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
userUuid: Uuid,
|
||||
newRevisionsInSecondaryCount: number,
|
||||
updatedRevisionsInSecondary: string[],
|
||||
alreadyExistingInSecondaryAndPrimary: string[],
|
||||
): Promise<Result<boolean>> {
|
||||
try {
|
||||
const totalRevisionsCountForUserInPrimary = await this.primaryRevisionsRepository.countByUserUuid(userUuid)
|
||||
@@ -341,6 +344,14 @@ export class TransitionRevisionsFromPrimaryToSecondaryDatabaseForUser implements
|
||||
continue
|
||||
}
|
||||
|
||||
if (
|
||||
alreadyExistingInSecondaryAndPrimary.find(
|
||||
(alreadyExistingRevisionUuid) => alreadyExistingRevisionUuid === revision.id.toString(),
|
||||
)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (!revision.isIdenticalTo(revisionInSecondary)) {
|
||||
return Result.fail(
|
||||
`Revision ${revision.id.toString()} is not identical in primary and secondary database. Revision in primary database: ${JSON.stringify(
|
||||
|
||||
@@ -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.20.50](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.49...@standardnotes/scheduler-server@1.20.50) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.20.49](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.48...@standardnotes/scheduler-server@1.20.49) (2023-09-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
## [1.20.48](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.20.47...@standardnotes/scheduler-server@1.20.48) (2023-09-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/scheduler-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/scheduler-server",
|
||||
"version": "1.20.48",
|
||||
"version": "1.20.50",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -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.21.35](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.34...@standardnotes/settings@1.21.35) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/settings
|
||||
|
||||
## [1.21.34](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.33...@standardnotes/settings@1.21.34) (2023-09-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/settings
|
||||
|
||||
## [1.21.33](https://github.com/standardnotes/server/compare/@standardnotes/settings@1.21.32...@standardnotes/settings@1.21.33) (2023-09-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/settings
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/settings",
|
||||
"version": "1.21.33",
|
||||
"version": "1.21.35",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,25 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.99.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.6...@standardnotes/syncing-server@1.99.0) (2023-09-20)
|
||||
|
||||
### Features
|
||||
|
||||
* **syncing-server:** add notification for user upon declined shared vault invitation ([#837](https://github.com/standardnotes/syncing-server-js/issues/837)) ([31e7aaf](https://github.com/standardnotes/syncing-server-js/commit/31e7aaf253029a951d8b943d6cffd655cd5ca765))
|
||||
|
||||
## [1.98.6](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.5...@standardnotes/syncing-server@1.98.6) (2023-09-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* skip removing already existing content in secondary to pick up where the transition left of ([857c6af](https://github.com/standardnotes/syncing-server-js/commit/857c6af9468ec829ff4dce9a96ba7bf9c14d55a5))
|
||||
|
||||
## [1.98.5](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.4...@standardnotes/syncing-server@1.98.5) (2023-09-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* increase timeout for secondary database to catch up for indexes to be rebuilt ([b265a39](https://github.com/standardnotes/syncing-server-js/commit/b265a39b635373c36ee8c3d8e09f0631159b3574))
|
||||
* logs verbosity during transitions ([e589029](https://github.com/standardnotes/syncing-server-js/commit/e589029722ab9f4debc8aa6cc78913f877eda2e3))
|
||||
|
||||
## [1.98.4](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.98.3...@standardnotes/syncing-server@1.98.4) (2023-09-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/syncing-server",
|
||||
"version": "1.98.4",
|
||||
"version": "1.99.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -723,7 +723,12 @@ export class ContainerConfigLoader {
|
||||
)
|
||||
container
|
||||
.bind<DeclineInviteToSharedVault>(TYPES.Sync_DeclineInviteToSharedVault)
|
||||
.toConstantValue(new DeclineInviteToSharedVault(container.get(TYPES.Sync_SharedVaultInviteRepository)))
|
||||
.toConstantValue(
|
||||
new DeclineInviteToSharedVault(
|
||||
container.get<SharedVaultInviteRepositoryInterface>(TYPES.Sync_SharedVaultInviteRepository),
|
||||
container.get<AddNotificationForUser>(TYPES.Sync_AddNotificationForUser),
|
||||
),
|
||||
)
|
||||
container
|
||||
.bind<DeleteSharedVaultInvitesToUser>(TYPES.Sync_DeleteSharedVaultInvitesToUser)
|
||||
.toConstantValue(
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { SharedVaultUserPermission, Timestamps, Uuid } from '@standardnotes/domain-core'
|
||||
import { NotificationPayload, Result, SharedVaultUserPermission, Timestamps, Uuid } from '@standardnotes/domain-core'
|
||||
import { SharedVaultInviteRepositoryInterface } from '../../../SharedVault/User/Invite/SharedVaultInviteRepositoryInterface'
|
||||
import { DeclineInviteToSharedVault } from './DeclineInviteToSharedVault'
|
||||
import { SharedVaultInvite } from '../../../SharedVault/User/Invite/SharedVaultInvite'
|
||||
import { AddNotificationForUser } from '../../Messaging/AddNotificationForUser/AddNotificationForUser'
|
||||
|
||||
describe('DeclineInviteToSharedVault', () => {
|
||||
let sharedVaultInviteRepository: SharedVaultInviteRepositoryInterface
|
||||
let invite: SharedVaultInvite
|
||||
let addNotificationForUser: AddNotificationForUser
|
||||
|
||||
const createUseCase = () => new DeclineInviteToSharedVault(sharedVaultInviteRepository)
|
||||
const createUseCase = () => new DeclineInviteToSharedVault(sharedVaultInviteRepository, addNotificationForUser)
|
||||
|
||||
beforeEach(() => {
|
||||
invite = SharedVaultInvite.create({
|
||||
@@ -22,6 +24,9 @@ describe('DeclineInviteToSharedVault', () => {
|
||||
sharedVaultInviteRepository = {} as jest.Mocked<SharedVaultInviteRepositoryInterface>
|
||||
sharedVaultInviteRepository.findByUuid = jest.fn().mockResolvedValue(invite)
|
||||
sharedVaultInviteRepository.remove = jest.fn()
|
||||
|
||||
addNotificationForUser = {} as jest.Mocked<AddNotificationForUser>
|
||||
addNotificationForUser.execute = jest.fn().mockReturnValue(Result.ok())
|
||||
})
|
||||
|
||||
it('should fail if invite uuid is invalid', async () => {
|
||||
@@ -36,6 +41,37 @@ describe('DeclineInviteToSharedVault', () => {
|
||||
expect(result.getError()).toBe('Given value is not a valid uuid: invalid')
|
||||
})
|
||||
|
||||
it('should fail if adding a notification for user fails', async () => {
|
||||
addNotificationForUser.execute = jest.fn().mockReturnValue(Result.fail('Error'))
|
||||
|
||||
const useCase = createUseCase()
|
||||
|
||||
const result = await useCase.execute({
|
||||
inviteUuid: '00000000-0000-0000-0000-000000000000',
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Error')
|
||||
})
|
||||
|
||||
it('should return error if notification payload could not be created', async () => {
|
||||
const mock = jest.spyOn(NotificationPayload, 'create')
|
||||
mock.mockReturnValue(Result.fail('Oops'))
|
||||
|
||||
const useCase = createUseCase()
|
||||
|
||||
const result = await useCase.execute({
|
||||
inviteUuid: '00000000-0000-0000-0000-000000000000',
|
||||
userUuid: '00000000-0000-0000-0000-000000000000',
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Oops')
|
||||
|
||||
mock.mockRestore()
|
||||
})
|
||||
|
||||
it('should fail if originator uuid is invalid', async () => {
|
||||
const useCase = createUseCase()
|
||||
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
|
||||
import { NotificationPayload, NotificationType, Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
|
||||
|
||||
import { DeclineInviteToSharedVaultDTO } from './DeclineInviteToSharedVaultDTO'
|
||||
import { SharedVaultInviteRepositoryInterface } from '../../../SharedVault/User/Invite/SharedVaultInviteRepositoryInterface'
|
||||
import { AddNotificationForUser } from '../../Messaging/AddNotificationForUser/AddNotificationForUser'
|
||||
|
||||
export class DeclineInviteToSharedVault implements UseCaseInterface<void> {
|
||||
constructor(private sharedVaultInviteRepository: SharedVaultInviteRepositoryInterface) {}
|
||||
constructor(
|
||||
private sharedVaultInviteRepository: SharedVaultInviteRepositoryInterface,
|
||||
private addNotificationForUser: AddNotificationForUser,
|
||||
) {}
|
||||
|
||||
async execute(dto: DeclineInviteToSharedVaultDTO): Promise<Result<void>> {
|
||||
const inviteUuidOrError = Uuid.create(dto.inviteUuid)
|
||||
@@ -29,6 +34,26 @@ export class DeclineInviteToSharedVault implements UseCaseInterface<void> {
|
||||
|
||||
await this.sharedVaultInviteRepository.remove(invite)
|
||||
|
||||
const notificationPayloadOrError = NotificationPayload.create({
|
||||
sharedVaultUuid: invite.props.sharedVaultUuid,
|
||||
type: NotificationType.create(NotificationType.TYPES.SharedVaultInviteDeclined).getValue(),
|
||||
version: '1.0',
|
||||
})
|
||||
if (notificationPayloadOrError.isFailed()) {
|
||||
return Result.fail(notificationPayloadOrError.getError())
|
||||
}
|
||||
const notificationPayload = notificationPayloadOrError.getValue()
|
||||
|
||||
const result = await this.addNotificationForUser.execute({
|
||||
userUuid: invite.props.userUuid.value,
|
||||
type: NotificationType.TYPES.SharedVaultInviteDeclined,
|
||||
payload: notificationPayload,
|
||||
version: '1.0',
|
||||
})
|
||||
if (result.isFailed()) {
|
||||
return Result.fail(result.getError())
|
||||
}
|
||||
|
||||
return Result.ok()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,19 +32,16 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
||||
|
||||
let newItemsInSecondaryCount = 0
|
||||
let updatedItemsInSecondary: string[] = []
|
||||
let alreadyIdenticalInSecondaryAndPrimary: string[] = []
|
||||
if (await this.hasAlreadyDataInSecondaryDatabase(userUuid)) {
|
||||
const { alreadyExistingInPrimary, newItemsInSecondary, updatedInSecondary } =
|
||||
const { alreadyExistingInSecondaryAndPrimary, newItemsInSecondary, updatedInSecondary } =
|
||||
await this.getNewItemsCreatedInSecondaryDatabase(userUuid)
|
||||
|
||||
this.logger.info(
|
||||
`[${dto.userUuid}] Removing ${alreadyExistingInPrimary.length} already existing items from secondary database.`,
|
||||
`[${dto.userUuid}] ${alreadyExistingInSecondaryAndPrimary.length} already existing identical items in primary and secondary.`,
|
||||
)
|
||||
|
||||
for (const existingItemUuid of alreadyExistingInPrimary) {
|
||||
await (this.secondaryItemRepository as ItemRepositoryInterface).removeByUuid(
|
||||
Uuid.create(existingItemUuid).getValue(),
|
||||
)
|
||||
}
|
||||
alreadyIdenticalInSecondaryAndPrimary = alreadyExistingInSecondaryAndPrimary
|
||||
|
||||
if (newItemsInSecondary.length > 0) {
|
||||
this.logger.info(`[${dto.userUuid}] Found ${newItemsInSecondary.length} new items in secondary database.`)
|
||||
@@ -64,7 +61,13 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
||||
|
||||
const migrationTimeStart = this.timer.getTimestampInMicroseconds()
|
||||
|
||||
const migrationResult = await this.migrateItemsForUser(userUuid, updatedItemsInSecondary)
|
||||
this.logger.info(`[${dto.userUuid}] Migrating items`)
|
||||
|
||||
const migrationResult = await this.migrateItemsForUser(
|
||||
userUuid,
|
||||
updatedItemsInSecondary,
|
||||
alreadyIdenticalInSecondaryAndPrimary,
|
||||
)
|
||||
if (migrationResult.isFailed()) {
|
||||
if (newItemsInSecondaryCount === 0 && updatedItemsInSecondaryCount === 0) {
|
||||
const cleanupResult = await this.deleteItemsForUser(userUuid, this.secondaryItemRepository)
|
||||
@@ -84,6 +87,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
||||
userUuid,
|
||||
newItemsInSecondaryCount,
|
||||
updatedItemsInSecondary,
|
||||
alreadyIdenticalInSecondaryAndPrimary,
|
||||
)
|
||||
if (integrityCheckResult.isFailed()) {
|
||||
if (newItemsInSecondaryCount === 0 && updatedItemsInSecondaryCount === 0) {
|
||||
@@ -129,18 +133,18 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
||||
}
|
||||
|
||||
private async allowForSecondaryDatabaseToCatchUp(): Promise<void> {
|
||||
const twoSecondsInMilliseconds = 2_000
|
||||
await this.timer.sleep(twoSecondsInMilliseconds)
|
||||
const tenSecondsInMillisecondsToRebuildIndexes = 10_000
|
||||
await this.timer.sleep(tenSecondsInMillisecondsToRebuildIndexes)
|
||||
}
|
||||
|
||||
private async getNewItemsCreatedInSecondaryDatabase(userUuid: Uuid): Promise<{
|
||||
alreadyExistingInPrimary: string[]
|
||||
alreadyExistingInSecondaryAndPrimary: string[]
|
||||
newItemsInSecondary: string[]
|
||||
updatedInSecondary: string[]
|
||||
}> {
|
||||
this.logger.info(`[${userUuid.value}] Checking for new items in secondary database`)
|
||||
|
||||
const alreadyExistingInPrimary: string[] = []
|
||||
const alreadyExistingInSecondaryAndPrimary: string[] = []
|
||||
const updatedInSecondary: string[] = []
|
||||
const newItemsInSecondary: string[] = []
|
||||
|
||||
@@ -159,16 +163,16 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
||||
|
||||
const items = await (this.secondaryItemRepository as ItemRepositoryInterface).findAll(query)
|
||||
for (const item of items) {
|
||||
const { itemInPrimary, newerItemInSecondary } = await this.checkIfItemExistsInPrimaryDatabase(item)
|
||||
if (itemInPrimary !== null) {
|
||||
alreadyExistingInPrimary.push(item.id.toString())
|
||||
const { identicalItemInPrimary, newerItemInSecondary } = await this.checkIfItemExistsInPrimaryDatabase(item)
|
||||
if (identicalItemInPrimary !== null) {
|
||||
alreadyExistingInSecondaryAndPrimary.push(item.id.toString())
|
||||
continue
|
||||
}
|
||||
if (newerItemInSecondary !== null) {
|
||||
updatedInSecondary.push(newerItemInSecondary.id.toString())
|
||||
continue
|
||||
}
|
||||
if (itemInPrimary === null && newerItemInSecondary === null) {
|
||||
if (identicalItemInPrimary === null && newerItemInSecondary === null) {
|
||||
newItemsInSecondary.push(item.id.toString())
|
||||
continue
|
||||
}
|
||||
@@ -176,7 +180,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
||||
}
|
||||
|
||||
return {
|
||||
alreadyExistingInPrimary,
|
||||
alreadyExistingInSecondaryAndPrimary,
|
||||
newItemsInSecondary,
|
||||
updatedInSecondary,
|
||||
}
|
||||
@@ -184,11 +188,11 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
||||
|
||||
private async checkIfItemExistsInPrimaryDatabase(
|
||||
item: Item,
|
||||
): Promise<{ itemInPrimary: Item | null; newerItemInSecondary: Item | null }> {
|
||||
): Promise<{ identicalItemInPrimary: Item | null; newerItemInSecondary: Item | null }> {
|
||||
const itemInPrimary = await this.primaryItemRepository.findByUuid(item.uuid)
|
||||
|
||||
if (itemInPrimary === null) {
|
||||
return { itemInPrimary: null, newerItemInSecondary: null }
|
||||
return { identicalItemInPrimary: null, newerItemInSecondary: null }
|
||||
}
|
||||
|
||||
if (!item.isIdenticalTo(itemInPrimary)) {
|
||||
@@ -201,15 +205,19 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
||||
)
|
||||
|
||||
return {
|
||||
itemInPrimary: null,
|
||||
identicalItemInPrimary: null,
|
||||
newerItemInSecondary: item.props.timestamps.updatedAt > itemInPrimary.props.timestamps.updatedAt ? item : null,
|
||||
}
|
||||
}
|
||||
|
||||
return { itemInPrimary: itemInPrimary, newerItemInSecondary: null }
|
||||
return { identicalItemInPrimary: itemInPrimary, newerItemInSecondary: null }
|
||||
}
|
||||
|
||||
private async migrateItemsForUser(userUuid: Uuid, updatedItemsInSecondary: string[]): Promise<Result<void>> {
|
||||
private async migrateItemsForUser(
|
||||
userUuid: Uuid,
|
||||
updatedItemsInSecondary: string[],
|
||||
alreadyExistingInSecondaryAndPrimary: string[],
|
||||
): Promise<Result<void>> {
|
||||
try {
|
||||
const totalItemsCountForUser = await this.primaryItemRepository.countAll({ userUuid: userUuid.value })
|
||||
const totalPages = Math.ceil(totalItemsCountForUser / this.pageSize)
|
||||
@@ -232,6 +240,10 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
||||
|
||||
continue
|
||||
}
|
||||
if (alreadyExistingInSecondaryAndPrimary.find((itemUuid) => item.uuid.value === itemUuid)) {
|
||||
continue
|
||||
}
|
||||
|
||||
await (this.secondaryItemRepository as ItemRepositoryInterface).save(item)
|
||||
}
|
||||
}
|
||||
@@ -256,6 +268,7 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
||||
userUuid: Uuid,
|
||||
newItemsInSecondaryCount: number,
|
||||
updatedItemsInSecondary: string[],
|
||||
alreadyExistingInSecondaryAndPrimary: string[],
|
||||
): Promise<Result<boolean>> {
|
||||
try {
|
||||
const totalItemsCountForUserInPrimary = await this.primaryItemRepository.countAll({ userUuid: userUuid.value })
|
||||
@@ -296,6 +309,10 @@ export class TransitionItemsFromPrimaryToSecondaryDatabaseForUser implements Use
|
||||
continue
|
||||
}
|
||||
|
||||
if (alreadyExistingInSecondaryAndPrimary.find((itemUuid) => item.uuid.value === itemUuid)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (!item.isIdenticalTo(itemInSecondary)) {
|
||||
return Result.fail(
|
||||
`Item ${
|
||||
|
||||
@@ -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.10.47](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.46...@standardnotes/websockets-server@1.10.47) (2023-09-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||
|
||||
## [1.10.46](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.45...@standardnotes/websockets-server@1.10.46) (2023-09-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||
|
||||
## [1.10.45](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.10.44...@standardnotes/websockets-server@1.10.45) (2023-09-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/websockets-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/websockets-server",
|
||||
"version": "1.10.45",
|
||||
"version": "1.10.47",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user