create-cogenta 0.5.3 → 0.6.7
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/dist/blueprint-defaults.js +1 -1
- package/dist/blueprint-defaults.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/playground-reset.js +1 -1
- package/dist/playground-reset.js.map +1 -1
- package/dist/recap.js +1 -1
- package/dist/recap.js.map +1 -1
- package/dist/scaffold.d.ts +4 -2
- package/dist/scaffold.d.ts.map +1 -1
- package/dist/scaffold.js +10 -6
- package/dist/scaffold.js.map +1 -1
- package/dist/wizard.js +1 -1
- package/dist/wizard.js.map +1 -1
- package/package.json +14 -13
- package/dist/blueprints/assets/photos/association/community-cleanup.jpg +0 -0
- package/dist/blueprints/assets/photos/association/fundraising-dinner.jpg +0 -0
- package/dist/blueprints/assets/photos/association/garden-planting.jpg +0 -0
- package/dist/blueprints/assets/photos/association/harvest-food-drive.jpg +0 -0
- package/dist/blueprints/assets/photos/association/hero.jpg +0 -0
- package/dist/blueprints/assets/photos/association/volunteer-orientation.jpg +0 -0
- package/dist/blueprints/assets/photos/association/winter-coat-collection.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/blog-runs-itself.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/desk-setup.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/editing.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/hero.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/notebooks.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/plain-text-editor.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/reading-nonfiction.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/small-tool.jpg +0 -0
- package/dist/blueprints/assets/photos/blog/writing-schedule.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/business-2.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/business-3.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/business.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/culture-2.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/culture-3.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/culture.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/news-2.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/news-3.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/news.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/opinion-2.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/opinion-3.jpg +0 -0
- package/dist/blueprints/assets/photos/magazine/opinion.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/adatum-publishing.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/contoso-mobile-app.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/fabrikam-annual-report.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/hero.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/litware-signage.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/northwind-rebrand.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/proseware-launch.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/tailspin-streaming.jpg +0 -0
- package/dist/blueprints/assets/photos/portfolio/wingtip-wayfinding.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/charred-octopus.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/chocolate-tart.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/creme-brulee.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/hero.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/house-red.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/house-white.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/pan-seared-trout.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/poached-pear.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/roasted-beet-salad.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/slow-roast-duck-leg.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/soup-of-the-day.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/sparkling-water.jpg +0 -0
- package/dist/blueprints/assets/photos/restaurant/wild-mushroom-risotto.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/avatar-1.jpg +0 -0
- package/dist/blueprints/assets/photos/saas/hero.jpg +0 -0
- package/dist/blueprints/assets/photos/store/camp-blanket.jpg +0 -0
- package/dist/blueprints/assets/photos/store/canvas-tote.jpg +0 -0
- package/dist/blueprints/assets/photos/store/cast-iron-skillet.jpg +0 -0
- package/dist/blueprints/assets/photos/store/ceramic-pour-over-set.jpg +0 -0
- package/dist/blueprints/assets/photos/store/enamel-mug.jpg +0 -0
- package/dist/blueprints/assets/photos/store/everyday-tee.jpg +0 -0
- package/dist/blueprints/assets/photos/store/field-jacket.jpg +0 -0
- package/dist/blueprints/assets/photos/store/hero.jpg +0 -0
- package/dist/blueprints/assets/photos/store/leather-card-holder.jpg +0 -0
- package/dist/blueprints/assets/photos/store/linen-table-runner.jpg +0 -0
- package/dist/blueprints/assets/photos/store/trail-tote.jpg +0 -0
- package/dist/blueprints/assets/photos/store/wool-beanie.jpg +0 -0
- package/dist/blueprints/assets/photos/store/wool-overshirt.jpg +0 -0
- package/dist/blueprints/assets/photos/vitrine/avatar-1.jpg +0 -0
- package/dist/blueprints/assets/photos/vitrine/avatar-2.jpg +0 -0
- package/dist/blueprints/assets/photos/vitrine/avatar-3.jpg +0 -0
- package/dist/blueprints/assets/photos/vitrine/dashboard.jpg +0 -0
- package/dist/blueprints/assets/photos/vitrine/hero.jpg +0 -0
- package/dist/blueprints/association.d.ts +0 -151
- package/dist/blueprints/association.d.ts.map +0 -1
- package/dist/blueprints/association.js +0 -732
- package/dist/blueprints/association.js.map +0 -1
- package/dist/blueprints/blog.d.ts +0 -198
- package/dist/blueprints/blog.d.ts.map +0 -1
- package/dist/blueprints/blog.js +0 -665
- package/dist/blueprints/blog.js.map +0 -1
- package/dist/blueprints/content-pack.d.ts +0 -143
- package/dist/blueprints/content-pack.d.ts.map +0 -1
- package/dist/blueprints/content-pack.js +0 -111
- package/dist/blueprints/content-pack.js.map +0 -1
- package/dist/blueprints/content-packs.d.ts +0 -11
- package/dist/blueprints/content-packs.d.ts.map +0 -1
- package/dist/blueprints/content-packs.js +0 -29
- package/dist/blueprints/content-packs.js.map +0 -1
- package/dist/blueprints/demo-media.d.ts +0 -39
- package/dist/blueprints/demo-media.d.ts.map +0 -1
- package/dist/blueprints/demo-media.js +0 -30
- package/dist/blueprints/demo-media.js.map +0 -1
- package/dist/blueprints/documentation.d.ts +0 -134
- package/dist/blueprints/documentation.d.ts.map +0 -1
- package/dist/blueprints/documentation.js +0 -678
- package/dist/blueprints/documentation.js.map +0 -1
- package/dist/blueprints/magazine.d.ts +0 -145
- package/dist/blueprints/magazine.d.ts.map +0 -1
- package/dist/blueprints/magazine.js +0 -543
- package/dist/blueprints/magazine.js.map +0 -1
- package/dist/blueprints/menus.d.ts +0 -25
- package/dist/blueprints/menus.d.ts.map +0 -1
- package/dist/blueprints/menus.js +0 -33
- package/dist/blueprints/menus.js.map +0 -1
- package/dist/blueprints/photo-assets.d.ts +0 -3
- package/dist/blueprints/photo-assets.d.ts.map +0 -1
- package/dist/blueprints/photo-assets.js +0 -33
- package/dist/blueprints/photo-assets.js.map +0 -1
- package/dist/blueprints/portfolio.d.ts +0 -141
- package/dist/blueprints/portfolio.d.ts.map +0 -1
- package/dist/blueprints/portfolio.js +0 -700
- package/dist/blueprints/portfolio.js.map +0 -1
- package/dist/blueprints/restaurant.d.ts +0 -124
- package/dist/blueprints/restaurant.d.ts.map +0 -1
- package/dist/blueprints/restaurant.js +0 -457
- package/dist/blueprints/restaurant.js.map +0 -1
- package/dist/blueprints/saas.d.ts +0 -133
- package/dist/blueprints/saas.d.ts.map +0 -1
- package/dist/blueprints/saas.js +0 -551
- package/dist/blueprints/saas.js.map +0 -1
- package/dist/blueprints/site-settings-seed.d.ts +0 -17
- package/dist/blueprints/site-settings-seed.d.ts.map +0 -1
- package/dist/blueprints/site-settings-seed.js +0 -45
- package/dist/blueprints/site-settings-seed.js.map +0 -1
- package/dist/blueprints/starting-skins.d.ts +0 -19
- package/dist/blueprints/starting-skins.d.ts.map +0 -1
- package/dist/blueprints/starting-skins.js +0 -301
- package/dist/blueprints/starting-skins.js.map +0 -1
- package/dist/blueprints/store.d.ts +0 -173
- package/dist/blueprints/store.d.ts.map +0 -1
- package/dist/blueprints/store.js +0 -643
- package/dist/blueprints/store.js.map +0 -1
- package/dist/blueprints/vitrine.d.ts +0 -178
- package/dist/blueprints/vitrine.d.ts.map +0 -1
- package/dist/blueprints/vitrine.js +0 -529
- package/dist/blueprints/vitrine.js.map +0 -1
- package/dist/demo-art/compositions.d.ts +0 -48
- package/dist/demo-art/compositions.d.ts.map +0 -1
- package/dist/demo-art/compositions.js +0 -690
- package/dist/demo-art/compositions.js.map +0 -1
- package/dist/demo-art/index.d.ts +0 -8
- package/dist/demo-art/index.d.ts.map +0 -1
- package/dist/demo-art/index.js +0 -5
- package/dist/demo-art/index.js.map +0 -1
- package/dist/demo-art/oklch.d.ts +0 -39
- package/dist/demo-art/oklch.d.ts.map +0 -1
- package/dist/demo-art/oklch.js +0 -79
- package/dist/demo-art/oklch.js.map +0 -1
- package/dist/demo-art/png.d.ts +0 -24
- package/dist/demo-art/png.d.ts.map +0 -1
- package/dist/demo-art/png.js +0 -110
- package/dist/demo-art/png.js.map +0 -1
- package/dist/demo-art/render.d.ts +0 -228
- package/dist/demo-art/render.d.ts.map +0 -1
- package/dist/demo-art/render.js +0 -478
- package/dist/demo-art/render.js.map +0 -1
package/dist/blueprints/blog.js
DELETED
|
@@ -1,665 +0,0 @@
|
|
|
1
|
-
import { CogentaError } from '@cogenta/core';
|
|
2
|
-
import { createContentStore, createTaxonomyStore, defineCollection, defineTaxonomy, f, validateCollectionSet, validateTaxonomySet, } from '@cogenta/schema';
|
|
3
|
-
import { avatarArt, coverArt, heroArt, logoArt } from '../demo-art/compositions.js';
|
|
4
|
-
import { SEO_FIELDS, toBlockZoneEntry, } from './content-pack.js';
|
|
5
|
-
import { STARTING_SKINS } from './starting-skins.js';
|
|
6
|
-
/**
|
|
7
|
-
* The `blog` blueprint's content model (L9 task 3, richened for L25 D4).
|
|
8
|
-
*
|
|
9
|
-
* `post` reuses `SystemFields.status`/`createdAt` for publish state and
|
|
10
|
-
* publish date rather than declaring its own — contract A already carries
|
|
11
|
-
* both on every entry. Authorship reuses `SystemFields.createdBy`, which
|
|
12
|
-
* points at the real user/actor system, rather than a separate author
|
|
13
|
-
* collection this blueprint would have to invent and keep in sync.
|
|
14
|
-
*
|
|
15
|
-
* `category`/`tag` are `defineTaxonomy()` declarations, not collections
|
|
16
|
-
* (audit fiche 04, T02/T10 — `schema@2.0`, ADR-0022, already figé). `category`
|
|
17
|
-
* stays hierarchical (its default); `tag` is declared flat.
|
|
18
|
-
*/
|
|
19
|
-
export const category = defineTaxonomy({
|
|
20
|
-
name: 'category',
|
|
21
|
-
labels: {
|
|
22
|
-
singular: { en: 'Category', fr: 'Catégorie' },
|
|
23
|
-
plural: { en: 'Categories', fr: 'Catégories' },
|
|
24
|
-
},
|
|
25
|
-
permissions: {
|
|
26
|
-
read: ['public'],
|
|
27
|
-
create: ['editor', 'admin'],
|
|
28
|
-
update: ['editor', 'admin'],
|
|
29
|
-
delete: ['admin'],
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
export const tag = defineTaxonomy({
|
|
33
|
-
name: 'tag',
|
|
34
|
-
labels: {
|
|
35
|
-
singular: { en: 'Tag', fr: 'Étiquette' },
|
|
36
|
-
plural: { en: 'Tags', fr: 'Étiquettes' },
|
|
37
|
-
},
|
|
38
|
-
hierarchical: false,
|
|
39
|
-
permissions: {
|
|
40
|
-
read: ['public'],
|
|
41
|
-
create: ['editor', 'admin'],
|
|
42
|
-
update: ['editor', 'admin'],
|
|
43
|
-
delete: ['admin'],
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
export const post = defineCollection({
|
|
47
|
-
name: 'post',
|
|
48
|
-
labels: { singular: 'Post', plural: 'Posts' },
|
|
49
|
-
routing: { pattern: '/blog/:slug' },
|
|
50
|
-
versioning: { drafts: true, history: true },
|
|
51
|
-
fields: {
|
|
52
|
-
title: f.text({ required: true, max: 200 }),
|
|
53
|
-
slug: f.slug({ from: 'title', unique: true }),
|
|
54
|
-
body: f.richText({ required: true }),
|
|
55
|
-
excerpt: f.text({ max: 300, multiline: true }),
|
|
56
|
-
// L25 D4: a cover image, read by `entryImage` (`@cogenta/theme-kit`)
|
|
57
|
-
// for the "Latest"/"From the archive" cards and the post's own
|
|
58
|
-
// `renderEntryHeader` cover.
|
|
59
|
-
coverImage: f.media({ accept: ['image'] }),
|
|
60
|
-
category: f.taxonomy({ of: 'category', many: false }),
|
|
61
|
-
tags: f.taxonomy({ of: 'tag', many: true }),
|
|
62
|
-
// Declared (contract A's own `docs/04-contrats.md` example does the
|
|
63
|
-
// same on its `article` collection) so `createContentStore`'s own
|
|
64
|
-
// publish-time default (`store.ts`: only set when the collection
|
|
65
|
-
// declares this field) actually fires — without it every post's
|
|
66
|
-
// `renderEntryHeader` meta line silently drops the "date lisible" the
|
|
67
|
-
// brief asks for, since `theme-render.ts` only forwards `publishedAt`
|
|
68
|
-
// when it is non-null.
|
|
69
|
-
publishedAt: f.datetime(),
|
|
70
|
-
...SEO_FIELDS,
|
|
71
|
-
},
|
|
72
|
-
indexes: [['publishedAt', 'desc'], ['slug']],
|
|
73
|
-
permissions: {
|
|
74
|
-
read: ['public'],
|
|
75
|
-
create: ['editor', 'admin'],
|
|
76
|
-
update: ['editor', 'admin'],
|
|
77
|
-
delete: ['admin'],
|
|
78
|
-
publish: ['admin'],
|
|
79
|
-
},
|
|
80
|
-
});
|
|
81
|
-
export const page = defineCollection({
|
|
82
|
-
name: 'page',
|
|
83
|
-
labels: { singular: 'Page', plural: 'Pages' },
|
|
84
|
-
routing: { pattern: '/:slug' },
|
|
85
|
-
fields: {
|
|
86
|
-
title: f.text({ required: true, max: 200 }),
|
|
87
|
-
slug: f.slug({ from: 'title', unique: true }),
|
|
88
|
-
blocks: f.blocks({ required: true }),
|
|
89
|
-
...SEO_FIELDS,
|
|
90
|
-
},
|
|
91
|
-
indexes: [['slug']],
|
|
92
|
-
permissions: {
|
|
93
|
-
read: ['public'],
|
|
94
|
-
create: ['editor', 'admin'],
|
|
95
|
-
update: ['editor', 'admin'],
|
|
96
|
-
delete: ['admin'],
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
export const BLOG_COLLECTIONS = [post, page];
|
|
100
|
-
export const BLOG_TAXONOMIES = [category, tag];
|
|
101
|
-
validateCollectionSet(BLOG_COLLECTIONS);
|
|
102
|
-
validateTaxonomySet(BLOG_TAXONOMIES, BLOG_COLLECTIONS);
|
|
103
|
-
let paragraphKey = 0;
|
|
104
|
-
/** One `normal`-style rich-text paragraph, unmarked. */
|
|
105
|
-
function paragraph(text) {
|
|
106
|
-
paragraphKey += 1;
|
|
107
|
-
return {
|
|
108
|
-
_key: `demo-p-${paragraphKey}`,
|
|
109
|
-
_type: 'block',
|
|
110
|
-
style: 'normal',
|
|
111
|
-
children: [{ _key: `demo-p-${paragraphKey}-span`, _type: 'span', text, marks: [] }],
|
|
112
|
-
markDefs: [],
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
function heading2(text) {
|
|
116
|
-
paragraphKey += 1;
|
|
117
|
-
return {
|
|
118
|
-
_key: `demo-h-${paragraphKey}`,
|
|
119
|
-
_type: 'block',
|
|
120
|
-
style: 'h2',
|
|
121
|
-
children: [{ _key: `demo-h-${paragraphKey}-span`, _type: 'span', text, marks: [] }],
|
|
122
|
-
markDefs: [],
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
function bulletItem(text) {
|
|
126
|
-
paragraphKey += 1;
|
|
127
|
-
return {
|
|
128
|
-
_key: `demo-l-${paragraphKey}`,
|
|
129
|
-
_type: 'block',
|
|
130
|
-
style: 'normal',
|
|
131
|
-
listItem: 'bullet',
|
|
132
|
-
level: 1,
|
|
133
|
-
children: [{ _key: `demo-l-${paragraphKey}-span`, _type: 'span', text, marks: [] }],
|
|
134
|
-
markDefs: [],
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
function quoteLine(text) {
|
|
138
|
-
paragraphKey += 1;
|
|
139
|
-
return {
|
|
140
|
-
_key: `demo-q-${paragraphKey}`,
|
|
141
|
-
_type: 'block',
|
|
142
|
-
style: 'blockquote',
|
|
143
|
-
children: [{ _key: `demo-q-${paragraphKey}-span`, _type: 'span', text, marks: [] }],
|
|
144
|
-
markDefs: [],
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
export const BLOG_DEMO_CATEGORIES = [
|
|
148
|
-
{ name: 'Reading', slug: 'reading' },
|
|
149
|
-
{ name: 'Building', slug: 'building' },
|
|
150
|
-
{ name: 'Writing', slug: 'writing' },
|
|
151
|
-
{ name: 'Craft', slug: 'craft' },
|
|
152
|
-
];
|
|
153
|
-
// L26 D1: `name` is the display label shown as-is on a tag archive's <h1>
|
|
154
|
-
// (`renderTermArchive`) — lowercase read as unfinished placeholder text
|
|
155
|
-
// next to `category`'s title-cased labels ("Writing", not "writing").
|
|
156
|
-
// `slug` is untouched: it is the URL and the join-table key.
|
|
157
|
-
export const BLOG_DEMO_TAGS = [
|
|
158
|
-
{ name: 'Process', slug: 'process' },
|
|
159
|
-
{ name: 'Tools', slug: 'tools' },
|
|
160
|
-
{ name: 'Habits', slug: 'habits' },
|
|
161
|
-
{ name: 'Editors', slug: 'editors' },
|
|
162
|
-
{ name: 'Notebooks', slug: 'notebooks' },
|
|
163
|
-
{ name: 'Focus', slug: 'focus' },
|
|
164
|
-
{ name: 'Drafts', slug: 'drafts' },
|
|
165
|
-
{ name: 'Revision', slug: 'revision' },
|
|
166
|
-
];
|
|
167
|
-
export const BLOG_DEMO_POSTS = [
|
|
168
|
-
{
|
|
169
|
-
title: 'Why I still write in a plain-text editor',
|
|
170
|
-
slug: 'plain-text-editor',
|
|
171
|
-
excerpt: 'Ten years of trying every tool that promised to make writing easier.',
|
|
172
|
-
categorySlug: 'writing',
|
|
173
|
-
tagSlugs: ['tools', 'editors'],
|
|
174
|
-
body: [
|
|
175
|
-
paragraph('I have paid for at least nine different writing apps since 2016. Each one promised the same ' +
|
|
176
|
-
'thing: a calmer place to think, fewer distractions, a nicer font. Every single one eventually ' +
|
|
177
|
-
'added a sidebar, a sync indicator, and a subscription reminder, and I went back to a plain-text ' +
|
|
178
|
-
'editor within a month.'),
|
|
179
|
-
heading2('What a plain file actually gives you'),
|
|
180
|
-
bulletItem('It opens instantly, every time, on every machine I own.'),
|
|
181
|
-
bulletItem('It will still open in twenty years — the format is the text itself.'),
|
|
182
|
-
bulletItem('Nothing about the tool is trying to keep my attention.'),
|
|
183
|
-
paragraph('None of that is a complaint about design. It is a complaint about incentives: a writing tool that ' +
|
|
184
|
-
'has to grow a business ends up optimising for engagement, and engagement is the opposite of what ' +
|
|
185
|
-
'a first draft needs.'),
|
|
186
|
-
quoteLine('The best writing tool is the one that gets out of the way and stays out of the way.'),
|
|
187
|
-
paragraph('So the editor I actually finish drafts in has no plugins, no themes, and no update notifications. ' +
|
|
188
|
-
'It has a cursor and a blinking line, and that turns out to be enough.'),
|
|
189
|
-
],
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
title: 'The desk setup that finally stuck',
|
|
193
|
-
slug: 'desk-setup-that-stuck',
|
|
194
|
-
excerpt: 'Every previous version of this desk lasted about six weeks. This one is two years old.',
|
|
195
|
-
categorySlug: 'craft',
|
|
196
|
-
tagSlugs: ['tools', 'habits'],
|
|
197
|
-
body: [
|
|
198
|
-
paragraph('I used to rebuild my desk setup every time I read a good "how I work" post. New monitor arm, new ' +
|
|
199
|
-
'keyboard, new lamp, new chair — a little dopamine hit, a week of feeling productive, and then back ' +
|
|
200
|
-
'to the same problems.'),
|
|
201
|
-
paragraph('What actually fixed it was removing things rather than adding them: one monitor instead of three, a ' +
|
|
202
|
-
'closed door instead of noise-cancelling headphones, and a chair I stopped noticing entirely. The ' +
|
|
203
|
-
'setup that stuck is the one I stopped thinking about.'),
|
|
204
|
-
],
|
|
205
|
-
},
|
|
206
|
-
{
|
|
207
|
-
title: 'What ten years of reading nonfiction taught me',
|
|
208
|
-
slug: 'ten-years-reading-nonfiction',
|
|
209
|
-
excerpt: 'Mostly that I was reading for the wrong reason for most of it.',
|
|
210
|
-
categorySlug: 'reading',
|
|
211
|
-
tagSlugs: ['habits', 'notebooks'],
|
|
212
|
-
body: [
|
|
213
|
-
paragraph('For the first several years I read to be able to say I had read the book. I finished things I ' +
|
|
214
|
-
'disliked out of a sense of obligation, and I remembered almost none of them a month later.'),
|
|
215
|
-
heading2('The one change that mattered'),
|
|
216
|
-
paragraph('I started keeping a single notebook — not a book journal, just a running list of the one idea from ' +
|
|
217
|
-
'each book that changed how I thought about something. The books I remember now are the ones that ' +
|
|
218
|
-
'earned a line in that notebook, and nothing else.'),
|
|
219
|
-
],
|
|
220
|
-
},
|
|
221
|
-
{
|
|
222
|
-
title: 'A small tool I built to stop losing drafts',
|
|
223
|
-
slug: 'tool-to-stop-losing-drafts',
|
|
224
|
-
excerpt: 'It is ugly, it has no users but me, and it has saved three articles this year alone.',
|
|
225
|
-
categorySlug: 'building',
|
|
226
|
-
tagSlugs: ['tools', 'drafts'],
|
|
227
|
-
body: [
|
|
228
|
-
paragraph('Every text editor I have used eventually loses a draft — a crash, a sync conflict, a laptop that ' +
|
|
229
|
-
'died mid-sentence. After the third time it happened to something I actually cared about, I wrote a ' +
|
|
230
|
-
'forty-line script that copies whatever is in my drafts folder to a second disk every five minutes.'),
|
|
231
|
-
paragraph('It has no interface, no settings, and no name beyond `backup.sh`. It is the single most useful piece ' +
|
|
232
|
-
'of software I have ever written, and it took less time to build than writing this post did.'),
|
|
233
|
-
],
|
|
234
|
-
},
|
|
235
|
-
{
|
|
236
|
-
title: 'The one habit that fixed my writing schedule',
|
|
237
|
-
slug: 'habit-that-fixed-my-schedule',
|
|
238
|
-
excerpt: 'Not a morning routine. Not a word-count goal. Something much smaller.',
|
|
239
|
-
categorySlug: 'writing',
|
|
240
|
-
tagSlugs: ['habits', 'focus'],
|
|
241
|
-
body: [
|
|
242
|
-
paragraph('I tried the 5am wake-up. I tried a 1,000-word daily minimum. Both worked for about a week and then ' +
|
|
243
|
-
'collapsed the first time life got in the way, which made me feel worse than not trying at all.'),
|
|
244
|
-
paragraph('What actually stuck was absurdly small: open the draft file before doing anything else on the ' +
|
|
245
|
-
'computer, even if I only read the last paragraph and close it again. Some days that is all that ' +
|
|
246
|
-
'happens. Most days, once the file is open, I keep going.'),
|
|
247
|
-
],
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
title: 'Notebooks I have actually finished',
|
|
251
|
-
slug: 'notebooks-actually-finished',
|
|
252
|
-
excerpt: 'A short, honest list, after a drawer full of notebooks with four used pages each.',
|
|
253
|
-
categorySlug: 'reading',
|
|
254
|
-
tagSlugs: ['notebooks', 'habits'],
|
|
255
|
-
body: [
|
|
256
|
-
paragraph('I own a drawer of notebooks that got four pages of enthusiastic notes and then nothing. The ones I ' +
|
|
257
|
-
'actually filled share one property: they were too plain and too cheap to feel precious.'),
|
|
258
|
-
bulletItem('A notebook I am afraid to ruin is a notebook I will not open.'),
|
|
259
|
-
bulletItem('Grid paper beats lined paper for anything that is not a diary.'),
|
|
260
|
-
bulletItem('A pen that writes badly is worse for the habit than no pen at all.'),
|
|
261
|
-
],
|
|
262
|
-
},
|
|
263
|
-
{
|
|
264
|
-
title: 'Building a blog that runs itself',
|
|
265
|
-
slug: 'blog-that-runs-itself',
|
|
266
|
-
excerpt: 'What I actually automated, and — more importantly — what I deliberately did not.',
|
|
267
|
-
categorySlug: 'building',
|
|
268
|
-
tagSlugs: ['tools', 'process'],
|
|
269
|
-
body: [
|
|
270
|
-
paragraph('This blog is a static content model with a scheduler that checks for broken links, a spellchecker ' +
|
|
271
|
-
'that flags anything odd before it publishes, and a script that reminds me when a post has not been ' +
|
|
272
|
-
'revisited in two years.'),
|
|
273
|
-
paragraph('What it does not do is write anything, choose what to publish, or decide when a draft is ready. The ' +
|
|
274
|
-
'automation handles the boring parts so the writing stays mine.'),
|
|
275
|
-
],
|
|
276
|
-
},
|
|
277
|
-
{
|
|
278
|
-
title: 'Editing is where the writing happens',
|
|
279
|
-
slug: 'editing-is-where-writing-happens',
|
|
280
|
-
excerpt: 'A first draft is raw material. The real writing starts on the second pass.',
|
|
281
|
-
categorySlug: 'writing',
|
|
282
|
-
tagSlugs: ['revision', 'drafts'],
|
|
283
|
-
body: [
|
|
284
|
-
paragraph('I used to think of editing as cleanup — fixing typos, tightening a sentence here and there. Every ' +
|
|
285
|
-
'post that actually worked was rebuilt at least once, sometimes from a completely different opening.'),
|
|
286
|
-
heading2('What I look for on a second pass'),
|
|
287
|
-
bulletItem('The paragraph that is doing the least work — usually the second one.'),
|
|
288
|
-
bulletItem('A claim I made without an example to back it up.'),
|
|
289
|
-
bulletItem('The sentence I am proudest of, which is often the one that should go.'),
|
|
290
|
-
quoteLine('A draft is a question. An edit is the answer you are actually willing to publish.'),
|
|
291
|
-
],
|
|
292
|
-
},
|
|
293
|
-
];
|
|
294
|
-
const BLOCK_VERSION = '1.0.0';
|
|
295
|
-
/**
|
|
296
|
-
* The blueprint's own starting skin (`starting-skins.js`) — asserted present
|
|
297
|
-
* with a real check, not a `!`, the same guard `store.ts`'s `storePalette`
|
|
298
|
-
* uses: `STARTING_SKINS` is keyed by blueprint id and TypeScript cannot see
|
|
299
|
-
* that this particular key is always populated.
|
|
300
|
-
*/
|
|
301
|
-
function blogPalette() {
|
|
302
|
-
const skin = STARTING_SKINS.blog;
|
|
303
|
-
if (skin === undefined) {
|
|
304
|
-
throw new CogentaError({
|
|
305
|
-
code: 'BLUEPRINT_REGISTRY_CORRUPT',
|
|
306
|
-
message: 'STARTING_SKINS.blog is missing.',
|
|
307
|
-
hint: 'The "blog" entry must stay declared in starting-skins.ts for this blueprint to render its demo art.',
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
return skin.color;
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* Procedural visuals this blueprint seeds (L25 D4): a magazine-cover hero
|
|
314
|
-
* backdrop, one cover per demo post (keyed by the post's own slug), a reader
|
|
315
|
-
* avatar for the "reader's words" quote block, and five neutral wordmark
|
|
316
|
-
* stand-ins for the "As featured in" strip.
|
|
317
|
-
*/
|
|
318
|
-
/** Bundled photography (`assets/photos/blog/`), keyed by the same slug `BLOG_DEMO_POSTS` uses. */
|
|
319
|
-
const BLOG_POST_PHOTOS = {
|
|
320
|
-
'plain-text-editor': 'blog/plain-text-editor.jpg',
|
|
321
|
-
'desk-setup-that-stuck': 'blog/desk-setup.jpg',
|
|
322
|
-
'ten-years-reading-nonfiction': 'blog/reading-nonfiction.jpg',
|
|
323
|
-
'tool-to-stop-losing-drafts': 'blog/small-tool.jpg',
|
|
324
|
-
'habit-that-fixed-my-schedule': 'blog/writing-schedule.jpg',
|
|
325
|
-
'notebooks-actually-finished': 'blog/notebooks.jpg',
|
|
326
|
-
'blog-that-runs-itself': 'blog/blog-runs-itself.jpg',
|
|
327
|
-
'editing-is-where-writing-happens': 'blog/editing.jpg',
|
|
328
|
-
};
|
|
329
|
-
export const BLOG_MEDIA_SPECS = [
|
|
330
|
-
{
|
|
331
|
-
name: 'hero',
|
|
332
|
-
spec: heroArt(blogPalette(), 'radial', 7),
|
|
333
|
-
alt: 'A writer’s desk',
|
|
334
|
-
photo: 'blog/hero.jpg',
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
name: 'quote-avatar',
|
|
338
|
-
spec: avatarArt(blogPalette(), 3),
|
|
339
|
-
alt: 'Abstract avatar mark for a reader quote',
|
|
340
|
-
},
|
|
341
|
-
// L26 D2/D3: the About page had nothing but two paragraphs of text and no
|
|
342
|
-
// visual at all — a different seed from `quote-avatar` (7, not 3) so the
|
|
343
|
-
// two abstract marks read as distinct rather than a copy-pasted image.
|
|
344
|
-
// No bundled photo fits an author portrait (the nine real photos in
|
|
345
|
-
// `assets/photos/blog/` are the hero backdrop and eight post covers, all
|
|
346
|
-
// already spoken for), and there is no image-generation key to make a new
|
|
347
|
-
// one — the procedural generator is the honest fallback here, exactly as
|
|
348
|
-
// it already is for `quote-avatar` and the five press logos below.
|
|
349
|
-
{
|
|
350
|
-
name: 'about-avatar',
|
|
351
|
-
spec: avatarArt(blogPalette(), 7),
|
|
352
|
-
alt: 'Abstract avatar mark for the About page',
|
|
353
|
-
},
|
|
354
|
-
...[1, 2, 3, 4, 5].map((n) => ({
|
|
355
|
-
name: `logo-${n}`,
|
|
356
|
-
spec: logoArt(n),
|
|
357
|
-
alt: `Neutral wordmark placeholder ${n}`,
|
|
358
|
-
})),
|
|
359
|
-
...BLOG_DEMO_POSTS.map((demo, index) => {
|
|
360
|
-
const photo = BLOG_POST_PHOTOS[demo.slug];
|
|
361
|
-
return {
|
|
362
|
-
name: `post-${demo.slug}`,
|
|
363
|
-
spec: coverArt(blogPalette(), index + 1),
|
|
364
|
-
alt: `Cover art for "${demo.title}"`,
|
|
365
|
-
...(photo === undefined ? {} : { photo }),
|
|
366
|
-
};
|
|
367
|
-
}),
|
|
368
|
-
];
|
|
369
|
-
/** Header/footer navigation and the header call-to-action button (L25 D4). */
|
|
370
|
-
export const BLOG_MENUS = {
|
|
371
|
-
header: [
|
|
372
|
-
{ label: 'Home' },
|
|
373
|
-
{ label: 'Writing', url: '/blog' },
|
|
374
|
-
{ label: 'About', url: '/about' },
|
|
375
|
-
],
|
|
376
|
-
footer: [
|
|
377
|
-
{ label: 'About', url: '/about' },
|
|
378
|
-
{ label: 'Archive', url: '/archive' },
|
|
379
|
-
{ label: 'RSS', url: '/feed.xml' },
|
|
380
|
-
],
|
|
381
|
-
headerAction: { label: 'Subscribe', url: '/#newsletter' },
|
|
382
|
-
};
|
|
383
|
-
export const BLOG_SITE_SETTINGS = {
|
|
384
|
-
'general.tagline': 'Notes on reading, building and writing things down.',
|
|
385
|
-
'general.socialLinks': [
|
|
386
|
-
{ label: 'Mastodon', url: 'https://mastodon.social/@example' },
|
|
387
|
-
{ label: 'X', url: 'https://x.com/example' },
|
|
388
|
-
{ label: 'GitHub', url: 'https://github.com/example' },
|
|
389
|
-
],
|
|
390
|
-
'general.footerNote': 'A personal blog, scaffolded by create-cogenta.',
|
|
391
|
-
};
|
|
392
|
-
export const BLOG_RECOMMENDED_AGENTS = [
|
|
393
|
-
{
|
|
394
|
-
name: 'seoAgent',
|
|
395
|
-
package: '@cogenta/agents-builtin',
|
|
396
|
-
reason: 'Audits published posts for on-page SEO issues and internal-linking gaps.',
|
|
397
|
-
},
|
|
398
|
-
{
|
|
399
|
-
name: 'contentAgent',
|
|
400
|
-
package: '@cogenta/agents-builtin',
|
|
401
|
-
reason: 'Flags terminology drift and topic gaps across the post archive.',
|
|
402
|
-
},
|
|
403
|
-
];
|
|
404
|
-
/**
|
|
405
|
-
* `home` (the featured-post hero, a live "Latest" grid, the topics rail, a
|
|
406
|
-
* reader quote, an editorial "From the archive" list, a newsletter panel, a
|
|
407
|
-
* press strip and an FAQ — eight blocks, the brief's own order) and `about`.
|
|
408
|
-
* `media` (`SeedContext.media`, L25 task A0b) supplies the hero backdrop and
|
|
409
|
-
* the quote avatar; a function of it rather than a static const for the same
|
|
410
|
-
* reason `store.ts`'s `buildStoreDemoPages` is.
|
|
411
|
-
*/
|
|
412
|
-
export function buildBlogDemoPages(media) {
|
|
413
|
-
const featured = BLOG_DEMO_POSTS[0];
|
|
414
|
-
if (featured === undefined) {
|
|
415
|
-
throw new CogentaError({
|
|
416
|
-
code: 'BLUEPRINT_REGISTRY_CORRUPT',
|
|
417
|
-
message: 'BLOG_DEMO_POSTS is empty.',
|
|
418
|
-
hint: 'The blog blueprint needs at least one demo post to feature on its home page.',
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
const logoItems = [1, 2, 3, 4, 5]
|
|
422
|
-
.filter((n) => media[`logo-${n}`] !== undefined)
|
|
423
|
-
.map((n) => ({ _key: `demo-logo-${n}`, media: media[`logo-${n}`] }));
|
|
424
|
-
const aboutAvatar = media['about-avatar'];
|
|
425
|
-
return [
|
|
426
|
-
{
|
|
427
|
-
title: 'Home',
|
|
428
|
-
slug: 'home',
|
|
429
|
-
blocks: [
|
|
430
|
-
{
|
|
431
|
-
_key: 'demo-home-hero',
|
|
432
|
-
_type: 'hero',
|
|
433
|
-
_version: BLOCK_VERSION,
|
|
434
|
-
eyebrow: 'Featured',
|
|
435
|
-
title: featured.title,
|
|
436
|
-
subtitle: featured.excerpt,
|
|
437
|
-
...(media.hero === undefined ? {} : { media: media.hero }),
|
|
438
|
-
actions: [{ label: 'Read the story', target: { href: `/blog/${featured.slug}` } }],
|
|
439
|
-
},
|
|
440
|
-
{
|
|
441
|
-
_key: 'demo-home-latest',
|
|
442
|
-
_type: 'collectionList',
|
|
443
|
-
_version: BLOCK_VERSION,
|
|
444
|
-
title: 'Latest',
|
|
445
|
-
collection: 'post',
|
|
446
|
-
sort: { field: 'createdAt', direction: 'desc' },
|
|
447
|
-
limit: 6,
|
|
448
|
-
layout: 'grid',
|
|
449
|
-
},
|
|
450
|
-
{
|
|
451
|
-
_key: 'demo-home-topics',
|
|
452
|
-
_type: 'featureGrid',
|
|
453
|
-
_version: BLOCK_VERSION,
|
|
454
|
-
title: 'Topics',
|
|
455
|
-
items: [
|
|
456
|
-
{
|
|
457
|
-
_key: 'demo-topic-1',
|
|
458
|
-
icon: 'book',
|
|
459
|
-
title: 'Reading',
|
|
460
|
-
text: 'What I read, and why it stuck.',
|
|
461
|
-
},
|
|
462
|
-
{
|
|
463
|
-
_key: 'demo-topic-2',
|
|
464
|
-
icon: 'code',
|
|
465
|
-
title: 'Building',
|
|
466
|
-
text: 'Small tools, made to be used once.',
|
|
467
|
-
},
|
|
468
|
-
{
|
|
469
|
-
_key: 'demo-topic-3',
|
|
470
|
-
icon: 'pen',
|
|
471
|
-
title: 'Writing',
|
|
472
|
-
text: 'How a draft becomes a post.',
|
|
473
|
-
},
|
|
474
|
-
{
|
|
475
|
-
_key: 'demo-topic-4',
|
|
476
|
-
icon: 'coffee',
|
|
477
|
-
title: 'Craft',
|
|
478
|
-
text: 'The unglamorous parts of making things.',
|
|
479
|
-
},
|
|
480
|
-
],
|
|
481
|
-
},
|
|
482
|
-
{
|
|
483
|
-
_key: 'demo-home-quote',
|
|
484
|
-
_type: 'quote',
|
|
485
|
-
_version: BLOCK_VERSION,
|
|
486
|
-
text: 'I started reading this blog for the writing advice and stayed for everything else.',
|
|
487
|
-
author: 'A. Reader',
|
|
488
|
-
role: 'Subscriber since issue one',
|
|
489
|
-
...(media['quote-avatar'] === undefined ? {} : { avatar: media['quote-avatar'] }),
|
|
490
|
-
},
|
|
491
|
-
{
|
|
492
|
-
_key: 'demo-home-archive',
|
|
493
|
-
_type: 'collectionList',
|
|
494
|
-
_version: BLOCK_VERSION,
|
|
495
|
-
title: 'From the archive',
|
|
496
|
-
collection: 'post',
|
|
497
|
-
sort: { field: 'createdAt', direction: 'asc' },
|
|
498
|
-
limit: 5,
|
|
499
|
-
layout: 'list',
|
|
500
|
-
},
|
|
501
|
-
{
|
|
502
|
-
_key: 'demo-home-newsletter',
|
|
503
|
-
_type: 'cta',
|
|
504
|
-
_version: BLOCK_VERSION,
|
|
505
|
-
title: 'Get the weekly letter',
|
|
506
|
-
text: 'One email, every Thursday, no more than five minutes to read.',
|
|
507
|
-
actions: [
|
|
508
|
-
{ label: 'Subscribe', target: { href: '/#newsletter' }, emphasis: 'primary' },
|
|
509
|
-
{ label: 'See a past issue', target: { href: '/archive' } },
|
|
510
|
-
],
|
|
511
|
-
},
|
|
512
|
-
// Omitted entirely, rather than sent with an empty `logos` array,
|
|
513
|
-
// when no logo mark was actually ingested (e.g. `seedDemoContent`
|
|
514
|
-
// called with `media: {}`) — contract B requires at least one item.
|
|
515
|
-
...(logoItems.length === 0
|
|
516
|
-
? []
|
|
517
|
-
: [
|
|
518
|
-
{
|
|
519
|
-
_key: 'demo-home-featured-in',
|
|
520
|
-
_type: 'logoStrip',
|
|
521
|
-
_version: BLOCK_VERSION,
|
|
522
|
-
caption: 'As featured in',
|
|
523
|
-
logos: logoItems,
|
|
524
|
-
},
|
|
525
|
-
]),
|
|
526
|
-
{
|
|
527
|
-
_key: 'demo-home-faq',
|
|
528
|
-
_type: 'faq',
|
|
529
|
-
_version: BLOCK_VERSION,
|
|
530
|
-
title: 'About this blog',
|
|
531
|
-
items: [
|
|
532
|
-
{
|
|
533
|
-
_key: 'demo-faq-1',
|
|
534
|
-
question: 'How often do you publish?',
|
|
535
|
-
answer: [
|
|
536
|
-
paragraph('Every other Thursday, with the occasional extra when something is urgent.'),
|
|
537
|
-
],
|
|
538
|
-
},
|
|
539
|
-
{
|
|
540
|
-
_key: 'demo-faq-2',
|
|
541
|
-
question: 'Do you accept guest posts?',
|
|
542
|
-
answer: [
|
|
543
|
-
paragraph('Not currently — everything here is written and edited by one person.'),
|
|
544
|
-
],
|
|
545
|
-
},
|
|
546
|
-
{
|
|
547
|
-
_key: 'demo-faq-3',
|
|
548
|
-
question: 'Is there an RSS feed?',
|
|
549
|
-
answer: [paragraph('Yes — the link is in the footer of every page.')],
|
|
550
|
-
},
|
|
551
|
-
{
|
|
552
|
-
_key: 'demo-faq-4',
|
|
553
|
-
question: 'Can I republish a post?',
|
|
554
|
-
answer: [paragraph('With attribution and a link back, always — just ask first.')],
|
|
555
|
-
},
|
|
556
|
-
],
|
|
557
|
-
},
|
|
558
|
-
],
|
|
559
|
-
},
|
|
560
|
-
{
|
|
561
|
-
title: 'About',
|
|
562
|
-
slug: 'about',
|
|
563
|
-
blocks: [
|
|
564
|
-
// L26 D2/D3: a small figure above the fold — the page read as bare
|
|
565
|
-
// with nothing but two short paragraphs and no visual at all.
|
|
566
|
-
// `align: 'start'` keeps it a modest author-photo size (half the
|
|
567
|
-
// reading measure, not a full-bleed hero) rather than stretching an
|
|
568
|
-
// abstract 600×600 mark across the whole page width.
|
|
569
|
-
...(aboutAvatar === undefined
|
|
570
|
-
? []
|
|
571
|
-
: [
|
|
572
|
-
{
|
|
573
|
-
_key: 'demo-about-avatar',
|
|
574
|
-
_type: 'mediaFigure',
|
|
575
|
-
_version: BLOCK_VERSION,
|
|
576
|
-
media: aboutAvatar,
|
|
577
|
-
ratio: '1:1',
|
|
578
|
-
align: 'start',
|
|
579
|
-
},
|
|
580
|
-
]),
|
|
581
|
-
{
|
|
582
|
-
_key: 'demo-about-prose',
|
|
583
|
-
_type: 'prose',
|
|
584
|
-
_version: BLOCK_VERSION,
|
|
585
|
-
body: [
|
|
586
|
-
paragraph('Ink & Paper started as a running list of one idea per book, kept so I would stop forgetting ' +
|
|
587
|
-
'what I had just read. It grew into a place for the smaller things too: the desk setups that ' +
|
|
588
|
-
'did not last, the tools that quietly disappeared, the habit that finally stuck after a dozen ' +
|
|
589
|
-
'that did not.'),
|
|
590
|
-
paragraph('Nothing here is written to sound like advice. Most of it is closer to a lab notebook — what I ' +
|
|
591
|
-
'tried, what broke, and the one detail that turned out to matter more than the rest. If a post ' +
|
|
592
|
-
'reads as useful to someone else, that is a bonus I do not plan around.'),
|
|
593
|
-
paragraph('This is a demo blog, scaffolded by create-cogenta from the "blog" blueprint. Its posts, ' +
|
|
594
|
-
'categories, tags and this very page were seeded by the installer so there is real content to ' +
|
|
595
|
-
'look at from the first run, not an empty admin screen.'),
|
|
596
|
-
paragraph('Everything here — the schema, the content, the skin — is a normal part of the site and is ' +
|
|
597
|
-
'meant to be edited, renamed or deleted the moment the defaults stop fitting.'),
|
|
598
|
-
],
|
|
599
|
-
},
|
|
600
|
-
],
|
|
601
|
-
},
|
|
602
|
-
];
|
|
603
|
-
}
|
|
604
|
-
/**
|
|
605
|
-
* Inserts the `blog` blueprint's demo content through the real `ContentStore`
|
|
606
|
-
* — never mocked (house rule).
|
|
607
|
-
*/
|
|
608
|
-
async function seedBlogDemoContent(ctx) {
|
|
609
|
-
const { db, defaultLocale, adminId, media } = ctx;
|
|
610
|
-
const categoryStore = createTaxonomyStore({ db, taxonomy: category });
|
|
611
|
-
const tagStore = createTaxonomyStore({ db, taxonomy: tag });
|
|
612
|
-
const postStore = createContentStore({ db, collection: post, defaultLocale });
|
|
613
|
-
const pageStore = createContentStore({ db, collection: page, defaultLocale });
|
|
614
|
-
const categoryIdBySlug = new Map();
|
|
615
|
-
for (const demo of BLOG_DEMO_CATEGORIES) {
|
|
616
|
-
const term = await categoryStore.create({
|
|
617
|
-
slug: demo.slug,
|
|
618
|
-
labels: { [defaultLocale]: demo.name },
|
|
619
|
-
});
|
|
620
|
-
categoryIdBySlug.set(demo.slug, term.id);
|
|
621
|
-
}
|
|
622
|
-
const tagIdBySlug = new Map();
|
|
623
|
-
for (const demo of BLOG_DEMO_TAGS) {
|
|
624
|
-
const term = await tagStore.create({
|
|
625
|
-
slug: demo.slug,
|
|
626
|
-
labels: { [defaultLocale]: demo.name },
|
|
627
|
-
});
|
|
628
|
-
tagIdBySlug.set(demo.slug, term.id);
|
|
629
|
-
}
|
|
630
|
-
for (const demo of BLOG_DEMO_POSTS) {
|
|
631
|
-
const cover = media[`post-${demo.slug}`];
|
|
632
|
-
await postStore.create({
|
|
633
|
-
status: 'published',
|
|
634
|
-
createdBy: adminId,
|
|
635
|
-
values: {
|
|
636
|
-
title: demo.title,
|
|
637
|
-
slug: demo.slug,
|
|
638
|
-
excerpt: demo.excerpt,
|
|
639
|
-
body: demo.body,
|
|
640
|
-
category: categoryIdBySlug.get(demo.categorySlug) ?? null,
|
|
641
|
-
tags: demo.tagSlugs.map((slug) => tagIdBySlug.get(slug)).filter((id) => id !== undefined),
|
|
642
|
-
...(cover === undefined ? {} : { coverImage: cover }),
|
|
643
|
-
},
|
|
644
|
-
});
|
|
645
|
-
}
|
|
646
|
-
for (const demo of buildBlogDemoPages(media)) {
|
|
647
|
-
await pageStore.create({
|
|
648
|
-
status: 'published',
|
|
649
|
-
createdBy: adminId,
|
|
650
|
-
values: { title: demo.title, slug: demo.slug },
|
|
651
|
-
blocks: { blocks: demo.blocks.map(toBlockZoneEntry) },
|
|
652
|
-
});
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
export const blogContentPack = {
|
|
656
|
-
collections: BLOG_COLLECTIONS,
|
|
657
|
-
taxonomies: BLOG_TAXONOMIES,
|
|
658
|
-
recommendedAgents: BLOG_RECOMMENDED_AGENTS,
|
|
659
|
-
seedDemoContent: seedBlogDemoContent,
|
|
660
|
-
defaultTheme: '@cogenta/theme-blog',
|
|
661
|
-
menus: BLOG_MENUS,
|
|
662
|
-
siteSettings: BLOG_SITE_SETTINGS,
|
|
663
|
-
mediaSpecs: BLOG_MEDIA_SPECS,
|
|
664
|
-
};
|
|
665
|
-
//# sourceMappingURL=blog.js.map
|