@getvitops/emdash 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,33 @@
1
+ # @getvitops/emdash
2
+
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 44de07f: Shared toolchain version + changelogs that reach consumers.
8
+ - **`@getvitops/astro` now shares the toolchain version** (`core`/`generator`/`utils`/`cli`/`vite`),
9
+ so it moves from its own `0.4.x` line onto the group's. The number changes; the package does not —
10
+ install it at the same version as `@getvitops/cli`. It was already being bumped on every toolchain
11
+ release by its dependency updates, and it depends on core, generator, utils _and_ vite, so a
12
+ separate version line cost the same churn while leaving the compatible pairing implicit. The
13
+ lockstep is load-bearing: the generator ships a snapshot of core's CSS + web-component bundles
14
+ while the Astro integration copies the _installed_ core's bundles, so mismatched versions can leave
15
+ the CSS and the components disagreeing.
16
+
17
+ - **Every package now ships its `CHANGELOG.md` in the published tarball.** npm does not include
18
+ changelogs by default, so none of this history previously reached anyone who installed the
19
+ packages. Per-package history now reads from `node_modules/@getvitops/<pkg>/CHANGELOG.md`;
20
+ curated toolchain-level release notes live in the repo's root `CHANGELOG.md`.
21
+
22
+ ## 0.2.0
23
+
24
+ ### Minor Changes
25
+
26
+ - New `vitopsHosting()` export — the hosting seam for EmDash sites. Resolves
27
+ the Astro adapter + EmDash database/storage for a target: `cloudflare`
28
+ (default — `@astrojs/cloudflare`, D1 `DB`, R2 `MEDIA`) or `node`
29
+ (`@astrojs/node` standalone, SQLite file, local uploads). Target precedence
30
+ `HOSTING` env > `options.target` > cloudflare; adapter packages resolve
31
+ lazily (install per target, missing ones fail with install instructions);
32
+ `options.node.database/storage` accept full descriptors (postgres/s3) for
33
+ production Node hosts.
package/README.md CHANGED
@@ -38,6 +38,43 @@ export default defineConfig({
38
38
 
39
39
  Tested against `emdash@0.31.x`.
40
40
 
41
+ ## Hosting seam: `vitopsHosting()`
42
+
43
+ One call resolves the Astro adapter + EmDash database/storage for a hosting
44
+ target, so a site can start on Cloudflare and later move to a Node host
45
+ (VPS / docker-compose / k8s) — or back — by flipping one value:
46
+
47
+ ```js
48
+ // astro.config.mjs
49
+ import { vitopsEmdash, vitopsHosting } from '@getvitops/emdash';
50
+
51
+ const { adapter, database, storage } = await vitopsHosting();
52
+
53
+ export default defineConfig({
54
+ output: 'server',
55
+ adapter,
56
+ integrations: [react(), emdash({ database, storage, plugins: [vitopsEmdash()] })],
57
+ });
58
+ ```
59
+
60
+ | Target | Adapter | Database | Storage | Install |
61
+ | ---------------------- | ---------------------------- | --------------------------------------- | ------------------------ | ----------------------------------------------------- |
62
+ | `cloudflare` (default) | `@astrojs/cloudflare` | D1 (`binding: 'DB'`, `session: 'auto'`) | R2 (`binding: 'MEDIA'`) | `pnpm add @astrojs/cloudflare @emdash-cms/cloudflare` |
63
+ | `node` | `@astrojs/node` (standalone) | SQLite (`file:./data/emdash.db`) | local (`./data/uploads`) | `pnpm add @astrojs/node better-sqlite3` |
64
+
65
+ - Target precedence: `HOSTING` env var > `options.target` > `'cloudflare'`.
66
+ - Adapter packages are resolved lazily — install only the stack you use; a
67
+ missing one fails with install instructions.
68
+ - Overrides: `vitopsHosting({ cloudflare: { dbBinding, mediaBinding, session } })`
69
+ or `vitopsHosting({ node: { databaseUrl, uploadsDir, database, storage } })` —
70
+ the `database`/`storage` escape hatches take full descriptors, e.g.
71
+ `postgres()` from `emdash/db` or `s3()` from `emdash/astro` for production
72
+ Node hosts.
73
+ - On Node, scheduled publishing runs in-process — no worker/cron trigger.
74
+ - Switching an existing site is a data migration, not a rewrite: content lives
75
+ in the database (D1 export / EmDash seed round-trip), media in the storage
76
+ backend (bucket/directory copy). Both directions work.
77
+
41
78
  ## Editor blocks (v1)
42
79
 
43
80
  | Slash-menu entry | `_type` | Renders |
@@ -77,3 +114,10 @@ EmDash's Portable Text block fields are flat, so patterns with repeating data
77
114
  - **Field Kit `list` widgets** on `json` collection fields: model the repeating
78
115
  rows in the collection schema and render them at the template level with
79
116
  `Cards.astro` / `NodeRenderer.astro` from `@getvitops/astro`.
117
+
118
+ ## Changelog
119
+
120
+ This package's history: [`CHANGELOG.md`](./CHANGELOG.md) (shipped in the npm tarball, so it
121
+ also reads from `node_modules/@getvitops/emdash/CHANGELOG.md`). This package versions
122
+ independently of the `@getvitops` toolchain (`core`/`generator`/`utils`/`cli`/`vite`/`astro`,
123
+ which share one version).
package/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { PluginDescriptor, PortableTextBlockConfig } from "emdash";
2
+ import { AstroIntegration } from "astro";
2
3
 
3
4
  //#region src/blocks.d.ts
4
5
  /** The v1 subset of EmDash Block Kit field elements used by these blocks. */
@@ -10,6 +11,33 @@ type PortableTextBlockDef = Omit<PortableTextBlockConfig, 'fields'> & {
10
11
  };
11
12
  declare const BLOCKS: PortableTextBlockDef[];
12
13
  //#endregion
14
+ //#region src/hosting.d.ts
15
+ type HostingTarget = 'cloudflare' | 'node';
16
+ interface VitopsHostingOptions {
17
+ /** Hosting target. Overridden by the `HOSTING` env var. Default 'cloudflare'. */
18
+ target?: HostingTarget;
19
+ cloudflare?: {
20
+ /** D1 binding name in wrangler config (default 'DB'). */dbBinding?: string; /** R2 binding name in wrangler config (default 'MEDIA'). */
21
+ mediaBinding?: string; /** D1 Sessions API read-replication mode (default 'auto'). */
22
+ session?: string;
23
+ };
24
+ node?: {
25
+ /** SQLite URL (default `DATABASE_PATH` env or 'file:./data/emdash.db'). */databaseUrl?: string; /** Full database descriptor override (e.g. postgres() from 'emdash/db'). */
26
+ database?: unknown; /** Local uploads directory (default './data/uploads'). */
27
+ uploadsDir?: string; /** Full storage descriptor override (e.g. s3() from 'emdash/astro'). */
28
+ storage?: unknown;
29
+ };
30
+ }
31
+ interface VitopsHosting {
32
+ target: HostingTarget;
33
+ adapter: AstroIntegration;
34
+ /** EmDash database descriptor — pass to emdash({ database }). */
35
+ database: unknown;
36
+ /** EmDash storage descriptor — pass to emdash({ storage }). */
37
+ storage: unknown;
38
+ }
39
+ declare function vitopsHosting(options?: VitopsHostingOptions): Promise<VitopsHosting>;
40
+ //#endregion
13
41
  //#region src/index.d.ts
14
42
  interface VitopsEmdashOptions {
15
43
  /**
@@ -34,5 +62,5 @@ declare function vitopsEmdash(options?: VitopsEmdashOptions): PluginDescriptor;
34
62
  /** Runtime side — EmDash imports and calls this from the descriptor's entrypoint. */
35
63
  declare function createPlugin(options?: VitopsEmdashOptions): import("emdash").ResolvedPlugin<import("emdash").PluginStorageConfig>;
36
64
  //#endregion
37
- export { BLOCKS, type BlockKitFieldDef, type PortableTextBlockDef, VitopsEmdashOptions, createPlugin, createPlugin as default, vitopsEmdash };
65
+ export { BLOCKS, type BlockKitFieldDef, type HostingTarget, type PortableTextBlockDef, VitopsEmdashOptions, type VitopsHosting, type VitopsHostingOptions, createPlugin, createPlugin as default, vitopsEmdash, vitopsHosting };
38
66
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/blocks.ts","../src/index.ts"],"mappings":";;;;KAeY,gBAAA,GAAmB,OAAA,CAC7B,WAAA,CAAY,uBAAA;EACV,IAAA;AAAA;AAAA,KAGQ,oBAAA,GAAuB,IAAA,CAAK,uBAAA;EACtC,MAAA,GAAS,gBAAA;AAAA;AAAA,cAGE,MAAA,EAAQ,oBAAoB;;;UCSxB,mBAAA;EDlBW;;;;;;;;;;EC6B1B,OAAA;ED3BM;EC6BN,MAAM;AAAA;;;;;iBAOQ,YAAA,CAAa,OAAA,GAAS,mBAAA,GAA2B,gBAAgB;;iBAajE,YAAA,CAAa,OAAA,GAAS,mBAAwB,oBAAA,cAAA,kBAAA,mBAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/blocks.ts","../src/hosting.ts","../src/index.ts"],"mappings":";;;;;KAeY,gBAAA,GAAmB,OAAA,CAC7B,WAAA,CAAY,uBAAA;EACV,IAAA;AAAA;AAAA,KAGQ,oBAAA,GAAuB,IAAA,CAAK,uBAAA;EACtC,MAAA,GAAS,gBAAA;AAAA;AAAA,cAGE,MAAA,EAAQ,oBAAoB;;;KCQ7B,aAAA;AAAA,UAIK,oBAAA;EDyFhB;ECvFC,MAAA,GAAS,aAAa;EACtB,UAAA;IDfuC,yDCiBrC,SAAA;IAEA,YAAA,WAXQ;IAaR,OAAA;EAAA;EAEF,IAAA;IAfuB,2EAiBrB,WAAA,WAbiC;IAejC,QAAA,YAboB;IAepB,UAAA,WAfO;IAiBP,OAAA;EAAA;AAAA;AAAA,UAIa,aAAA;EACf,MAAA,EAAQ,aAAA;EACR,OAAA,EAAS,gBAAgB;EAVvB;EAYF,QAAA;EARE;EAUF,OAAA;AAAA;AAAA,iBAoBoB,aAAA,CAAc,OAAA,GAAS,oBAAA,GAA4B,OAAA,CAAQ,aAAA;;;UClDhE,mBAAA;;;;;;;;;;;EAWf,OAAA;EF7BM;EE+BN,MAAM;AAAA;;;;;iBAOQ,YAAA,CAAa,OAAA,GAAS,mBAAA,GAA2B,gBAAgB;;iBAajE,YAAA,CAAa,OAAA,GAAS,mBAAwB,oBAAA,cAAA,kBAAA,mBAAA"}
package/dist/index.mjs CHANGED
@@ -174,6 +174,66 @@ const BLOCKS = [
174
174
  }
175
175
  ];
176
176
 
177
+ //#endregion
178
+ //#region src/hosting.ts
179
+ const TARGETS = ["cloudflare", "node"];
180
+ /**
181
+ * Import an optional hosting dependency. The specifier is passed as a
182
+ * variable so bundlers/type-checkers leave it as a plain runtime import —
183
+ * these packages are optional peers a consumer installs per target.
184
+ */
185
+ async function importFor(target, specifier, install) {
186
+ try {
187
+ return await import(
188
+ /* @vite-ignore */
189
+ specifier
190
+ );
191
+ } catch (cause) {
192
+ throw new Error(`[vitops] hosting target '${target}' needs ${specifier}, which isn't installed.\nInstall the ${target} stack first: ${install}`, { cause });
193
+ }
194
+ }
195
+ async function vitopsHosting(options = {}) {
196
+ const target = process.env.HOSTING || options.target || "cloudflare";
197
+ if (target === "cloudflare") {
198
+ const install = "pnpm add @astrojs/cloudflare @emdash-cms/cloudflare";
199
+ const cf = options.cloudflare ?? {};
200
+ const { default: cloudflare } = await importFor(target, "@astrojs/cloudflare", install);
201
+ const { d1, r2 } = await importFor(target, "@emdash-cms/cloudflare", install);
202
+ return {
203
+ target,
204
+ adapter: cloudflare(),
205
+ database: d1({
206
+ binding: cf.dbBinding ?? "DB",
207
+ session: cf.session ?? "auto"
208
+ }),
209
+ storage: r2({ binding: cf.mediaBinding ?? "MEDIA" })
210
+ };
211
+ }
212
+ if (target === "node") {
213
+ const install = "pnpm add @astrojs/node better-sqlite3";
214
+ const opts = options.node ?? {};
215
+ const { default: node } = await importFor(target, "@astrojs/node", install);
216
+ const { sqlite } = await importFor(target, "emdash/db", install);
217
+ const { local } = await importFor(target, "emdash/astro", install);
218
+ const { mkdirSync } = await import("node:fs");
219
+ const { dirname } = await import("node:path");
220
+ const databaseUrl = opts.databaseUrl ?? process.env.DATABASE_PATH ?? "file:./data/emdash.db";
221
+ const uploadsDir = opts.uploadsDir ?? "./data/uploads";
222
+ if (!opts.database && databaseUrl.startsWith("file:")) mkdirSync(dirname(databaseUrl.slice(5)), { recursive: true });
223
+ if (!opts.storage) mkdirSync(uploadsDir, { recursive: true });
224
+ return {
225
+ target,
226
+ adapter: node({ mode: "standalone" }),
227
+ database: opts.database ?? sqlite({ url: databaseUrl }),
228
+ storage: opts.storage ?? local({
229
+ directory: uploadsDir,
230
+ baseUrl: "/_emdash/api/media/file"
231
+ })
232
+ };
233
+ }
234
+ throw new Error(`[vitops] unknown hosting target '${target}' (from ${process.env.HOSTING ? "HOSTING env var" : "options.target"}). Valid targets: ${TARGETS.join(", ")}.`);
235
+ }
236
+
177
237
  //#endregion
178
238
  //#region src/index.ts
179
239
  /**
@@ -198,7 +258,7 @@ const BLOCKS = [
198
258
  * ```
199
259
  */
200
260
  /** Keep in sync with package.json (asserted by index.test.ts). */
201
- const VERSION = "0.1.0";
261
+ const VERSION = "0.2.0";
202
262
  const PLUGIN_ID = "vitops";
203
263
  const FRAGMENTS_CAPABILITY = "hooks.page-fragments:register";
204
264
  /**
@@ -241,5 +301,5 @@ function createPlugin(options = {}) {
241
301
  }
242
302
 
243
303
  //#endregion
244
- export { BLOCKS, createPlugin, createPlugin as default, vitopsEmdash };
304
+ export { BLOCKS, createPlugin, createPlugin as default, vitopsEmdash, vitopsHosting };
245
305
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/blocks.ts","../src/index.ts"],"sourcesContent":["/**\n * Portable Text block-type declarations for the EmDash editor.\n *\n * v1 exposes only Vitops patterns whose data model fits EmDash's flat Block Kit\n * fields (text_input / number_input / select / toggle). Repeating structured\n * patterns (Cards, wc-entries, FAQ, forms) go through EmDash Sections or\n * Field Kit `list` widgets on json collection fields instead — see the README.\n *\n * Every `action_id` here must have a matching prop consumed by the block's\n * .astro component in `src/astro/blocks/` (enforced by blocks.test.ts).\n */\n\nimport type { PortableTextBlockConfig } from 'emdash';\n\n/** The v1 subset of EmDash Block Kit field elements used by these blocks. */\nexport type BlockKitFieldDef = Extract<\n NonNullable<PortableTextBlockConfig['fields']>[number],\n { type: 'text_input' | 'number_input' | 'select' | 'toggle' }\n>;\n\nexport type PortableTextBlockDef = Omit<PortableTextBlockConfig, 'fields'> & {\n fields?: BlockKitFieldDef[];\n};\n\nexport const BLOCKS: PortableTextBlockDef[] = [\n {\n type: 'vitops.imageCompare',\n label: 'Image compare',\n placeholder: 'Before/after image slider',\n fields: [\n { type: 'text_input', action_id: 'before', label: 'Before image URL' },\n { type: 'text_input', action_id: 'beforeAlt', label: 'Before alt text' },\n {\n type: 'text_input',\n action_id: 'beforeLabel',\n label: 'Before label',\n initial_value: 'Before',\n },\n { type: 'text_input', action_id: 'after', label: 'After image URL' },\n { type: 'text_input', action_id: 'afterAlt', label: 'After alt text' },\n { type: 'text_input', action_id: 'afterLabel', label: 'After label', initial_value: 'After' },\n ],\n },\n {\n type: 'vitops.copyButton',\n label: 'Copy snippet',\n icon: 'code',\n placeholder: 'Text with a copy-to-clipboard button',\n fields: [\n { type: 'text_input', action_id: 'text', label: 'Text to copy', multiline: true },\n { type: 'text_input', action_id: 'label', label: 'Button label', initial_value: 'Copy' },\n {\n type: 'select',\n action_id: 'display',\n label: 'Display',\n initial_value: 'code-block',\n options: [\n { label: 'Code block', value: 'code-block' },\n { label: 'Inline', value: 'inline' },\n ],\n },\n ],\n },\n {\n type: 'vitops.banner',\n label: 'Banner',\n placeholder: 'Announcement or notice',\n fields: [\n { type: 'text_input', action_id: 'message', label: 'Message', multiline: true },\n {\n type: 'select',\n action_id: 'tone',\n label: 'Tone',\n initial_value: 'info',\n options: [\n { label: 'Info', value: 'info' },\n { label: 'Success', value: 'success' },\n { label: 'Warning', value: 'warning' },\n { label: 'Danger', value: 'danger' },\n ],\n },\n { type: 'toggle', action_id: 'dismissible', label: 'Dismissible', initial_value: true },\n ],\n },\n {\n type: 'vitops.details',\n label: 'Disclosure',\n placeholder: 'Collapsible details/summary',\n fields: [\n { type: 'text_input', action_id: 'summary', label: 'Summary (always visible)' },\n { type: 'text_input', action_id: 'body', label: 'Body (revealed)', multiline: true },\n { type: 'toggle', action_id: 'open', label: 'Open by default', initial_value: false },\n ],\n },\n {\n type: 'vitops.carousel',\n label: 'Carousel',\n placeholder: 'Image carousel',\n fields: [\n {\n type: 'text_input',\n action_id: 'images',\n label: 'Image URLs (one per line)',\n multiline: true,\n },\n {\n type: 'text_input',\n action_id: 'alts',\n label: 'Alt texts (one per line, same order)',\n multiline: true,\n },\n {\n type: 'text_input',\n action_id: 'label',\n label: 'Accessible name',\n initial_value: 'Carousel',\n },\n {\n type: 'number_input',\n action_id: 'autoplay',\n label: 'Autoplay interval (ms, 0 = off)',\n initial_value: 0,\n },\n ],\n },\n];\n","/**\n * @getvitops/emdash — EmDash CMS native plugin for the Vitops design system.\n *\n * Declares Vitops Portable Text block types (editable from the EmDash admin's\n * slash menu) and ships the Astro components that render them via the\n * `componentsEntry` (`@getvitops/emdash/astro`).\n *\n * Composes with — does not replace — the `getvitops()` Astro integration from\n * `@getvitops/astro`: the integration owns design-system CSS generation and\n * copies the web-component bundles into `public/<wcBase>/`; this plugin only\n * adds the editor-facing layer. Register both in the consumer site:\n *\n * ```js\n * // astro.config.mjs\n * integrations: [\n * react(),\n * getvitops({ css: {...} }),\n * emdash({ database, storage, plugins: [vitopsEmdash()] }),\n * ]\n * ```\n */\nimport { definePlugin } from 'emdash';\nimport type { PluginDescriptor } from 'emdash';\nimport { BLOCKS } from './blocks.ts';\n\nexport { BLOCKS } from './blocks.ts';\nexport type { BlockKitFieldDef, PortableTextBlockDef } from './blocks.ts';\n\n/** Keep in sync with package.json (asserted by index.test.ts). */\nconst VERSION = '0.1.0';\nconst PLUGIN_ID = 'vitops';\nconst FRAGMENTS_CAPABILITY = 'hooks.page-fragments:register';\n\nexport interface VitopsEmdashOptions {\n /**\n * How the web-component runtime scripts reach the page:\n * - `'integration'` (default) — the site's layout renders `<Head />` from\n * `@getvitops/astro`, which emits the script tags; this plugin adds none.\n * - `'fragments'` — for layouts using EmDash's `<EmDashHead/>`/`<EmDashBodyEnd/>`\n * instead: the plugin injects the script tags via the `page:fragments` hook.\n * Either way the bundles themselves must exist under `public/<wcBase>/`,\n * which the `getvitops()` integration provides (webComponents: true).\n * Do not enable both delivery paths — the scripts would load twice.\n */\n scripts?: 'integration' | 'fragments';\n /** Public base path of the web-component bundles (default '/vitops'). */\n wcBase?: string;\n}\n\n/**\n * Descriptor factory — import in `astro.config.mjs` and pass to the emdash()\n * integration's `plugins` array.\n */\nexport function vitopsEmdash(options: VitopsEmdashOptions = {}): PluginDescriptor {\n return {\n id: PLUGIN_ID,\n version: VERSION,\n format: 'native',\n entrypoint: '@getvitops/emdash',\n componentsEntry: '@getvitops/emdash/astro',\n options,\n capabilities: options.scripts === 'fragments' ? [FRAGMENTS_CAPABILITY] : [],\n } as PluginDescriptor;\n}\n\n/** Runtime side — EmDash imports and calls this from the descriptor's entrypoint. */\nexport function createPlugin(options: VitopsEmdashOptions = {}) {\n const scripts = options.scripts ?? 'integration';\n const wcBase = options.wcBase ?? '/vitops';\n\n return definePlugin({\n id: PLUGIN_ID,\n version: VERSION,\n capabilities: scripts === 'fragments' ? [FRAGMENTS_CAPABILITY] : [],\n\n hooks:\n scripts === 'fragments'\n ? {\n // Mirrors @getvitops/astro Head.astro: module polyfills + elements\n // in head, deferred enhancements at end of body.\n 'page:fragments': async () => [\n {\n kind: 'html',\n placement: 'head',\n html:\n `<link rel=\"modulepreload\" href=\"${wcBase}/polyfills.js\">` +\n `<script type=\"module\" src=\"${wcBase}/polyfills.js\"></script>` +\n `<script type=\"module\" src=\"${wcBase}/elements.js\"></script>`,\n key: 'vitops-wc',\n },\n {\n kind: 'external-script',\n placement: 'body:end',\n src: `${wcBase}/deferred.js`,\n defer: true,\n key: 'vitops-deferred',\n },\n ],\n }\n : {},\n\n admin: {\n portableTextBlocks: BLOCKS,\n },\n });\n}\n\nexport default createPlugin;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/blocks.ts","../src/hosting.ts","../src/index.ts"],"sourcesContent":["/**\n * Portable Text block-type declarations for the EmDash editor.\n *\n * v1 exposes only Vitops patterns whose data model fits EmDash's flat Block Kit\n * fields (text_input / number_input / select / toggle). Repeating structured\n * patterns (Cards, wc-entries, FAQ, forms) go through EmDash Sections or\n * Field Kit `list` widgets on json collection fields instead — see the README.\n *\n * Every `action_id` here must have a matching prop consumed by the block's\n * .astro component in `src/astro/blocks/` (enforced by blocks.test.ts).\n */\n\nimport type { PortableTextBlockConfig } from 'emdash';\n\n/** The v1 subset of EmDash Block Kit field elements used by these blocks. */\nexport type BlockKitFieldDef = Extract<\n NonNullable<PortableTextBlockConfig['fields']>[number],\n { type: 'text_input' | 'number_input' | 'select' | 'toggle' }\n>;\n\nexport type PortableTextBlockDef = Omit<PortableTextBlockConfig, 'fields'> & {\n fields?: BlockKitFieldDef[];\n};\n\nexport const BLOCKS: PortableTextBlockDef[] = [\n {\n type: 'vitops.imageCompare',\n label: 'Image compare',\n placeholder: 'Before/after image slider',\n fields: [\n { type: 'text_input', action_id: 'before', label: 'Before image URL' },\n { type: 'text_input', action_id: 'beforeAlt', label: 'Before alt text' },\n {\n type: 'text_input',\n action_id: 'beforeLabel',\n label: 'Before label',\n initial_value: 'Before',\n },\n { type: 'text_input', action_id: 'after', label: 'After image URL' },\n { type: 'text_input', action_id: 'afterAlt', label: 'After alt text' },\n { type: 'text_input', action_id: 'afterLabel', label: 'After label', initial_value: 'After' },\n ],\n },\n {\n type: 'vitops.copyButton',\n label: 'Copy snippet',\n icon: 'code',\n placeholder: 'Text with a copy-to-clipboard button',\n fields: [\n { type: 'text_input', action_id: 'text', label: 'Text to copy', multiline: true },\n { type: 'text_input', action_id: 'label', label: 'Button label', initial_value: 'Copy' },\n {\n type: 'select',\n action_id: 'display',\n label: 'Display',\n initial_value: 'code-block',\n options: [\n { label: 'Code block', value: 'code-block' },\n { label: 'Inline', value: 'inline' },\n ],\n },\n ],\n },\n {\n type: 'vitops.banner',\n label: 'Banner',\n placeholder: 'Announcement or notice',\n fields: [\n { type: 'text_input', action_id: 'message', label: 'Message', multiline: true },\n {\n type: 'select',\n action_id: 'tone',\n label: 'Tone',\n initial_value: 'info',\n options: [\n { label: 'Info', value: 'info' },\n { label: 'Success', value: 'success' },\n { label: 'Warning', value: 'warning' },\n { label: 'Danger', value: 'danger' },\n ],\n },\n { type: 'toggle', action_id: 'dismissible', label: 'Dismissible', initial_value: true },\n ],\n },\n {\n type: 'vitops.details',\n label: 'Disclosure',\n placeholder: 'Collapsible details/summary',\n fields: [\n { type: 'text_input', action_id: 'summary', label: 'Summary (always visible)' },\n { type: 'text_input', action_id: 'body', label: 'Body (revealed)', multiline: true },\n { type: 'toggle', action_id: 'open', label: 'Open by default', initial_value: false },\n ],\n },\n {\n type: 'vitops.carousel',\n label: 'Carousel',\n placeholder: 'Image carousel',\n fields: [\n {\n type: 'text_input',\n action_id: 'images',\n label: 'Image URLs (one per line)',\n multiline: true,\n },\n {\n type: 'text_input',\n action_id: 'alts',\n label: 'Alt texts (one per line, same order)',\n multiline: true,\n },\n {\n type: 'text_input',\n action_id: 'label',\n label: 'Accessible name',\n initial_value: 'Carousel',\n },\n {\n type: 'number_input',\n action_id: 'autoplay',\n label: 'Autoplay interval (ms, 0 = off)',\n initial_value: 0,\n },\n ],\n },\n];\n","/**\n * Hosting seam — one call in astro.config.mjs resolves the adapter + EmDash\n * database/storage for the chosen hosting target, so a site can start on\n * Cloudflare and move to a Node host (VPS / docker-compose / k8s) — or back —\n * by flipping a single value instead of rewiring its config:\n *\n * ```js\n * import { vitopsEmdash, vitopsHosting } from '@getvitops/emdash';\n * const { adapter, database, storage } = await vitopsHosting();\n * export default defineConfig({\n * output: 'server',\n * adapter,\n * integrations: [react(), emdash({ database, storage, plugins: [vitopsEmdash()] })],\n * });\n * ```\n *\n * Targets:\n * - `'cloudflare'` (default) — `@astrojs/cloudflare` + D1/R2 bindings.\n * Needs `@astrojs/cloudflare` and `@emdash-cms/cloudflare` installed.\n * - `'node'` — `@astrojs/node` (standalone) + SQLite file + local uploads.\n * Needs `@astrojs/node` and `better-sqlite3` installed. Scheduled publishing\n * runs in-process on Node (no worker/cron trigger needed). For production,\n * move storage to S3-compatible (`s3()` from `emdash/astro`) and/or the\n * database to Postgres (`postgres()` from `emdash/db`) via `options.node`.\n *\n * The adapter packages are optional peer dependencies, resolved lazily — a\n * site only installs the stack for the target it uses. Content lives in the\n * database and media in the storage backend, so switching hosts is a data\n * migration (D1 export / EmDash seed round-trip + media copy), not a rewrite.\n */\nimport type { AstroIntegration } from 'astro';\n\nexport type HostingTarget = 'cloudflare' | 'node';\n\nconst TARGETS: HostingTarget[] = ['cloudflare', 'node'];\n\nexport interface VitopsHostingOptions {\n /** Hosting target. Overridden by the `HOSTING` env var. Default 'cloudflare'. */\n target?: HostingTarget;\n cloudflare?: {\n /** D1 binding name in wrangler config (default 'DB'). */\n dbBinding?: string;\n /** R2 binding name in wrangler config (default 'MEDIA'). */\n mediaBinding?: string;\n /** D1 Sessions API read-replication mode (default 'auto'). */\n session?: string;\n };\n node?: {\n /** SQLite URL (default `DATABASE_PATH` env or 'file:./data/emdash.db'). */\n databaseUrl?: string;\n /** Full database descriptor override (e.g. postgres() from 'emdash/db'). */\n database?: unknown;\n /** Local uploads directory (default './data/uploads'). */\n uploadsDir?: string;\n /** Full storage descriptor override (e.g. s3() from 'emdash/astro'). */\n storage?: unknown;\n };\n}\n\nexport interface VitopsHosting {\n target: HostingTarget;\n adapter: AstroIntegration;\n /** EmDash database descriptor — pass to emdash({ database }). */\n database: unknown;\n /** EmDash storage descriptor — pass to emdash({ storage }). */\n storage: unknown;\n}\n\n/**\n * Import an optional hosting dependency. The specifier is passed as a\n * variable so bundlers/type-checkers leave it as a plain runtime import —\n * these packages are optional peers a consumer installs per target.\n */\nasync function importFor(target: HostingTarget, specifier: string, install: string) {\n try {\n return await import(/* @vite-ignore */ specifier);\n } catch (cause) {\n throw new Error(\n `[vitops] hosting target '${target}' needs ${specifier}, which isn't installed.\\n` +\n `Install the ${target} stack first: ${install}`,\n { cause },\n );\n }\n}\n\nexport async function vitopsHosting(options: VitopsHostingOptions = {}): Promise<VitopsHosting> {\n const target = (process.env.HOSTING as HostingTarget) || options.target || 'cloudflare';\n\n if (target === 'cloudflare') {\n const install = 'pnpm add @astrojs/cloudflare @emdash-cms/cloudflare';\n const cf = options.cloudflare ?? {};\n const { default: cloudflare } = await importFor(target, '@astrojs/cloudflare', install);\n const { d1, r2 } = await importFor(target, '@emdash-cms/cloudflare', install);\n return {\n target,\n adapter: cloudflare(),\n database: d1({ binding: cf.dbBinding ?? 'DB', session: cf.session ?? 'auto' }),\n storage: r2({ binding: cf.mediaBinding ?? 'MEDIA' }),\n };\n }\n\n if (target === 'node') {\n const install = 'pnpm add @astrojs/node better-sqlite3';\n const opts = options.node ?? {};\n const { default: node } = await importFor(target, '@astrojs/node', install);\n // Required peer of this package, so always present — but still routed\n // through importFor: a literal import('emdash/db') would be statically\n // analyzable, and bundling the plugin runtime would drag EmDash's whole\n // integration graph into the site's server/client bundles.\n const { sqlite } = await importFor(target, 'emdash/db', install);\n const { local } = await importFor(target, 'emdash/astro', install);\n const { mkdirSync } = await import('node:fs');\n const { dirname } = await import('node:path');\n\n const databaseUrl = opts.databaseUrl ?? process.env.DATABASE_PATH ?? 'file:./data/emdash.db';\n const uploadsDir = opts.uploadsDir ?? './data/uploads';\n // better-sqlite3 refuses to create parent directories, so make sure the\n // defaults exist (runs at astro config load — dev and build). A deployed\n // host still needs the data directory mounted/persisted as a volume.\n if (!opts.database && databaseUrl.startsWith('file:')) {\n mkdirSync(dirname(databaseUrl.slice('file:'.length)), { recursive: true });\n }\n if (!opts.storage) mkdirSync(uploadsDir, { recursive: true });\n\n return {\n target,\n adapter: node({ mode: 'standalone' }),\n database: opts.database ?? sqlite({ url: databaseUrl }),\n storage: opts.storage ?? local({ directory: uploadsDir, baseUrl: '/_emdash/api/media/file' }),\n };\n }\n\n throw new Error(\n `[vitops] unknown hosting target '${target}' (from ${process.env.HOSTING ? 'HOSTING env var' : 'options.target'}). ` +\n `Valid targets: ${TARGETS.join(', ')}.`,\n );\n}\n","/**\n * @getvitops/emdash — EmDash CMS native plugin for the Vitops design system.\n *\n * Declares Vitops Portable Text block types (editable from the EmDash admin's\n * slash menu) and ships the Astro components that render them via the\n * `componentsEntry` (`@getvitops/emdash/astro`).\n *\n * Composes with — does not replace — the `getvitops()` Astro integration from\n * `@getvitops/astro`: the integration owns design-system CSS generation and\n * copies the web-component bundles into `public/<wcBase>/`; this plugin only\n * adds the editor-facing layer. Register both in the consumer site:\n *\n * ```js\n * // astro.config.mjs\n * integrations: [\n * react(),\n * getvitops({ css: {...} }),\n * emdash({ database, storage, plugins: [vitopsEmdash()] }),\n * ]\n * ```\n */\nimport { definePlugin } from 'emdash';\nimport type { PluginDescriptor } from 'emdash';\nimport { BLOCKS } from './blocks.ts';\n\nexport { BLOCKS } from './blocks.ts';\nexport type { BlockKitFieldDef, PortableTextBlockDef } from './blocks.ts';\nexport { vitopsHosting } from './hosting.ts';\nexport type { HostingTarget, VitopsHosting, VitopsHostingOptions } from './hosting.ts';\n\n/** Keep in sync with package.json (asserted by index.test.ts). */\nconst VERSION = '0.2.0';\nconst PLUGIN_ID = 'vitops';\nconst FRAGMENTS_CAPABILITY = 'hooks.page-fragments:register';\n\nexport interface VitopsEmdashOptions {\n /**\n * How the web-component runtime scripts reach the page:\n * - `'integration'` (default) — the site's layout renders `<Head />` from\n * `@getvitops/astro`, which emits the script tags; this plugin adds none.\n * - `'fragments'` — for layouts using EmDash's `<EmDashHead/>`/`<EmDashBodyEnd/>`\n * instead: the plugin injects the script tags via the `page:fragments` hook.\n * Either way the bundles themselves must exist under `public/<wcBase>/`,\n * which the `getvitops()` integration provides (webComponents: true).\n * Do not enable both delivery paths — the scripts would load twice.\n */\n scripts?: 'integration' | 'fragments';\n /** Public base path of the web-component bundles (default '/vitops'). */\n wcBase?: string;\n}\n\n/**\n * Descriptor factory — import in `astro.config.mjs` and pass to the emdash()\n * integration's `plugins` array.\n */\nexport function vitopsEmdash(options: VitopsEmdashOptions = {}): PluginDescriptor {\n return {\n id: PLUGIN_ID,\n version: VERSION,\n format: 'native',\n entrypoint: '@getvitops/emdash',\n componentsEntry: '@getvitops/emdash/astro',\n options,\n capabilities: options.scripts === 'fragments' ? [FRAGMENTS_CAPABILITY] : [],\n } as PluginDescriptor;\n}\n\n/** Runtime side — EmDash imports and calls this from the descriptor's entrypoint. */\nexport function createPlugin(options: VitopsEmdashOptions = {}) {\n const scripts = options.scripts ?? 'integration';\n const wcBase = options.wcBase ?? '/vitops';\n\n return definePlugin({\n id: PLUGIN_ID,\n version: VERSION,\n capabilities: scripts === 'fragments' ? [FRAGMENTS_CAPABILITY] : [],\n\n hooks:\n scripts === 'fragments'\n ? {\n // Mirrors @getvitops/astro Head.astro: module polyfills + elements\n // in head, deferred enhancements at end of body.\n 'page:fragments': async () => [\n {\n kind: 'html',\n placement: 'head',\n html:\n `<link rel=\"modulepreload\" href=\"${wcBase}/polyfills.js\">` +\n `<script type=\"module\" src=\"${wcBase}/polyfills.js\"></script>` +\n `<script type=\"module\" src=\"${wcBase}/elements.js\"></script>`,\n key: 'vitops-wc',\n },\n {\n kind: 'external-script',\n placement: 'body:end',\n src: `${wcBase}/deferred.js`,\n defer: true,\n key: 'vitops-deferred',\n },\n ],\n }\n : {},\n\n admin: {\n portableTextBlocks: BLOCKS,\n },\n });\n}\n\nexport default createPlugin;\n"],"mappings":";;;AAwBA,MAAa,SAAiC;CAC5C;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,QAAQ;GACN;IAAE,MAAM;IAAc,WAAW;IAAU,OAAO;GAAmB;GACrE;IAAE,MAAM;IAAc,WAAW;IAAa,OAAO;GAAkB;GACvE;IACE,MAAM;IACN,WAAW;IACX,OAAO;IACP,eAAe;GACjB;GACA;IAAE,MAAM;IAAc,WAAW;IAAS,OAAO;GAAkB;GACnE;IAAE,MAAM;IAAc,WAAW;IAAY,OAAO;GAAiB;GACrE;IAAE,MAAM;IAAc,WAAW;IAAc,OAAO;IAAe,eAAe;GAAQ;EAC9F;CACF;CACA;EACE,MAAM;EACN,OAAO;EACP,MAAM;EACN,aAAa;EACb,QAAQ;GACN;IAAE,MAAM;IAAc,WAAW;IAAQ,OAAO;IAAgB,WAAW;GAAK;GAChF;IAAE,MAAM;IAAc,WAAW;IAAS,OAAO;IAAgB,eAAe;GAAO;GACvF;IACE,MAAM;IACN,WAAW;IACX,OAAO;IACP,eAAe;IACf,SAAS,CACP;KAAE,OAAO;KAAc,OAAO;IAAa,GAC3C;KAAE,OAAO;KAAU,OAAO;IAAS,CACrC;GACF;EACF;CACF;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,QAAQ;GACN;IAAE,MAAM;IAAc,WAAW;IAAW,OAAO;IAAW,WAAW;GAAK;GAC9E;IACE,MAAM;IACN,WAAW;IACX,OAAO;IACP,eAAe;IACf,SAAS;KACP;MAAE,OAAO;MAAQ,OAAO;KAAO;KAC/B;MAAE,OAAO;MAAW,OAAO;KAAU;KACrC;MAAE,OAAO;MAAW,OAAO;KAAU;KACrC;MAAE,OAAO;MAAU,OAAO;KAAS;IACrC;GACF;GACA;IAAE,MAAM;IAAU,WAAW;IAAe,OAAO;IAAe,eAAe;GAAK;EACxF;CACF;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,QAAQ;GACN;IAAE,MAAM;IAAc,WAAW;IAAW,OAAO;GAA2B;GAC9E;IAAE,MAAM;IAAc,WAAW;IAAQ,OAAO;IAAmB,WAAW;GAAK;GACnF;IAAE,MAAM;IAAU,WAAW;IAAQ,OAAO;IAAmB,eAAe;GAAM;EACtF;CACF;CACA;EACE,MAAM;EACN,OAAO;EACP,aAAa;EACb,QAAQ;GACN;IACE,MAAM;IACN,WAAW;IACX,OAAO;IACP,WAAW;GACb;GACA;IACE,MAAM;IACN,WAAW;IACX,OAAO;IACP,WAAW;GACb;GACA;IACE,MAAM;IACN,WAAW;IACX,OAAO;IACP,eAAe;GACjB;GACA;IACE,MAAM;IACN,WAAW;IACX,OAAO;IACP,eAAe;GACjB;EACF;CACF;AACF;;;;AC3FA,MAAM,UAA2B,CAAC,cAAc,MAAM;;;;;;AAuCtD,eAAe,UAAU,QAAuB,WAAmB,SAAiB;CAClF,IAAI;EACF,OAAO,MAAM;;GAA0B;;CACzC,SAAS,OAAO;EACd,MAAM,IAAI,MACR,4BAA4B,OAAO,UAAU,UAAU,wCACtC,OAAO,iBAAiB,WACzC,EAAE,MAAM,CACV;CACF;AACF;AAEA,eAAsB,cAAc,UAAgC,CAAC,GAA2B;CAC9F,MAAM,SAAU,QAAQ,IAAI,WAA6B,QAAQ,UAAU;CAE3E,IAAI,WAAW,cAAc;EAC3B,MAAM,UAAU;EAChB,MAAM,KAAK,QAAQ,cAAc,CAAC;EAClC,MAAM,EAAE,SAAS,eAAe,MAAM,UAAU,QAAQ,uBAAuB,OAAO;EACtF,MAAM,EAAE,IAAI,OAAO,MAAM,UAAU,QAAQ,0BAA0B,OAAO;EAC5E,OAAO;GACL;GACA,SAAS,WAAW;GACpB,UAAU,GAAG;IAAE,SAAS,GAAG,aAAa;IAAM,SAAS,GAAG,WAAW;GAAO,CAAC;GAC7E,SAAS,GAAG,EAAE,SAAS,GAAG,gBAAgB,QAAQ,CAAC;EACrD;CACF;CAEA,IAAI,WAAW,QAAQ;EACrB,MAAM,UAAU;EAChB,MAAM,OAAO,QAAQ,QAAQ,CAAC;EAC9B,MAAM,EAAE,SAAS,SAAS,MAAM,UAAU,QAAQ,iBAAiB,OAAO;EAK1E,MAAM,EAAE,WAAW,MAAM,UAAU,QAAQ,aAAa,OAAO;EAC/D,MAAM,EAAE,UAAU,MAAM,UAAU,QAAQ,gBAAgB,OAAO;EACjE,MAAM,EAAE,cAAc,MAAM,OAAO;EACnC,MAAM,EAAE,YAAY,MAAM,OAAO;EAEjC,MAAM,cAAc,KAAK,eAAe,QAAQ,IAAI,iBAAiB;EACrE,MAAM,aAAa,KAAK,cAAc;EAItC,IAAI,CAAC,KAAK,YAAY,YAAY,WAAW,OAAO,GAClD,UAAU,QAAQ,YAAY,MAAM,CAAc,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC;EAE3E,IAAI,CAAC,KAAK,SAAS,UAAU,YAAY,EAAE,WAAW,KAAK,CAAC;EAE5D,OAAO;GACL;GACA,SAAS,KAAK,EAAE,MAAM,aAAa,CAAC;GACpC,UAAU,KAAK,YAAY,OAAO,EAAE,KAAK,YAAY,CAAC;GACtD,SAAS,KAAK,WAAW,MAAM;IAAE,WAAW;IAAY,SAAS;GAA0B,CAAC;EAC9F;CACF;CAEA,MAAM,IAAI,MACR,oCAAoC,OAAO,UAAU,QAAQ,IAAI,UAAU,oBAAoB,iBAAiB,oBAC5F,QAAQ,KAAK,IAAI,EAAE,EACzC;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;ACzGA,MAAM,UAAU;AAChB,MAAM,YAAY;AAClB,MAAM,uBAAuB;;;;;AAsB7B,SAAgB,aAAa,UAA+B,CAAC,GAAqB;CAChF,OAAO;EACL,IAAI;EACJ,SAAS;EACT,QAAQ;EACR,YAAY;EACZ,iBAAiB;EACjB;EACA,cAAc,QAAQ,YAAY,cAAc,CAAC,oBAAoB,IAAI,CAAC;CAC5E;AACF;;AAGA,SAAgB,aAAa,UAA+B,CAAC,GAAG;CAC9D,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,SAAS,QAAQ,UAAU;CAEjC,OAAO,aAAa;EAClB,IAAI;EACJ,SAAS;EACT,cAAc,YAAY,cAAc,CAAC,oBAAoB,IAAI,CAAC;EAElE,OACE,YAAY,cACR,EAGE,kBAAkB,YAAY,CAC5B;GACE,MAAM;GACN,WAAW;GACX,MACE,mCAAmC,OAAO,4CACZ,OAAO,sDACP,OAAO;GACvC,KAAK;EACP,GACA;GACE,MAAM;GACN,WAAW;GACX,KAAK,GAAG,OAAO;GACf,OAAO;GACP,KAAK;EACP,CACF,EACF,IACA,CAAC;EAEP,OAAO,EACL,oBAAoB,OACtB;CACF,CAAC;AACH"}
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@getvitops/emdash",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "EmDash CMS native plugin for the Vitops design system — Portable Text block types editors can insert from the admin, rendered with the design-system web components and CSS framework.",
5
5
  "license": "MIT",
6
6
  "files": [
7
7
  "dist",
8
- "src/astro"
8
+ "src/astro",
9
+ "CHANGELOG.md"
9
10
  ],
10
11
  "type": "module",
11
12
  "types": "./dist/index.d.mts",
@@ -21,10 +22,24 @@
21
22
  "access": "public"
22
23
  },
23
24
  "devDependencies": {
25
+ "@astrojs/cloudflare": "^14.0.0",
26
+ "@emdash-cms/cloudflare": "^0.31.0",
27
+ "astro": "^7.1.2",
24
28
  "emdash": "^0.31.0",
25
29
  "vitest": "^4.1.9"
26
30
  },
27
31
  "peerDependencies": {
32
+ "@astrojs/cloudflare": ">=14",
33
+ "@emdash-cms/cloudflare": ">=0.31.0",
34
+ "astro": ">=7",
28
35
  "emdash": ">=0.31.0"
36
+ },
37
+ "peerDependenciesMeta": {
38
+ "@astrojs/cloudflare": {
39
+ "optional": true
40
+ },
41
+ "@emdash-cms/cloudflare": {
42
+ "optional": true
43
+ }
29
44
  }
30
45
  }