Skip to content

Commit 55b7f8c

Browse files
Stefen Alpergregberge
authored andcommitted
feat: seeds (#25)
1 parent e6c75c7 commit 55b7f8c

File tree

16 files changed

+402
-3
lines changed

16 files changed

+402
-3
lines changed

packages/smooth-backend-wordpress/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
},
2727
"dependencies": {
2828
"axios": "^0.18.0",
29+
"mime-types": "^2.1.24",
2930
"mkdirp": "^0.5.1",
3031
"ncp": "^2.0.0",
32+
"p-limit": "^2.2.0",
3133
"qs": "^6.7.0"
3234
}
3335
}

packages/smooth-backend-wordpress/src/acf/api.js

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import fs from 'fs'
12
import axios from 'axios'
23
import qs from 'qs'
4+
import path from 'path'
5+
import mime from 'mime-types'
6+
import pLimit from 'p-limit'
37

48
function getParams({ lang, type, query }) {
59
const params = {}
@@ -13,7 +17,19 @@ function paramsSerializer(params) {
1317
return qs.stringify(params, { arrayFormat: 'indices' })
1418
}
1519

16-
export function createClient({ baseUrl, defaultLanguage }) {
20+
export const onCreateResponse = ({ id, acf }) => ({ id, ...acf })
21+
22+
export function createClient({
23+
baseUrl,
24+
concurrency,
25+
password,
26+
user,
27+
defaultLanguage,
28+
}) {
29+
const limit = pLimit(concurrency)
30+
const token = Buffer.from(`${user}:${password}`).toString('base64')
31+
const headers = { Authorization: `Basic ${token}` }
32+
1733
return {
1834
async getContents({ type, slug, lang, query }) {
1935
type = type.toLowerCase()
@@ -40,10 +56,12 @@ export function createClient({ baseUrl, defaultLanguage }) {
4056
data,
4157
}
4258
},
59+
4360
async getContent(request) {
4461
const { data } = await this.getContents(request)
4562
return data[0] || null
4663
},
64+
4765
async getContentPreview({ lang, id }) {
4866
const params = getParams({ lang: lang || defaultLanguage })
4967
const { data } = await axios.get(
@@ -52,5 +70,52 @@ export function createClient({ baseUrl, defaultLanguage }) {
5270
)
5371
return data
5472
},
73+
74+
async create({ type, data }) {
75+
const url = `${baseUrl}/wp-json/wp/v2/${type}`
76+
77+
if (type === 'media') {
78+
const mediaPath = data
79+
const filename = path.basename(mediaPath)
80+
const { data: content } = await axios.post(url, fs.readFileSync(data), {
81+
headers: {
82+
'cache-control': 'no-cache',
83+
'Content-Disposition': `attachment; filename=${filename}`,
84+
'Content-Type': mime.contentType(filename),
85+
...headers,
86+
},
87+
})
88+
return onCreateResponse(content)
89+
}
90+
91+
const { data: content } = await axios.post(url, data, { headers })
92+
return onCreateResponse(content)
93+
},
94+
95+
async createMany({ type, data }) {
96+
return Promise.all(
97+
data.map(d => limit(() => this.create({ type, data: d }))),
98+
)
99+
},
100+
101+
async truncate({ type }) {
102+
const { data: results } = await axios.get(
103+
`${baseUrl}/wp-json/wp/v2/${type}`,
104+
{
105+
params: { per_page: 100 },
106+
},
107+
)
108+
109+
return Promise.all(
110+
results.map(async ({ id }) =>
111+
limit(() =>
112+
axios.delete(`${baseUrl}/wp-json/wp/v2/${type}/${id}`, {
113+
headers,
114+
params: { force: 1 },
115+
}),
116+
),
117+
),
118+
)
119+
},
55120
}
56121
}

packages/smooth-backend-wordpress/src/acf/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,13 @@ export async function getContents({ request }, options) {
3535
const apiClient = createClient(options)
3636
return apiClient.getContents(request)
3737
}
38+
39+
export async function createMany({ request }, options) {
40+
const apiClient = createClient(options)
41+
return apiClient.createMany(request)
42+
}
43+
44+
export async function truncate({ request }, options) {
45+
const apiClient = createClient(options)
46+
return apiClient.truncate(request)
47+
}

packages/smooth-backend-wordpress/src/smooth-node.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ export function resolveOptions(options) {
1515
options.homeUrl = process.env.WP_HOME
1616
}
1717

18+
options.user = options.user || process.env.WP_USER || 'admin'
19+
options.password = options.password || process.env.WP_PASSWORD || 'admin'
20+
options.concurrency =
21+
Number(options.concurrency || process.env.SEED_CONCURRENCY) || 8
22+
1823
return options
1924
}
2025

@@ -37,3 +42,20 @@ export async function getContent(params, options) {
3742
export async function getContents(params, options) {
3843
return acf.getContents(params, options)
3944
}
45+
46+
export async function createMany(params, options) {
47+
return acf.createMany(params, options)
48+
}
49+
50+
export async function truncate(params, options) {
51+
return acf.truncate(params, options)
52+
}
53+
54+
export function createBackendPayload({ data, name, type }) {
55+
if (type === 'media') {
56+
return data
57+
}
58+
59+
const { slug, ...fields } = data
60+
return { status: 'publish', slug, title: name, fields }
61+
}

packages/smooth/seeds.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./lib/seeds')

packages/smooth/src/api/index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,17 @@ export function createAPIClient({ config, lang }) {
1515
...options,
1616
})
1717
},
18+
async createMany(options) {
19+
return callApi(config.plugins, 'createMany', {
20+
...defaultOptions,
21+
...options,
22+
})
23+
},
24+
async truncate(options) {
25+
return callApi(config.plugins, 'truncate', {
26+
...defaultOptions,
27+
...options,
28+
})
29+
},
1830
}
1931
}

