Skip to content

Commit

Permalink
Work works now
Browse files Browse the repository at this point in the history
Signed-off-by: Reece Dunham <me@rdil.rocks>
  • Loading branch information
RDIL committed Feb 3, 2021
1 parent 04cd562 commit 9441f47
Show file tree
Hide file tree
Showing 5 changed files with 334 additions and 107 deletions.
20 changes: 15 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "docusaurus-plugin-remote-content",
"version": "1.0.0",
"description": "A Docusaurus v2 plugin!",
"main": "src/index.js",
"repository": "https://github.com/rdilweb/template-docusaurus-plugin.git",
"description": "A Docusaurus v2 plugin that allows you to fetch content from remote sources!",
"main": "build/index.js",
"repository": "https://github.com/rdilweb/docusaurus-plugin-remote-content.git",
"author": "Reece Dunham <me@rdil.rocks>",
"license": "MIT",
"scripts": {
Expand All @@ -18,14 +18,24 @@
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@types/react-helmet": "^6.1.0",
"@types/rimraf": "^3.0.0",
"commander": "^7.0.0",
"prettier": "^2.2.1",
"typescript": "^4.1.3"
},
"peerDependencies": {
"@docusaurus/core": "2.x"
},
"bugs": {
"url": "https://github.com/rdilweb/docusaurus-plugin-remote-content/issues"
},
"dependencies": {
"axios": "^0.21.1"
}
"axios": "^0.21.1",
"chalk": "^4.1.0",
"pretty-ms": "^7.0.1",
"rimraf": "^3.0.2"
},
"files": [
"build"
]
}
263 changes: 162 additions & 101 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,129 +1,190 @@
import type { LoadContext, Props } from "@docusaurus/types"
import type { LoadContext } from "@docusaurus/types"
import type commander from "commander"
import axios from "axios"
import { writeFileSync } from "fs"
import { join } from "path"
import { sync as delFile } from "rimraf"
import chalk from "chalk"
import milli from "pretty-ms"

/**
* The plugin's options.
*/
export interface RemoteContentPluginOptions {
/**
* Delete local content after everything?
*/
performCleanup?: boolean

/**
* Is this instance for the docs plugin?
*/
docsIntegration?: boolean
/**
* Is this instance for the blog plugin?
*/
blogIntegration?: boolean

/**
* The base url for the source of the content.
*/
sourceBaseUrl: string
/**
* Specify the document paths from the sourceBaseUrl
* in a string array or function that returns a string array.
*/
documents?: string[] | (() => string[])
/**
* Delete local content after everything?
*/
performCleanup?: boolean
/**
* CLI only mode
*/
noRuntimeDownloads?: boolean

/**
* Is this instance for the docs plugin?
*/
docsIntegration?: boolean
/**
* Is this instance for the blog plugin?
*/
blogIntegration?: boolean

/**
* The base url for the source of the content.
*/
sourceBaseUrl: string
/**
* Specify the document paths from the sourceBaseUrl
* in a string array or function that returns a string array.
*/
documents?: string[] | (() => string[])
}

export type LoadableContent = void

interface Collectable {
url: string
identifier: string
url: string
identifier: string
}

