@commonpub/layer 0.57.0 → 0.59.0

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.
Files changed (132) hide show
  1. package/components/LayoutRow.vue +8 -8
  2. package/components/LayoutSection.vue +8 -8
  3. package/components/LayoutSlot.vue +3 -3
  4. package/components/MirrorDetailModal.vue +3 -3
  5. package/components/MirrorRequestApproveModal.vue +3 -3
  6. package/components/PollDisplay.vue +1 -1
  7. package/components/RegistryDirectory.vue +2 -2
  8. package/components/admin/layouts/AdminLayoutsAutoForm.vue +1 -1
  9. package/components/admin/layouts/AdminLayoutsCanvas.vue +2 -2
  10. package/components/admin/layouts/AdminLayoutsConflictModal.vue +1 -1
  11. package/components/admin/layouts/AdminLayoutsHelpOverlay.vue +1 -1
  12. package/components/admin/layouts/AdminLayoutsInspectorPage.vue +1 -1
  13. package/components/admin/layouts/AdminLayoutsToolbar.vue +5 -5
  14. package/components/admin/theme/AdminThemeSceneGallery.vue +3 -3
  15. package/components/admin/theme/AdminThemeSceneProse.vue +3 -3
  16. package/components/admin/theme/AdminThemeTokenInput.vue +1 -1
  17. package/components/blocks/BlockCodeView.vue +2 -2
  18. package/components/blocks/BlockDividerView.vue +1 -1
  19. package/components/blocks/BlockPartsListView.vue +1 -1
  20. package/components/blocks/BlockQuizView.vue +1 -1
  21. package/components/blocks/BlockQuoteView.vue +1 -1
  22. package/components/contest/ContestHero.vue +2 -2
  23. package/components/contest/ContestStagesEditor.vue +4 -4
  24. package/components/editors/ArticleEditor.vue +1 -1
  25. package/components/editors/ExplainerEditor.vue +1 -1
  26. package/components/sections/SectionLearning.vue +1 -1
  27. package/components/views/ArticleView.vue +2 -2
  28. package/components/views/ProjectView.vue +3 -3
  29. package/composables/useAdminSidebar.ts +3 -3
  30. package/composables/useLayoutEditor.ts +1 -1
  31. package/composables/useLayoutHotkeys.ts +1 -1
  32. package/composables/useLayoutResize.ts +1 -1
  33. package/composables/usePublishValidation.ts +1 -1
  34. package/composables/useThemeAdmin.ts +2 -2
  35. package/error.vue +1 -1
  36. package/layouts/admin.vue +2 -2
  37. package/layouts/default.vue +2 -2
  38. package/package.json +6 -6
  39. package/pages/[type]/index.vue +1 -1
  40. package/pages/about.vue +3 -3
  41. package/pages/admin/api-keys.vue +5 -5
  42. package/pages/admin/audit.vue +2 -2
  43. package/pages/admin/categories.vue +1 -1
  44. package/pages/admin/content.vue +2 -2
  45. package/pages/admin/features.vue +1 -1
  46. package/pages/admin/federation.vue +9 -9
  47. package/pages/admin/homepage.vue +4 -4
  48. package/pages/admin/index.vue +1 -1
  49. package/pages/admin/layouts/[id].vue +18 -18
  50. package/pages/admin/layouts/index.vue +4 -4
  51. package/pages/admin/navigation.vue +1 -1
  52. package/pages/admin/reports.vue +1 -1
  53. package/pages/admin/settings.vue +2 -2
  54. package/pages/admin/theme/edit/[id].vue +2 -2
  55. package/pages/admin/theme/index.vue +5 -5
  56. package/pages/admin/users.vue +1 -1
  57. package/pages/auth/forgot-password.vue +1 -1
  58. package/pages/auth/login.vue +3 -3
  59. package/pages/auth/register.vue +1 -1
  60. package/pages/auth/reset-password.vue +1 -1
  61. package/pages/auth/verify-email.vue +1 -1
  62. package/pages/cert/[code].vue +1 -1
  63. package/pages/contests/[slug]/edit.vue +78 -19
  64. package/pages/contests/[slug]/index.vue +7 -7
  65. package/pages/contests/[slug]/judge.vue +15 -3
  66. package/pages/contests/[slug]/results.vue +5 -5
  67. package/pages/contests/create.vue +15 -15
  68. package/pages/contests/index.vue +2 -2
  69. package/pages/cookies.vue +1 -1
  70. package/pages/create.vue +2 -2
  71. package/pages/dashboard.vue +1 -1
  72. package/pages/docs/[siteSlug]/[...pagePath].vue +1 -1
  73. package/pages/docs/[siteSlug]/edit.vue +1 -1
  74. package/pages/docs/[siteSlug]/index.vue +1 -1
  75. package/pages/docs/create.vue +1 -1
  76. package/pages/docs/index.vue +1 -1
  77. package/pages/events/[slug]/edit.vue +1 -1
  78. package/pages/events/[slug]/index.vue +2 -2
  79. package/pages/events/create.vue +1 -1
  80. package/pages/events/index.vue +1 -1
  81. package/pages/explore.vue +1 -1
  82. package/pages/federated-hubs/[id]/index.vue +3 -3
  83. package/pages/federated-hubs/[id]/posts/[postId].vue +1 -1
  84. package/pages/federation/search.vue +1 -1
  85. package/pages/feed.vue +1 -1
  86. package/pages/hubs/[slug]/members.vue +1 -1
  87. package/pages/hubs/[slug]/posts/[postId].vue +1 -1
  88. package/pages/hubs/[slug]/settings.vue +5 -5
  89. package/pages/hubs/create.vue +6 -6
  90. package/pages/hubs/index.vue +1 -1
  91. package/pages/index.vue +2 -2
  92. package/pages/learn/[slug]/[lessonSlug]/edit.vue +1 -1
  93. package/pages/learn/[slug]/[lessonSlug]/index.vue +4 -4
  94. package/pages/learn/[slug]/edit.vue +1 -1
  95. package/pages/learn/[slug]/index.vue +1 -1
  96. package/pages/learn/create.vue +1 -1
  97. package/pages/learn/index.vue +2 -2
  98. package/pages/messages/[conversationId].vue +1 -1
  99. package/pages/messages/index.vue +1 -1
  100. package/pages/notifications.vue +1 -1
  101. package/pages/privacy.vue +5 -5
  102. package/pages/products/[slug].vue +1 -1
  103. package/pages/products/index.vue +1 -1
  104. package/pages/search.vue +1 -1
  105. package/pages/settings/profile.vue +1 -1
  106. package/pages/settings.vue +1 -1
  107. package/pages/tags/[slug].vue +1 -1
  108. package/pages/tags/index.vue +1 -1
  109. package/pages/terms.vue +1 -1
  110. package/pages/u/[username]/[type]/[slug]/edit.vue +3 -3
  111. package/pages/u/[username]/[type]/[slug]/index.vue +1 -1
  112. package/pages/u/[username]/followers.vue +1 -1
  113. package/pages/u/[username]/following.vue +1 -1
  114. package/pages/u/[username]/index.vue +3 -3
  115. package/pages/videos/[id].vue +1 -1
  116. package/pages/videos/index.vue +1 -1
  117. package/pages/videos/submit.vue +2 -2
  118. package/sections/builtin/hero.ts +1 -1
  119. package/sections/builtin/markdown.ts +1 -1
  120. package/server/api/admin/homepage/sections.put.ts +1 -1
  121. package/server/api/admin/layouts/[id].put.ts +1 -1
  122. package/server/api/contests/[slug]/entries.post.ts +3 -3
  123. package/server/api/hubs/[slug]/feed.xml.get.ts +1 -1
  124. package/server/api/users/[username]/feed.xml.get.ts +1 -1
  125. package/server/middleware/content-redirect.ts +1 -1
  126. package/server/plugins/federation-delivery.ts +1 -1
  127. package/server/plugins/federation-hub-sync.ts +1 -1
  128. package/server/plugins/registry-heartbeat.ts +3 -3
  129. package/server/plugins/search-index.ts +1 -1
  130. package/server/utils/email.ts +3 -3
  131. package/server/utils/instanceTheme.ts +1 -1
  132. package/utils/contestStages.ts +3 -3
