@autumnsgrove/groveengine 0.6.3 → 0.6.5

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.
Files changed (35) hide show
  1. package/dist/components/admin/FloatingToolbar.svelte +373 -0
  2. package/dist/components/admin/FloatingToolbar.svelte.d.ts +17 -0
  3. package/dist/components/admin/MarkdownEditor.svelte +26 -347
  4. package/dist/components/admin/MarkdownEditor.svelte.d.ts +1 -1
  5. package/dist/components/admin/composables/index.d.ts +0 -2
  6. package/dist/components/admin/composables/index.js +0 -2
  7. package/dist/components/custom/MobileTOC.svelte +20 -13
  8. package/dist/components/quota/UpgradePrompt.svelte +1 -1
  9. package/dist/server/services/database.d.ts +138 -0
  10. package/dist/server/services/database.js +234 -0
  11. package/dist/server/services/index.d.ts +5 -1
  12. package/dist/server/services/index.js +24 -2
  13. package/dist/server/services/turnstile.d.ts +66 -0
  14. package/dist/server/services/turnstile.js +131 -0
  15. package/dist/server/services/users.d.ts +104 -0
  16. package/dist/server/services/users.js +158 -0
  17. package/dist/styles/README.md +50 -0
  18. package/dist/styles/vine-pattern.css +24 -0
  19. package/dist/types/turnstile.d.ts +42 -0
  20. package/dist/ui/components/forms/TurnstileWidget.svelte +111 -0
  21. package/dist/ui/components/forms/TurnstileWidget.svelte.d.ts +14 -0
  22. package/dist/ui/components/primitives/dialog/dialog-overlay.svelte +1 -1
  23. package/dist/ui/components/primitives/sheet/sheet-overlay.svelte +1 -1
  24. package/dist/ui/components/ui/Logo.svelte +161 -23
  25. package/dist/ui/components/ui/Logo.svelte.d.ts +4 -10
  26. package/dist/ui/tokens/fonts.d.ts +69 -0
  27. package/dist/ui/tokens/fonts.js +341 -0
  28. package/dist/ui/tokens/index.d.ts +6 -5
  29. package/dist/ui/tokens/index.js +7 -6
  30. package/package.json +1 -1
  31. package/static/robots.txt +487 -0
  32. package/dist/components/admin/composables/useCommandPalette.svelte.d.ts +0 -87
  33. package/dist/components/admin/composables/useCommandPalette.svelte.js +0 -158
  34. package/dist/components/admin/composables/useSlashCommands.svelte.d.ts +0 -104
  35. package/dist/components/admin/composables/useSlashCommands.svelte.js +0 -215