// @ts-ignore
export default class PluginRemoteContent extends Plugin<LoadableContent, RemoteContentPluginOptions> {
name = "docusaurus-plugin-remote-content"

options: RemoteContentPluginOptions
context: LoadContext

constructor(context: LoadContext, options: RemoteContentPluginOptions) {
super(options, context)

this.options = options
this.context = context

this.onLoad()
}

onLoad(): void {
let { blogIntegration, docsIntegration, sourceBaseUrl, documents } = this.options

if (!([blogIntegration, docsIntegration].includes(true))) {
throw new Error("No integrations enabled! Please enable one of the blogIntegration, docsIntegration, or pagesIntegration fields in your remote-content plugin options.")
}

if (documents === undefined) {
throw new Error("The documents field is undefined, so I don't know what to fetch!")
}

if (sourceBaseUrl === undefined) {
throw new Error("The sourceBaseUrl field is undefined, so I don't know where to fetch from!")
}

if (!sourceBaseUrl.endsWith("/")) {
sourceBaseUrl = `${sourceBaseUrl}/`
export default function pluginRemoteContent(
context: LoadContext,
options: RemoteContentPluginOptions
): any {
let {
blogIntegration,
docsIntegration,
sourceBaseUrl,
documents,
noRuntimeDownloads,
performCleanup,
} = options

if (![blogIntegration, docsIntegration].includes(true)) {
throw new Error(
"No integrations enabled! Please enable either the blogIntegration or docsIntegration fields in your remote-content plugin options."
)
}

if (documents === undefined) {
throw new Error(
"The documents field is undefined, so I don't know what to fetch!"
)
}

if (sourceBaseUrl === undefined) {
throw new Error(
"The sourceBaseUrl field is undefined, so I don't know where to fetch from!"
)
}

if (!sourceBaseUrl.endsWith("/")) {
sourceBaseUrl = `${sourceBaseUrl}/`
}

function findCollectables(): Collectable[] {
const a: Collectable[] = []

if (docsIntegration === true || blogIntegration === true) {
;((typeof documents == "function"
? documents.call(context.siteConfig)
: documents) as string[]).forEach((d) => {
if (d.endsWith("md")) {
a.push({ url: `${sourceBaseUrl}/${d}`, identifier: d })
} else {
a.push({ url: `${sourceBaseUrl}/${d}.md`, identifier: `${d}.md` })
}
})
}

findCollectables(): Collectable[] {
const { documents, sourceBaseUrl } = this.options
const a: Collectable[] = []

if (this.options.docsIntegration === true) {
(
(typeof documents == "function" ? documents.call(this.context.siteConfig) : documents) as string[]
).forEach((d) => {
if (d.endsWith("md")) {
a.push({ url: `${sourceBaseUrl}/${d}`, identifier: d })
} else {
a.push({ url: `${sourceBaseUrl}/${d}.md`, identifier: `${d}.md` })
}
})
}
return a
}

return a
function getTargetDirectory(): string {
if (docsIntegration) {
return join(context.siteDir, "docs")
}

async loadContent(): Promise<LoadableContent> {
const c = this.findCollectables()
let loc = ""

if (this.options.docsIntegration) {
loc = join(this.context.siteDir, "docs")
}

if (this.options.blogIntegration) {
loc = join(this.context.siteDir, "blog")
}

for (let i = 0; i < c.length; i++) {
writeFileSync(join(loc, c[i].identifier), await (await axios({ url: c[i].url })).data)
}
if (blogIntegration) {
return join(context.siteDir, "blog")
}

async contentLoaded(): Promise<void> {
// The contentLoaded hook is done after loadContent hook is done.
}
return ""
}

async postBuild(props: Props): Promise<void> {
// After docusaurus <build> finish.
}
// 'this' is a huge mess in JS, so we avoid that where we can, such as here.
const pluginReturn = {
name: `docusaurus-plugin-remote-content-${
[blogIntegration && "blog", docsIntegration && "docs"].filter(Boolean)[0]
}`,

async loadContent(): Promise<LoadableContent> {
if ([false, undefined].includes(noRuntimeDownloads)) {
return await pluginReturn.fetchContent()
}
},

async postBuild(): Promise<void> {
if (performCleanup !== false) {
return await pluginReturn.cleanContent()
}
},

async fetchContent(): Promise<void> {
const c = findCollectables()

for (let i = 0; i < c.length; i++) {
writeFileSync(
join(getTargetDirectory(), c[i].identifier),
await (await axios({ url: c[i].url })).data
)
}
},

async cleanContent(): Promise<void> {
const c = findCollectables()

for (let i = 0; i < c.length; i++) {
delFile(join(getTargetDirectory(), c[i].identifier))
}
},

extendCli(cli: commander.CommanderStatic): void {
cli
.command("dothing")
.description("Does something")
.action(() => {})
}
const t = [blogIntegration && "blog", docsIntegration && "docs"].filter(
Boolean
)[0]

cli
.command(`download-remote-${t}`)
.description(`Downloads the remote ${t} data.`)
.action(() => {
;(async () => {
const startTime = new Date()
await pluginReturn.fetchContent()
console.log(
chalk`{green Successfully fetched content in} {white ${milli(
(new Date() as any) - (startTime as any)
)}}{green !}`
)
})()
})

cli
.command(`clear-remote-${t}`)
.description(`Removes the local copy of the remote ${t} data.`)
.action(() => {
;(async () => {
const startTime = new Date()
await pluginReturn.cleanContent()
console.log(
chalk`{green Successfully deleted content in} {white ${milli(
(new Date() as any) - (startTime as any)
)}}{green !}`
)
})()
})
},
}

return pluginReturn
}
2 changes: 2 additions & 0 deletions testsite/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*

docs/api.md
5 changes: 4 additions & 1 deletion testsite/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ module.exports = {
[
require.resolve("../build/index.js"),
{
// options here, or if you have none, just leave this empty.
docsIntegration: true,
sourceBaseUrl:
"https://raw.githubusercontent.com/rdilweb/docs/master/docs",
documents: ["api"],
},
],
],
Expand Down
Loading

0 comments on commit 9441f47

Please sign in to comment.