@jant/core 0.2.2 → 0.2.4

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 (92) hide show
  1. package/dist/client.d.ts +4 -1
  2. package/dist/client.d.ts.map +1 -1
  3. package/dist/client.js +6 -2
  4. package/dist/lib/assets.d.ts +4 -3
  5. package/dist/lib/assets.d.ts.map +1 -1
  6. package/dist/lib/assets.js +1 -3
  7. package/dist/theme/layouts/BaseLayout.js +0 -5
  8. package/package.json +4 -5
  9. package/src/app.tsx +377 -0
  10. package/src/auth.ts +38 -0
  11. package/src/client.ts +7 -2
  12. package/src/db/index.ts +14 -0
  13. package/src/db/migrations/0000_solid_moon_knight.sql +118 -0
  14. package/src/db/migrations/0001_add_search_fts.sql +40 -0
  15. package/src/db/migrations/0002_collection_path.sql +2 -0
  16. package/src/db/migrations/0003_collection_path_nullable.sql +21 -0
  17. package/src/db/migrations/0004_media_uuid.sql +35 -0
  18. package/src/db/migrations/meta/0000_snapshot.json +784 -0
  19. package/src/db/migrations/meta/_journal.json +41 -0
  20. package/src/db/schema.ts +159 -0
  21. package/src/i18n/EXAMPLES.md +235 -0
  22. package/src/i18n/README.md +296 -0
  23. package/src/i18n/Trans.tsx +31 -0
  24. package/src/i18n/context.tsx +101 -0
  25. package/src/i18n/detect.ts +100 -0
  26. package/src/i18n/i18n.ts +62 -0
  27. package/src/i18n/index.ts +65 -0
  28. package/src/i18n/locales/en.po +875 -0
  29. package/src/i18n/locales/en.ts +1 -0
  30. package/src/i18n/locales/zh-Hans.po +875 -0
  31. package/src/i18n/locales/zh-Hans.ts +1 -0
  32. package/src/i18n/locales/zh-Hant.po +875 -0
  33. package/src/i18n/locales/zh-Hant.ts +1 -0
  34. package/src/i18n/locales.ts +14 -0
  35. package/src/i18n/middleware.ts +59 -0
  36. package/src/index.ts +42 -0
  37. package/src/lib/assets.ts +49 -0
  38. package/src/lib/constants.ts +67 -0
  39. package/src/lib/image.ts +107 -0
  40. package/src/lib/index.ts +9 -0
  41. package/src/lib/markdown.ts +93 -0
  42. package/src/lib/schemas.ts +92 -0
  43. package/src/lib/sqid.ts +79 -0
  44. package/src/lib/sse.ts +152 -0
  45. package/src/lib/time.ts +117 -0
  46. package/src/lib/url.ts +107 -0
  47. package/src/middleware/auth.ts +59 -0
  48. package/src/preset.css +2 -11
  49. package/src/routes/api/posts.ts +127 -0
  50. package/src/routes/api/search.ts +53 -0
  51. package/src/routes/api/upload.ts +240 -0
  52. package/src/routes/dash/collections.tsx +341 -0
  53. package/src/routes/dash/index.tsx +89 -0
  54. package/src/routes/dash/media.tsx +551 -0
  55. package/src/routes/dash/pages.tsx +245 -0
  56. package/src/routes/dash/posts.tsx +202 -0
  57. package/src/routes/dash/redirects.tsx +155 -0
  58. package/src/routes/dash/settings.tsx +93 -0
  59. package/src/routes/feed/rss.ts +119 -0
  60. package/src/routes/feed/sitemap.ts +75 -0
  61. package/src/routes/pages/archive.tsx +223 -0
  62. package/src/routes/pages/collection.tsx +79 -0
  63. package/src/routes/pages/home.tsx +93 -0
  64. package/src/routes/pages/page.tsx +64 -0
  65. package/src/routes/pages/post.tsx +81 -0
  66. package/src/routes/pages/search.tsx +162 -0
  67. package/src/services/collection.ts +180 -0
  68. package/src/services/index.ts +40 -0
  69. package/src/services/media.ts +97 -0
  70. package/src/services/post.ts +279 -0
  71. package/src/services/redirect.ts +74 -0
  72. package/src/services/search.ts +117 -0
  73. package/src/services/settings.ts +76 -0
  74. package/src/theme/components/ActionButtons.tsx +98 -0
  75. package/src/theme/components/CrudPageHeader.tsx +48 -0
  76. package/src/theme/components/DangerZone.tsx +77 -0
  77. package/src/theme/components/EmptyState.tsx +56 -0
  78. package/src/theme/components/ListItemRow.tsx +24 -0
  79. package/src/theme/components/PageForm.tsx +114 -0
  80. package/src/theme/components/Pagination.tsx +196 -0
  81. package/src/theme/components/PostForm.tsx +122 -0
  82. package/src/theme/components/PostList.tsx +68 -0
  83. package/src/theme/components/ThreadView.tsx +118 -0
  84. package/src/theme/components/TypeBadge.tsx +28 -0
  85. package/src/theme/components/VisibilityBadge.tsx +33 -0
  86. package/src/theme/components/index.ts +12 -0
  87. package/src/theme/index.ts +24 -0
  88. package/src/theme/layouts/BaseLayout.tsx +50 -0
  89. package/src/theme/layouts/DashLayout.tsx +108 -0
  90. package/src/theme/layouts/index.ts +2 -0
  91. package/src/types.ts +222 -0
  92. package/static/assets/datastar.min.js +0 -7
