moonwave-gitlab 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/bun.lock +228 -0
- package/package.json +47 -0
- package/src/argv.ts +74 -0
- package/src/binary.ts +143 -0
- package/src/commands/build.ts +88 -0
- package/src/commands/dev.ts +83 -0
- package/src/getDocusaurusConfig.ts +168 -0
- package/src/index.ts +3 -0
- package/src/prepareProject.ts +492 -0
- package/src/typings/cachedir.d.ts +5 -0
- package/template/home/index.js +84 -0
- package/template/home/index.module.css +51 -0
- package/template/root/babel.config.js +3 -0
- package/template/root/package-lock.json +19700 -0
- package/template/root/package.json +38 -0
- package/template/root/src/css/moonwave.css +10 -0
- package/template/root/static/.nojekyll +0 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
import cachedir from "cachedir"
|
|
2
|
+
import { execSync } from "child_process"
|
|
3
|
+
import fs from "fs-extra"
|
|
4
|
+
import parseGitConfig from "parse-git-config"
|
|
5
|
+
import path, { dirname } from "path"
|
|
6
|
+
import toml from "toml"
|
|
7
|
+
import { fileURLToPath } from "url"
|
|
8
|
+
import getDocusaurusConfig, {
|
|
9
|
+
GenerateConfigParams,
|
|
10
|
+
} from "./getDocusaurusConfig.js"
|
|
11
|
+
|
|
12
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
13
|
+
|
|
14
|
+
const TEMPLATE_PATH = path.join(__dirname, "../template")
|
|
15
|
+
const ROOT_PATH = path.join(TEMPLATE_PATH, "root")
|
|
16
|
+
|
|
17
|
+
const SNIP_BEFORE = "<!--moonwave-hide-before-this-line-->"
|
|
18
|
+
const SNIP_AFTER = "<!--moonwave-hide-after-this-line-->"
|
|
19
|
+
const INDEX_EXTS = ["html", "js", "mdx", "md"]
|
|
20
|
+
const COPY_FOLDERS = ["blog", "docs", "pages"] as const
|
|
21
|
+
|
|
22
|
+
const NO_README_TEXT = (title: string) => `# ${title}
|
|
23
|
+
This project doesn't have a README.
|
|
24
|
+
If it had a README.md in its root directory, you would be reading that right now.`
|
|
25
|
+
|
|
26
|
+
const NO_GIT_REPO_TEXT = `# This project has no configured title
|
|
27
|
+
The site title is usually pulled from your Git repo, but no git repo could be detected.
|
|
28
|
+
Either set this project up as a Git repo, or configure the website title in moonwave.toml`
|
|
29
|
+
|
|
30
|
+
export type FoldersEnabled = {
|
|
31
|
+
[index in (typeof COPY_FOLDERS)[number]]: boolean
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type ClassOrder = (
|
|
35
|
+
| string
|
|
36
|
+
| {
|
|
37
|
+
section?: string
|
|
38
|
+
classes?: string[]
|
|
39
|
+
tag?: string
|
|
40
|
+
}
|
|
41
|
+
)[]
|
|
42
|
+
|
|
43
|
+
export type Config = Partial<{
|
|
44
|
+
// Moonwave
|
|
45
|
+
gitRepoUrl: string
|
|
46
|
+
gitSourceBranch: string
|
|
47
|
+
title: string
|
|
48
|
+
changelog: boolean
|
|
49
|
+
classOrder: ClassOrder
|
|
50
|
+
apiCategories: string[]
|
|
51
|
+
autoSectionPath?: string
|
|
52
|
+
|
|
53
|
+
// Docusaurus
|
|
54
|
+
docusaurus: Partial<{
|
|
55
|
+
title: string
|
|
56
|
+
tagline: string
|
|
57
|
+
url: string
|
|
58
|
+
baseUrl: string
|
|
59
|
+
onBrokenLinks: string
|
|
60
|
+
onBrokenMarkdownLinks: string
|
|
61
|
+
favicon: string
|
|
62
|
+
organizationName: string
|
|
63
|
+
projectName: string
|
|
64
|
+
}>
|
|
65
|
+
|
|
66
|
+
navbar: Partial<{
|
|
67
|
+
title: string
|
|
68
|
+
logo: { alt: string; src: string }
|
|
69
|
+
items: { to: string; label: string; position: "left" | "right" }[]
|
|
70
|
+
}>
|
|
71
|
+
|
|
72
|
+
home: Partial<{
|
|
73
|
+
enabled: boolean
|
|
74
|
+
bannerImage: string
|
|
75
|
+
includeReadme: boolean
|
|
76
|
+
|
|
77
|
+
features: {
|
|
78
|
+
title: string
|
|
79
|
+
description: string
|
|
80
|
+
image: string
|
|
81
|
+
}[]
|
|
82
|
+
}>
|
|
83
|
+
|
|
84
|
+
footer: Partial<{
|
|
85
|
+
style: string
|
|
86
|
+
links: {
|
|
87
|
+
title: string
|
|
88
|
+
copyright: string
|
|
89
|
+
items: { label: string; to: string }[]
|
|
90
|
+
}[]
|
|
91
|
+
}>
|
|
92
|
+
}>
|
|
93
|
+
|
|
94
|
+
function getGitRepoUrl(): string | undefined {
|
|
95
|
+
const gitConfig = parseGitConfig.sync()
|
|
96
|
+
|
|
97
|
+
if (gitConfig) {
|
|
98
|
+
if (gitConfig['remote "origin"']?.url?.includes("git@")) {
|
|
99
|
+
const [, repoHostSite, repoAuthor, repoName] = gitConfig[
|
|
100
|
+
'remote "origin"'
|
|
101
|
+
]?.url
|
|
102
|
+
.replace(/\.git$/, "")
|
|
103
|
+
.match(/^git@+(.+):(.+)\/(.+)$/)
|
|
104
|
+
return `https://${repoHostSite}/${repoAuthor}/${repoName}`
|
|
105
|
+
} else {
|
|
106
|
+
return gitConfig['remote "origin"']?.url
|
|
107
|
+
?.replace(/\.git$/, "")
|
|
108
|
+
?.replace(/\/\/.*@/, "//") // Strip out http basic auth if present
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function readConfig(projectDir: string): Config {
|
|
114
|
+
const configPath = path.join(projectDir, "moonwave")
|
|
115
|
+
|
|
116
|
+
if (fs.existsSync(configPath + ".toml")) {
|
|
117
|
+
return toml.parse(
|
|
118
|
+
fs.readFileSync(configPath + ".toml", { encoding: "utf-8" })
|
|
119
|
+
)
|
|
120
|
+
} else if (fs.existsSync(configPath + ".json")) {
|
|
121
|
+
return fs.readJSONSync(configPath + ".json")
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return {}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function getConfig(projectDir: string): Config {
|
|
128
|
+
const gitRepoUrl = getGitRepoUrl()
|
|
129
|
+
|
|
130
|
+
const [, repoAuthor, repoName] =
|
|
131
|
+
gitRepoUrl?.match(/^https?:\/\/.+\/(.+)\/(.+)$/) || []
|
|
132
|
+
|
|
133
|
+
const config = readConfig(projectDir)
|
|
134
|
+
|
|
135
|
+
// Note: Only copying values from other places in the config should go here.
|
|
136
|
+
// Default values for docusaurus.config.js belong in getDocusaurusConfig
|
|
137
|
+
return {
|
|
138
|
+
title: repoName,
|
|
139
|
+
gitRepoUrl: gitRepoUrl,
|
|
140
|
+
changelog: true,
|
|
141
|
+
...config,
|
|
142
|
+
|
|
143
|
+
docusaurus: {
|
|
144
|
+
projectName: repoName ?? undefined,
|
|
145
|
+
organizationName: repoAuthor ?? undefined,
|
|
146
|
+
title: config.title ?? repoName ?? "You need to configure your title",
|
|
147
|
+
baseUrl: repoName ? `/${repoName}/` : "/",
|
|
148
|
+
...config.docusaurus,
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
navbar: {
|
|
152
|
+
title: config.title ?? config.docusaurus?.title ?? repoName ?? "No Title",
|
|
153
|
+
...config.navbar,
|
|
154
|
+
},
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function prepareReadme(readmeContent: string): string {
|
|
159
|
+
while (true) {
|
|
160
|
+
const index_before = readmeContent.indexOf(SNIP_BEFORE)
|
|
161
|
+
const index_after = readmeContent.indexOf(SNIP_AFTER)
|
|
162
|
+
|
|
163
|
+
if (index_before > -1) {
|
|
164
|
+
if (index_after > -1 && index_after < index_before) {
|
|
165
|
+
// snip text between comments
|
|
166
|
+
readmeContent =
|
|
167
|
+
readmeContent.slice(0, index_after) +
|
|
168
|
+
readmeContent.slice(index_before + SNIP_BEFORE.length)
|
|
169
|
+
} else {
|
|
170
|
+
// regular hide before
|
|
171
|
+
readmeContent = readmeContent.slice(index_before + SNIP_BEFORE.length)
|
|
172
|
+
}
|
|
173
|
+
} else if (index_after > -1) {
|
|
174
|
+
// can only handle a lone hide-after if no hide-before
|
|
175
|
+
readmeContent = readmeContent.slice(0, index_after)
|
|
176
|
+
} else {
|
|
177
|
+
return readmeContent
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function makeHomePage(projectDir: string, tempDir: string, config: Config) {
|
|
183
|
+
if (
|
|
184
|
+
INDEX_EXTS.filter((ext) =>
|
|
185
|
+
fs.existsSync(path.join(projectDir, "pages", "index." + ext))
|
|
186
|
+
).length === 0
|
|
187
|
+
) {
|
|
188
|
+
fs.ensureDirSync(path.join(tempDir, "pages"))
|
|
189
|
+
|
|
190
|
+
INDEX_EXTS.forEach((ext) =>
|
|
191
|
+
fs.removeSync(path.join(tempDir, "pages", "index." + ext))
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
if (config.home?.enabled) {
|
|
195
|
+
const features = config.home?.features?.map((feature) => {
|
|
196
|
+
if (feature.image && feature.image.startsWith("/")) {
|
|
197
|
+
feature.image = config.docusaurus?.baseUrl + feature.image
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return feature
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
let indexSource = fs
|
|
204
|
+
.readFileSync(path.join(TEMPLATE_PATH, "home", "index.js"), {
|
|
205
|
+
encoding: "utf-8",
|
|
206
|
+
})
|
|
207
|
+
.replace("/***features***/", JSON.stringify(features ?? null))
|
|
208
|
+
|
|
209
|
+
const readmePath = path.join(
|
|
210
|
+
projectDir,
|
|
211
|
+
typeof config.home?.includeReadme === "string"
|
|
212
|
+
? config.home.includeReadme
|
|
213
|
+
: "README.md"
|
|
214
|
+
)
|
|
215
|
+
if (config.home?.includeReadme && fs.existsSync(readmePath)) {
|
|
216
|
+
fs.copyFileSync(readmePath, path.join(tempDir, "README.md"))
|
|
217
|
+
|
|
218
|
+
let readmeContent = fs.readFileSync(readmePath, { encoding: "utf-8" })
|
|
219
|
+
|
|
220
|
+
readmeContent = prepareReadme(readmeContent)
|
|
221
|
+
|
|
222
|
+
fs.writeFileSync(path.join(tempDir, "README.md"), readmeContent)
|
|
223
|
+
indexSource = 'import README from "../README.md"\n' + indexSource
|
|
224
|
+
indexSource = indexSource.replace("{/***readme***/}", "<README />")
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
fs.writeFileSync(path.join(tempDir, "pages", "index.js"), indexSource)
|
|
228
|
+
|
|
229
|
+
fs.copyFileSync(
|
|
230
|
+
path.join(TEMPLATE_PATH, "home", "index.module.css"),
|
|
231
|
+
path.join(tempDir, "pages", "index.module.css")
|
|
232
|
+
)
|
|
233
|
+
} else {
|
|
234
|
+
const indexPath = path.join(tempDir, "pages", "index.md")
|
|
235
|
+
const readmePath = path.join(projectDir, "README.md")
|
|
236
|
+
|
|
237
|
+
if (fs.existsSync(readmePath)) {
|
|
238
|
+
let readmeContent = fs.readFileSync(readmePath, { encoding: "utf-8" })
|
|
239
|
+
|
|
240
|
+
readmeContent = prepareReadme(readmeContent)
|
|
241
|
+
|
|
242
|
+
fs.writeFileSync(indexPath, readmeContent)
|
|
243
|
+
} else {
|
|
244
|
+
const placeholderHomeText = config.title
|
|
245
|
+
? NO_README_TEXT(config.title)
|
|
246
|
+
: NO_GIT_REPO_TEXT
|
|
247
|
+
|
|
248
|
+
fs.writeFileSync(indexPath, placeholderHomeText)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function copyChangelog(
|
|
255
|
+
projectDir: string,
|
|
256
|
+
tempDir: string,
|
|
257
|
+
config: Config
|
|
258
|
+
): boolean {
|
|
259
|
+
const changelogPath = path.join(projectDir, "CHANGELOG.md")
|
|
260
|
+
const targetPath = path.join(tempDir, "pages", "changelog.md")
|
|
261
|
+
|
|
262
|
+
if (config.changelog && fs.existsSync(changelogPath)) {
|
|
263
|
+
fs.ensureDirSync(path.join(tempDir, "pages"))
|
|
264
|
+
|
|
265
|
+
fs.copyFileSync(changelogPath, targetPath)
|
|
266
|
+
|
|
267
|
+
return true
|
|
268
|
+
} else if (fs.existsSync(targetPath)) {
|
|
269
|
+
fs.removeSync(targetPath)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return false
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function copyMoonwaveFolder(
|
|
276
|
+
projectDir: string,
|
|
277
|
+
tempDir: string
|
|
278
|
+
): { customCssExists: boolean; customSidebarExists: boolean } {
|
|
279
|
+
const staticDir = path.join(projectDir, ".moonwave", "static")
|
|
280
|
+
if (fs.existsSync(staticDir)) {
|
|
281
|
+
fs.copySync(staticDir, path.join(tempDir, "static"))
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const status = { customCssExists: false, customSidebarExists: false }
|
|
285
|
+
|
|
286
|
+
const customCssPath = path.join(projectDir, ".moonwave", "custom.css")
|
|
287
|
+
if (fs.existsSync(customCssPath)) {
|
|
288
|
+
fs.copySync(customCssPath, path.join(tempDir, "src", "css", "custom.css"))
|
|
289
|
+
|
|
290
|
+
status.customCssExists = true
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const customSidebarsPath = path.join(projectDir, ".moonwave", "sidebars.js")
|
|
294
|
+
if (fs.existsSync(customSidebarsPath)) {
|
|
295
|
+
fs.copySync(customSidebarsPath, path.join(tempDir, "src", "sidebars.js"))
|
|
296
|
+
|
|
297
|
+
status.customSidebarExists = true
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return status
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function writeDocusaurusConfig(tempDir: string, params: GenerateConfigParams) {
|
|
304
|
+
const docusaurusConfigPath = path.join(tempDir, "./docusaurus.config.js")
|
|
305
|
+
const newDocusaurusConfig =
|
|
306
|
+
"module.exports = " + JSON.stringify(getDocusaurusConfig(params), null, 2)
|
|
307
|
+
|
|
308
|
+
if (
|
|
309
|
+
fs.existsSync(docusaurusConfigPath) &&
|
|
310
|
+
fs.readFileSync(docusaurusConfigPath, { encoding: "utf-8" }) ===
|
|
311
|
+
newDocusaurusConfig
|
|
312
|
+
) {
|
|
313
|
+
return false
|
|
314
|
+
} else {
|
|
315
|
+
fs.writeFileSync(docusaurusConfigPath, newDocusaurusConfig)
|
|
316
|
+
return true
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function copyContentFolders(
|
|
321
|
+
projectDir: string,
|
|
322
|
+
tempDir: string
|
|
323
|
+
): FoldersEnabled {
|
|
324
|
+
return Object.fromEntries(
|
|
325
|
+
COPY_FOLDERS.map((folder) => {
|
|
326
|
+
const folderPath = path.join(projectDir, folder)
|
|
327
|
+
const targetPath = path.join(tempDir, folder)
|
|
328
|
+
|
|
329
|
+
if (fs.existsSync(folderPath)) {
|
|
330
|
+
fs.copySync(folderPath, targetPath)
|
|
331
|
+
return true
|
|
332
|
+
} else {
|
|
333
|
+
return false
|
|
334
|
+
}
|
|
335
|
+
}).map((wasFound, index) => [COPY_FOLDERS[index], wasFound])
|
|
336
|
+
) as FoldersEnabled
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
function needsCompleteRebuild(tempDir: string): boolean {
|
|
340
|
+
if (process.env.MOONWAVE_DEV) {
|
|
341
|
+
// We do fancy things to package.json in dev mode, which causes this code to always think a rebuild is needed
|
|
342
|
+
return false
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (
|
|
346
|
+
!fs.existsSync(tempDir) ||
|
|
347
|
+
!fs.existsSync(path.join(tempDir, "package.json")) ||
|
|
348
|
+
!fs.existsSync(path.join(tempDir, "package-lock.json"))
|
|
349
|
+
) {
|
|
350
|
+
console.log(
|
|
351
|
+
"Moonwave: package.json or package-lock.json does not exist, rebuilding..."
|
|
352
|
+
)
|
|
353
|
+
return true
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (
|
|
357
|
+
!fs
|
|
358
|
+
.readFileSync(path.join(ROOT_PATH, "package.json"))
|
|
359
|
+
.equals(fs.readFileSync(path.join(tempDir, "package.json")))
|
|
360
|
+
) {
|
|
361
|
+
console.log(
|
|
362
|
+
"Moonwave: package.json differs from cached files, rebuilding..."
|
|
363
|
+
)
|
|
364
|
+
return true
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return false
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export interface PreparedProject {
|
|
371
|
+
tempDir: string
|
|
372
|
+
projectDir: string
|
|
373
|
+
|
|
374
|
+
watchPaths: string[]
|
|
375
|
+
|
|
376
|
+
docusaurusConfigModified: boolean
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
export interface PrepareProjectOptions {
|
|
380
|
+
codePaths: string[]
|
|
381
|
+
binaryPath: string
|
|
382
|
+
skipRootCopy?: boolean
|
|
383
|
+
fresh?: boolean
|
|
384
|
+
install?: boolean
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export function prepareProject(
|
|
388
|
+
projectDir: string,
|
|
389
|
+
options: PrepareProjectOptions
|
|
390
|
+
): PreparedProject {
|
|
391
|
+
const config = getConfig(projectDir)
|
|
392
|
+
|
|
393
|
+
const folderName = projectDir.split(path.sep).slice(-1)[0] ?? "unknown"
|
|
394
|
+
const tempDir = path.join(cachedir("moonwave"), folderName)
|
|
395
|
+
|
|
396
|
+
if (
|
|
397
|
+
(options.install && fs.existsSync(tempDir)) ||
|
|
398
|
+
needsCompleteRebuild(tempDir)
|
|
399
|
+
) {
|
|
400
|
+
console.log(`Deleting ${tempDir} for complete re-install`)
|
|
401
|
+
fs.removeSync(tempDir)
|
|
402
|
+
} else if (options.fresh && fs.existsSync(tempDir)) {
|
|
403
|
+
for (const file of fs
|
|
404
|
+
.readdirSync(tempDir)
|
|
405
|
+
.filter((name) => name !== "node_modules")) {
|
|
406
|
+
fs.removeSync(path.join(tempDir, file))
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (!options.skipRootCopy) {
|
|
411
|
+
fs.copySync(ROOT_PATH, tempDir)
|
|
412
|
+
|
|
413
|
+
const moonwavePluginPath = process.env.MOONWAVE_PLUGIN_PATH
|
|
414
|
+
|
|
415
|
+
if (process.env.MOONWAVE_DEV || moonwavePluginPath) {
|
|
416
|
+
console.log(
|
|
417
|
+
`Moonwave: Using development Docusaurus plugin: ${
|
|
418
|
+
process.env.MOONWAVE_PLUGIN_PATH || "../../docusaurus-plugin-moonwave"
|
|
419
|
+
}`
|
|
420
|
+
)
|
|
421
|
+
const packageJsonPath = path.join(tempDir, "package.json")
|
|
422
|
+
|
|
423
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"))
|
|
424
|
+
packageJson.dependencies["docusaurus-plugin-moonwave"] =
|
|
425
|
+
moonwavePluginPath
|
|
426
|
+
? path.resolve(process.cwd(), moonwavePluginPath)
|
|
427
|
+
: path.resolve(__dirname, "../../docusaurus-plugin-moonwave")
|
|
428
|
+
|
|
429
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2))
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Create home page or copy readme
|
|
434
|
+
makeHomePage(projectDir, tempDir, config)
|
|
435
|
+
// Copy CHANGELOG.md if it exists
|
|
436
|
+
const changelogExists = copyChangelog(projectDir, tempDir, config)
|
|
437
|
+
|
|
438
|
+
const foundFolders = copyContentFolders(projectDir, tempDir)
|
|
439
|
+
|
|
440
|
+
const { customCssExists, customSidebarExists } = copyMoonwaveFolder(
|
|
441
|
+
projectDir,
|
|
442
|
+
tempDir
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
const docusaurusConfigModified = writeDocusaurusConfig(tempDir, {
|
|
446
|
+
config,
|
|
447
|
+
enablePlugins: foundFolders,
|
|
448
|
+
customCssExists,
|
|
449
|
+
customSidebarExists,
|
|
450
|
+
codePaths: options.codePaths,
|
|
451
|
+
binaryPath: options.binaryPath,
|
|
452
|
+
changelogExists,
|
|
453
|
+
projectDir,
|
|
454
|
+
classOrder: config.classOrder ?? [],
|
|
455
|
+
apiCategories: config.apiCategories ?? [],
|
|
456
|
+
autoSectionPath: config.autoSectionPath,
|
|
457
|
+
})
|
|
458
|
+
|
|
459
|
+
if (
|
|
460
|
+
!fs.existsSync(path.join(tempDir, "./node_modules")) ||
|
|
461
|
+
!fs.existsSync(path.join(tempDir, "./node_modules/.bin/docusaurus"))
|
|
462
|
+
) {
|
|
463
|
+
console.log("Installing dependencies (this might take awhile)...")
|
|
464
|
+
|
|
465
|
+
execSync("npm i", {
|
|
466
|
+
cwd: tempDir,
|
|
467
|
+
stdio: "inherit",
|
|
468
|
+
})
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
return {
|
|
472
|
+
docusaurusConfigModified,
|
|
473
|
+
tempDir,
|
|
474
|
+
projectDir,
|
|
475
|
+
watchPaths: [
|
|
476
|
+
path.join(
|
|
477
|
+
projectDir,
|
|
478
|
+
typeof config.home?.includeReadme === "string"
|
|
479
|
+
? config.home.includeReadme
|
|
480
|
+
: "README.md"
|
|
481
|
+
),
|
|
482
|
+
path.join(projectDir, "moonwave.toml"),
|
|
483
|
+
path.join(projectDir, "moonwave.json"),
|
|
484
|
+
path.join(projectDir, "CHANGELOG.md"),
|
|
485
|
+
path.join(projectDir, ".moonwave/"),
|
|
486
|
+
...Object.entries(foundFolders)
|
|
487
|
+
// .filter(([_folder, wasFound]) => wasFound)
|
|
488
|
+
.map(([folder]) => folder)
|
|
489
|
+
.map((folder) => path.join(projectDir, folder)),
|
|
490
|
+
],
|
|
491
|
+
}
|
|
492
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import Link from "@docusaurus/Link"
|
|
2
|
+
import useDocusaurusContext from "@docusaurus/useDocusaurusContext"
|
|
3
|
+
import Layout from "@theme/Layout"
|
|
4
|
+
import clsx from "clsx"
|
|
5
|
+
import React from "react"
|
|
6
|
+
import styles from "./index.module.css"
|
|
7
|
+
|
|
8
|
+
const FEATURES = /***features***/
|
|
9
|
+
|
|
10
|
+
function Feature({ image, title, description }) {
|
|
11
|
+
return (
|
|
12
|
+
<div className={clsx("col col--4")}>
|
|
13
|
+
{image && (
|
|
14
|
+
<div className="text--center">
|
|
15
|
+
<img className={styles.featureSvg} alt={title} src={image} />
|
|
16
|
+
</div>
|
|
17
|
+
)}
|
|
18
|
+
<div className="text--center padding-horiz--md">
|
|
19
|
+
<h3>{title}</h3>
|
|
20
|
+
<p>{description}</p>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function HomepageFeatures() {
|
|
27
|
+
if (!FEATURES) return null
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<section className={styles.features}>
|
|
31
|
+
<div className="container">
|
|
32
|
+
<div className="row">
|
|
33
|
+
{FEATURES.map((props, idx) => (
|
|
34
|
+
<Feature key={idx} {...props} />
|
|
35
|
+
))}
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</section>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function HomepageHeader() {
|
|
43
|
+
const { siteConfig } = useDocusaurusContext()
|
|
44
|
+
const bannerImage = siteConfig.customFields.bannerImage
|
|
45
|
+
const hasBannerImage = bannerImage ? true : false
|
|
46
|
+
const heroBannerStyle = hasBannerImage ? { backgroundImage: `url("${bannerImage}")` } : null
|
|
47
|
+
|
|
48
|
+
const titleClassName = clsx("hero__title", {
|
|
49
|
+
[styles.titleOnBannerImage]: hasBannerImage
|
|
50
|
+
})
|
|
51
|
+
const taglineClassName = clsx("hero__subtitle", {
|
|
52
|
+
[styles.taglineOnBannerImage]: hasBannerImage
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<header className={clsx("hero", styles.heroBanner)} style={heroBannerStyle}>
|
|
57
|
+
<div className="container">
|
|
58
|
+
<h1 className={titleClassName}>{siteConfig.title}</h1>
|
|
59
|
+
<p className={taglineClassName}>{siteConfig.tagline}</p>
|
|
60
|
+
<div className={styles.buttons}>
|
|
61
|
+
<Link
|
|
62
|
+
className="button button--secondary button--lg"
|
|
63
|
+
to="/docs/intro"
|
|
64
|
+
>
|
|
65
|
+
Get Started →
|
|
66
|
+
</Link>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</header>
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export default function Home() {
|
|
74
|
+
const { siteConfig, tagline } = useDocusaurusContext()
|
|
75
|
+
return (
|
|
76
|
+
<Layout title={siteConfig.title} description={tagline}>
|
|
77
|
+
<HomepageHeader />
|
|
78
|
+
<main>
|
|
79
|
+
<HomepageFeatures />
|
|
80
|
+
<div className="container">{/***readme***/}</div>
|
|
81
|
+
</main>
|
|
82
|
+
</Layout>
|
|
83
|
+
)
|
|
84
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* stylelint-disable docusaurus/copyright-header */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CSS files with the .module.css suffix will be treated as CSS modules
|
|
5
|
+
* and scoped locally.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
.heroBanner {
|
|
9
|
+
padding: 4rem 0;
|
|
10
|
+
text-align: center;
|
|
11
|
+
position: relative;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
|
|
14
|
+
background-repeat: no-repeat;
|
|
15
|
+
background-size: cover;
|
|
16
|
+
background-position: center;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@media screen and (max-width: 966px) {
|
|
20
|
+
.heroBanner {
|
|
21
|
+
padding: 2rem;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.buttons {
|
|
26
|
+
display: flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.features {
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
padding: 2rem 0;
|
|
35
|
+
width: 100%;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.featureSvg {
|
|
39
|
+
height: 200px;
|
|
40
|
+
width: 200px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.titleOnBannerImage {
|
|
44
|
+
text-shadow: 0px 2px 4px rgb(0, 0, 0);
|
|
45
|
+
color: var(--ifm-color-gray-100);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.taglineOnBannerImage {
|
|
49
|
+
text-shadow: 0px 2px 4px rgb(0, 0, 0);
|
|
50
|
+
color: var(--ifm-color-gray-100);
|
|
51
|
+
}
|