pagiera 0.2.0-alpha.33
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/README.md +528 -0
- package/dist/adapters.d.ts +89 -0
- package/dist/adapters.d.ts.map +1 -0
- package/dist/adapters.js +2 -0
- package/dist/adapters.js.map +1 -0
- package/dist/client.d.ts +22 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +33 -0
- package/dist/client.js.map +1 -0
- package/dist/data.js +210 -0
- package/dist/data.js.map +7 -0
- package/dist/document.d.ts +63 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +25 -0
- package/dist/document.js.map +1 -0
- package/dist/editor.d.ts +14 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +59 -0
- package/dist/editor.js.map +1 -0
- package/dist/full-editor.d.ts +53 -0
- package/dist/full-editor.js +11117 -0
- package/dist/full-editor.js.map +7 -0
- package/dist/full.css +3498 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/app/api/ai-design/route.d.ts +3 -0
- package/dist/internal/app/api/ai-design/route.d.ts.map +1 -0
- package/dist/internal/app/api/ai-design/route.js +165 -0
- package/dist/internal/app/api/ai-design/route.js.map +1 -0
- package/dist/internal/app/p/editor/ai-panel.d.ts +27 -0
- package/dist/internal/app/p/editor/ai-panel.d.ts.map +1 -0
- package/dist/internal/app/p/editor/ai-panel.js +77 -0
- package/dist/internal/app/p/editor/ai-panel.js.map +1 -0
- package/dist/internal/app/p/editor/data-modal.d.ts +26 -0
- package/dist/internal/app/p/editor/data-modal.d.ts.map +1 -0
- package/dist/internal/app/p/editor/data-modal.js +94 -0
- package/dist/internal/app/p/editor/data-modal.js.map +1 -0
- package/dist/internal/app/p/editor/data-panel.d.ts +18 -0
- package/dist/internal/app/p/editor/data-panel.d.ts.map +1 -0
- package/dist/internal/app/p/editor/data-panel.js +45 -0
- package/dist/internal/app/p/editor/data-panel.js.map +1 -0
- package/dist/internal/app/p/editor/editor.d.ts +51 -0
- package/dist/internal/app/p/editor/editor.d.ts.map +1 -0
- package/dist/internal/app/p/editor/editor.js +1551 -0
- package/dist/internal/app/p/editor/editor.js.map +1 -0
- package/dist/internal/app/p/editor/fields.d.ts +111 -0
- package/dist/internal/app/p/editor/fields.d.ts.map +1 -0
- package/dist/internal/app/p/editor/fields.js +141 -0
- package/dist/internal/app/p/editor/fields.js.map +1 -0
- package/dist/internal/app/p/editor/inspector.d.ts +38 -0
- package/dist/internal/app/p/editor/inspector.d.ts.map +1 -0
- package/dist/internal/app/p/editor/inspector.js +336 -0
- package/dist/internal/app/p/editor/inspector.js.map +1 -0
- package/dist/internal/app/p/editor/library.d.ts +18 -0
- package/dist/internal/app/p/editor/library.d.ts.map +1 -0
- package/dist/internal/app/p/editor/library.js +61 -0
- package/dist/internal/app/p/editor/library.js.map +1 -0
- package/dist/internal/app/p/editor/parts.d.ts +75 -0
- package/dist/internal/app/p/editor/parts.d.ts.map +1 -0
- package/dist/internal/app/p/editor/parts.js +261 -0
- package/dist/internal/app/p/editor/parts.js.map +1 -0
- package/dist/internal/app/p/editor/templates-panel.d.ts +6 -0
- package/dist/internal/app/p/editor/templates-panel.d.ts.map +1 -0
- package/dist/internal/app/p/editor/templates-panel.js +12 -0
- package/dist/internal/app/p/editor/templates-panel.js.map +1 -0
- package/dist/internal/app/p/editor/use-canvas-view.d.ts +24 -0
- package/dist/internal/app/p/editor/use-canvas-view.d.ts.map +1 -0
- package/dist/internal/app/p/editor/use-canvas-view.js +242 -0
- package/dist/internal/app/p/editor/use-canvas-view.js.map +1 -0
- package/dist/internal/app/p/editor/use-editor.d.ts +48 -0
- package/dist/internal/app/p/editor/use-editor.d.ts.map +1 -0
- package/dist/internal/app/p/editor/use-editor.js +224 -0
- package/dist/internal/app/p/editor/use-editor.js.map +1 -0
- package/dist/internal/app/p/editor/variables-panel.d.ts +8 -0
- package/dist/internal/app/p/editor/variables-panel.d.ts.map +1 -0
- package/dist/internal/app/p/editor/variables-panel.js +52 -0
- package/dist/internal/app/p/editor/variables-panel.js.map +1 -0
- package/dist/internal/components/ui/select.d.ts +12 -0
- package/dist/internal/components/ui/select.d.ts.map +1 -0
- package/dist/internal/components/ui/select.js +32 -0
- package/dist/internal/components/ui/select.js.map +1 -0
- package/dist/internal/drizzle/index.d.ts +6 -0
- package/dist/internal/drizzle/index.d.ts.map +1 -0
- package/dist/internal/drizzle/index.js +20 -0
- package/dist/internal/drizzle/index.js.map +1 -0
- package/dist/internal/drizzle/schema.d.ts +405 -0
- package/dist/internal/drizzle/schema.d.ts.map +1 -0
- package/dist/internal/drizzle/schema.js +70 -0
- package/dist/internal/drizzle/schema.js.map +1 -0
- package/dist/internal/lib/data/context.d.ts +8 -0
- package/dist/internal/lib/data/context.d.ts.map +1 -0
- package/dist/internal/lib/data/context.js +17 -0
- package/dist/internal/lib/data/context.js.map +1 -0
- package/dist/internal/lib/data/source.d.ts +54 -0
- package/dist/internal/lib/data/source.d.ts.map +1 -0
- package/dist/internal/lib/data/source.js +229 -0
- package/dist/internal/lib/data/source.js.map +1 -0
- package/dist/internal/lib/editor/ai-types.d.ts +44 -0
- package/dist/internal/lib/editor/ai-types.d.ts.map +1 -0
- package/dist/internal/lib/editor/ai-types.js +2 -0
- package/dist/internal/lib/editor/ai-types.js.map +1 -0
- package/dist/internal/lib/editor/arrange.d.ts +12 -0
- package/dist/internal/lib/editor/arrange.d.ts.map +1 -0
- package/dist/internal/lib/editor/arrange.js +72 -0
- package/dist/internal/lib/editor/arrange.js.map +1 -0
- package/dist/internal/lib/editor/cascade.d.ts +39 -0
- package/dist/internal/lib/editor/cascade.d.ts.map +1 -0
- package/dist/internal/lib/editor/cascade.js +86 -0
- package/dist/internal/lib/editor/cascade.js.map +1 -0
- package/dist/internal/lib/editor/icon.d.ts +6 -0
- package/dist/internal/lib/editor/icon.d.ts.map +1 -0
- package/dist/internal/lib/editor/icon.js +13 -0
- package/dist/internal/lib/editor/icon.js.map +1 -0
- package/dist/internal/lib/editor/presets.d.ts +10 -0
- package/dist/internal/lib/editor/presets.d.ts.map +1 -0
- package/dist/internal/lib/editor/presets.js +83 -0
- package/dist/internal/lib/editor/presets.js.map +1 -0
- package/dist/internal/lib/editor/showcase.d.ts +14 -0
- package/dist/internal/lib/editor/showcase.d.ts.map +1 -0
- package/dist/internal/lib/editor/showcase.js +219 -0
- package/dist/internal/lib/editor/showcase.js.map +1 -0
- package/dist/internal/lib/editor/site-templates.d.ts +4 -0
- package/dist/internal/lib/editor/site-templates.d.ts.map +1 -0
- package/dist/internal/lib/editor/site-templates.js +156 -0
- package/dist/internal/lib/editor/site-templates.js.map +1 -0
- package/dist/internal/lib/editor/snap.d.ts +34 -0
- package/dist/internal/lib/editor/snap.d.ts.map +1 -0
- package/dist/internal/lib/editor/snap.js +70 -0
- package/dist/internal/lib/editor/snap.js.map +1 -0
- package/dist/internal/lib/editor/style.d.ts +53 -0
- package/dist/internal/lib/editor/style.d.ts.map +1 -0
- package/dist/internal/lib/editor/style.js +313 -0
- package/dist/internal/lib/editor/style.js.map +1 -0
- package/dist/internal/lib/editor/tree.d.ts +72 -0
- package/dist/internal/lib/editor/tree.d.ts.map +1 -0
- package/dist/internal/lib/editor/tree.js +301 -0
- package/dist/internal/lib/editor/tree.js.map +1 -0
- package/dist/internal/lib/editor/types.d.ts +273 -0
- package/dist/internal/lib/editor/types.d.ts.map +1 -0
- package/dist/internal/lib/editor/types.js +411 -0
- package/dist/internal/lib/editor/types.js.map +1 -0
- package/dist/internal/lib/editor/validate.d.ts +20 -0
- package/dist/internal/lib/editor/validate.d.ts.map +1 -0
- package/dist/internal/lib/editor/validate.js +467 -0
- package/dist/internal/lib/editor/validate.js.map +1 -0
- package/dist/internal/lib/pages.d.ts +83 -0
- package/dist/internal/lib/pages.d.ts.map +1 -0
- package/dist/internal/lib/pages.js +294 -0
- package/dist/internal/lib/pages.js.map +1 -0
- package/dist/internal/lib/render/bind.d.ts +18 -0
- package/dist/internal/lib/render/bind.d.ts.map +1 -0
- package/dist/internal/lib/render/bind.js +28 -0
- package/dist/internal/lib/render/bind.js.map +1 -0
- package/dist/internal/lib/render/css.d.ts +31 -0
- package/dist/internal/lib/render/css.d.ts.map +1 -0
- package/dist/internal/lib/render/css.js +239 -0
- package/dist/internal/lib/render/css.js.map +1 -0
- package/dist/internal/lib/render/load-data.d.ts +15 -0
- package/dist/internal/lib/render/load-data.d.ts.map +1 -0
- package/dist/internal/lib/render/load-data.js +39 -0
- package/dist/internal/lib/render/load-data.js.map +1 -0
- package/dist/internal/lib/render/page-render.d.ts +17 -0
- package/dist/internal/lib/render/page-render.d.ts.map +1 -0
- package/dist/internal/lib/render/page-render.js +117 -0
- package/dist/internal/lib/render/page-render.js.map +1 -0
- package/dist/internal/lib/utils.d.ts +3 -0
- package/dist/internal/lib/utils.d.ts.map +1 -0
- package/dist/internal/lib/utils.js +6 -0
- package/dist/internal/lib/utils.js.map +1 -0
- package/dist/manrope-data.d.ts +3 -0
- package/dist/manrope-data.d.ts.map +1 -0
- package/dist/manrope-data.js +3 -0
- package/dist/manrope-data.js.map +1 -0
- package/dist/page.d.ts +9 -0
- package/dist/page.d.ts.map +1 -0
- package/dist/page.js +148 -0
- package/dist/page.js.map +1 -0
- package/dist/provider.d.ts +14 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +45 -0
- package/dist/provider.js.map +1 -0
- package/dist/runtime.d.ts +8 -0
- package/dist/runtime.js +717 -0
- package/dist/runtime.js.map +7 -0
- package/dist/server.d.ts +31 -0
- package/dist/server.js +2267 -0
- package/dist/server.js.map +7 -0
- package/dist/styles.css +300 -0
- package/package.json +94 -0
- package/thumbnail.png +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
# Pagiera
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Pagiera is a full-stack visual website builder for React and Next.js. It ships the editor, responsive canvas, page management, reusable components, templates, AI generation, server-side data fetching, publishing runtime, PostgreSQL persistence, and Redis caching as one installable package.
|
|
6
|
+
|
|
7
|
+
Design in the editor and render the same document on the server. Published pages use semantic HTML, support dynamic routes and query parameters, and can load external API data before HTML is sent to the browser.
|
|
8
|
+
|
|
9
|
+
## Highlights
|
|
10
|
+
|
|
11
|
+
- Framer-style visual editor with an infinite canvas
|
|
12
|
+
- Responsive breakpoints with isolated overrides
|
|
13
|
+
- Free and flow-based layouts
|
|
14
|
+
- Reusable components and variants
|
|
15
|
+
- Layers, assets, templates, icons, and component library
|
|
16
|
+
- Hover, press, entrance, loop, and scroll effects
|
|
17
|
+
- Custom easing curves and spring controls
|
|
18
|
+
- Site-wide fonts provided through `next/font`
|
|
19
|
+
- AI-assisted site generation through OpenRouter and the AI SDK
|
|
20
|
+
- GET, POST, PUT, PATCH, and DELETE data sources
|
|
21
|
+
- Path parameters, query parameters, headers, and request bodies
|
|
22
|
+
- Server-side Request and Repeat blocks
|
|
23
|
+
- Dynamic routes such as `/blog/:slug`
|
|
24
|
+
- Draft preview and published page rendering
|
|
25
|
+
- PostgreSQL persistence and optimistic revisions
|
|
26
|
+
- Redis-backed publishing cache and AI rate limiting
|
|
27
|
+
- Semantic output including `main`, `section`, `nav`, `header`, `footer`, headings, links, paragraphs, and buttons
|
|
28
|
+
|
|
29
|
+
## Requirements
|
|
30
|
+
|
|
31
|
+
- Node.js 20+
|
|
32
|
+
- React 18.3+
|
|
33
|
+
- Next.js App Router for the full-stack integration
|
|
34
|
+
- PostgreSQL
|
|
35
|
+
- Redis
|
|
36
|
+
- OpenRouter API key for AI generation
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install pagiera
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
bun add pagiera
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Environment variables
|
|
49
|
+
|
|
50
|
+
Create `.env.local`:
|
|
51
|
+
|
|
52
|
+
```env
|
|
53
|
+
PAGIERA_POSTGRES_URL=postgresql://postgres:postgres@localhost:5432/pagiera
|
|
54
|
+
PAGIERA_REDIS_URL=redis://localhost:6379
|
|
55
|
+
OPENROUTER_API_KEY=sk-or-v1-your-key
|
|
56
|
+
OPENROUTER_MODEL=anthropic/claude-sonnet-4.5
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Pagiera creates its required PostgreSQL tables when the server initializes. Redis is used for published-page caching and AI rate limiting.
|
|
60
|
+
|
|
61
|
+
## Next.js setup
|
|
62
|
+
|
|
63
|
+
### 1. Import the editor stylesheet
|
|
64
|
+
|
|
65
|
+
```css
|
|
66
|
+
/* src/app/globals.css */
|
|
67
|
+
@import "tailwindcss";
|
|
68
|
+
@import "pagiera/full.css";
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`full.css` contains the complete studio UI. Use `pagiera/styles.css` only with the smaller `PagieraEditor` API.
|
|
72
|
+
|
|
73
|
+
### 2. Add the font provider
|
|
74
|
+
|
|
75
|
+
The provider makes `next/font` fonts available in **Typography → Site font**. A selection applies to the canvas, preview, and published site.
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
// src/app/layout.tsx
|
|
79
|
+
import { Geist, Geist_Mono } from "next/font/google";
|
|
80
|
+
import { PagieraProvider } from "pagiera/provider";
|
|
81
|
+
import "./globals.css";
|
|
82
|
+
|
|
83
|
+
const geistSans = Geist({
|
|
84
|
+
variable: "--font-geist-sans",
|
|
85
|
+
subsets: ["latin"],
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const geistMono = Geist_Mono({
|
|
89
|
+
variable: "--font-geist-mono",
|
|
90
|
+
subsets: ["latin"],
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
export default function RootLayout({ children }: LayoutProps<"/">) {
|
|
94
|
+
return (
|
|
95
|
+
<html lang="en">
|
|
96
|
+
<body>
|
|
97
|
+
<PagieraProvider
|
|
98
|
+
fonts={[
|
|
99
|
+
{ variable: geistSans.variable, title: "Geist Sans" },
|
|
100
|
+
{ variable: geistMono.variable, title: "Geist Mono" },
|
|
101
|
+
]}
|
|
102
|
+
>
|
|
103
|
+
{children}
|
|
104
|
+
</PagieraProvider>
|
|
105
|
+
</body>
|
|
106
|
+
</html>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
type PagieraFont = {
|
|
113
|
+
variable: string;
|
|
114
|
+
title: string;
|
|
115
|
+
};
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 3. Mount the backend
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
// src/app/api/pagiera/[...path]/route.ts
|
|
122
|
+
import {
|
|
123
|
+
createPagieraRouteHandlers,
|
|
124
|
+
pagieraConfigFromEnv,
|
|
125
|
+
} from "pagiera/server";
|
|
126
|
+
|
|
127
|
+
export const maxDuration = 120;
|
|
128
|
+
export const dynamic = "force-dynamic";
|
|
129
|
+
|
|
130
|
+
const handlers = createPagieraRouteHandlers(pagieraConfigFromEnv());
|
|
131
|
+
export const { GET, POST, PUT, PATCH, DELETE } = handlers;
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Open `/api/pagiera/health` after starting the application to verify PostgreSQL, Redis, and the configured OpenRouter model.
|
|
135
|
+
|
|
136
|
+
### 4. Load editor data on the server
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
// src/lib/editor-bootstrap.ts
|
|
140
|
+
import {
|
|
141
|
+
getPagieraServer,
|
|
142
|
+
pagieraConfigFromEnv,
|
|
143
|
+
} from "pagiera/server";
|
|
144
|
+
|
|
145
|
+
export async function editorBootstrap(pageId?: string) {
|
|
146
|
+
const server = await getPagieraServer(pagieraConfigFromEnv());
|
|
147
|
+
const bootstrap = await server.getEditorBootstrap(pageId);
|
|
148
|
+
|
|
149
|
+
if (!bootstrap) throw new Error("Editor page not found");
|
|
150
|
+
return bootstrap;
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 5. Mount the studio
|
|
155
|
+
|
|
156
|
+
The initial document is server-rendered. A client wrapper handles editing and in-editor navigation.
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
// src/app/editor/pagiera-editor.tsx
|
|
160
|
+
"use client";
|
|
161
|
+
|
|
162
|
+
import { createPagieraClient } from "pagiera";
|
|
163
|
+
import PagieraStudio from "pagiera/full";
|
|
164
|
+
import type { PagieraStudioProps } from "pagiera/full";
|
|
165
|
+
import { useRouter } from "next/navigation";
|
|
166
|
+
import { useMemo, useState } from "react";
|
|
167
|
+
|
|
168
|
+
type Bootstrap = {
|
|
169
|
+
page: PagieraStudioProps["page"];
|
|
170
|
+
pages: PagieraStudioProps["pages"];
|
|
171
|
+
library: PagieraStudioProps["library"];
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export function PagieraEditorClient({ initial }: { initial: Bootstrap }) {
|
|
175
|
+
const router = useRouter();
|
|
176
|
+
const client = useMemo(() => createPagieraClient(), []);
|
|
177
|
+
const [bootstrap, setBootstrap] = useState(initial);
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<PagieraStudio
|
|
181
|
+
page={bootstrap.page}
|
|
182
|
+
pages={bootstrap.pages}
|
|
183
|
+
library={bootstrap.library}
|
|
184
|
+
adapters={{
|
|
185
|
+
...client.adapters,
|
|
186
|
+
navigate: async (pageId, options) => {
|
|
187
|
+
if (pageId === bootstrap.page.id) return;
|
|
188
|
+
const next = await client.bootstrap(pageId) as Bootstrap;
|
|
189
|
+
setBootstrap(next);
|
|
190
|
+
const href = `/editor/${encodeURIComponent(pageId)}`;
|
|
191
|
+
options?.replace ? router.replace(href) : router.push(href);
|
|
192
|
+
},
|
|
193
|
+
refresh: () => {
|
|
194
|
+
void client.bootstrap(bootstrap.page.id).then((next) => {
|
|
195
|
+
setBootstrap(next as Bootstrap);
|
|
196
|
+
});
|
|
197
|
+
},
|
|
198
|
+
previewHref: (pageId) => `/preview/${encodeURIComponent(pageId)}`,
|
|
199
|
+
publishedHref: (slug) => slug === "home" ? "/" : `/${slug}`,
|
|
200
|
+
}}
|
|
201
|
+
/>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
// src/app/editor/page.tsx
|
|
208
|
+
import { editorBootstrap } from "@/lib/editor-bootstrap";
|
|
209
|
+
import { PagieraEditorClient } from "./pagiera-editor";
|
|
210
|
+
|
|
211
|
+
export const dynamic = "force-dynamic";
|
|
212
|
+
|
|
213
|
+
export default async function EditorPage() {
|
|
214
|
+
return <PagieraEditorClient initial={await editorBootstrap()} />;
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
// src/app/editor/[pageId]/page.tsx
|
|
220
|
+
import { editorBootstrap } from "@/lib/editor-bootstrap";
|
|
221
|
+
import { PagieraEditorClient } from "../pagiera-editor";
|
|
222
|
+
|
|
223
|
+
export const dynamic = "force-dynamic";
|
|
224
|
+
|
|
225
|
+
export default async function EditorDocumentPage({ params }: {
|
|
226
|
+
params: Promise<{ pageId: string }>;
|
|
227
|
+
}) {
|
|
228
|
+
return (
|
|
229
|
+
<PagieraEditorClient
|
|
230
|
+
initial={await editorBootstrap((await params).pageId)}
|
|
231
|
+
/>
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Publishing pages
|
|
237
|
+
|
|
238
|
+
Load published documents on the server. Request blocks then finish before HTML is returned, making API-backed content available to search engines.
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
// src/lib/published-page.tsx
|
|
242
|
+
import { notFound } from "next/navigation";
|
|
243
|
+
import { RenderedPage } from "pagiera/runtime";
|
|
244
|
+
import {
|
|
245
|
+
getPagieraServer,
|
|
246
|
+
pagieraConfigFromEnv,
|
|
247
|
+
} from "pagiera/server";
|
|
248
|
+
|
|
249
|
+
type SearchParams = Promise<Record<string, string | string[] | undefined>>;
|
|
250
|
+
|
|
251
|
+
export async function renderPublishedPage(
|
|
252
|
+
slug: string,
|
|
253
|
+
searchParams: SearchParams,
|
|
254
|
+
params: Record<string, string> = {},
|
|
255
|
+
) {
|
|
256
|
+
const rawQuery = await searchParams;
|
|
257
|
+
const query = Object.fromEntries(
|
|
258
|
+
Object.entries(rawQuery).map(([key, value]) => [
|
|
259
|
+
key,
|
|
260
|
+
Array.isArray(value) ? value[0] ?? "" : value ?? "",
|
|
261
|
+
]),
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
const server = await getPagieraServer(pagieraConfigFromEnv());
|
|
265
|
+
const page = await server.getPublishedPage(slug, {
|
|
266
|
+
query,
|
|
267
|
+
params,
|
|
268
|
+
page: { slug },
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
if (!page) notFound();
|
|
272
|
+
|
|
273
|
+
return (
|
|
274
|
+
<RenderedPage
|
|
275
|
+
elements={page.elements}
|
|
276
|
+
rootStyle={page.rootStyle}
|
|
277
|
+
data={page.data}
|
|
278
|
+
/>
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
The `home` page is permanent and maps to `/`:
|
|
284
|
+
|
|
285
|
+
```tsx
|
|
286
|
+
// src/app/page.tsx
|
|
287
|
+
import { renderPublishedPage } from "@/lib/published-page";
|
|
288
|
+
|
|
289
|
+
export const dynamic = "force-dynamic";
|
|
290
|
+
|
|
291
|
+
export default function HomePage({ searchParams }: {
|
|
292
|
+
searchParams: Promise<Record<string, string | string[] | undefined>>;
|
|
293
|
+
}) {
|
|
294
|
+
return renderPublishedPage("home", searchParams);
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Other pages can use a catch-all route:
|
|
299
|
+
|
|
300
|
+
```tsx
|
|
301
|
+
// src/app/[...path]/page.tsx
|
|
302
|
+
import { renderPublishedPage } from "@/lib/published-page";
|
|
303
|
+
|
|
304
|
+
export const dynamic = "force-dynamic";
|
|
305
|
+
|
|
306
|
+
export default async function PublishedPage({ params, searchParams }: {
|
|
307
|
+
params: Promise<{ path: string[] }>;
|
|
308
|
+
searchParams: Promise<Record<string, string | string[] | undefined>>;
|
|
309
|
+
}) {
|
|
310
|
+
return renderPublishedPage((await params).path.join("/"), searchParams);
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Dynamic routes and request data
|
|
315
|
+
|
|
316
|
+
Page slugs may contain named parameters:
|
|
317
|
+
|
|
318
|
+
```text
|
|
319
|
+
blog/:slug
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
For `/blog/1`, pass the matched values in the server context:
|
|
323
|
+
|
|
324
|
+
```ts
|
|
325
|
+
{
|
|
326
|
+
params: { slug: "1" },
|
|
327
|
+
query: { preview: "true" }
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Request URLs, headers, query fields, and bodies may reference context values:
|
|
332
|
+
|
|
333
|
+
```text
|
|
334
|
+
https://dummyjson.com/posts/{{params.slug}}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
```text
|
|
338
|
+
https://api.example.com/search?q={{query.q}}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Request blocks expose one returned object directly to descendants. Repeat blocks iterate array results. Both are resolved on the server for published pages.
|
|
342
|
+
|
|
343
|
+
An upstream `404` can turn the complete route into a 404 page when the data source uses the `page-404` behavior.
|
|
344
|
+
|
|
345
|
+
## Preview routes
|
|
346
|
+
|
|
347
|
+
```tsx
|
|
348
|
+
// src/app/preview/[pageId]/page.tsx
|
|
349
|
+
import { notFound } from "next/navigation";
|
|
350
|
+
import { RenderedPage } from "pagiera/runtime";
|
|
351
|
+
import {
|
|
352
|
+
getPagieraServer,
|
|
353
|
+
pagieraConfigFromEnv,
|
|
354
|
+
} from "pagiera/server";
|
|
355
|
+
|
|
356
|
+
export const dynamic = "force-dynamic";
|
|
357
|
+
|
|
358
|
+
export default async function PreviewPage({ params }: {
|
|
359
|
+
params: Promise<{ pageId: string }>;
|
|
360
|
+
}) {
|
|
361
|
+
const server = await getPagieraServer(pagieraConfigFromEnv());
|
|
362
|
+
const page = await server.getPreviewPage((await params).pageId);
|
|
363
|
+
if (!page) notFound();
|
|
364
|
+
|
|
365
|
+
return (
|
|
366
|
+
<RenderedPage
|
|
367
|
+
elements={page.elements}
|
|
368
|
+
rootStyle={page.rootStyle}
|
|
369
|
+
data={page.data}
|
|
370
|
+
/>
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## Server API
|
|
376
|
+
|
|
377
|
+
```ts
|
|
378
|
+
import {
|
|
379
|
+
createPagieraRouteHandlers,
|
|
380
|
+
createPagieraServer,
|
|
381
|
+
getPagieraServer,
|
|
382
|
+
pagieraConfigFromEnv,
|
|
383
|
+
} from "pagiera/server";
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
`getPagieraServer(config)` returns a shared server with:
|
|
387
|
+
|
|
388
|
+
- `handle(request)` — process a Pagiera API request
|
|
389
|
+
- `getEditorBootstrap(pageId?)` — load editor document, pages, and library
|
|
390
|
+
- `getPreviewPage(pageId, context?)` — load a draft and resolve data
|
|
391
|
+
- `getPublishedDocument(slug)` — load published document metadata
|
|
392
|
+
- `getPublishedPage(slug, context?)` — load published document and SSR data
|
|
393
|
+
- `close()` — close PostgreSQL and Redis connections
|
|
394
|
+
- `pool` — PostgreSQL pool
|
|
395
|
+
- `redis` — Redis client
|
|
396
|
+
|
|
397
|
+
```ts
|
|
398
|
+
type PagieraServerConfig = {
|
|
399
|
+
postgresUrl: string;
|
|
400
|
+
redisUrl: string;
|
|
401
|
+
openRouterApiKey: string;
|
|
402
|
+
openRouterModel: string;
|
|
403
|
+
basePath?: string;
|
|
404
|
+
aiRateLimitPerMinute?: number;
|
|
405
|
+
};
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## Client API
|
|
409
|
+
|
|
410
|
+
```ts
|
|
411
|
+
import { createPagieraClient } from "pagiera";
|
|
412
|
+
|
|
413
|
+
const client = createPagieraClient({
|
|
414
|
+
baseUrl: "/api/pagiera",
|
|
415
|
+
});
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
The client includes:
|
|
419
|
+
|
|
420
|
+
- `bootstrap(pageId?)`
|
|
421
|
+
- `loadPage(pageId)`
|
|
422
|
+
- `adapters.save(...)`
|
|
423
|
+
- `adapters.createPage(...)`
|
|
424
|
+
- `adapters.renamePage(...)`
|
|
425
|
+
- `adapters.duplicatePage(...)`
|
|
426
|
+
- `adapters.deletePage(...)`
|
|
427
|
+
- `adapters.installTemplate(...)`
|
|
428
|
+
- `adapters.publishPage(...)`
|
|
429
|
+
- `adapters.unpublishPage(...)`
|
|
430
|
+
- `adapters.previewSource(...)`
|
|
431
|
+
- `adapters.generate(...)`
|
|
432
|
+
|
|
433
|
+
## Package exports
|
|
434
|
+
|
|
435
|
+
| Import | Purpose |
|
|
436
|
+
| --- | --- |
|
|
437
|
+
| `pagiera` | Document utilities, lightweight editor, renderer, client adapters |
|
|
438
|
+
| `pagiera/provider` | Provider, `next/font` integration, font types |
|
|
439
|
+
| `pagiera/full` | Complete visual studio component |
|
|
440
|
+
| `pagiera/full.css` | Complete studio stylesheet |
|
|
441
|
+
| `pagiera/runtime` | Published and preview renderer |
|
|
442
|
+
| `pagiera/data` | Server-side page data loader |
|
|
443
|
+
| `pagiera/server` | PostgreSQL, Redis, OpenRouter, API, publishing server |
|
|
444
|
+
| `pagiera/styles.css` | Lightweight editor stylesheet |
|
|
445
|
+
|
|
446
|
+
## Lightweight editor
|
|
447
|
+
|
|
448
|
+
```tsx
|
|
449
|
+
"use client";
|
|
450
|
+
|
|
451
|
+
import { useState } from "react";
|
|
452
|
+
import {
|
|
453
|
+
createDocument,
|
|
454
|
+
PagieraEditor,
|
|
455
|
+
type PagieraDocument,
|
|
456
|
+
} from "pagiera";
|
|
457
|
+
import "pagiera/styles.css";
|
|
458
|
+
|
|
459
|
+
export function SmallEditor() {
|
|
460
|
+
const [document, setDocument] = useState<PagieraDocument>(() => (
|
|
461
|
+
createDocument()
|
|
462
|
+
));
|
|
463
|
+
|
|
464
|
+
return (
|
|
465
|
+
<PagieraEditor
|
|
466
|
+
value={document}
|
|
467
|
+
onChange={setDocument}
|
|
468
|
+
adapters={{
|
|
469
|
+
save: async (nextDocument) => saveDocument(nextDocument),
|
|
470
|
+
}}
|
|
471
|
+
/>
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
## Security
|
|
477
|
+
|
|
478
|
+
The Pagiera API can create, modify, publish, and delete content. Protect `/editor`, `/preview`, and write operations under `/api/pagiera` with your application's authentication and authorization layer before deploying publicly.
|
|
479
|
+
|
|
480
|
+
Never expose `PAGIERA_POSTGRES_URL`, `PAGIERA_REDIS_URL`, or `OPENROUTER_API_KEY` to client components. These are server-only values.
|
|
481
|
+
|
|
482
|
+
## Troubleshooting
|
|
483
|
+
|
|
484
|
+
### `server.getEditorBootstrap is not a function`
|
|
485
|
+
|
|
486
|
+
Make sure all imports resolve to one installed Pagiera version. Remove stale local tarballs or lockfile entries, reinstall, and verify:
|
|
487
|
+
|
|
488
|
+
```bash
|
|
489
|
+
node -p "require('pagiera/package.json').version"
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### CSS says `@import` must precede other rules
|
|
493
|
+
|
|
494
|
+
Upgrade Pagiera. Current builds use `@font-face` for the editor font and do not distribute a Google Fonts `@import`.
|
|
495
|
+
|
|
496
|
+
### PostgreSQL or Redis fails
|
|
497
|
+
|
|
498
|
+
Open `/api/pagiera/health`, then verify both connection URLs are reachable from the Next.js server process.
|
|
499
|
+
|
|
500
|
+
### AI generation fails
|
|
501
|
+
|
|
502
|
+
Verify the OpenRouter key, model identifier, model availability, and account credits.
|
|
503
|
+
|
|
504
|
+
### Published API data is missing from HTML
|
|
505
|
+
|
|
506
|
+
Use `server.getPublishedPage(...)` or `loadPageData(...)` in a Server Component before rendering `RenderedPage`. Client-only fetching does not provide the same SEO behavior.
|
|
507
|
+
|
|
508
|
+
## Local package example
|
|
509
|
+
|
|
510
|
+
This repository includes `package-example`, a standalone consumer that installs the generated `.tgz` instead of importing package source files.
|
|
511
|
+
|
|
512
|
+
```bash
|
|
513
|
+
cd package-example
|
|
514
|
+
cp .env.example .env.local
|
|
515
|
+
bun install
|
|
516
|
+
bun run dev
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
Open:
|
|
520
|
+
|
|
521
|
+
- `/editor` — visual editor
|
|
522
|
+
- `/preview/:pageId` — draft renderer
|
|
523
|
+
- `/` — published `home` page
|
|
524
|
+
- `/api/pagiera/health` — backend diagnostics
|
|
525
|
+
|
|
526
|
+
## License
|
|
527
|
+
|
|
528
|
+
MIT
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { PagieraDocument } from "./document.js";
|
|
2
|
+
export type PagieraPageSummary = {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
slug: string;
|
|
6
|
+
published?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type PagieraSaveResult = {
|
|
9
|
+
status: "saved";
|
|
10
|
+
version?: number;
|
|
11
|
+
} | {
|
|
12
|
+
status: "conflict";
|
|
13
|
+
document: PagieraDocument;
|
|
14
|
+
version?: number;
|
|
15
|
+
} | {
|
|
16
|
+
status: "error";
|
|
17
|
+
message: string;
|
|
18
|
+
};
|
|
19
|
+
export type PagieraDataPreview = {
|
|
20
|
+
rows: Array<Record<string, unknown>>;
|
|
21
|
+
keys: string[];
|
|
22
|
+
};
|
|
23
|
+
export type PagieraAdapters = {
|
|
24
|
+
persistence?: {
|
|
25
|
+
save(document: PagieraDocument, context: {
|
|
26
|
+
pageId?: string;
|
|
27
|
+
version?: number;
|
|
28
|
+
}): Promise<PagieraSaveResult>;
|
|
29
|
+
};
|
|
30
|
+
pages?: {
|
|
31
|
+
list(): Promise<PagieraPageSummary[]>;
|
|
32
|
+
load(pageId: string): Promise<PagieraDocument>;
|
|
33
|
+
create(input: {
|
|
34
|
+
name: string;
|
|
35
|
+
slug: string;
|
|
36
|
+
}): Promise<PagieraPageSummary>;
|
|
37
|
+
rename(pageId: string, input: {
|
|
38
|
+
name: string;
|
|
39
|
+
slug: string;
|
|
40
|
+
}): Promise<void>;
|
|
41
|
+
duplicate(pageId: string, input: {
|
|
42
|
+
name: string;
|
|
43
|
+
slug: string;
|
|
44
|
+
}): Promise<PagieraPageSummary>;
|
|
45
|
+
delete(pageId: string): Promise<void>;
|
|
46
|
+
publish(pageId: string, document: PagieraDocument): Promise<{
|
|
47
|
+
url?: string;
|
|
48
|
+
}>;
|
|
49
|
+
unpublish(pageId: string): Promise<void>;
|
|
50
|
+
};
|
|
51
|
+
ai?: {
|
|
52
|
+
generate(input: {
|
|
53
|
+
prompt: string;
|
|
54
|
+
document: PagieraDocument;
|
|
55
|
+
breakpoint: string;
|
|
56
|
+
history?: Array<{
|
|
57
|
+
role: "user" | "assistant";
|
|
58
|
+
text: string;
|
|
59
|
+
}>;
|
|
60
|
+
}): Promise<PagieraDocument>;
|
|
61
|
+
};
|
|
62
|
+
data?: {
|
|
63
|
+
preview(source: unknown, context?: Record<string, unknown>): Promise<PagieraDataPreview>;
|
|
64
|
+
};
|
|
65
|
+
assets?: {
|
|
66
|
+
upload(file: File): Promise<{
|
|
67
|
+
url: string;
|
|
68
|
+
name?: string;
|
|
69
|
+
}>;
|
|
70
|
+
list?(): Promise<Array<{
|
|
71
|
+
id: string;
|
|
72
|
+
name: string;
|
|
73
|
+
url: string;
|
|
74
|
+
type?: string;
|
|
75
|
+
}>>;
|
|
76
|
+
};
|
|
77
|
+
templates?: {
|
|
78
|
+
install(templateId: string): Promise<{
|
|
79
|
+
pages: PagieraPageSummary[];
|
|
80
|
+
activePageId?: string;
|
|
81
|
+
}>;
|
|
82
|
+
};
|
|
83
|
+
navigation?: {
|
|
84
|
+
openPage(pageId: string): void;
|
|
85
|
+
openPreview?(pageId?: string): void;
|
|
86
|
+
openPublished?(url: string): void;
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=adapters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":"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"}
|
package/dist/adapters.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.js","sourceRoot":"","sources":["../src/adapters.ts"],"names":[],"mappings":""}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type PagieraClientOptions = {
|
|
2
|
+
baseUrl?: string;
|
|
3
|
+
fetch?: typeof globalThis.fetch;
|
|
4
|
+
};
|
|
5
|
+
/** Ready-to-pass adapters for `<PagieraStudio />`. */
|
|
6
|
+
export declare function createPagieraClient(options?: PagieraClientOptions): {
|
|
7
|
+
bootstrap: (pageId?: string) => Promise<any>;
|
|
8
|
+
loadPage: (pageId: string) => Promise<any>;
|
|
9
|
+
adapters: {
|
|
10
|
+
save: (pageId: string, document: unknown, expectedVersion: number) => Promise<any>;
|
|
11
|
+
createPage: (name: string, slug: string) => Promise<any>;
|
|
12
|
+
renamePage: (id: string, name: string, slug: string) => Promise<any>;
|
|
13
|
+
duplicatePage: (id: string, name: string, slug: string) => Promise<any>;
|
|
14
|
+
deletePage: (id: string) => Promise<any>;
|
|
15
|
+
installTemplate: (id: string) => Promise<any>;
|
|
16
|
+
publishPage: (id: string) => Promise<any>;
|
|
17
|
+
unpublishPage: (id: string) => Promise<any>;
|
|
18
|
+
previewSource: (source: unknown, sampleQuery: string) => Promise<any>;
|
|
19
|
+
generate: (request: unknown) => Promise<any>;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACnC,CAAC;AAYF,sDAAsD;AACtD,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB;yBAOzC,MAAM;uBACR,MAAM;;uBAEN,MAAM,YAAY,OAAO,mBAAmB,MAAM;2BAC9C,MAAM,QAAQ,MAAM;yBACtB,MAAM,QAAQ,MAAM,QAAQ,MAAM;4BAC/B,MAAM,QAAQ,MAAM,QAAQ,MAAM;yBACrC,MAAM;8BACD,MAAM;0BACV,MAAM;4BACJ,MAAM;gCACF,OAAO,eAAe,MAAM;4BAChC,OAAO;;EAGtC"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
async function jsonRequest(fetcher, url, init) {
|
|
2
|
+
const response = await fetcher(url, {
|
|
3
|
+
...init,
|
|
4
|
+
headers: { "Content-Type": "application/json", ...init?.headers },
|
|
5
|
+
});
|
|
6
|
+
const body = await response.json().catch(() => null);
|
|
7
|
+
if (!response.ok)
|
|
8
|
+
throw new Error(body?.error ?? `Pagiera API request failed (${response.status})`);
|
|
9
|
+
return body;
|
|
10
|
+
}
|
|
11
|
+
/** Ready-to-pass adapters for `<PagieraStudio />`. */
|
|
12
|
+
export function createPagieraClient(options = {}) {
|
|
13
|
+
const base = (options.baseUrl ?? "/api/pagiera").replace(/\/$/, "");
|
|
14
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
15
|
+
const call = (path, method, body) => jsonRequest(fetcher, `${base}${path}`, { method, body: body === undefined ? undefined : JSON.stringify(body) });
|
|
16
|
+
return {
|
|
17
|
+
bootstrap: (pageId) => jsonRequest(fetcher, `${base}/bootstrap${pageId ? `?pageId=${encodeURIComponent(pageId)}` : ""}`),
|
|
18
|
+
loadPage: (pageId) => jsonRequest(fetcher, `${base}/pages/${pageId}`),
|
|
19
|
+
adapters: {
|
|
20
|
+
save: (pageId, document, expectedVersion) => call(`/pages/${pageId}/save`, "POST", { document, expectedVersion }),
|
|
21
|
+
createPage: (name, slug) => call("/pages", "POST", { name, slug }),
|
|
22
|
+
renamePage: (id, name, slug) => call(`/pages/${id}`, "PATCH", { name, slug }),
|
|
23
|
+
duplicatePage: (id, name, slug) => call(`/pages/${id}/duplicate`, "POST", { name, slug }),
|
|
24
|
+
deletePage: (id) => call(`/pages/${id}`, "DELETE"),
|
|
25
|
+
installTemplate: (id) => call(`/templates/${id}`, "POST"),
|
|
26
|
+
publishPage: (id) => call(`/pages/${id}/publish`, "POST"),
|
|
27
|
+
unpublishPage: (id) => call(`/pages/${id}/unpublish`, "POST"),
|
|
28
|
+
previewSource: (source, sampleQuery) => call("/data/preview", "POST", { source, sampleQuery }),
|
|
29
|
+
generate: (request) => call("/ai", "POST", request),
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|