@@ -0,0 +1,118 @@
1
+ CREATE TABLE `account` (
2
+ `id` text PRIMARY KEY NOT NULL,
3
+ `account_id` text NOT NULL,
4
+ `provider_id` text NOT NULL,
5
+ `user_id` text NOT NULL,
6
+ `access_token` text,
7
+ `refresh_token` text,
8
+ `id_token` text,
9
+ `access_token_expires_at` integer,
10
+ `refresh_token_expires_at` integer,
11
+ `scope` text,
12
+ `password` text,
13
+ `created_at` integer NOT NULL,
14
+ `updated_at` integer NOT NULL,
15
+ FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE no action
16
+ );
17
+ --> statement-breakpoint
18
+ CREATE TABLE `collections` (
19
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
20
+ `slug` text NOT NULL,
21
+ `title` text NOT NULL,
22
+ `description` text,
23
+ `created_at` integer NOT NULL,
24
+ `updated_at` integer NOT NULL
25
+ );
26
+ --> statement-breakpoint
27
+ CREATE UNIQUE INDEX `collections_slug_unique` ON `collections` (`slug`);--> statement-breakpoint
28
+ CREATE TABLE `media` (
29
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
30
+ `post_id` integer,
31
+ `filename` text NOT NULL,
32
+ `original_name` text NOT NULL,
33
+ `mime_type` text NOT NULL,
34
+ `size` integer NOT NULL,
35
+ `r2_key` text NOT NULL,
36
+ `width` integer,
37
+ `height` integer,
38
+ `alt` text,
39
+ `created_at` integer NOT NULL,
40
+ FOREIGN KEY (`post_id`) REFERENCES `posts`(`id`) ON UPDATE no action ON DELETE no action
41
+ );
42
+ --> statement-breakpoint
43
+ CREATE TABLE `post_collections` (
44
+ `post_id` integer NOT NULL,
45
+ `collection_id` integer NOT NULL,
46
+ `added_at` integer NOT NULL,
47
+ PRIMARY KEY(`post_id`, `collection_id`),
48
+ FOREIGN KEY (`post_id`) REFERENCES `posts`(`id`) ON UPDATE no action ON DELETE no action,
49
+ FOREIGN KEY (`collection_id`) REFERENCES `collections`(`id`) ON UPDATE no action ON DELETE no action
50
+ );
51
+ --> statement-breakpoint
52
+ CREATE TABLE `posts` (
53
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
54
+ `type` text NOT NULL,
55
+ `visibility` text DEFAULT 'quiet' NOT NULL,
56
+ `title` text,
57
+ `path` text,
58
+ `content` text,
59
+ `content_html` text,
60
+ `source_url` text,
61
+ `source_name` text,
62
+ `source_domain` text,
63
+ `reply_to_id` integer,
64
+ `thread_id` integer,
65
+ `deleted_at` integer,
66
+ `published_at` integer NOT NULL,
67
+ `created_at` integer NOT NULL,
68
+ `updated_at` integer NOT NULL
69
+ );
70
+ --> statement-breakpoint
71
+ CREATE TABLE `redirects` (
72
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
73
+ `from_path` text NOT NULL,
74
+ `to_path` text NOT NULL,
75
+ `type` integer DEFAULT 301 NOT NULL,
76
+ `created_at` integer NOT NULL
77
+ );
78
+ --> statement-breakpoint
79
+ CREATE UNIQUE INDEX `redirects_from_path_unique` ON `redirects` (`from_path`);--> statement-breakpoint
80
+ CREATE TABLE `session` (
81
+ `id` text PRIMARY KEY NOT NULL,
82
+ `expires_at` integer NOT NULL,
83
+ `token` text NOT NULL,
84
+ `created_at` integer NOT NULL,
85
+ `updated_at` integer NOT NULL,
86
+ `ip_address` text,
87
+ `user_agent` text,
88
+ `user_id` text NOT NULL,
89
+ FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE no action
90
+ );
91
+ --> statement-breakpoint
92
+ CREATE UNIQUE INDEX `session_token_unique` ON `session` (`token`);--> statement-breakpoint
93
+ CREATE TABLE `settings` (
94
+ `key` text PRIMARY KEY NOT NULL,
95
+ `value` text NOT NULL,
96
+ `updated_at` integer NOT NULL
97
+ );
98
+ --> statement-breakpoint
99
+ CREATE TABLE `user` (
100
+ `id` text PRIMARY KEY NOT NULL,
101
+ `name` text NOT NULL,
102
+ `email` text NOT NULL,
103
+ `email_verified` integer DEFAULT false NOT NULL,
104
+ `image` text,
105
+ `role` text DEFAULT 'admin',
106
+ `created_at` integer NOT NULL,
107
+ `updated_at` integer NOT NULL
108
+ );
109
+ --> statement-breakpoint
110
+ CREATE UNIQUE INDEX `user_email_unique` ON `user` (`email`);--> statement-breakpoint
111
+ CREATE TABLE `verification` (
112
+ `id` text PRIMARY KEY NOT NULL,
113
+ `identifier` text NOT NULL,
114
+ `value` text NOT NULL,
115
+ `expires_at` integer NOT NULL,
116
+ `created_at` integer,
117
+ `updated_at` integer
118
+ );
@@ -0,0 +1,40 @@
1
+ -- FTS5 Full-Text Search for posts
2
+ -- This creates a virtual table that indexes post titles and content
3
+
4
+ CREATE VIRTUAL TABLE IF NOT EXISTS posts_fts USING fts5(
5
+ title,
6
+ content,
7
+ content='posts',
8
+ content_rowid='id'
9
+ );
10
+ --> statement-breakpoint
11
+
12
+ -- Populate FTS table with existing posts
13
+ INSERT INTO posts_fts(rowid, title, content)
14
+ SELECT id, COALESCE(title, ''), COALESCE(content, '') FROM posts WHERE deleted_at IS NULL;
15
+ --> statement-breakpoint
16
+
17
+ -- Trigger to keep FTS in sync on INSERT
18
+ CREATE TRIGGER posts_fts_insert AFTER INSERT ON posts
19
+ WHEN NEW.deleted_at IS NULL
20
+ BEGIN
21
+ INSERT INTO posts_fts(rowid, title, content)
22
+ VALUES (NEW.id, COALESCE(NEW.title, ''), COALESCE(NEW.content, ''));
23
+ END;
24
+ --> statement-breakpoint
25
+
26
+ -- Trigger to keep FTS in sync on UPDATE
27
+ CREATE TRIGGER posts_fts_update AFTER UPDATE ON posts
28
+ BEGIN
29
+ DELETE FROM posts_fts WHERE rowid = OLD.id;
30
+ INSERT INTO posts_fts(rowid, title, content)
31
+ SELECT NEW.id, COALESCE(NEW.title, ''), COALESCE(NEW.content, '')
32
+ WHERE NEW.deleted_at IS NULL;
33
+ END;
34
+ --> statement-breakpoint
35
+
36
+ -- Trigger to remove from FTS on DELETE
37
+ CREATE TRIGGER posts_fts_delete AFTER DELETE ON posts
38
+ BEGIN
39
+ DELETE FROM posts_fts WHERE rowid = OLD.id;
40
+ END;
@@ -0,0 +1,2 @@
1
+ -- Rename slug to path in collections table
2
+ ALTER TABLE collections RENAME COLUMN slug TO path;
@@ -0,0 +1,21 @@
1
+ -- Make collections.path nullable
2
+ -- SQLite doesn't support ALTER COLUMN, so we need to recreate the table
3
+
4
+ PRAGMA foreign_keys=OFF;
5
+
6
+ CREATE TABLE collections_new (
7
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
8
+ path TEXT UNIQUE,
9
+ title TEXT NOT NULL,
10
+ description TEXT,
11
+ created_at INTEGER NOT NULL,
12
+ updated_at INTEGER NOT NULL
13
+ );
14
+
15
+ INSERT INTO collections_new SELECT * FROM collections;
16
+
17
+ DROP TABLE collections;
18
+
19
+ ALTER TABLE collections_new RENAME TO collections;
20
+
21
+ PRAGMA foreign_keys=ON;
@@ -0,0 +1,35 @@
1
+ -- Migration: Change media.id from integer to UUIDv7 (text)
2
+ -- SQLite doesn't support altering primary key types, so we recreate the table
3
+
4
+ -- Create new table with text id
5
+ CREATE TABLE media_new (
6
+ id TEXT PRIMARY KEY NOT NULL,
7
+ post_id INTEGER REFERENCES posts(id),
8
+ filename TEXT NOT NULL,
9
+ original_name TEXT NOT NULL,
10
+ mime_type TEXT NOT NULL,
11
+ size INTEGER NOT NULL,
12
+ r2_key TEXT NOT NULL,
13
+ width INTEGER,
14
+ height INTEGER,
15
+ alt TEXT,
16
+ created_at INTEGER NOT NULL
17
+ );
18
+
19
+ -- Migrate existing data (generate UUIDv7-like ids from old integer ids)
20
+ -- For existing data, we use a deterministic format based on timestamp + old id
21
+ INSERT INTO media_new (id, post_id, filename, original_name, mime_type, size, r2_key, width, height, alt, created_at)
22
+ SELECT
23
+ printf('%08x-%04x-7%03x-%04x-%012x',
24
+ created_at,
25
+ (id >> 16) & 0xFFFF,
26
+ id & 0x0FFF,
27
+ 0x8000 | (RANDOM() & 0x3FFF),
28
+ ABS(RANDOM())
29
+ ) as id,
30
+ post_id, filename, original_name, mime_type, size, r2_key, width, height, alt, created_at
31
+ FROM media;
32
+
33
+ -- Drop old table and rename new one
34
+ DROP TABLE media;
35
+ ALTER TABLE media_new RENAME TO media;