1 | #!/usr/bin/env node
|
2 |
|
3 | const [
|
4 | knexfile = "knexfile.js",
|
5 | seedDir = "seeds",
|
6 | uploadDir = "uploads"
|
7 | ] = process.argv.slice(2);
|
8 | const knex = require("knex");
|
9 | const path = require("path");
|
10 | const { execSync } = require("child_process");
|
11 | const { writeFile, copyFile } = require("fs");
|
12 | const fs = require("fs-extra");
|
13 |
|
14 | const SEED_TEMPLATE = `// this file has been auto-generated by cotype seed creation
|
15 | const data = :data;
|
16 |
|
17 | exports.seed = knex =>
|
18 | knex(":name")
|
19 | .del()
|
20 | .then(() => {
|
21 | const seedData = [].concat(data);
|
22 | const chunks = [];
|
23 |
|
24 | while (seedData.length) {
|
25 | chunks.push(seedData.splice(0, 100));
|
26 | }
|
27 |
|
28 | return chunks.reduce(async (memo, chunk) => {
|
29 | await memo;
|
30 |
|
31 | return knex(":name").insert(chunk);
|
32 | }, Promise.resolve());
|
33 | });
|
34 | `;
|
35 |
|
36 | const tables = [
|
37 | "media",
|
38 | "roles",
|
39 | "users",
|
40 | "contents",
|
41 | "content_revisions",
|
42 | "content_values",
|
43 | "content_search",
|
44 | "content_references"
|
45 | ];
|
46 |
|
47 | const leftpad = (str, len, ch) => {
|
48 | while (String(str).length < len) {
|
49 | str = `${ch}${str}`;
|
50 | }
|
51 |
|
52 | return str;
|
53 | };
|
54 |
|
55 | const db = knex(require(path.resolve(knexfile)));
|
56 | const absSeedDir = path.resolve(seedDir);
|
57 | fs.ensureFileSync(absSeedDir);
|
58 | const absMediaDir = path.join(absSeedDir, "_media");
|
59 |
|
60 | execSync(`rm -rf ${absSeedDir}; mkdir ${absSeedDir} && mkdir ${absMediaDir}`);
|
61 |
|
62 | async function saveReferredMedia() {
|
63 | const contentReferences = await db.select().from("content_references");
|
64 |
|
65 | return Promise.all(
|
66 | contentReferences
|
67 | .filter(({ media }) => media)
|
68 | .map(({ media }) =>
|
69 | Promise.all([
|
70 | new Promise((resolve, reject) => {
|
71 | const destPath = path.resolve(absMediaDir, media);
|
72 | fs.ensureFileSync(destPath);
|
73 | copyFile(path.resolve(uploadDir, media), destPath, err =>
|
74 | err ? reject(err) : resolve()
|
75 | );
|
76 | }),
|
77 | new Promise((resolve, reject) => {
|
78 | const ext = path.extname(media);
|
79 | const dirname = path.dirname(media);
|
80 | const basename = path.basename(media, ext);
|
81 | const thumb = `${dirname}/${basename}.thumb.square${ext}`;
|
82 | const destPath = path.resolve(absMediaDir, thumb);
|
83 | fs.ensureFileSync(destPath);
|
84 | copyFile(path.resolve(uploadDir, thumb), destPath, err =>
|
85 | err ? reject(err) : resolve()
|
86 | );
|
87 | })
|
88 | ])
|
89 | )
|
90 | );
|
91 | }
|
92 |
|
93 | Promise.all(
|
94 | tables
|
95 | .map(async (tableName, i) => {
|
96 | const content = SEED_TEMPLATE.replace(/:name/g, tableName).replace(
|
97 | ":data",
|
98 | JSON.stringify(await db.select().from(tableName), null, 2)
|
99 | );
|
100 | return new Promise((resolve, reject) => {
|
101 | writeFile(
|
102 | path.resolve(absSeedDir, `${leftpad(i, 3, 0)}_${tableName}.js`),
|
103 | content,
|
104 | err => (err ? reject(err) : resolve())
|
105 | );
|
106 | });
|
107 | })
|
108 | .concat(saveReferredMedia())
|
109 | )
|
110 | .then(db.destroy)
|
111 | .then(() => {
|
112 | console.log(
|
113 | `OK: Seeds have been created in ./${path.relative(
|
114 | process.cwd(),
|
115 | absSeedDir
|
116 | )}`
|
117 | );
|
118 | })
|
119 | .catch(err => {
|
120 | console.error(err);
|
121 | process.exit(1);
|
122 | });
|