seed.js
7.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
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);
});