Fix scope
This commit is contained in:
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
|||||||
- run: pnpm install --frozen-lockfile
|
- run: pnpm install --frozen-lockfile
|
||||||
- run: pnpm build
|
- run: pnpm build
|
||||||
- run: pnpm typecheck
|
- run: pnpm typecheck
|
||||||
- run: pnpm run --filter emdashcms-demo --filter @emdashcms/demo-cloudflare typecheck
|
- run: pnpm run --filter emdashcms-demo --filter @emdash-cms/demo-cloudflare typecheck
|
||||||
- run: pnpm typecheck:templates
|
- run: pnpm typecheck:templates
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
@@ -156,7 +156,7 @@ jobs:
|
|||||||
node-version: 22
|
node-version: 22
|
||||||
cache: pnpm
|
cache: pnpm
|
||||||
- run: pnpm install --frozen-lockfile
|
- run: pnpm install --frozen-lockfile
|
||||||
- run: pnpm run --filter @emdashcms/admin... build
|
- run: pnpm run --filter @emdash-cms/admin... build
|
||||||
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||||
id: playwright-cache
|
id: playwright-cache
|
||||||
with:
|
with:
|
||||||
@@ -164,7 +164,7 @@ jobs:
|
|||||||
key: playwright-${{ hashFiles('pnpm-lock.yaml') }}
|
key: playwright-${{ hashFiles('pnpm-lock.yaml') }}
|
||||||
- run: pnpm exec playwright install --with-deps chromium
|
- run: pnpm exec playwright install --with-deps chromium
|
||||||
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||||
- run: pnpm run --filter @emdashcms/admin test
|
- run: pnpm run --filter @emdash-cms/admin test
|
||||||
|
|
||||||
test-e2e:
|
test-e2e:
|
||||||
name: E2E tests (${{ matrix.shardIndex }}/${{ matrix.shardTotal }})
|
name: E2E tests (${{ matrix.shardIndex }}/${{ matrix.shardTotal }})
|
||||||
|
|||||||
@@ -43,19 +43,19 @@ Templates in `templates/` are workspace members and can be run directly:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# First time: set up database and seed content
|
# First time: set up database and seed content
|
||||||
pnpm --filter @emdashcms/template-portfolio bootstrap
|
pnpm --filter @emdash-cms/template-portfolio bootstrap
|
||||||
|
|
||||||
# Run the dev server
|
# Run the dev server
|
||||||
pnpm --filter @emdashcms/template-portfolio dev
|
pnpm --filter @emdash-cms/template-portfolio dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Available templates:
|
Available templates:
|
||||||
|
|
||||||
| Template | Filter Name |
|
| Template | Filter Name |
|
||||||
| --------- | ------------------------------ |
|
| --------- | ------------------------------ |
|
||||||
| Blog | `@emdashcms/template-blog` |
|
| Blog | `@emdash-cms/template-blog` |
|
||||||
| Portfolio | `@emdashcms/template-portfolio` |
|
| Portfolio | `@emdash-cms/template-portfolio` |
|
||||||
| Marketing | `@emdashcms/template-marketing` |
|
| Marketing | `@emdash-cms/template-marketing` |
|
||||||
|
|
||||||
Edit files in `templates/{name}/src/` and changes hot reload.
|
Edit files in `templates/{name}/src/` and changes hot reload.
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ To start fresh, delete the database and re-bootstrap:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
rm templates/portfolio/data.db
|
rm templates/portfolio/data.db
|
||||||
pnpm --filter @emdashcms/template-portfolio bootstrap
|
pnpm --filter @emdash-cms/template-portfolio bootstrap
|
||||||
```
|
```
|
||||||
|
|
||||||
## Development Workflow
|
## Development Workflow
|
||||||
@@ -123,9 +123,9 @@ Tests use real in-memory SQLite — no mocking. Each test gets a fresh database.
|
|||||||
emdash/
|
emdash/
|
||||||
├── packages/
|
├── packages/
|
||||||
│ ├── core/ # emdash — the main package (Astro integration + APIs + admin)
|
│ ├── core/ # emdash — the main package (Astro integration + APIs + admin)
|
||||||
│ ├── auth/ # @emdashcms/auth — passkeys, OAuth, magic links
|
│ ├── auth/ # @emdash-cms/auth — passkeys, OAuth, magic links
|
||||||
│ ├── admin/ # @emdashcms/admin — React admin SPA
|
│ ├── admin/ # @emdash-cms/admin — React admin SPA
|
||||||
│ ├── cloudflare/ # @emdashcms/cloudflare — CF adapter + plugin sandbox
|
│ ├── cloudflare/ # @emdash-cms/cloudflare — CF adapter + plugin sandbox
|
||||||
│ ├── create-emdash/ # create-emdash — project scaffolder
|
│ ├── create-emdash/ # create-emdash — project scaffolder
|
||||||
│ ├── gutenberg-to-portable-text/ # WP block → Portable Text converter
|
│ ├── gutenberg-to-portable-text/ # WP block → Portable Text converter
|
||||||
│ └── plugins/ # first-party plugins (each dir = package)
|
│ └── plugins/ # first-party plugins (each dir = package)
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import {
|
|||||||
cloudflareCache,
|
cloudflareCache,
|
||||||
cloudflareImages,
|
cloudflareImages,
|
||||||
cloudflareStream,
|
cloudflareStream,
|
||||||
} from "@emdashcms/cloudflare";
|
} from "@emdash-cms/cloudflare";
|
||||||
import { formsPlugin } from "@emdashcms/plugin-forms";
|
import { formsPlugin } from "@emdash-cms/plugin-forms";
|
||||||
import { webhookNotifierPlugin } from "@emdashcms/plugin-webhook-notifier";
|
import { webhookNotifierPlugin } from "@emdash-cms/plugin-webhook-notifier";
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import emdash from "emdash/astro";
|
import emdash from "emdash/astro";
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@emdashcms/demo-cloudflare",
|
"name": "@emdash-cms/demo-cloudflare",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
"build:all": "pnpm run --filter @emdashcms/demo-cloudflare... build",
|
"build:all": "pnpm run --filter @emdash-cms/demo-cloudflare... build",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"deploy": "pnpm build:all && wrangler deploy",
|
"deploy": "pnpm build:all && wrangler deploy",
|
||||||
"db:create": "wrangler d1 create emdash-demo",
|
"db:create": "wrangler d1 create emdash-demo",
|
||||||
@@ -16,9 +16,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/cloudflare": "catalog:",
|
"@astrojs/cloudflare": "catalog:",
|
||||||
"@astrojs/react": "catalog:",
|
"@astrojs/react": "catalog:",
|
||||||
"@emdashcms/cloudflare": "workspace:*",
|
"@emdash-cms/cloudflare": "workspace:*",
|
||||||
"@emdashcms/plugin-forms": "workspace:*",
|
"@emdash-cms/plugin-forms": "workspace:*",
|
||||||
"@emdashcms/plugin-webhook-notifier": "workspace:*",
|
"@emdash-cms/plugin-webhook-notifier": "workspace:*",
|
||||||
"@tanstack/react-query": "catalog:",
|
"@tanstack/react-query": "catalog:",
|
||||||
"@tanstack/react-router": "catalog:",
|
"@tanstack/react-router": "catalog:",
|
||||||
"astro": "catalog:",
|
"astro": "catalog:",
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import handler from "@astrojs/cloudflare/entrypoints/server";
|
|||||||
|
|
||||||
// Re-export PluginBridge from the cloudflare sandbox runtime
|
// Re-export PluginBridge from the cloudflare sandbox runtime
|
||||||
// This makes it available via ctx.exports.PluginBridge
|
// This makes it available via ctx.exports.PluginBridge
|
||||||
export { PluginBridge } from "@emdashcms/cloudflare/sandbox";
|
export { PluginBridge } from "@emdash-cms/cloudflare/sandbox";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default export - just re-export the Astro handler
|
* Default export - just re-export the Astro handler
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import cloudflare from "@astrojs/cloudflare";
|
import cloudflare from "@astrojs/cloudflare";
|
||||||
import react from "@astrojs/react";
|
import react from "@astrojs/react";
|
||||||
import { playgroundDatabase } from "@emdashcms/cloudflare";
|
import { playgroundDatabase } from "@emdash-cms/cloudflare";
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import emdash from "emdash/astro";
|
import emdash from "emdash/astro";
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ export default defineConfig({
|
|||||||
// Playground mode: injects playground middleware before runtime init,
|
// Playground mode: injects playground middleware before runtime init,
|
||||||
// skips setup/auth (handled by playground middleware)
|
// skips setup/auth (handled by playground middleware)
|
||||||
playground: {
|
playground: {
|
||||||
middlewareEntrypoint: "@emdashcms/cloudflare/db/playground-middleware",
|
middlewareEntrypoint: "@emdash-cms/cloudflare/db/playground-middleware",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@emdashcms/playground",
|
"name": "@emdash-cms/playground",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/cloudflare": "catalog:",
|
"@astrojs/cloudflare": "catalog:",
|
||||||
"@astrojs/react": "catalog:",
|
"@astrojs/react": "catalog:",
|
||||||
"@emdashcms/cloudflare": "workspace:*",
|
"@emdash-cms/cloudflare": "workspace:*",
|
||||||
"astro": "catalog:",
|
"astro": "catalog:",
|
||||||
"emdash": "workspace:*",
|
"emdash": "workspace:*",
|
||||||
"react": "catalog:",
|
"react": "catalog:",
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
import handler from "@astrojs/cloudflare/entrypoints/server";
|
import handler from "@astrojs/cloudflare/entrypoints/server";
|
||||||
|
|
||||||
// Export the DO class so Cloudflare can instantiate it
|
// Export the DO class so Cloudflare can instantiate it
|
||||||
export { EmDashPreviewDB } from "@emdashcms/cloudflare/db/playground";
|
export { EmDashPreviewDB } from "@emdash-cms/cloudflare/db/playground";
|
||||||
|
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ This demo showcases EmDash's plugin system with plugins that demonstrate the hoo
|
|||||||
|
|
||||||
## Plugins Included
|
## Plugins Included
|
||||||
|
|
||||||
### 1. Audit Log Plugin (`@emdashcms/plugin-audit-log`)
|
### 1. Audit Log Plugin (`@emdash-cms/plugin-audit-log`)
|
||||||
|
|
||||||
Tracks all content changes for compliance.
|
Tracks all content changes for compliance.
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ Tracks all content changes for compliance.
|
|||||||
- Before/after state comparison
|
- Before/after state comparison
|
||||||
- Admin history page
|
- Admin history page
|
||||||
|
|
||||||
### 2. Webhook Notifier Plugin (`@emdashcms/plugin-webhook-notifier`)
|
### 2. Webhook Notifier Plugin (`@emdash-cms/plugin-webhook-notifier`)
|
||||||
|
|
||||||
Posts JSON payloads to external webhook URLs on content/media events.
|
Posts JSON payloads to external webhook URLs on content/media events.
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ Posts JSON payloads to external webhook URLs on content/media events.
|
|||||||
- SSRF protection
|
- SSRF protection
|
||||||
- Delivery tracking
|
- Delivery tracking
|
||||||
|
|
||||||
### 3. Embeds Plugin (`@emdashcms/plugin-embeds`)
|
### 3. Embeds Plugin (`@emdash-cms/plugin-embeds`)
|
||||||
|
|
||||||
Provides Portable Text block types for embedding external content.
|
Provides Portable Text block types for embedding external content.
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ Provides Portable Text block types for embedding external content.
|
|||||||
- Link previews (Open Graph)
|
- Link previews (Open Graph)
|
||||||
- GitHub Gist embeds
|
- GitHub Gist embeds
|
||||||
|
|
||||||
### 4. API Test Plugin (`@emdashcms/plugin-api-test`)
|
### 4. API Test Plugin (`@emdash-cms/plugin-api-test`)
|
||||||
|
|
||||||
Exercises all v2 plugin APIs for testing.
|
Exercises all v2 plugin APIs for testing.
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import node from "@astrojs/node";
|
import node from "@astrojs/node";
|
||||||
import react from "@astrojs/react";
|
import react from "@astrojs/react";
|
||||||
import { apiTestPlugin } from "@emdashcms/plugin-api-test";
|
import { apiTestPlugin } from "@emdash-cms/plugin-api-test";
|
||||||
import { auditLogPlugin } from "@emdashcms/plugin-audit-log";
|
import { auditLogPlugin } from "@emdash-cms/plugin-audit-log";
|
||||||
import { embedsPlugin } from "@emdashcms/plugin-embeds";
|
import { embedsPlugin } from "@emdash-cms/plugin-embeds";
|
||||||
import { webhookNotifierPlugin } from "@emdashcms/plugin-webhook-notifier";
|
import { webhookNotifierPlugin } from "@emdash-cms/plugin-webhook-notifier";
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import emdash from "emdash/astro";
|
import emdash from "emdash/astro";
|
||||||
import { sqlite } from "emdash/db";
|
import { sqlite } from "emdash/db";
|
||||||
|
|||||||
@@ -14,10 +14,10 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/node": "catalog:",
|
"@astrojs/node": "catalog:",
|
||||||
"@astrojs/react": "catalog:",
|
"@astrojs/react": "catalog:",
|
||||||
"@emdashcms/plugin-audit-log": "workspace:*",
|
"@emdash-cms/plugin-audit-log": "workspace:*",
|
||||||
"@emdashcms/plugin-api-test": "workspace:*",
|
"@emdash-cms/plugin-api-test": "workspace:*",
|
||||||
"@emdashcms/plugin-webhook-notifier": "workspace:*",
|
"@emdash-cms/plugin-webhook-notifier": "workspace:*",
|
||||||
"@emdashcms/plugin-embeds": "workspace:*",
|
"@emdash-cms/plugin-embeds": "workspace:*",
|
||||||
"@tanstack/react-query": "catalog:",
|
"@tanstack/react-query": "catalog:",
|
||||||
"@tanstack/react-router": "catalog:",
|
"@tanstack/react-router": "catalog:",
|
||||||
"astro": "catalog:",
|
"astro": "catalog:",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
import { getEmDashEntry } from "emdash";
|
import { getEmDashEntry } from "emdash";
|
||||||
import { PortableText } from "emdash/ui";
|
import { PortableText } from "emdash/ui";
|
||||||
import { embedComponents } from "@emdashcms/plugin-embeds/astro";
|
import { embedComponents } from "@emdash-cms/plugin-embeds/astro";
|
||||||
|
|
||||||
const { slug } = Astro.params;
|
const { slug } = Astro.params;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* This page renders hardcoded Portable Text with embed blocks.
|
* This page renders hardcoded Portable Text with embed blocks.
|
||||||
*/
|
*/
|
||||||
import { PortableText } from "emdash/ui";
|
import { PortableText } from "emdash/ui";
|
||||||
import { embedComponents } from "@emdashcms/plugin-embeds/astro";
|
import { embedComponents } from "@emdash-cms/plugin-embeds/astro";
|
||||||
|
|
||||||
// Sample Portable Text content with various embed types
|
// Sample Portable Text content with various embed types
|
||||||
const testContent = [
|
const testContent = [
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@emdashcms/demo-postgres",
|
"name": "@emdash-cms/demo-postgres",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import cloudflare from "@astrojs/cloudflare";
|
import cloudflare from "@astrojs/cloudflare";
|
||||||
import react from "@astrojs/react";
|
import react from "@astrojs/react";
|
||||||
import { previewDatabase } from "@emdashcms/cloudflare";
|
import { previewDatabase } from "@emdash-cms/cloudflare";
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import emdash from "emdash/astro";
|
import emdash from "emdash/astro";
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@emdashcms/demo-preview",
|
"name": "@emdash-cms/demo-preview",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
"build:all": "pnpm run --filter @emdashcms/demo-preview... build",
|
"build:all": "pnpm run --filter @emdash-cms/demo-preview... build",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"deploy": "pnpm build:all && wrangler deploy",
|
"deploy": "pnpm build:all && wrangler deploy",
|
||||||
"typecheck": "astro check"
|
"typecheck": "astro check"
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/cloudflare": "catalog:",
|
"@astrojs/cloudflare": "catalog:",
|
||||||
"@astrojs/react": "catalog:",
|
"@astrojs/react": "catalog:",
|
||||||
"@emdashcms/cloudflare": "workspace:*",
|
"@emdash-cms/cloudflare": "workspace:*",
|
||||||
"@tanstack/react-query": "catalog:",
|
"@tanstack/react-query": "catalog:",
|
||||||
"@tanstack/react-router": "catalog:",
|
"@tanstack/react-router": "catalog:",
|
||||||
"astro": "catalog:",
|
"astro": "catalog:",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* populates snapshots, and overrides the request-context DB.
|
* populates snapshots, and overrides the request-context DB.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createPreviewMiddleware } from "@emdashcms/cloudflare/db/do";
|
import { createPreviewMiddleware } from "@emdash-cms/cloudflare/db/do";
|
||||||
import { sequence } from "astro:middleware";
|
import { sequence } from "astro:middleware";
|
||||||
|
|
||||||
const preview = createPreviewMiddleware({
|
const preview = createPreviewMiddleware({
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
import handler from "@astrojs/cloudflare/entrypoints/server";
|
import handler from "@astrojs/cloudflare/entrypoints/server";
|
||||||
|
|
||||||
// Export the DO class so Cloudflare can instantiate it
|
// Export the DO class so Cloudflare can instantiate it
|
||||||
export { EmDashPreviewDB } from "@emdashcms/cloudflare/db/do";
|
export { EmDashPreviewDB } from "@emdash-cms/cloudflare/db/do";
|
||||||
|
|
||||||
export default handler;
|
export default handler;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import node from "@astrojs/node";
|
import node from "@astrojs/node";
|
||||||
import react from "@astrojs/react";
|
import react from "@astrojs/react";
|
||||||
import { auditLogPlugin } from "@emdashcms/plugin-audit-log";
|
import { auditLogPlugin } from "@emdash-cms/plugin-audit-log";
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import emdash, { local } from "emdash/astro";
|
import emdash, { local } from "emdash/astro";
|
||||||
import { sqlite } from "emdash/db";
|
import { sqlite } from "emdash/db";
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/node": "catalog:",
|
"@astrojs/node": "catalog:",
|
||||||
"@astrojs/react": "catalog:",
|
"@astrojs/react": "catalog:",
|
||||||
"@emdashcms/plugin-audit-log": "workspace:*",
|
"@emdash-cms/plugin-audit-log": "workspace:*",
|
||||||
"@emdashcms/plugin-color": "workspace:*",
|
"@emdash-cms/plugin-color": "workspace:*",
|
||||||
"astro": "catalog:",
|
"astro": "catalog:",
|
||||||
"better-sqlite3": "catalog:",
|
"better-sqlite3": "catalog:",
|
||||||
"emdash": "workspace:*",
|
"emdash": "workspace:*",
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ Extend EmDash with plugins that add hooks, storage, settings, and admin UI:
|
|||||||
|
|
||||||
```ts title="astro.config.mjs"
|
```ts title="astro.config.mjs"
|
||||||
import emdash from "emdash/astro";
|
import emdash from "emdash/astro";
|
||||||
import seoPlugin from "@emdashcms/plugin-seo";
|
import seoPlugin from "@emdash-cms/plugin-seo";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [
|
integrations: [
|
||||||
|
|||||||
@@ -204,8 +204,8 @@ Plugins can extend the admin with pages and dashboard widgets. The integration g
|
|||||||
|
|
||||||
```ts
|
```ts
|
||||||
// virtual:emdash/plugin-admins (generated)
|
// virtual:emdash/plugin-admins (generated)
|
||||||
import * as pluginAdmin0 from "@emdashcms/plugin-seo/admin";
|
import * as pluginAdmin0 from "@emdash-cms/plugin-seo/admin";
|
||||||
import * as pluginAdmin1 from "@emdashcms/plugin-analytics/admin";
|
import * as pluginAdmin1 from "@emdash-cms/plugin-analytics/admin";
|
||||||
|
|
||||||
export const pluginAdmins = {
|
export const pluginAdmins = {
|
||||||
seo: pluginAdmin0,
|
seo: pluginAdmin0,
|
||||||
@@ -218,7 +218,7 @@ export const pluginAdmins = {
|
|||||||
Plugin pages mount under `/_emdash/admin/plugins/:pluginId/*`:
|
Plugin pages mount under `/_emdash/admin/plugins/:pluginId/*`:
|
||||||
|
|
||||||
```tsx
|
```tsx
|
||||||
// @emdashcms/plugin-seo/src/admin.tsx
|
// @emdash-cms/plugin-seo/src/admin.tsx
|
||||||
export const pages = [
|
export const pages = [
|
||||||
{
|
{
|
||||||
path: "settings",
|
path: "settings",
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ Plugins can run in two modes:
|
|||||||
|
|
||||||
```ts
|
```ts
|
||||||
// astro.config.mjs
|
// astro.config.mjs
|
||||||
import { seoPlugin } from "@emdashcms/plugin-seo";
|
import { seoPlugin } from "@emdash-cms/plugin-seo";
|
||||||
|
|
||||||
emdash({
|
emdash({
|
||||||
plugins: [seoPlugin({ maxTitleLength: 60 })],
|
plugins: [seoPlugin({ maxTitleLength: 60 })],
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ EmDash is a **pnpm monorepo** with multiple packages:
|
|||||||
emdash/
|
emdash/
|
||||||
├── packages/
|
├── packages/
|
||||||
│ ├── core/ # emdash — Astro integration, APIs, admin (main package)
|
│ ├── core/ # emdash — Astro integration, APIs, admin (main package)
|
||||||
│ ├── auth/ # @emdashcms/auth — Authentication (passkeys, OAuth, magic links)
|
│ ├── auth/ # @emdash-cms/auth — Authentication (passkeys, OAuth, magic links)
|
||||||
│ ├── cloudflare/ # @emdashcms/cloudflare — Cloudflare adapter + sandbox runner
|
│ ├── cloudflare/ # @emdash-cms/cloudflare — Cloudflare adapter + sandbox runner
|
||||||
│ ├── admin/ # @emdashcms/admin — Admin React SPA
|
│ ├── admin/ # @emdash-cms/admin — Admin React SPA
|
||||||
│ ├── create-emdash/ # create-emdash — project scaffolder
|
│ ├── create-emdash/ # create-emdash — project scaffolder
|
||||||
│ ├── gutenberg-to-portable-text/ # WordPress block → Portable Text converter
|
│ ├── gutenberg-to-portable-text/ # WordPress block → Portable Text converter
|
||||||
│ └── plugins/ # First-party plugins (each subdirectory is its own package)
|
│ └── plugins/ # First-party plugins (each subdirectory is its own package)
|
||||||
@@ -279,7 +279,7 @@ Route files live in `packages/core/src/astro/routes/api/`. Follow these conventi
|
|||||||
```ts
|
```ts
|
||||||
// packages/core/src/astro/routes/api/my-resource.ts
|
// packages/core/src/astro/routes/api/my-resource.ts
|
||||||
import type { APIRoute } from "astro";
|
import type { APIRoute } from "astro";
|
||||||
import type { User } from "@emdashcms/auth";
|
import type { User } from "@emdash-cms/auth";
|
||||||
import { apiError, handleError } from "#api/error.js";
|
import { apiError, handleError } from "#api/error.js";
|
||||||
import { requirePerm } from "#api/authorize.js";
|
import { requirePerm } from "#api/authorize.js";
|
||||||
import { parseBody } from "#api/parse.js";
|
import { parseBody } from "#api/parse.js";
|
||||||
@@ -398,7 +398,7 @@ Use `import type` for type-only imports:
|
|||||||
|
|
||||||
```ts
|
```ts
|
||||||
import type { Kysely } from "kysely";
|
import type { Kysely } from "kysely";
|
||||||
import type { User } from "@emdashcms/auth";
|
import type { User } from "@emdash-cms/auth";
|
||||||
```
|
```
|
||||||
|
|
||||||
### Error Handling
|
### Error Handling
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ D1 supports [read replication](https://developers.cloudflare.com/d1/configuratio
|
|||||||
EmDash uses the D1 Sessions API to manage this transparently. Enable it with the `session` option:
|
EmDash uses the D1 Sessions API to manage this transparently. Enable it with the `session` option:
|
||||||
|
|
||||||
```js title="astro.config.mjs"
|
```js title="astro.config.mjs"
|
||||||
import { d1 } from "@emdashcms/cloudflare";
|
import { d1 } from "@emdash-cms/cloudflare";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [
|
integrations: [
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ In addition to local storage, EmDash supports external media providers for speci
|
|||||||
```js title="astro.config.mjs"
|
```js title="astro.config.mjs"
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import emdash from "emdash/astro";
|
import emdash from "emdash/astro";
|
||||||
import { cloudflareImages } from "@emdashcms/cloudflare";
|
import { cloudflareImages } from "@emdash-cms/cloudflare";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [
|
integrations: [
|
||||||
@@ -381,7 +381,7 @@ export default defineConfig({
|
|||||||
```js title="astro.config.mjs"
|
```js title="astro.config.mjs"
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import emdash from "emdash/astro";
|
import emdash from "emdash/astro";
|
||||||
import { cloudflareStream } from "@emdashcms/cloudflare";
|
import { cloudflareStream } from "@emdash-cms/cloudflare";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [
|
integrations: [
|
||||||
@@ -418,7 +418,7 @@ You can configure multiple providers. Each appears as a tab in the media picker:
|
|||||||
```js title="astro.config.mjs"
|
```js title="astro.config.mjs"
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import emdash from "emdash/astro";
|
import emdash from "emdash/astro";
|
||||||
import { cloudflareImages, cloudflareStream } from "@emdashcms/cloudflare";
|
import { cloudflareImages, cloudflareStream } from "@emdash-cms/cloudflare";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [
|
integrations: [
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ description: Monetize content with the x402 payment protocol — charge bots, no
|
|||||||
|
|
||||||
import { Aside, Steps, Tabs, TabItem } from "@astrojs/starlight/components";
|
import { Aside, Steps, Tabs, TabItem } from "@astrojs/starlight/components";
|
||||||
|
|
||||||
The `@emdashcms/x402` package adds [x402 payment protocol](https://www.x402.org/) support to any Astro site on Cloudflare. It works standalone — no dependency on EmDash core — but pairs well with EmDash's CMS fields for per-page pricing.
|
The `@emdash-cms/x402` package adds [x402 payment protocol](https://www.x402.org/) support to any Astro site on Cloudflare. It works standalone — no dependency on EmDash core — but pairs well with EmDash's CMS fields for per-page pricing.
|
||||||
|
|
||||||
x402 is an HTTP-native payment protocol. When a client requests a paid resource without payment, the server responds with `402 Payment Required` and machine-readable payment instructions. Agents and browsers that understand x402 can complete payment automatically and retry the request.
|
x402 is an HTTP-native payment protocol. When a client requests a paid resource without payment, the server responds with `402 Payment Required` and machine-readable payment instructions. Agents and browsers that understand x402 can complete payment automatically and retry the request.
|
||||||
|
|
||||||
@@ -20,17 +20,17 @@ You can also enforce payment for all visitors, or check for payment headers with
|
|||||||
<Tabs>
|
<Tabs>
|
||||||
<TabItem label="pnpm">
|
<TabItem label="pnpm">
|
||||||
```bash
|
```bash
|
||||||
pnpm add @emdashcms/x402
|
pnpm add @emdash-cms/x402
|
||||||
```
|
```
|
||||||
</TabItem>
|
</TabItem>
|
||||||
<TabItem label="npm">
|
<TabItem label="npm">
|
||||||
```bash
|
```bash
|
||||||
npm install @emdashcms/x402
|
npm install @emdash-cms/x402
|
||||||
```
|
```
|
||||||
</TabItem>
|
</TabItem>
|
||||||
<TabItem label="yarn">
|
<TabItem label="yarn">
|
||||||
```bash
|
```bash
|
||||||
yarn add @emdashcms/x402
|
yarn add @emdash-cms/x402
|
||||||
```
|
```
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
@@ -41,7 +41,7 @@ Add the integration to your Astro config:
|
|||||||
|
|
||||||
```js title="astro.config.mjs"
|
```js title="astro.config.mjs"
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import { x402 } from "@emdashcms/x402";
|
import { x402 } from "@emdash-cms/x402";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [
|
integrations: [
|
||||||
@@ -59,7 +59,7 @@ export default defineConfig({
|
|||||||
Add the type reference so TypeScript knows about `Astro.locals.x402`:
|
Add the type reference so TypeScript knows about `Astro.locals.x402`:
|
||||||
|
|
||||||
```ts title="src/env.d.ts"
|
```ts title="src/env.d.ts"
|
||||||
/// <reference types="@emdashcms/x402/locals" />
|
/// <reference types="@emdash-cms/x402/locals" />
|
||||||
```
|
```
|
||||||
|
|
||||||
## Basic Usage
|
## Basic Usage
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import { Card, CardGrid } from "@astrojs/starlight/components";
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Create a new EmDash site
|
# Create a new EmDash site
|
||||||
npm create astro@latest -- --template @emdashcms/template-blog
|
npm create astro@latest -- --template @emdash-cms/template-blog
|
||||||
|
|
||||||
# Start the dev server
|
# Start the dev server
|
||||||
npm run dev
|
npm run dev
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ Pages mount at `/_emdash/admin/plugins/<plugin-id>/<path>`.
|
|||||||
|
|
||||||
```typescript title="src/components/SettingsPage.tsx"
|
```typescript title="src/components/SettingsPage.tsx"
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { usePluginAPI } from "@emdashcms/admin";
|
import { usePluginAPI } from "@emdash-cms/admin";
|
||||||
|
|
||||||
export function SettingsPage() {
|
export function SettingsPage() {
|
||||||
const api = usePluginAPI();
|
const api = usePluginAPI();
|
||||||
@@ -135,7 +135,7 @@ export function SettingsPage() {
|
|||||||
Use `usePluginAPI()` to call your plugin's routes:
|
Use `usePluginAPI()` to call your plugin's routes:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { usePluginAPI } from "@emdashcms/admin";
|
import { usePluginAPI } from "@emdash-cms/admin";
|
||||||
|
|
||||||
function MyComponent() {
|
function MyComponent() {
|
||||||
const api = usePluginAPI();
|
const api = usePluginAPI();
|
||||||
@@ -177,7 +177,7 @@ admin: {
|
|||||||
|
|
||||||
```typescript title="src/components/SEOWidget.tsx"
|
```typescript title="src/components/SEOWidget.tsx"
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { usePluginAPI } from "@emdashcms/admin";
|
import { usePluginAPI } from "@emdash-cms/admin";
|
||||||
|
|
||||||
export function SEOWidget() {
|
export function SEOWidget() {
|
||||||
const api = usePluginAPI();
|
const api = usePluginAPI();
|
||||||
@@ -253,7 +253,7 @@ import {
|
|||||||
Pagination,
|
Pagination,
|
||||||
Alert,
|
Alert,
|
||||||
Loading
|
Loading
|
||||||
} from "@emdashcms/admin";
|
} from "@emdash-cms/admin";
|
||||||
|
|
||||||
function SettingsPage() {
|
function SettingsPage() {
|
||||||
return (
|
return (
|
||||||
@@ -309,7 +309,7 @@ export default {
|
|||||||
},
|
},
|
||||||
format: "esm",
|
format: "esm",
|
||||||
dts: true,
|
dts: true,
|
||||||
external: ["react", "react-dom", "emdash", "@emdashcms/admin"]
|
external: ["react", "react-dom", "emdash", "@emdash-cms/admin"]
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
</TabItem>
|
</TabItem>
|
||||||
@@ -319,7 +319,7 @@ export default {
|
|||||||
entry: ["src/index.ts", "src/admin.tsx"],
|
entry: ["src/index.ts", "src/admin.tsx"],
|
||||||
format: "esm",
|
format: "esm",
|
||||||
dts: true,
|
dts: true,
|
||||||
external: ["react", "react-dom", "emdash", "@emdashcms/admin"]
|
external: ["react", "react-dom", "emdash", "@emdash-cms/admin"]
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|||||||
@@ -402,7 +402,7 @@ routes: {
|
|||||||
Use the `usePluginAPI()` hook in admin components:
|
Use the `usePluginAPI()` hook in admin components:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { usePluginAPI } from "@emdashcms/admin";
|
import { usePluginAPI } from "@emdash-cms/admin";
|
||||||
|
|
||||||
function SettingsPage() {
|
function SettingsPage() {
|
||||||
const api = usePluginAPI();
|
const api = usePluginAPI();
|
||||||
|
|||||||
@@ -89,10 +89,10 @@ routes: {
|
|||||||
|
|
||||||
## Builder helpers
|
## Builder helpers
|
||||||
|
|
||||||
The `@emdashcms/blocks` package exports builder helpers for cleaner code:
|
The `@emdash-cms/blocks` package exports builder helpers for cleaner code:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { blocks, elements } from "@emdashcms/blocks";
|
import { blocks, elements } from "@emdash-cms/blocks";
|
||||||
|
|
||||||
const { header, form, section, stats } = blocks;
|
const { header, form, section, stats } = blocks;
|
||||||
const { textInput, toggle, select, button } = elements;
|
const { textInput, toggle, select, button } = elements;
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ The `id` field must follow these rules:
|
|||||||
// Valid IDs
|
// Valid IDs
|
||||||
"seo";
|
"seo";
|
||||||
"audit-log";
|
"audit-log";
|
||||||
"@emdashcms/plugin-forms";
|
"@emdash-cms/plugin-forms";
|
||||||
|
|
||||||
// Invalid IDs
|
// Invalid IDs
|
||||||
"MyPlugin"; // No uppercase
|
"MyPlugin"; // No uppercase
|
||||||
@@ -445,7 +445,7 @@ export function myPlugin(options = {}): PluginDescriptor {
|
|||||||
Plugin block components are automatically merged into `<PortableText>` — site authors don't need to import anything. User-provided components take precedence over plugin defaults.
|
Plugin block components are automatically merged into `<PortableText>` — site authors don't need to import anything. User-provided components take precedence over plugin defaults.
|
||||||
|
|
||||||
<Aside type="tip">
|
<Aside type="tip">
|
||||||
The embeds plugin (`@emdashcms/plugin-embeds`) is a complete example of this pattern. It provides
|
The embeds plugin (`@emdash-cms/plugin-embeds`) is a complete example of this pattern. It provides
|
||||||
YouTube, Vimeo, Tweet, Bluesky, Mastodon, Gist, and Link Preview block types with both admin
|
YouTube, Vimeo, Tweet, Bluesky, Mastodon, Gist, and Link Preview block types with both admin
|
||||||
editing fields and site-side Astro rendering components.
|
editing fields and site-side Astro rendering components.
|
||||||
</Aside>
|
</Aside>
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ For trusted plugins (your own code, or packages you install via npm), add them d
|
|||||||
```typescript title="astro.config.mjs"
|
```typescript title="astro.config.mjs"
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import { emdash } from "emdash/astro";
|
import { emdash } from "emdash/astro";
|
||||||
import seoPlugin from "@emdashcms/plugin-seo";
|
import seoPlugin from "@emdash-cms/plugin-seo";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [
|
integrations: [
|
||||||
|
|||||||
@@ -135,8 +135,8 @@ Register plugins in your Astro configuration:
|
|||||||
```typescript title="astro.config.mjs"
|
```typescript title="astro.config.mjs"
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import { emdash } from "emdash/astro";
|
import { emdash } from "emdash/astro";
|
||||||
import seoPlugin from "@emdashcms/plugin-seo";
|
import seoPlugin from "@emdash-cms/plugin-seo";
|
||||||
import auditLogPlugin from "@emdashcms/plugin-audit-log";
|
import auditLogPlugin from "@emdash-cms/plugin-audit-log";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [
|
integrations: [
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ The bundle command finds your code through `package.json` exports:
|
|||||||
|
|
||||||
| Export | Purpose | Built as |
|
| Export | Purpose | Built as |
|
||||||
| ------------ | ------- | -------- |
|
| ------------ | ------- | -------- |
|
||||||
| `"."` | Main entry — used to extract the manifest | Externals: `emdash`, `@emdashcms/*` |
|
| `"."` | Main entry — used to extract the manifest | Externals: `emdash`, `@emdash-cms/*` |
|
||||||
| `"./sandbox"` | Backend code that runs in the sandbox | Fully self-contained (no externals) |
|
| `"./sandbox"` | Backend code that runs in the sandbox | Fully self-contained (no externals) |
|
||||||
| `"./admin"` | Admin UI components | Fully self-contained |
|
| `"./admin"` | Admin UI components | Fully self-contained |
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ EmDash supports running plugins in two execution modes: **trusted** and **sandbo
|
|||||||
Trusted plugins run in the same process as your Astro site. They are loaded from npm packages or local files and configured in `astro.config.mjs`:
|
Trusted plugins run in the same process as your Astro site. They are loaded from npm packages or local files and configured in `astro.config.mjs`:
|
||||||
|
|
||||||
```typescript title="astro.config.mjs"
|
```typescript title="astro.config.mjs"
|
||||||
import myPlugin from "@emdashcms/plugin-analytics";
|
import myPlugin from "@emdash-cms/plugin-analytics";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [
|
integrations: [
|
||||||
@@ -54,7 +54,7 @@ To enable sandboxing, configure the sandbox runner in your Astro config:
|
|||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
integrations: [
|
integrations: [
|
||||||
emdash({
|
emdash({
|
||||||
sandboxRunner: "@emdashcms/cloudflare/sandbox",
|
sandboxRunner: "@emdash-cms/cloudflare/sandbox",
|
||||||
sandboxed: [
|
sandboxed: [
|
||||||
{
|
{
|
||||||
manifest: seoPluginManifest,
|
manifest: seoPluginManifest,
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ database: libsql({
|
|||||||
authToken: process.env.LIBSQL_AUTH_TOKEN,
|
authToken: process.env.LIBSQL_AUTH_TOKEN,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cloudflare D1 (import from @emdashcms/cloudflare)
|
// Cloudflare D1 (import from @emdash-cms/cloudflare)
|
||||||
database: d1({ binding: "DB" });
|
database: d1({ binding: "DB" });
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ See [Storage Options](/deployment/storage/) for details.
|
|||||||
**Optional.** Array of EmDash plugins.
|
**Optional.** Array of EmDash plugins.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import seoPlugin from "@emdashcms/plugin-seo";
|
import seoPlugin from "@emdash-cms/plugin-seo";
|
||||||
|
|
||||||
plugins: [seoPlugin()];
|
plugins: [seoPlugin()];
|
||||||
```
|
```
|
||||||
@@ -258,7 +258,7 @@ postgres({ connectionString: process.env.DATABASE_URL });
|
|||||||
|
|
||||||
### `d1(config)`
|
### `d1(config)`
|
||||||
|
|
||||||
Cloudflare D1 database. Import from `@emdashcms/cloudflare`.
|
Cloudflare D1 database. Import from `@emdash-cms/cloudflare`.
|
||||||
|
|
||||||
| Option | Type | Default | Description |
|
| Option | Type | Default | Description |
|
||||||
| ---------------- | -------- | -------------------- | --------------------------------------------------- |
|
| ---------------- | -------- | -------------------- | --------------------------------------------------- |
|
||||||
@@ -417,7 +417,7 @@ EmDash generates types in `.emdash/types.ts`. Add to your `tsconfig.json`:
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"paths": {
|
"paths": {
|
||||||
"@emdashcms/types": ["./.emdash/types.ts"]
|
"@emdash-cms/types": ["./.emdash/types.ts"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
docs/src/content/docs/themes/overview.mdx
vendored
14
docs/src/content/docs/themes/overview.mdx
vendored
@@ -64,7 +64,7 @@ When you create a site from a theme, this happens:
|
|||||||
Use `create-astro` with a template:
|
Use `create-astro` with a template:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm create astro@latest -- --template @emdashcms/template-blog
|
npm create astro@latest -- --template @emdash-cms/template-blog
|
||||||
```
|
```
|
||||||
|
|
||||||
Community themes work via GitHub:
|
Community themes work via GitHub:
|
||||||
@@ -125,18 +125,18 @@ EmDash provides official starter themes, each available in local (SQLite + files
|
|||||||
|
|
||||||
| Theme | Description | Use Case |
|
| Theme | Description | Use Case |
|
||||||
| ----- | ----------- | -------- |
|
| ----- | ----------- | -------- |
|
||||||
| `@emdashcms/template-blog` | Minimal blog with posts, pages, categories, and dark mode | Personal blogs, simple sites |
|
| `@emdash-cms/template-blog` | Minimal blog with posts, pages, categories, and dark mode | Personal blogs, simple sites |
|
||||||
| `@emdashcms/template-portfolio` | Editorial-style portfolio with projects, serif typography (Playfair Display), and image-focused layouts | Freelancers, agencies, creatives |
|
| `@emdash-cms/template-portfolio` | Editorial-style portfolio with projects, serif typography (Playfair Display), and image-focused layouts | Freelancers, agencies, creatives |
|
||||||
| `@emdashcms/template-marketing` | Bold marketing site with custom Portable Text blocks (hero, features, testimonials, pricing, FAQ) | Landing pages, SaaS sites, product marketing |
|
| `@emdash-cms/template-marketing` | Bold marketing site with custom Portable Text blocks (hero, features, testimonials, pricing, FAQ) | Landing pages, SaaS sites, product marketing |
|
||||||
|
|
||||||
### Cloudflare Variants
|
### Cloudflare Variants
|
||||||
|
|
||||||
For deployment on Cloudflare Pages with D1 and R2, append `-cloudflare` to the template name:
|
For deployment on Cloudflare Pages with D1 and R2, append `-cloudflare` to the template name:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm create astro@latest -- --template @emdashcms/template-blog-cloudflare
|
npm create astro@latest -- --template @emdash-cms/template-blog-cloudflare
|
||||||
npm create astro@latest -- --template @emdashcms/template-portfolio-cloudflare
|
npm create astro@latest -- --template @emdash-cms/template-portfolio-cloudflare
|
||||||
npm create astro@latest -- --template @emdashcms/template-marketing-cloudflare
|
npm create astro@latest -- --template @emdash-cms/template-marketing-cloudflare
|
||||||
```
|
```
|
||||||
|
|
||||||
These variants include `wrangler.jsonc` for deployment configuration.
|
These variants include `wrangler.jsonc` for deployment configuration.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
import node from "@astrojs/node";
|
import node from "@astrojs/node";
|
||||||
import react from "@astrojs/react";
|
import react from "@astrojs/react";
|
||||||
import { colorPlugin } from "@emdashcms/plugin-color";
|
import { colorPlugin } from "@emdash-cms/plugin-color";
|
||||||
import { defineConfig } from "astro/config";
|
import { defineConfig } from "astro/config";
|
||||||
import emdash from "emdash/astro";
|
import emdash from "emdash/astro";
|
||||||
import { sqlite } from "emdash/db";
|
import { sqlite } from "emdash/db";
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/node": "catalog:",
|
"@astrojs/node": "catalog:",
|
||||||
"@astrojs/react": "catalog:",
|
"@astrojs/react": "catalog:",
|
||||||
"@emdashcms/auth": "workspace:*",
|
"@emdash-cms/auth": "workspace:*",
|
||||||
"@emdashcms/plugin-color": "workspace:*",
|
"@emdash-cms/plugin-color": "workspace:*",
|
||||||
"astro": "catalog:",
|
"astro": "catalog:",
|
||||||
"better-sqlite3": "catalog:",
|
"better-sqlite3": "catalog:",
|
||||||
"emdash": "workspace:*",
|
"emdash": "workspace:*",
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ async function ensureBuilt(): Promise<void> {
|
|||||||
/**
|
/**
|
||||||
* Ensure all e2e fixture dependencies are built.
|
* Ensure all e2e fixture dependencies are built.
|
||||||
* The CI build filter (--filter emdash...) only builds emdash and its deps,
|
* The CI build filter (--filter emdash...) only builds emdash and its deps,
|
||||||
* not the fixture's plugin dependencies like @emdashcms/plugin-color.
|
* not the fixture's plugin dependencies like @emdash-cms/plugin-color.
|
||||||
*/
|
*/
|
||||||
async function ensureFixtureDepsBuilt(): Promise<void> {
|
async function ensureFixtureDepsBuilt(): Promise<void> {
|
||||||
const colorDist = join(ROOT, "packages/plugins/color/dist/index.mjs");
|
const colorDist = join(ROOT, "packages/plugins/color/dist/index.mjs");
|
||||||
|
|||||||
@@ -6,12 +6,12 @@
|
|||||||
"description": "Agent-portable reimplementation of WordPress on Astro",
|
"description": "Agent-portable reimplementation of WordPress on Astro",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"typecheck": "pnpm run --filter './packages/**' typecheck",
|
"typecheck": "pnpm run --filter './packages/**' typecheck",
|
||||||
"typecheck:demos": "pnpm run --workspace-concurrency=1 --filter './demos/*' --filter '!@emdashcms/demo-cloudflare' typecheck",
|
"typecheck:demos": "pnpm run --workspace-concurrency=1 --filter './demos/*' --filter '!@emdash-cms/demo-cloudflare' typecheck",
|
||||||
"typecheck:templates": "pnpm run --workspace-concurrency=1 --filter './templates/*' typecheck",
|
"typecheck:templates": "pnpm run --workspace-concurrency=1 --filter './templates/*' typecheck",
|
||||||
"check": "pnpm run typecheck && pnpm run --filter './packages/*' check",
|
"check": "pnpm run typecheck && pnpm run --filter './packages/*' check",
|
||||||
"test": "pnpm run --filter './packages/*' test",
|
"test": "pnpm run --filter './packages/*' test",
|
||||||
"test:unit": "pnpm run --filter emdash --filter @emdashcms/auth --filter @emdashcms/blocks --filter @emdashcms/gutenberg-to-portable-text --filter @emdashcms/marketplace test",
|
"test:unit": "pnpm run --filter emdash --filter @emdash-cms/auth --filter @emdash-cms/blocks --filter @emdash-cms/gutenberg-to-portable-text --filter @emdash-cms/marketplace test",
|
||||||
"test:browser": "pnpm run --filter @emdashcms/admin test",
|
"test:browser": "pnpm run --filter @emdash-cms/admin test",
|
||||||
"test:e2e": "playwright test",
|
"test:e2e": "playwright test",
|
||||||
"test:e2e:ui": "playwright test --ui",
|
"test:e2e:ui": "playwright test --ui",
|
||||||
"build": "pnpm run --filter './packages/**' build",
|
"build": "pnpm run --filter './packages/**' build",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@emdashcms/admin",
|
"name": "@emdash-cms/admin",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"description": "Admin UI for EmDash CMS",
|
"description": "Admin UI for EmDash CMS",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"@dnd-kit/core": "^6.3.1",
|
"@dnd-kit/core": "^6.3.1",
|
||||||
"@dnd-kit/sortable": "^10.0.0",
|
"@dnd-kit/sortable": "^10.0.0",
|
||||||
"@dnd-kit/utilities": "^3.2.2",
|
"@dnd-kit/utilities": "^3.2.2",
|
||||||
"@emdashcms/blocks": "workspace:*",
|
"@emdash-cms/blocks": "workspace:*",
|
||||||
"@floating-ui/react": "^0.27.16",
|
"@floating-ui/react": "^0.27.16",
|
||||||
"@phosphor-icons/react": "catalog:",
|
"@phosphor-icons/react": "catalog:",
|
||||||
"@tanstack/react-query": "catalog:",
|
"@tanstack/react-query": "catalog:",
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import { useHotkeys } from "react-hotkeys-hook";
|
|||||||
import { apiFetch } from "../lib/api/client";
|
import { apiFetch } from "../lib/api/client";
|
||||||
import { useCurrentUser } from "../lib/api/current-user";
|
import { useCurrentUser } from "../lib/api/current-user";
|
||||||
|
|
||||||
// Role levels (matching @emdashcms/auth)
|
// Role levels (matching @emdash-cms/auth)
|
||||||
const ROLE_ADMIN = 50;
|
const ROLE_ADMIN = 50;
|
||||||
const ROLE_EDITOR = 40;
|
const ROLE_EDITOR = 40;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Input, Switch } from "@cloudflare/kumo";
|
import { Input, Switch } from "@cloudflare/kumo";
|
||||||
import type { Element } from "@emdashcms/blocks";
|
import type { Element } from "@emdash-cms/blocks";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
interface BlockKitFieldWidgetProps {
|
interface BlockKitFieldWidgetProps {
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ import { SaveButton } from "./SaveButton";
|
|||||||
import { SeoPanel } from "./SeoPanel";
|
import { SeoPanel } from "./SeoPanel";
|
||||||
import { TaxonomySidebar } from "./TaxonomySidebar";
|
import { TaxonomySidebar } from "./TaxonomySidebar";
|
||||||
|
|
||||||
// Editor role level (40) from @emdashcms/auth
|
// Editor role level (40) from @emdash-cms/auth
|
||||||
const ROLE_EDITOR = 40;
|
const ROLE_EDITOR = 40;
|
||||||
|
|
||||||
export interface FieldDescriptor {
|
export interface FieldDescriptor {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import {
|
|||||||
type Icon,
|
type Icon,
|
||||||
} from "@phosphor-icons/react";
|
} from "@phosphor-icons/react";
|
||||||
import { X } from "@phosphor-icons/react";
|
import { X } from "@phosphor-icons/react";
|
||||||
import type { Element } from "@emdashcms/blocks";
|
import type { Element } from "@emdash-cms/blocks";
|
||||||
import { Extension, type Range } from "@tiptap/core";
|
import { Extension, type Range } from "@tiptap/core";
|
||||||
import CharacterCount from "@tiptap/extension-character-count";
|
import CharacterCount from "@tiptap/extension-character-count";
|
||||||
import Focus from "@tiptap/extension-focus";
|
import Focus from "@tiptap/extension-focus";
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { CircleNotch, WarningCircle } from "@phosphor-icons/react";
|
import { CircleNotch, WarningCircle } from "@phosphor-icons/react";
|
||||||
import { BlockRenderer } from "@emdashcms/blocks";
|
import { BlockRenderer } from "@emdash-cms/blocks";
|
||||||
import type { Block, BlockInteraction, BlockResponse } from "@emdashcms/blocks";
|
import type { Block, BlockInteraction, BlockResponse } from "@emdash-cms/blocks";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
import { apiFetch, API_BASE } from "../lib/api/client.js";
|
import { apiFetch, API_BASE } from "../lib/api/client.js";
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { CircleNotch } from "@phosphor-icons/react";
|
import { CircleNotch } from "@phosphor-icons/react";
|
||||||
import { BlockRenderer } from "@emdashcms/blocks";
|
import { BlockRenderer } from "@emdash-cms/blocks";
|
||||||
import type { Block, BlockInteraction, BlockResponse } from "@emdashcms/blocks";
|
import type { Block, BlockInteraction, BlockResponse } from "@emdash-cms/blocks";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
import { apiFetch, API_BASE } from "../lib/api/client.js";
|
import { apiFetch, API_BASE } from "../lib/api/client.js";
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import { cn } from "../lib/utils";
|
|||||||
// Re-export for Shell.tsx and Header.tsx
|
// Re-export for Shell.tsx and Header.tsx
|
||||||
export { KumoSidebar as Sidebar, useSidebar };
|
export { KumoSidebar as Sidebar, useSidebar };
|
||||||
|
|
||||||
// Role levels (matching @emdashcms/auth)
|
// Role levels (matching @emdash-cms/auth)
|
||||||
const ROLE_ADMIN = 50;
|
const ROLE_ADMIN = 50;
|
||||||
const ROLE_EDITOR = 40;
|
const ROLE_EDITOR = 40;
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import {
|
|||||||
Cube,
|
Cube,
|
||||||
ListBullets,
|
ListBullets,
|
||||||
} from "@phosphor-icons/react";
|
} from "@phosphor-icons/react";
|
||||||
import type { Element } from "@emdashcms/blocks";
|
import type { Element } from "@emdash-cms/blocks";
|
||||||
import { Node, mergeAttributes } from "@tiptap/core";
|
import { Node, mergeAttributes } from "@tiptap/core";
|
||||||
import type { NodeViewProps } from "@tiptap/react";
|
import type { NodeViewProps } from "@tiptap/react";
|
||||||
import { ReactNodeViewRenderer, NodeViewWrapper } from "@tiptap/react";
|
import { ReactNodeViewRenderer, NodeViewWrapper } from "@tiptap/react";
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Base API client configuration and shared types
|
* Base API client configuration and shared types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Element } from "@emdashcms/blocks";
|
import type { Element } from "@emdash-cms/blocks";
|
||||||
|
|
||||||
export const API_BASE = "/_emdash/api";
|
export const API_BASE = "/_emdash/api";
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ export interface AdminManifest {
|
|||||||
{
|
{
|
||||||
name?: string;
|
name?: string;
|
||||||
version?: string;
|
version?: string;
|
||||||
/** Package name for dynamic import (e.g., "@emdashcms/plugin-audit-log") */
|
/** Package name for dynamic import (e.g., "@emdash-cms/plugin-audit-log") */
|
||||||
package?: string;
|
package?: string;
|
||||||
/** Whether the plugin is enabled */
|
/** Whether the plugin is enabled */
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
@@ -97,7 +97,7 @@ export interface AdminManifest {
|
|||||||
name: string;
|
name: string;
|
||||||
label: string;
|
label: string;
|
||||||
fieldTypes: string[];
|
fieldTypes: string[];
|
||||||
elements?: import("@emdashcms/blocks").Element[];
|
elements?: import("@emdash-cms/blocks").Element[];
|
||||||
}>;
|
}>;
|
||||||
/** Block types for Portable Text editor */
|
/** Block types for Portable Text editor */
|
||||||
portableTextBlocks?: Array<{
|
portableTextBlocks?: Array<{
|
||||||
|
|||||||
@@ -469,7 +469,7 @@ const contentEditRoute = createRoute({
|
|||||||
component: ContentEditPage,
|
component: ContentEditPage,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Editor role level from @emdashcms/auth
|
// Editor role level from @emdash-cms/auth
|
||||||
const ROLE_EDITOR = 40;
|
const ROLE_EDITOR = 40;
|
||||||
|
|
||||||
function ContentEditPage() {
|
function ContentEditPage() {
|
||||||
@@ -889,7 +889,7 @@ const commentsRoute = createRoute({
|
|||||||
component: CommentsPage,
|
component: CommentsPage,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Admin role level from @emdashcms/auth
|
// Admin role level from @emdash-cms/auth
|
||||||
const ROLE_ADMIN = 50;
|
const ROLE_ADMIN = 50;
|
||||||
|
|
||||||
function CommentsPage() {
|
function CommentsPage() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@emdashcms/auth",
|
"name": "@emdash-cms/auth",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"description": "Passkey-first authentication for EmDash",
|
"description": "Passkey-first authentication for EmDash",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Kysely database adapter for @emdashcms/auth
|
* Kysely database adapter for @emdash-cms/auth
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Kysely, Insertable, Selectable, Updateable } from "kysely";
|
import type { Kysely, Insertable, Selectable, Updateable } from "kysely";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Configuration schema for @emdashcms/auth
|
* Configuration schema for @emdash-cms/auth
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @emdashcms/auth - Passkey-first authentication for EmDash
|
* @emdash-cms/auth - Passkey-first authentication for EmDash
|
||||||
*
|
*
|
||||||
* Email is now handled by the plugin email pipeline (see PLUGIN-EMAIL.md).
|
* Email is now handled by the plugin email pipeline (see PLUGIN-EMAIL.md).
|
||||||
* Auth functions accept an optional `email` send function instead of a
|
* Auth functions accept an optional `email` send function instead of a
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```ts
|
* ```ts
|
||||||
* import { auth } from '@emdashcms/auth'
|
* import { auth } from '@emdash-cms/auth'
|
||||||
*
|
*
|
||||||
* export default defineConfig({
|
* export default defineConfig({
|
||||||
* integrations: [
|
* integrations: [
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Core types for @emdashcms/auth
|
* Core types for @emdash-cms/auth
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@emdashcms/blocks",
|
"name": "@emdash-cms/blocks",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"description": "Declarative plugin UI blocks for EmDash CMS",
|
"description": "Declarative plugin UI blocks for EmDash CMS",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@emdashcms/blocks-playground",
|
"name": "@emdash-cms/blocks-playground",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emdashcms/blocks": "workspace:*",
|
"@emdash-cms/blocks": "workspace:*",
|
||||||
"@cloudflare/kumo": "^1.1.0",
|
"@cloudflare/kumo": "^1.1.0",
|
||||||
"@phosphor-icons/react": "catalog:",
|
"@phosphor-icons/react": "catalog:",
|
||||||
"react": "catalog:",
|
"react": "catalog:",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Sun, Moon, Share, Check, Trash, CaretDown, Warning, Plus } from "@phosphor-icons/react";
|
import { Sun, Moon, Share, Check, Trash, CaretDown, Warning, Plus } from "@phosphor-icons/react";
|
||||||
import { BlockRenderer, validateBlocks } from "@emdashcms/blocks";
|
import { BlockRenderer, validateBlocks } from "@emdash-cms/blocks";
|
||||||
import type { Block, BlockInteraction } from "@emdashcms/blocks";
|
import type { Block, BlockInteraction } from "@emdash-cms/blocks";
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
|
|
||||||
import { blockCatalog } from "./block-defaults";
|
import { blockCatalog } from "./block-defaults";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Block } from "@emdashcms/blocks";
|
import type { Block } from "@emdash-cms/blocks";
|
||||||
|
|
||||||
interface BlockCatalogEntry {
|
interface BlockCatalogEntry {
|
||||||
type: Block["type"];
|
type: Block["type"];
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Block, ChartSeries } from "@emdashcms/blocks";
|
import type { Block, ChartSeries } from "@emdash-cms/blocks";
|
||||||
|
|
||||||
export interface Template {
|
export interface Template {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -508,7 +508,7 @@ export const templates: Template[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "code",
|
type: "code",
|
||||||
code: 'import { blocks } from "@emdashcms/blocks";\n\nconst page = [\n\tblocks.header("Hello"),\n\tblocks.section("Welcome to EmDash."),\n];',
|
code: 'import { blocks } from "@emdash-cms/blocks";\n\nconst page = [\n\tblocks.header("Hello"),\n\tblocks.section("Welcome to EmDash."),\n];',
|
||||||
language: "ts",
|
language: "ts",
|
||||||
},
|
},
|
||||||
{ type: "divider" },
|
{ type: "divider" },
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ export default defineConfig({
|
|||||||
plugins: [react(), tailwindcss()],
|
plugins: [react(), tailwindcss()],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
// Resolve @emdashcms/blocks from source for HMR
|
// Resolve @emdash-cms/blocks from source for HMR
|
||||||
"@emdashcms/blocks": new URL("../src/index.ts", import.meta.url).pathname,
|
"@emdash-cms/blocks": new URL("../src/index.ts", import.meta.url).pathname,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Server-safe exports for @emdashcms/blocks.
|
* Server-safe exports for @emdash-cms/blocks.
|
||||||
*
|
*
|
||||||
* Use this entry point in plugin route handlers and other server-side code
|
* Use this entry point in plugin route handlers and other server-side code
|
||||||
* that doesn't have React available. Provides builders, validation, and types
|
* that doesn't have React available. Provides builders, validation, and types
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@emdashcms/cloudflare",
|
"name": "@emdash-cms/cloudflare",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"description": "Cloudflare adapters for EmDash - D1, R2, Access, and Worker Loader sandbox",
|
"description": "Cloudflare adapters for EmDash - D1, R2, Access, and Worker Loader sandbox",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* This module is loaded at runtime when authenticating requests.
|
* This module is loaded at runtime when authenticating requests.
|
||||||
* It exports the `authenticate` function required by the auth provider interface.
|
* It exports the `authenticate` function required by the auth provider interface.
|
||||||
*
|
*
|
||||||
* For config-time usage, import { access } from "@emdashcms/cloudflare" instead.
|
* For config-time usage, import { access } from "@emdash-cms/cloudflare" instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { authenticate } from "./cloudflare-access.js";
|
export { authenticate } from "./cloudflare-access.js";
|
||||||
|
|||||||
6
packages/cloudflare/src/cache/config.ts
vendored
6
packages/cloudflare/src/cache/config.ts
vendored
@@ -4,7 +4,7 @@
|
|||||||
* This is the config-time helper. Import it in your astro.config.mjs:
|
* This is the config-time helper. Import it in your astro.config.mjs:
|
||||||
*
|
*
|
||||||
* ```ts
|
* ```ts
|
||||||
* import { cloudflareCache } from "@emdashcms/cloudflare";
|
* import { cloudflareCache } from "@emdash-cms/cloudflare";
|
||||||
*
|
*
|
||||||
* export default defineConfig({
|
* export default defineConfig({
|
||||||
* experimental: {
|
* experimental: {
|
||||||
@@ -49,7 +49,7 @@ export type { CloudflareCacheConfig };
|
|||||||
* ```ts
|
* ```ts
|
||||||
* import { defineConfig } from "astro/config";
|
* import { defineConfig } from "astro/config";
|
||||||
* import cloudflare from "@astrojs/cloudflare";
|
* import cloudflare from "@astrojs/cloudflare";
|
||||||
* import { cloudflareCache } from "@emdashcms/cloudflare";
|
* import { cloudflareCache } from "@emdash-cms/cloudflare";
|
||||||
*
|
*
|
||||||
* export default defineConfig({
|
* export default defineConfig({
|
||||||
* adapter: cloudflare(),
|
* adapter: cloudflare(),
|
||||||
@@ -75,7 +75,7 @@ export function cloudflareCache(
|
|||||||
): CacheProviderConfig<CloudflareCacheConfig> {
|
): CacheProviderConfig<CloudflareCacheConfig> {
|
||||||
return {
|
return {
|
||||||
// Resolved by Vite/Astro at build time — points to the runtime module
|
// Resolved by Vite/Astro at build time — points to the runtime module
|
||||||
entrypoint: "@emdashcms/cloudflare/cache",
|
entrypoint: "@emdash-cms/cloudflare/cache",
|
||||||
config,
|
config,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
4
packages/cloudflare/src/cache/runtime.ts
vendored
4
packages/cloudflare/src/cache/runtime.ts
vendored
@@ -15,7 +15,7 @@
|
|||||||
* headers from the response that next() returns.
|
* headers from the response that next() returns.
|
||||||
*
|
*
|
||||||
* Do NOT import this at config time. Use cloudflareCache() from
|
* Do NOT import this at config time. Use cloudflareCache() from
|
||||||
* "@emdashcms/cloudflare" or "@emdashcms/cloudflare/cache/config" instead.
|
* "@emdash-cms/cloudflare" or "@emdash-cms/cloudflare/cache/config" instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { CacheProviderFactory } from "astro";
|
import type { CacheProviderFactory } from "astro";
|
||||||
@@ -41,7 +41,7 @@ const SWR_REGEX = /stale-while-revalidate=(\d+)/;
|
|||||||
/** Internal headers to strip before returning responses to the client */
|
/** Internal headers to strip before returning responses to the client */
|
||||||
const INTERNAL_HEADERS = [STORED_AT_HEADER, MAX_AGE_HEADER, SWR_HEADER];
|
const INTERNAL_HEADERS = [STORED_AT_HEADER, MAX_AGE_HEADER, SWR_HEADER];
|
||||||
|
|
||||||
/** Default D1 bookmark cookie name (from @emdashcms/cloudflare d1 config) */
|
/** Default D1 bookmark cookie name (from @emdash-cms/cloudflare d1 config) */
|
||||||
const DEFAULT_BOOKMARK_COOKIE = "__ec_d1_bookmark";
|
const DEFAULT_BOOKMARK_COOKIE = "__ec_d1_bookmark";
|
||||||
|
|
||||||
export interface CloudflareCacheConfig {
|
export interface CloudflareCacheConfig {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* Loaded at runtime via virtual module when database queries are needed.
|
* Loaded at runtime via virtual module when database queries are needed.
|
||||||
*
|
*
|
||||||
* This module imports directly from cloudflare:workers to access the D1 binding.
|
* This module imports directly from cloudflare:workers to access the D1 binding.
|
||||||
* Do NOT import this at config time - use { d1 } from "@emdashcms/cloudflare" instead.
|
* Do NOT import this at config time - use { d1 } from "@emdash-cms/cloudflare" instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { env } from "cloudflare:workers";
|
import { env } from "cloudflare:workers";
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
* @example
|
* @example
|
||||||
* ```ts
|
* ```ts
|
||||||
* // src/middleware.ts (in the preview Worker)
|
* // src/middleware.ts (in the preview Worker)
|
||||||
* import { createPreviewMiddleware } from "@emdashcms/cloudflare/db/do";
|
* import { createPreviewMiddleware } from "@emdash-cms/cloudflare/db/do";
|
||||||
*
|
*
|
||||||
* export const onRequest = createPreviewMiddleware({
|
* export const onRequest = createPreviewMiddleware({
|
||||||
* binding: "PREVIEW_DB",
|
* binding: "PREVIEW_DB",
|
||||||
|
|||||||
@@ -320,7 +320,7 @@ export const onRequest = defineMiddleware(async (context, next) => {
|
|||||||
|
|
||||||
// Stash the DO database and user on locals so downstream middleware
|
// Stash the DO database and user on locals so downstream middleware
|
||||||
// (runtime init, request-context) can use them. We can't use ALS directly
|
// (runtime init, request-context) can use them. We can't use ALS directly
|
||||||
// because this middleware is in @emdashcms/cloudflare and resolves to a
|
// because this middleware is in @emdash-cms/cloudflare and resolves to a
|
||||||
// different AsyncLocalStorage instance than the emdash core package
|
// different AsyncLocalStorage instance than the emdash core package
|
||||||
// (workerd loads dist modules separately from Vite's source modules).
|
// (workerd loads dist modules separately from Vite's source modules).
|
||||||
// The request-context middleware (same module context as the loader)
|
// The request-context middleware (same module context as the loader)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @emdashcms/cloudflare
|
* @emdash-cms/cloudflare
|
||||||
*
|
*
|
||||||
* Cloudflare adapters for EmDash:
|
* Cloudflare adapters for EmDash:
|
||||||
* - D1 database adapter
|
* - D1 database adapter
|
||||||
@@ -12,13 +12,13 @@
|
|||||||
*
|
*
|
||||||
* For runtime exports (PluginBridge, authenticate), import from the specific
|
* For runtime exports (PluginBridge, authenticate), import from the specific
|
||||||
* runtime entrypoints:
|
* runtime entrypoints:
|
||||||
* - @emdashcms/cloudflare/sandbox (PluginBridge, createSandboxRunner)
|
* - @emdash-cms/cloudflare/sandbox (PluginBridge, createSandboxRunner)
|
||||||
* - @emdashcms/cloudflare/auth (authenticate)
|
* - @emdash-cms/cloudflare/auth (authenticate)
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```ts
|
* ```ts
|
||||||
* import emdash from "emdash/astro";
|
* import emdash from "emdash/astro";
|
||||||
* import { d1, r2, access, sandbox } from "@emdashcms/cloudflare";
|
* import { d1, r2, access, sandbox } from "@emdash-cms/cloudflare";
|
||||||
*
|
*
|
||||||
* export default defineConfig({
|
* export default defineConfig({
|
||||||
* integrations: [
|
* integrations: [
|
||||||
@@ -160,7 +160,7 @@ export interface AccessConfig {
|
|||||||
*/
|
*/
|
||||||
export function d1(config: D1Config): DatabaseDescriptor {
|
export function d1(config: D1Config): DatabaseDescriptor {
|
||||||
return {
|
return {
|
||||||
entrypoint: "@emdashcms/cloudflare/db/d1",
|
entrypoint: "@emdash-cms/cloudflare/db/d1",
|
||||||
config,
|
config,
|
||||||
type: "sqlite",
|
type: "sqlite",
|
||||||
};
|
};
|
||||||
@@ -183,7 +183,7 @@ export type { PreviewDOConfig } from "./db/do-types.js";
|
|||||||
*/
|
*/
|
||||||
export function previewDatabase(config: PreviewDOConfig): DatabaseDescriptor {
|
export function previewDatabase(config: PreviewDOConfig): DatabaseDescriptor {
|
||||||
return {
|
return {
|
||||||
entrypoint: "@emdashcms/cloudflare/db/do",
|
entrypoint: "@emdash-cms/cloudflare/db/do",
|
||||||
config,
|
config,
|
||||||
type: "sqlite",
|
type: "sqlite",
|
||||||
};
|
};
|
||||||
@@ -205,7 +205,7 @@ export function previewDatabase(config: PreviewDOConfig): DatabaseDescriptor {
|
|||||||
*/
|
*/
|
||||||
export function playgroundDatabase(config: PreviewDOConfig): DatabaseDescriptor {
|
export function playgroundDatabase(config: PreviewDOConfig): DatabaseDescriptor {
|
||||||
return {
|
return {
|
||||||
entrypoint: "@emdashcms/cloudflare/db/playground",
|
entrypoint: "@emdash-cms/cloudflare/db/playground",
|
||||||
config,
|
config,
|
||||||
type: "sqlite",
|
type: "sqlite",
|
||||||
};
|
};
|
||||||
@@ -231,7 +231,7 @@ export function playgroundDatabase(config: PreviewDOConfig): DatabaseDescriptor
|
|||||||
*/
|
*/
|
||||||
export function r2(config: R2StorageConfig): StorageDescriptor {
|
export function r2(config: R2StorageConfig): StorageDescriptor {
|
||||||
return {
|
return {
|
||||||
entrypoint: "@emdashcms/cloudflare/storage/r2",
|
entrypoint: "@emdash-cms/cloudflare/storage/r2",
|
||||||
config: { binding: config.binding, publicUrl: config.publicUrl },
|
config: { binding: config.binding, publicUrl: config.publicUrl },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -257,7 +257,7 @@ export function r2(config: R2StorageConfig): StorageDescriptor {
|
|||||||
export function access(config: AccessConfig): AuthDescriptor {
|
export function access(config: AccessConfig): AuthDescriptor {
|
||||||
return {
|
return {
|
||||||
type: "cloudflare-access",
|
type: "cloudflare-access",
|
||||||
entrypoint: "@emdashcms/cloudflare/auth",
|
entrypoint: "@emdash-cms/cloudflare/auth",
|
||||||
config,
|
config,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -274,7 +274,7 @@ export function access(config: AccessConfig): AuthDescriptor {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export function sandbox(): string {
|
export function sandbox(): string {
|
||||||
return "@emdashcms/cloudflare/sandbox";
|
return "@emdash-cms/cloudflare/sandbox";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-export media providers (config-time)
|
// Re-export media providers (config-time)
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ const IMAGES_ICON = `data:image/svg+xml,${encodeURIComponent('<svg xmlns="http:/
|
|||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```ts
|
* ```ts
|
||||||
* import { cloudflareImages } from "@emdashcms/cloudflare";
|
* import { cloudflareImages } from "@emdash-cms/cloudflare";
|
||||||
*
|
*
|
||||||
* emdash({
|
* emdash({
|
||||||
* mediaProviders: [
|
* mediaProviders: [
|
||||||
@@ -102,7 +102,7 @@ export function cloudflareImages(
|
|||||||
id: "cloudflare-images",
|
id: "cloudflare-images",
|
||||||
name: "Cloudflare Images",
|
name: "Cloudflare Images",
|
||||||
icon: IMAGES_ICON,
|
icon: IMAGES_ICON,
|
||||||
entrypoint: "@emdashcms/cloudflare/media/images-runtime",
|
entrypoint: "@emdash-cms/cloudflare/media/images-runtime",
|
||||||
capabilities: {
|
capabilities: {
|
||||||
browse: true,
|
browse: true,
|
||||||
search: false, // Images API doesn't support search
|
search: false, // Images API doesn't support search
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ const STREAM_ICON = `data:image/svg+xml,${encodeURIComponent('<svg xmlns="http:/
|
|||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```ts
|
* ```ts
|
||||||
* import { cloudflareStream } from "@emdashcms/cloudflare";
|
* import { cloudflareStream } from "@emdash-cms/cloudflare";
|
||||||
*
|
*
|
||||||
* emdash({
|
* emdash({
|
||||||
* mediaProviders: [
|
* mediaProviders: [
|
||||||
@@ -106,7 +106,7 @@ export function cloudflareStream(
|
|||||||
id: "cloudflare-stream",
|
id: "cloudflare-stream",
|
||||||
name: "Cloudflare Stream",
|
name: "Cloudflare Stream",
|
||||||
icon: STREAM_ICON,
|
icon: STREAM_ICON,
|
||||||
entrypoint: "@emdashcms/cloudflare/media/stream-runtime",
|
entrypoint: "@emdash-cms/cloudflare/media/stream-runtime",
|
||||||
capabilities: {
|
capabilities: {
|
||||||
browse: true,
|
browse: true,
|
||||||
search: true,
|
search: true,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
* ```typescript
|
* ```typescript
|
||||||
* // astro.config.mjs
|
* // astro.config.mjs
|
||||||
* import emdash from "emdash/astro";
|
* import emdash from "emdash/astro";
|
||||||
* import { vectorizeSearch } from "@emdashcms/cloudflare/plugins";
|
* import { vectorizeSearch } from "@emdash-cms/cloudflare/plugins";
|
||||||
*
|
*
|
||||||
* export default defineConfig({
|
* export default defineConfig({
|
||||||
* integrations: [
|
* integrations: [
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* This module is loaded at runtime when plugins need to be sandboxed.
|
* This module is loaded at runtime when plugins need to be sandboxed.
|
||||||
* It imports cloudflare:workers and should NOT be imported at config time.
|
* It imports cloudflare:workers and should NOT be imported at config time.
|
||||||
*
|
*
|
||||||
* For config-time usage, import { sandbox } from "@emdashcms/cloudflare" instead.
|
* For config-time usage, import { sandbox } from "@emdash-cms/cloudflare" instead.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
* This module imports directly from cloudflare:workers to access
|
* This module imports directly from cloudflare:workers to access
|
||||||
* the LOADER binding and PluginBridge export. It's only loaded
|
* the LOADER binding and PluginBridge export. It's only loaded
|
||||||
* when the user configures `sandboxRunner: "@emdashcms/cloudflare/sandbox"`.
|
* when the user configures `sandboxRunner: "@emdash-cms/cloudflare/sandbox"`.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export function generatePluginWrapper(manifest: PluginManifest, options?: Wrappe
|
|||||||
return `
|
return `
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Sandboxed Plugin Wrapper
|
// Sandboxed Plugin Wrapper
|
||||||
// Generated by @emdashcms/cloudflare
|
// Generated by @emdash-cms/cloudflare
|
||||||
// Plugin: ${sanitizeComment(manifest.id)}@${sanitizeComment(manifest.version)}
|
// Plugin: ${sanitizeComment(manifest.id)}@${sanitizeComment(manifest.version)}
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* This avoids the AWS SDK overhead and works with the native R2 API.
|
* This avoids the AWS SDK overhead and works with the native R2 API.
|
||||||
*
|
*
|
||||||
* This module imports directly from cloudflare:workers to access R2 bindings.
|
* This module imports directly from cloudflare:workers to access R2 bindings.
|
||||||
* Do NOT import this at config time - use { r2 } from "@emdashcms/cloudflare" instead.
|
* Do NOT import this at config time - use { r2 } from "@emdash-cms/cloudflare" instead.
|
||||||
*
|
*
|
||||||
* For Astro 6 / Cloudflare adapter v13+:
|
* For Astro 6 / Cloudflare adapter v13+:
|
||||||
* - Bindings are accessed via `import { env } from 'cloudflare:workers'`
|
* - Bindings are accessed via `import { env } from 'cloudflare:workers'`
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ describe("previewDatabase()", () => {
|
|||||||
it("returns a sqlite DatabaseDescriptor with the DO entrypoint", () => {
|
it("returns a sqlite DatabaseDescriptor with the DO entrypoint", () => {
|
||||||
const result = previewDatabase({ binding: "PREVIEW_DB" });
|
const result = previewDatabase({ binding: "PREVIEW_DB" });
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
entrypoint: "@emdashcms/cloudflare/db/do",
|
entrypoint: "@emdash-cms/cloudflare/db/do",
|
||||||
config: { binding: "PREVIEW_DB" },
|
config: { binding: "PREVIEW_DB" },
|
||||||
type: "sqlite",
|
type: "sqlite",
|
||||||
});
|
});
|
||||||
@@ -22,7 +22,7 @@ describe("playgroundDatabase()", () => {
|
|||||||
it("returns a sqlite DatabaseDescriptor with the playground entrypoint", () => {
|
it("returns a sqlite DatabaseDescriptor with the playground entrypoint", () => {
|
||||||
const result = playgroundDatabase({ binding: "PLAYGROUND_DB" });
|
const result = playgroundDatabase({ binding: "PLAYGROUND_DB" });
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
entrypoint: "@emdashcms/cloudflare/db/playground",
|
entrypoint: "@emdash-cms/cloudflare/db/playground",
|
||||||
config: { binding: "PLAYGROUND_DB" },
|
config: { binding: "PLAYGROUND_DB" },
|
||||||
type: "sqlite",
|
type: "sqlite",
|
||||||
});
|
});
|
||||||
|
|||||||
4
packages/core/locals.d.ts
vendored
4
packages/core/locals.d.ts
vendored
@@ -5,7 +5,7 @@
|
|||||||
* Referenced via triple-slash directive in the generated emdash-env.d.ts.
|
* Referenced via triple-slash directive in the generated emdash-env.d.ts.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { User } from "@emdashcms/auth";
|
import type { User } from "@emdash-cms/auth";
|
||||||
|
|
||||||
import type { EmDashHandlers, EmDashManifest } from "./dist/types.d.mts";
|
import type { EmDashHandlers, EmDashManifest } from "./dist/types.d.mts";
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ declare global {
|
|||||||
/**
|
/**
|
||||||
* Per-session Durable Object database for playground mode.
|
* Per-session Durable Object database for playground mode.
|
||||||
*
|
*
|
||||||
* Set by the playground middleware (@emdashcms/cloudflare). Read by
|
* Set by the playground middleware (@emdash-cms/cloudflare). Read by
|
||||||
* the runtime middleware and request-context middleware to set the
|
* the runtime middleware and request-context middleware to set the
|
||||||
* database in ALS for the current request.
|
* database in ALS for the current request.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -152,9 +152,9 @@
|
|||||||
"test": "vitest"
|
"test": "vitest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emdashcms/admin": "workspace:*",
|
"@emdash-cms/admin": "workspace:*",
|
||||||
"@emdashcms/auth": "workspace:*",
|
"@emdash-cms/auth": "workspace:*",
|
||||||
"@emdashcms/gutenberg-to-portable-text": "workspace:*",
|
"@emdash-cms/gutenberg-to-portable-text": "workspace:*",
|
||||||
"@floating-ui/react": "^0.27.16",
|
"@floating-ui/react": "^0.27.16",
|
||||||
"@modelcontextprotocol/sdk": "^1.26.0",
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
||||||
"@portabletext/toolkit": "^5.0.1",
|
"@portabletext/toolkit": "^5.0.1",
|
||||||
@@ -205,7 +205,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@apidevtools/swagger-parser": "^12.1.0",
|
"@apidevtools/swagger-parser": "^12.1.0",
|
||||||
"@arethetypeswrong/cli": "catalog:",
|
"@arethetypeswrong/cli": "catalog:",
|
||||||
"@emdashcms/blocks": "workspace:*",
|
"@emdash-cms/blocks": "workspace:*",
|
||||||
"@types/better-sqlite3": "^7.6.12",
|
"@types/better-sqlite3": "^7.6.12",
|
||||||
"@types/pg": "^8.16.0",
|
"@types/pg": "^8.16.0",
|
||||||
"@types/sanitize-html": "^2.16.0",
|
"@types/sanitize-html": "^2.16.0",
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* Authorization helpers for API routes
|
* Authorization helpers for API routes
|
||||||
*
|
*
|
||||||
* Thin wrappers around @emdashcms/auth RBAC that return HTTP responses.
|
* Thin wrappers around @emdash-cms/auth RBAC that return HTTP responses.
|
||||||
* Auth middleware handles authentication; these handle authorization.
|
* Auth middleware handles authentication; these handle authorization.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Permission, RoleLevel } from "@emdashcms/auth";
|
import type { Permission, RoleLevel } from "@emdash-cms/auth";
|
||||||
import { hasPermission, canActOnOwn } from "@emdashcms/auth";
|
import { hasPermission, canActOnOwn } from "@emdash-cms/auth";
|
||||||
|
|
||||||
import { apiError } from "./error.js";
|
import { apiError } from "./error.js";
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
* The user opens a browser, logs in, enters the code, and the CLI gets
|
* The user opens a browser, logs in, enters the code, and the CLI gets
|
||||||
* an access + refresh token pair.
|
* an access + refresh token pair.
|
||||||
*
|
*
|
||||||
* Uses arctic for code generation and @emdashcms/auth for token utilities.
|
* Uses arctic for code generation and @emdash-cms/auth for token utilities.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { clampScopes } from "@emdashcms/auth";
|
import { clampScopes } from "@emdash-cms/auth";
|
||||||
import type { RoleLevel } from "@emdashcms/auth";
|
import type { RoleLevel } from "@emdash-cms/auth";
|
||||||
import { generateCodeVerifier } from "arctic";
|
import { generateCodeVerifier } from "arctic";
|
||||||
import type { Kysely } from "kysely";
|
import type { Kysely } from "kysely";
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
* Implements the server side of the authorization code grant for MCP clients
|
* Implements the server side of the authorization code grant for MCP clients
|
||||||
* (Claude Desktop, VS Code, etc.) per the MCP authorization spec (draft).
|
* (Claude Desktop, VS Code, etc.) per the MCP authorization spec (draft).
|
||||||
*
|
*
|
||||||
* Uses arctic for PKCE challenge generation and @emdashcms/auth for token
|
* Uses arctic for PKCE challenge generation and @emdash-cms/auth for token
|
||||||
* utilities. Token infrastructure is shared with the device flow.
|
* utilities. Token infrastructure is shared with the device flow.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { clampScopes, computeS256Challenge } from "@emdashcms/auth";
|
import { clampScopes, computeS256Challenge } from "@emdash-cms/auth";
|
||||||
import type { RoleLevel } from "@emdashcms/auth";
|
import type { RoleLevel } from "@emdash-cms/auth";
|
||||||
import { generateCodeVerifier } from "arctic";
|
import { generateCodeVerifier } from "arctic";
|
||||||
import type { Kysely } from "kysely";
|
import type { Kysely } from "kysely";
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* role and reject disabled users.
|
* role and reject disabled users.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { toRoleLevel, type RoleLevel } from "@emdashcms/auth";
|
import { toRoleLevel, type RoleLevel } from "@emdash-cms/auth";
|
||||||
import type { Kysely } from "kysely";
|
import type { Kysely } from "kysely";
|
||||||
|
|
||||||
import type { Database } from "../../database/types.js";
|
import type { Database } from "../../database/types.js";
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { z } from "zod";
|
|||||||
import { roleLevel } from "./common.js";
|
import { roleLevel } from "./common.js";
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// WebAuthn credential schemas (matching @emdashcms/auth/passkey types)
|
// WebAuthn credential schemas (matching @emdash-cms/auth/passkey types)
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
const authenticatorTransport = z.enum(["usb", "nfc", "ble", "internal", "hybrid"]);
|
const authenticatorTransport = z.enum(["usb", "nfc", "ble", "internal", "hybrid"]);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* Astro integration for EmDash CMS (build-time only)
|
* Astro integration for EmDash CMS (build-time only)
|
||||||
*
|
*
|
||||||
* For runtime APIs (loader, query functions, dialects), import from "emdash" directly.
|
* For runtime APIs (loader, query functions, dialects), import from "emdash" directly.
|
||||||
* For Cloudflare-specific adapters (d1, r2, access), import from "@emdashcms/cloudflare".
|
* For Cloudflare-specific adapters (d1, r2, access), import from "@emdash-cms/cloudflare".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Locals types (for typing Astro.locals in API routes)
|
// Locals types (for typing Astro.locals in API routes)
|
||||||
@@ -17,7 +17,7 @@ export type {
|
|||||||
} from "./types.js";
|
} from "./types.js";
|
||||||
|
|
||||||
// Storage adapters (for integration config)
|
// Storage adapters (for integration config)
|
||||||
// Note: For R2 bindings, use `r2()` from `@emdashcms/cloudflare`
|
// Note: For R2 bindings, use `r2()` from `@emdash-cms/cloudflare`
|
||||||
export { local, s3 } from "./storage/index.js";
|
export { local, s3 } from "./storage/index.js";
|
||||||
export type { StorageDescriptor, LocalStorageConfig, S3StorageConfig } from "./storage/index.js";
|
export type { StorageDescriptor, LocalStorageConfig, S3StorageConfig } from "./storage/index.js";
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export interface PluginDescriptor<TOptions = Record<string, unknown>> {
|
|||||||
id: string;
|
id: string;
|
||||||
/** Plugin version (semver) */
|
/** Plugin version (semver) */
|
||||||
version: string;
|
version: string;
|
||||||
/** Module specifier to import (e.g., "@emdashcms/plugin-api-test") */
|
/** Module specifier to import (e.g., "@emdash-cms/plugin-api-test") */
|
||||||
entrypoint: string;
|
entrypoint: string;
|
||||||
/**
|
/**
|
||||||
* Options to pass to createPlugin(). Native format only.
|
* Options to pass to createPlugin(). Native format only.
|
||||||
@@ -87,7 +87,7 @@ export interface PluginDescriptor<TOptions = Record<string, unknown>> {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
format?: "standard" | "native";
|
format?: "standard" | "native";
|
||||||
/** Admin UI module specifier (e.g., "@emdashcms/plugin-audit-log/admin") */
|
/** Admin UI module specifier (e.g., "@emdash-cms/plugin-audit-log/admin") */
|
||||||
adminEntry?: string;
|
adminEntry?: string;
|
||||||
/** Module specifier for site-side Astro rendering components (must export `blockComponents`) */
|
/** Module specifier for site-side Astro rendering components (must export `blockComponents`) */
|
||||||
componentsEntry?: string;
|
componentsEntry?: string;
|
||||||
@@ -153,8 +153,8 @@ export interface EmDashConfig {
|
|||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```ts
|
* ```ts
|
||||||
* import { auditLogPlugin } from "@emdashcms/plugin-audit-log";
|
* import { auditLogPlugin } from "@emdash-cms/plugin-audit-log";
|
||||||
* import { webhookNotifierPlugin } from "@emdashcms/plugin-webhook-notifier";
|
* import { webhookNotifierPlugin } from "@emdash-cms/plugin-webhook-notifier";
|
||||||
*
|
*
|
||||||
* emdash({
|
* emdash({
|
||||||
* plugins: [
|
* plugins: [
|
||||||
@@ -178,7 +178,7 @@ export interface EmDashConfig {
|
|||||||
* emdash({
|
* emdash({
|
||||||
* plugins: [trustedPlugin()], // runs in host
|
* plugins: [trustedPlugin()], // runs in host
|
||||||
* sandboxed: [untrustedPlugin()], // runs in isolate
|
* sandboxed: [untrustedPlugin()], // runs in isolate
|
||||||
* sandboxRunner: "@emdashcms/sandbox-cloudflare",
|
* sandboxRunner: "@emdash-cms/sandbox-cloudflare",
|
||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
@@ -190,7 +190,7 @@ export interface EmDashConfig {
|
|||||||
* @example
|
* @example
|
||||||
* ```ts
|
* ```ts
|
||||||
* emdash({
|
* emdash({
|
||||||
* sandboxRunner: "@emdashcms/sandbox-cloudflare",
|
* sandboxRunner: "@emdash-cms/sandbox-cloudflare",
|
||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
@@ -200,13 +200,13 @@ export interface EmDashConfig {
|
|||||||
* Authentication configuration
|
* Authentication configuration
|
||||||
*
|
*
|
||||||
* Use an auth adapter function from a platform package:
|
* Use an auth adapter function from a platform package:
|
||||||
* - `access({ teamDomain: "..." })` from `@emdashcms/cloudflare`
|
* - `access({ teamDomain: "..." })` from `@emdash-cms/cloudflare`
|
||||||
*
|
*
|
||||||
* When an external auth provider is configured, passkey auth is disabled.
|
* When an external auth provider is configured, passkey auth is disabled.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```ts
|
* ```ts
|
||||||
* import { access } from "@emdashcms/cloudflare";
|
* import { access } from "@emdash-cms/cloudflare";
|
||||||
*
|
*
|
||||||
* emdash({
|
* emdash({
|
||||||
* auth: access({
|
* auth: access({
|
||||||
@@ -256,7 +256,7 @@ export interface EmDashConfig {
|
|||||||
* ```ts
|
* ```ts
|
||||||
* emdash({
|
* emdash({
|
||||||
* marketplace: "https://marketplace.emdashcms.com",
|
* marketplace: "https://marketplace.emdashcms.com",
|
||||||
* sandboxRunner: "@emdashcms/sandbox-cloudflare",
|
* sandboxRunner: "@emdash-cms/sandbox-cloudflare",
|
||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
@@ -273,7 +273,7 @@ export interface EmDashConfig {
|
|||||||
*
|
*
|
||||||
* Setup and auth middleware are skipped (the playground handles both).
|
* Setup and auth middleware are skipped (the playground handles both).
|
||||||
*
|
*
|
||||||
* Requires `@emdashcms/cloudflare` as a dependency and a DO binding
|
* Requires `@emdash-cms/cloudflare` as a dependency and a DO binding
|
||||||
* in wrangler.jsonc.
|
* in wrangler.jsonc.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
@@ -281,7 +281,7 @@ export interface EmDashConfig {
|
|||||||
* emdash({
|
* emdash({
|
||||||
* database: playgroundDatabase({ binding: "PLAYGROUND_DB" }),
|
* database: playgroundDatabase({ binding: "PLAYGROUND_DB" }),
|
||||||
* playground: {
|
* playground: {
|
||||||
* middlewareEntrypoint: "@emdashcms/cloudflare/db/playground-middleware",
|
* middlewareEntrypoint: "@emdash-cms/cloudflare/db/playground-middleware",
|
||||||
* },
|
* },
|
||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
@@ -300,8 +300,8 @@ export interface EmDashConfig {
|
|||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```ts
|
* ```ts
|
||||||
* import { cloudflareImages, cloudflareStream } from "@emdashcms/cloudflare";
|
* import { cloudflareImages, cloudflareStream } from "@emdash-cms/cloudflare";
|
||||||
* import { unsplash } from "@emdashcms/provider-unsplash";
|
* import { unsplash } from "@emdash-cms/provider-unsplash";
|
||||||
*
|
*
|
||||||
* emdash({
|
* emdash({
|
||||||
* mediaProviders: [
|
* mediaProviders: [
|
||||||
|
|||||||
@@ -55,19 +55,19 @@ import {
|
|||||||
*/
|
*/
|
||||||
function resolveAdminDist(): string {
|
function resolveAdminDist(): string {
|
||||||
const require = createRequire(import.meta.url);
|
const require = createRequire(import.meta.url);
|
||||||
const adminPath = require.resolve("@emdashcms/admin");
|
const adminPath = require.resolve("@emdash-cms/admin");
|
||||||
// Return the directory containing the built package (dist/)
|
// Return the directory containing the built package (dist/)
|
||||||
return dirname(adminPath);
|
return dirname(adminPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve path to the admin package source directory.
|
* Resolve path to the admin package source directory.
|
||||||
* In dev mode, we alias @emdashcms/admin to the source so Vite processes it
|
* In dev mode, we alias @emdash-cms/admin to the source so Vite processes it
|
||||||
* directly — giving instant HMR instead of requiring a rebuild + restart.
|
* directly — giving instant HMR instead of requiring a rebuild + restart.
|
||||||
*/
|
*/
|
||||||
function resolveAdminSource(): string | undefined {
|
function resolveAdminSource(): string | undefined {
|
||||||
const require = createRequire(import.meta.url);
|
const require = createRequire(import.meta.url);
|
||||||
const adminPath = require.resolve("@emdashcms/admin");
|
const adminPath = require.resolve("@emdash-cms/admin");
|
||||||
// dist/index.js -> go up to package root, then into src/
|
// dist/index.js -> go up to package root, then into src/
|
||||||
const packageRoot = resolve(dirname(adminPath), "..");
|
const packageRoot = resolve(dirname(adminPath), "..");
|
||||||
const srcEntry = resolve(packageRoot, "src", "index.ts");
|
const srcEntry = resolve(packageRoot, "src", "index.ts");
|
||||||
@@ -244,16 +244,16 @@ export function createViteConfig(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
resolve: {
|
resolve: {
|
||||||
dedupe: ["@emdashcms/admin", "react", "react-dom"],
|
dedupe: ["@emdash-cms/admin", "react", "react-dom"],
|
||||||
// Array form so more-specific entries are checked first.
|
// Array form so more-specific entries are checked first.
|
||||||
// The styles.css alias must come before the package alias, otherwise
|
// The styles.css alias must come before the package alias, otherwise
|
||||||
// Vite's prefix matching on "@emdashcms/admin" would resolve
|
// Vite's prefix matching on "@emdash-cms/admin" would resolve
|
||||||
// "@emdashcms/admin/styles.css" through the source directory.
|
// "@emdash-cms/admin/styles.css" through the source directory.
|
||||||
alias: [
|
alias: [
|
||||||
// CSS: always dist (pre-compiled by @tailwindcss/cli)
|
// CSS: always dist (pre-compiled by @tailwindcss/cli)
|
||||||
{ find: "@emdashcms/admin/styles.css", replacement: resolve(adminDistPath, "styles.css") },
|
{ find: "@emdash-cms/admin/styles.css", replacement: resolve(adminDistPath, "styles.css") },
|
||||||
// JS: source in dev (HMR), dist in build
|
// JS: source in dev (HMR), dist in build
|
||||||
{ find: "@emdashcms/admin", replacement: useSource ? adminSourcePath : adminDistPath },
|
{ find: "@emdash-cms/admin", replacement: useSource ? adminSourcePath : adminDistPath },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Monorepo has both vite 6 (docs) and vite 7 (core). tsgo resolves correctly.
|
// eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Monorepo has both vite 6 (docs) and vite 7 (core). tsgo resolves correctly.
|
||||||
@@ -264,7 +264,7 @@ export function createViteConfig(
|
|||||||
// ssr.external conflicts with @cloudflare/vite-plugin's resolve.external validation.
|
// ssr.external conflicts with @cloudflare/vite-plugin's resolve.external validation.
|
||||||
ssr: cloudflare
|
ssr: cloudflare
|
||||||
? {
|
? {
|
||||||
noExternal: ["emdash", "@emdashcms/admin"],
|
noExternal: ["emdash", "@emdash-cms/admin"],
|
||||||
// Pre-bundle EmDash's runtime deps for workerd. Without this,
|
// Pre-bundle EmDash's runtime deps for workerd. Without this,
|
||||||
// Vite discovers them one-by-one on first request, causing workerd
|
// Vite discovers them one-by-one on first request, causing workerd
|
||||||
// to enter "worker cancelled" state on cold cache.
|
// to enter "worker cancelled" state on cold cache.
|
||||||
@@ -288,10 +288,10 @@ export function createViteConfig(
|
|||||||
"emdash > sax",
|
"emdash > sax",
|
||||||
// Deeper transitive deps
|
// Deeper transitive deps
|
||||||
"emdash > sanitize-html > parse5",
|
"emdash > sanitize-html > parse5",
|
||||||
"emdash > @emdashcms/gutenberg-to-portable-text > @wordpress/block-serialization-default-parser",
|
"emdash > @emdash-cms/gutenberg-to-portable-text > @wordpress/block-serialization-default-parser",
|
||||||
"emdash > @emdashcms/auth > @oslojs/crypto/ecdsa",
|
"emdash > @emdash-cms/auth > @oslojs/crypto/ecdsa",
|
||||||
"emdash > @emdashcms/auth > @oslojs/crypto/sha2",
|
"emdash > @emdash-cms/auth > @oslojs/crypto/sha2",
|
||||||
"emdash > @emdashcms/auth > @oslojs/webauthn",
|
"emdash > @emdash-cms/auth > @oslojs/webauthn",
|
||||||
// React (commonly used, may be hoisted)
|
// React (commonly used, may be hoisted)
|
||||||
"react",
|
"react",
|
||||||
"react/jsx-dev-runtime",
|
"react/jsx-dev-runtime",
|
||||||
@@ -301,7 +301,7 @@ export function createViteConfig(
|
|||||||
// Top-level deps (use astro > path for pnpm compat)
|
// Top-level deps (use astro > path for pnpm compat)
|
||||||
"astro > zod/v4",
|
"astro > zod/v4",
|
||||||
"astro > zod/v4/core",
|
"astro > zod/v4/core",
|
||||||
"@emdashcms/cloudflare > kysely-d1",
|
"@emdash-cms/cloudflare > kysely-d1",
|
||||||
// Astro internal deps not covered by @astrojs/cloudflare adapter
|
// Astro internal deps not covered by @astrojs/cloudflare adapter
|
||||||
"astro/virtual-modules/middleware.js",
|
"astro/virtual-modules/middleware.js",
|
||||||
"astro/virtual-modules/live-config",
|
"astro/virtual-modules/live-config",
|
||||||
@@ -314,14 +314,14 @@ export function createViteConfig(
|
|||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
external: NODE_NATIVE_EXTERNALS,
|
external: NODE_NATIVE_EXTERNALS,
|
||||||
noExternal: ["emdash", "@emdashcms/admin"],
|
noExternal: ["emdash", "@emdash-cms/admin"],
|
||||||
},
|
},
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
// When using source, don't pre-bundle JS — let Vite transform on the fly for HMR.
|
// When using source, don't pre-bundle JS — let Vite transform on the fly for HMR.
|
||||||
// When using dist, pre-bundle to avoid re-optimization on first hydration.
|
// When using dist, pre-bundle to avoid re-optimization on first hydration.
|
||||||
include: useSource
|
include: useSource
|
||||||
? ["@astrojs/react/client.js"]
|
? ["@astrojs/react/client.js"]
|
||||||
: ["@emdashcms/admin", "@astrojs/react/client.js"],
|
: ["@emdash-cms/admin", "@astrojs/react/client.js"],
|
||||||
exclude: cloudflare ? [] : NODE_NATIVE_EXTERNALS,
|
exclude: cloudflare ? [] : NODE_NATIVE_EXTERNALS,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
* we know setup is complete and users exist.
|
* we know setup is complete and users exist.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { User, RoleLevel } from "@emdashcms/auth";
|
import type { User, RoleLevel } from "@emdash-cms/auth";
|
||||||
import { createKyselyAdapter } from "@emdashcms/auth/adapters/kysely";
|
import { createKyselyAdapter } from "@emdash-cms/auth/adapters/kysely";
|
||||||
import { defineMiddleware } from "astro:middleware";
|
import { defineMiddleware } from "astro:middleware";
|
||||||
import { ulid } from "ulidx";
|
import { ulid } from "ulidx";
|
||||||
// Import auth provider via virtual module (statically bundled)
|
// Import auth provider via virtual module (statically bundled)
|
||||||
@@ -47,7 +47,7 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Role level constants (matching @emdashcms/auth)
|
// Role level constants (matching @emdash-cms/auth)
|
||||||
const ROLE_ADMIN = 50;
|
const ROLE_ADMIN = 50;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export const onRequest = defineMiddleware(async (context, next) => {
|
|||||||
const { user } = context.locals;
|
const { user } = context.locals;
|
||||||
const isEditor = !!user && user.role >= 30;
|
const isEditor = !!user && user.role >= 30;
|
||||||
|
|
||||||
// Playground mode: the playground middleware (from @emdashcms/cloudflare) stashes
|
// Playground mode: the playground middleware (from @emdash-cms/cloudflare) stashes
|
||||||
// the per-session DO database on locals.__playgroundDb. We set it via ALS here
|
// the per-session DO database on locals.__playgroundDb. We set it via ALS here
|
||||||
// (same module instance as the loader) so getDb() picks it up correctly.
|
// (same module instance as the loader) so getDb() picks it up correctly.
|
||||||
const playgroundDb = context.locals.__playgroundDb;
|
const playgroundDb = context.locals.__playgroundDb;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* together with the admin app and available via React context.
|
* together with the admin app and available via React context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { AdminApp } from "@emdashcms/admin";
|
import { AdminApp } from "@emdash-cms/admin";
|
||||||
// @ts-ignore - virtual module generated by integration
|
// @ts-ignore - virtual module generated by integration
|
||||||
import { pluginAdmins } from "virtual:emdash/admin-registry";
|
import { pluginAdmins } from "virtual:emdash/admin-registry";
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* This page serves the EmDash admin React SPA.
|
* This page serves the EmDash admin React SPA.
|
||||||
* AdminWrapper imports plugin admin modules and passes them to AdminApp.
|
* AdminWrapper imports plugin admin modules and passes them to AdminApp.
|
||||||
*/
|
*/
|
||||||
import "@emdashcms/admin/styles.css";
|
import "@emdash-cms/admin/styles.css";
|
||||||
// Use package-qualified import so Astro generates a proper module URL
|
// Use package-qualified import so Astro generates a proper module URL
|
||||||
// (relative imports resolve to absolute paths which break client hydration)
|
// (relative imports resolve to absolute paths which break client hydration)
|
||||||
import AdminWrapper from "emdash/routes/PluginRegistry";
|
import AdminWrapper from "emdash/routes/PluginRegistry";
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import type { APIRoute } from "astro";
|
|||||||
|
|
||||||
export const prerender = false;
|
export const prerender = false;
|
||||||
|
|
||||||
import { Role, roleFromLevel } from "@emdashcms/auth";
|
import { Role, roleFromLevel } from "@emdash-cms/auth";
|
||||||
import { createKyselyAdapter } from "@emdashcms/auth/adapters/kysely";
|
import { createKyselyAdapter } from "@emdash-cms/auth/adapters/kysely";
|
||||||
|
|
||||||
import { apiError, apiSuccess, handleError } from "#api/error.js";
|
import { apiError, apiSuccess, handleError } from "#api/error.js";
|
||||||
import { isParseError, parseBody } from "#api/parse.js";
|
import { isParseError, parseBody } from "#api/parse.js";
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import type { APIRoute } from "astro";
|
|||||||
|
|
||||||
export const prerender = false;
|
export const prerender = false;
|
||||||
|
|
||||||
import { Role, roleFromLevel } from "@emdashcms/auth";
|
import { Role, roleFromLevel } from "@emdash-cms/auth";
|
||||||
import { createKyselyAdapter } from "@emdashcms/auth/adapters/kysely";
|
import { createKyselyAdapter } from "@emdash-cms/auth/adapters/kysely";
|
||||||
|
|
||||||
import { apiError, apiSuccess, handleError } from "#api/error.js";
|
import { apiError, apiSuccess, handleError } from "#api/error.js";
|
||||||
import { isParseError, parseBody } from "#api/parse.js";
|
import { isParseError, parseBody } from "#api/parse.js";
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* DELETE /_emdash/api/admin/api-tokens/:id — Revoke a token
|
* DELETE /_emdash/api/admin/api-tokens/:id — Revoke a token
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Role } from "@emdashcms/auth";
|
import { Role } from "@emdash-cms/auth";
|
||||||
import type { APIRoute } from "astro";
|
import type { APIRoute } from "astro";
|
||||||
|
|
||||||
import { apiError, handleError, unwrapResult } from "#api/error.js";
|
import { apiError, handleError, unwrapResult } from "#api/error.js";
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* POST /_emdash/api/admin/api-tokens — Create a new token
|
* POST /_emdash/api/admin/api-tokens — Create a new token
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Role } from "@emdashcms/auth";
|
import { Role } from "@emdash-cms/auth";
|
||||||
import type { APIRoute } from "astro";
|
import type { APIRoute } from "astro";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Role } from "@emdashcms/auth";
|
import { Role } from "@emdash-cms/auth";
|
||||||
import type { APIRoute } from "astro";
|
import type { APIRoute } from "astro";
|
||||||
|
|
||||||
import { requirePerm } from "#api/authorize.js";
|
import { requirePerm } from "#api/authorize.js";
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user