Fix scope

This commit is contained in:
Matt Kane
2026-04-01 10:58:32 +01:00
parent 482a442f60
commit 2e863566b3
264 changed files with 578 additions and 578 deletions

View File

@@ -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 }})

View File

@@ -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)

View File

@@ -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";

View File

@@ -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:",

View File

@@ -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

View File

@@ -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",
}, },
}), }),
], ],

View File

@@ -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:",

View File

@@ -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;

View File

@@ -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.

View File

@@ -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";

View File

@@ -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:",

View File

@@ -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;

View File

@@ -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 = [

View File

@@ -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",

View File

@@ -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";

View File

@@ -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:",

View File

@@ -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({

View File

@@ -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;

View File

@@ -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";

View File

@@ -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:*",

View File

@@ -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: [

View File

@@ -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",

View File

@@ -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 })],

View File

@@ -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

View File

@@ -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: [

View File

@@ -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: [

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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();

View File

@@ -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;

View File

@@ -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>

View File

@@ -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: [

View File

@@ -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: [

View File

@@ -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 |

View File

@@ -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,

View File

@@ -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"]
} }
} }
} }

View File

@@ -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.

View File

@@ -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";

View File

@@ -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:*",

View File

@@ -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");

View File

@@ -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",

View File

@@ -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:",

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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";

View File

@@ -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";

View File

@@ -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";

View File

@@ -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;

View File

@@ -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";

View File

@@ -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<{

View File

@@ -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() {

View File

@@ -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",

View File

@@ -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";

View File

@@ -1,5 +1,5 @@
/** /**
* Configuration schema for @emdashcms/auth * Configuration schema for @emdash-cms/auth
*/ */
import { z } from "zod"; import { z } from "zod";

View File

@@ -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: [

View File

@@ -1,5 +1,5 @@
/** /**
* Core types for @emdashcms/auth * Core types for @emdash-cms/auth
*/ */
// ============================================================================ // ============================================================================

View File

@@ -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",

View File

@@ -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:",

View File

@@ -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";

View File

@@ -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"];

View File

@@ -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" },

View File

@@ -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,
}, },
}, },
}); });

View File

@@ -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

View File

@@ -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",

View File

@@ -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";

View File

@@ -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,
}; };
} }

View File

@@ -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 {

View File

@@ -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";

View File

@@ -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",

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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,

View File

@@ -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: [

View File

@@ -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.
* *
*/ */

View File

@@ -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"`.
* *
*/ */

View File

@@ -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)}
// ============================================================================= // =============================================================================

View File

@@ -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'`

View File

@@ -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",
}); });

View File

@@ -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.
* *

View File

@@ -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",

View File

@@ -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";

View File

@@ -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";

View File

@@ -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";

View File

@@ -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";

View File

@@ -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"]);

View File

@@ -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";

View File

@@ -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: [

View File

@@ -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,
}, },
}; };

View File

@@ -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;
/** /**

View File

@@ -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;

View File

@@ -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";

View File

@@ -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";

View File

@@ -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";

View File

@@ -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";

View File

@@ -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";

View File

@@ -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";

View File

@@ -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