This commit is contained in:
Troughy
2026-05-19 22:15:11 +02:00
commit 2c7f61d62c
101 changed files with 26568 additions and 0 deletions
@@ -0,0 +1,194 @@
import type { Core } from '@strapi/strapi';
const DEMO_EMAIL = 'demo@strapi-demo.local';
const DEMO_PASSWORD = 'Demo1234!';
type PermissionMap = Record<string, string[]>;
async function ensurePermissions(
strapi: Core.Strapi,
roleType: 'public' | 'authenticated',
permissions: PermissionMap,
) {
const role = await strapi.db.query('plugin::users-permissions.role').findOne({
where: { type: roleType },
});
if (!role) return;
for (const [uid, actions] of Object.entries(permissions)) {
for (const action of actions) {
const permissionAction = `${uid}.${action}`;
const existing = await strapi.db.query('plugin::users-permissions.permission').findOne({
where: { action: permissionAction, role: role.id },
});
if (!existing) {
await strapi.db.query('plugin::users-permissions.permission').create({
data: { action: permissionAction, role: role.id },
});
}
}
}
}
async function ensureDemoUser(strapi: Core.Strapi) {
const existing = await strapi.db.query('plugin::users-permissions.user').findOne({
where: { email: DEMO_EMAIL },
});
if (existing) return;
const authenticatedRole = await strapi.db.query('plugin::users-permissions.role').findOne({
where: { type: 'authenticated' },
});
if (!authenticatedRole) return;
await strapi.plugin('users-permissions').service('user').add({
username: 'demo',
email: DEMO_EMAIL,
password: DEMO_PASSWORD,
role: authenticatedRole.id,
confirmed: true,
provider: 'local',
});
strapi.log.info(`Demo user created: ${DEMO_EMAIL} / ${DEMO_PASSWORD}`);
}
async function seedGlobal(strapi: Core.Strapi) {
const existing = await strapi.documents('api::global.global').findFirst({});
const data = {
siteName: 'Strapi Demo',
siteDescription: 'A small demo site powered by Strapi and Vue.',
heroTitle: 'Content managed in Strapi',
heroSubtitle: 'Edit copy, blog posts, and member-only pages from the Strapi admin — no redeploy needed.',
heroCtaLabel: 'Explore the blog',
defaultSeo: {
metaTitle: 'Strapi Demo',
metaDescription: 'See what Strapi can do with a Vue frontend.',
},
};
if (!existing) {
await strapi.documents('api::global.global').create({ data });
} else {
await strapi.documents('api::global.global').update({
documentId: existing.documentId,
data,
});
}
}
async function seedAbout(strapi: Core.Strapi) {
const existing = await strapi.documents('api::about.about').findFirst({});
if (!existing) {
await strapi.documents('api::about.about').create({
data: {
title: 'About this demo',
blocks: [
{
__component: 'shared.rich-text',
body: 'This site is a minimal showcase of Strapi as a headless CMS. Public pages load content from the Strapi REST API. The member area is protected — only logged-in users can fetch that content.',
},
{
__component: 'shared.quote',
title: 'Why Strapi?',
body: 'Give editors a friendly admin panel while developers keep building with their favorite frontend framework.',
},
],
} as never,
});
}
}
async function seedBlogPosts(strapi: Core.Strapi) {
const posts = [
{
title: 'What is a headless CMS?',
slug: 'what-is-a-headless-cms',
excerpt: 'Separate content from presentation and deliver it anywhere via APIs.',
body: '<p>A headless CMS stores structured content and exposes it through APIs. Your Vue app (or mobile app, or another site) decides how to display it.</p>',
},
{
title: 'Why teams pick Strapi',
slug: 'why-teams-pick-strapi',
excerpt: 'Open source, customizable, and quick to set up for prototypes and production.',
body: '<p>Strapi gives you content types, roles, media library, and plugins out of the box — perfect for demos like this one.</p>',
},
{
title: 'Connecting Vue to Strapi',
slug: 'connecting-vue-to-strapi',
excerpt: 'Use the REST API and JWT auth from your frontend.',
body: '<p>This demo uses fetch with a JWT stored in localStorage. Public endpoints need no token; protected content sends Authorization: Bearer …</p>',
},
];
for (const post of posts) {
const existing = await strapi.documents('api::blog-post.blog-post').findFirst({
filters: { slug: post.slug },
});
if (existing) {
if (!existing.publishedAt) {
await strapi.documents('api::blog-post.blog-post').publish({
documentId: existing.documentId,
});
}
continue;
}
await strapi.documents('api::blog-post.blog-post').create({
data: post,
status: 'published',
});
}
const testPost = await strapi.documents('api::blog-post.blog-post').findFirst({
filters: { slug: 'test' },
});
if (testPost) {
await strapi.documents('api::blog-post.blog-post').delete({
documentId: testPost.documentId,
});
}
}
async function seedMemberArea(strapi: Core.Strapi) {
const existing = await strapi.documents('api::member-area.member-area').findFirst({});
const data = {
title: 'Welcome, member!',
content:
'<p>This page is loaded from Strapis <strong>Member Area</strong> single type. The Public role cannot read it — you had to log in so the API returns this content.</p><p>Try changing this text in the Strapi admin under Content Manager → Member Area.</p>',
};
if (!existing) {
await strapi.documents('api::member-area.member-area').create({ data });
}
}
export async function setupDemo(strapi: Core.Strapi) {
await ensurePermissions(strapi, 'public', {
'api::global.global': ['find'],
'api::about.about': ['find'],
'api::blog-post.blog-post': ['find', 'findOne'],
});
await ensurePermissions(strapi, 'authenticated', {
'api::member-area.member-area': ['find'],
});
await ensureDemoUser(strapi);
await seedGlobal(strapi);
await seedAbout(strapi);
await seedBlogPosts(strapi);
await seedMemberArea(strapi);
strapi.log.info('Demo content and permissions are ready.');
}
export { DEMO_EMAIL, DEMO_PASSWORD };