diff --git a/Journal.App/.prettierignore b/Journal.App/.prettierignore
new file mode 100644
index 0000000..ca17681
--- /dev/null
+++ b/Journal.App/.prettierignore
@@ -0,0 +1,8 @@
+node_modules/
+build/
+.svelte-kit/
+.vscode/
+dist/
+coverage/
+target/
+src-tauri/target/
diff --git a/Journal.App/README.md b/Journal.App/README.md
index d5f55d0..aa3ddaa 100644
--- a/Journal.App/README.md
+++ b/Journal.App/README.md
@@ -18,12 +18,12 @@ npm run tauri dev # Tauri desktop window (connects to dev server)
## Build Targets
-| Command | Output | Use case |
-|---------|--------|----------|
-| `npm run build` | `Journal.App/build/` | Web bundle for `Journal.WebGateway` |
-| `.\scripts\publish-app.ps1 -Target web` | `Journal.App/build/` | Same, via script |
-| `.\scripts\publish-app.ps1 -Target tauri -TauriBundles none` | `src-tauri/target/release/journalapp.exe` | Raw desktop exe |
-| `.\scripts\publish-app.ps1 -Target tauri -TauriBundles nsis` | NSIS installer | Packaged installer |
+| Command | Output | Use case |
+| ------------------------------------------------------------ | ----------------------------------------- | ----------------------------------- |
+| `npm run build` | `Journal.App/build/` | Web bundle for `Journal.WebGateway` |
+| `.\scripts\publish-app.ps1 -Target web` | `Journal.App/build/` | Same, via script |
+| `.\scripts\publish-app.ps1 -Target tauri -TauriBundles none` | `src-tauri/target/release/journalapp.exe` | Raw desktop exe |
+| `.\scripts\publish-app.ps1 -Target tauri -TauriBundles nsis` | NSIS installer | Packaged installer |
## Frontend State Management
@@ -31,13 +31,13 @@ Svelte stores are the source of truth for all feature state.
### Current Stores
-| Store file | State exports | Notes |
-|-----------|---------------|-------|
-| `src/lib/stores/entries.ts` | `entriesStore` | Entry list, `getDefaultEntry`, `createEntryDraft` |
-| `src/lib/stores/fragments.ts` | `fragmentsStore` | Fragment CRUD + parse/serialize helpers |
-| `src/lib/stores/todos.ts` | `todoListsStore`, `todosStore` | Todo list and item CRUD |
-| `src/lib/stores/lists.ts` | `listsStore` | Generic list CRUD, `createListDraft` |
-| `src/lib/stores/settings.ts` | `settingsTags`, `settingsFragmentTypes` | Tag/type config |
+| Store file | State exports | Notes |
+| ----------------------------- | --------------------------------------- | ------------------------------------------------- |
+| `src/lib/stores/entries.ts` | `entriesStore` | Entry list, `getDefaultEntry`, `createEntryDraft` |
+| `src/lib/stores/fragments.ts` | `fragmentsStore` | Fragment CRUD + parse/serialize helpers |
+| `src/lib/stores/todos.ts` | `todoListsStore`, `todosStore` | Todo list and item CRUD |
+| `src/lib/stores/lists.ts` | `listsStore` | Generic list CRUD, `createListDraft` |
+| `src/lib/stores/settings.ts` | `settingsTags`, `settingsFragmentTypes` | Tag/type config |
### Store-First Rule
@@ -47,14 +47,14 @@ Svelte stores are the source of truth for all feature state.
## Tauri Commands (Rust → Frontend)
-| Command | Description |
-|---------|-------------|
-| `sidecar_command` | Forward a `CommandEnvelope` to `Journal.Sidecar` stdin/stdout and return parsed JSON |
-| `get_sidecar_root` | Get currently resolved sidecar root path |
-| `set_sidecar_root` | Override root path (saved to `settings.json`, restarts sidecar) |
-| `get_ui_settings` | Load tag/fragment-type settings |
-| `set_ui_settings` | Persist tag/fragment-type settings |
-| `shutdown` | Stop sidecar, exit app |
+| Command | Description |
+| ------------------ | ------------------------------------------------------------------------------------ |
+| `sidecar_command` | Forward a `CommandEnvelope` to `Journal.Sidecar` stdin/stdout and return parsed JSON |
+| `get_sidecar_root` | Get currently resolved sidecar root path |
+| `set_sidecar_root` | Override root path (saved to `settings.json`, restarts sidecar) |
+| `get_ui_settings` | Load tag/fragment-type settings |
+| `set_ui_settings` | Persist tag/fragment-type settings |
+| `shutdown` | Stop sidecar, exit app |
## Sidecar Path Resolution
diff --git a/Journal.App/package-lock.json b/Journal.App/package-lock.json
index c9c5ff0..47db5f0 100644
--- a/Journal.App/package-lock.json
+++ b/Journal.App/package-lock.json
@@ -18,6 +18,8 @@
"@sveltejs/kit": "^2.9.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tauri-apps/cli": "^2",
+ "prettier": "^3.8.1",
+ "prettier-plugin-svelte": "^3.5.0",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"typescript": "~5.6.2",
@@ -906,7 +908,6 @@
"integrity": "sha512-NXsZLvalgI3HrHG6ogoEVzjyV7bSFQNqQeekfU7nNufQFrRyV3EBDfQKEwxx50peu7spZR42JuC1PFhwxuvBrg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@standard-schema/spec": "^1.0.0",
"@sveltejs/acorn-typescript": "^1.0.5",
@@ -949,7 +950,6 @@
"integrity": "sha512-Y1Cs7hhTc+a5E9Va/xwKlAJoariQyHY+5zBgCZg4PFWNYQ1nMN9sjK1zhw1gK69DuqVP++sht/1GZg1aRwmAXQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@sveltejs/vite-plugin-svelte-inspector": "^4.0.1",
"debug": "^4.4.1",
@@ -1256,7 +1256,6 @@
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -1543,7 +1542,6 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=12"
},
@@ -1580,6 +1578,33 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/prettier": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz",
+ "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/prettier-plugin-svelte": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.5.0.tgz",
+ "integrity": "sha512-2lLO/7EupnjO/95t+XZesXs8Bf3nYLIDfCo270h5QWbj/vjLqmrQ1LiRk9LPggxSDsnVYfehamZNf+rgQYApZg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "prettier": "^3.0.0",
+ "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0"
+ }
+ },
"node_modules/readdirp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
@@ -1690,7 +1715,6 @@
"integrity": "sha512-pRUBr6j6uQDgBi208gHnGRMykw0Rf2Yr1HmLyRucsvcaYgIUxswJkT93WZJflsmezu5s8Lq+q78EoyLv2yaFCg==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@jridgewell/remapping": "^2.3.4",
"@jridgewell/sourcemap-codec": "^1.5.0",
@@ -1770,7 +1794,6 @@
"integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
"dev": true,
"license": "Apache-2.0",
- "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -1785,7 +1808,6 @@
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.4.4",
diff --git a/Journal.App/package.json b/Journal.App/package.json
index bdca238..bcb8b0a 100644
--- a/Journal.App/package.json
+++ b/Journal.App/package.json
@@ -9,7 +9,9 @@
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
- "tauri": "tauri"
+ "tauri": "tauri",
+ "format": "prettier --write .",
+ "format:check": "prettier --check ."
},
"license": "MIT",
"dependencies": {
@@ -22,6 +24,8 @@
"@sveltejs/kit": "^2.9.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tauri-apps/cli": "^2",
+ "prettier": "^3.8.1",
+ "prettier-plugin-svelte": "^3.5.0",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"typescript": "~5.6.2",
diff --git a/Journal.App/prettier.config.cjs b/Journal.App/prettier.config.cjs
new file mode 100644
index 0000000..282b589
--- /dev/null
+++ b/Journal.App/prettier.config.cjs
@@ -0,0 +1,11 @@
+module.exports = {
+ plugins: ["prettier-plugin-svelte"],
+ overrides: [
+ {
+ files: "*.svelte",
+ options: {
+ parser: "svelte",
+ },
+ },
+ ],
+};
diff --git a/Journal.App/src-tauri/capabilities/default.json b/Journal.App/src-tauri/capabilities/default.json
index 01a4101..cce481c 100644
--- a/Journal.App/src-tauri/capabilities/default.json
+++ b/Journal.App/src-tauri/capabilities/default.json
@@ -3,9 +3,5 @@
"identifier": "default",
"description": "Capability for the main window",
"windows": ["main"],
- "permissions": [
- "core:default",
- "dialog:default",
- "opener:default"
- ]
+ "permissions": ["core:default", "dialog:default", "opener:default"]
}
diff --git a/Journal.App/src-tauri/tauri.conf.json b/Journal.App/src-tauri/tauri.conf.json
index ffc904b..2b445fc 100644
--- a/Journal.App/src-tauri/tauri.conf.json
+++ b/Journal.App/src-tauri/tauri.conf.json
@@ -32,4 +32,4 @@
"icons/icon.ico"
]
}
-}
\ No newline at end of file
+}
diff --git a/Journal.App/src/app.html b/Journal.App/src/app.html
index ef938e9..a3a83c3 100644
--- a/Journal.App/src/app.html
+++ b/Journal.App/src/app.html
@@ -3,12 +3,16 @@
-
-
+
+
Journal
%sveltekit.head%
+
%sveltekit.body%
diff --git a/Journal.App/src/lib/backend/auth.ts b/Journal.App/src/lib/backend/auth.ts
index b3f8697..f1c3639 100644
--- a/Journal.App/src/lib/backend/auth.ts
+++ b/Journal.App/src/lib/backend/auth.ts
@@ -4,7 +4,7 @@ import { pickCase } from "./normalize";
export function hydrateWorkspace(password: string): Promise {
return sendCommand({
action: "db.hydrate_workspace",
- payload: { password }
+ payload: { password },
});
}
@@ -24,17 +24,19 @@ type PersistOptions = {
keepalive?: boolean;
};
-async function getRuntimeConfig(options: PersistOptions = {}): Promise {
+async function getRuntimeConfig(
+ options: PersistOptions = {},
+): Promise {
const data = await sendCommand(
{
- action: "config.get"
+ action: "config.get",
},
- options
+ options,
);
return {
dataDirectory: pickCase(data, "dataDirectory", "DataDirectory", ""),
- vaultDirectory: pickCase(data, "vaultDirectory", "VaultDirectory", "")
+ vaultDirectory: pickCase(data, "vaultDirectory", "VaultDirectory", ""),
};
}
@@ -45,8 +47,8 @@ export async function unlockVaultWorkspace(password: string): Promise {
payload: {
password,
vaultDirectory: config.vaultDirectory,
- dataDirectory: config.dataDirectory
- }
+ dataDirectory: config.dataDirectory,
+ },
});
if (!loaded) {
@@ -57,12 +59,15 @@ export async function unlockVaultWorkspace(password: string): Promise {
action: "db.hydrate_workspace",
payload: {
password,
- dataDirectory: config.dataDirectory
- }
+ dataDirectory: config.dataDirectory,
+ },
});
}
-export async function persistAndClearVault(password: string, options: PersistOptions = {}): Promise {
+export async function persistAndClearVault(
+ password: string,
+ options: PersistOptions = {},
+): Promise {
const config = await getRuntimeConfig(options);
await sendCommand(
@@ -71,19 +76,19 @@ export async function persistAndClearVault(password: string, options: PersistOpt
payload: {
password,
vaultDirectory: config.vaultDirectory,
- dataDirectory: config.dataDirectory
- }
+ dataDirectory: config.dataDirectory,
+ },
},
- options
+ options,
);
await sendCommand(
{
action: "vault.clear_data_directory",
payload: {
- dataDirectory: config.dataDirectory
- }
+ dataDirectory: config.dataDirectory,
+ },
},
- options
+ options,
);
}
diff --git a/Journal.App/src/lib/backend/client.ts b/Journal.App/src/lib/backend/client.ts
index 1ab887b..81b5dc2 100644
--- a/Journal.App/src/lib/backend/client.ts
+++ b/Journal.App/src/lib/backend/client.ts
@@ -9,14 +9,17 @@ type SendCommandOptions = {
keepalive?: boolean;
};
-export async function sendCommand(command: BackendCommand, options: SendCommandOptions = {}): Promise {
+export async function sendCommand(
+ command: BackendCommand,
+ options: SendCommandOptions = {},
+): Promise {
const envelope: BackendCommand = {
...command,
- correlationId: command.correlationId ?? newCorrelationId()
+ correlationId: command.correlationId ?? newCorrelationId(),
};
const response = await invoke>("sidecar_command", {
command: envelope,
- keepalive: options.keepalive === true
+ keepalive: options.keepalive === true,
});
if (!response.ok) {
diff --git a/Journal.App/src/lib/backend/entries.ts b/Journal.App/src/lib/backend/entries.ts
index a4dd4c3..9b6fdd0 100644
--- a/Journal.App/src/lib/backend/entries.ts
+++ b/Journal.App/src/lib/backend/entries.ts
@@ -1,5 +1,9 @@
import { sendCommand } from "./client";
-import { normalizeFragment, type FragmentDto, type FragmentDtoRaw } from "./fragments";
+import {
+ normalizeFragment,
+ type FragmentDto,
+ type FragmentDtoRaw,
+} from "./fragments";
import { pickCase } from "./normalize";
export type ParsedSectionDto = {
@@ -107,80 +111,126 @@ function normalizeSection(raw: ParsedSectionDtoRaw): ParsedSectionDto {
return {
title: pickCase(raw, "title", "Title", ""),
content: pickCase(raw, "content", "Content", [] as string[]),
- checkboxes: pickCase(raw, "checkboxes", "Checkboxes", {} as Record)
+ checkboxes: pickCase(
+ raw,
+ "checkboxes",
+ "Checkboxes",
+ {} as Record,
+ ),
};
}
-function normalizeJournalEntry(raw: JournalEntryDtoRaw | undefined): JournalEntryDto {
- const fragments = pickCase(raw, "fragments", "Fragments", [] as FragmentDtoRaw[]);
- const sections = pickCase(raw, "sections", "Sections", {} as Record);
+function normalizeJournalEntry(
+ raw: JournalEntryDtoRaw | undefined,
+): JournalEntryDto {
+ const fragments = pickCase(
+ raw,
+ "fragments",
+ "Fragments",
+ [] as FragmentDtoRaw[],
+ );
+ const sections = pickCase(
+ raw,
+ "sections",
+ "Sections",
+ {} as Record,
+ );
return {
date: pickCase(raw, "date", "Date", ""),
fragments: fragments.map(normalizeFragment),
rawContent: pickCase(raw, "rawContent", "RawContent", ""),
sections: Object.fromEntries(
- Object.entries(sections).map(([key, value]) => [key, normalizeSection(value)])
- )
+ Object.entries(sections).map(([key, value]) => [
+ key,
+ normalizeSection(value),
+ ]),
+ ),
};
}
function normalizeEntryListItem(raw: EntryListItemDtoRaw): EntryListItemDto {
return {
fileName: pickCase(raw, "fileName", "FileName", ""),
- filePath: pickCase(raw, "filePath", "FilePath", "")
+ filePath: pickCase(raw, "filePath", "FilePath", ""),
};
}
-function normalizeEntryLoadResult(raw: EntryLoadResultDtoRaw): EntryLoadResultDto {
- const nestedEntry = pickCase(raw, "entry", "Entry", undefined as JournalEntryDtoRaw | undefined);
- const entry =
- nestedEntry
- ? normalizeJournalEntry(nestedEntry)
- : normalizeJournalEntry({
- date: pickCase(raw, "date", "Date", undefined as string | undefined),
- rawContent: pickCase(raw, "rawContent", "RawContent", undefined as string | undefined),
- fragments: [],
- sections: {}
- });
+function normalizeEntryLoadResult(
+ raw: EntryLoadResultDtoRaw,
+): EntryLoadResultDto {
+ const nestedEntry = pickCase(
+ raw,
+ "entry",
+ "Entry",
+ undefined as JournalEntryDtoRaw | undefined,
+ );
+ const entry = nestedEntry
+ ? normalizeJournalEntry(nestedEntry)
+ : normalizeJournalEntry({
+ date: pickCase(raw, "date", "Date", undefined as string | undefined),
+ rawContent: pickCase(
+ raw,
+ "rawContent",
+ "RawContent",
+ undefined as string | undefined,
+ ),
+ fragments: [],
+ sections: {},
+ });
return {
fileName: pickCase(raw, "fileName", "FileName", ""),
filePath: pickCase(raw, "filePath", "FilePath", ""),
- entry
+ entry,
};
}
-function normalizeEntrySearchResult(raw: EntrySearchResultDtoRaw): EntrySearchResultDto {
- const nestedEntry = pickCase(raw, "entry", "Entry", undefined as JournalEntryDtoRaw | undefined);
- const entry =
- nestedEntry
- ? normalizeJournalEntry(nestedEntry)
- : normalizeJournalEntry({
- date: pickCase(raw, "date", "Date", undefined as string | undefined),
- rawContent: pickCase(raw, "rawContent", "RawContent", undefined as string | undefined),
- fragments: [],
- sections: {}
- });
+function normalizeEntrySearchResult(
+ raw: EntrySearchResultDtoRaw,
+): EntrySearchResultDto {
+ const nestedEntry = pickCase(
+ raw,
+ "entry",
+ "Entry",
+ undefined as JournalEntryDtoRaw | undefined,
+ );
+ const entry = nestedEntry
+ ? normalizeJournalEntry(nestedEntry)
+ : normalizeJournalEntry({
+ date: pickCase(raw, "date", "Date", undefined as string | undefined),
+ rawContent: pickCase(
+ raw,
+ "rawContent",
+ "RawContent",
+ undefined as string | undefined,
+ ),
+ fragments: [],
+ sections: {},
+ });
return {
fileName: pickCase(raw, "fileName", "FileName", ""),
- entry
+ entry,
};
}
-export async function listEntries(dataDirectory?: string): Promise {
+export async function listEntries(
+ dataDirectory?: string,
+): Promise {
const data = await sendCommand({
action: "entries.list",
- payload: { dataDirectory }
+ payload: { dataDirectory },
});
- return data.map(normalizeEntryListItem).filter((item) => Boolean(item.filePath));
+ return data
+ .map(normalizeEntryListItem)
+ .filter((item) => Boolean(item.filePath));
}
export async function loadEntry(filePath: string): Promise {
const data = await sendCommand({
action: "entries.load",
- payload: { filePath }
+ payload: { filePath },
});
return normalizeEntryLoadResult(data);
@@ -194,26 +244,30 @@ export async function saveEntry(payload: {
}): Promise {
const data = await sendCommand({
action: "entries.save",
- payload
+ payload,
});
return {
- filePath: pickCase(data, "filePath", "FilePath", "")
+ filePath: pickCase(data, "filePath", "FilePath", ""),
};
}
export async function deleteEntry(filePath: string): Promise {
return sendCommand({
action: "entries.delete",
- payload: { filePath }
+ payload: { filePath },
});
}
-export async function searchEntries(payload: EntrySearchRequestDto): Promise {
+export async function searchEntries(
+ payload: EntrySearchRequestDto,
+): Promise {
const data = await sendCommand({
action: "search.entries",
- payload
+ payload,
});
- return data.map(normalizeEntrySearchResult).filter((item) => Boolean(item.fileName));
+ return data
+ .map(normalizeEntrySearchResult)
+ .filter((item) => Boolean(item.fileName));
}
diff --git a/Journal.App/src/lib/backend/fragments.ts b/Journal.App/src/lib/backend/fragments.ts
index dc0f26f..fdd03a2 100644
--- a/Journal.App/src/lib/backend/fragments.ts
+++ b/Journal.App/src/lib/backend/fragments.ts
@@ -41,13 +41,13 @@ export function normalizeFragment(raw: FragmentDtoRaw): FragmentDto {
type: pickCase(raw, "type", "Type", ""),
description: pickCase(raw, "description", "Description", ""),
time: pickCase(raw, "time", "Time", ""),
- tags: pickCase(raw, "tags", "Tags", [] as string[])
+ tags: pickCase(raw, "tags", "Tags", [] as string[]),
};
}
export async function listFragments(): Promise {
const data = await sendCommand({
- action: "fragments.list"
+ action: "fragments.list",
});
return data.map(normalizeFragment).filter((item) => Boolean(item.id));
}
@@ -55,32 +55,37 @@ export async function listFragments(): Promise {
export async function getFragment(id: string): Promise {
const data = await sendCommand({
action: "fragments.get",
- id
+ id,
});
if (!data) return null;
const normalized = normalizeFragment(data);
return normalized.id ? normalized : null;
}
-export async function createFragment(payload: CreateFragmentPayload): Promise {
+export async function createFragment(
+ payload: CreateFragmentPayload,
+): Promise {
const data = await sendCommand({
action: "fragments.create",
- payload
+ payload,
});
return normalizeFragment(data);
}
-export function updateFragment(id: string, payload: UpdateFragmentPayload): Promise {
+export function updateFragment(
+ id: string,
+ payload: UpdateFragmentPayload,
+): Promise {
return sendCommand({
action: "fragments.update",
id,
- payload
+ payload,
});
}
export function deleteFragment(id: string): Promise {
return sendCommand({
action: "fragments.delete",
- id
+ id,
});
}
diff --git a/Journal.App/src/lib/backend/lists.ts b/Journal.App/src/lib/backend/lists.ts
index 74ec4d8..037c3f4 100644
--- a/Journal.App/src/lib/backend/lists.ts
+++ b/Journal.App/src/lib/backend/lists.ts
@@ -38,13 +38,13 @@ export function normalizeList(raw: ListDocumentDtoRaw): ListDocumentDto {
label: pickCase(raw, "label", "Label", ""),
content: pickCase(raw, "content", "Content", ""),
createdAt: pickCase(raw, "createdAt", "CreatedAt", ""),
- updatedAt: pickCase(raw, "updatedAt", "UpdatedAt", "")
+ updatedAt: pickCase(raw, "updatedAt", "UpdatedAt", ""),
};
}
export async function listLists(): Promise {
const data = await sendCommand({
- action: "lists.list"
+ action: "lists.list",
});
return data.map(normalizeList).filter((item) => Boolean(item.id));
}
@@ -52,32 +52,37 @@ export async function listLists(): Promise {
export async function getList(id: string): Promise {
const data = await sendCommand({
action: "lists.get",
- id
+ id,
});
if (!data) return null;
const normalized = normalizeList(data);
return normalized.id ? normalized : null;
}
-export async function createList(payload: CreateListPayload): Promise {
+export async function createList(
+ payload: CreateListPayload,
+): Promise {
const data = await sendCommand({
action: "lists.create",
- payload
+ payload,
});
return normalizeList(data);
}
-export function updateList(id: string, payload: UpdateListPayload): Promise {
+export function updateList(
+ id: string,
+ payload: UpdateListPayload,
+): Promise {
return sendCommand({
action: "lists.update",
id,
- payload
+ payload,
});
}
export function deleteList(id: string): Promise {
return sendCommand({
action: "lists.delete",
- id
+ id,
});
}
diff --git a/Journal.App/src/lib/backend/normalize.ts b/Journal.App/src/lib/backend/normalize.ts
index 6dded60..40a6413 100644
--- a/Journal.App/src/lib/backend/normalize.ts
+++ b/Journal.App/src/lib/backend/normalize.ts
@@ -1,14 +1,16 @@
type UnknownObject = Record;
function asObject(value: unknown): UnknownObject | undefined {
- return value && typeof value === "object" ? (value as UnknownObject) : undefined;
+ return value && typeof value === "object"
+ ? (value as UnknownObject)
+ : undefined;
}
export function pickCase(
source: unknown,
camelKey: string,
pascalKey: string,
- fallback: T
+ fallback: T,
): T {
const obj = asObject(source);
if (!obj) return fallback;
diff --git a/Journal.App/src/lib/backend/templates.ts b/Journal.App/src/lib/backend/templates.ts
index 79bf828..0b6b8ef 100644
--- a/Journal.App/src/lib/backend/templates.ts
+++ b/Journal.App/src/lib/backend/templates.ts
@@ -37,32 +37,40 @@ type EntryTemplateSaveResultDtoRaw = {
FilePath?: string;
};
-function normalizeTemplateItem(raw: EntryTemplateItemDtoRaw): EntryTemplateItemDto {
+function normalizeTemplateItem(
+ raw: EntryTemplateItemDtoRaw,
+): EntryTemplateItemDto {
return {
fileName: pickCase(raw, "fileName", "FileName", ""),
- filePath: pickCase(raw, "filePath", "FilePath", "")
+ filePath: pickCase(raw, "filePath", "FilePath", ""),
};
}
-export async function listEntryTemplates(dataDirectory?: string): Promise {
+export async function listEntryTemplates(
+ dataDirectory?: string,
+): Promise {
const data = await sendCommand({
action: "templates.list",
- payload: { dataDirectory }
+ payload: { dataDirectory },
});
- return data.map(normalizeTemplateItem).filter((item) => Boolean(item.filePath));
+ return data
+ .map(normalizeTemplateItem)
+ .filter((item) => Boolean(item.filePath));
}
-export async function loadEntryTemplate(filePath: string): Promise {
+export async function loadEntryTemplate(
+ filePath: string,
+): Promise {
const data = await sendCommand({
action: "templates.load",
- payload: { filePath }
+ payload: { filePath },
});
return {
fileName: pickCase(data, "fileName", "FileName", ""),
filePath: pickCase(data, "filePath", "FilePath", ""),
- content: pickCase(data, "content", "Content", "")
+ content: pickCase(data, "content", "Content", ""),
};
}
@@ -74,17 +82,17 @@ export async function saveEntryTemplate(payload: {
}): Promise {
const data = await sendCommand({
action: "templates.save",
- payload
+ payload,
});
return {
- filePath: pickCase(data, "filePath", "FilePath", "")
+ filePath: pickCase(data, "filePath", "FilePath", ""),
};
}
export async function deleteEntryTemplate(filePath: string): Promise {
return sendCommand({
action: "templates.delete",
- payload: { filePath }
+ payload: { filePath },
});
}
diff --git a/Journal.App/src/lib/backend/todos.ts b/Journal.App/src/lib/backend/todos.ts
index 1802e9e..73c5150 100644
--- a/Journal.App/src/lib/backend/todos.ts
+++ b/Journal.App/src/lib/backend/todos.ts
@@ -66,7 +66,7 @@ function normalizeItem(raw: TodoItemDtoRaw): TodoItemDto {
listId: pickCase(raw, "listId", "ListId", ""),
text: pickCase(raw, "text", "Text", ""),
done: pickCase(raw, "done", "Done", false),
- sortOrder: pickCase(raw, "sortOrder", "SortOrder", 0)
+ sortOrder: pickCase(raw, "sortOrder", "SortOrder", 0),
};
}
@@ -76,13 +76,13 @@ function normalizeList(raw: TodoListDtoRaw): TodoListDto {
id: pickCase(raw, "id", "Id", ""),
label: pickCase(raw, "label", "Label", ""),
createdAt: pickCase(raw, "createdAt", "CreatedAt", ""),
- items: rawItems.map(normalizeItem)
+ items: rawItems.map(normalizeItem),
};
}
export async function listTodoLists(): Promise {
const data = await sendCommand({
- action: "todos.list"
+ action: "todos.list",
});
return data.map(normalizeList).filter((item) => Boolean(item.id));
}
@@ -90,55 +90,65 @@ export async function listTodoLists(): Promise {
export async function getTodoList(id: string): Promise {
const data = await sendCommand({
action: "todos.get",
- id
+ id,
});
if (!data) return null;
const normalized = normalizeList(data);
return normalized.id ? normalized : null;
}
-export async function createTodoList(payload: CreateTodoListPayload): Promise {
+export async function createTodoList(
+ payload: CreateTodoListPayload,
+): Promise {
const data = await sendCommand({
action: "todos.create",
- payload
+ payload,
});
return normalizeList(data);
}
-export function updateTodoList(id: string, payload: UpdateTodoListPayload): Promise {
+export function updateTodoList(
+ id: string,
+ payload: UpdateTodoListPayload,
+): Promise {
return sendCommand({
action: "todos.update",
id,
- payload
+ payload,
});
}
export function deleteTodoList(id: string): Promise {
return sendCommand({
action: "todos.delete",
- id
+ id,
});
}
-export async function createTodoItem(payload: CreateTodoItemPayload): Promise {
+export async function createTodoItem(
+ payload: CreateTodoItemPayload,
+): Promise {
const data = await sendCommand({
action: "todos.items.create",
- payload
+ payload,
});
return normalizeItem(data);
}
-export function updateTodoItem(id: string, payload: UpdateTodoItemPayload): Promise {
+export function updateTodoItem(
+ id: string,
+ payload: UpdateTodoItemPayload,
+): Promise {
return sendCommand({
action: "todos.items.update",
id,
- payload
+ payload,
});
}
export function deleteTodoItem(id: string): Promise {
return sendCommand({
action: "todos.items.delete",
- id
+ id,
});
}
diff --git a/Journal.App/src/lib/backend/types.ts b/Journal.App/src/lib/backend/types.ts
index 87644cf..1be56ad 100644
--- a/Journal.App/src/lib/backend/types.ts
+++ b/Journal.App/src/lib/backend/types.ts
@@ -10,4 +10,3 @@ export type BackendCommand = {
export type BackendOk = { ok: true; data: T };
export type BackendErr = { ok: false; error: string };
export type BackendResponse = BackendOk | BackendErr;
-
diff --git a/Journal.App/src/lib/components/AppModal.svelte b/Journal.App/src/lib/components/AppModal.svelte
index 2ced0ef..240d830 100644
--- a/Journal.App/src/lib/components/AppModal.svelte
+++ b/Journal.App/src/lib/components/AppModal.svelte
@@ -1,3 +1,4 @@
+