mirror of
https://github.com/standardnotes/app
synced 2026-09-16 00:46:00 -04:00
Compare commits
66
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9dc51f51b2 | ||
|
|
f1f0d65dd5 | ||
|
|
47b3286235 | ||
|
|
166953de20 | ||
|
|
b98f5e2d02 | ||
|
|
5dd3d521cb | ||
|
|
fc6c6bad2c | ||
|
|
e9bf7d336b | ||
|
|
e63b4f0592 | ||
|
|
ac28b29d65 | ||
|
|
18235751d4 | ||
|
|
cbd0063926 | ||
|
|
3b048a31aa | ||
|
|
4a2dc1ef7a | ||
|
|
21f725bb2a | ||
|
|
173bacdfa3 | ||
|
|
c503d781ae | ||
|
|
9fb85cd77a | ||
|
|
bd40a49484 | ||
|
|
4a1612c7dc | ||
|
|
d3ed4391b7 | ||
|
|
856e499d89 | ||
|
|
4f0805d5b0 | ||
|
|
401a35f4db | ||
|
|
83b484002c | ||
|
|
30310dbb45 | ||
|
|
c6e3580678 | ||
|
|
ea285a36d8 | ||
|
|
1addaf4c39 | ||
|
|
92bba942f1 | ||
|
|
f71e6fe703 | ||
|
|
143b528b73 | ||
|
|
5d202a823e | ||
|
|
8d7d577b1c | ||
|
|
76f23e13ec | ||
|
|
4f3b258363 | ||
|
|
9cc3304741 | ||
|
|
4432f1cb4c | ||
|
|
6c47f95748 | ||
|
|
57fab4f670 | ||
|
|
fb7b9350b2 | ||
|
|
fb72c2fdae | ||
|
|
050fa9cabc | ||
|
|
a8535cfa23 | ||
|
|
27bb4ebdae | ||
|
|
60a8e8b92b | ||
|
|
1f07d9fa17 | ||
|
|
d333d4f188 | ||
|
|
7e3d7a8825 | ||
|
|
e99c7b7c51 | ||
|
|
0282a7958a | ||
|
|
4030953b00 | ||
|
|
ba9a9f8d01 | ||
|
|
80e76ee52c | ||
|
|
bbebfb42fd | ||
|
|
9954bdc29f | ||
|
|
e4de9c1be7 | ||
|
|
07ffc01ede | ||
|
|
eec7ae1589 | ||
|
|
361f773f2c | ||
|
|
5ffd37d447 | ||
|
|
2b66ff82ee | ||
|
|
c83dc48d3f | ||
|
|
8dc7eaf3a4 | ||
|
|
e40cd157b6 | ||
|
|
66805fa552 |
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"extends": ["./node_modules/@standardnotes/config/src/.eslintrc"],
|
||||
"rules": {
|
||||
"max-classes-per-file": ["error", 1]
|
||||
},
|
||||
"ignorePatterns": [".eslintrc.js", "*.webpack.*.js", "webpack-defaults.js", "jest.config.js", "__mocks__", "**/**/coverage"]
|
||||
}
|
||||
|
||||
@@ -36,11 +36,23 @@ jobs:
|
||||
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
|
||||
id: extract_branch
|
||||
|
||||
- name: Find open PR
|
||||
uses: juliangruber/find-pull-request-action@v1
|
||||
id: find-pull-request
|
||||
with:
|
||||
branch: ${{ steps.extract_branch.outputs.branch }}
|
||||
- run: echo "Pull Request ${number} (${sha})"
|
||||
env:
|
||||
number: ${{ steps.find-pull-request.outputs.number }}
|
||||
sha: ${{ steps.find-pull-request.outputs.head-sha }}
|
||||
|
||||
- uses: peter-evans/create-pull-request@v4
|
||||
if: startsWith(github.event.head_commit.message, 'chore(deps)') == false && startsWith(github.event.head_commit.message, 'chore(deps-dev)') == false
|
||||
with:
|
||||
token: ${{ secrets.CI_PAT_TOKEN }}
|
||||
branch: ${{ github.ref }}
|
||||
base: main
|
||||
title: ${{ steps.extract_branch.outputs.branch }}
|
||||
body: "Public PR: https://github.com/standardnotes/app/pull/${{ steps.find-pull-request.outputs.number }}"
|
||||
assignees: ${{ github.actor }}
|
||||
reviewers: ${{ github.actor }}
|
||||
|
||||
@@ -70,6 +70,8 @@ jobs:
|
||||
packages/mobile/android/app/build/outputs/apk/prod/release/app-prod-release.apk
|
||||
|
||||
ios:
|
||||
env:
|
||||
ITMSTRANSPORTER_FORCE_ITMS_PACKAGE_UPLOAD: true
|
||||
defaults:
|
||||
run:
|
||||
working-directory: packages/mobile
|
||||
|
||||
@@ -49,6 +49,8 @@ jobs:
|
||||
with:
|
||||
path: packages/mobile
|
||||
ios:
|
||||
env:
|
||||
ITMSTRANSPORTER_FORCE_ITMS_PACKAGE_UPLOAD: true
|
||||
defaults:
|
||||
run:
|
||||
working-directory: packages/mobile
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@
|
||||
"css-loader": "^6.7.1",
|
||||
"eslint": "^8.17.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"husky": "^8.0.0",
|
||||
"husky": "^8.0.1",
|
||||
"lint-staged": "^13.0.1",
|
||||
"npm-check-updates": "^14.1.1",
|
||||
"prettier": "^2.6.2",
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.17.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api
|
||||
|
||||
## [1.17.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* refactor application event observing on web ([9fb85cd](https://github.com/standardnotes/app/commit/9fb85cd77a627364738a9c21706431d2a01e9c44))
|
||||
|
||||
# [1.17.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
### Features
|
||||
|
||||
* **api:** add accepting invites by the client ([4f0805d](https://github.com/standardnotes/app/commit/4f0805d5b078e5a3524f5d6699b45dfd7e3456f3))
|
||||
|
||||
## [1.16.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api
|
||||
|
||||
## [1.16.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api
|
||||
|
||||
## [1.16.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api",
|
||||
"version": "1.16.3",
|
||||
"version": "1.17.2",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -2,4 +2,5 @@ export enum SubscriptionApiOperations {
|
||||
Inviting,
|
||||
CancelingInvite,
|
||||
ListingInvites,
|
||||
AcceptingInvite,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Invitation } from '@standardnotes/models'
|
||||
|
||||
import { SubscriptionInviteAcceptResponse } from '../../Response/Subscription/SubscriptionInviteAcceptResponse'
|
||||
import { SubscriptionInviteCancelResponse } from '../../Response/Subscription/SubscriptionInviteCancelResponse'
|
||||
import { SubscriptionInviteListResponse } from '../../Response/Subscription/SubscriptionInviteListResponse'
|
||||
import { SubscriptionInviteResponse } from '../../Response/Subscription/SubscriptionInviteResponse'
|
||||
@@ -24,6 +25,9 @@ describe('SubscriptionApiService', () => {
|
||||
subscriptionServer.listInvites = jest.fn().mockReturnValue({
|
||||
data: { invitations: [{} as jest.Mocked<Invitation>] },
|
||||
} as jest.Mocked<SubscriptionInviteListResponse>)
|
||||
subscriptionServer.acceptInvite = jest.fn().mockReturnValue({
|
||||
data: { success: true },
|
||||
} as jest.Mocked<SubscriptionInviteAcceptResponse>)
|
||||
})
|
||||
|
||||
it('should invite a user', async () => {
|
||||
@@ -160,4 +164,48 @@ describe('SubscriptionApiService', () => {
|
||||
|
||||
expect(error).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should accept an invite', async () => {
|
||||
const response = await createService().acceptInvite('1-2-3')
|
||||
|
||||
expect(response).toEqual({
|
||||
data: {
|
||||
success: true,
|
||||
},
|
||||
})
|
||||
expect(subscriptionServer.acceptInvite).toHaveBeenCalledWith({
|
||||
inviteUuid: '1-2-3',
|
||||
})
|
||||
})
|
||||
|
||||
it('should not accept an invite if it is already accepting', async () => {
|
||||
const service = createService()
|
||||
Object.defineProperty(service, 'operationsInProgress', {
|
||||
get: () => new Map([[SubscriptionApiOperations.AcceptingInvite, true]]),
|
||||
})
|
||||
|
||||
let error = null
|
||||
try {
|
||||
await service.acceptInvite('1-2-3')
|
||||
} catch (caughtError) {
|
||||
error = caughtError
|
||||
}
|
||||
|
||||
expect(error).not.toBeNull()
|
||||
})
|
||||
|
||||
it('should not accept an invite if the server fails', async () => {
|
||||
subscriptionServer.acceptInvite = jest.fn().mockImplementation(() => {
|
||||
throw new Error('Oops')
|
||||
})
|
||||
|
||||
let error = null
|
||||
try {
|
||||
await createService().acceptInvite('1-2-3')
|
||||
} catch (caughtError) {
|
||||
error = caughtError
|
||||
}
|
||||
|
||||
expect(error).not.toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -6,9 +6,11 @@ import { SubscriptionServerInterface } from '../../Server/Subscription/Subscript
|
||||
import { SubscriptionInviteResponse } from '../../Response/Subscription/SubscriptionInviteResponse'
|
||||
import { SubscriptionInviteListResponse } from '../../Response/Subscription/SubscriptionInviteListResponse'
|
||||
import { SubscriptionInviteCancelResponse } from '../../Response/Subscription/SubscriptionInviteCancelResponse'
|
||||
import { SubscriptionInviteAcceptResponse } from '../../Response/Subscription/SubscriptionInviteAcceptResponse'
|
||||
|
||||
import { SubscriptionApiServiceInterface } from './SubscriptionApiServiceInterface'
|
||||
import { SubscriptionApiOperations } from './SubscriptionApiOperations'
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
|
||||
export class SubscriptionApiService implements SubscriptionApiServiceInterface {
|
||||
private operationsInProgress: Map<SubscriptionApiOperations, boolean>
|
||||
@@ -78,4 +80,24 @@ export class SubscriptionApiService implements SubscriptionApiServiceInterface {
|
||||
throw new ApiCallError(ErrorMessage.GenericFail)
|
||||
}
|
||||
}
|
||||
|
||||
async acceptInvite(inviteUuid: Uuid): Promise<SubscriptionInviteAcceptResponse> {
|
||||
if (this.operationsInProgress.get(SubscriptionApiOperations.AcceptingInvite)) {
|
||||
throw new ApiCallError(ErrorMessage.GenericInProgress)
|
||||
}
|
||||
|
||||
this.operationsInProgress.set(SubscriptionApiOperations.AcceptingInvite, true)
|
||||
|
||||
try {
|
||||
const response = await this.subscriptionServer.acceptInvite({
|
||||
inviteUuid,
|
||||
})
|
||||
|
||||
this.operationsInProgress.set(SubscriptionApiOperations.AcceptingInvite, false)
|
||||
|
||||
return response
|
||||
} catch (error) {
|
||||
throw new ApiCallError(ErrorMessage.GenericFail)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
|
||||
import { SubscriptionInviteAcceptResponse } from '../../Response/Subscription/SubscriptionInviteAcceptResponse'
|
||||
import { SubscriptionInviteCancelResponse } from '../../Response/Subscription/SubscriptionInviteCancelResponse'
|
||||
import { SubscriptionInviteListResponse } from '../../Response/Subscription/SubscriptionInviteListResponse'
|
||||
import { SubscriptionInviteResponse } from '../../Response/Subscription/SubscriptionInviteResponse'
|
||||
@@ -8,4 +9,5 @@ export interface SubscriptionApiServiceInterface {
|
||||
invite(inviteeEmail: string): Promise<SubscriptionInviteResponse>
|
||||
listInvites(): Promise<SubscriptionInviteListResponse>
|
||||
cancelInvite(inviteUuid: Uuid): Promise<SubscriptionInviteCancelResponse>
|
||||
acceptInvite(inviteUuid: Uuid): Promise<SubscriptionInviteAcceptResponse>
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
|
||||
import { ApiEndpointParam } from '../ApiEndpointParam'
|
||||
import { ApiVersion } from '../../Api/ApiVersion'
|
||||
|
||||
export type SubscriptionInviteAcceptRequestParams = {
|
||||
[ApiEndpointParam.ApiVersion]: ApiVersion.v0
|
||||
inviteUuid: Uuid
|
||||
[additionalParam: string]: unknown
|
||||
}
|
||||
|
||||
+1
-3
@@ -1,3 +1 @@
|
||||
export type SubscriptionInviteAcceptResponseBody = {
|
||||
success: boolean
|
||||
}
|
||||
export type SubscriptionInviteAcceptResponseBody = { success: true } | { success: false; message: string }
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.7.21](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
### Reverts
|
||||
|
||||
* Revert "chore: remove deprecated editors folder" ([fc00b5c](https://github.com/standardnotes/app/commit/fc00b5c4996045750589c3e08c139d5d39bf4140))
|
||||
* Revert "chore: fix code editor build" ([bb8ac49](https://github.com/standardnotes/app/commit/bb8ac49052136b3f688f19df5c71c2c32a85ed51))
|
||||
|
||||
## [2.7.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/components-meta
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/components-meta",
|
||||
"version": "2.7.20",
|
||||
"version": "2.7.21",
|
||||
"private": true,
|
||||
"author": "Standard Notes.",
|
||||
"main": "dist",
|
||||
|
||||
@@ -3,6 +3,86 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [3.23.240](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-23)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.239](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-23)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.238](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-22)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.237](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.236](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.235](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.234](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.233](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.232](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.231](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.230](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.229](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.228](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.227](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.226](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.225](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.224](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.223](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.222](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.221](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
## [3.23.220](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/desktop
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@standardnotes/desktop",
|
||||
"main": "./app/dist/index.js",
|
||||
"version": "3.23.220",
|
||||
"version": "3.23.240",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"author": "Standard Notes.",
|
||||
"private": true,
|
||||
|
||||
@@ -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.18.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/encryption
|
||||
|
||||
## [1.18.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/encryption
|
||||
|
||||
## [1.18.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/encryption
|
||||
|
||||
## [1.18.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/encryption
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/encryption",
|
||||
"version": "1.18.2",
|
||||
"version": "1.18.5",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.53.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/features
|
||||
|
||||
## [1.53.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/features",
|
||||
"version": "1.53.1",
|
||||
"version": "1.53.2",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -5,4 +5,5 @@ export enum NoteType {
|
||||
RichText = 'rich-text',
|
||||
Spreadsheet = 'spreadsheet',
|
||||
Task = 'task',
|
||||
Plain = 'plain-text',
|
||||
}
|
||||
|
||||
@@ -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.24.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/filepicker
|
||||
|
||||
## [1.24.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/filepicker
|
||||
|
||||
## [1.24.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/filepicker
|
||||
|
||||
## [1.24.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/filepicker
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/filepicker",
|
||||
"version": "1.24.4",
|
||||
"version": "1.24.7",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.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.11.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files
|
||||
|
||||
## [1.11.6](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files
|
||||
|
||||
## [1.11.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files
|
||||
|
||||
## [1.11.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/files
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/files",
|
||||
"version": "1.11.4",
|
||||
"version": "1.11.7",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,88 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [3.43.27](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-23)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.26](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-23)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.25](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-22)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.24](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.23](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.22](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.21](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.20](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.19](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.18](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.17](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.16](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.15](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.14](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.13](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.12](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* help & feedback links on mobile ([#1849](https://github.com/standardnotes/app/issues/1849)) ([fb72c2f](https://github.com/standardnotes/app/commit/fb72c2fdae277cb4e348ce5ee550f0545f281dcd))
|
||||
|
||||
## [3.43.11](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.10](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.9](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.8](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
## [3.43.7](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/mobile
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="https"/>
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="mailto"/>
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
<array>
|
||||
<string>http</string>
|
||||
<string>https</string>
|
||||
<string>mailto</string>
|
||||
</array>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
<array>
|
||||
<string>http</string>
|
||||
<string>https</string>
|
||||
<string>mailto</string>
|
||||
</array>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/mobile",
|
||||
"version": "3.43.7",
|
||||
"version": "3.43.27",
|
||||
"author": "Standard Notes.",
|
||||
"private": true,
|
||||
"license": "AGPL-3.0-or-later",
|
||||
|
||||
@@ -3,6 +3,24 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.30.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
### Features
|
||||
|
||||
* ability to favorite tags + customize icon ([#1858](https://github.com/standardnotes/app/issues/1858)) ([cbd0063](https://github.com/standardnotes/app/commit/cbd0063926a416c23225242a4a1796712b6b224e))
|
||||
|
||||
## [1.29.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* issue with not being able to unlink a file from a note ([#1836](https://github.com/standardnotes/app/issues/1836)) ([4030953](https://github.com/standardnotes/app/commit/4030953b00ad609dc2b0f5b66cfd971d449f6121))
|
||||
|
||||
# [1.29.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
### Features
|
||||
|
||||
* authorize notes for listed ([#1823](https://github.com/standardnotes/app/issues/1823)) ([9954bdc](https://github.com/standardnotes/app/commit/9954bdc29f9de2a42c4539d55749991d86a72943))
|
||||
|
||||
# [1.28.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/models",
|
||||
"version": "1.28.0",
|
||||
"version": "1.30.0",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
@@ -25,6 +25,7 @@
|
||||
"@types/jest": "^28.1.5",
|
||||
"@types/lodash": "^4.14.182",
|
||||
"@typescript-eslint/eslint-plugin": "^5.30.0",
|
||||
"eslint": "*",
|
||||
"eslint-plugin-prettier": "*",
|
||||
"jest": "^28.1.2",
|
||||
"ts-jest": "^28.0.5",
|
||||
|
||||
@@ -8,6 +8,6 @@ export enum AppDataField {
|
||||
NotAvailableOnMobile = 'notAvailableOnMobile',
|
||||
MobileActive = 'mobileActive',
|
||||
LastSize = 'lastSize',
|
||||
PrefersPlainEditor = 'prefersPlainEditor',
|
||||
LegacyPrefersPlainEditor = 'prefersPlainEditor',
|
||||
ComponentInstallError = 'installError',
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { FillItemContent } from '../../Abstract/Content/ItemContent'
|
||||
import { SNComponent } from './Component'
|
||||
import { ComponentContent } from './ComponentContent'
|
||||
import { PayloadTimestampDefaults } from '../../Abstract/Payload'
|
||||
import { NoteType } from '@standardnotes/features'
|
||||
|
||||
describe('component model', () => {
|
||||
it('valid hosted url should ignore url', () => {
|
||||
@@ -46,4 +47,42 @@ describe('component model', () => {
|
||||
expect(component.hasValidHostedUrl()).toBe(true)
|
||||
expect(component.hosted_url).toBe('http://foo.com')
|
||||
})
|
||||
|
||||
it('should return noteType as specified in package_info', () => {
|
||||
const component = new SNComponent(
|
||||
new DecryptedPayload(
|
||||
{
|
||||
uuid: String(Math.random()),
|
||||
content_type: ContentType.Component,
|
||||
content: FillItemContent({
|
||||
package_info: {
|
||||
note_type: NoteType.Authentication,
|
||||
},
|
||||
} as ComponentContent),
|
||||
...PayloadTimestampDefaults(),
|
||||
},
|
||||
PayloadSource.Constructor,
|
||||
),
|
||||
)
|
||||
|
||||
expect(component.noteType).toEqual(NoteType.Authentication)
|
||||
})
|
||||
|
||||
it('should return plain as noteType if no note type defined in package_info', () => {
|
||||
const component = new SNComponent(
|
||||
new DecryptedPayload(
|
||||
{
|
||||
uuid: String(Math.random()),
|
||||
content_type: ContentType.Component,
|
||||
content: FillItemContent({
|
||||
package_info: {},
|
||||
} as ComponentContent),
|
||||
...PayloadTimestampDefaults(),
|
||||
},
|
||||
PayloadSource.Constructor,
|
||||
),
|
||||
)
|
||||
|
||||
expect(component.noteType).toEqual(NoteType.Plain)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
ComponentFlag,
|
||||
ComponentPermission,
|
||||
FindNativeFeature,
|
||||
NoteType,
|
||||
} from '@standardnotes/features'
|
||||
import { AppDataField } from '../../Abstract/Item/Types/AppDataField'
|
||||
import { ComponentContent, ComponentInterface } from './ComponentContent'
|
||||
@@ -177,6 +178,10 @@ export class SNComponent extends DecryptedItem<ComponentContent> implements Comp
|
||||
return this.package_info as ThirdPartyFeatureDescription
|
||||
}
|
||||
|
||||
public get noteType(): NoteType {
|
||||
return this.package_info.note_type || NoteType.Plain
|
||||
}
|
||||
|
||||
public get isDeprecated(): boolean {
|
||||
let flags: string[] = this.package_info.flags ?? []
|
||||
flags = flags.map((flag: string) => flag.toLowerCase())
|
||||
|
||||
@@ -4,7 +4,8 @@ import { DecryptedPayloadInterface } from '../../Abstract/Payload/Interfaces/Dec
|
||||
import { FileMetadata } from './FileMetadata'
|
||||
import { FileProtocolV1 } from './FileProtocolV1'
|
||||
import { SortableItem } from '../../Runtime/Collection/CollectionSort'
|
||||
import { ConflictStrategy } from '../../Abstract/Item'
|
||||
import { ConflictStrategy, ItemInterface } from '../../Abstract/Item'
|
||||
import { ContentType } from '@standardnotes/common'
|
||||
|
||||
type EncryptedBytesLength = number
|
||||
type DecryptedBytesLength = number
|
||||
@@ -31,6 +32,8 @@ export type FileContentSpecialized = FileContentWithoutSize & FileMetadata & Siz
|
||||
|
||||
export type FileContent = FileContentSpecialized & ItemContent
|
||||
|
||||
export const isFile = (x: ItemInterface): x is FileItem => x.content_type === ContentType.File
|
||||
|
||||
export class FileItem
|
||||
extends DecryptedItem<FileContent>
|
||||
implements FileContentWithoutSize, Sizes, FileProtocolV1, FileMetadata, SortableItem
|
||||
|
||||
@@ -29,14 +29,9 @@ describe('SNNote Tests', () => {
|
||||
expect(note.preview_html).toBeFalsy()
|
||||
})
|
||||
|
||||
it('should set mobilePrefersPlainEditor when given a valid choice', () => {
|
||||
const selected = createNote({
|
||||
mobilePrefersPlainEditor: true,
|
||||
})
|
||||
it('should not set default value for note type if none is provided', () => {
|
||||
const note = createNote({})
|
||||
|
||||
const unselected = createNote()
|
||||
|
||||
expect(selected.mobilePrefersPlainEditor).toBeTruthy()
|
||||
expect(unselected.mobilePrefersPlainEditor).toBe(undefined)
|
||||
expect(note.noteType).toBe(undefined)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { AppDataField } from './../../Abstract/Item/Types/AppDataField'
|
||||
import { ContentType } from '@standardnotes/common'
|
||||
import { FeatureIdentifier, NoteType } from '@standardnotes/features'
|
||||
import { DecryptedItem } from '../../Abstract/Item/Implementations/DecryptedItem'
|
||||
import { ItemInterface } from '../../Abstract/Item/Interfaces/ItemInterface'
|
||||
import { AppDataField } from '../../Abstract/Item/Types/AppDataField'
|
||||
import { DecryptedPayloadInterface } from '../../Abstract/Payload/Interfaces/DecryptedPayload'
|
||||
import { NoteContent, NoteContentSpecialized } from './NoteContent'
|
||||
|
||||
@@ -10,12 +11,15 @@ export const isNote = (x: ItemInterface): x is SNNote => x.content_type === Cont
|
||||
export class SNNote extends DecryptedItem<NoteContent> implements NoteContentSpecialized {
|
||||
public readonly title: string
|
||||
public readonly text: string
|
||||
public readonly mobilePrefersPlainEditor?: boolean
|
||||
public readonly hidePreview: boolean = false
|
||||
public readonly preview_plain: string
|
||||
public readonly preview_html: string
|
||||
public readonly prefersPlainEditor: boolean
|
||||
public readonly spellcheck?: boolean
|
||||
public readonly noteType?: NoteType
|
||||
public readonly authorizedForListed: boolean
|
||||
|
||||
/** The package_info.identifier of the editor (not its uuid), such as org.standardnotes.advanced-markdown */
|
||||
public readonly editorIdentifier?: FeatureIdentifier | string
|
||||
|
||||
constructor(payload: DecryptedPayloadInterface<NoteContent>) {
|
||||
super(payload)
|
||||
@@ -26,9 +30,15 @@ export class SNNote extends DecryptedItem<NoteContent> implements NoteContentSpe
|
||||
this.preview_html = String(this.payload.content.preview_html || '')
|
||||
this.hidePreview = Boolean(this.payload.content.hidePreview)
|
||||
this.spellcheck = this.payload.content.spellcheck
|
||||
this.noteType = this.payload.content.noteType
|
||||
this.editorIdentifier = this.payload.content.editorIdentifier
|
||||
this.authorizedForListed = this.payload.content.authorizedForListed || false
|
||||
|
||||
this.prefersPlainEditor = this.getAppDomainValueWithDefault(AppDataField.PrefersPlainEditor, false)
|
||||
|
||||
this.mobilePrefersPlainEditor = this.payload.content.mobilePrefersPlainEditor
|
||||
if (!this.noteType) {
|
||||
const prefersPlain = this.getAppDomainValueWithDefault(AppDataField.LegacyPrefersPlainEditor, false)
|
||||
if (prefersPlain) {
|
||||
this.noteType = NoteType.Plain
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import { FeatureIdentifier, NoteType } from '@standardnotes/features'
|
||||
import { ItemContent } from '../../Abstract/Content/ItemContent'
|
||||
|
||||
export interface NoteContentSpecialized {
|
||||
title: string
|
||||
text: string
|
||||
mobilePrefersPlainEditor?: boolean
|
||||
hidePreview?: boolean
|
||||
preview_plain?: string
|
||||
preview_html?: string
|
||||
spellcheck?: boolean
|
||||
noteType?: NoteType
|
||||
editorIdentifier?: FeatureIdentifier | string
|
||||
authorizedForListed?: boolean
|
||||
}
|
||||
|
||||
export type NoteContent = NoteContentSpecialized & ItemContent
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { NoteMutator } from './NoteMutator'
|
||||
import { createNote } from './../../Utilities/Test/SpecUtils'
|
||||
import { MutationType } from '../../Abstract/Item'
|
||||
import { FeatureIdentifier, NoteType } from '@standardnotes/features'
|
||||
|
||||
describe('note mutator', () => {
|
||||
it('sets noteType', () => {
|
||||
const note = createNote({})
|
||||
const mutator = new NoteMutator(note, MutationType.NoUpdateUserTimestamps)
|
||||
mutator.noteType = NoteType.Authentication
|
||||
const result = mutator.getResult()
|
||||
|
||||
expect(result.content.noteType).toEqual(NoteType.Authentication)
|
||||
})
|
||||
|
||||
it('sets editorIdentifier', () => {
|
||||
const note = createNote({})
|
||||
const mutator = new NoteMutator(note, MutationType.NoUpdateUserTimestamps)
|
||||
mutator.editorIdentifier = FeatureIdentifier.MarkdownProEditor
|
||||
const result = mutator.getResult()
|
||||
|
||||
expect(result.content.editorIdentifier).toEqual(FeatureIdentifier.MarkdownProEditor)
|
||||
})
|
||||
})
|
||||
@@ -1,10 +1,10 @@
|
||||
import { AppDataField } from '../../Abstract/Item/Types/AppDataField'
|
||||
import { NoteContent } from './NoteContent'
|
||||
import { DecryptedItemMutator } from '../../Abstract/Item/Mutator/DecryptedItemMutator'
|
||||
import { SNNote } from './Note'
|
||||
import { NoteToNoteReference } from '../../Abstract/Reference/NoteToNoteReference'
|
||||
import { ContentType } from '@standardnotes/common'
|
||||
import { ContentReferenceType } from '../../Abstract/Item'
|
||||
import { FeatureIdentifier, NoteType } from '@standardnotes/features'
|
||||
|
||||
export class NoteMutator extends DecryptedItemMutator<NoteContent> {
|
||||
set title(title: string) {
|
||||
@@ -27,14 +27,22 @@ export class NoteMutator extends DecryptedItemMutator<NoteContent> {
|
||||
this.mutableContent.preview_html = preview_html
|
||||
}
|
||||
|
||||
set prefersPlainEditor(prefersPlainEditor: boolean) {
|
||||
this.setAppDataItem(AppDataField.PrefersPlainEditor, prefersPlainEditor)
|
||||
}
|
||||
|
||||
set spellcheck(spellcheck: boolean) {
|
||||
this.mutableContent.spellcheck = spellcheck
|
||||
}
|
||||
|
||||
set noteType(noteType: NoteType) {
|
||||
this.mutableContent.noteType = noteType
|
||||
}
|
||||
|
||||
set editorIdentifier(identifier: FeatureIdentifier | string | undefined) {
|
||||
this.mutableContent.editorIdentifier = identifier
|
||||
}
|
||||
|
||||
set authorizedForListed(authorizedForListed: boolean) {
|
||||
this.mutableContent.authorizedForListed = authorizedForListed
|
||||
}
|
||||
|
||||
toggleSpellcheck(): void {
|
||||
if (this.mutableContent.spellcheck == undefined) {
|
||||
this.mutableContent.spellcheck = false
|
||||
|
||||
@@ -1,41 +1,33 @@
|
||||
import { DecryptedItem } from '../../Abstract/Item/Implementations/DecryptedItem'
|
||||
import { PredicateInterface, PredicateJsonForm } from '../../Runtime/Predicate/Interface'
|
||||
import { PredicateInterface } from '../../Runtime/Predicate/Interface'
|
||||
import { predicateFromJson } from '../../Runtime/Predicate/Generators'
|
||||
import { ItemContent } from '../../Abstract/Content/ItemContent'
|
||||
import { DecryptedPayloadInterface } from '../../Abstract/Payload/Interfaces/DecryptedPayload'
|
||||
import { SystemViewId } from './SystemViewId'
|
||||
import { EmojiString, IconType } from '../../Utilities/Icon/IconType'
|
||||
import { SmartViewDefaultIconName, systemViewIcon } from './SmartViewIcons'
|
||||
import { SmartViewContent } from './SmartViewContent'
|
||||
|
||||
export const SMART_TAG_DSL_PREFIX = '!['
|
||||
|
||||
export enum SystemViewId {
|
||||
AllNotes = 'all-notes',
|
||||
Files = 'files',
|
||||
ArchivedNotes = 'archived-notes',
|
||||
TrashedNotes = 'trashed-notes',
|
||||
UntaggedNotes = 'untagged-notes',
|
||||
StarredNotes = 'starred-notes',
|
||||
}
|
||||
|
||||
export interface SmartViewContent extends ItemContent {
|
||||
title: string
|
||||
predicate: PredicateJsonForm
|
||||
}
|
||||
|
||||
export function isSystemView(view: SmartView): boolean {
|
||||
return Object.values(SystemViewId).includes(view.uuid as SystemViewId)
|
||||
}
|
||||
|
||||
/**
|
||||
* A tag that defines a predicate that consumers can use
|
||||
* to retrieve a dynamic list of items.
|
||||
*/
|
||||
export class SmartView extends DecryptedItem<SmartViewContent> {
|
||||
public readonly predicate!: PredicateInterface<DecryptedItem>
|
||||
public readonly title: string
|
||||
public readonly iconString: IconType | EmojiString
|
||||
|
||||
constructor(payload: DecryptedPayloadInterface<SmartViewContent>) {
|
||||
super(payload)
|
||||
this.title = String(this.content.title || '')
|
||||
|
||||
if (isSystemView(this)) {
|
||||
this.iconString = systemViewIcon(this.uuid as SystemViewId)
|
||||
} else {
|
||||
this.iconString = this.payload.content.iconString || SmartViewDefaultIconName
|
||||
}
|
||||
|
||||
try {
|
||||
this.predicate = this.content.predicate && predicateFromJson(this.content.predicate)
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { DecryptedPayload } from './../../Abstract/Payload/Implementations/DecryptedPayload'
|
||||
import { SNNote } from '../Note/Note'
|
||||
import { SmartViewContent, SmartView, SystemViewId } from './SmartView'
|
||||
import { SmartView } from './SmartView'
|
||||
import { SmartViewContent } from './SmartViewContent'
|
||||
import { SystemViewId } from './SystemViewId'
|
||||
import { ItemWithTags } from '../../Runtime/Display/Search/ItemWithTags'
|
||||
import { ContentType } from '@standardnotes/common'
|
||||
import { FillItemContent } from '../../Abstract/Content/ItemContent'
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import { TagContent } from './../Tag/TagContent'
|
||||
import { PredicateJsonForm } from '../../Runtime/Predicate/Interface'
|
||||
|
||||
export interface SmartViewContent extends TagContent {
|
||||
predicate: PredicateJsonForm
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { SystemViewId } from './SystemViewId'
|
||||
import { IconType } from '../../Utilities/Icon/IconType'
|
||||
|
||||
export const SmartViewIcons: Record<SystemViewId, IconType> = {
|
||||
[SystemViewId.AllNotes]: 'notes',
|
||||
[SystemViewId.Files]: 'folder',
|
||||
[SystemViewId.ArchivedNotes]: 'archive',
|
||||
[SystemViewId.TrashedNotes]: 'trash',
|
||||
[SystemViewId.UntaggedNotes]: 'hashtag-off',
|
||||
[SystemViewId.StarredNotes]: 'star-filled',
|
||||
}
|
||||
|
||||
export function systemViewIcon(id: SystemViewId): IconType {
|
||||
return SmartViewIcons[id]
|
||||
}
|
||||
|
||||
export const SmartViewDefaultIconName: IconType = 'restore'
|
||||
@@ -0,0 +1,8 @@
|
||||
export enum SystemViewId {
|
||||
AllNotes = 'all-notes',
|
||||
Files = 'files',
|
||||
ArchivedNotes = 'archived-notes',
|
||||
TrashedNotes = 'trashed-notes',
|
||||
UntaggedNotes = 'untagged-notes',
|
||||
StarredNotes = 'starred-notes',
|
||||
}
|
||||
@@ -1,2 +1,4 @@
|
||||
export * from './SmartView'
|
||||
export * from './SmartViewBuilder'
|
||||
export * from './SystemViewId'
|
||||
export * from './SmartViewContent'
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { PayloadSource } from './../../Abstract/Payload/Types/PayloadSource'
|
||||
import { DecryptedPayload } from './../../Abstract/Payload/Implementations/DecryptedPayload'
|
||||
import { SNTag, TagContent } from './Tag'
|
||||
import { SNTag } from './Tag'
|
||||
import { ContentType } from '@standardnotes/common'
|
||||
import { FillItemContent } from '../../Abstract/Content/ItemContent'
|
||||
import { ContentReference } from '../../Abstract/Reference/ContentReference'
|
||||
import { PayloadTimestampDefaults } from '../../Abstract/Payload'
|
||||
import { TagContent } from './TagContent'
|
||||
|
||||
const randUuid = () => String(Math.random())
|
||||
|
||||
|
||||
@@ -1,32 +1,28 @@
|
||||
import { VectorIconNameOrEmoji, IconType } from './../../Utilities/Icon/IconType'
|
||||
import { ContentType, Uuid } from '@standardnotes/common'
|
||||
import { DecryptedItem } from '../../Abstract/Item/Implementations/DecryptedItem'
|
||||
import { ItemInterface } from '../../Abstract/Item/Interfaces/ItemInterface'
|
||||
import { ItemContent } from '../../Abstract/Content/ItemContent'
|
||||
import { ContentReference } from '../../Abstract/Reference/ContentReference'
|
||||
import { isTagToParentTagReference } from '../../Abstract/Reference/Functions'
|
||||
import { DecryptedPayloadInterface } from '../../Abstract/Payload/Interfaces/DecryptedPayload'
|
||||
import { TagContent, TagContentSpecialized } from './TagContent'
|
||||
|
||||
export const TagFolderDelimitter = '.'
|
||||
|
||||
interface TagInterface {
|
||||
title: string
|
||||
expanded: boolean
|
||||
}
|
||||
|
||||
export type TagContent = TagInterface & ItemContent
|
||||
export const DefaultTagIconName: IconType = 'hashtag'
|
||||
|
||||
export const isTag = (x: ItemInterface): x is SNTag => x.content_type === ContentType.Tag
|
||||
|
||||
export class SNTag extends DecryptedItem<TagContent> implements TagInterface {
|
||||
export class SNTag extends DecryptedItem<TagContent> implements TagContentSpecialized {
|
||||
public readonly title: string
|
||||
|
||||
/** Whether to render child tags in view hierarchy. Opposite of collapsed. */
|
||||
public readonly iconString: VectorIconNameOrEmoji
|
||||
public readonly expanded: boolean
|
||||
|
||||
constructor(payload: DecryptedPayloadInterface<TagContent>) {
|
||||
super(payload)
|
||||
this.title = this.payload.content.title || ''
|
||||
this.expanded = this.payload.content.expanded != undefined ? this.payload.content.expanded : true
|
||||
this.iconString = this.payload.content.iconString || DefaultTagIconName
|
||||
}
|
||||
|
||||
get noteReferences(): ContentReference[] {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { IconType } from './../../Utilities/Icon/IconType'
|
||||
import { ItemContent } from '../../Abstract/Content/ItemContent'
|
||||
import { EmojiString } from '../../Utilities/Icon/IconType'
|
||||
|
||||
export interface TagContentSpecialized {
|
||||
title: string
|
||||
expanded: boolean
|
||||
iconString: IconType | EmojiString
|
||||
}
|
||||
|
||||
export type TagContent = TagContentSpecialized & ItemContent
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ContentType } from '@standardnotes/common'
|
||||
import { TagContent, SNTag } from './Tag'
|
||||
import { SNTag } from './Tag'
|
||||
import { TagContent } from './TagContent'
|
||||
import { FileItem } from '../File'
|
||||
import { SNNote } from '../Note'
|
||||
import { isTagToParentTagReference } from '../../Abstract/Reference/Functions'
|
||||
@@ -17,6 +18,10 @@ export class TagMutator extends DecryptedItemMutator<TagContent> {
|
||||
this.mutableContent.expanded = expanded
|
||||
}
|
||||
|
||||
set iconString(iconString: string) {
|
||||
this.mutableContent.iconString = iconString
|
||||
}
|
||||
|
||||
public makeChildOf(tag: SNTag): void {
|
||||
const references = this.immutableItem.references.filter((ref) => !isTagToParentTagReference(ref))
|
||||
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './Tag'
|
||||
export * from './TagMutator'
|
||||
export * from './TagContent'
|
||||
|
||||
+4
@@ -1,3 +1,7 @@
|
||||
export type VectorIconNameOrEmoji = EmojiString | IconType
|
||||
|
||||
export type EmojiString = string
|
||||
|
||||
export type IconType =
|
||||
| 'accessibility'
|
||||
| 'account-card-details-outline'
|
||||
@@ -1,55 +0,0 @@
|
||||
import { DecryptedPayloadInterface } from './../../Abstract/Payload/Interfaces/DecryptedPayload'
|
||||
import { ComponentContent } from '../../Syncable/Component/ComponentContent'
|
||||
import { ComponentArea } from '@standardnotes/features'
|
||||
import { ContentType } from '@standardnotes/common'
|
||||
import { ComponentMutator, SNComponent } from '../../Syncable/Component'
|
||||
import { CreateDecryptedItemFromPayload } from '../Item/ItemGenerator'
|
||||
import { ImmutablePayloadCollection } from '../../Runtime/Collection/Payload/ImmutablePayloadCollection'
|
||||
import { MutationType } from '../../Abstract/Item/Types/MutationType'
|
||||
import { FullyFormedPayloadInterface } from '../../Abstract/Payload/Interfaces/UnionTypes'
|
||||
import { isDecryptedPayload } from '../../Abstract/Payload'
|
||||
import { SyncResolvedPayload } from '../../Runtime/Deltas/Utilities/SyncResolvedPayload'
|
||||
|
||||
export type AffectorFunction = (
|
||||
basePayload: FullyFormedPayloadInterface,
|
||||
duplicatePayload: FullyFormedPayloadInterface,
|
||||
baseCollection: ImmutablePayloadCollection<FullyFormedPayloadInterface>,
|
||||
) => SyncResolvedPayload[]
|
||||
|
||||
const NoteDuplicationAffectedPayloads: AffectorFunction = (
|
||||
basePayload: FullyFormedPayloadInterface,
|
||||
duplicatePayload: FullyFormedPayloadInterface,
|
||||
baseCollection: ImmutablePayloadCollection<FullyFormedPayloadInterface>,
|
||||
) => {
|
||||
/** If note has editor, maintain editor relationship in duplicate note */
|
||||
const components = baseCollection
|
||||
.all(ContentType.Component)
|
||||
.filter(isDecryptedPayload)
|
||||
.map((payload) => {
|
||||
return CreateDecryptedItemFromPayload<ComponentContent, SNComponent>(
|
||||
payload as DecryptedPayloadInterface<ComponentContent>,
|
||||
)
|
||||
})
|
||||
|
||||
const editor = components
|
||||
.filter((c) => c.area === ComponentArea.Editor)
|
||||
.find((e) => {
|
||||
return e.isExplicitlyEnabledForItem(basePayload.uuid)
|
||||
})
|
||||
|
||||
if (!editor) {
|
||||
return []
|
||||
}
|
||||
|
||||
/** Modify the editor to include new note */
|
||||
const mutator = new ComponentMutator(editor, MutationType.NoUpdateUserTimestamps)
|
||||
mutator.associateWithItem(duplicatePayload.uuid)
|
||||
|
||||
const result = mutator.getResult() as SyncResolvedPayload
|
||||
|
||||
return [result]
|
||||
}
|
||||
|
||||
export const AffectorMapping = {
|
||||
[ContentType.Note]: NoteDuplicationAffectedPayloads,
|
||||
} as Partial<Record<ContentType, AffectorFunction>>
|
||||
@@ -2,7 +2,6 @@ import { PayloadSource } from './../../Abstract/Payload/Types/PayloadSource'
|
||||
import { extendArray, UuidGenerator } from '@standardnotes/utils'
|
||||
import { ImmutablePayloadCollection } from '../../Runtime/Collection/Payload/ImmutablePayloadCollection'
|
||||
import { ItemContent } from '../../Abstract/Content/ItemContent'
|
||||
import { AffectorMapping } from './AffectorFunction'
|
||||
import { PayloadsByUpdatingReferencingPayloadReferences } from './PayloadsByUpdatingReferencingPayloadReferences'
|
||||
import { isDecryptedPayload } from '../../Abstract/Payload/Interfaces/TypeCheck'
|
||||
import { FullyFormedPayloadInterface } from '../../Abstract/Payload/Interfaces/UnionTypes'
|
||||
@@ -69,13 +68,5 @@ export function PayloadsByDuplicating<C extends ItemContent = ItemContent>(dto:
|
||||
extendArray(results, updatedReferencing)
|
||||
}
|
||||
|
||||
const affector = AffectorMapping[payload.content_type]
|
||||
if (affector) {
|
||||
const affected = affector(payload, copy, baseCollection)
|
||||
if (affected) {
|
||||
extendArray(results, affected)
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TagContent } from './../../Syncable/Tag/Tag'
|
||||
import { TagContent } from './../../Syncable/Tag/TagContent'
|
||||
import { ContentType } from '@standardnotes/common'
|
||||
import { FillItemContent, ItemContent } from '../../Abstract/Content/ItemContent'
|
||||
import { DecryptedPayload, PayloadSource, PayloadTimestampDefaults } from '../../Abstract/Payload'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export * from './Abstract/Component/ActionObserver'
|
||||
export * from './Abstract/Component/ComponentViewerEvent'
|
||||
export * from './Abstract/Component/ComponentMessage'
|
||||
export * from './Abstract/Component/ComponentEventObserver'
|
||||
export * from './Abstract/Component/ComponentMessage'
|
||||
export * from './Abstract/Component/ComponentViewerEvent'
|
||||
export * from './Abstract/Component/IncomingComponentItemPayload'
|
||||
export * from './Abstract/Component/KeyboardModifier'
|
||||
export * from './Abstract/Component/MessageData'
|
||||
@@ -43,9 +43,9 @@ export * from './Runtime/Collection/Payload/ImmutablePayloadCollection'
|
||||
export * from './Runtime/Collection/Payload/PayloadCollection'
|
||||
export * from './Runtime/Deltas'
|
||||
export * from './Runtime/DirtyCounter/DirtyCounter'
|
||||
export * from './Runtime/Display'
|
||||
export * from './Runtime/Display/ItemDisplayController'
|
||||
export * from './Runtime/Display/Types'
|
||||
export * from './Runtime/Display'
|
||||
export * from './Runtime/History'
|
||||
export * from './Runtime/Index/ItemDelta'
|
||||
export * from './Runtime/Index/SNIndex'
|
||||
@@ -70,11 +70,11 @@ export * from './Syncable/SmartView'
|
||||
export * from './Syncable/Tag'
|
||||
export * from './Syncable/Theme'
|
||||
export * from './Syncable/UserPrefs'
|
||||
export * from './Utilities/Icon/IconType'
|
||||
export * from './Utilities/Item/FindItem'
|
||||
export * from './Utilities/Item/ItemContentsDiffer'
|
||||
export * from './Utilities/Item/ItemContentsEqual'
|
||||
export * from './Utilities/Item/ItemGenerator'
|
||||
export * from './Utilities/Payload/AffectorFunction'
|
||||
export * from './Utilities/Payload/CopyPayloadWithContentOverride'
|
||||
export * from './Utilities/Payload/CreatePayload'
|
||||
export * from './Utilities/Payload/FindPayload'
|
||||
|
||||
@@ -3,6 +3,86 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.3.169](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-23)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.168](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-23)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.167](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-22)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.166](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.165](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.164](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.163](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.162](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.161](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.160](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.159](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.158](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.157](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.156](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.155](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.154](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-20)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.153](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.152](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.151](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.150](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
## [1.3.149](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/releases
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/releases",
|
||||
"version": "1.3.149",
|
||||
"version": "1.3.169",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"main": "dist/releases.json",
|
||||
"types": "dist/index.d.ts",
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.11.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/responses
|
||||
|
||||
## [1.11.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/responses
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/responses",
|
||||
"version": "1.11.1",
|
||||
"version": "1.11.2",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.34.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/services
|
||||
|
||||
## [1.34.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/services
|
||||
|
||||
## [1.34.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/services
|
||||
|
||||
## [1.34.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* issue with not being able to unlink a file from a note ([#1836](https://github.com/standardnotes/app/issues/1836)) ([4030953](https://github.com/standardnotes/app/commit/4030953b00ad609dc2b0f5b66cfd971d449f6121))
|
||||
|
||||
# [1.34.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
### Features
|
||||
|
||||
* authorize notes for listed ([#1823](https://github.com/standardnotes/app/issues/1823)) ([9954bdc](https://github.com/standardnotes/app/commit/9954bdc29f9de2a42c4539d55749991d86a72943))
|
||||
|
||||
## [1.33.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/services
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/services",
|
||||
"version": "1.33.1",
|
||||
"version": "1.34.4",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -24,4 +24,5 @@ export enum ChallengeReason {
|
||||
UnprotectFile,
|
||||
UnprotectNote,
|
||||
DeleteAccount,
|
||||
AuthorizeNoteForListed,
|
||||
}
|
||||
|
||||
@@ -20,5 +20,5 @@ export interface ComponentManagerInterface {
|
||||
urlOverride?: string,
|
||||
): ComponentViewerInterface
|
||||
presentPermissionsDialog(_dialog: PermissionDialog): void
|
||||
getDefaultEditor(): SNComponent
|
||||
getDefaultEditor(): SNComponent | undefined
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/* istanbul ignore file */
|
||||
|
||||
export enum ItemRelationshipDirection {
|
||||
AReferencesB,
|
||||
BReferencesA,
|
||||
NoRelationship,
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
/* istanbul ignore file */
|
||||
|
||||
import { ContentType, Uuid } from '@standardnotes/common'
|
||||
import {
|
||||
SNNote,
|
||||
@@ -76,9 +78,9 @@ export interface ItemsClientInterface {
|
||||
linkNoteToNote(note: SNNote, otherNote: SNNote): Promise<SNNote>
|
||||
linkFileToFile(file: FileItem, otherFile: FileItem): Promise<FileItem>
|
||||
|
||||
unlinkItem(
|
||||
item: DecryptedItemInterface<ItemContent>,
|
||||
itemToUnlink: DecryptedItemInterface<ItemContent>,
|
||||
unlinkItems(
|
||||
itemOne: DecryptedItemInterface<ItemContent>,
|
||||
itemTwo: DecryptedItemInterface<ItemContent>,
|
||||
): Promise<DecryptedItemInterface<ItemContent>>
|
||||
|
||||
/**
|
||||
@@ -115,12 +117,6 @@ export interface ItemsClientInterface {
|
||||
*/
|
||||
getSortedTagsForItem(item: DecryptedItemInterface<ItemContent>): SNTag[]
|
||||
|
||||
getSortedLinkedFilesForItem(item: DecryptedItemInterface<ItemContent>): FileItem[]
|
||||
getSortedFilesLinkingToItem(item: DecryptedItemInterface<ItemContent>): FileItem[]
|
||||
|
||||
getSortedLinkedNotesForItem(item: DecryptedItemInterface<ItemContent>): SNNote[]
|
||||
getSortedNotesLinkingToItem(item: DecryptedItemInterface<ItemContent>): SNNote[]
|
||||
|
||||
isSmartViewTitle(title: string): boolean
|
||||
|
||||
getSmartViews(): SmartView[]
|
||||
@@ -152,12 +148,4 @@ export interface ItemsClientInterface {
|
||||
* @returns Whether the item is a template (unmanaged)
|
||||
*/
|
||||
isTemplateItem(item: DecryptedItemInterface): boolean
|
||||
|
||||
/**
|
||||
* @returns `'direct'` if `itemOne` has the reference to `itemTwo`, `'indirect'` if `itemTwo` has the reference to `itemOne`, `'unlinked'` if neither reference each other
|
||||
*/
|
||||
relationshipTypeForItems(
|
||||
itemOne: DecryptedItemInterface,
|
||||
itemTwo: DecryptedItemInterface,
|
||||
): 'direct' | 'indirect' | 'unlinked'
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ export * from './Item/ItemCounterInterface'
|
||||
export * from './Item/ItemManagerInterface'
|
||||
export * from './Item/ItemsClientInterface'
|
||||
export * from './Item/ItemsServerInterface'
|
||||
export * from './Item/ItemRelationshipDirection'
|
||||
export * from './Mutator/MutatorClientInterface'
|
||||
export * from './Payloads/PayloadManagerInterface'
|
||||
export * from './Preferences/PreferenceServiceInterface'
|
||||
|
||||
@@ -3,6 +3,34 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [2.143.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
### Features
|
||||
|
||||
* ability to favorite tags + customize icon ([#1858](https://github.com/standardnotes/app/issues/1858)) ([cbd0063](https://github.com/standardnotes/app/commit/cbd0063926a416c23225242a4a1796712b6b224e))
|
||||
|
||||
## [2.142.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* refactor application event observing on web ([9fb85cd](https://github.com/standardnotes/app/commit/9fb85cd77a627364738a9c21706431d2a01e9c44))
|
||||
|
||||
## [2.142.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/snjs
|
||||
|
||||
## [2.142.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* issue with not being able to unlink a file from a note ([#1836](https://github.com/standardnotes/app/issues/1836)) ([4030953](https://github.com/standardnotes/app/commit/4030953b00ad609dc2b0f5b66cfd971d449f6121))
|
||||
|
||||
# [2.142.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
### Features
|
||||
|
||||
* authorize notes for listed ([#1823](https://github.com/standardnotes/app/issues/1823)) ([9954bdc](https://github.com/standardnotes/app/commit/9954bdc29f9de2a42c4539d55749991d86a72943))
|
||||
|
||||
## [2.141.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/snjs
|
||||
|
||||
@@ -68,7 +68,7 @@ import { ClientDisplayableError } from '@standardnotes/responses'
|
||||
|
||||
import { SnjsVersion } from './../Version'
|
||||
import { SNLog } from '../Log'
|
||||
import { Challenge, ChallengeResponse } from '../Services'
|
||||
import { Challenge, ChallengeResponse, ListedClientInterface } from '../Services'
|
||||
import { ApplicationConstructorOptions, FullyResolvedApplicationOptions } from './Options/ApplicationOptions'
|
||||
import { ApplicationOptionsDefaults } from './Options/Defaults'
|
||||
|
||||
@@ -86,9 +86,7 @@ type ApplicationObserver = {
|
||||
|
||||
type ObserverRemover = () => void
|
||||
|
||||
export class SNApplication
|
||||
implements ApplicationInterface, AppGroupManagedApplication, InternalServices.ListedClientInterface
|
||||
{
|
||||
export class SNApplication implements ApplicationInterface, AppGroupManagedApplication {
|
||||
onDeinit!: ExternalServices.DeinitCallback
|
||||
|
||||
/**
|
||||
@@ -273,6 +271,10 @@ export class SNApplication
|
||||
return this.componentManagerService
|
||||
}
|
||||
|
||||
public get listed(): ListedClientInterface {
|
||||
return this.listedService
|
||||
}
|
||||
|
||||
public computePrivateUsername(username: string): Promise<string | undefined> {
|
||||
return ComputePrivateUsername(this.options.crypto, username)
|
||||
}
|
||||
@@ -682,25 +684,6 @@ export class SNApplication
|
||||
return this.protectionService.authorizeSearchingProtectedNotesText()
|
||||
}
|
||||
|
||||
public canRegisterNewListedAccount(): boolean {
|
||||
return this.listedService.canRegisterNewListedAccount()
|
||||
}
|
||||
|
||||
public async requestNewListedAccount(): Promise<Responses.ListedAccount | undefined> {
|
||||
return this.listedService.requestNewListedAccount()
|
||||
}
|
||||
|
||||
public async getListedAccounts(): Promise<Responses.ListedAccount[]> {
|
||||
return this.listedService.getListedAccounts()
|
||||
}
|
||||
|
||||
public getListedAccountInfo(
|
||||
account: Responses.ListedAccount,
|
||||
inContextOfItem?: UuidString,
|
||||
): Promise<Responses.ListedAccountInfo | undefined> {
|
||||
return this.listedService.getListedAccountInfo(account, inContextOfItem)
|
||||
}
|
||||
|
||||
public async createEncryptedBackupFileForAutomatedDesktopBackups(): Promise<BackupFile | undefined> {
|
||||
return this.protocolService.createEncryptedBackupFile()
|
||||
}
|
||||
@@ -1096,11 +1079,11 @@ export class SNApplication
|
||||
this.createComponentManager()
|
||||
this.createMigrationService()
|
||||
this.createMfaService()
|
||||
this.createListedService()
|
||||
this.createActionsManager()
|
||||
this.createFileService()
|
||||
this.createIntegrityService()
|
||||
this.createMutatorService()
|
||||
this.createListedService()
|
||||
this.createActionsManager()
|
||||
this.createStatusService()
|
||||
|
||||
if (isDesktopDevice(this.deviceInterface)) {
|
||||
@@ -1175,6 +1158,8 @@ export class SNApplication
|
||||
this.itemManager,
|
||||
this.settingsService,
|
||||
this.deprecatedHttpService,
|
||||
this.protectionService,
|
||||
this.mutator,
|
||||
this.internalEventBus,
|
||||
)
|
||||
this.services.push(this.listedService)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { NoteType } from '@standardnotes/features'
|
||||
import { IconType } from '@Lib/Types/IconType'
|
||||
import { IconType } from '@standardnotes/models'
|
||||
|
||||
export class IconsController {
|
||||
getIconForFileType(type: string): IconType {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { SNApplication } from './../Application/Application'
|
||||
import { ContentType } from '@standardnotes/common'
|
||||
import { MutatorService } from './../Services/Mutator/MutatorService'
|
||||
import { SNComponentManager } from './../Services/ComponentManager/ComponentManager'
|
||||
import { NoteType } from '@standardnotes/features'
|
||||
import { NoteViewController } from './NoteViewController'
|
||||
|
||||
describe('note view controller', () => {
|
||||
let application: SNApplication
|
||||
|
||||
beforeEach(() => {
|
||||
application = {} as jest.Mocked<SNApplication>
|
||||
application.streamItems = jest.fn()
|
||||
|
||||
const componentManager = {} as jest.Mocked<SNComponentManager>
|
||||
componentManager.getDefaultEditor = jest.fn()
|
||||
Object.defineProperty(application, 'componentManager', { value: componentManager })
|
||||
|
||||
const mutator = {} as jest.Mocked<MutatorService>
|
||||
mutator.createTemplateItem = jest.fn()
|
||||
Object.defineProperty(application, 'mutator', { value: mutator })
|
||||
})
|
||||
|
||||
it('should create notes with plaintext note type', async () => {
|
||||
const controller = new NoteViewController(application)
|
||||
await controller.initialize(false)
|
||||
|
||||
expect(application.mutator.createTemplateItem).toHaveBeenCalledWith(
|
||||
ContentType.Note,
|
||||
expect.objectContaining({ noteType: NoteType.Plain }),
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -1,3 +1,4 @@
|
||||
import { NoteType } from '@standardnotes/features'
|
||||
import {
|
||||
NoteMutator,
|
||||
SNNote,
|
||||
@@ -66,9 +67,12 @@ export class NoteViewController implements ItemViewControllerInterface {
|
||||
|
||||
async initialize(addTagHierarchy: boolean): Promise<void> {
|
||||
if (!this.item) {
|
||||
const editor = this.application.componentManager.getDefaultEditor()
|
||||
const note = this.application.mutator.createTemplateItem<NoteContent, SNNote>(ContentType.Note, {
|
||||
text: '',
|
||||
title: this.defaultTitle || '',
|
||||
noteType: editor?.noteType || NoteType.Plain,
|
||||
editorIdentifier: editor?.identifier,
|
||||
references: [],
|
||||
})
|
||||
|
||||
|
||||
@@ -167,6 +167,7 @@ export const ChallengeStrings = {
|
||||
SelectProtectedNote: 'Authentication is required to select a protected note',
|
||||
DisableMfa: 'Authentication is required to disable two-factor authentication',
|
||||
DeleteAccount: 'Authentication is required to delete your account',
|
||||
ListedAuthorization: 'Authentication is required to approve this note for Listed',
|
||||
}
|
||||
|
||||
export const ErrorAlertStrings = {
|
||||
|
||||
@@ -79,6 +79,8 @@ export class Challenge implements ChallengeInterface {
|
||||
return ChallengeStrings.DisableMfa
|
||||
case ChallengeReason.DeleteAccount:
|
||||
return ChallengeStrings.DeleteAccount
|
||||
case ChallengeReason.AuthorizeNoteForListed:
|
||||
return ChallengeStrings.ListedAuthorization
|
||||
case ChallengeReason.Custom:
|
||||
return ''
|
||||
default:
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
*/
|
||||
|
||||
import { SNPreferencesService } from '../Preferences/PreferencesService'
|
||||
import { createNote } from './../../Spec/SpecUtils'
|
||||
import {
|
||||
ComponentAction,
|
||||
ComponentPermission,
|
||||
FeatureDescription,
|
||||
FindNativeFeature,
|
||||
FeatureIdentifier,
|
||||
NoteType,
|
||||
} from '@standardnotes/features'
|
||||
import { ContentType } from '@standardnotes/common'
|
||||
import { GenericItem, SNComponent, Environment, Platform } from '@standardnotes/models'
|
||||
@@ -306,6 +308,26 @@ describe('featuresService', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('editors', () => {
|
||||
it('getEditorForNote should return undefined is note type is plain', () => {
|
||||
const note = createNote({
|
||||
noteType: NoteType.Plain,
|
||||
})
|
||||
const manager = createManager(Environment.Web, Platform.MacWeb)
|
||||
|
||||
expect(manager.editorForNote(note)).toBe(undefined)
|
||||
})
|
||||
|
||||
it('getEditorForNote should call legacy function if no note editorIdentifier or noteType', () => {
|
||||
const note = createNote({})
|
||||
const manager = createManager(Environment.Web, Platform.MacWeb)
|
||||
manager['legacyGetEditorForNote'] = jest.fn()
|
||||
manager.editorForNote(note)
|
||||
|
||||
expect(manager['legacyGetEditorForNote']).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('editor change alert', () => {
|
||||
it('should not require alert switching from plain editor', () => {
|
||||
const manager = createManager(Environment.Web, Platform.MacWeb)
|
||||
|
||||
@@ -17,7 +17,14 @@ import {
|
||||
import { SNSyncService } from '@Lib/Services/Sync/SyncService'
|
||||
import find from 'lodash/find'
|
||||
import uniq from 'lodash/uniq'
|
||||
import { ComponentArea, ComponentAction, ComponentPermission, FindNativeFeature } from '@standardnotes/features'
|
||||
import {
|
||||
ComponentArea,
|
||||
ComponentAction,
|
||||
ComponentPermission,
|
||||
FindNativeFeature,
|
||||
NoteType,
|
||||
FeatureIdentifier,
|
||||
} from '@standardnotes/features'
|
||||
import { Copy, filterFromArray, removeFromArray, sleep, assert } from '@standardnotes/utils'
|
||||
import { UuidString } from '@Lib/Types/UuidString'
|
||||
import { AllowedBatchContentTypes } from '@Lib/Services/ComponentManager/Types'
|
||||
@@ -112,6 +119,10 @@ export class SNComponentManager
|
||||
})
|
||||
}
|
||||
|
||||
componentWithIdentifier(identifier: FeatureIdentifier | string): SNComponent | undefined {
|
||||
return this.components.find((component) => component.identifier === identifier)
|
||||
}
|
||||
|
||||
override deinit(): void {
|
||||
super.deinit()
|
||||
|
||||
@@ -569,13 +580,6 @@ export class SNComponentManager
|
||||
}
|
||||
|
||||
allComponentIframes(): HTMLIFrameElement[] {
|
||||
if (this.isMobile) {
|
||||
/**
|
||||
* Retrieving all iframes is typically related to lifecycle management of
|
||||
* non-editor components. So this function is not useful to mobile.
|
||||
*/
|
||||
return []
|
||||
}
|
||||
return Array.from(document.getElementsByTagName('iframe'))
|
||||
}
|
||||
|
||||
@@ -584,23 +588,29 @@ export class SNComponentManager
|
||||
}
|
||||
|
||||
editorForNote(note: SNNote): SNComponent | undefined {
|
||||
if (note.editorIdentifier) {
|
||||
return this.componentWithIdentifier(note.editorIdentifier)
|
||||
}
|
||||
|
||||
if (note.noteType === NoteType.Plain) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return this.legacyGetEditorForNote(note)
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses legacy approach of note/editor association. New method uses note.editorIdentifier and note.noteType directly.
|
||||
*/
|
||||
private legacyGetEditorForNote(note: SNNote): SNComponent | undefined {
|
||||
const editors = this.componentsForArea(ComponentArea.Editor)
|
||||
for (const editor of editors) {
|
||||
if (editor.isExplicitlyEnabledForItem(note.uuid)) {
|
||||
return editor
|
||||
}
|
||||
}
|
||||
let defaultEditor
|
||||
/* No editor found for note. Use default editor, if note does not prefer system editor */
|
||||
if (this.isMobile) {
|
||||
if (!note.mobilePrefersPlainEditor) {
|
||||
defaultEditor = this.getDefaultEditor()
|
||||
}
|
||||
} else {
|
||||
if (!note.prefersPlainEditor) {
|
||||
defaultEditor = this.getDefaultEditor()
|
||||
}
|
||||
}
|
||||
const defaultEditor = this.getDefaultEditor()
|
||||
|
||||
if (defaultEditor && !defaultEditor.isExplicitlyDisabledForItem(note.uuid)) {
|
||||
return defaultEditor
|
||||
} else {
|
||||
@@ -608,15 +618,9 @@ export class SNComponentManager
|
||||
}
|
||||
}
|
||||
|
||||
getDefaultEditor(): SNComponent {
|
||||
getDefaultEditor(): SNComponent | undefined {
|
||||
const editors = this.componentsForArea(ComponentArea.Editor)
|
||||
if (this.isMobile) {
|
||||
return editors.filter((e) => {
|
||||
return e.isMobileDefault
|
||||
})[0]
|
||||
} else {
|
||||
return editors.filter((e) => e.isDefaultEditor())[0]
|
||||
}
|
||||
return editors.filter((e) => e.isDefaultEditor())[0]
|
||||
}
|
||||
|
||||
permissionsStringForPermissions(permissions: ComponentPermission[], component: SNComponent): string {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ContentType } from '@standardnotes/common'
|
||||
import { InternalEventBusInterface } from '@standardnotes/services'
|
||||
import { InternalEventBusInterface, ItemRelationshipDirection } from '@standardnotes/services'
|
||||
import { ItemManager } from './ItemManager'
|
||||
import { PayloadManager } from '../Payloads/PayloadManager'
|
||||
import { UuidGenerator } from '@standardnotes/utils'
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
SmartView,
|
||||
SystemViewId,
|
||||
} from '@standardnotes/models'
|
||||
import { createNoteWithTitle } from '../../Spec/SpecUtils'
|
||||
|
||||
const setupRandomUuid = () => {
|
||||
UuidGenerator.SetGenerator(() => String(Math.random()))
|
||||
@@ -83,19 +84,6 @@ describe('itemManager', () => {
|
||||
)
|
||||
}
|
||||
|
||||
const createNote = (title: string) => {
|
||||
return new Models.SNNote(
|
||||
new Models.DecryptedPayload({
|
||||
uuid: String(Math.random()),
|
||||
content_type: ContentType.Note,
|
||||
content: Models.FillItemContent<Models.NoteContent>({
|
||||
title: title,
|
||||
}),
|
||||
...PayloadTimestampDefaults(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
const createFile = (name: string) => {
|
||||
return new Models.FileItem(
|
||||
new Models.DecryptedPayload({
|
||||
@@ -168,7 +156,7 @@ describe('itemManager', () => {
|
||||
it('viewing notes with tag', async () => {
|
||||
itemManager = createService()
|
||||
const tag = createTag('parent')
|
||||
const note = createNote('note')
|
||||
const note = createNoteWithTitle('note')
|
||||
await itemManager.insertItems([tag, note])
|
||||
await itemManager.addTagToNote(note, tag, false)
|
||||
|
||||
@@ -185,9 +173,9 @@ describe('itemManager', () => {
|
||||
it('viewing trashed notes smart view should include archived notes', async () => {
|
||||
itemManager = createService()
|
||||
|
||||
const archivedNote = createNote('archived')
|
||||
const trashedNote = createNote('trashed')
|
||||
const archivedAndTrashedNote = createNote('archived&trashed')
|
||||
const archivedNote = createNoteWithTitle('archived')
|
||||
const trashedNote = createNoteWithTitle('trashed')
|
||||
const archivedAndTrashedNote = createNoteWithTitle('archived&trashed')
|
||||
|
||||
await itemManager.insertItems([archivedNote, trashedNote, archivedAndTrashedNote])
|
||||
|
||||
@@ -389,8 +377,8 @@ describe('itemManager', () => {
|
||||
await itemManager.insertItems([parentTag, childTag])
|
||||
await itemManager.setTagParent(parentTag, childTag)
|
||||
|
||||
const parentNote = createNote('parentNote')
|
||||
const childNote = createNote('childNote')
|
||||
const parentNote = createNoteWithTitle('parentNote')
|
||||
const childNote = createNoteWithTitle('childNote')
|
||||
await itemManager.insertItems([parentNote, childNote])
|
||||
|
||||
await itemManager.addTagToNote(parentNote, parentTag, false)
|
||||
@@ -477,7 +465,7 @@ describe('itemManager', () => {
|
||||
const fooDelimiter = await itemManager.createTag('bar.foo')
|
||||
const barFooDelimiter = await itemManager.createTag('baz.bar.foo')
|
||||
const fooAttached = await itemManager.createTag('Foo')
|
||||
const note = createNote('note')
|
||||
const note = createNoteWithTitle('note')
|
||||
await itemManager.insertItems([foo, foobar, bar, barfoo, fooDelimiter, barFooDelimiter, fooAttached, note])
|
||||
await itemManager.addTagToNote(note, fooAttached, false)
|
||||
|
||||
@@ -501,8 +489,8 @@ describe('itemManager', () => {
|
||||
await itemManager.insertItems([parentTag, childTag])
|
||||
await itemManager.setTagParent(parentTag, childTag)
|
||||
|
||||
const parentNote = createNote('parentNote')
|
||||
const childNote = createNote('childNote')
|
||||
const parentNote = createNoteWithTitle('parentNote')
|
||||
const childNote = createNoteWithTitle('childNote')
|
||||
await itemManager.insertItems([parentNote, childNote])
|
||||
|
||||
await itemManager.addTagToNote(parentNote, parentTag, false)
|
||||
@@ -519,8 +507,8 @@ describe('itemManager', () => {
|
||||
const tag1 = createTag('tag 1')
|
||||
await itemManager.insertItems([tag1])
|
||||
|
||||
const note1 = createNote('note 1')
|
||||
const note2 = createNote('note 2')
|
||||
const note1 = createNoteWithTitle('note 1')
|
||||
const note2 = createNoteWithTitle('note 2')
|
||||
await itemManager.insertItems([note1, note2])
|
||||
|
||||
await itemManager.addTagToNote(note1, tag1, false)
|
||||
@@ -654,8 +642,8 @@ describe('itemManager', () => {
|
||||
const view = itemManager.untaggedNotesSmartView
|
||||
|
||||
const tag = createTag('tag')
|
||||
const untaggedNote = createNote('note')
|
||||
const taggedNote = createNote('taggedNote')
|
||||
const untaggedNote = createNoteWithTitle('note')
|
||||
const taggedNote = createNoteWithTitle('taggedNote')
|
||||
await itemManager.insertItems([tag, untaggedNote, taggedNote])
|
||||
|
||||
expect(itemManager.notesMatchingSmartView(view)).toHaveLength(2)
|
||||
@@ -704,7 +692,7 @@ describe('itemManager', () => {
|
||||
itemManager = createService()
|
||||
const parentTag = createTag('parent')
|
||||
const childTag = createTag('child')
|
||||
const note = createNote('note')
|
||||
const note = createNoteWithTitle('note')
|
||||
|
||||
await itemManager.insertItems([parentTag, childTag, note])
|
||||
await itemManager.setTagParent(parentTag, childTag)
|
||||
@@ -722,7 +710,7 @@ describe('itemManager', () => {
|
||||
itemManager = createService()
|
||||
const parentTag = createTag('parent')
|
||||
const childTag = createTag('child')
|
||||
const note = createNote('note')
|
||||
const note = createNoteWithTitle('note')
|
||||
|
||||
await itemManager.insertItems([parentTag, childTag, note])
|
||||
await itemManager.setTagParent(parentTag, childTag)
|
||||
@@ -772,7 +760,7 @@ describe('itemManager', () => {
|
||||
|
||||
it('should link file with note', async () => {
|
||||
itemManager = createService()
|
||||
const note = createNote('invoices')
|
||||
const note = createNoteWithTitle('invoices')
|
||||
const file = createFile('invoice_1.pdf')
|
||||
await itemManager.insertItems([note, file])
|
||||
|
||||
@@ -785,7 +773,7 @@ describe('itemManager', () => {
|
||||
|
||||
it('should unlink file from note', async () => {
|
||||
itemManager = createService()
|
||||
const note = createNote('invoices')
|
||||
const note = createNoteWithTitle('invoices')
|
||||
const file = createFile('invoice_1.pdf')
|
||||
await itemManager.insertItems([note, file])
|
||||
|
||||
@@ -796,25 +784,10 @@ describe('itemManager', () => {
|
||||
expect(references).toHaveLength(0)
|
||||
})
|
||||
|
||||
it('should get files linked with note', async () => {
|
||||
itemManager = createService()
|
||||
const note = createNote('invoices')
|
||||
const file = createFile('invoice_1.pdf')
|
||||
const secondFile = createFile('unrelated-file.xlsx')
|
||||
await itemManager.insertItems([note, file, secondFile])
|
||||
|
||||
await itemManager.associateFileWithNote(file, note)
|
||||
|
||||
const filesAssociatedWithNote = itemManager.getSortedFilesLinkingToItem(note)
|
||||
|
||||
expect(filesAssociatedWithNote).toHaveLength(1)
|
||||
expect(filesAssociatedWithNote[0].uuid).toBe(file.uuid)
|
||||
})
|
||||
|
||||
it('should link note to note', async () => {
|
||||
itemManager = createService()
|
||||
const note = createNote('research')
|
||||
const note2 = createNote('citation')
|
||||
const note = createNoteWithTitle('research')
|
||||
const note2 = createNoteWithTitle('citation')
|
||||
await itemManager.insertItems([note, note2])
|
||||
|
||||
const resultingNote = await itemManager.linkNoteToNote(note, note2)
|
||||
@@ -839,108 +812,56 @@ describe('itemManager', () => {
|
||||
|
||||
it('should get the relationship type for two items', async () => {
|
||||
itemManager = createService()
|
||||
const firstNote = createNote('First note')
|
||||
const secondNote = createNote('Second note')
|
||||
const unlinkedNote = createNote('Unlinked note')
|
||||
const firstNote = createNoteWithTitle('First note')
|
||||
const secondNote = createNoteWithTitle('Second note')
|
||||
const unlinkedNote = createNoteWithTitle('Unlinked note')
|
||||
await itemManager.insertItems([firstNote, secondNote, unlinkedNote])
|
||||
|
||||
const firstNoteLinkedToSecond = await itemManager.linkNoteToNote(firstNote, secondNote)
|
||||
|
||||
const relationshipOfFirstNoteToSecond = itemManager.relationshipTypeForItems(firstNoteLinkedToSecond, secondNote)
|
||||
const relationshipOfSecondNoteToFirst = itemManager.relationshipTypeForItems(secondNote, firstNoteLinkedToSecond)
|
||||
const relationshipOfFirstNoteToUnlinked = itemManager.relationshipTypeForItems(
|
||||
const relationshipOfFirstNoteToSecond = itemManager.relationshipDirectionBetweenItems(
|
||||
firstNoteLinkedToSecond,
|
||||
secondNote,
|
||||
)
|
||||
const relationshipOfSecondNoteToFirst = itemManager.relationshipDirectionBetweenItems(
|
||||
secondNote,
|
||||
firstNoteLinkedToSecond,
|
||||
)
|
||||
const relationshipOfFirstNoteToUnlinked = itemManager.relationshipDirectionBetweenItems(
|
||||
firstNoteLinkedToSecond,
|
||||
unlinkedNote,
|
||||
)
|
||||
|
||||
expect(relationshipOfFirstNoteToSecond).toBe('direct')
|
||||
expect(relationshipOfSecondNoteToFirst).toBe('indirect')
|
||||
expect(relationshipOfFirstNoteToUnlinked).toBe('unlinked')
|
||||
expect(relationshipOfFirstNoteToSecond).toBe(ItemRelationshipDirection.AReferencesB)
|
||||
expect(relationshipOfSecondNoteToFirst).toBe(ItemRelationshipDirection.BReferencesA)
|
||||
expect(relationshipOfFirstNoteToUnlinked).toBe(ItemRelationshipDirection.NoRelationship)
|
||||
})
|
||||
|
||||
it('should unlink itemToUnlink from item', async () => {
|
||||
it('should unlink itemOne from itemTwo if relation is direct', async () => {
|
||||
itemManager = createService()
|
||||
const note = createNote('Note 1')
|
||||
const note2 = createNote('Note 2')
|
||||
const note = createNoteWithTitle('Note 1')
|
||||
const note2 = createNoteWithTitle('Note 2')
|
||||
await itemManager.insertItems([note, note2])
|
||||
|
||||
const linkedItem = await itemManager.linkNoteToNote(note, note2)
|
||||
const unlinkedItem = await itemManager.unlinkItem(linkedItem, note2)
|
||||
const unlinkedItem = await itemManager.unlinkItems(linkedItem, note2)
|
||||
const references = unlinkedItem.references
|
||||
|
||||
expect(unlinkedItem.uuid).toBe(note.uuid)
|
||||
expect(references).toHaveLength(0)
|
||||
})
|
||||
|
||||
it('should get all linked files for item', async () => {
|
||||
it('should unlink itemTwo from itemOne if relation is indirect', async () => {
|
||||
itemManager = createService()
|
||||
const file = createFile('A1')
|
||||
const file2 = createFile('B2')
|
||||
const file3 = createFile('C3')
|
||||
const note = createNoteWithTitle('Note 1')
|
||||
const note2 = createNoteWithTitle('Note 2')
|
||||
await itemManager.insertItems([note, note2])
|
||||
|
||||
await itemManager.insertItems([file, file2, file3])
|
||||
const linkedItem = await itemManager.linkNoteToNote(note, note2)
|
||||
const changedItem = await itemManager.unlinkItems(linkedItem, note2)
|
||||
|
||||
await itemManager.linkFileToFile(file, file3)
|
||||
await itemManager.linkFileToFile(file, file2)
|
||||
|
||||
const sortedFilesForItem = itemManager.getSortedLinkedFilesForItem(file)
|
||||
|
||||
expect(sortedFilesForItem).toHaveLength(2)
|
||||
expect(sortedFilesForItem[0].uuid).toEqual(file2.uuid)
|
||||
expect(sortedFilesForItem[1].uuid).toEqual(file3.uuid)
|
||||
})
|
||||
|
||||
it('should get all files linking to item', async () => {
|
||||
itemManager = createService()
|
||||
const baseFile = createFile('file')
|
||||
const fileToLink1 = createFile('A1')
|
||||
const fileToLink2 = createFile('B2')
|
||||
|
||||
await itemManager.insertItems([baseFile, fileToLink1, fileToLink2])
|
||||
|
||||
await itemManager.linkFileToFile(fileToLink2, baseFile)
|
||||
await itemManager.linkFileToFile(fileToLink1, baseFile)
|
||||
|
||||
const sortedFilesForItem = itemManager.getSortedFilesLinkingToItem(baseFile)
|
||||
|
||||
expect(sortedFilesForItem).toHaveLength(2)
|
||||
expect(sortedFilesForItem[0].uuid).toEqual(fileToLink1.uuid)
|
||||
expect(sortedFilesForItem[1].uuid).toEqual(fileToLink2.uuid)
|
||||
})
|
||||
|
||||
it('should get all linked notes for item', async () => {
|
||||
itemManager = createService()
|
||||
const baseNote = createNote('note')
|
||||
const noteToLink1 = createNote('A1')
|
||||
const noteToLink2 = createNote('B2')
|
||||
|
||||
await itemManager.insertItems([baseNote, noteToLink1, noteToLink2])
|
||||
|
||||
await itemManager.linkNoteToNote(baseNote, noteToLink2)
|
||||
await itemManager.linkNoteToNote(baseNote, noteToLink1)
|
||||
|
||||
const sortedFilesForItem = itemManager.getSortedLinkedNotesForItem(baseNote)
|
||||
|
||||
expect(sortedFilesForItem).toHaveLength(2)
|
||||
expect(sortedFilesForItem[0].uuid).toEqual(noteToLink1.uuid)
|
||||
expect(sortedFilesForItem[1].uuid).toEqual(noteToLink2.uuid)
|
||||
})
|
||||
|
||||
it('should get all notes linking to item', async () => {
|
||||
itemManager = createService()
|
||||
const baseNote = createNote('note')
|
||||
const noteToLink1 = createNote('A1')
|
||||
const noteToLink2 = createNote('B2')
|
||||
|
||||
await itemManager.insertItems([baseNote, noteToLink1, noteToLink2])
|
||||
|
||||
await itemManager.linkNoteToNote(noteToLink2, baseNote)
|
||||
await itemManager.linkNoteToNote(noteToLink1, baseNote)
|
||||
|
||||
const sortedFilesForItem = itemManager.getSortedNotesLinkingToItem(baseNote)
|
||||
|
||||
expect(sortedFilesForItem).toHaveLength(2)
|
||||
expect(sortedFilesForItem[0].uuid).toEqual(noteToLink1.uuid)
|
||||
expect(sortedFilesForItem[1].uuid).toEqual(noteToLink2.uuid)
|
||||
expect(changedItem.uuid).toBe(note.uuid)
|
||||
expect(changedItem.references).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@ import { UuidString } from '../../Types/UuidString'
|
||||
import * as Models from '@standardnotes/models'
|
||||
import * as Services from '@standardnotes/services'
|
||||
import { PayloadManagerChangeData } from '../Payloads'
|
||||
import { DiagnosticInfo, ItemsClientInterface } from '@standardnotes/services'
|
||||
import { DiagnosticInfo, ItemsClientInterface, ItemRelationshipDirection } from '@standardnotes/services'
|
||||
import { ApplicationDisplayOptions } from '@Lib/Application/Options/OptionalOptions'
|
||||
import { CollectionSort, DecryptedItemInterface, ItemContent } from '@standardnotes/models'
|
||||
|
||||
@@ -1169,12 +1169,18 @@ export class ItemManager
|
||||
})
|
||||
}
|
||||
|
||||
public async unlinkItem(
|
||||
item: DecryptedItemInterface<ItemContent>,
|
||||
itemToUnlink: DecryptedItemInterface<ItemContent>,
|
||||
) {
|
||||
return this.changeItem(item, (mutator) => {
|
||||
mutator.removeItemAsRelationship(itemToUnlink)
|
||||
public async unlinkItems(itemA: DecryptedItemInterface<ItemContent>, itemB: DecryptedItemInterface<ItemContent>) {
|
||||
const relationshipDirection = this.relationshipDirectionBetweenItems(itemA, itemB)
|
||||
|
||||
if (relationshipDirection === ItemRelationshipDirection.NoRelationship) {
|
||||
throw new Error('Trying to unlink already unlinked items')
|
||||
}
|
||||
|
||||
const itemToChange = relationshipDirection === ItemRelationshipDirection.AReferencesB ? itemA : itemB
|
||||
const itemToRemove = itemToChange === itemA ? itemB : itemA
|
||||
|
||||
return this.changeItem(itemToChange, (mutator) => {
|
||||
mutator.removeItemAsRelationship(itemToRemove)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1192,54 +1198,6 @@ export class ItemManager
|
||||
)
|
||||
}
|
||||
|
||||
public getSortedLinkedFilesForItem(item: DecryptedItemInterface<ItemContent>): Models.FileItem[] {
|
||||
if (this.isTemplateItem(item)) {
|
||||
return []
|
||||
}
|
||||
|
||||
const filesReferencedByItem = this.referencesForItem(item).filter(
|
||||
(ref) => ref.content_type === ContentType.File,
|
||||
) as Models.FileItem[]
|
||||
|
||||
return naturalSort(filesReferencedByItem, 'title')
|
||||
}
|
||||
|
||||
public getSortedFilesLinkingToItem(item: DecryptedItemInterface<ItemContent>): Models.FileItem[] {
|
||||
if (this.isTemplateItem(item)) {
|
||||
return []
|
||||
}
|
||||
|
||||
const filesReferencingItem = this.itemsReferencingItem(item).filter(
|
||||
(ref) => ref.content_type === ContentType.File,
|
||||
) as Models.FileItem[]
|
||||
|
||||
return naturalSort(filesReferencingItem, 'title')
|
||||
}
|
||||
|
||||
public getSortedLinkedNotesForItem(item: DecryptedItemInterface<ItemContent>): Models.SNNote[] {
|
||||
if (this.isTemplateItem(item)) {
|
||||
return []
|
||||
}
|
||||
|
||||
const notesReferencedByItem = this.referencesForItem(item).filter(
|
||||
(ref) => ref.content_type === ContentType.Note,
|
||||
) as Models.SNNote[]
|
||||
|
||||
return naturalSort(notesReferencedByItem, 'title')
|
||||
}
|
||||
|
||||
public getSortedNotesLinkingToItem(item: Models.DecryptedItemInterface<Models.ItemContent>): Models.SNNote[] {
|
||||
if (this.isTemplateItem(item)) {
|
||||
return []
|
||||
}
|
||||
|
||||
const notesReferencingItem = this.itemsReferencingItem(item).filter(
|
||||
(ref) => ref.content_type === ContentType.Note,
|
||||
) as Models.SNNote[]
|
||||
|
||||
return naturalSort(notesReferencingItem, 'title')
|
||||
}
|
||||
|
||||
public async createTag(title: string, parentItemToLookupUuidFor?: Models.SNTag): Promise<Models.SNTag> {
|
||||
const newTag = await this.createItem<Models.SNTag>(
|
||||
ContentType.Tag,
|
||||
@@ -1433,21 +1391,18 @@ export class ItemManager
|
||||
return this.findAnyItems(uuids) as (Models.DecryptedItemInterface | Models.DeletedItemInterface)[]
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns `'direct'` if `itemOne` has the reference to `itemTwo`, `'indirect'` if `itemTwo` has the reference to `itemOne`, `'unlinked'` if neither reference each other
|
||||
*/
|
||||
public relationshipTypeForItems(
|
||||
itemOne: Models.DecryptedItemInterface<Models.ItemContent>,
|
||||
itemTwo: Models.DecryptedItemInterface<Models.ItemContent>,
|
||||
): 'direct' | 'indirect' | 'unlinked' {
|
||||
const itemOneReferencesItemTwo = this.isTemplateItem(itemOne)
|
||||
? false
|
||||
: !!this.referencesForItem(itemOne).find((reference) => reference.uuid === itemTwo.uuid)
|
||||
const itemTwoReferencesItemOne = this.isTemplateItem(itemTwo)
|
||||
? false
|
||||
: !!this.referencesForItem(itemTwo).find((reference) => reference.uuid === itemOne.uuid)
|
||||
public relationshipDirectionBetweenItems(
|
||||
itemA: Models.DecryptedItemInterface<Models.ItemContent>,
|
||||
itemB: Models.DecryptedItemInterface<Models.ItemContent>,
|
||||
): ItemRelationshipDirection {
|
||||
const itemAReferencesItemB = !!itemA.references.find((reference) => reference.uuid === itemB.uuid)
|
||||
const itemBReferencesItemA = !!itemB.references.find((reference) => reference.uuid === itemA.uuid)
|
||||
|
||||
return itemOneReferencesItemTwo ? 'direct' : itemTwoReferencesItemOne ? 'indirect' : 'unlinked'
|
||||
return itemAReferencesItemB
|
||||
? ItemRelationshipDirection.AReferencesB
|
||||
: itemBReferencesItemA
|
||||
? ItemRelationshipDirection.BReferencesA
|
||||
: ItemRelationshipDirection.NoRelationship
|
||||
}
|
||||
|
||||
override getDiagnostics(): Promise<DiagnosticInfo | undefined> {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SNNote } from '@standardnotes/models'
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
import { ListedAccount, ListedAccountInfo } from '@standardnotes/responses'
|
||||
|
||||
@@ -6,4 +7,6 @@ export interface ListedClientInterface {
|
||||
requestNewListedAccount: () => Promise<ListedAccount | undefined>
|
||||
getListedAccounts(): Promise<ListedAccount[]>
|
||||
getListedAccountInfo(account: ListedAccount, inContextOfItem?: Uuid): Promise<ListedAccountInfo | undefined>
|
||||
isNoteAuthorizedForListed(note: SNNote): boolean
|
||||
authorizeNoteForListed(note: SNNote): Promise<boolean>
|
||||
}
|
||||
|
||||
@@ -8,8 +8,9 @@ import { SNSettingsService } from '../Settings/SNSettingsService'
|
||||
import { ListedClientInterface } from './ListedClientInterface'
|
||||
import { SNApiService } from '../Api/ApiService'
|
||||
import { ListedAccount, ListedAccountInfo, ListedAccountInfoResponse } from '@standardnotes/responses'
|
||||
import { SNActionsExtension } from '@standardnotes/models'
|
||||
import { AbstractService, InternalEventBusInterface } from '@standardnotes/services'
|
||||
import { NoteMutator, SNActionsExtension, SNNote } from '@standardnotes/models'
|
||||
import { AbstractService, InternalEventBusInterface, MutatorClientInterface } from '@standardnotes/services'
|
||||
import { SNProtectionService } from '../Protection'
|
||||
|
||||
export class ListedService extends AbstractService implements ListedClientInterface {
|
||||
constructor(
|
||||
@@ -17,6 +18,8 @@ export class ListedService extends AbstractService implements ListedClientInterf
|
||||
private itemManager: ItemManager,
|
||||
private settingsService: SNSettingsService,
|
||||
private httpSerivce: SNHttpService,
|
||||
private protectionService: SNProtectionService,
|
||||
private mutatorService: MutatorClientInterface,
|
||||
protected override internalEventBus: InternalEventBusInterface,
|
||||
) {
|
||||
super(internalEventBus)
|
||||
@@ -27,6 +30,8 @@ export class ListedService extends AbstractService implements ListedClientInterf
|
||||
;(this.settingsService as unknown) = undefined
|
||||
;(this.apiService as unknown) = undefined
|
||||
;(this.httpSerivce as unknown) = undefined
|
||||
;(this.protectionService as unknown) = undefined
|
||||
;(this.mutatorService as unknown) = undefined
|
||||
super.deinit()
|
||||
}
|
||||
|
||||
@@ -34,6 +39,23 @@ export class ListedService extends AbstractService implements ListedClientInterf
|
||||
return this.apiService.user != undefined
|
||||
}
|
||||
|
||||
public isNoteAuthorizedForListed(note: SNNote): boolean {
|
||||
return note.authorizedForListed
|
||||
}
|
||||
|
||||
public async authorizeNoteForListed(note: SNNote): Promise<boolean> {
|
||||
const result = await this.protectionService.authorizeListedPublishing()
|
||||
if (result === false) {
|
||||
return false
|
||||
}
|
||||
|
||||
await this.mutatorService.changeAndSaveItem<NoteMutator>(note, (mutator) => {
|
||||
mutator.authorizedForListed = true
|
||||
})
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Account creation is asyncronous on the backend due to message-based nature of architecture.
|
||||
* In order to get the newly created account, we poll the server to check for new accounts.
|
||||
@@ -73,8 +95,11 @@ export class ListedService extends AbstractService implements ListedClientInterf
|
||||
if (inContextOfItem) {
|
||||
url += `&item_uuid=${inContextOfItem}`
|
||||
}
|
||||
const response = (await this.httpSerivce.getAbsolute(url)) as ListedAccountInfoResponse
|
||||
if (response.error || !response.data || isString(response.data)) {
|
||||
|
||||
const response = (await this.httpSerivce.getAbsolute(url).catch((error) => {
|
||||
console.error(error)
|
||||
})) as ListedAccountInfoResponse
|
||||
if (!response || response.error || !response.data || isString(response.data)) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
|
||||
@@ -219,13 +219,18 @@ export class SNProtectionService extends AbstractService<ProtectionEvent> implem
|
||||
return this.authorizeAction(ChallengeReason.RevokeSession)
|
||||
}
|
||||
|
||||
async authorizeListedPublishing(): Promise<boolean> {
|
||||
return this.authorizeAction(ChallengeReason.AuthorizeNoteForListed, { forcePrompt: true })
|
||||
}
|
||||
|
||||
async authorizeAction(
|
||||
reason: ChallengeReason,
|
||||
{ fallBackToAccountPassword = true, requireAccountPassword = false } = {},
|
||||
{ fallBackToAccountPassword = true, requireAccountPassword = false, forcePrompt = false } = {},
|
||||
): Promise<boolean> {
|
||||
return this.validateOrRenewSession(reason, {
|
||||
requireAccountPassword,
|
||||
fallBackToAccountPassword,
|
||||
forcePrompt,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -295,9 +300,9 @@ export class SNProtectionService extends AbstractService<ProtectionEvent> implem
|
||||
|
||||
private async validateOrRenewSession(
|
||||
reason: ChallengeReason,
|
||||
{ fallBackToAccountPassword = true, requireAccountPassword = false } = {},
|
||||
{ fallBackToAccountPassword = true, requireAccountPassword = false, forcePrompt = false } = {},
|
||||
): Promise<boolean> {
|
||||
if (this.getSessionExpiryDate() > new Date()) {
|
||||
if (this.getSessionExpiryDate() > new Date() && !forcePrompt) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ export class SNSessionManager extends AbstractService<SessionEvent> implements S
|
||||
return isNullOrUndefined(this.apiService.getSession())
|
||||
}
|
||||
|
||||
public getUser() {
|
||||
public getUser(): Responses.User | undefined {
|
||||
return this.user
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ClientDisplayableError } from '@standardnotes/responses'
|
||||
import { ClientDisplayableError, User } from '@standardnotes/responses'
|
||||
import { Base64String } from '@standardnotes/sncrypto-common'
|
||||
|
||||
export interface SessionsClientInterface {
|
||||
createDemoShareToken(): Promise<Base64String | ClientDisplayableError>
|
||||
|
||||
populateSessionFromDemoShareToken(token: Base64String): Promise<void>
|
||||
getUser(): User | undefined
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { ContentType } from '@standardnotes/common'
|
||||
import * as Models from '@standardnotes/models'
|
||||
|
||||
export const createNote = (payload?: Partial<Models.NoteContent>): Models.SNNote => {
|
||||
return new Models.SNNote(
|
||||
new Models.DecryptedPayload(
|
||||
{
|
||||
uuid: String(Math.random()),
|
||||
content_type: ContentType.Note,
|
||||
content: Models.FillItemContent({ ...payload }),
|
||||
...Models.PayloadTimestampDefaults(),
|
||||
},
|
||||
Models.PayloadSource.Constructor,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
export const createNoteWithTitle = (title: string) => {
|
||||
return new Models.SNNote(
|
||||
new Models.DecryptedPayload({
|
||||
uuid: String(Math.random()),
|
||||
content_type: ContentType.Note,
|
||||
content: Models.FillItemContent<Models.NoteContent>({
|
||||
title: title,
|
||||
}),
|
||||
...Models.PayloadTimestampDefaults(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
@@ -1,3 +1,2 @@
|
||||
export * from './ApplicationEventPayload'
|
||||
export * from './IconType'
|
||||
export * from './UuidString'
|
||||
|
||||
@@ -356,14 +356,13 @@ describe('app models', () => {
|
||||
})
|
||||
|
||||
it('maintains editor reference when duplicating note', async function () {
|
||||
const note = await Factory.createMappedNote(this.application)
|
||||
const editor = await this.application.itemManager.createItem(
|
||||
ContentType.Component,
|
||||
{ area: ComponentArea.Editor },
|
||||
{ area: ComponentArea.Editor, package_info: { identifier: 'foo-editor' } },
|
||||
true,
|
||||
)
|
||||
await this.application.itemManager.changeComponent(editor, (mutator) => {
|
||||
mutator.associateWithItem(note.uuid)
|
||||
const note = await Factory.insertItemWithOverride(this.application, ContentType.Note, {
|
||||
editorIdentifier: 'foo-editor',
|
||||
})
|
||||
|
||||
expect(this.application.componentManager.editorForNote(note).uuid).to.equal(editor.uuid)
|
||||
|
||||
@@ -114,59 +114,6 @@ describe('online conflict handling', function () {
|
||||
await this.sharedFinalAssertions()
|
||||
})
|
||||
|
||||
it('duplicating note should maintain editor ref', async function () {
|
||||
const note = await Factory.createSyncedNote(this.application)
|
||||
this.expectedItemCount++
|
||||
const basePayload = createDirtyPayload(ContentType.Component)
|
||||
const payload = basePayload.copy({
|
||||
content: {
|
||||
...basePayload.content,
|
||||
area: ComponentArea.Editor,
|
||||
},
|
||||
})
|
||||
const editor = await this.application.itemManager.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
|
||||
this.expectedItemCount++
|
||||
await this.application.syncService.sync(syncOptions)
|
||||
|
||||
await this.application.mutator.changeAndSaveItem(
|
||||
editor,
|
||||
(mutator) => {
|
||||
mutator.associateWithItem(note.uuid)
|
||||
},
|
||||
undefined,
|
||||
undefined,
|
||||
syncOptions,
|
||||
)
|
||||
|
||||
expect(this.application.componentManager.editorForNote(note)).to.be.ok
|
||||
|
||||
/** Conflict the note */
|
||||
/** First modify the item without saving so that
|
||||
* our local contents digress from the server's */
|
||||
await this.application.mutator.changeItem(note, (mutator) => {
|
||||
mutator.title = `${Math.random()}`
|
||||
})
|
||||
|
||||
await Factory.changePayloadTimeStampAndSync(
|
||||
this.application,
|
||||
note.payload,
|
||||
Factory.dateToMicroseconds(Factory.yesterday()),
|
||||
{
|
||||
title: 'zar',
|
||||
},
|
||||
syncOptions,
|
||||
)
|
||||
|
||||
this.expectedItemCount++
|
||||
|
||||
const duplicate = this.application.itemManager.getDisplayableNotes().find((n) => {
|
||||
return n.uuid !== note.uuid
|
||||
})
|
||||
expect(duplicate).to.be.ok
|
||||
expect(this.application.componentManager.editorForNote(duplicate)).to.be.ok
|
||||
await this.sharedFinalAssertions()
|
||||
})
|
||||
|
||||
it('should create conflicted copy if incoming server item attempts to overwrite local dirty item', async function () {
|
||||
// create an item and sync it
|
||||
const note = await Factory.createMappedNote(this.application)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/snjs",
|
||||
"version": "2.141.1",
|
||||
"version": "2.143.0",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,34 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.9.2](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/ui-services
|
||||
|
||||
## [1.9.1](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* refactor application event observing on web ([9fb85cd](https://github.com/standardnotes/app/commit/9fb85cd77a627364738a9c21706431d2a01e9c44))
|
||||
|
||||
# [1.9.0](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-21)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ui-services:** add route type getter ([401a35f](https://github.com/standardnotes/app/commit/401a35f4db9e7f090ad84c2d9e0ce5b465c7e790))
|
||||
|
||||
### Features
|
||||
|
||||
* add accepting subscription invite route type ([83b4840](https://github.com/standardnotes/app/commit/83b484002c066675e58625d7c0a1f7a7566df787))
|
||||
|
||||
## [1.8.5](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-19)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/ui-services
|
||||
|
||||
## [1.8.4](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-18)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/ui-services
|
||||
|
||||
## [1.8.3](https://github.com/standardnotes/app/compare/@standardnotes/[email protected]...@standardnotes/[email protected]) (2022-10-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/ui-services
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/ui-services",
|
||||
"version": "1.8.3",
|
||||
"version": "1.9.2",
|
||||
"engines": {
|
||||
"node": ">=16.0.0 <17.0.0"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export type DemoParams = {
|
||||
token: string
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export type OnboardingParams = {
|
||||
fromHomepage: boolean
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export type PurchaseParams = {
|
||||
plan: string
|
||||
period: string
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { PreferenceId } from '../../Preferences/PreferenceId'
|
||||
|
||||
export type SettingsParams = {
|
||||
panel: PreferenceId
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Uuid } from '@standardnotes/common'
|
||||
|
||||
export type SubscriptionInviteParams = {
|
||||
inviteUuid: Uuid
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export enum RootQueryParam {
|
||||
Purchase = 'purchase',
|
||||
Settings = 'settings',
|
||||
DemoToken = 'demo-token',
|
||||
AcceptSubscriptionInvite = 'accept-subscription-invite',
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export enum RootRoutes {
|
||||
Onboarding = '/onboard',
|
||||
None = '/',
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import { PreferenceId } from '../Preferences/PreferenceId'
|
||||
|
||||
export type OnboardingParams = {
|
||||
fromHomepage: boolean
|
||||
}
|
||||
|
||||
export type SettingsParams = {
|
||||
panel: PreferenceId
|
||||
}
|
||||
|
||||
export type DemoParams = {
|
||||
token: string
|
||||
}
|
||||
|
||||
export type PurchaseParams = {
|
||||
plan: string
|
||||
period: string
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user