@jant/core 0.7.0 → 0.7.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/bin/commands/export.js +3 -1
- package/bin/commands/import-site.js +689 -216
- package/bin/commands/setup.js +136 -0
- package/bin/commands/site/export.js +71 -34
- package/bin/commands/site/pull-media.js +2 -6
- package/bin/commands/site/snapshot/export.js +18 -60
- package/bin/commands/site/snapshot/import.js +22 -23
- package/bin/lib/d1-query.js +87 -2
- package/bin/lib/hugo-markdown.js +4 -0
- package/bin/lib/site-pull-media.js +21 -28
- package/bin/lib/site-selection.js +10 -1
- package/bin/lib/site-snapshot.js +338 -3
- package/bin/lib/sql-export.js +68 -5
- package/bin/lib/wrangler-cli.js +9 -0
- package/bin/lib/zip-archive.js +187 -0
- package/dist/{app-K_Aa1MMn.js → app-ZcaI1kPN.js} +732 -217
- package/dist/client/.vite/manifest.json +20 -20
- package/dist/client/_assets/chunks/{create-editor-CD3FhrOB.js → create-editor-B-m7X7S5.js} +50 -46
- package/dist/client/_assets/chunks/{sortable-list-CgaL2jCs.js → sortable-list-BJyd-LXE.js} +1 -1
- package/dist/client/_assets/chunks/{unsafe-svg-0QCkP0vZ.js → unsafe-svg-BkscJx69.js} +2 -2
- package/dist/client/_assets/{client-GiYENVw8.css → client-DAhoqPdr.css} +1 -1
- package/dist/client/_assets/{client-auth-k8gJ6QJj.js → client-auth-CAMfTrKW.js} +1 -1
- package/dist/client/_assets/{client-compose-B_kDtWkW.js → client-compose-D6rExKVK.js} +1 -1
- package/dist/client/_assets/{client-VnFxJN7G.js → client-knSEyUJO.js} +1 -1
- package/dist/client/_assets/{client-manage-M90aSTOk.js → client-manage-sVOkqVbH.js} +1 -1
- package/dist/client/_assets/{client-settings-DfYs9n1F.js → client-settings-CGR_nZ78.js} +7 -7
- package/dist/{github-sync-BPAvT999.js → github-sync-Gw4orAHk.js} +799 -110
- package/dist/index.js +2 -2
- package/dist/node.js +9 -5
- package/package.json +13 -3
- package/src/__tests__/dev-scripts.test.ts +203 -0
- package/src/__tests__/export-collection-order.test.ts +276 -0
- package/src/__tests__/export-feed-ids.test.ts +184 -0
- package/src/__tests__/export-feed-order.test.ts +294 -0
- package/src/__tests__/export-hugo-build.test.ts +130 -0
- package/src/__tests__/export-import-roundtrip.test.ts +94 -0
- package/src/__tests__/export-service.test.ts +611 -28
- package/src/__tests__/export-smart-collection.test.ts +329 -0
- package/src/__tests__/helpers/hugo-site.ts +146 -0
- package/src/__tests__/import-site-command.test.ts +487 -1
- package/src/__tests__/mise-config.test.ts +75 -4
- package/src/__tests__/node-dev-tasks.test.ts +264 -0
- package/src/__tests__/site-export-canonical-import.test.ts +149 -0
- package/src/__tests__/snapshot-canonical-replay.test.ts +179 -0
- package/src/__tests__/snapshot-settings.test.ts +97 -0
- package/src/__tests__/snapshot-tables.test.ts +219 -0
- package/src/__tests__/sql-export.test.ts +173 -0
- package/src/__tests__/zip-archive.test.ts +106 -0
- package/src/app.tsx +15 -6
- package/src/client/components/__tests__/jant-settings-avatar.test.ts +1 -1
- package/src/client/components/__tests__/jant-settings-general.test.ts +21 -1
- package/src/client/components/jant-repo-picker-types.ts +6 -1
- package/src/client/components/jant-repo-picker.ts +4 -7
- package/src/client/components/jant-settings-general.ts +17 -12
- package/src/client/tiptap/__tests__/list-editing.test.ts +224 -86
- package/src/client/tiptap/__tests__/mark-exit.test.ts +1 -2
- package/src/client/tiptap/__tests__/markdown-clipboard.test.ts +26 -0
- package/src/client/tiptap/extensions.ts +0 -3
- package/src/client/tiptap/structural-keymap.ts +158 -47
- package/src/db/__tests__/d1-query.test.ts +56 -1
- package/src/i18n/locales/settings/en.po +8 -8
- package/src/i18n/locales/settings/en.ts +1 -1
- package/src/i18n/locales/settings/zh-Hans.po +8 -8
- package/src/i18n/locales/settings/zh-Hans.ts +1 -1
- package/src/i18n/locales/settings/zh-Hant.po +8 -8
- package/src/i18n/locales/settings/zh-Hant.ts +1 -1
- package/src/lib/__tests__/github-sync-repo-name.test.ts +40 -0
- package/src/lib/__tests__/image.test.ts +27 -1
- package/src/lib/__tests__/markdown-to-tiptap.test.ts +105 -0
- package/src/lib/__tests__/markdown.test.ts +10 -0
- package/src/lib/__tests__/resolve-config.test.ts +67 -0
- package/src/lib/__tests__/schemas.test.ts +27 -1
- package/src/lib/__tests__/timeline.test.ts +87 -0
- package/src/lib/__tests__/tiptap-to-markdown.test.ts +172 -4
- package/src/lib/discover.ts +3 -1
- package/src/lib/github-sync-repo-name.ts +45 -0
- package/src/lib/hugo-markdown.ts +46 -0
- package/src/lib/image.ts +17 -4
- package/src/lib/markdown-manager.ts +392 -2
- package/src/lib/post-body-html.ts +11 -4
- package/src/lib/resolve-config.ts +58 -1
- package/src/lib/schemas.ts +50 -5
- package/src/lib/thread-fold.ts +3 -3
- package/src/lib/timeline.ts +1 -1
- package/src/lib/tiptap-to-markdown.ts +13 -7
- package/src/lib/url.ts +20 -0
- package/src/lib/view.ts +2 -2
- package/src/node/__tests__/cli-setup.test.ts +163 -0
- package/src/node/__tests__/cli-site-snapshot.test.ts +67 -0
- package/src/node/__tests__/cli-snapshot-meta.test.ts +20 -0
- package/src/node/__tests__/runtime.test.ts +38 -0
- package/src/node/index.ts +2 -0
- package/src/node/request-handler.ts +3 -1
- package/src/routes/api/__tests__/posts.test.ts +24 -0
- package/src/routes/api/__tests__/upload.test.ts +34 -0
- package/src/routes/api/export.ts +3 -3
- package/src/routes/api/internal/sites.ts +0 -1
- package/src/routes/api/posts.ts +2 -0
- package/src/routes/api/public/posts.ts +21 -1
- package/src/routes/api/upload.ts +10 -3
- package/src/routes/compose.tsx +4 -0
- package/src/routes/dash/__tests__/github-sync-app.test.ts +365 -0
- package/src/routes/dash/settings.tsx +212 -70
- package/src/routes/pages/__tests__/post-page-round-trips.test.ts +211 -0
- package/src/routes/pages/__tests__/thread-order.test.ts +179 -0
- package/src/routes/pages/archive.tsx +17 -11
- package/src/routes/pages/featured.tsx +11 -5
- package/src/routes/pages/page.tsx +53 -31
- package/src/routes/pages/search.tsx +4 -2
- package/src/runtime/__tests__/readiness.test.ts +23 -0
- package/src/runtime/node.ts +49 -0
- package/src/runtime/readiness.ts +15 -0
- package/src/services/__tests__/bootstrap-setup-instance.test.ts +230 -0
- package/src/services/__tests__/custom-url.test.ts +34 -0
- package/src/services/__tests__/github-app-installations.test.ts +153 -0
- package/src/services/__tests__/github-sync-push.test.ts +46 -0
- package/src/services/__tests__/media.test.ts +31 -0
- package/src/services/__tests__/path.test.ts +56 -0
- package/src/services/__tests__/post-timeline.test.ts +127 -0
- package/src/services/__tests__/post.test.ts +74 -0
- package/src/services/bootstrap.ts +263 -44
- package/src/services/custom-url.ts +2 -2
- package/src/services/export-theme/layouts/_default/alias.html +27 -1
- package/src/services/export-theme/layouts/_default/list.html +2 -63
- package/src/services/export-theme/layouts/_default/rss.xml +27 -38
- package/src/services/export-theme/layouts/collections/list.html +3 -3
- package/src/services/export-theme/layouts/featured/list.html +1 -4
- package/src/services/export-theme/layouts/index.html +40 -26
- package/src/services/export-theme/layouts/partials/collection-members.html +100 -0
- package/src/services/export-theme/layouts/partials/collection-threads.html +33 -0
- package/src/services/export-theme/layouts/partials/featured-members.html +35 -0
- package/src/services/export-theme/layouts/partials/featured-thread.html +1 -1
- package/src/services/export-theme/layouts/partials/footer.html +1 -1
- package/src/services/export-theme/layouts/partials/head.html +1 -1
- package/src/services/export-theme/layouts/partials/header.html +5 -3
- package/src/services/export-theme/layouts/partials/jant-data.html +23 -0
- package/src/services/export-theme/layouts/partials/latest-members.html +48 -0
- package/src/services/export-theme/layouts/partials/smart-collection-members.html +129 -0
- package/src/services/export-theme/layouts/partials/thread-preview.html +1 -1
- package/src/services/export-theme/layouts/post/list.html +1 -1
- package/src/services/export-theme/layouts/smart_collection/list.html +24 -0
- package/src/services/export-theme/styles/main.css +0 -1
- package/src/services/export-theme/theme.toml +1 -1
- package/src/services/export.ts +620 -71
- package/src/services/github-app-installations.ts +171 -4
- package/src/services/github-sync.ts +69 -15
- package/src/services/mcp.ts +19 -1
- package/src/services/media.ts +8 -1
- package/src/services/path.ts +34 -1
- package/src/services/post.ts +214 -39
- package/src/services/site-admin.ts +3 -7
- package/src/services/site.ts +83 -31
- package/src/styles/ui.css +7 -1
- package/src/types/app-context.ts +16 -0
- package/src/types/bindings.ts +5 -0
- package/src/types/operations.ts +10 -0
- package/src/ui/dash/settings/GeneralContent.tsx +10 -8
- package/src/client/tiptap/exitable-marks.ts +0 -73
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
{{- /*
|
|
2
|
+
The Thread roots a smart collection's conditions select, in its order.
|
|
3
|
+
|
|
4
|
+
The same set and order Jant shows a signed-out reader on the smart
|
|
5
|
+
collection's page (`smartCollections.toPostFilters` handed to
|
|
6
|
+
`posts.list`), computed from the exported front matter so the page keeps
|
|
7
|
+
up with the posts in this repository. Every condition reads the root:
|
|
8
|
+
|
|
9
|
+
format `format`
|
|
10
|
+
title `title`; for a quote, `source_name`, which is what Jant
|
|
11
|
+
stores in the title column
|
|
12
|
+
year `date`, the publication time, in UTC
|
|
13
|
+
media the root's own `media` entries: `any`, `none`, or a list of
|
|
14
|
+
kinds, any one of which matches
|
|
15
|
+
replies whether the root has published replies
|
|
16
|
+
visibility `public` and `latest_hidden` match `visibility`; `featured`
|
|
17
|
+
matches a root with `featured_at`
|
|
18
|
+
collection a `collections` entry with that slug
|
|
19
|
+
|
|
20
|
+
Drafts and private roots are exported as Hugo drafts and never reach here;
|
|
21
|
+
they are checked again so a `--buildDrafts` preview agrees with Jant.
|
|
22
|
+
|
|
23
|
+
Takes a dict: `page`, the smart collection's section page, and `feed`,
|
|
24
|
+
true for its Atom feed.
|
|
25
|
+
|
|
26
|
+
Orders, each ending on the post ID so no two roots tie:
|
|
27
|
+
newest Thread activity (`last_activity_at`, else `date`), newest first
|
|
28
|
+
oldest publication, oldest first
|
|
29
|
+
rating_desc rated before unrated, higher rating first, then as newest.
|
|
30
|
+
On the page, fewer than two rated roots fall back to
|
|
31
|
+
newest, as Jant's page does; the feed keeps the stored
|
|
32
|
+
order, as Jant's feed does.
|
|
33
|
+
|
|
34
|
+
`src/__tests__/export-smart-collection.test.ts` builds a site with Hugo
|
|
35
|
+
and compares every condition and order against Jant's own list.
|
|
36
|
+
*/ -}}
|
|
37
|
+
{{- $page := .page -}}
|
|
38
|
+
{{- $feed := .feed -}}
|
|
39
|
+
{{- $selection := $page.Params.selection | default dict -}}
|
|
40
|
+
{{- $roots := where (where site.Pages "Type" "post") "Kind" "section" -}}
|
|
41
|
+
{{- $members := slice -}}
|
|
42
|
+
{{- range $roots -}}
|
|
43
|
+
{{- $post := . -}}
|
|
44
|
+
{{- $params := .Params -}}
|
|
45
|
+
{{- $matches := and (eq ($params.status | default "published") "published") (ne $params.visibility "private") -}}
|
|
46
|
+
{{- if and $matches (isset $selection "format") -}}
|
|
47
|
+
{{- $matches = eq $params.format $selection.format -}}
|
|
48
|
+
{{- end -}}
|
|
49
|
+
{{- if and $matches (isset $selection "title") -}}
|
|
50
|
+
{{- $title := $params.title -}}
|
|
51
|
+
{{- if eq $params.format "quote" -}}{{- $title = $params.source_name -}}{{- end -}}
|
|
52
|
+
{{- $matches = eq (gt (len (string ($title | default ""))) 0) $selection.title -}}
|
|
53
|
+
{{- end -}}
|
|
54
|
+
{{- if and $matches (isset $selection "year") -}}
|
|
55
|
+
{{- $matches = eq $post.Date.UTC.Year (int $selection.year) -}}
|
|
56
|
+
{{- end -}}
|
|
57
|
+
{{- if and $matches (isset $selection "media") -}}
|
|
58
|
+
{{- $media := $params.media | default slice -}}
|
|
59
|
+
{{- $wanted := $selection.media -}}
|
|
60
|
+
{{- if reflect.IsSlice $wanted -}}
|
|
61
|
+
{{- $found := false -}}
|
|
62
|
+
{{- range $media -}}{{- if in $wanted .kind -}}{{- $found = true -}}{{- end -}}{{- end -}}
|
|
63
|
+
{{- $matches = $found -}}
|
|
64
|
+
{{- else if eq $wanted "any" -}}
|
|
65
|
+
{{- $matches = gt (len $media) 0 -}}
|
|
66
|
+
{{- else -}}
|
|
67
|
+
{{- $matches = eq (len $media) 0 -}}
|
|
68
|
+
{{- end -}}
|
|
69
|
+
{{- end -}}
|
|
70
|
+
{{- if and $matches (isset $selection "replies") -}}
|
|
71
|
+
{{- $matches = eq (gt (len $post.Pages) 0) $selection.replies -}}
|
|
72
|
+
{{- end -}}
|
|
73
|
+
{{- if and $matches (isset $selection "visibility") -}}
|
|
74
|
+
{{- if eq $selection.visibility "featured" -}}
|
|
75
|
+
{{- $matches = ne ($params.featured_at | default "") "" -}}
|
|
76
|
+
{{- else -}}
|
|
77
|
+
{{- $matches = eq $params.visibility $selection.visibility -}}
|
|
78
|
+
{{- end -}}
|
|
79
|
+
{{- end -}}
|
|
80
|
+
{{- if and $matches (isset $selection "collection") -}}
|
|
81
|
+
{{- $inCollection := false -}}
|
|
82
|
+
{{- range $params.collections -}}
|
|
83
|
+
{{- if eq .slug $selection.collection -}}{{- $inCollection = true -}}{{- end -}}
|
|
84
|
+
{{- end -}}
|
|
85
|
+
{{- $matches = $inCollection -}}
|
|
86
|
+
{{- end -}}
|
|
87
|
+
|
|
88
|
+
{{- if $matches -}}
|
|
89
|
+
{{- $activity := $post.Date.Unix -}}
|
|
90
|
+
{{- with $params.last_activity_at -}}{{- $activity = (time.AsTime .).Unix -}}{{- end -}}
|
|
91
|
+
{{- $rated := ne $params.rating nil -}}
|
|
92
|
+
{{- $rating := 0 -}}
|
|
93
|
+
{{- if $rated -}}{{- $rating = int $params.rating -}}{{- end -}}
|
|
94
|
+
{{- $members = $members | append (dict
|
|
95
|
+
"post" $post
|
|
96
|
+
"id" $params.id
|
|
97
|
+
"published" $post.Date.Unix
|
|
98
|
+
"activity" $activity
|
|
99
|
+
"rated" $rated
|
|
100
|
+
"rating" $rating
|
|
101
|
+
) -}}
|
|
102
|
+
{{- end -}}
|
|
103
|
+
{{- end -}}
|
|
104
|
+
|
|
105
|
+
{{- $order := $page.Params.sort_order | default "newest" -}}
|
|
106
|
+
{{- if and (not $feed) (eq $order "rating_desc") (le (len (where $members "rated" true)) 1) -}}
|
|
107
|
+
{{- $order = "newest" -}}
|
|
108
|
+
{{- end -}}
|
|
109
|
+
|
|
110
|
+
{{- /* One string key per root, fixed-width numbers first, so a single sort
|
|
111
|
+
orders by every key in turn. */ -}}
|
|
112
|
+
{{- $keyed := slice -}}
|
|
113
|
+
{{- range $members -}}
|
|
114
|
+
{{- $key := printf "%020d %s" .activity .id -}}
|
|
115
|
+
{{- if eq $order "oldest" -}}
|
|
116
|
+
{{- $key = printf "%020d %s" .published .id -}}
|
|
117
|
+
{{- else if eq $order "rating_desc" -}}
|
|
118
|
+
{{- $key = printf "%d %02d %020d %s" (cond .rated 1 0) .rating .activity .id -}}
|
|
119
|
+
{{- end -}}
|
|
120
|
+
{{- $keyed = $keyed | append (dict "key" $key "post" .post) -}}
|
|
121
|
+
{{- end -}}
|
|
122
|
+
|
|
123
|
+
{{- $ordered := slice -}}
|
|
124
|
+
{{- if $keyed -}}
|
|
125
|
+
{{- range sort $keyed "key" (cond (eq $order "oldest") "asc" "desc") -}}
|
|
126
|
+
{{- $ordered = $ordered | append .post -}}
|
|
127
|
+
{{- end -}}
|
|
128
|
+
{{- end -}}
|
|
129
|
+
{{- return $ordered -}}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/ -}}
|
|
21
21
|
{{- $root := . -}}
|
|
22
22
|
{{- $replies := where $root.Pages "Params.visibility" "public" -}}
|
|
23
|
-
{{- $replies = $replies.
|
|
23
|
+
{{- $replies = $replies.ByWeight -}}
|
|
24
24
|
{{- $replyCount := len $replies -}}
|
|
25
25
|
{{- if eq $replyCount 0 -}}
|
|
26
26
|
{{ partial "post-card.html" $root }}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
{{- $media := $root.Params.media | default slice -}}
|
|
6
6
|
{{- $collections := $root.Params.collections | default slice -}}
|
|
7
7
|
{{- $linkUrl := $root.Params.link_url -}}
|
|
8
|
-
{{- $replies := $root.Pages.
|
|
8
|
+
{{- $replies := $root.Pages.ByWeight -}}
|
|
9
9
|
{{- $hasReplies := gt (len $replies) 0 -}}
|
|
10
10
|
<article class="thread thread-{{ $format }}{{ if $hasReplies }} thread-has-replies{{ end }}" id="{{ $slug }}" data-format="{{ $format }}" data-slug="{{ $slug }}"
|
|
11
11
|
{{- if $root.Params.pinned_at }} data-post-pinned{{ end -}}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{{ define "main" }}
|
|
2
|
+
{{- /*
|
|
3
|
+
A smart collection's page (`type: smart_collection`). The members come
|
|
4
|
+
from its conditions, applied to the posts in this site by the
|
|
5
|
+
`smart-collection-members` partial.
|
|
6
|
+
*/ -}}
|
|
7
|
+
{{- $posts := partial "smart-collection-members.html" (dict "page" . "feed" false) -}}
|
|
8
|
+
{{- $pageSize := .Site.Params.page_size | default 10 -}}
|
|
9
|
+
{{- $paginator := .Paginate $posts $pageSize -}}
|
|
10
|
+
|
|
11
|
+
<section class="section section-collection section-smart-collection">
|
|
12
|
+
<header class="section-header">
|
|
13
|
+
<h1 class="section-title">{{ .Title }}</h1>
|
|
14
|
+
{{- with .Params.summary_text -}}
|
|
15
|
+
<p class="section-summary">{{ . }}</p>
|
|
16
|
+
{{- end -}}
|
|
17
|
+
{{- with len $posts -}}
|
|
18
|
+
<p class="section-meta">{{ . }} {{ if eq . 1 }}thread{{ else }}threads{{ end }}</p>
|
|
19
|
+
{{- end -}}
|
|
20
|
+
{{ .Content }}
|
|
21
|
+
</header>
|
|
22
|
+
{{ partial "collection-threads.html" (dict "paginator" $paginator "empty" "Nothing matches these conditions yet.") }}
|
|
23
|
+
</section>
|
|
24
|
+
{{ end }}
|