@rimelight/cms 0.0.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/README.md +19 -0
- package/package.json +69 -0
- package/src/astro/BlockRenderer.astro +111 -0
- package/src/astro/PageRenderer.astro +23 -0
- package/src/astro/blocks/CalloutBlock.astro +78 -0
- package/src/astro/blocks/CardBlock.astro +43 -0
- package/src/astro/blocks/CardsBlock.astro +24 -0
- package/src/astro/blocks/CodeBlock.astro +16 -0
- package/src/astro/blocks/DialogueBlock.astro +23 -0
- package/src/astro/blocks/FileTreeBlock.astro +45 -0
- package/src/astro/blocks/ImageBlock.astro +17 -0
- package/src/astro/blocks/OrderedListBlock.astro +55 -0
- package/src/astro/blocks/ParagraphBlock.astro +65 -0
- package/src/astro/blocks/SceneBlock.astro +65 -0
- package/src/astro/blocks/ScriptBlock.astro +59 -0
- package/src/astro/blocks/SectionBlock.astro +46 -0
- package/src/astro/blocks/StepItemBlock.astro +25 -0
- package/src/astro/blocks/StepsBlock.astro +14 -0
- package/src/astro/blocks/TabItemBlock.astro +19 -0
- package/src/astro/blocks/TableBlock.astro +49 -0
- package/src/astro/blocks/TabsBlock.astro +67 -0
- package/src/astro/blocks/UnorderedListBlock.astro +55 -0
- package/src/auth/editor-guards.ts +148 -0
- package/src/auth/filter-blocks.ts +44 -0
- package/src/auth/filter-templates.ts +81 -0
- package/src/auth/permissions.ts +40 -0
- package/src/cache/purge.ts +37 -0
- package/src/client/components/RimelightBlock.tsx +487 -0
- package/src/client/components/RimelightBlockPicker.tsx +305 -0
- package/src/client/components/RimelightEditor.tsx +131 -0
- package/src/client/components/RimelightEditorLayout.tsx +143 -0
- package/src/client/components/RimelightPreview.tsx +354 -0
- package/src/client/components/RimelightPropertiesPanel.tsx +408 -0
- package/src/client/components/RimelightTemplateEditor.tsx +245 -0
- package/src/client/components/editors/CalloutEditor.tsx +185 -0
- package/src/client/components/editors/CardEditor.tsx +60 -0
- package/src/client/components/editors/CardsEditor.tsx +132 -0
- package/src/client/components/editors/CodeEditor.tsx +101 -0
- package/src/client/components/editors/DialogueEditor.tsx +52 -0
- package/src/client/components/editors/FileTreeEditor.tsx +65 -0
- package/src/client/components/editors/ImageEditor.tsx +70 -0
- package/src/client/components/editors/ParagraphEditor.tsx +314 -0
- package/src/client/components/editors/SceneEditor.tsx +245 -0
- package/src/client/components/editors/ScriptEditor.tsx +245 -0
- package/src/client/components/editors/SectionEditor.tsx +139 -0
- package/src/client/components/editors/StepItemEditor.tsx +117 -0
- package/src/client/components/editors/StepsEditor.tsx +105 -0
- package/src/client/components/editors/TabItemEditor.tsx +113 -0
- package/src/client/components/editors/TableEditor.tsx +181 -0
- package/src/client/components/editors/TabsEditor.tsx +105 -0
- package/src/client/components/index.ts +7 -0
- package/src/client/loader.ts +19 -0
- package/src/client/state/autosave.ts +122 -0
- package/src/client/state/editor-store.ts +411 -0
- package/src/client/state/history.ts +251 -0
- package/src/client/state/lock-manager.ts +89 -0
- package/src/client/styles/cms-editor.css +653 -0
- package/src/client/toast.ts +12 -0
- package/src/client/utils/sortable.ts +184 -0
- package/src/client/utils/splitpane.ts +87 -0
- package/src/client/utils/tree-sanitizer.ts +33 -0
- package/src/core/page-definitions.ts +502 -0
- package/src/core/registry.ts +99 -0
- package/src/core/template-sync.ts +75 -0
- package/src/core/types/blocks.ts +367 -0
- package/src/core/types/inline.ts +23 -0
- package/src/core/types/pages.ts +36 -0
- package/src/core/types/templates.ts +32 -0
- package/src/core/types/versioning.ts +44 -0
- package/src/core/validator.ts +28 -0
- package/src/env.d.ts +4 -0
- package/src/index.ts +47 -0
- package/src/markdown/index.ts +2 -0
- package/src/markdown/parser.ts +347 -0
- package/src/markdown/serializer.ts +219 -0
- package/src/migration.ts +155 -0
- package/src/schema/index.ts +8 -0
- package/src/schema/page_draft_locks.ts +13 -0
- package/src/schema/page_drafts.ts +18 -0
- package/src/schema/page_templates.ts +27 -0
- package/src/schema/page_version_approvals.ts +12 -0
- package/src/schema/page_version_comments.ts +14 -0
- package/src/schema/page_versions.ts +34 -0
- package/src/schema/pages.ts +42 -0
- package/src/schema/search.ts +23 -0
- package/src/search/query.ts +10 -0
- package/src/search/sync.ts +32 -0
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import type { InlineNode } from "./inline"
|
|
2
|
+
|
|
3
|
+
export type BlockType =
|
|
4
|
+
| "SectionBlock"
|
|
5
|
+
| "ParagraphBlock"
|
|
6
|
+
| "CalloutBlock"
|
|
7
|
+
| "ImageBlock"
|
|
8
|
+
| "ScriptBlock"
|
|
9
|
+
| "SceneBlock"
|
|
10
|
+
| "DialogueBlock"
|
|
11
|
+
| "CodeBlock"
|
|
12
|
+
| "TableBlock"
|
|
13
|
+
| "TabsBlock"
|
|
14
|
+
| "TabItemBlock"
|
|
15
|
+
| "StepsBlock"
|
|
16
|
+
| "StepItemBlock"
|
|
17
|
+
| "CardsBlock"
|
|
18
|
+
| "CardBlock"
|
|
19
|
+
| "FileTreeBlock"
|
|
20
|
+
| (string & {})
|
|
21
|
+
|
|
22
|
+
export type TimeOfDay = "MORNING" | "NOON" | "AFTERNOON" | "EVENING" | "NIGHT" | "OTHER"
|
|
23
|
+
export type Setting = "INTERIOR" | "EXTERIOR" | "OTHER"
|
|
24
|
+
export type Transition = "CUT_TO" | "CUT_BACK_TO" | "FADE_TO" | "NONE"
|
|
25
|
+
|
|
26
|
+
export interface ScriptBlockProps {
|
|
27
|
+
title: string
|
|
28
|
+
synopsis: string
|
|
29
|
+
characters: string[]
|
|
30
|
+
aPlot: string
|
|
31
|
+
bPlot: string
|
|
32
|
+
cPlot: string
|
|
33
|
+
stinger: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface SceneBlockProps {
|
|
37
|
+
location: string
|
|
38
|
+
timeOfDay: TimeOfDay
|
|
39
|
+
setting: Setting
|
|
40
|
+
transition: Transition
|
|
41
|
+
description: string
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface DialogueBlockProps {
|
|
45
|
+
character: string
|
|
46
|
+
parenthetical?: string
|
|
47
|
+
line: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface BaseBlock {
|
|
51
|
+
/**
|
|
52
|
+
* Unique UUID v4 identifier
|
|
53
|
+
*/
|
|
54
|
+
id: string
|
|
55
|
+
type: BlockType
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Structural Template Lock: If true, this block is a permanent template anchor and can NEVER be
|
|
59
|
+
* deleted, reordered, or removed.
|
|
60
|
+
*/
|
|
61
|
+
isTemplated?: boolean
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Property Content Lock: Controls whether block prop content can be edited. - boolean true: ALL
|
|
65
|
+
* properties of this block are locked from editing. - string[]: Specific property keys locked
|
|
66
|
+
* from editing (e.g. ["title", "disclaimer"]).
|
|
67
|
+
*/
|
|
68
|
+
templatedProps?: boolean | string[]
|
|
69
|
+
|
|
70
|
+
allowedRoles?: string[]
|
|
71
|
+
requiredPermission?: string
|
|
72
|
+
props: Record<string, any>
|
|
73
|
+
children?: BaseBlock[]
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ─── Typed block prop interfaces ─────────────────────────────────────────────
|
|
77
|
+
|
|
78
|
+
export type HeadingLevel = 2 | 3 | 4 | 5 | 6
|
|
79
|
+
|
|
80
|
+
export const MIN_SECTION_HEADING_LEVEL: HeadingLevel = 2
|
|
81
|
+
export const MAX_SECTION_HEADING_LEVEL: HeadingLevel = 6
|
|
82
|
+
export const MAX_SECTION_DEPTH = 4 // Depth 0 -> H2, Depth 4 -> H6
|
|
83
|
+
|
|
84
|
+
export function calculateHeadingLevel(sectionDepth: number): HeadingLevel {
|
|
85
|
+
const depth = Math.max(0, Math.floor(sectionDepth || 0))
|
|
86
|
+
return Math.min(MAX_SECTION_HEADING_LEVEL, depth + MIN_SECTION_HEADING_LEVEL) as HeadingLevel
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export type CalloutVariant =
|
|
90
|
+
| "info"
|
|
91
|
+
| "success"
|
|
92
|
+
| "warning"
|
|
93
|
+
| "error"
|
|
94
|
+
| "commentary"
|
|
95
|
+
| "ideation"
|
|
96
|
+
| "source"
|
|
97
|
+
|
|
98
|
+
export interface SectionBlockProps {
|
|
99
|
+
title: string
|
|
100
|
+
description?: string
|
|
101
|
+
level?: HeadingLevel
|
|
102
|
+
mainArticleSlug?: string
|
|
103
|
+
children: BaseBlock[]
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface ParagraphBlockProps {
|
|
107
|
+
/**
|
|
108
|
+
* Stored as an InlineNode array (structured AST). Fallback: { en: string } or plain string.
|
|
109
|
+
*/
|
|
110
|
+
text: InlineNode[] | { en: string } | string
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface CalloutBlockProps {
|
|
114
|
+
variant: CalloutVariant
|
|
115
|
+
to?: string
|
|
116
|
+
target?: string
|
|
117
|
+
children: BaseBlock[]
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface ImageBlockProps {
|
|
121
|
+
src: string
|
|
122
|
+
alt: string
|
|
123
|
+
caption?: string
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface CodeBlockProps {
|
|
127
|
+
code: string
|
|
128
|
+
language: string
|
|
129
|
+
caption?: string
|
|
130
|
+
title?: string
|
|
131
|
+
filename?: string
|
|
132
|
+
showLineNumbers?: boolean
|
|
133
|
+
highlightLines?: number[]
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface TableColumnDef {
|
|
137
|
+
key: string
|
|
138
|
+
header: string
|
|
139
|
+
align?: "left" | "center" | "right"
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface TableBlockProps {
|
|
143
|
+
columns: TableColumnDef[]
|
|
144
|
+
rows: Record<string, string>[]
|
|
145
|
+
caption?: string
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export interface TabItemBlockProps {
|
|
149
|
+
label: string
|
|
150
|
+
value?: string
|
|
151
|
+
icon?: string
|
|
152
|
+
children: BaseBlock[]
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export interface TabsBlockProps {
|
|
156
|
+
defaultValue?: string
|
|
157
|
+
children: BaseBlock[]
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface StepItemBlockProps {
|
|
161
|
+
title: string
|
|
162
|
+
description?: string
|
|
163
|
+
children: BaseBlock[]
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface StepsBlockProps {
|
|
167
|
+
children: BaseBlock[]
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface CardBlockProps {
|
|
171
|
+
title: string
|
|
172
|
+
description?: string
|
|
173
|
+
icon?: string
|
|
174
|
+
href?: string
|
|
175
|
+
badge?: string
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export interface CardsBlockProps {
|
|
179
|
+
columns?: 1 | 2 | 3 | 4
|
|
180
|
+
children: BaseBlock[]
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export interface FileTreeNode {
|
|
184
|
+
name: string
|
|
185
|
+
isDir?: boolean
|
|
186
|
+
children?: FileTreeNode[]
|
|
187
|
+
comment?: string
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export interface FileTreeBlockProps {
|
|
191
|
+
tree: FileTreeNode[]
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export interface TypedScriptBlockProps extends ScriptBlockProps {
|
|
195
|
+
children: BaseBlock[]
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export interface TypedSceneBlockProps extends SceneBlockProps {
|
|
199
|
+
children: BaseBlock[]
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// ─── Typed block discriminated union ─────────────────────────────────────────
|
|
203
|
+
|
|
204
|
+
export interface SectionBlock extends BaseBlock {
|
|
205
|
+
type: "SectionBlock"
|
|
206
|
+
props: SectionBlockProps
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export interface ParagraphBlock extends BaseBlock {
|
|
210
|
+
type: "ParagraphBlock"
|
|
211
|
+
props: ParagraphBlockProps
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export interface CalloutBlock extends BaseBlock {
|
|
215
|
+
type: "CalloutBlock"
|
|
216
|
+
props: CalloutBlockProps
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export interface ImageBlock extends BaseBlock {
|
|
220
|
+
type: "ImageBlock"
|
|
221
|
+
props: ImageBlockProps
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export interface ScriptBlock extends BaseBlock {
|
|
225
|
+
type: "ScriptBlock"
|
|
226
|
+
props: TypedScriptBlockProps
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export interface SceneBlock extends BaseBlock {
|
|
230
|
+
type: "SceneBlock"
|
|
231
|
+
props: TypedSceneBlockProps
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export interface DialogueBlock extends BaseBlock {
|
|
235
|
+
type: "DialogueBlock"
|
|
236
|
+
props: DialogueBlockProps
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export interface CodeBlock extends BaseBlock {
|
|
240
|
+
type: "CodeBlock"
|
|
241
|
+
props: CodeBlockProps
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export interface TableBlock extends BaseBlock {
|
|
245
|
+
type: "TableBlock"
|
|
246
|
+
props: TableBlockProps
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export interface TabsBlock extends BaseBlock {
|
|
250
|
+
type: "TabsBlock"
|
|
251
|
+
props: TabsBlockProps
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export interface TabItemBlock extends BaseBlock {
|
|
255
|
+
type: "TabItemBlock"
|
|
256
|
+
props: TabItemBlockProps
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export interface StepsBlock extends BaseBlock {
|
|
260
|
+
type: "StepsBlock"
|
|
261
|
+
props: StepsBlockProps
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export interface StepItemBlock extends BaseBlock {
|
|
265
|
+
type: "StepItemBlock"
|
|
266
|
+
props: StepItemBlockProps
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export interface CardsBlock extends BaseBlock {
|
|
270
|
+
type: "CardsBlock"
|
|
271
|
+
props: CardsBlockProps
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export interface CardBlock extends BaseBlock {
|
|
275
|
+
type: "CardBlock"
|
|
276
|
+
props: CardBlockProps
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export interface FileTreeBlock extends BaseBlock {
|
|
280
|
+
type: "FileTreeBlock"
|
|
281
|
+
props: FileTreeBlockProps
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export type TypedBlock =
|
|
285
|
+
| SectionBlock
|
|
286
|
+
| ParagraphBlock
|
|
287
|
+
| CalloutBlock
|
|
288
|
+
| ImageBlock
|
|
289
|
+
| ScriptBlock
|
|
290
|
+
| SceneBlock
|
|
291
|
+
| DialogueBlock
|
|
292
|
+
| CodeBlock
|
|
293
|
+
| TableBlock
|
|
294
|
+
| TabsBlock
|
|
295
|
+
| TabItemBlock
|
|
296
|
+
| StepsBlock
|
|
297
|
+
| StepItemBlock
|
|
298
|
+
| CardsBlock
|
|
299
|
+
| CardBlock
|
|
300
|
+
| FileTreeBlock
|
|
301
|
+
|
|
302
|
+
export const ALLOWED_CHILDREN_MAP: Record<string, BlockType[]> = {
|
|
303
|
+
Root: [
|
|
304
|
+
"SectionBlock",
|
|
305
|
+
"ParagraphBlock",
|
|
306
|
+
"CalloutBlock",
|
|
307
|
+
"ImageBlock",
|
|
308
|
+
"CodeBlock",
|
|
309
|
+
"ScriptBlock",
|
|
310
|
+
"SceneBlock",
|
|
311
|
+
"DialogueBlock",
|
|
312
|
+
"TableBlock",
|
|
313
|
+
"TabsBlock",
|
|
314
|
+
"StepsBlock",
|
|
315
|
+
"CardsBlock",
|
|
316
|
+
"FileTreeBlock"
|
|
317
|
+
],
|
|
318
|
+
SectionBlock: [
|
|
319
|
+
"SectionBlock",
|
|
320
|
+
"ParagraphBlock",
|
|
321
|
+
"CalloutBlock",
|
|
322
|
+
"ImageBlock",
|
|
323
|
+
"CodeBlock",
|
|
324
|
+
"ScriptBlock",
|
|
325
|
+
"TableBlock",
|
|
326
|
+
"TabsBlock",
|
|
327
|
+
"StepsBlock",
|
|
328
|
+
"CardsBlock",
|
|
329
|
+
"FileTreeBlock"
|
|
330
|
+
],
|
|
331
|
+
CalloutBlock: [
|
|
332
|
+
"ParagraphBlock",
|
|
333
|
+
"CalloutBlock",
|
|
334
|
+
"ImageBlock",
|
|
335
|
+
"CodeBlock",
|
|
336
|
+
"TableBlock",
|
|
337
|
+
"TabsBlock",
|
|
338
|
+
"StepsBlock",
|
|
339
|
+
"CardsBlock",
|
|
340
|
+
"FileTreeBlock"
|
|
341
|
+
],
|
|
342
|
+
TabsBlock: ["TabItemBlock"],
|
|
343
|
+
TabItemBlock: [
|
|
344
|
+
"ParagraphBlock",
|
|
345
|
+
"CalloutBlock",
|
|
346
|
+
"ImageBlock",
|
|
347
|
+
"CodeBlock",
|
|
348
|
+
"TableBlock",
|
|
349
|
+
"StepsBlock",
|
|
350
|
+
"CardsBlock",
|
|
351
|
+
"FileTreeBlock"
|
|
352
|
+
],
|
|
353
|
+
StepsBlock: ["StepItemBlock"],
|
|
354
|
+
StepItemBlock: [
|
|
355
|
+
"ParagraphBlock",
|
|
356
|
+
"CalloutBlock",
|
|
357
|
+
"ImageBlock",
|
|
358
|
+
"CodeBlock",
|
|
359
|
+
"TableBlock",
|
|
360
|
+
"TabsBlock",
|
|
361
|
+
"CardsBlock",
|
|
362
|
+
"FileTreeBlock"
|
|
363
|
+
],
|
|
364
|
+
CardsBlock: ["CardBlock"],
|
|
365
|
+
ScriptBlock: ["SceneBlock"],
|
|
366
|
+
SceneBlock: ["ParagraphBlock", "CalloutBlock", "DialogueBlock"]
|
|
367
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type InlineNodeType = "text" | "page_mention" | "user_mention" | "link" | "emoji"
|
|
2
|
+
|
|
3
|
+
export interface TextInlineNode {
|
|
4
|
+
type: "text"
|
|
5
|
+
text: string
|
|
6
|
+
marks?: Array<"bold" | "italic" | "underline" | "strikethrough" | "code">
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface PageMentionNode {
|
|
10
|
+
type: "page_mention"
|
|
11
|
+
pageId: string
|
|
12
|
+
pageSlug: string
|
|
13
|
+
displayTitle?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface LinkInlineNode {
|
|
17
|
+
type: "link"
|
|
18
|
+
url: string
|
|
19
|
+
children: TextInlineNode[]
|
|
20
|
+
openInNewTab?: boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type InlineNode = TextInlineNode | PageMentionNode | LinkInlineNode
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { BaseBlock } from "./blocks"
|
|
2
|
+
|
|
3
|
+
export type Localized<T = string> = Record<string, T>
|
|
4
|
+
|
|
5
|
+
export type PageType = "wiki" | "article" | "doc" | "announcement" | "landing" | (string & {})
|
|
6
|
+
|
|
7
|
+
export interface RegisterPageTypes {
|
|
8
|
+
wiki: Record<string, any>
|
|
9
|
+
article: Record<string, any>
|
|
10
|
+
doc: Record<string, any>
|
|
11
|
+
announcement: Record<string, any>
|
|
12
|
+
landing: Record<string, any>
|
|
13
|
+
[key: string]: Record<string, any>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface PageMetadata {
|
|
17
|
+
id: string
|
|
18
|
+
slug: string
|
|
19
|
+
type: PageType
|
|
20
|
+
templateId?: string | null
|
|
21
|
+
templateVersion?: number
|
|
22
|
+
title: Localized
|
|
23
|
+
description?: Localized
|
|
24
|
+
tags?: Localized[]
|
|
25
|
+
authorIds?: string[]
|
|
26
|
+
publishedVersionId?: string | null
|
|
27
|
+
postedAt?: Date | null
|
|
28
|
+
createdAt?: Date
|
|
29
|
+
updatedAt?: Date
|
|
30
|
+
deletedAt?: Date | null
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface PageContent<P = Record<string, any>> {
|
|
34
|
+
blocks: BaseBlock[]
|
|
35
|
+
properties: P
|
|
36
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { BaseBlock } from "./blocks"
|
|
2
|
+
import type { Localized, PageType } from "./pages"
|
|
3
|
+
|
|
4
|
+
export interface TemplateApprovalRules {
|
|
5
|
+
minApprovals?: number
|
|
6
|
+
allowSelfApproval?: boolean
|
|
7
|
+
requiredRolesForApproval?: string[]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface TemplateRolePermissions {
|
|
11
|
+
whoCanCreate?: string[]
|
|
12
|
+
whoCanEdit?: string[]
|
|
13
|
+
whoCanReview?: string[]
|
|
14
|
+
whoCanView?: string[]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface PageTemplate {
|
|
18
|
+
id: string
|
|
19
|
+
slug: string
|
|
20
|
+
title: Localized
|
|
21
|
+
description?: Localized
|
|
22
|
+
pageType: PageType
|
|
23
|
+
version: number
|
|
24
|
+
allowedRoles: string[]
|
|
25
|
+
rolePermissions?: TemplateRolePermissions
|
|
26
|
+
requiredPermission?: string | null
|
|
27
|
+
approvalRules: TemplateApprovalRules
|
|
28
|
+
defaultProperties: Record<string, any>
|
|
29
|
+
initialBlocks: BaseBlock[]
|
|
30
|
+
createdAt?: Date
|
|
31
|
+
updatedAt?: Date
|
|
32
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { BaseBlock } from "./blocks"
|
|
2
|
+
import type { Localized, PageType } from "./pages"
|
|
3
|
+
|
|
4
|
+
export type PageVersionStatus = "pending" | "approved" | "rejected" | "published"
|
|
5
|
+
|
|
6
|
+
export interface PageVersion {
|
|
7
|
+
id: string
|
|
8
|
+
pageId: string
|
|
9
|
+
versionNumber: number
|
|
10
|
+
status: PageVersionStatus
|
|
11
|
+
slug: string
|
|
12
|
+
type: PageType
|
|
13
|
+
title: Localized
|
|
14
|
+
description?: Localized
|
|
15
|
+
tags?: Localized[]
|
|
16
|
+
authorIds?: string[]
|
|
17
|
+
content: {
|
|
18
|
+
blocks: BaseBlock[]
|
|
19
|
+
properties: Record<string, any>
|
|
20
|
+
}
|
|
21
|
+
createdBy: string
|
|
22
|
+
approvedBy: string[]
|
|
23
|
+
approvedAt?: Date | null
|
|
24
|
+
changeSummary?: string | null
|
|
25
|
+
createdAt?: Date
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface PageVersionComment {
|
|
29
|
+
id: string
|
|
30
|
+
versionId: string
|
|
31
|
+
userId: string
|
|
32
|
+
userRole: string
|
|
33
|
+
content: string
|
|
34
|
+
blockId?: string | null
|
|
35
|
+
createdAt?: Date
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface PageVersionApproval {
|
|
39
|
+
id: string
|
|
40
|
+
versionId: string
|
|
41
|
+
userId: string
|
|
42
|
+
userRole: string
|
|
43
|
+
approvedAt?: Date
|
|
44
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { BaseBlock } from "./types/blocks"
|
|
2
|
+
|
|
3
|
+
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
|
|
4
|
+
|
|
5
|
+
export function isValidUUID(uuid: string): boolean {
|
|
6
|
+
return UUID_REGEX.test(uuid)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function validateBlockAST(blocks: BaseBlock[]): { valid: boolean; errors: string[] } {
|
|
10
|
+
const errors: string[] = []
|
|
11
|
+
|
|
12
|
+
function checkBlocks(nodes: BaseBlock[]) {
|
|
13
|
+
for (const b of nodes) {
|
|
14
|
+
if (!b.id || typeof b.id !== "string" || !isValidUUID(b.id)) {
|
|
15
|
+
errors.push(`Block of type '${b.type}' has invalid UUID identifier: '${b.id}'`)
|
|
16
|
+
}
|
|
17
|
+
if (!b.type || typeof b.type !== "string") {
|
|
18
|
+
errors.push(`Block missing valid 'type' field`)
|
|
19
|
+
}
|
|
20
|
+
if (b.children && Array.isArray(b.children)) {
|
|
21
|
+
checkBlocks(b.children)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
checkBlocks(blocks)
|
|
27
|
+
return { valid: errors.length === 0, errors }
|
|
28
|
+
}
|
package/src/env.d.ts
ADDED
package/src/index.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Core Types
|
|
2
|
+
export * from "./core/types/blocks.ts"
|
|
3
|
+
export * from "./core/types/inline.ts"
|
|
4
|
+
export * from "./core/types/pages.ts"
|
|
5
|
+
export * from "./core/types/templates.ts"
|
|
6
|
+
export * from "./core/types/versioning.ts"
|
|
7
|
+
export * from "./core/page-definitions.ts"
|
|
8
|
+
|
|
9
|
+
// Re-export specific types for convenience
|
|
10
|
+
export type {
|
|
11
|
+
TimeOfDay,
|
|
12
|
+
Setting,
|
|
13
|
+
Transition,
|
|
14
|
+
ScriptBlockProps,
|
|
15
|
+
SceneBlockProps,
|
|
16
|
+
DialogueBlockProps
|
|
17
|
+
} from "./core/types/blocks.ts"
|
|
18
|
+
|
|
19
|
+
// Core Services & Registries
|
|
20
|
+
export * from "./core/registry.ts"
|
|
21
|
+
export * from "./core/validator.ts"
|
|
22
|
+
export * from "./core/template-sync.ts"
|
|
23
|
+
|
|
24
|
+
// Auth & Security Guards
|
|
25
|
+
export * from "./auth/permissions.ts"
|
|
26
|
+
export * from "./auth/filter-blocks.ts"
|
|
27
|
+
export * from "./auth/editor-guards.ts"
|
|
28
|
+
export * from "./auth/filter-templates.ts"
|
|
29
|
+
|
|
30
|
+
// Edge Cache & Search
|
|
31
|
+
export * from "./cache/purge.ts"
|
|
32
|
+
export * from "./search/query.ts"
|
|
33
|
+
export * from "./search/sync.ts"
|
|
34
|
+
|
|
35
|
+
// Database Schemas & Migration
|
|
36
|
+
export * from "./schema/index.ts"
|
|
37
|
+
export * from "./migration.ts"
|
|
38
|
+
|
|
39
|
+
// Markdown Serialization & Parsing
|
|
40
|
+
export * from "./markdown/index.ts"
|
|
41
|
+
|
|
42
|
+
// Astro Components
|
|
43
|
+
export { default as PageRenderer } from "./astro/PageRenderer.astro"
|
|
44
|
+
export { default as BlockRenderer } from "./astro/BlockRenderer.astro"
|
|
45
|
+
|
|
46
|
+
// Toast API
|
|
47
|
+
export * from "./client/toast.ts"
|