@@ -1,158 +0,0 @@
1
- /**
2
- * Command Palette Composable
3
- * Manages the command palette (Cmd+K) functionality
4
- */
5
-
6
- /**
7
- * @typedef {Object} PaletteAction
8
- * @property {string} id
9
- * @property {string} label
10
- * @property {string} shortcut
11
- * @property {() => void} action
12
- * @property {string} [themeKey]
13
- * @property {boolean} [isTheme]
14
- */
15
-
16
- /**
17
- * @typedef {Object} CommandPaletteState
18
- * @property {boolean} open
19
- * @property {string} query
20
- * @property {number} selectedIndex
21
- */
22
-
23
- /**
24
- * @typedef {Object} CommandPaletteOptions
25
- * @property {() => PaletteAction[]} [getActions] - Function to get available actions
26
- * @property {() => Record<string, any>} [getThemes] - Function to get available themes
27
- * @property {() => string} [getCurrentTheme] - Function to get current theme
28
- */
29
-
30
- /**
31
- * @typedef {Object} CommandPaletteManager
32
- * @property {CommandPaletteState} state
33
- * @property {boolean} isOpen
34
- * @property {string} query
35
- * @property {number} selectedIndex
36
- * @property {() => PaletteAction[]} getAllCommands
37
- * @property {() => PaletteAction[]} getFilteredCommands
38
- * @property {() => void} open
39
- * @property {() => void} close
40
- * @property {() => void} toggle
41
- * @property {(direction: 'up' | 'down') => void} navigate
42
- * @property {(index: number) => PaletteAction | undefined} execute
43
- * @property {(query: string) => void} setQuery
44
- */
45
-
46
- /**
47
- * Creates a command palette manager with Svelte 5 runes
48
- * @param {CommandPaletteOptions} options - Configuration options
49
- * @returns {CommandPaletteManager} Command palette state and controls
50
- */
51
- export function useCommandPalette(options = {}) {
52
- const { getActions, getThemes, getCurrentTheme } = options;
53
-
54
- let state = $state({
55
- open: false,
56
- query: "",
57
- selectedIndex: 0,
58
- });
59
-
60
- // Get all commands including theme commands
61
- function getAllCommands() {
62
- const actions = getActions ? getActions() : [];
63
- const themes = getThemes ? getThemes() : {};
64
- const currentTheme = getCurrentTheme ? getCurrentTheme() : "";
65
-
66
- const themeCommands = Object.entries(themes).map(([key, theme]) => ({
67
- id: `theme-${key}`,
68
- label: `Theme: ${theme.label} (${theme.desc})`,
69
- shortcut: currentTheme === key ? "●" : "",
70
- action: () => {
71
- // Theme action is handled by the caller
72
- },
73
- themeKey: key,
74
- isTheme: true,
75
- }));
76
-
77
- return [...actions, ...themeCommands];
78
- }
79
-
80
- // Get filtered commands based on query
81
- function getFilteredCommands() {
82
- const allCommands = getAllCommands();
83
- return allCommands.filter((cmd) =>
84
- cmd.label.toLowerCase().includes(state.query.toLowerCase())
85
- );
86
- }
87
-
88
- function open() {
89
- state.open = true;
90
- state.query = "";
91
- state.selectedIndex = 0;
92
- }
93
-
94
- function close() {
95
- state.open = false;
96
- }
97
-
98
- function toggle() {
99
- if (state.open) {
100
- close();
101
- } else {
102
- open();
103
- }
104
- }
105
-
106
- /** @param {'up' | 'down'} direction */
107
- function navigate(direction) {
108
- const filtered = getFilteredCommands();
109
- const count = filtered.length;
110
- if (count === 0) return;
111
-
112
- if (direction === "down") {
113
- state.selectedIndex = (state.selectedIndex + 1) % count;
114
- } else if (direction === "up") {
115
- state.selectedIndex = (state.selectedIndex - 1 + count) % count;
116
- }
117
- }
118
-
119
- /** @param {number} index */
120
- function execute(index) {
121
- const filtered = getFilteredCommands();
122
- const cmd = filtered[index];
123
- if (cmd && cmd.action) {
124
- cmd.action();
125
- close();
126
- }
127
- return cmd;
128
- }
129
-
130
- /** @param {string} query */
131
- function setQuery(query) {
132
- state.query = query;
133
- state.selectedIndex = 0;
134
- }
135
-
136
- return {
137
- get state() {
138
- return state;
139
- },
140
- get isOpen() {
141
- return state.open;
142
- },
143
- get query() {
144
- return state.query;
145
- },
146
- get selectedIndex() {
147
- return state.selectedIndex;
148
- },
149
- getAllCommands,
150
- getFilteredCommands,
151
- open,
152
- close,
153
- toggle,
154
- navigate,
155
- execute,
156
- setQuery,
157
- };
158
- }
@@ -1,104 +0,0 @@
1
- /**
2
- * Creates a slash commands manager with Svelte 5 runes
3
- * @param {SlashCommandsOptions} options - Configuration options
4
- * @returns {SlashCommandsManager} Slash commands state and controls
5
- */
6
- export function useSlashCommands(options?: SlashCommandsOptions): SlashCommandsManager;
7
- /**
8
- * Slash Commands Composable
9
- * Manages the slash command menu and execution
10
- */
11
- /**
12
- * @typedef {Object} SlashCommand
13
- * @property {string} id
14
- * @property {string} label
15
- * @property {string} insert
16
- * @property {number} [cursorOffset]
17
- * @property {boolean} [isSnippet]
18
- * @property {boolean} [isAction]
19
- * @property {(() => void)} [action]
20
- */
21
- /**
22
- * @typedef {Object} SlashMenuState
23
- * @property {boolean} open
24
- * @property {string} query
25
- * @property {{x: number, y: number}} position
26
- * @property {number} selectedIndex
27
- */
28
- /**
29
- * @typedef {Object} SlashCommandsOptions
30
- * @property {() => HTMLTextAreaElement|null} [getTextareaRef] - Function to get textarea reference
31
- * @property {() => string} [getContent] - Function to get content
32
- * @property {(content: string) => void} [setContent] - Function to set content
33
- * @property {() => Array<{id: string, name: string, content: string}>} [getSnippets] - Function to get user snippets
34
- * @property {() => void} [onOpenSnippetsModal] - Callback to open snippets modal
35
- */
36
- /**
37
- * @typedef {Object} SlashCommandsManager
38
- * @property {SlashMenuState} menu
39
- * @property {boolean} isOpen
40
- * @property {() => SlashCommand[]} getAllCommands
41
- * @property {() => SlashCommand[]} getFilteredCommands
42
- * @property {() => void} open
43
- * @property {() => void} close
44
- * @property {(direction: 'up' | 'down') => void} navigate
45
- * @property {(index: number) => void} execute
46
- * @property {(key: string, cursorPos: number, content: string) => boolean} shouldTrigger
47
- */
48
- /** @type {SlashCommand[]} */
49
- export const baseSlashCommands: SlashCommand[];
50
- export type SlashCommand = {
51
- id: string;
52
- label: string;
53
- insert: string;
54
- cursorOffset?: number | undefined;
55
- isSnippet?: boolean | undefined;
56
- isAction?: boolean | undefined;
57
- action?: (() => void) | undefined;
58
- };
59
- export type SlashMenuState = {
60
- open: boolean;
61
- query: string;
62
- position: {
63
- x: number;
64
- y: number;
65
- };
66
- selectedIndex: number;
67
- };
68
- export type SlashCommandsOptions = {
69
- /**
70
- * - Function to get textarea reference
71
- */
72
- getTextareaRef?: (() => HTMLTextAreaElement | null) | undefined;
73
- /**
74
- * - Function to get content
75
- */
76
- getContent?: (() => string) | undefined;
77
- /**
78
- * - Function to set content
79
- */
80
- setContent?: ((content: string) => void) | undefined;
81
- /**
82
- * - Function to get user snippets
83
- */
84
- getSnippets?: (() => Array<{
85
- id: string;
86
- name: string;
87
- content: string;
88
- }>) | undefined;
89
- /**
90
- * - Callback to open snippets modal
91
- */
92
- onOpenSnippetsModal?: (() => void) | undefined;
93
- };
94
- export type SlashCommandsManager = {
95
- menu: SlashMenuState;
96
- isOpen: boolean;
97
- getAllCommands: () => SlashCommand[];
98
- getFilteredCommands: () => SlashCommand[];
99
- open: () => void;
100
- close: () => void;
101
- navigate: (direction: "up" | "down") => void;
102
- execute: (index: number) => void;
103
- shouldTrigger: (key: string, cursorPos: number, content: string) => boolean;
104
- };
@@ -1,215 +0,0 @@
1
- /**
2
- * Slash Commands Composable
3
- * Manages the slash command menu and execution
4
- */
5
-
6
- /**
7
- * @typedef {Object} SlashCommand
8
- * @property {string} id
9
- * @property {string} label
10
- * @property {string} insert
11
- * @property {number} [cursorOffset]
12
- * @property {boolean} [isSnippet]
13
- * @property {boolean} [isAction]
14
- * @property {(() => void)} [action]
15
- */
16
-
17
- /**
18
- * @typedef {Object} SlashMenuState
19
- * @property {boolean} open
20
- * @property {string} query
21
- * @property {{x: number, y: number}} position
22
- * @property {number} selectedIndex
23
- */
24
-
25
- /**
26
- * @typedef {Object} SlashCommandsOptions
27
- * @property {() => HTMLTextAreaElement|null} [getTextareaRef] - Function to get textarea reference
28
- * @property {() => string} [getContent] - Function to get content
29
- * @property {(content: string) => void} [setContent] - Function to set content
30
- * @property {() => Array<{id: string, name: string, content: string}>} [getSnippets] - Function to get user snippets
31
- * @property {() => void} [onOpenSnippetsModal] - Callback to open snippets modal
32
- */
33
-
34
- /**
35
- * @typedef {Object} SlashCommandsManager
36
- * @property {SlashMenuState} menu
37
- * @property {boolean} isOpen
38
- * @property {() => SlashCommand[]} getAllCommands
39
- * @property {() => SlashCommand[]} getFilteredCommands
40
- * @property {() => void} open
41
- * @property {() => void} close
42
- * @property {(direction: 'up' | 'down') => void} navigate
43
- * @property {(index: number) => void} execute
44
- * @property {(key: string, cursorPos: number, content: string) => boolean} shouldTrigger
45
- */
46
-
47
- // Base slash commands definition
48
- /** @type {SlashCommand[]} */
49
- export const baseSlashCommands = [
50
- { id: "heading1", label: "Heading 1", insert: "# " },
51
- { id: "heading2", label: "Heading 2", insert: "## " },
52
- { id: "heading3", label: "Heading 3", insert: "### " },
53
- { id: "code", label: "Code Block", insert: "```\n\n```", cursorOffset: 4 },
54
- { id: "quote", label: "Quote", insert: "> " },
55
- { id: "list", label: "Bullet List", insert: "- " },
56
- { id: "numbered", label: "Numbered List", insert: "1. " },
57
- { id: "link", label: "Link", insert: "[](url)", cursorOffset: 1 },
58
- { id: "image", label: "Image", insert: "![alt](url)", cursorOffset: 2 },
59
- { id: "divider", label: "Divider", insert: "\n---\n" },
60
- {
61
- id: "anchor",
62
- label: "Custom Anchor",
63
- insert: "<!-- anchor:name -->\n",
64
- cursorOffset: 14,
65
- },
66
- ];
67
-
68
- /**
69
- * Creates a slash commands manager with Svelte 5 runes
70
- * @param {SlashCommandsOptions} options - Configuration options
71
- * @returns {SlashCommandsManager} Slash commands state and controls
72
- */
73
- export function useSlashCommands(options = {}) {
74
- const {
75
- getTextareaRef,
76
- getContent,
77
- setContent,
78
- getSnippets,
79
- onOpenSnippetsModal,
80
- } = options;
81
-
82
- let menu = $state({
83
- open: false,
84
- query: "",
85
- position: { x: 0, y: 0 },
86
- selectedIndex: 0,
87
- });
88
-
89
- // Build full command list including snippets
90
- /** @returns {SlashCommand[]} */
91
- function getAllCommands() {
92
- const snippets = getSnippets ? getSnippets() : [];
93
- /** @type {SlashCommand[]} */
94
- const snippetCommands = snippets.map((s) => ({
95
- id: s.id,
96
- label: `> ${s.name}`,
97
- insert: s.content,
98
- isSnippet: true,
99
- }));
100
-
101
- /** @type {SlashCommand} */
102
- const newSnippetCommand = {
103
- id: "newSnippet",
104
- label: "Create New Snippet...",
105
- insert: "",
106
- isAction: true,
107
- action: onOpenSnippetsModal,
108
- };
109
-
110
- return [...baseSlashCommands, newSnippetCommand, ...snippetCommands];
111
- }
112
-
113
- // Get filtered commands based on query
114
- function getFilteredCommands() {
115
- const allCommands = getAllCommands();
116
- return allCommands.filter((cmd) =>
117
- cmd.label.toLowerCase().includes(menu.query.toLowerCase())
118
- );
119
- }
120
-
121
- function open() {
122
- menu.open = true;
123
- menu.query = "";
124
- menu.selectedIndex = 0;
125
- }
126
-
127
- function close() {
128
- menu.open = false;
129
- }
130
-
131
- /** @param {'up' | 'down'} direction */
132
- function navigate(direction) {
133
- const filtered = getFilteredCommands();
134
- const count = filtered.length;
135
- if (count === 0) return;
136
-
137
- if (direction === "down") {
138
- menu.selectedIndex = (menu.selectedIndex + 1) % count;
139
- } else if (direction === "up") {
140
- menu.selectedIndex = (menu.selectedIndex - 1 + count) % count;
141
- }
142
- }
143
-
144
- /** @param {number} index */
145
- function execute(index) {
146
- const filtered = getFilteredCommands();
147
- const cmd = filtered[index];
148
- if (!cmd) return;
149
-
150
- const textareaRef = getTextareaRef ? getTextareaRef() : null;
151
- const content = getContent ? getContent() : '';
152
-
153
- if (!textareaRef || !setContent) return;
154
-
155
- // Handle action commands (like "Create New Snippet...")
156
- if (cmd.isAction && cmd.action) {
157
- // Remove the slash that triggered the menu
158
- const pos = textareaRef.selectionStart;
159
- const textBefore = content.substring(0, pos);
160
- const lastSlashIndex = textBefore.lastIndexOf("/");
161
- if (lastSlashIndex >= 0) {
162
- setContent(content.substring(0, lastSlashIndex) + content.substring(pos));
163
- }
164
- menu.open = false;
165
- cmd.action();
166
- return;
167
- }
168
-
169
- // Remove the slash that triggered the menu and insert command
170
- const pos = textareaRef.selectionStart;
171
- const textBefore = content.substring(0, pos);
172
- const lastSlashIndex = textBefore.lastIndexOf("/");
173
-
174
- if (lastSlashIndex >= 0) {
175
- setContent(
176
- content.substring(0, lastSlashIndex) + cmd.insert + content.substring(pos)
177
- );
178
-
179
- setTimeout(() => {
180
- const newPos = lastSlashIndex + (cmd.cursorOffset || cmd.insert.length);
181
- textareaRef.selectionStart = textareaRef.selectionEnd = newPos;
182
- textareaRef.focus();
183
- }, 0);
184
- }
185
-
186
- menu.open = false;
187
- }
188
-
189
- /**
190
- * @param {string} key
191
- * @param {number} cursorPos
192
- * @param {string} content
193
- */
194
- function shouldTrigger(key, cursorPos, content) {
195
- if (key !== "/" || menu.open) return false;
196
- // Only trigger at start of line or after whitespace
197
- return cursorPos === 0 || /\s$/.test(content.substring(0, cursorPos));
198
- }
199
-
200
- return {
201
- get menu() {
202
- return menu;
203
- },
204
- get isOpen() {
205
- return menu.open;
206
- },
207
- getAllCommands,
208
- getFilteredCommands,
209
- open,
210
- close,
211
- navigate,
212
- execute,
213
- shouldTrigger,
214
- };
215
- }