@commonpub/layer 0.5.2 → 0.5.4

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.
@@ -47,7 +47,7 @@ const blockTypes: BlockTypeGroup[] = [
47
47
  ];
48
48
 
49
49
  const openSections = ref<Record<string, boolean>>({
50
- meta: true, tags: true, visibility: true, cover: false, checklist: true,
50
+ meta: true, tags: true, visibility: true, cover: false, seo: false, checklist: true,
51
51
  });
52
52
  function toggleSection(key: string): void {
53
53
  openSections.value[key] = !openSections.value[key];
@@ -284,6 +284,14 @@ const blockCount = computed(() => props.blockEditor.blocks.value.length);
284
284
  </div>
285
285
  </EditorsEditorSection>
286
286
 
287
+ <EditorsEditorSection title="SEO" icon="fa-magnifying-glass" :open="openSections.seo" @toggle="toggleSection('seo')">
288
+ <div class="cpub-pe-field">
289
+ <label class="cpub-pe-flabel">Meta Description</label>
290
+ <textarea class="cpub-pe-textarea" rows="3" :value="metadata.seoDescription as string" placeholder="Search engine description (recommended 50-160 chars)" @input="updateMeta('seoDescription', ($event.target as HTMLTextAreaElement).value)" />
291
+ <span class="cpub-pe-hint">{{ ((metadata.seoDescription as string) || '').length }}/160</span>
292
+ </div>
293
+ </EditorsEditorSection>
294
+
287
295
  <EditorsEditorSection title="Checklist" icon="fa-circle-check" :open="openSections.checklist" @toggle="toggleSection('checklist')">
288
296
  <div class="cpub-pe-checklist">
289
297
  <div v-for="item in checklist" :key="item.label" class="cpub-pe-check-item" :class="{ pass: item.pass }">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commonpub/layer",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "type": "module",
5
5
  "main": "./nuxt.config.ts",
6
6
  "files": [
@@ -51,14 +51,14 @@
51
51
  "vue-router": "^4.3.0",
52
52
  "zod": "^4.3.6",
53
53
  "@commonpub/auth": "0.5.0",
54
- "@commonpub/docs": "0.6.0",
55
54
  "@commonpub/config": "0.8.0",
55
+ "@commonpub/docs": "0.6.0",
56
56
  "@commonpub/editor": "0.5.0",
57
- "@commonpub/explainer": "0.6.2",
58
- "@commonpub/schema": "0.8.16",
59
- "@commonpub/protocol": "0.9.6",
60
- "@commonpub/server": "2.24.0",
57
+ "@commonpub/explainer": "0.6.4",
61
58
  "@commonpub/learning": "0.5.0",
59
+ "@commonpub/schema": "0.8.17",
60
+ "@commonpub/protocol": "0.9.6",
61
+ "@commonpub/server": "2.24.1",
62
62
  "@commonpub/ui": "0.8.4"
63
63
  },
64
64
  "devDependencies": {
@@ -111,7 +111,7 @@ async function selectPage(pageId: string): Promise<void> {
111
111
 
112
112
  // Load properties
113
113
  pageSlug.value = page.slug ?? '';
114
- pageStatus.value = ((page as Record<string, unknown>).status as 'draft' | 'published') || 'draft';
114
+ pageStatus.value = ((page as unknown as Record<string, unknown>).status as 'draft' | 'published') || 'draft';
115
115
  isDirty.value = false;
116
116
  autoSaveStatus.value = 'idle';
117
117
 
@@ -20,7 +20,15 @@ export default defineEventHandler(async (event) => {
20
20
  if (!page) throw createError({ statusCode: 404, statusMessage: 'Page not found' });
21
21
 
22
22
  // Handle dual-format content: BlockTuple[] (new) or markdown string (legacy)
23
- const content = page.content;
23
+ // Content is stored as TEXT — JSON arrays come back as strings, need parsing
24
+ let content: string | unknown[] = page.content ?? '';
25
+ if (typeof content === 'string' && content.trimStart().startsWith('[')) {
26
+ try {
27
+ content = JSON.parse(content);
28
+ } catch {
29
+ // Not valid JSON — keep as markdown string
30
+ }
31
+ }
24
32
 
25
33
  if (Array.isArray(content)) {
26
34
  // New BlockTuple format — extract text for TOC generation