orgnote-api 0.15.3 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -329,3 +329,24 @@ test('Should armor and unarmor encrypted file', async () => {
329
329
 
330
330
  expect(data).toEqual(content);
331
331
  });
332
+
333
+ test('Should decrypt value from provided real world data and passwords', async () => {
334
+ const text = `Hello world!`;
335
+ const password = 'qweqwebebe1';
336
+
337
+ const encryptedContent = await encrypt({
338
+ content: text,
339
+ type: 'gpgPassword',
340
+ password,
341
+ });
342
+
343
+ const armoredContent = armor(encryptedContent as unknown as Uint8Array);
344
+
345
+ const decryptedMessage = await decrypt({
346
+ content: armoredContent,
347
+ type: 'gpgPassword',
348
+ password,
349
+ });
350
+
351
+ expect(decryptedMessage).toEqual('Hello world!');
352
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orgnote-api",
3
- "version": "0.15.3",
3
+ "version": "0.17.0",
4
4
  "description": "Official API for creating extensions for OrgNote app",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
@@ -45,6 +45,7 @@
45
45
  "axios": "1.7.3",
46
46
  "openpgp": "5.11.1",
47
47
  "org-mode-ast": "0.11.7",
48
+ "orgnote-api": "0.16.0",
48
49
  "vue": "3.4.15",
49
50
  "vue-router": "4.2.5"
50
51
  },
@@ -0,0 +1,176 @@
1
+ import { afterEach, beforeEach, expect, test } from 'vitest';
2
+ import { mkdirSync, rmdirSync, statSync, utimesSync, writeFileSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { findNotesFilesDiff, StoredNoteInfo } from '../find-notes-files-diff';
5
+
6
+ const testFilesFolder = 'src/tools/__tests__/miscellaneous/';
7
+
8
+ function initFiles(): void {
9
+ mkdirSync(testFilesFolder);
10
+ mkdirSync(testFilesFolder + '/nested-folder');
11
+ }
12
+
13
+ function cleanFiles(): void {
14
+ try {
15
+ rmdirSync(testFilesFolder, { recursive: true });
16
+ } catch (e) {}
17
+ }
18
+
19
+ function createTestFile(
20
+ content: string,
21
+ fileName: string,
22
+ updated: Date
23
+ ): void {
24
+ const filePath = join(testFilesFolder, fileName);
25
+
26
+ writeFileSync(filePath, content);
27
+
28
+ const time = updated.getTime() / 1000; // Convert to seconds
29
+ utimesSync(filePath, time, time);
30
+ }
31
+
32
+ beforeEach(() => initFiles());
33
+ afterEach(() => cleanFiles());
34
+
35
+ test('Should find files diff', () => {
36
+ createTestFile(`unchanged file!`, 'org-file.org', new Date('2021-01-01'));
37
+ createTestFile(
38
+ `changed org file 2!`,
39
+ 'org-file2.org',
40
+ new Date('2022-01-01')
41
+ );
42
+ createTestFile(
43
+ `deleted org in the nested folder file!`,
44
+ 'nested-folder/org-file3.org',
45
+ new Date('2021-01-01')
46
+ );
47
+ createTestFile(
48
+ `created file in the nested folder!`,
49
+ 'nested-folder/org-file4.org',
50
+ new Date('2021-02-01')
51
+ );
52
+
53
+ const storedNoteInfos: StoredNoteInfo[] = [
54
+ {
55
+ filePath: [testFilesFolder + 'deleted-org-file.org'],
56
+ id: 'deleted-org-file.org',
57
+ updatedAt: new Date('2021-01-01'),
58
+ },
59
+ {
60
+ filePath: [testFilesFolder + 'org-file.org'],
61
+ id: 'org-file.org',
62
+ updatedAt: new Date('2021-01-01'),
63
+ },
64
+ {
65
+ filePath: [testFilesFolder + 'org-file2.org'],
66
+ id: 'org-file2.org',
67
+ updatedAt: new Date('2021-01-01'),
68
+ },
69
+ {
70
+ filePath: [testFilesFolder + 'nested-folder/org-file3.org'],
71
+ id: 'nested-folder/org-file3.org',
72
+ updatedAt: new Date('2021-01-01'),
73
+ },
74
+ ];
75
+
76
+ const changedFiles = findNotesFilesDiff(
77
+ [
78
+ testFilesFolder + 'org-file.org',
79
+ testFilesFolder + 'org-file2.org',
80
+ testFilesFolder + 'nested-folder/org-file3.org',
81
+ testFilesFolder + 'nested-folder/org-file4.org',
82
+ ],
83
+ storedNoteInfos,
84
+ (filePath: string) => new Date(statSync(filePath).mtime)
85
+ );
86
+
87
+ expect(changedFiles).toEqual({
88
+ created: [testFilesFolder + 'nested-folder/org-file4.org'],
89
+ updated: [testFilesFolder + 'org-file2.org'],
90
+ deleted: [testFilesFolder + 'deleted-org-file.org'],
91
+ });
92
+ });
93
+
94
+ test('Should find files diff when folder was renamed', () => {
95
+ createTestFile(
96
+ `nested file!`,
97
+ 'nested-folder/org-file.org',
98
+ new Date('2021-01-01')
99
+ );
100
+ createTestFile(
101
+ `nested file2!`,
102
+ 'nested-folder/org-file-2.org',
103
+ new Date('2021-01-01')
104
+ );
105
+
106
+ const storedNoteInfos: StoredNoteInfo[] = [
107
+ {
108
+ filePath: [testFilesFolder + 'nested-folder/org-file.org'],
109
+ id: 'nested-folder/org-file.org',
110
+ updatedAt: new Date('2021-01-01'),
111
+ },
112
+ {
113
+ filePath: [testFilesFolder + 'nested-folder/org-file2.org'],
114
+ id: 'nested-folder/org-file2.org',
115
+ updatedAt: new Date('2021-01-01'),
116
+ },
117
+ ];
118
+
119
+ rmdirSync(testFilesFolder + 'nested-folder', { recursive: true });
120
+
121
+ const changedFiles = findNotesFilesDiff(
122
+ [],
123
+ storedNoteInfos,
124
+ (filePath: string) => new Date(statSync(filePath).mtime)
125
+ );
126
+
127
+ expect(changedFiles).toMatchInlineSnapshot(`
128
+ {
129
+ "created": [],
130
+ "deleted": [
131
+ "src/tools/__tests__/miscellaneous/nested-folder/org-file.org",
132
+ "src/tools/__tests__/miscellaneous/nested-folder/org-file2.org",
133
+ ],
134
+ "updated": [],
135
+ }
136
+ `);
137
+ });
138
+
139
+ test('Should find created note when nested folder created', () => {
140
+ mkdirSync(testFilesFolder + 'new-nested-folder');
141
+ createTestFile(
142
+ `new nested file!`,
143
+ 'new-nested-folder/org-file.org',
144
+ new Date('2023-01-01')
145
+ );
146
+
147
+ const storedNoteInfos: StoredNoteInfo[] = [];
148
+
149
+ const changedFiles = findNotesFilesDiff(
150
+ [testFilesFolder + 'new-nested-folder/org-file.org'],
151
+ storedNoteInfos,
152
+ (filePath: string) => new Date(statSync(filePath).mtime)
153
+ );
154
+
155
+ expect(changedFiles).toEqual({
156
+ created: [testFilesFolder + 'new-nested-folder/org-file.org'],
157
+ updated: [],
158
+ deleted: [],
159
+ });
160
+ });
161
+
162
+ test('Should find nothing when no files provided', () => {
163
+ const storedNoteInfos: StoredNoteInfo[] = [];
164
+
165
+ const changedFiles = findNotesFilesDiff(
166
+ [],
167
+ storedNoteInfos,
168
+ (filePath: string) => new Date(statSync(filePath).mtime)
169
+ );
170
+
171
+ expect(changedFiles).toEqual({
172
+ created: [],
173
+ updated: [],
174
+ deleted: [],
175
+ });
176
+ });
@@ -0,0 +1,32 @@
1
+ import { getStringPath } from '../get-string-path';
2
+ import { test, expect } from 'vitest';
3
+
4
+ test('should return the same string if path is a string', () => {
5
+ const path = 'some/path';
6
+ const result = getStringPath(path);
7
+ expect(result).toBe('some/path');
8
+ });
9
+
10
+ test('should join array elements with "/" if path is an array', () => {
11
+ const path = ['some', 'path'];
12
+ const result = getStringPath(path);
13
+ expect(result).toBe('some/path');
14
+ });
15
+
16
+ test('should return an empty string if path is an empty array', () => {
17
+ const path: string[] = [];
18
+ const result = getStringPath(path);
19
+ expect(result).toBe('');
20
+ });
21
+
22
+ test('should handle array with one element correctly', () => {
23
+ const path = ['single'];
24
+ const result = getStringPath(path);
25
+ expect(result).toBe('single');
26
+ });
27
+
28
+ test('should handle array with multiple elements correctly', () => {
29
+ const path = ['this', 'is', 'a', 'test'];
30
+ const result = getStringPath(path);
31
+ expect(result).toBe('this/is/a/test');
32
+ });
@@ -0,0 +1,62 @@
1
+ import { test, expect } from 'vitest';
2
+ import { isOrgFile, isOrgGpgFile } from '../is-org-file';
3
+
4
+ test('Should return true for org files', () => {
5
+ const files = [
6
+ 'myNote.org',
7
+ 'my_note.org',
8
+ '123.org',
9
+ 'some_long_note#4123$123eqasdasd.org.gpg',
10
+ 'some_long_note#4123$123eqasdasd.org',
11
+ 'note with space.org',
12
+ 'note with space.org.gpg',
13
+ ];
14
+
15
+ files.forEach((file) => {
16
+ expect(isOrgFile(file), file).toBe(true);
17
+ });
18
+ });
19
+
20
+ test('Should not return true for non-org files', () => {
21
+ const files = [
22
+ 'myNote.md',
23
+ 'my_note.md',
24
+ '123.md',
25
+ 'some_long_note#4123$123eqasdas',
26
+ 'note.org.file',
27
+ 'org',
28
+ 'org.',
29
+ 'text.gpg',
30
+ ];
31
+
32
+ files.forEach((file) => {
33
+ expect(isOrgFile(file), file).toBe(false);
34
+ });
35
+ });
36
+
37
+ test('Should return true for org.gpg files', () => {
38
+ const gpgFiles = [
39
+ 'myNote.org.gpg',
40
+ 'my_note.org.gpg',
41
+ '123.org.gpg',
42
+ 'org.org.gpg',
43
+ 'gp_org.org.gpg',
44
+ ];
45
+
46
+ gpgFiles.forEach((file) => {
47
+ expect(isOrgGpgFile(file), file).toBe(true);
48
+ });
49
+ });
50
+
51
+ test('Should not return true for not .org.gpg files', () => {
52
+ const notGpgFiles = [
53
+ 'myNote.org',
54
+ 'my_note.org',
55
+ '123.org',
56
+ 'some_gpg_file.txt',
57
+ ];
58
+
59
+ notGpgFiles.forEach((file) => {
60
+ expect(isOrgGpgFile(file), file).toBe(false);
61
+ });
62
+ });
@@ -0,0 +1,48 @@
1
+ import { getStringPath } from './get-string-path';
2
+
3
+ export interface ChangedFiles {
4
+ deleted: string[];
5
+ created: string[];
6
+ updated: string[];
7
+ }
8
+
9
+ export interface StoredNoteInfo {
10
+ filePath: string[];
11
+ id: string;
12
+ updatedAt: string | Date;
13
+ }
14
+
15
+ export function findNotesFilesDiff(
16
+ filePaths: string[],
17
+ storedNotesInfo: StoredNoteInfo[],
18
+ updatedTimeGetter: (filePath: string) => Date
19
+ ): ChangedFiles {
20
+ const existingFilePaths = new Set<string>(filePaths);
21
+
22
+ const storedNotesPathSet = new Set<string>(
23
+ storedNotesInfo.map((n) => getStringPath(n.filePath))
24
+ );
25
+ const changedFiles: ChangedFiles = { deleted: [], created: [], updated: [] };
26
+
27
+ storedNotesInfo.forEach((storedNote) => {
28
+ const fullPath = getStringPath(storedNote.filePath);
29
+ if (!existingFilePaths.has(fullPath)) {
30
+ changedFiles.deleted.push(fullPath);
31
+ return;
32
+ }
33
+
34
+ const updatedTime = updatedTimeGetter(fullPath);
35
+ if (updatedTime > new Date(storedNote.updatedAt)) {
36
+ changedFiles.updated.push(fullPath);
37
+ }
38
+ });
39
+
40
+ filePaths.forEach((filePath) => {
41
+ if (!storedNotesPathSet.has(filePath)) {
42
+ changedFiles.created.push(filePath);
43
+ return;
44
+ }
45
+ });
46
+
47
+ return changedFiles;
48
+ }
@@ -0,0 +1,6 @@
1
+ export function getStringPath(path: string | string[]): string {
2
+ if (Array.isArray(path)) {
3
+ return `${path.join('/')}`;
4
+ }
5
+ return path;
6
+ }
package/tools/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './mock-server';
2
2
  export * from './is-gpg-encrypted';
3
+ export * from './is-org-file';
@@ -0,0 +1,7 @@
1
+ const orgFileExtenstionRegex = /\.org(\.gpg)?$/;
2
+ export const isOrgFile = (fileName: string): boolean =>
3
+ orgFileExtenstionRegex.test(fileName);
4
+
5
+ const orgGpgFileExtenstionRegex = /\.org\.gpg$/;
6
+ export const isOrgGpgFile = (fileName: string): boolean =>
7
+ orgGpgFileExtenstionRegex.test(fileName);