@@ -86,7 +86,7 @@ export default defineEventHandler(async (event) => {
86
86
  try {
87
87
  const result = await migrateHomepageSectionsToLayout(db, {
88
88
  adminId: user.id,
89
- force: false, // changed from true see comment above
89
+ force: false, // changed from true, see comment above
90
90
  });
91
91
  if (result.migrated) {
92
92
  invalidateLayoutsByRouteCache();
@@ -103,7 +103,7 @@ export default defineEventHandler(async (event) => {
103
103
  ) {
104
104
  throw createError({
105
105
  statusCode: 400,
106
- statusMessage: 'Cannot change layout scope via PUT POST a new layout instead',
106
+ statusMessage: 'Cannot change layout scope via PUT, POST a new layout instead',
107
107
  });
108
108
  }
109
109
 
@@ -27,7 +27,7 @@ export default defineEventHandler(async (event): Promise<ContestEntryItem> => {
27
27
  const detail = contest.status === 'upcoming'
28
28
  ? 'Entries open once the contest is active.'
29
29
  : contest.status === 'judging'
30
- ? 'Submissions are closed the contest is being judged.'
30
+ ? 'Submissions are closed, the contest is being judged.'
31
31
  : `The contest is ${contest.status}.`;
32
32
  throw createError({ statusCode: 400, statusMessage: `This contest isn't accepting entries right now. ${detail}` });
33
33
  }
@@ -38,7 +38,7 @@ export default defineEventHandler(async (event): Promise<ContestEntryItem> => {
38
38
  .limit(1);
39
39
  if (!content) throw createError({ statusCode: 400, statusMessage: 'That content no longer exists.' });
40
40
  if (content.authorId !== user.id) throw createError({ statusCode: 403, statusMessage: 'You can only submit your own content.' });
41
- if (content.status !== 'published') throw createError({ statusCode: 400, statusMessage: 'That project isn’t published yet publish it first, then submit.' });
41
+ if (content.status !== 'published') throw createError({ statusCode: 400, statusMessage: 'That project isn’t published yet, publish it first, then submit.' });
42
42
  const eligible = contest.eligibleContentTypes ?? null;
43
43
  if (eligible && eligible.length > 0 && !eligible.includes(content.type)) {
44
44
  throw createError({ statusCode: 400, statusMessage: `This contest only accepts: ${eligible.join(', ')}.` });
@@ -48,7 +48,7 @@ export default defineEventHandler(async (event): Promise<ContestEntryItem> => {
48
48
  // cap + dedupes; a null here means already-entered or over the entry limit.
49
49
  const entry = await submitContestEntry(db, contest.id, input.contentId, user.id);
50
50
  if (!entry) {
51
- throw createError({ statusCode: 400, statusMessage: 'Couldn’t submit you may have already entered this project, or reached the contest’s entry limit.' });
51
+ throw createError({ statusCode: 400, statusMessage: 'Couldn’t submit, you may have already entered this project, or reached the contest’s entry limit.' });
52
52
  }
53
53
  return entry;
54
54
  });
@@ -44,7 +44,7 @@ export default defineEventHandler(async (event) => {
44
44
  const xml = `<?xml version="1.0" encoding="UTF-8"?>
45
45
  <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
46
46
  <channel>
47
- <title>${escapeXml(hub.name)} CommonPub</title>
47
+ <title>${escapeXml(hub.name)}, CommonPub</title>
48
48
  <link>${escapeXml(siteUrl)}/hubs/${escapeXml(slug)}</link>
49
49
  <description>${escapeXml(hub.description ?? `Content from ${hub.name}`)}</description>
50
50
  <language>en</language>
@@ -49,7 +49,7 @@ export default defineEventHandler(async (event) => {
49
49
  const xml = `<?xml version="1.0" encoding="UTF-8"?>
50
50
  <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
51
51
  <channel>
52
- <title>${escapeXml(displayName)} CommonPub</title>
52
+ <title>${escapeXml(displayName)}, CommonPub</title>
53
53
  <link>${escapeXml(siteUrl)}/u/${escapeXml(username)}</link>
54
54
  <description>Content by ${escapeXml(displayName)}</description>
55
55
  <language>en</language>
@@ -43,7 +43,7 @@ export default defineEventHandler(async (event) => {
43
43
  .where(and(eq(contentItems.slug, slug), isNull(contentItems.deletedAt)))
44
44
  .limit(1);
45
45
 
46
- if (!row) return; // Content not found let the page handler show 404
46
+ if (!row) return; // Content not found, let the page handler show 404
47
47
 
48
48
  const newPath = isEdit
49
49
  ? `/u/${row.username}/${row.type}/${row.slug}/edit`
@@ -15,7 +15,7 @@ export default defineNitroPlugin((nitro) => {
15
15
  try {
16
16
  const config = useConfig();
17
17
  if (!config.features.federation) {
18
- console.log('[federation] Federation disabled delivery worker not started');
18
+ console.log('[federation] Federation disabled, delivery worker not started');
19
19
  return;
20
20
  }
21
21
 
@@ -23,7 +23,7 @@ export default defineNitroPlugin((nitro) => {
23
23
  try {
24
24
  const config = useConfig();
25
25
  if (!config.features.federateHubs) {
26
- console.log('[hub-sync] Hub federation disabled sync worker not started');
26
+ console.log('[hub-sync] Hub federation disabled, sync worker not started');
27
27
  return;
28
28
  }
29
29
 
@@ -15,12 +15,12 @@ export default defineNitroPlugin((nitro) => {
15
15
  try {
16
16
  const config = useConfig();
17
17
  if (!config.features.announceToRegistry) {
18
- return; // opt-in silent when off
18
+ return; // opt-in, silent when off
19
19
  }
20
20
  // The registry verifies our ping by resolving `https://{instance.domain}/actor`, which is
21
21
  // only served when federation is on. Without it every ping 401s — warn + skip.
22
22
  if (!config.features.federation) {
23
- console.warn('[registry] announceToRegistry is on but federation is off pings would be unverifiable (our /actor is not served). Skipping.');
23
+ console.warn('[registry] announceToRegistry is on but federation is off, pings would be unverifiable (our /actor is not served). Skipping.');
24
24
  return;
25
25
  }
26
26
  const registryUrl = config.federation?.registryUrl ?? 'https://commonpub.io';
@@ -32,7 +32,7 @@ export default defineNitroPlugin((nitro) => {
32
32
  // Don't announce a registry to itself.
33
33
  const registryDomain = registryUrl.replace(/^https?:\/\//, '').replace(/[:/].*$/, '');
34
34
  if (registryDomain === domain) {
35
- console.log('[registry] Skipping heartbeat this instance is its own registry');
35
+ console.log('[registry] Skipping heartbeat, this instance is its own registry');
36
36
  return;
37
37
  }
38
38
 
@@ -13,7 +13,7 @@ export default defineNitroPlugin(async () => {
13
13
  const meiliKey = process.env.MEILI_MASTER_KEY;
14
14
 
15
15
  if (!meiliUrl) {
16
- console.log('[search-index] Meilisearch not configured search uses Postgres FTS fallback');
16
+ console.log('[search-index] Meilisearch not configured, search uses Postgres FTS fallback');
17
17
  return;
18
18
  }
19
19
 
@@ -21,7 +21,7 @@ export function useEmailAdapter(): EmailAdapter {
21
21
  const from = runtimeConfig.smtpFrom as string;
22
22
 
23
23
  if (!host || !user || !pass || !from) {
24
- console.warn('[email] SMTP configured but missing credentials falling back to console');
24
+ console.warn('[email] SMTP configured but missing credentials, falling back to console');
25
25
  cachedAdapter = new ConsoleEmailAdapter();
26
26
  return cachedAdapter;
27
27
  }
@@ -35,7 +35,7 @@ export function useEmailAdapter(): EmailAdapter {
35
35
  const from = runtimeConfig.resendFrom as string;
36
36
 
37
37
  if (!apiKey || !from) {
38
- console.warn('[email] Resend configured but missing API key or from address falling back to console');
38
+ console.warn('[email] Resend configured but missing API key or from address, falling back to console');
39
39
  cachedAdapter = new ConsoleEmailAdapter();
40
40
  return cachedAdapter;
41
41
  }
@@ -45,7 +45,7 @@ export function useEmailAdapter(): EmailAdapter {
45
45
  }
46
46
 
47
47
  if (process.env.NODE_ENV === 'production') {
48
- console.warn('[email] ⚠ Using console email adapter in production emails will be logged, not sent. Set NUXT_EMAIL_ADAPTER to "smtp" or "resend".');
48
+ console.warn('[email] ⚠ Using console email adapter in production, emails will be logged, not sent. Set NUXT_EMAIL_ADAPTER to "smtp" or "resend".');
49
49
  }
50
50
  cachedAdapter = new ConsoleEmailAdapter();
51
51
  return cachedAdapter;
@@ -12,7 +12,7 @@ import {
12
12
  } from '@commonpub/server';
13
13
  import { THEME_TO_FAMILY, FAMILY_VARIANTS, IS_DARK, VALID_THEME_IDS } from '../../utils/themeConfig';
14
14
 
15
- const CACHE_TTL = 60_000; // 1 minute admin changes propagate fast
15
+ const CACHE_TTL = 60_000; // 1 minute, admin changes propagate fast
16
16
 
17
17
  interface CachedThemeState {
18
18
  /** The admin's chosen default theme (built-in id, custom data-attr, or registered id) */
@@ -118,8 +118,8 @@ export const STAGE_KIND_LABEL: Record<ContestStage['kind'], string> = {
118
118
  export const STAGE_KIND_HELP: Record<ContestStage['kind'], string> = {
119
119
  submission: 'Entrants submit (or, in a later round, refine) entries. The hero countdown targets this stage’s end date.',
120
120
  review: 'Judges score entries on a rubric. End a review stage with an Advancement cut (Top-N) to pick who continues. Add per-round criteria below for multi-round contests.',
121
- interim: 'A working period e.g. a build sprint. The surviving cohort refines their existing entries; no new entrants.',
121
+ interim: 'A working period, e.g. a build sprint. The surviving cohort refines their existing entries; no new entrants.',
122
122
  results: 'Final standings are published (ranks calculated from the latest judging round).',
123
- event: 'A real-world milestone or showcase (date + location). Informational no entry/judging behaviour.',
124
- custom: 'An arbitrary dated milestone. No behaviour just appears on the timeline.',
123
+ event: 'A real-world milestone or showcase (date + location). Informational, no entry/judging behaviour.',
124
+ custom: 'An arbitrary dated milestone. No behaviour, just appears on the timeline.',
125
125
  };