packages/smooth/src/cli/index.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import {
1212
buildSchemaDefinition,
1313
buildWebpack,
1414
} from '../build'
15+
import babelRequire from '../babel/require'
16+
import { createAPIClient } from '../api'
17+
import processSeeds from '../seeds/process'
1518

1619
const logger = createLogger()
1720

@@ -99,6 +102,18 @@ async function startCommand() {
99102
console.log('Started 🚀')
100103
}
101104

105+
async function seedCommand() {
106+
const config = await getConfig({ dev: false })
107+
const api = createAPIClient({ config })
108+
await processSeeds({
109+
api,
110+
config,
111+
createSeeds: babelRequire(config.seedsPath).default,
112+
logger,
113+
})
114+
console.log('Seeded 🍙')
115+
}
116+
102117
function runCmd(command) {
103118
command().catch(error => {
104119
// eslint-disable-next-line no-console
@@ -122,5 +137,9 @@ program
122137
'Starts the application in production mode.\nThe application should be compiled with `smooth build` first.',
123138
)
124139
.action(() => runCmd(startCommand))
140+
program
141+
.command('seed')
142+
.description('Seeds the application using ./seeds directory.')
143+
.action(() => runCmd(seedCommand))
125144

126145
program.parse(process.argv)

packages/smooth/src/config/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export async function getConfig({ dev }) {
3838
blocksPath: path.join(localCwd, 'src/blocks'),
3939
pagesPath: path.join(localCwd, 'src/pages'),
4040
schemasPath: path.join(localCwd, 'src/schemas'),
41+
seedsPath: path.join(localCwd, process.env.SEEDS_PATH || './seeds'),
4142
server: {
4243
port: process.env.PORT || 3000,
4344
},
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { applyHook } from '../node'
2+
3+
export const createBackendPayload = config => ({ data, name, type }) =>
4+
applyHook(config, 'createBackendPayload', { data, name, type }, 'data')
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
export * from './createBackendPayload'
12
export * from './onBuild'
23
export * from './onCreateApolloServerConfig'
3-
export * from './onCreateServer'
44
export * from './onCreateBabelConfig'
5+
export * from './onCreateServer'
56
export * from './onCreateWebpackConfig'
67
export * from './onRenderBody'
78
export * from './wrapRootElement'

0 commit comments

Comments
 (0)