@rewrlution/papyrus-cli 0.0.1
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.
- package/README.md +699 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +16 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/auth/index.d.ts +2 -0
- package/dist/commands/auth/index.js +18 -0
- package/dist/commands/auth/index.js.map +1 -0
- package/dist/commands/auth/login.d.ts +1 -0
- package/dist/commands/auth/login.js +8 -0
- package/dist/commands/auth/login.js.map +1 -0
- package/dist/commands/auth/logout.d.ts +1 -0
- package/dist/commands/auth/logout.js +5 -0
- package/dist/commands/auth/logout.js.map +1 -0
- package/dist/commands/auth/register.d.ts +1 -0
- package/dist/commands/auth/register.js +8 -0
- package/dist/commands/auth/register.js.map +1 -0
- package/dist/commands/index.d.ts +2 -0
- package/dist/commands/index.js +3 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/journal/add.d.ts +2 -0
- package/dist/commands/journal/add.js +5 -0
- package/dist/commands/journal/add.js.map +1 -0
- package/dist/commands/journal/amend.d.ts +2 -0
- package/dist/commands/journal/amend.js +5 -0
- package/dist/commands/journal/amend.js.map +1 -0
- package/dist/commands/journal/edit.d.ts +6 -0
- package/dist/commands/journal/edit.js +60 -0
- package/dist/commands/journal/edit.js.map +1 -0
- package/dist/commands/journal/index.d.ts +2 -0
- package/dist/commands/journal/index.js +32 -0
- package/dist/commands/journal/index.js.map +1 -0
- package/dist/commands/journal/list.d.ts +1 -0
- package/dist/commands/journal/list.js +20 -0
- package/dist/commands/journal/list.js.map +1 -0
- package/dist/commands/journal/show.d.ts +2 -0
- package/dist/commands/journal/show.js +35 -0
- package/dist/commands/journal/show.js.map +1 -0
- package/dist/commands/journal/sync.d.ts +1 -0
- package/dist/commands/journal/sync.js +9 -0
- package/dist/commands/journal/sync.js.map +1 -0
- package/dist/commands/types.d.ts +9 -0
- package/dist/commands/types.js +2 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/components/Browser.d.ts +29 -0
- package/dist/components/Browser.js +124 -0
- package/dist/components/Browser.js.map +1 -0
- package/dist/components/BrowserFooter.d.ts +6 -0
- package/dist/components/BrowserFooter.js +6 -0
- package/dist/components/BrowserFooter.js.map +1 -0
- package/dist/components/BrowserHeader.d.ts +6 -0
- package/dist/components/BrowserHeader.js +6 -0
- package/dist/components/BrowserHeader.js.map +1 -0
- package/dist/components/ColdStart.d.ts +6 -0
- package/dist/components/ColdStart.js +24 -0
- package/dist/components/ColdStart.js.map +1 -0
- package/dist/components/FormInput.d.ts +10 -0
- package/dist/components/FormInput.js +7 -0
- package/dist/components/FormInput.js.map +1 -0
- package/dist/components/JournalListView.d.ts +10 -0
- package/dist/components/JournalListView.js +40 -0
- package/dist/components/JournalListView.js.map +1 -0
- package/dist/components/JournalViewer.d.ts +32 -0
- package/dist/components/JournalViewer.js +146 -0
- package/dist/components/JournalViewer.js.map +1 -0
- package/dist/components/LoginForm.d.ts +1 -0
- package/dist/components/LoginForm.js +68 -0
- package/dist/components/LoginForm.js.map +1 -0
- package/dist/components/Logo.d.ts +1 -0
- package/dist/components/Logo.js +57 -0
- package/dist/components/Logo.js.map +1 -0
- package/dist/components/RegisterForm.d.ts +1 -0
- package/dist/components/RegisterForm.js +72 -0
- package/dist/components/RegisterForm.js.map +1 -0
- package/dist/components/StatusMessage.d.ts +7 -0
- package/dist/components/StatusMessage.js +19 -0
- package/dist/components/StatusMessage.js.map +1 -0
- package/dist/components/SyncProgress.d.ts +1 -0
- package/dist/components/SyncProgress.js +46 -0
- package/dist/components/SyncProgress.js.map +1 -0
- package/dist/lib/api/api-client.d.ts +23 -0
- package/dist/lib/api/api-client.js +111 -0
- package/dist/lib/api/api-client.js.map +1 -0
- package/dist/lib/api/index.d.ts +3 -0
- package/dist/lib/api/index.js +6 -0
- package/dist/lib/api/index.js.map +1 -0
- package/dist/lib/auth/index.d.ts +1 -0
- package/dist/lib/auth/index.js +2 -0
- package/dist/lib/auth/index.js.map +1 -0
- package/dist/lib/auth/require-auth.d.ts +67 -0
- package/dist/lib/auth/require-auth.js +107 -0
- package/dist/lib/auth/require-auth.js.map +1 -0
- package/dist/lib/storage/base-storage.d.ts +50 -0
- package/dist/lib/storage/base-storage.js +91 -0
- package/dist/lib/storage/base-storage.js.map +1 -0
- package/dist/lib/storage/config-store.d.ts +40 -0
- package/dist/lib/storage/config-store.js +63 -0
- package/dist/lib/storage/config-store.js.map +1 -0
- package/dist/lib/storage/index.d.ts +12 -0
- package/dist/lib/storage/index.js +13 -0
- package/dist/lib/storage/index.js.map +1 -0
- package/dist/lib/storage/journal-storage.d.ts +46 -0
- package/dist/lib/storage/journal-storage.js +78 -0
- package/dist/lib/storage/journal-storage.js.map +1 -0
- package/dist/lib/storage/sync-meta-store.d.ts +37 -0
- package/dist/lib/storage/sync-meta-store.js +50 -0
- package/dist/lib/storage/sync-meta-store.js.map +1 -0
- package/dist/lib/storage/token-store.d.ts +25 -0
- package/dist/lib/storage/token-store.js +40 -0
- package/dist/lib/storage/token-store.js.map +1 -0
- package/dist/lib/sync/sync-engine.d.ts +13 -0
- package/dist/lib/sync/sync-engine.js +96 -0
- package/dist/lib/sync/sync-engine.js.map +1 -0
- package/dist/utils/date.d.ts +58 -0
- package/dist/utils/date.js +117 -0
- package/dist/utils/date.js.map +1 -0
- package/dist/utils/editor.d.ts +2 -0
- package/dist/utils/editor.js +81 -0
- package/dist/utils/editor.js.map +1 -0
- package/dist/utils/template.d.ts +2 -0
- package/dist/utils/template.js +17 -0
- package/dist/utils/template.js.map +1 -0
- package/dist/utils/token.d.ts +20 -0
- package/dist/utils/token.js +64 -0
- package/dist/utils/token.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { tokenStore } from '../storage/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* API Client for Papyrus server
|
|
5
|
+
* Uses shared types and storage layer for tokens
|
|
6
|
+
*
|
|
7
|
+
* Error handling strategy:
|
|
8
|
+
* - Validation errors: Caught by Zod client-side (before API call)
|
|
9
|
+
* - API errors: Descriptive messages from ApiErrorResponse
|
|
10
|
+
* - Network errors: Wrapped with descriptive message
|
|
11
|
+
*/
|
|
12
|
+
export class ApiClient {
|
|
13
|
+
http;
|
|
14
|
+
constructor(baseUrl) {
|
|
15
|
+
this.http = axios.create({
|
|
16
|
+
baseURL: baseUrl,
|
|
17
|
+
timeout: 90000, // set api timeout to 90 sec. serverless app warm-up may take up to a minute.
|
|
18
|
+
headers: {
|
|
19
|
+
'Content-Type': 'application/json',
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
// Add token to requests automatically from storage layer
|
|
23
|
+
this.http.interceptors.request.use((config) => {
|
|
24
|
+
const token = tokenStore.get();
|
|
25
|
+
if (token) {
|
|
26
|
+
config.headers.Authorization = `Bearer ${token}`;
|
|
27
|
+
}
|
|
28
|
+
return config;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async register(credentials) {
|
|
32
|
+
try {
|
|
33
|
+
const response = await this.http.post('/auth/signup', credentials);
|
|
34
|
+
return response.data.data;
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
this.handleError(error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async login(credentials) {
|
|
41
|
+
try {
|
|
42
|
+
const response = await this.http.post('/auth/signin', credentials);
|
|
43
|
+
// Save token to storage layer
|
|
44
|
+
if (response.data.data.token) {
|
|
45
|
+
tokenStore.save(response.data.data.token);
|
|
46
|
+
}
|
|
47
|
+
return response.data.data;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
this.handleError(error);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
logout() {
|
|
54
|
+
tokenStore.clear();
|
|
55
|
+
}
|
|
56
|
+
isAuthenticated() {
|
|
57
|
+
return tokenStore.exists();
|
|
58
|
+
}
|
|
59
|
+
async listJournalsMetadata() {
|
|
60
|
+
try {
|
|
61
|
+
const response = await this.http.get('/journals/metadata');
|
|
62
|
+
return response.data.data;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
this.handleError(error);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async getJournal(date) {
|
|
69
|
+
try {
|
|
70
|
+
const response = await this.http.get(`/journals/${date}`);
|
|
71
|
+
return response.data.data;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
this.handleError(error);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async createJournal(date, content) {
|
|
78
|
+
try {
|
|
79
|
+
const response = await this.http.post('/journals', {
|
|
80
|
+
date,
|
|
81
|
+
content,
|
|
82
|
+
});
|
|
83
|
+
return response.data.data;
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
this.handleError(error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async updateJournal(date, content) {
|
|
90
|
+
try {
|
|
91
|
+
const response = await this.http.put(`/journals/${date}`, { content });
|
|
92
|
+
return response.data.data;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
this.handleError(error);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
handleError(error) {
|
|
99
|
+
if (axios.isAxiosError(error)) {
|
|
100
|
+
// API returned an error response with message
|
|
101
|
+
if (error.response?.data.message) {
|
|
102
|
+
throw new Error(error.response.data.message);
|
|
103
|
+
}
|
|
104
|
+
// Network error (connection refused, timeout, DNS failure)
|
|
105
|
+
throw new Error(`Network error: ${error.message}`);
|
|
106
|
+
}
|
|
107
|
+
// Unknown error
|
|
108
|
+
throw new Error(error instanceof Error ? error.message : 'unknown error');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../../src/lib/api/api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { configStore } from '../storage/index.js';
|
|
2
|
+
import { ApiClient } from './api-client.js';
|
|
3
|
+
const API_BASE_URL = configStore.get('apiUrl') || 'http://localhost:3000/api';
|
|
4
|
+
export const api = new ApiClient(API_BASE_URL);
|
|
5
|
+
export { ApiClient } from './api-client.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,2BAA2B,CAAC;AAC9E,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,YAAY,CAAC,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { requireAuth, ensureAuthenticated, type AuthCheckResult, type RequireAuthOptions, } from './require-auth.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,mBAAmB,GAGpB,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export interface AuthCheckResult {
|
|
2
|
+
isAuthenticated: boolean;
|
|
3
|
+
isExpired: boolean;
|
|
4
|
+
isExpiringSoon: boolean;
|
|
5
|
+
timeUntilExpiration: string | null;
|
|
6
|
+
message?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Options for authentication check
|
|
10
|
+
*/
|
|
11
|
+
export interface RequireAuthOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Hours before expiration to consider "expiring soon"
|
|
14
|
+
* @default 24
|
|
15
|
+
*/
|
|
16
|
+
expirationThresholdHours?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Whether to show warnings for tokens expiring soon
|
|
19
|
+
* @default true
|
|
20
|
+
*/
|
|
21
|
+
warnOnExpiringSoon?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if user is authenticated and token is valid
|
|
25
|
+
* Returns detailed auth status for flexible handling
|
|
26
|
+
*
|
|
27
|
+
* This is the core function that any command can use to check authentication.
|
|
28
|
+
* It handles all the edge cases: missing token, expired token, invalid token,
|
|
29
|
+
* and token expiring soon.
|
|
30
|
+
*
|
|
31
|
+
* @param options - Authentication check options
|
|
32
|
+
* @returns Authentication check result with detailed status
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // Basic usage in a command
|
|
37
|
+
* const auth = requireAuth();
|
|
38
|
+
* if (!auth.isAuthenticated) {
|
|
39
|
+
* console.error(`Error: ${auth.message}`);
|
|
40
|
+
* process.exit(1);
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function requireAuth(options?: RequireAuthOptions): AuthCheckResult;
|
|
45
|
+
/**
|
|
46
|
+
* Ensures user is authenticated, exits process if not
|
|
47
|
+
*
|
|
48
|
+
* This is a convenience function for commands that require authentication.
|
|
49
|
+
* It checks authentication and exits with a clear error message if not authenticated.
|
|
50
|
+
* If authenticated but token is expiring soon, it shows a warning but continues.
|
|
51
|
+
*
|
|
52
|
+
* Use this in commands that MUST have authentication to proceed.
|
|
53
|
+
*
|
|
54
|
+
* @param options - Authentication check options
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* // Simplest usage - one line in your command
|
|
59
|
+
* export async function sync() {
|
|
60
|
+
* ensureAuthenticated(); // Will exit if not authenticated
|
|
61
|
+
*
|
|
62
|
+
* // Safe to proceed - user is authenticated
|
|
63
|
+
* await performSync();
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare function ensureAuthenticated(options?: RequireAuthOptions): void;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { isTokenExpired, isTokenExpiringSoon, getTimeUntilExpiration, } from '../../utils/token.js';
|
|
2
|
+
import { tokenStore } from '../storage/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Check if user is authenticated and token is valid
|
|
5
|
+
* Returns detailed auth status for flexible handling
|
|
6
|
+
*
|
|
7
|
+
* This is the core function that any command can use to check authentication.
|
|
8
|
+
* It handles all the edge cases: missing token, expired token, invalid token,
|
|
9
|
+
* and token expiring soon.
|
|
10
|
+
*
|
|
11
|
+
* @param options - Authentication check options
|
|
12
|
+
* @returns Authentication check result with detailed status
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // Basic usage in a command
|
|
17
|
+
* const auth = requireAuth();
|
|
18
|
+
* if (!auth.isAuthenticated) {
|
|
19
|
+
* console.error(`Error: ${auth.message}`);
|
|
20
|
+
* process.exit(1);
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function requireAuth(options = {}) {
|
|
25
|
+
const { expirationThresholdHours = 23, warnOnExpiringSoon = true } = options;
|
|
26
|
+
// Check if token exists in storage
|
|
27
|
+
if (!tokenStore.exists()) {
|
|
28
|
+
return {
|
|
29
|
+
isAuthenticated: false,
|
|
30
|
+
isExpired: false,
|
|
31
|
+
isExpiringSoon: false,
|
|
32
|
+
timeUntilExpiration: null,
|
|
33
|
+
message: 'Not authenticated. Pleas run `papyrus login` first.',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const token = tokenStore.get();
|
|
37
|
+
if (!token) {
|
|
38
|
+
return {
|
|
39
|
+
isAuthenticated: false,
|
|
40
|
+
isExpired: false,
|
|
41
|
+
isExpiringSoon: false,
|
|
42
|
+
timeUntilExpiration: null,
|
|
43
|
+
message: 'Invalid token. Please run `papyrus login` again.',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// Check if token is expired
|
|
47
|
+
if (isTokenExpired(token)) {
|
|
48
|
+
// Automatically clear expired token
|
|
49
|
+
tokenStore.clear();
|
|
50
|
+
return {
|
|
51
|
+
isAuthenticated: false,
|
|
52
|
+
isExpired: true,
|
|
53
|
+
isExpiringSoon: false,
|
|
54
|
+
timeUntilExpiration: null,
|
|
55
|
+
message: 'Your session has expired. Please run `papyrus login` again.',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// Check if token is expiring soon
|
|
59
|
+
const expiringSoon = isTokenExpiringSoon(token, expirationThresholdHours);
|
|
60
|
+
const timeUntilExpiration = getTimeUntilExpiration(token);
|
|
61
|
+
return {
|
|
62
|
+
isAuthenticated: true,
|
|
63
|
+
isExpired: false,
|
|
64
|
+
isExpiringSoon: expiringSoon,
|
|
65
|
+
timeUntilExpiration,
|
|
66
|
+
message: expiringSoon && warnOnExpiringSoon && timeUntilExpiration
|
|
67
|
+
? `Your session will expire in ${timeUntilExpiration}. Please run \`papyrus login\` to refresh.`
|
|
68
|
+
: undefined,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Ensures user is authenticated, exits process if not
|
|
73
|
+
*
|
|
74
|
+
* This is a convenience function for commands that require authentication.
|
|
75
|
+
* It checks authentication and exits with a clear error message if not authenticated.
|
|
76
|
+
* If authenticated but token is expiring soon, it shows a warning but continues.
|
|
77
|
+
*
|
|
78
|
+
* Use this in commands that MUST have authentication to proceed.
|
|
79
|
+
*
|
|
80
|
+
* @param options - Authentication check options
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* // Simplest usage - one line in your command
|
|
85
|
+
* export async function sync() {
|
|
86
|
+
* ensureAuthenticated(); // Will exit if not authenticated
|
|
87
|
+
*
|
|
88
|
+
* // Safe to proceed - user is authenticated
|
|
89
|
+
* await performSync();
|
|
90
|
+
* }
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export function ensureAuthenticated(options = {}) {
|
|
94
|
+
const authResult = requireAuth(options);
|
|
95
|
+
if (!authResult.isAuthenticated) {
|
|
96
|
+
console.error(`Error: ${authResult.message}`);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
if (authResult.isExpired) {
|
|
100
|
+
console.error(`Error: ${authResult.message}`);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
if (authResult.isExpiringSoon && authResult.message) {
|
|
104
|
+
console.warn(`Warning: ${authResult.message}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=require-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"require-auth.js","sourceRoot":"","sources":["../../../src/lib/auth/require-auth.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA2BjD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,WAAW,CAAC,UAA8B,EAAE;IAC1D,MAAM,EAAE,wBAAwB,GAAG,EAAE,EAAE,kBAAkB,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAE7E,mCAAmC;IACnC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;QACzB,OAAO;YACL,eAAe,EAAE,KAAK;YACtB,SAAS,EAAE,KAAK;YAChB,cAAc,EAAE,KAAK;YACrB,mBAAmB,EAAE,IAAI;YACzB,OAAO,EAAE,qDAAqD;SAC/D,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;YACL,eAAe,EAAE,KAAK;YACtB,SAAS,EAAE,KAAK;YAChB,cAAc,EAAE,KAAK;YACrB,mBAAmB,EAAE,IAAI;YACzB,OAAO,EAAE,kDAAkD;SAC5D,CAAC;IACJ,CAAC;IAED,4BAA4B;IAC5B,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,oCAAoC;QACpC,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO;YACL,eAAe,EAAE,KAAK;YACtB,SAAS,EAAE,IAAI;YACf,cAAc,EAAE,KAAK;YACrB,mBAAmB,EAAE,IAAI;YACzB,OAAO,EAAE,6DAA6D;SACvE,CAAC;IACJ,CAAC;IAED,kCAAkC;IAClC,MAAM,YAAY,GAAG,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,CAAC,CAAC;IAC1E,MAAM,mBAAmB,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAE1D,OAAO;QACL,eAAe,EAAE,IAAI;QACrB,SAAS,EAAE,KAAK;QAChB,cAAc,EAAE,YAAY;QAC5B,mBAAmB;QACnB,OAAO,EACL,YAAY,IAAI,kBAAkB,IAAI,mBAAmB;YACvD,CAAC,CAAC,+BAA+B,mBAAmB,4CAA4C;YAChG,CAAC,CAAC,SAAS;KAChB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAA8B,EAAE;IAClE,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IAExC,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,UAAU,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,UAAU,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,UAAU,CAAC,cAAc,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,YAAY,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base storage class that follows the XDG-base directory standard
|
|
3
|
+
* and handles cross-platform directory management
|
|
4
|
+
* and common file operations
|
|
5
|
+
*/
|
|
6
|
+
export declare class BaseStorage {
|
|
7
|
+
/**
|
|
8
|
+
* the env-paths will add `runtime` to the path name.
|
|
9
|
+
* we must set { suffix: "" }, otherwise, in Windows,
|
|
10
|
+
* the folder will become:
|
|
11
|
+
* /c/users/{username}/appdata/local/papyrus-nodejs/data
|
|
12
|
+
* instead of
|
|
13
|
+
* /c/users/{username}/appdata/local/papyrus/data
|
|
14
|
+
*/
|
|
15
|
+
private paths;
|
|
16
|
+
/**
|
|
17
|
+
* Get config directory
|
|
18
|
+
* Linux: ~/.config/papyrus
|
|
19
|
+
* Windows: %APPDATA%\papyrus\Config
|
|
20
|
+
* macOS: ~/Library/Preferences/papyrus
|
|
21
|
+
*/
|
|
22
|
+
protected getConfigDir(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Get data directory
|
|
25
|
+
* Linux: ~/.local/share/papyrus
|
|
26
|
+
* Windows: %LOCALAPPDATA%\papyrus\Data
|
|
27
|
+
* macOS: ~/Library/Application Support/papyrus
|
|
28
|
+
*/
|
|
29
|
+
protected getDataDir(): string;
|
|
30
|
+
/**
|
|
31
|
+
* Ensure directory exists, create if it doesn't
|
|
32
|
+
*/
|
|
33
|
+
protected ensureDir(dir: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Read file contents, return null if doesn't exist
|
|
36
|
+
*/
|
|
37
|
+
protected readFile(filePath: string): string | null;
|
|
38
|
+
/**
|
|
39
|
+
* Write file contents, create parent directories if needed
|
|
40
|
+
*/
|
|
41
|
+
protected writeFile(filePath: string, content: string): void;
|
|
42
|
+
/**
|
|
43
|
+
* Delete file if it exists
|
|
44
|
+
*/
|
|
45
|
+
protected deleteFile(filePath: string): void;
|
|
46
|
+
/**
|
|
47
|
+
* Check if file exists
|
|
48
|
+
*/
|
|
49
|
+
protected fileExists(filePath: string): boolean;
|
|
50
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import envPaths from 'env-paths';
|
|
4
|
+
/**
|
|
5
|
+
* Base storage class that follows the XDG-base directory standard
|
|
6
|
+
* and handles cross-platform directory management
|
|
7
|
+
* and common file operations
|
|
8
|
+
*/
|
|
9
|
+
export class BaseStorage {
|
|
10
|
+
/**
|
|
11
|
+
* the env-paths will add `runtime` to the path name.
|
|
12
|
+
* we must set { suffix: "" }, otherwise, in Windows,
|
|
13
|
+
* the folder will become:
|
|
14
|
+
* /c/users/{username}/appdata/local/papyrus-nodejs/data
|
|
15
|
+
* instead of
|
|
16
|
+
* /c/users/{username}/appdata/local/papyrus/data
|
|
17
|
+
*/
|
|
18
|
+
paths = envPaths('papyrus', { suffix: '' });
|
|
19
|
+
/**
|
|
20
|
+
* Get config directory
|
|
21
|
+
* Linux: ~/.config/papyrus
|
|
22
|
+
* Windows: %APPDATA%\papyrus\Config
|
|
23
|
+
* macOS: ~/Library/Preferences/papyrus
|
|
24
|
+
*/
|
|
25
|
+
getConfigDir() {
|
|
26
|
+
return this.paths.config;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get data directory
|
|
30
|
+
* Linux: ~/.local/share/papyrus
|
|
31
|
+
* Windows: %LOCALAPPDATA%\papyrus\Data
|
|
32
|
+
* macOS: ~/Library/Application Support/papyrus
|
|
33
|
+
*/
|
|
34
|
+
getDataDir() {
|
|
35
|
+
return this.paths.data;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Ensure directory exists, create if it doesn't
|
|
39
|
+
*/
|
|
40
|
+
ensureDir(dir) {
|
|
41
|
+
if (!fs.existsSync(dir)) {
|
|
42
|
+
/**
|
|
43
|
+
* The mode 0o700 grants the owner of the file or directory full read, write, and execute permissions,
|
|
44
|
+
* while denying all access to everyone else.
|
|
45
|
+
* - 1st digit (7): Owner (User, with `rwx` permissions)
|
|
46
|
+
* - 2nd digit (0): Group
|
|
47
|
+
* - 3rd digit (0): Others (anyone not the owner or in the group)
|
|
48
|
+
*
|
|
49
|
+
* For directories, `x` permission is required to `cd` into a dir or access files inside
|
|
50
|
+
*/
|
|
51
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Read file contents, return null if doesn't exist
|
|
56
|
+
*/
|
|
57
|
+
readFile(filePath) {
|
|
58
|
+
try {
|
|
59
|
+
if (fs.existsSync(filePath)) {
|
|
60
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Write file contents, create parent directories if needed
|
|
70
|
+
*/
|
|
71
|
+
writeFile(filePath, content) {
|
|
72
|
+
const dir = path.dirname(filePath);
|
|
73
|
+
this.ensureDir(dir);
|
|
74
|
+
fs.writeFileSync(filePath, content, 'utf-8');
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Delete file if it exists
|
|
78
|
+
*/
|
|
79
|
+
deleteFile(filePath) {
|
|
80
|
+
if (fs.existsSync(filePath)) {
|
|
81
|
+
fs.unlinkSync(filePath);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Check if file exists
|
|
86
|
+
*/
|
|
87
|
+
fileExists(filePath) {
|
|
88
|
+
return fs.existsSync(filePath);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=base-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-storage.js","sourceRoot":"","sources":["../../../src/lib/storage/base-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,QAAQ,MAAM,WAAW,CAAC;AAEjC;;;;GAIG;AACH,MAAM,OAAO,WAAW;IACtB;;;;;;;OAOG;IACK,KAAK,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IAEpD;;;;;OAKG;IACO,YAAY;QACpB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED;;;;;OAKG;IACO,UAAU;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED;;OAEG;IACO,SAAS,CAAC,GAAW;QAC7B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB;;;;;;;;eAQG;YACH,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED;;OAEG;IACO,QAAQ,CAAC,QAAgB;QACjC,IAAI,CAAC;YACH,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC5C,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACO,SAAS,CAAC,QAAgB,EAAE,OAAe;QACnD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACpB,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACO,UAAU,CAAC,QAAgB;QACnC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED;;OAEG;IACO,UAAU,CAAC,QAAgB;QACnC,OAAO,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { BaseStorage } from './base-storage.js';
|
|
2
|
+
/**
|
|
3
|
+
* User configuration structure
|
|
4
|
+
*/
|
|
5
|
+
export interface Config {
|
|
6
|
+
apiUrl?: string;
|
|
7
|
+
editor?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Manages user configuration stored in XDG_CONFIG_HOME
|
|
11
|
+
* Example: ~/.config/papyrus/config.json
|
|
12
|
+
*/
|
|
13
|
+
export declare class ConfigStore extends BaseStorage {
|
|
14
|
+
private configPath;
|
|
15
|
+
constructor(configDir?: string);
|
|
16
|
+
/**
|
|
17
|
+
* Load configuration, returns empty object if not found
|
|
18
|
+
*/
|
|
19
|
+
load(): Config;
|
|
20
|
+
/**
|
|
21
|
+
* Save configuration
|
|
22
|
+
*/
|
|
23
|
+
save(config: Config): void;
|
|
24
|
+
/**
|
|
25
|
+
* Update specific config values
|
|
26
|
+
*/
|
|
27
|
+
update(updates: Partial<Config>): void;
|
|
28
|
+
/**
|
|
29
|
+
* Get specific config value
|
|
30
|
+
*/
|
|
31
|
+
get<K extends keyof Config>(key: K): Config[K] | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Set specific config value
|
|
34
|
+
*/
|
|
35
|
+
set<K extends keyof Config>(key: K, value: Config[K]): void;
|
|
36
|
+
/**
|
|
37
|
+
* Clear all configuration
|
|
38
|
+
*/
|
|
39
|
+
clear(): void;
|
|
40
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { BaseStorage } from './base-storage.js';
|
|
3
|
+
/**
|
|
4
|
+
* Manages user configuration stored in XDG_CONFIG_HOME
|
|
5
|
+
* Example: ~/.config/papyrus/config.json
|
|
6
|
+
*/
|
|
7
|
+
export class ConfigStore extends BaseStorage {
|
|
8
|
+
configPath;
|
|
9
|
+
constructor(configDir) {
|
|
10
|
+
super();
|
|
11
|
+
const dir = configDir ?? this.getConfigDir();
|
|
12
|
+
this.configPath = path.join(dir, 'config.json');
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Load configuration, returns empty object if not found
|
|
16
|
+
*/
|
|
17
|
+
load() {
|
|
18
|
+
const content = this.readFile(this.configPath);
|
|
19
|
+
if (!content)
|
|
20
|
+
return {};
|
|
21
|
+
try {
|
|
22
|
+
return JSON.parse(content);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Save configuration
|
|
30
|
+
*/
|
|
31
|
+
save(config) {
|
|
32
|
+
const content = JSON.stringify(config, null, 2);
|
|
33
|
+
this.writeFile(this.configPath, content);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Update specific config values
|
|
37
|
+
*/
|
|
38
|
+
update(updates) {
|
|
39
|
+
const current = this.load();
|
|
40
|
+
const updated = { ...current, ...updates };
|
|
41
|
+
this.save(updated);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get specific config value
|
|
45
|
+
*/
|
|
46
|
+
get(key) {
|
|
47
|
+
const config = this.load();
|
|
48
|
+
return config[key];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Set specific config value
|
|
52
|
+
*/
|
|
53
|
+
set(key, value) {
|
|
54
|
+
this.update({ [key]: value });
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Clear all configuration
|
|
58
|
+
*/
|
|
59
|
+
clear() {
|
|
60
|
+
this.deleteFile(this.configPath);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=config-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-store.js","sourceRoot":"","sources":["../../../src/lib/storage/config-store.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAUhD;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,WAAW;IAClC,UAAU,CAAS;IAE3B,YAAY,SAAkB;QAC5B,KAAK,EAAE,CAAC;QACR,MAAM,GAAG,GAAG,SAAS,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QAC7C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,IAAI;QACF,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QAExB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAW,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,MAAc;QACjB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAChD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,OAAwB;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,GAAG,CAAyB,GAAM;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC3B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,GAAG,CAAyB,GAAM,EAAE,KAAgB;QAClD,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAqB,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ConfigStore } from './config-store.js';
|
|
2
|
+
import { JournalStore } from './journal-storage.js';
|
|
3
|
+
import { SyncMetaStore } from './sync-meta-store.js';
|
|
4
|
+
import { TokenStore } from './token-store.js';
|
|
5
|
+
export { ConfigStore, type Config } from './config-store.js';
|
|
6
|
+
/**
|
|
7
|
+
* Singletons for easy access
|
|
8
|
+
*/
|
|
9
|
+
export declare const configStore: ConfigStore;
|
|
10
|
+
export declare const tokenStore: TokenStore;
|
|
11
|
+
export declare const syncMetaStore: SyncMetaStore;
|
|
12
|
+
export declare const journalStore: JournalStore;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ConfigStore } from './config-store.js';
|
|
2
|
+
import { JournalStore } from './journal-storage.js';
|
|
3
|
+
import { SyncMetaStore } from './sync-meta-store.js';
|
|
4
|
+
import { TokenStore } from './token-store.js';
|
|
5
|
+
export { ConfigStore } from './config-store.js';
|
|
6
|
+
/**
|
|
7
|
+
* Singletons for easy access
|
|
8
|
+
*/
|
|
9
|
+
export const configStore = new ConfigStore();
|
|
10
|
+
export const tokenStore = new TokenStore();
|
|
11
|
+
export const syncMetaStore = new SyncMetaStore();
|
|
12
|
+
export const journalStore = new JournalStore();
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAe,MAAM,mBAAmB,CAAC;AAC7D;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AAC7C,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;AAC3C,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;AACjD,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { BaseStorage } from './base-storage.js';
|
|
2
|
+
export interface JournalFileInfo {
|
|
3
|
+
date: string;
|
|
4
|
+
path: string;
|
|
5
|
+
size: number;
|
|
6
|
+
modified: Date;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Manages journal entries stored as markdown files with YAML frontmatter.
|
|
10
|
+
*
|
|
11
|
+
* File format:
|
|
12
|
+
* ---
|
|
13
|
+
* date: "20251210"
|
|
14
|
+
* hash: "abc123..."
|
|
15
|
+
* createdAt: "2025-12-10T10:00:00.000Z"
|
|
16
|
+
* updatedAt: "2025-12-10T10:00:00.000Z"
|
|
17
|
+
* deletedAt: null
|
|
18
|
+
* ---
|
|
19
|
+
*
|
|
20
|
+
* # Journal content here
|
|
21
|
+
*/
|
|
22
|
+
export declare class JournalStore extends BaseStorage {
|
|
23
|
+
private journalsDir;
|
|
24
|
+
constructor(dataDir?: string);
|
|
25
|
+
private getEntryPath;
|
|
26
|
+
/**
|
|
27
|
+
* Create a new journal entry
|
|
28
|
+
*/
|
|
29
|
+
create(date: string, content?: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* Get journal entry by date
|
|
32
|
+
*/
|
|
33
|
+
load(date: string): string | null;
|
|
34
|
+
/**
|
|
35
|
+
* Delete journal entry
|
|
36
|
+
*/
|
|
37
|
+
delete(date: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Check if entry exists for date
|
|
40
|
+
*/
|
|
41
|
+
exists(date: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* List all journal entries (sorted by date descending)
|
|
44
|
+
*/
|
|
45
|
+
list(): JournalFileInfo[];
|
|
46
|
+
}
|