aboutsummaryrefslogtreecommitdiff
path: root/playground/scripts/seed.js
diff options
context:
space:
mode:
Diffstat (limited to 'playground/scripts/seed.js')
-rw-r--r--playground/scripts/seed.js274
1 files changed, 274 insertions, 0 deletions
diff --git a/playground/scripts/seed.js b/playground/scripts/seed.js
new file mode 100644
index 0000000..d7e3505
--- /dev/null
+++ b/playground/scripts/seed.js
@@ -0,0 +1,274 @@
+'use strict';
+
+const fs = require('fs-extra');
+const path = require('path');
+const mime = require('mime-types');
+const { categories, authors, articles, global, about } = require('../data/data.json');
+
+async function seedExampleApp() {
+ const shouldImportSeedData = await isFirstRun();
+
+ if (shouldImportSeedData) {
+ try {
+ console.log('Setting up the template...');
+ await importSeedData();
+ console.log('Ready to go');
+ } catch (error) {
+ console.log('Could not import seed data');
+ console.error(error);
+ }
+ } else {
+ console.log(
+ 'Seed data has already been imported. We cannot reimport unless you clear your database first.'
+ );
+ }
+}
+
+async function isFirstRun() {
+ const pluginStore = strapi.store({
+ environment: strapi.config.environment,
+ type: 'type',
+ name: 'setup',
+ });
+ const initHasRun = await pluginStore.get({ key: 'initHasRun' });
+ await pluginStore.set({ key: 'initHasRun', value: true });
+ return !initHasRun;
+}
+
+async function setPublicPermissions(newPermissions) {
+ // Find the ID of the public role
+ const publicRole = await strapi.query('plugin::users-permissions.role').findOne({
+ where: {
+ type: 'public',
+ },
+ });
+
+ // Create the new permissions and link them to the public role
+ const allPermissionsToCreate = [];
+ Object.keys(newPermissions).map((controller) => {
+ const actions = newPermissions[controller];
+ const permissionsToCreate = actions.map((action) => {
+ return strapi.query('plugin::users-permissions.permission').create({
+ data: {
+ action: `api::${controller}.${controller}.${action}`,
+ role: publicRole.id,
+ },
+ });
+ });
+ allPermissionsToCreate.push(...permissionsToCreate);
+ });
+ await Promise.all(allPermissionsToCreate);
+}
+
+function getFileSizeInBytes(filePath) {
+ const stats = fs.statSync(filePath);
+ const fileSizeInBytes = stats['size'];
+ return fileSizeInBytes;
+}
+
+function getFileData(fileName) {
+ const filePath = path.join('data', 'uploads', fileName);
+ // Parse the file metadata
+ const size = getFileSizeInBytes(filePath);
+ const ext = fileName.split('.').pop();
+ const mimeType = mime.lookup(ext || '') || '';
+
+ return {
+ filepath: filePath,
+ originalFileName: fileName,
+ size,
+ mimetype: mimeType,
+ };
+}
+
+async function uploadFile(file, name) {
+ return strapi
+ .plugin('upload')
+ .service('upload')
+ .upload({
+ files: file,
+ data: {
+ fileInfo: {
+ alternativeText: `An image uploaded to Strapi called ${name}`,
+ caption: name,
+ name,
+ },
+ },
+ });
+}
+
+// Create an entry and attach files if there are any
+async function createEntry({ model, entry }) {
+ try {
+ // Actually create the entry in Strapi
+ await strapi.documents(`api::${model}.${model}`).create({
+ data: entry,
+ });
+ } catch (error) {
+ console.error({ model, entry, error });
+ }
+}
+
+async function checkFileExistsBeforeUpload(files) {
+ const existingFiles = [];
+ const uploadedFiles = [];
+ const filesCopy = [...files];
+
+ for (const fileName of filesCopy) {
+ // Check if the file already exists in Strapi
+ const fileWhereName = await strapi.query('plugin::upload.file').findOne({
+ where: {
+ name: fileName.replace(/\..*$/, ''),
+ },
+ });
+
+ if (fileWhereName) {
+ // File exists, don't upload it
+ existingFiles.push(fileWhereName);
+ } else {
+ // File doesn't exist, upload it
+ const fileData = getFileData(fileName);
+ const fileNameNoExtension = fileName.split('.').shift();
+ const [file] = await uploadFile(fileData, fileNameNoExtension);
+ uploadedFiles.push(file);
+ }
+ }
+ const allFiles = [...existingFiles, ...uploadedFiles];
+ // If only one file then return only that file
+ return allFiles.length === 1 ? allFiles[0] : allFiles;
+}
+
+async function updateBlocks(blocks) {
+ const updatedBlocks = [];
+ for (const block of blocks) {
+ if (block.__component === 'shared.media') {
+ const uploadedFiles = await checkFileExistsBeforeUpload([block.file]);
+ // Copy the block to not mutate directly
+ const blockCopy = { ...block };
+ // Replace the file name on the block with the actual file
+ blockCopy.file = uploadedFiles;
+ updatedBlocks.push(blockCopy);
+ } else if (block.__component === 'shared.slider') {
+ // Get files already uploaded to Strapi or upload new files
+ const existingAndUploadedFiles = await checkFileExistsBeforeUpload(block.files);
+ // Copy the block to not mutate directly
+ const blockCopy = { ...block };
+ // Replace the file names on the block with the actual files
+ blockCopy.files = existingAndUploadedFiles;
+ // Push the updated block
+ updatedBlocks.push(blockCopy);
+ } else {
+ // Just push the block as is
+ updatedBlocks.push(block);
+ }
+ }
+
+ return updatedBlocks;
+}
+
+async function importArticles() {
+ for (const article of articles) {
+ const cover = await checkFileExistsBeforeUpload([`${article.slug}.jpg`]);
+ const updatedBlocks = await updateBlocks(article.blocks);
+
+ await createEntry({
+ model: 'article',
+ entry: {
+ ...article,
+ cover,
+ blocks: updatedBlocks,
+ // Make sure it's not a draft
+ publishedAt: Date.now(),
+ },
+ });
+ }
+}
+
+async function importGlobal() {
+ const favicon = await checkFileExistsBeforeUpload(['favicon.png']);
+ const shareImage = await checkFileExistsBeforeUpload(['default-image.png']);
+ return createEntry({
+ model: 'global',
+ entry: {
+ ...global,
+ favicon,
+ // Make sure it's not a draft
+ publishedAt: Date.now(),
+ defaultSeo: {
+ ...global.defaultSeo,
+ shareImage,
+ },
+ },
+ });
+}
+
+async function importAbout() {
+ const updatedBlocks = await updateBlocks(about.blocks);
+
+ await createEntry({
+ model: 'about',
+ entry: {
+ ...about,
+ blocks: updatedBlocks,
+ // Make sure it's not a draft
+ publishedAt: Date.now(),
+ },
+ });
+}
+
+async function importCategories() {
+ for (const category of categories) {
+ await createEntry({ model: 'category', entry: category });
+ }
+}
+
+async function importAuthors() {
+ for (const author of authors) {
+ const avatar = await checkFileExistsBeforeUpload([author.avatar]);
+
+ await createEntry({
+ model: 'author',
+ entry: {
+ ...author,
+ avatar,
+ },
+ });
+ }
+}
+
+async function importSeedData() {
+ // Allow read of application content types
+ await setPublicPermissions({
+ article: ['find', 'findOne'],
+ category: ['find', 'findOne'],
+ author: ['find', 'findOne'],
+ global: ['find', 'findOne'],
+ about: ['find', 'findOne'],
+ });
+
+ // Create all entries
+ await importCategories();
+ await importAuthors();
+ await importArticles();
+ await importGlobal();
+ await importAbout();
+}
+
+async function main() {
+ const { createStrapi, compileStrapi } = require('@strapi/strapi');
+
+ const appContext = await compileStrapi();
+ const app = await createStrapi(appContext).load();
+
+ app.log.level = 'error';
+
+ await seedExampleApp();
+ await app.destroy();
+
+ process.exit(0);
+}
+
+main().catch((error) => {
+ console.error(error);
+ process.exit(1);
+});