@coywolf/emdash 0.0.0-stage → 0.35.13
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/LICENSE +21 -0
- package/README.md +201 -2
- package/package.json +70 -5
- package/src/admin/admin-css.ts +57 -0
- package/src/admin/ai.tsx +915 -0
- package/src/admin/backups.tsx +613 -0
- package/src/admin/breadcrumbs.tsx +542 -0
- package/src/admin/codeBlocks.tsx +204 -0
- package/src/admin/customBlocks.tsx +321 -0
- package/src/admin/dirty.ts +20 -0
- package/src/admin/discovery.tsx +463 -0
- package/src/admin/download.ts +28 -0
- package/src/admin/feature-switches.tsx +124 -0
- package/src/admin/features.tsx +142 -0
- package/src/admin/files.tsx +791 -0
- package/src/admin/formUploads.tsx +445 -0
- package/src/admin/guides.tsx +18 -0
- package/src/admin/headings.tsx +262 -0
- package/src/admin/images.tsx +825 -0
- package/src/admin/index.tsx +62 -0
- package/src/admin/links.tsx +980 -0
- package/src/admin/performance.tsx +330 -0
- package/src/admin/preview.tsx +63 -0
- package/src/admin/redirects-removed.tsx +266 -0
- package/src/admin/redirects.tsx +470 -0
- package/src/admin/reviews.tsx +232 -0
- package/src/admin/robots-bots.tsx +647 -0
- package/src/admin/robots-shared.tsx +109 -0
- package/src/admin/robots-wizard.tsx +748 -0
- package/src/admin/robots.tsx +911 -0
- package/src/admin/save-bar.tsx +134 -0
- package/src/admin/schema.tsx +1187 -0
- package/src/admin/search.tsx +355 -0
- package/src/admin/settings-ui.tsx +87 -0
- package/src/admin/trash-prompt-core.ts +135 -0
- package/src/admin/trash-prompt.tsx +156 -0
- package/src/admin/usage.tsx +301 -0
- package/src/admin/videos-display.tsx +248 -0
- package/src/admin/videos.tsx +1202 -0
- package/src/admin/wpImport.tsx +1516 -0
- package/src/ai/entities.ts +59 -0
- package/src/ai/export.ts +61 -0
- package/src/ai/logic.test.ts +187 -0
- package/src/ai/logic.ts +606 -0
- package/src/ai/pack.ts +121 -0
- package/src/ai/prompts.ts +87 -0
- package/src/ai/providers.ts +276 -0
- package/src/ai/queue.test.ts +97 -0
- package/src/ai/routes.ts +359 -0
- package/src/ai/store.ts +301 -0
- package/src/ai/wikidata.test.ts +184 -0
- package/src/ai/wikidata.ts +87 -0
- package/src/ai/worker.ts +530 -0
- package/src/astro/astro-modules.d.ts +6 -0
- package/src/astro/breadcrumbs/Breadcrumbs.astro +129 -0
- package/src/astro/breadcrumbs/BreadcrumbsBlock.astro +12 -0
- package/src/astro/codeBlocks/CodeBlock.astro +62 -0
- package/src/astro/codeBlocks/EmDashCode.astro +61 -0
- package/src/astro/customBlocks/CustomBlock.astro +64 -0
- package/src/astro/customBlocks/Details.astro +8 -0
- package/src/astro/customBlocks/Disclosure.astro +8 -0
- package/src/astro/customBlocks/Note.astro +8 -0
- package/src/astro/customBlocks/Podcast.astro +8 -0
- package/src/astro/customBlocks/Quote.astro +8 -0
- package/src/astro/customBlocks/Testimonial.astro +8 -0
- package/src/astro/files/FileCard.astro +103 -0
- package/src/astro/headings/HeadingBlock.astro +129 -0
- package/src/astro/headings/TableOfContents.astro +45 -0
- package/src/astro/headings/request.ts +19 -0
- package/src/astro/images/ResponsiveImage.astro +60 -0
- package/src/astro/index.ts +84 -0
- package/src/astro/reviews/CoywolfReview.astro +27 -0
- package/src/astro/reviews/Review.astro +49 -0
- package/src/astro/search/SearchBox.astro +61 -0
- package/src/astro/search/SearchBoxForm.astro +509 -0
- package/src/astro/tables/CaptionedTable.astro +72 -0
- package/src/astro/videos/CoywolfVideo.astro +448 -0
- package/src/backups/download.ts +112 -0
- package/src/backups/dump.test.mjs +287 -0
- package/src/backups/dump.ts +288 -0
- package/src/backups/module.ts +276 -0
- package/src/backups/pack.ts +33 -0
- package/src/backups/restore.test.mjs +103 -0
- package/src/backups/restore.ts +209 -0
- package/src/backups/store.ts +409 -0
- package/src/breadcrumbs/pack.ts +113 -0
- package/src/breadcrumbs/settings.ts +102 -0
- package/src/breadcrumbs/stamp.ts +40 -0
- package/src/breadcrumbs/trail.ts +123 -0
- package/src/codeBlocks/contrast.ts +179 -0
- package/src/codeBlocks/hljs.d.ts +5 -0
- package/src/codeBlocks/pack.ts +110 -0
- package/src/codeBlocks/render.test.ts +152 -0
- package/src/codeBlocks/render.ts +304 -0
- package/src/codeBlocks/settings.ts +18 -0
- package/src/codeBlocks/themes.generated.ts +304 -0
- package/src/codeBlocks/themes.ts +114 -0
- package/src/core/compose.ts +244 -0
- package/src/core/content-url.ts +888 -0
- package/src/core/csv.ts +119 -0
- package/src/core/d1-batch.ts +65 -0
- package/src/core/entry-docs.ts +175 -0
- package/src/core/features-module.ts +48 -0
- package/src/core/features.ts +392 -0
- package/src/core/generation.ts +88 -0
- package/src/core/guide-content.ts +166 -0
- package/src/core/module.ts +104 -0
- package/src/core/read-failures.ts +57 -0
- package/src/core/request-memo.ts +71 -0
- package/src/core/secrets.ts +83 -0
- package/src/core/settings-enhance.ts +74 -0
- package/src/core/site.ts +36 -0
- package/src/core/storage.ts +27 -0
- package/src/customBlocks/pack.ts +260 -0
- package/src/customBlocks/render.ts +424 -0
- package/src/customBlocks/rich.ts +313 -0
- package/src/customBlocks/settings.ts +46 -0
- package/src/discovery/build.ts +252 -0
- package/src/discovery/feed-build.ts +217 -0
- package/src/discovery/feed.ts +172 -0
- package/src/discovery/indexnow.ts +114 -0
- package/src/discovery/llms.ts +79 -0
- package/src/discovery/markdown.ts +294 -0
- package/src/discovery/memory-cache.ts +97 -0
- package/src/discovery/middleware.ts +186 -0
- package/src/discovery/module.ts +353 -0
- package/src/discovery/news.ts +99 -0
- package/src/discovery/pack.ts +58 -0
- package/src/discovery/settings.ts +91 -0
- package/src/discovery/urls.ts +35 -0
- package/src/env.d.ts +10 -0
- package/src/files/card.ts +231 -0
- package/src/files/counts.test.ts +114 -0
- package/src/files/counts.ts +60 -0
- package/src/files/export.ts +44 -0
- package/src/files/format.test.ts +93 -0
- package/src/files/format.ts +163 -0
- package/src/files/module.ts +596 -0
- package/src/files/pack.ts +92 -0
- package/src/files/r2-rules.test.ts +30 -0
- package/src/files/r2-rules.ts +41 -0
- package/src/files/range.ts +50 -0
- package/src/files/s3.ts +114 -0
- package/src/files/serve.ts +141 -0
- package/src/files/sigv4.test.ts +64 -0
- package/src/files/sigv4.ts +160 -0
- package/src/files/site.ts +137 -0
- package/src/files/walker.ts +58 -0
- package/src/formUploads/lib.ts +266 -0
- package/src/formUploads/pack.ts +55 -0
- package/src/formUploads/wrap.ts +592 -0
- package/src/forms.ts +16 -0
- package/src/headings/headings.test.ts +159 -0
- package/src/headings/pack.ts +154 -0
- package/src/headings/render.ts +139 -0
- package/src/headings/settings.ts +117 -0
- package/src/headings/slug.ts +68 -0
- package/src/headings/stamp.ts +142 -0
- package/src/headings/test-hooks.mjs +14 -0
- package/src/headings/toc.ts +48 -0
- package/src/images/cloudflare.ts +329 -0
- package/src/images/lib.ts +221 -0
- package/src/images/module.ts +372 -0
- package/src/images/pack.ts +804 -0
- package/src/images/pending.ts +37 -0
- package/src/images/settings.ts +48 -0
- package/src/images/setup.ts +192 -0
- package/src/images/variants-estimate.ts +162 -0
- package/src/images/variants-store.ts +475 -0
- package/src/images/variants.ts +311 -0
- package/src/index.ts +143 -0
- package/src/links/check.ts +101 -0
- package/src/links/classify.ts +270 -0
- package/src/links/export.ts +59 -0
- package/src/links/module.ts +652 -0
- package/src/links/pack.ts +43 -0
- package/src/links/pt.ts +325 -0
- package/src/links/store.ts +704 -0
- package/src/middleware.ts +287 -0
- package/src/modules.ts +53 -0
- package/src/options.ts +66 -0
- package/src/pageCache/lib.test.mjs +224 -0
- package/src/pageCache/lib.ts +274 -0
- package/src/pageCache/pack.ts +240 -0
- package/src/pageCache/usage-core.ts +152 -0
- package/src/pageCache/usage.ts +262 -0
- package/src/pageCache/warm.test.mjs +670 -0
- package/src/pageCache/warm.ts +722 -0
- package/src/redirects/middleware.ts +169 -0
- package/src/redirects/module.ts +124 -0
- package/src/redirects/pack.ts +89 -0
- package/src/redirects/removed-core.ts +151 -0
- package/src/redirects/removed.ts +293 -0
- package/src/redirects/rules.ts +355 -0
- package/src/redirects/slug-changes.ts +207 -0
- package/src/redirects/slug-core.test.ts +50 -0
- package/src/redirects/slug-core.ts +49 -0
- package/src/redirects/transfer.ts +92 -0
- package/src/reviews/lib.ts +624 -0
- package/src/reviews/pack.ts +135 -0
- package/src/reviews/schema.ts +128 -0
- package/src/reviews/settings.ts +26 -0
- package/src/robots/bots.ts +321 -0
- package/src/robots/data/bots.json +696 -0
- package/src/robots/data/verified.json +582 -0
- package/src/robots/directory.ts +26 -0
- package/src/robots/explain.ts +191 -0
- package/src/robots/guided.ts +300 -0
- package/src/robots/importer.ts +263 -0
- package/src/robots/middleware.ts +151 -0
- package/src/robots/module.ts +446 -0
- package/src/robots/pack.ts +69 -0
- package/src/robots/radar.ts +129 -0
- package/src/robots/rep.test.ts +335 -0
- package/src/robots/rep.ts +362 -0
- package/src/robots/rules.test.ts +251 -0
- package/src/robots/rules.ts +883 -0
- package/src/robots/transfer.ts +45 -0
- package/src/robots/validate.ts +524 -0
- package/src/schema/catalog.ts +146 -0
- package/src/schema/graph.test.mjs +522 -0
- package/src/schema/graph.ts +791 -0
- package/src/schema/module.ts +1138 -0
- package/src/schema/og-image.ts +100 -0
- package/src/schema/pack.ts +58 -0
- package/src/search/engine.ts +578 -0
- package/src/search/fallback.ts +80 -0
- package/src/search/live-cache.ts +116 -0
- package/src/search/live-client.ts +770 -0
- package/src/search/live-serve.ts +282 -0
- package/src/search/module.ts +261 -0
- package/src/search/pack.ts +57 -0
- package/src/search/query.ts +132 -0
- package/src/search/ratelimit-core.ts +118 -0
- package/src/search/ratelimit.ts +79 -0
- package/src/search/snippet.ts +135 -0
- package/src/search/title-index.ts +139 -0
- package/src/search/title-match.ts +192 -0
- package/src/shared.ts +71 -0
- package/src/version.ts +2 -0
- package/src/videos/date.ts +40 -0
- package/src/videos/engagement.ts +75 -0
- package/src/videos/lib.ts +679 -0
- package/src/videos/module.ts +1160 -0
- package/src/videos/pack.ts +187 -0
- package/src/videos/pause.ts +42 -0
- package/src/videos/poster.ts +324 -0
- package/src/videos/render.ts +336 -0
- package/src/videos/store.ts +551 -0
- package/src/videos/stream.ts +134 -0
- package/src/wpImport/convert.ts +702 -0
- package/src/wpImport/guests.ts +329 -0
- package/src/wpImport/gutenberg.ts +157 -0
- package/src/wpImport/markers.ts +66 -0
- package/src/wpImport/pack.ts +451 -0
- package/src/wpImport/parents.ts +202 -0
- package/src/wpImport/prepare.ts +592 -0
- package/src/wpImport/redirects.ts +358 -0
- package/src/wpImport/sources.ts +67 -0
- package/src/wpImport/stream.ts +160 -0
- package/src/wpImport/urls.ts +354 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Coywolf LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,202 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Coywolf Pack for EmDash
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Coywolf Pack is an [EmDash](https://emdashcms.com) plugin that enhances existing features and adds features not available in EmDash. It helps you manage your site like a pro and ensure it's absurdly fast for humans and bots.
|
|
4
|
+
|
|
5
|
+
- **Absurdly fast for humans and bots:** cached pages answer in 60–90 ms, cache warming keeps pages cached for visitors and crawlers alike, and images come straight from Cloudflare's edge.
|
|
6
|
+
- **Enhances what EmDash already does:** redirects, search, robots.txt, schema, images and RSS feeds go well beyond EmDash's built-in versions and starter templates.
|
|
7
|
+
- **Adds what EmDash doesn't have:** backups and restore, link checking, videos, reviews, AI enrichment and more.
|
|
8
|
+
- **Manage your site like a pro:** turn each feature on or off, see your Cloudflare usage and estimated bill, and finish a move from WordPress. Everything starts off, so installing or updating changes nothing until you're ready.
|
|
9
|
+
- **Free and open source** (MIT).
|
|
10
|
+
|
|
11
|
+
**New here?** Follow [Getting started](#getting-started) to install it and turn features on.
|
|
12
|
+
|
|
13
|
+
## Modules
|
|
14
|
+
|
|
15
|
+
Every module starts off. Turn on only the ones you want under **Plugins → Coywolf Pack → Features**.
|
|
16
|
+
|
|
17
|
+
| Module | What it does |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| [Performance](docs/performance.md) | Always on: keeps Cloudflare's edge page cache correct (cleared after deploys and edits), optional cache warming, and a Cloudflare usage card with the estimated bill |
|
|
20
|
+
| [Clean Image URLs](docs/images.md) | Images from a `media.` subdomain on R2, resized to the sizes the theme uses, cached for a year |
|
|
21
|
+
| [Backups](docs/backups.md) | Backups of the D1 database and R2 media, rewind with undo, restore to a new database |
|
|
22
|
+
| [Redirects](docs/redirects.md) | External, file-path and regex redirects, bulk import and export, and automatic redirects for slug changes and removed content |
|
|
23
|
+
| [Schema & Social](docs/schema.md) | One Schema.org graph per page (publisher, articles, authors), breadcrumbs, robots directives, Open Graph |
|
|
24
|
+
| [Discovery](docs/discovery.md) | IndexNow, an RSS feed, a Google News sitemap, and llms.txt with Markdown versions of entries |
|
|
25
|
+
| [Robots.txt Rules](docs/robots.md) | Plain-English robots.txt rules with a guided editor, a verified crawler directory, history and a URL tester |
|
|
26
|
+
| [Search](docs/search.md) | Fast as-you-type results on EmDash's full-text search, a search box, and rate limiting |
|
|
27
|
+
| [Link Manager](docs/links.md) | Every link in your content with its status, and bulk replace, unlink and ignore |
|
|
28
|
+
| [Headings & TOC](docs/headings.md) | Linkable headings and a Table of Contents block |
|
|
29
|
+
| [Breadcrumb Nav](docs/breadcrumbs.md) | An accessible breadcrumb trail for themes and as a block |
|
|
30
|
+
| [Code Blocks](docs/code-blocks.md) | Server-side syntax highlighting, themes, language labels, copy buttons |
|
|
31
|
+
| [File Downloads](docs/files.md) | Download cards, stable download URLs with counts, uploads of any size |
|
|
32
|
+
| [Private form uploads](docs/form-uploads.md) | Files sent through EmDash Forms go to a private bucket that only admins can read |
|
|
33
|
+
| [Videos](docs/videos.md) | Cloudflare Stream library, a video block with a light embed, video schema and sitemap, plays and likes |
|
|
34
|
+
| [Reviews](docs/reviews.md) | A review block (rating, pros and cons) with Review schema |
|
|
35
|
+
| [Custom Blocks](docs/custom-blocks.md) | Note, Details, Affiliate disclosure, Quote, Testimonial and Podcast links blocks |
|
|
36
|
+
| [AI Enrichment](docs/ai.md) | Wikidata-grounded entities for schema, meta descriptions and image alt text |
|
|
37
|
+
| [WordPress import](docs/wordpress-import.md) | Finishes a move from WordPress: blocks, authors, category parents, media URLs and redirects |
|
|
38
|
+
|
|
39
|
+
## Getting started
|
|
40
|
+
|
|
41
|
+
Coywolf Pack is a native (trusted) EmDash plugin: you add it to your site's code and deploy, rather than installing it from EmDash's plugin directory (which lists only sandboxed plugins, and those can't read the database or buckets directly). The steps below use coywolf.com as the example: change the names to your site's.
|
|
42
|
+
|
|
43
|
+
### What you need
|
|
44
|
+
|
|
45
|
+
- An EmDash site (1.2 or later) on Cloudflare Workers, using EmDash's Cloudflare adapter with a D1 database bound as `DB` and an R2 media bucket bound as `MEDIA`. That's the setup EmDash's own Cloudflare starter creates.
|
|
46
|
+
- The site's code in a folder (or Git repository) you can edit and deploy, with Node.js and Wrangler.
|
|
47
|
+
|
|
48
|
+
### 1. Install the package
|
|
49
|
+
|
|
50
|
+
From the site's folder, install the latest release. Releases are listed under [Tags](https://github.com/coywolf-llc/coywolf-pack/tags); replace `v0.35.13` with the newest one:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install https://codeload.github.com/coywolf-llc/coywolf-pack/tar.gz/refs/tags/v0.35.13
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The package is named `@coywolf/emdash`. Use the tarball URL rather than `github:coywolf-llc/coywolf-pack`: npm records `github:` installs as SSH Git URLs, which CI runners without an SSH key can't fetch.
|
|
57
|
+
|
|
58
|
+
### 2. Add the plugin to `astro.config.mjs`
|
|
59
|
+
|
|
60
|
+
Import `coywolfPlugin` and add it to EmDash's `plugins`:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
// astro.config.mjs
|
|
64
|
+
import { coywolfPlugin } from "@coywolf/emdash";
|
|
65
|
+
|
|
66
|
+
export default defineConfig({
|
|
67
|
+
// ...
|
|
68
|
+
integrations: [
|
|
69
|
+
emdash({
|
|
70
|
+
// ...your existing database and storage settings
|
|
71
|
+
plugins: [
|
|
72
|
+
coywolfPlugin({
|
|
73
|
+
// Backups is the one module that's added only when you give it a name (it names the backup files).
|
|
74
|
+
backups: { name: "coywolf" },
|
|
75
|
+
}),
|
|
76
|
+
],
|
|
77
|
+
}),
|
|
78
|
+
],
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`coywolfPlugin()` with no options works too: every module except Backups is included with its defaults. Each module's page in [docs](docs/README.md) lists its options; set a module to `false` (for example `videos: false`) to leave it out of the site entirely.
|
|
83
|
+
|
|
84
|
+
### 3. Add the middleware
|
|
85
|
+
|
|
86
|
+
Several features answer their own URLs before EmDash renders a page: redirects, `/robots.txt` rules, the RSS feed, llms.txt and Markdown versions, file downloads, sitemaps for videos and news, image sizes, and cache warming. They need the pack's middleware, first in `src/middleware.ts`:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
// src/middleware.ts
|
|
90
|
+
import { sequence } from "astro:middleware";
|
|
91
|
+
import { coywolfPack } from "@coywolf/emdash/middleware";
|
|
92
|
+
|
|
93
|
+
export const onRequest = sequence(coywolfPack() /* , your own middleware */);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
If the site has no `src/middleware.ts` yet, create it with just these lines.
|
|
97
|
+
|
|
98
|
+
### 4. Check `wrangler.jsonc`
|
|
99
|
+
|
|
100
|
+
`DB` and `MEDIA` are all the pack needs to start. Other bindings turn on more features; add them when you turn those features on (each module's page in [docs](docs/README.md) has the details):
|
|
101
|
+
|
|
102
|
+
```jsonc
|
|
103
|
+
// wrangler.jsonc (coywolf.com)
|
|
104
|
+
{
|
|
105
|
+
"name": "coywolf",
|
|
106
|
+
"d1_databases": [{ "binding": "DB", "database_name": "coywolf", "database_id": "<D1 database id>" }],
|
|
107
|
+
"r2_buckets": [
|
|
108
|
+
{ "binding": "MEDIA", "bucket_name": "coywolf-media" },
|
|
109
|
+
// Backups: a second bucket for backup files.
|
|
110
|
+
{ "binding": "BACKUPS", "bucket_name": "coywolf-backups" }
|
|
111
|
+
],
|
|
112
|
+
// Page cache: Workers Cache in front of the Worker, and the deployed version so old pages are cleared after a deploy.
|
|
113
|
+
"cache": { "enabled": true },
|
|
114
|
+
"version_metadata": { "binding": "CF_VERSION_METADATA" },
|
|
115
|
+
// Cache warming and checking internal links: the Worker calling itself.
|
|
116
|
+
"services": [{ "binding": "SELF", "service": "coywolf" }]
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
API keys and tokens (for AI Enrichment, Videos, Robots.txt's Cloudflare Radar sync, Clean Image URLs setup, Cloudflare usage) are stored encrypted, so the site also needs EmDash's `EMDASH_ENCRYPTION_KEY` secret. EmDash's setup usually creates it; if not:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npx wrangler secret put EMDASH_ENCRYPTION_KEY
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Keep that key in a password manager: encrypted settings can't be read without it.
|
|
127
|
+
|
|
128
|
+
### 5. Deploy
|
|
129
|
+
|
|
130
|
+
Deploy the site the way you usually do (for example `npx wrangler deploy`, or your CI). Nothing changes for visitors yet: every feature starts off.
|
|
131
|
+
|
|
132
|
+
### 6. Turn features on
|
|
133
|
+
|
|
134
|
+
1. Sign in to the site's admin (`https://coywolf.com/_emdash/admin`).
|
|
135
|
+
2. Open **Plugins → Coywolf Pack → Features**.
|
|
136
|
+
3. Turn on the modules you want, and any of their parts. Each module that's on adds its page to the **Coywolf Pack** section of the sidebar.
|
|
137
|
+
4. Open each module's page for its settings and step-by-step guides. A part can also be turned on or off there.
|
|
138
|
+
|
|
139
|
+
A good first set for most sites:
|
|
140
|
+
|
|
141
|
+
| Turn on | What you get | Then |
|
|
142
|
+
| --- | --- | --- |
|
|
143
|
+
| **Performance** (always on) | Page cache lifetimes, clearing after deploys, cache warming | Turn on **Cache warming** on the Performance page (needs `SELF`) |
|
|
144
|
+
| **Clean Image URLs** | Images from a `media.` subdomain, resized and cached | Run **Set up media host** on its page (see [Setting up a media host](docs/images.md#setting-up-a-media-host)) |
|
|
145
|
+
| **Schema & Social** | Schema.org markup and Open Graph tags | Review the publisher on the Schema page |
|
|
146
|
+
| **Redirects** | Redirects EmDash's own can't handle, plus slug-change and removed-content redirects | Import old redirects on the Redirects page |
|
|
147
|
+
| **Discovery** | IndexNow, an RSS feed, a news sitemap, llms.txt | Turn on the parts you want on the Discovery page |
|
|
148
|
+
| **Backups** | Backups of the database and media, on demand or daily | Add `backups: { name: "coywolf" }` (step 2) and the `BACKUPS` bucket, then turn on the daily backup (see [Backups](docs/backups.md)) |
|
|
149
|
+
|
|
150
|
+
### Using the admin
|
|
151
|
+
|
|
152
|
+
- **Features** (**Plugins → Coywolf Pack → Features**) turns modules and their parts on or off. A module's page also has switches for its parts.
|
|
153
|
+
- **Each module's page** holds its settings, grouped into sections, with step-by-step guides. A feature that needs an API key or a binding shows a setup card until it's there.
|
|
154
|
+
- **API keys and tokens** can be entered on their module's page or on the plugin's **Settings** page, which lists only those. EmDash stores them encrypted.
|
|
155
|
+
- **Saving:** a bar appears at the bottom of a settings page when there are unsaved changes, with **Discard** and **Save** (also Ctrl/⌘+S).
|
|
156
|
+
|
|
157
|
+
### Updating
|
|
158
|
+
|
|
159
|
+
Install the newer release's tarball (step 1 with the new tag), then deploy. Updates never turn features on by themselves: new features start off.
|
|
160
|
+
|
|
161
|
+
### Local development
|
|
162
|
+
|
|
163
|
+
In development, keep Vite from pre-bundling the plugin. A pre-bundled copy gets its own instance of `emdash`, which breaks plugin error handling. Its UI libraries should stay pre-bundled:
|
|
164
|
+
|
|
165
|
+
```js
|
|
166
|
+
// astro.config.mjs
|
|
167
|
+
export default defineConfig({
|
|
168
|
+
vite: {
|
|
169
|
+
optimizeDeps: { exclude: ["@coywolf/emdash"], include: ["@phosphor-icons/react", "@cloudflare/kumo"] },
|
|
170
|
+
ssr: { optimizeDeps: { exclude: ["@coywolf/emdash"] } },
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Troubleshooting
|
|
176
|
+
|
|
177
|
+
- **Coywolf Pack isn't in the admin.** Check that `coywolfPlugin()` is in `emdash({ plugins: [...] })` in `astro.config.mjs` and that the site was deployed (or the dev server restarted) after adding it.
|
|
178
|
+
- **A module's page isn't in the sidebar.** Its main switch is off: turn it on under **Plugins → Coywolf Pack → Features**.
|
|
179
|
+
- **Redirects, `/robots.txt` rules, the feed or downloads don't answer.** The middleware isn't running: check step 3, and that `coywolfPack()` comes before your own middleware in `sequence()`.
|
|
180
|
+
- **A feature shows a setup card instead of its settings.** It needs a binding, an API key or `EMDASH_ENCRYPTION_KEY`; the card says which.
|
|
181
|
+
- **Pages don't change after an edit.** EmDash and the pack clear cached pages on edits and deploys; **Plugins → Coywolf Pack → Performance → Clear pages and images** clears everything now. Cloudflare's zone **Purge Everything** doesn't reach the Worker's page cache.
|
|
182
|
+
|
|
183
|
+
## Documentation
|
|
184
|
+
|
|
185
|
+
Each module has its own page in [docs](docs/README.md), with its setup, settings and notes:
|
|
186
|
+
|
|
187
|
+
- [Performance](docs/performance.md): page cache, cache warming, Cloudflare usage
|
|
188
|
+
- [Content URLs](docs/content-urls.md): telling the pack how your theme routes entries
|
|
189
|
+
- Modules: [Clean Image URLs](docs/images.md) · [Backups](docs/backups.md) · [Redirects](docs/redirects.md) · [Schema & Social](docs/schema.md) · [Discovery](docs/discovery.md) · [Robots.txt Rules](docs/robots.md) · [Search](docs/search.md) · [Link Manager](docs/links.md) · [Headings & TOC](docs/headings.md) · [Breadcrumb Nav](docs/breadcrumbs.md) · [Code Blocks](docs/code-blocks.md) · [File Downloads](docs/files.md) · [Private form uploads](docs/form-uploads.md) · [Videos](docs/videos.md) · [Reviews](docs/reviews.md) · [Custom Blocks](docs/custom-blocks.md) · [AI Enrichment](docs/ai.md)
|
|
190
|
+
- [Migrating from WordPress](docs/wordpress-import.md)
|
|
191
|
+
- [Internals](docs/internals.md): how the pack keeps database reads low
|
|
192
|
+
|
|
193
|
+
## Development
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
npx tsc --noEmit -p . # typecheck
|
|
197
|
+
npm test # unit tests: test/ and src/**/*.test.ts (Node 22.15+; runs the TypeScript sources directly)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## License
|
|
201
|
+
|
|
202
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,71 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@coywolf/emdash",
|
|
3
|
+
"version": "0.35.13",
|
|
4
|
+
"description": "Coywolf Pack for EmDash: one plugin with Coywolf's features for EmDash sites on Cloudflare. Full backups and restore, a redirect manager, and more to come.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Coywolf LLC (https://coywolf.com)",
|
|
7
|
+
"homepage": "https://github.com/coywolf-llc/coywolf-pack",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/coywolf-llc/coywolf-pack.git"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"emdash",
|
|
15
|
+
"emdash-plugin",
|
|
16
|
+
"coywolf",
|
|
17
|
+
"backup",
|
|
18
|
+
"restore",
|
|
19
|
+
"redirects",
|
|
20
|
+
"cloudflare",
|
|
21
|
+
"d1",
|
|
22
|
+
"r2"
|
|
23
|
+
],
|
|
24
|
+
"main": "./src/index.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": "./src/index.ts",
|
|
27
|
+
"./admin": "./src/admin/index.tsx",
|
|
28
|
+
"./astro": "./src/astro/index.ts",
|
|
29
|
+
"./middleware": "./src/middleware.ts",
|
|
30
|
+
"./forms": "./src/forms.ts"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"src",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"typecheck": "tsc --noEmit",
|
|
39
|
+
"test": "node --import ./test/ts-resolve.mjs --test \"test/**/*.test.mjs\" \"src/**/*.test.ts\" \"src/**/*.test.mjs\""
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"@cloudflare/kumo": "*",
|
|
43
|
+
"@emdash-cms/plugin-forms": ">=0.2.9",
|
|
44
|
+
"@phosphor-icons/react": "^2.1.0",
|
|
45
|
+
"@tanstack/react-query": "^5.0.0",
|
|
46
|
+
"astro": ">=6.0.0",
|
|
47
|
+
"emdash": ">=1.2.0",
|
|
48
|
+
"highlight.js": "^11.0.0",
|
|
49
|
+
"lowlight": "^3.0.0",
|
|
50
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
51
|
+
"react-dom": "^18.0.0 || ^19.0.0",
|
|
52
|
+
"zod": "^3.24.0 || ^4.0.0"
|
|
53
|
+
},
|
|
54
|
+
"peerDependenciesMeta": {
|
|
55
|
+
"@emdash-cms/plugin-forms": {
|
|
56
|
+
"optional": true
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@cloudflare/kumo": "*",
|
|
61
|
+
"@cloudflare/workers-types": "^4.0.0",
|
|
62
|
+
"@phosphor-icons/react": "^2.1.0",
|
|
63
|
+
"@tanstack/react-query": "^5.0.0",
|
|
64
|
+
"@types/react": "^19.0.0",
|
|
65
|
+
"astro": "^7.3.0",
|
|
66
|
+
"emdash": "^1.3.0",
|
|
67
|
+
"react": "^19.0.0",
|
|
68
|
+
"typescript": "^5.9.0",
|
|
69
|
+
"zod": "^4.6.0"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// The admin pages render inside EmDash's admin, whose stylesheet is a precompiled
|
|
2
|
+
// Tailwind build: a utility class it doesn't already contain does nothing. For the
|
|
3
|
+
// layouts it has no class for (responsive variants, arbitrary grid templates, sticky
|
|
4
|
+
// panels), the pack ships these rules under its own cw- names, so they can't collide
|
|
5
|
+
// with a Tailwind class a future EmDash build adds. Breakpoints match Tailwind's
|
|
6
|
+
// (sm 40rem, md 48rem, lg 64rem) and colors use EmDash's kumo tokens.
|
|
7
|
+
//
|
|
8
|
+
// These rules are unlayered, so they win over EmDash's @layer utilities: each class
|
|
9
|
+
// carries its own hidden state (cw-lg-block is display:none below lg) rather than
|
|
10
|
+
// pairing with Tailwind's `hidden`.
|
|
11
|
+
//
|
|
12
|
+
// test/admin-classes.test.mjs fails when an admin className is in neither EmDash's
|
|
13
|
+
// stylesheet nor this file.
|
|
14
|
+
|
|
15
|
+
export const SAVE_BAR_CSS = `@keyframes cw-save-bar-in{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
|
|
16
|
+
.cw-save-bar{animation:cw-save-bar-in 160ms ease-out}
|
|
17
|
+
@media (prefers-reduced-motion: reduce){.cw-save-bar{animation:none}}`;
|
|
18
|
+
|
|
19
|
+
export const ADMIN_CSS = `.cw-fill-tint{fill:var(--color-kumo-tint)}
|
|
20
|
+
.cw-stroke-line{stroke:var(--color-kumo-line)}
|
|
21
|
+
.cw-accent-current{accent-color:currentColor}
|
|
22
|
+
.cw-field-icon{bottom:.625rem}
|
|
23
|
+
.cw-w-60{width:15rem}
|
|
24
|
+
.cw-overflow-auto{overflow:auto}
|
|
25
|
+
.cw-ps-6{padding-inline-start:1.5rem}
|
|
26
|
+
.cw-md-flex,.cw-md-table-cell,.cw-lg-block{display:none}
|
|
27
|
+
@media (min-width:40rem){
|
|
28
|
+
.cw-sm-cols-8-fill{grid-template-columns:8rem minmax(0,1fr)}
|
|
29
|
+
}
|
|
30
|
+
@media (min-width:48rem){
|
|
31
|
+
.cw-md-flex{display:flex}
|
|
32
|
+
.cw-md-row{flex-direction:row;align-items:center}
|
|
33
|
+
.cw-md-w-60{width:15rem}
|
|
34
|
+
.cw-md-table-cell{display:table-cell}
|
|
35
|
+
}
|
|
36
|
+
@media (min-width:64rem){
|
|
37
|
+
.cw-lg-block{display:block}
|
|
38
|
+
.cw-lg-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}
|
|
39
|
+
.cw-lg-cols-20-fill{grid-template-columns:minmax(0,20rem) minmax(0,1fr)}
|
|
40
|
+
.cw-lg-cols-24-fill{grid-template-columns:minmax(0,24rem) minmax(0,1fr)}
|
|
41
|
+
.cw-lg-cols-fill-24{grid-template-columns:minmax(0,1fr) minmax(0,24rem);align-items:start}
|
|
42
|
+
.cw-lg-sticky{position:sticky;top:1rem}
|
|
43
|
+
}`;
|
|
44
|
+
|
|
45
|
+
const STYLE_ID = "cw-pack-admin-css";
|
|
46
|
+
|
|
47
|
+
/** Adds the pack's admin CSS to the page once (a no-op outside the browser). */
|
|
48
|
+
export function injectAdminCss(): void {
|
|
49
|
+
if (typeof document === "undefined") return;
|
|
50
|
+
let style = document.getElementById(STYLE_ID);
|
|
51
|
+
if (!style) {
|
|
52
|
+
style = document.createElement("style");
|
|
53
|
+
style.id = STYLE_ID;
|
|
54
|
+
document.head.appendChild(style);
|
|
55
|
+
}
|
|
56
|
+
if (style.textContent !== ADMIN_CSS) style.textContent = ADMIN_CSS;
|
|
57
|
+
}
|