mirror of
https://github.com/zhigang1992/docz.git
synced 2026-03-26 10:14:33 +08:00
fix(docz-core): data server rewriting files and refac utils (#370)
* chore: update dependencies * chore: prettier fix * fix(docz-core): data server rewriting files * feat(rehype-docz): add __componentPath on PropsTable * feat(docz-utils): add first version of package * chore(docz-utils): refac to include some more utils * chore(docz-core): remove unnescessary code * chore: tslint error
This commit is contained in:
@@ -7,14 +7,14 @@
|
||||
"build": "docz build"
|
||||
},
|
||||
"dependencies": {
|
||||
"emotion": "^9.2.8",
|
||||
"emotion": "^9.2.9",
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^16.5.0",
|
||||
"react-dom": "^16.5.0",
|
||||
"react-emotion": "^9.2.8"
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-emotion": "^9.2.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-plugin-emotion": "^9.2.8",
|
||||
"babel-plugin-emotion": "^9.2.9",
|
||||
"docz": "^0.11.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,17 +7,17 @@
|
||||
"build": "docz build"
|
||||
},
|
||||
"dependencies": {
|
||||
"emotion": "^9.2.8",
|
||||
"emotion": "^9.2.9",
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^16.5.0",
|
||||
"react-dom": "^16.5.0",
|
||||
"react-emotion": "^9.2.8"
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-emotion": "^9.2.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-flow": "^7.0.0",
|
||||
"babel-plugin-emotion": "^9.2.8",
|
||||
"babel-plugin-emotion": "^9.2.9",
|
||||
"docz": "^0.11.2",
|
||||
"flow-bin": "^0.80.0",
|
||||
"flow-bin": "^0.81.0",
|
||||
"flow-typed": "^2.5.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^16.5.0",
|
||||
"react-dom": "^16.5.0",
|
||||
"styled-components": "^3.4.5"
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.5.2",
|
||||
"styled-components": "^3.4.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"docz": "^0.11.2"
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
"dependencies": {
|
||||
"docz": "^0.11.2",
|
||||
"docz-core": "^0.11.2",
|
||||
"emotion": "^9.2.8",
|
||||
"react": "^16.5.0",
|
||||
"react-dom": "^16.5.0",
|
||||
"react-emotion": "^9.2.8"
|
||||
"emotion": "^9.2.9",
|
||||
"react": "^16.5.2",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-emotion": "^9.2.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-plugin-emotion": "^9.2.8"
|
||||
"babel-plugin-emotion": "^9.2.9"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,15 +37,15 @@
|
||||
"commitizen": "^2.10.1",
|
||||
"del": "^3.0.0",
|
||||
"husky": "^1.0.0-rc.13",
|
||||
"lerna": "3.3.0",
|
||||
"libundler": "^1.7.1",
|
||||
"lerna": "3.4.0",
|
||||
"libundler": "^1.7.6",
|
||||
"lint-staged": "^7.2.2",
|
||||
"npm-run-all": "^4.1.3",
|
||||
"prettier": "^1.14.2",
|
||||
"trash-cli": "^1.4.0",
|
||||
"tslint": "^5.11.0",
|
||||
"tslint-config-prettier": "^1.15.0",
|
||||
"typescript": "^2.9.2"
|
||||
"typescript": "^3.0.3"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/*",
|
||||
|
||||
@@ -22,17 +22,17 @@
|
||||
"tslint": "tslint --project ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "7.0.0",
|
||||
"@babel/plugin-proposal-class-properties": "7.0.0",
|
||||
"@babel/core": "7.1.0",
|
||||
"@babel/plugin-proposal-class-properties": "7.1.0",
|
||||
"@babel/plugin-proposal-object-rest-spread": "7.0.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "7.0.0",
|
||||
"@babel/plugin-transform-destructuring": "7.0.0",
|
||||
"@babel/plugin-transform-regenerator": "7.0.0",
|
||||
"@babel/plugin-transform-runtime": "7.0.0",
|
||||
"@babel/preset-env": "7.0.0",
|
||||
"@babel/plugin-transform-runtime": "7.1.0",
|
||||
"@babel/preset-env": "7.1.0",
|
||||
"@babel/preset-flow": "7.0.0",
|
||||
"@babel/preset-react": "7.0.0",
|
||||
"@babel/preset-typescript": "7.0.0",
|
||||
"@babel/preset-typescript": "7.1.0",
|
||||
"babel-plugin-macros": "^2.4.0",
|
||||
"babel-plugin-react-docgen": "^2.0.0",
|
||||
"babel-plugin-transform-dynamic-import": "^2.0.0",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"tslint": "tslint --project ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "7.0.0",
|
||||
"@babel/core": "7.1.0",
|
||||
"@babel/polyfill": "7.0.0",
|
||||
"@babel/runtime": "^7.0.0",
|
||||
"@mdx-js/loader": "^0.15.2",
|
||||
@@ -41,6 +41,7 @@
|
||||
"cpy": "^7.0.1",
|
||||
"deepmerge": "^2.1.1",
|
||||
"detect-port": "^1.2.3",
|
||||
"docz-utils": "^0.11.2",
|
||||
"dotenv": "^6.0.0",
|
||||
"env-dot-prop": "^1.0.2",
|
||||
"fast-deep-equal": "^2.0.1",
|
||||
@@ -53,7 +54,7 @@
|
||||
"happypack": "^5.0.0",
|
||||
"html-minifier": "^3.5.20",
|
||||
"humanize-string": "^1.0.2",
|
||||
"koa": "^2.5.2",
|
||||
"koa": "^2.5.3",
|
||||
"koa-connect": "^2.0.1",
|
||||
"koa-mount": "^3.0.0",
|
||||
"koa-range": "^0.3.0",
|
||||
@@ -61,37 +62,29 @@
|
||||
"load-cfg": "^0.11.1",
|
||||
"lodash.get": "^4.4.2",
|
||||
"mini-html-webpack-plugin": "^0.2.3",
|
||||
"prettier": "^1.14.2",
|
||||
"react-dev-utils": "^5.0.2",
|
||||
"react-docgen-typescript-loader": "^3.0.0-rc.0",
|
||||
"react-hot-loader": "4.3.6",
|
||||
"react-hot-loader": "4.3.8",
|
||||
"rehype-docz": "^0.11.0",
|
||||
"rehype-slug": "^2.0.1",
|
||||
"remark-docz": "^0.11.0",
|
||||
"remark-frontmatter": "^1.2.1",
|
||||
"remark-parse": "^5.0.0",
|
||||
"remark-parse-yaml": "^0.0.1",
|
||||
"remark-slug": "^5.1.0",
|
||||
"resolve": "^1.8.1",
|
||||
"signale": "^1.2.1",
|
||||
"signale": "^1.3.0",
|
||||
"titleize": "^1.0.1",
|
||||
"to-vfile": "^5.0.1",
|
||||
"uglifyjs-webpack-plugin": "^1.3.0",
|
||||
"unified": "^7.0.0",
|
||||
"unist-util-find": "^1.0.1",
|
||||
"unist-util-is": "^2.1.2",
|
||||
"unist-util-visit": "^1.4.0",
|
||||
"terser-webpack-plugin": "^1.1.0",
|
||||
"url-loader": "^1.1.1",
|
||||
"webpack": "^4.17.2",
|
||||
"webpack-chain": "^4.10.0",
|
||||
"webpack": "^4.19.1",
|
||||
"webpack-chain": "^4.11.0",
|
||||
"webpack-hot-client": "^4.1.1",
|
||||
"webpack-manifest-plugin": "^2.0.3",
|
||||
"webpack-manifest-plugin": "^2.0.4",
|
||||
"webpack-serve": "^2.0.2",
|
||||
"webpack-serve-overlay": "^0.3.0",
|
||||
"webpack-serve-waitpage": "^1.0.2",
|
||||
"webpackbar": "^2.6.3",
|
||||
"ws": "^6.0.0",
|
||||
"yargs": "^12.0.1"
|
||||
"yargs": "^12.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chokidar": "^1.7.5",
|
||||
@@ -102,13 +95,13 @@
|
||||
"@types/html-webpack-plugin": "^3.2.0",
|
||||
"@types/koa": "^2.0.46",
|
||||
"@types/lodash.get": "^4.4.4",
|
||||
"@types/node": "10.9.4",
|
||||
"@types/node": "10.10.1",
|
||||
"@types/prettier": "^1.13.2",
|
||||
"@types/resolve": "^0.0.8",
|
||||
"@types/webpack": "^4.4.11",
|
||||
"@types/webpack-chain": "^4.8.1",
|
||||
"@types/ws": "^6.0.1",
|
||||
"@types/yargs": "^11.1.1",
|
||||
"@types/yargs": "^12.0.0",
|
||||
"tslint": "^5.11.0",
|
||||
"tslint-config-prettier": "^1.15.0",
|
||||
"typescript": "^3.0.1"
|
||||
|
||||
@@ -60,7 +60,7 @@ export class DataServer {
|
||||
)
|
||||
)
|
||||
|
||||
await touch(paths.db, JSON.stringify(this.state, null, 2))
|
||||
this.updateStateFile()
|
||||
}
|
||||
|
||||
public async listen(): Promise<void> {
|
||||
@@ -97,6 +97,11 @@ export class DataServer {
|
||||
return (key: string, val: any): void => {
|
||||
this.state[key] = val
|
||||
send(`state.${key}`, val)
|
||||
this.updateStateFile()
|
||||
}
|
||||
}
|
||||
|
||||
private async updateStateFile(): Promise<void> {
|
||||
await touch(paths.db, JSON.stringify(this.state, null, 2))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as path from 'path'
|
||||
import * as fs from 'fs-extra'
|
||||
import { parseMdx } from 'docz-utils/lib/mdast'
|
||||
import glob from 'fast-glob'
|
||||
|
||||
import * as paths from './config/paths'
|
||||
@@ -9,11 +10,9 @@ import { mapToObj } from './utils/helpers'
|
||||
import { Entry, EntryObj } from './Entry'
|
||||
import { Plugin } from './Plugin'
|
||||
import { Config } from './commands/args'
|
||||
import { parseMdx } from './utils/ast'
|
||||
import { getRepoEditUrl } from './utils/repo-info'
|
||||
|
||||
const DEFAULT_IGNORE = [
|
||||
'!**/node_modules/**',
|
||||
'readme.md',
|
||||
'changelog.md',
|
||||
'code_of_conduct.md',
|
||||
@@ -21,6 +20,9 @@ const DEFAULT_IGNORE = [
|
||||
'license.md',
|
||||
]
|
||||
|
||||
const ignoreFiles = (arr: string[]) =>
|
||||
['!**/node_modules/**'].concat(arr.length > 0 ? arr : DEFAULT_IGNORE)
|
||||
|
||||
export const fromTemplates = (file: string) => path.join(paths.templates, file)
|
||||
|
||||
const matchFilesWithSrc = (config: Config) => (files: string[]) => {
|
||||
@@ -83,7 +85,7 @@ export class Entries {
|
||||
const toMatch = matchFilesWithSrc(config)
|
||||
|
||||
const files = await glob<string>(toMatch(arr), {
|
||||
ignore: DEFAULT_IGNORE.concat(ignore),
|
||||
ignore: ignoreFiles(ignore),
|
||||
onlyFiles: true,
|
||||
unique: true,
|
||||
nocase: true,
|
||||
|
||||
@@ -2,45 +2,14 @@ import * as path from 'path'
|
||||
import * as crypto from 'crypto'
|
||||
import slugify from '@sindresorhus/slugify'
|
||||
import humanize from 'humanize-string'
|
||||
import find from 'unist-util-find'
|
||||
import is from 'unist-util-is'
|
||||
import visit from 'unist-util-visit'
|
||||
import get from 'lodash.get'
|
||||
import {
|
||||
Heading,
|
||||
getParsedData,
|
||||
headingsFromAst,
|
||||
ParsedData,
|
||||
} from 'docz-utils/lib/mdast'
|
||||
|
||||
import * as paths from './config/paths'
|
||||
import { valueFromHeading } from './utils/ast'
|
||||
|
||||
interface ParsedData {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
const getParsedData = (ast: any): ParsedData => {
|
||||
const node = find(ast, (node: any) => is('yaml', node))
|
||||
return get(node, `data.parsedValue`) || {}
|
||||
}
|
||||
|
||||
export interface Heading {
|
||||
depth: number
|
||||
slug: string
|
||||
value: string
|
||||
}
|
||||
|
||||
const getHeadings = (ast: any): Heading[] => {
|
||||
const headings: Heading[] = []
|
||||
|
||||
visit(ast, 'heading', (node: any) => {
|
||||
const slug = get(node, 'data.id')
|
||||
const depth = get(node, 'depth')
|
||||
|
||||
headings.push({
|
||||
depth,
|
||||
slug,
|
||||
value: valueFromHeading(node),
|
||||
})
|
||||
})
|
||||
|
||||
return headings
|
||||
}
|
||||
|
||||
const createId = (file: string) =>
|
||||
crypto
|
||||
@@ -90,7 +59,7 @@ export class Entry {
|
||||
this.name = name
|
||||
this.order = parsed.order || 0
|
||||
this.menu = parsed.menu || null
|
||||
this.headings = getHeadings(ast)
|
||||
this.headings = headingsFromAst(ast)
|
||||
this.settings = parsed
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { minify } from 'html-minifier'
|
||||
import miniHtmlWebpack from 'mini-html-webpack-plugin'
|
||||
import friendlyErrors from 'friendly-errors-webpack-plugin'
|
||||
import manifestPlugin from 'webpack-manifest-plugin'
|
||||
import UglifyJs from 'uglifyjs-webpack-plugin'
|
||||
import TerserPlugin from 'terser-webpack-plugin'
|
||||
|
||||
import * as loaders from './loaders'
|
||||
import * as paths from '../../config/paths'
|
||||
@@ -15,11 +15,8 @@ import { Config as Args, Env } from '../../commands/args'
|
||||
import { BabelRC } from '../../utils/babel-config'
|
||||
import { parseHtml, htmlTemplate } from '../../utils/parse-html'
|
||||
|
||||
const uglify = new UglifyJs({
|
||||
parallel: true,
|
||||
cache: true,
|
||||
sourceMap: true,
|
||||
uglifyOptions: {
|
||||
const terser = new TerserPlugin({
|
||||
terserOptions: {
|
||||
parse: {
|
||||
ecma: 8,
|
||||
},
|
||||
@@ -37,6 +34,9 @@ const uglify = new UglifyJs({
|
||||
ascii_only: true,
|
||||
},
|
||||
},
|
||||
parallel: true,
|
||||
cache: true,
|
||||
sourceMap: true,
|
||||
})
|
||||
|
||||
export const createConfig = (args: Args, env: Env) => async (
|
||||
@@ -105,7 +105,7 @@ export const createConfig = (args: Args, env: Env) => async (
|
||||
},
|
||||
...(isProd && {
|
||||
minimize: true,
|
||||
minimizer: [uglify],
|
||||
minimizer: [terser],
|
||||
}),
|
||||
},
|
||||
})
|
||||
@@ -123,9 +123,9 @@ export const createConfig = (args: Args, env: Env) => async (
|
||||
* resolve
|
||||
*/
|
||||
|
||||
config.resolve
|
||||
.set('symlinks', true)
|
||||
.extensions.add('.web.js')
|
||||
config.resolve.set('symlinks', true)
|
||||
config.resolve.extensions
|
||||
.add('.web.js')
|
||||
.add('.mjs')
|
||||
.add('.js')
|
||||
.add('.json')
|
||||
|
||||
@@ -12,13 +12,15 @@ import { Config } from './args'
|
||||
export const build = async (args: Config) => {
|
||||
const env = envDotProp.get('node.env')
|
||||
const config = loadConfig(args)
|
||||
const entries = new Entries(config)
|
||||
|
||||
const bundler = webpack(config, env)
|
||||
const run = Plugin.runPluginsMethod(config.plugins)
|
||||
const dataServer = new DataServer()
|
||||
|
||||
try {
|
||||
dataServer.register([states.entries(config), states.config(config)])
|
||||
dataServer.register([states.config(config), states.entries(entries, config)])
|
||||
|
||||
try {
|
||||
await Entries.writeApp(config)
|
||||
await dataServer.init()
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ export const dev = async (args: Config) => {
|
||||
|
||||
const newConfig = { ...config, websocketPort, hotPort, port }
|
||||
const bundler = webpack(newConfig, env)
|
||||
const entries = new Entries(config)
|
||||
|
||||
const bundlerConfig = await bundler.getConfig(env)
|
||||
const server = await bundler.createServer(bundlerConfig)
|
||||
const { app } = await server.start()
|
||||
@@ -32,9 +34,12 @@ export const dev = async (args: Config) => {
|
||||
config.websocketHost
|
||||
)
|
||||
|
||||
try {
|
||||
dataServer.register([states.entries(newConfig), states.config(newConfig)])
|
||||
dataServer.register([
|
||||
states.config(newConfig),
|
||||
states.entries(entries, newConfig),
|
||||
])
|
||||
|
||||
try {
|
||||
await Entries.writeApp(newConfig, true)
|
||||
await dataServer.init()
|
||||
await dataServer.listen()
|
||||
|
||||
@@ -3,10 +3,12 @@ import slug from 'rehype-slug'
|
||||
import remarkDocz from 'remark-docz'
|
||||
import rehypeDocz from 'rehype-docz'
|
||||
|
||||
import * as paths from './paths'
|
||||
|
||||
export const config = {
|
||||
type: 'yaml',
|
||||
marker: '-',
|
||||
}
|
||||
|
||||
export const remarkPlugins = [matter, remarkDocz]
|
||||
export const rehypePlugins = [rehypeDocz, slug]
|
||||
export const rehypePlugins = [rehypeDocz(paths.root), slug]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import * as fs from 'fs-extra'
|
||||
import { load, finds } from 'load-cfg'
|
||||
import chokidar from 'chokidar'
|
||||
import equal from 'fast-deep-equal'
|
||||
import get from 'lodash.get'
|
||||
|
||||
import { Params, State } from '../DataServer'
|
||||
@@ -36,18 +35,13 @@ const getInitialConfig = (config: Config): Payload => {
|
||||
}
|
||||
}
|
||||
|
||||
const updateConfig = (config: Config) => async (p: Params) => {
|
||||
const old = p.state.config
|
||||
const newConfig = load('docz', getInitialConfig(config), true, false)
|
||||
|
||||
if (newConfig && !equal(old, newConfig)) {
|
||||
p.setState('config', newConfig)
|
||||
}
|
||||
}
|
||||
const updateConfig = (config: Config) => async ({ setState }: Params) =>
|
||||
setState('config', load('docz', getInitialConfig(config), true, false))
|
||||
|
||||
export const state = (config: Config): State => {
|
||||
const watcher = chokidar.watch(finds('docz'), {
|
||||
cwd: paths.root,
|
||||
ignored: /(^|[\/\\])\../,
|
||||
persistent: true,
|
||||
})
|
||||
|
||||
@@ -55,10 +49,11 @@ export const state = (config: Config): State => {
|
||||
init: updateConfig(config),
|
||||
update: async params => {
|
||||
const update = updateConfig(config)
|
||||
const fn = async () => update(params)
|
||||
|
||||
watcher.on('add', async () => update(params))
|
||||
watcher.on('change', async () => update(params))
|
||||
watcher.on('unlink', async () => update(params))
|
||||
watcher.on('add', fn)
|
||||
watcher.on('change', fn)
|
||||
watcher.on('unlink', fn)
|
||||
|
||||
return () => watcher.close()
|
||||
},
|
||||
|
||||
@@ -25,8 +25,7 @@ const updateEntries = (entries: Entries) => async (p: Params) => {
|
||||
}
|
||||
}
|
||||
|
||||
export const state = (config: Config): State => {
|
||||
const entries = new Entries(config)
|
||||
export const state = (entries: Entries, config: Config): State => {
|
||||
const src = path.relative(paths.root, config.src)
|
||||
const files = path.join(src, config.files)
|
||||
const watcher = chokidar.watch(files, {
|
||||
|
||||
10
packages/docz-core/src/types.d.ts
vendored
10
packages/docz-core/src/types.d.ts
vendored
@@ -9,29 +9,21 @@ declare module 'find-up'
|
||||
declare module 'humanize-string'
|
||||
declare module 'get-pkg-repo'
|
||||
declare module 'titleize'
|
||||
declare module 'unified'
|
||||
declare module 'strip-indent'
|
||||
declare module 'unist-util-is'
|
||||
declare module 'unist-util-visit'
|
||||
declare module 'unist-util-find'
|
||||
declare module 'unist-util-remove'
|
||||
declare module 'hast-util-to-string'
|
||||
declare module 'html-minifer'
|
||||
declare module 'mini-html-webpack-plugin'
|
||||
declare module 'happypack'
|
||||
declare module 'common-tags'
|
||||
declare module 'remark-parse'
|
||||
declare module 'remark-slug'
|
||||
declare module 'remark-parse-yaml'
|
||||
declare module 'remark-frontmatter'
|
||||
declare module 'remark-parse/lib/block-elements.json'
|
||||
declare module 'rehype-slug'
|
||||
declare module 'rehype-autolink-headings'
|
||||
declare module 'to-vfile'
|
||||
declare module 'art-template'
|
||||
declare module 'friendly-errors-webpack-plugin'
|
||||
declare module 'webpack-manifest-plugin'
|
||||
declare module 'uglifyjs-webpack-plugin'
|
||||
declare module 'terser-webpack-plugin'
|
||||
declare module 'lodash.get'
|
||||
declare module 'signale'
|
||||
declare module 'webpackbar'
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import * as path from 'path'
|
||||
import * as fs from 'fs-extra'
|
||||
import { compile } from 'art-template'
|
||||
|
||||
import { format } from './format'
|
||||
import { format } from 'docz-utils'
|
||||
|
||||
export const touch = (file: string, raw: string) =>
|
||||
new Promise(async (resolve, reject) => {
|
||||
|
||||
@@ -29,12 +29,9 @@ export const loadConfig = (args: Config): Config => {
|
||||
modifyBabelRc: (babelrc: BabelRC) => babelrc,
|
||||
}
|
||||
|
||||
let config
|
||||
if (args.config) {
|
||||
config = loadFrom<Config>(path.resolve(args.config), defaultConfig)
|
||||
} else {
|
||||
config = load<Config>('docz', defaultConfig)
|
||||
}
|
||||
const config = args.config
|
||||
? loadFrom<Config>(path.resolve(args.config), defaultConfig)
|
||||
: load<Config>('docz', defaultConfig)
|
||||
|
||||
const reduce = Plugin.reduceFromPlugins<Config>(config.plugins)
|
||||
return omit<Config>(toOmit, reduce('setConfig', { ...config, paths }))
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
"codemirror": "^5.40.0",
|
||||
"copy-text-to-clipboard": "^1.0.4",
|
||||
"docz": "^0.11.2",
|
||||
"emotion": "^9.2.8",
|
||||
"emotion-theming": "^9.2.6",
|
||||
"emotion": "^9.2.9",
|
||||
"emotion-theming": "^9.2.9",
|
||||
"facepaint": "^1.2.1",
|
||||
"hotkeys-js": "^3.3.7",
|
||||
"lodash.flattendepth": "^4.7.0",
|
||||
@@ -35,15 +35,15 @@
|
||||
"polished": "^2.0.3",
|
||||
"pretty": "^2.0.0",
|
||||
"prop-types": "15.6.2",
|
||||
"re-resizable": "^4.8.1",
|
||||
"react": "^16.5.0",
|
||||
"re-resizable": "^4.9.0",
|
||||
"react": "^16.5.2",
|
||||
"react-codemirror2": "^5.1.0",
|
||||
"react-dom": "^16.5.0",
|
||||
"react-emotion": "^9.2.8",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-emotion": "^9.2.9",
|
||||
"react-feather": "^1.1.3",
|
||||
"react-lightweight-tooltip": "^1.0.0",
|
||||
"react-live": "^1.11.0",
|
||||
"react-perfect-scrollbar": "^1.2.0",
|
||||
"react-perfect-scrollbar": "^1.2.1",
|
||||
"react-powerplug": "^1.0.0-rc.1",
|
||||
"react-sizes": "^1.0.4",
|
||||
"webfontloader": "^1.6.28"
|
||||
@@ -53,21 +53,21 @@
|
||||
"react-dom": "^16.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.0.0",
|
||||
"@babel/core": "7.1.0",
|
||||
"@types/lodash.flattendepth": "^4.7.4",
|
||||
"@types/lodash.get": "^4.4.4",
|
||||
"@types/react": "^16.4.7",
|
||||
"@types/react": "^16.4.14",
|
||||
"@types/react-dom": "^16.0.6",
|
||||
"babel-loader": "^8.0.2",
|
||||
"babel-plugin-emotion": "^9.2.8",
|
||||
"babel-plugin-emotion": "^9.2.9",
|
||||
"css-loader": "^1.0.0",
|
||||
"cross-env": "^5.2.0",
|
||||
"filemanager-webpack-plugin": "^2.0.4",
|
||||
"filemanager-webpack-plugin": "^2.0.5",
|
||||
"style-loader": "^0.23.0",
|
||||
"ts-loader": "^4.5.0",
|
||||
"uglifyjs-webpack-plugin": "^1.3.0",
|
||||
"webpack": "^4.17.2",
|
||||
"webpack-bundle-analyzer": "^2.13.1",
|
||||
"terser-webpack-plugin": "^1.1.0",
|
||||
"ts-loader": "^5.1.1",
|
||||
"webpack": "^4.19.1",
|
||||
"webpack-bundle-analyzer": "^3.0.2",
|
||||
"webpack-cli": "^3.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@ import * as React from 'react'
|
||||
|
||||
export const CodeSandboxLogo = (props: any) => (
|
||||
<svg {...props} viewBox="0 0 512 512">
|
||||
<path d="M69.2898098,165.083974 L69.2898098,276.649443 L152.161311,324.692718 L152.161311,412.603224 L241.327633,463.829131 L241.327633,264.06328 L69.2898098,165.083974 Z M89.0172642,137.098529 L260.121958,235.540974 L427.640018,138.456525 L339.210941,87.2017661 L262.258901,131.853758 L179.736828,84.2839889 L89.0172642,137.098529 Z M272.206216,463.739666 L370.845646,406.905256 L370.845646,322.809124 L444.244039,280.276172 L444.244039,167.397587 L272.206216,266.116045 L272.206216,463.739666 Z M255.633239,512 L34,384.729507 L34,128.977638 L255.644267,0 L477.328236,128.432852 L477.328236,384.321468 L255.633239,512 Z" fill="currentColor" />
|
||||
<path
|
||||
d="M69.2898098,165.083974 L69.2898098,276.649443 L152.161311,324.692718 L152.161311,412.603224 L241.327633,463.829131 L241.327633,264.06328 L69.2898098,165.083974 Z M89.0172642,137.098529 L260.121958,235.540974 L427.640018,138.456525 L339.210941,87.2017661 L262.258901,131.853758 L179.736828,84.2839889 L89.0172642,137.098529 Z M272.206216,463.739666 L370.845646,406.905256 L370.845646,322.809124 L444.244039,280.276172 L444.244039,167.397587 L272.206216,266.116045 L272.206216,463.739666 Z M255.633239,512 L34,384.729507 L34,128.977638 L255.644267,0 L477.328236,128.432852 L477.328236,384.321468 L255.633239,512 Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const UglifyJs = require('uglifyjs-webpack-plugin')
|
||||
const TerserPlugin = require('terser-webpack-plugin')
|
||||
const FileManagerPlugin = require('filemanager-webpack-plugin')
|
||||
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
|
||||
|
||||
@@ -51,11 +51,8 @@ const externals = deps
|
||||
.concat(externalList)
|
||||
.filter(dep => internals.indexOf(dep) === -1)
|
||||
|
||||
const uglify = new UglifyJs({
|
||||
parallel: true,
|
||||
cache: true,
|
||||
sourceMap: true,
|
||||
uglifyOptions: {
|
||||
const minify = new TerserPlugin({
|
||||
terserOptions: {
|
||||
parse: {
|
||||
ecma: 8,
|
||||
},
|
||||
@@ -73,6 +70,9 @@ const uglify = new UglifyJs({
|
||||
ascii_only: true,
|
||||
},
|
||||
},
|
||||
parallel: true,
|
||||
cache: true,
|
||||
sourceMap: true,
|
||||
})
|
||||
|
||||
const plugins = [
|
||||
@@ -132,7 +132,7 @@ module.exports = {
|
||||
namedModules: true,
|
||||
...(IS_PROD && {
|
||||
minimize: true,
|
||||
minimizer: [uglify],
|
||||
minimizer: [minify],
|
||||
}),
|
||||
},
|
||||
performance: {
|
||||
|
||||
53
packages/docz-utils/package.json
Normal file
53
packages/docz-utils/package.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "docz-utils",
|
||||
"version": "0.11.2",
|
||||
"description": "Some methods used and utilities used on docz",
|
||||
"license": "MIT",
|
||||
"main": "lib/index.js",
|
||||
"module": "lib/index.m.js",
|
||||
"typings": "lib/index.d.ts",
|
||||
"source": [
|
||||
"src/index.ts",
|
||||
"src/ast.ts",
|
||||
"src/mdast.ts",
|
||||
"src/codesandbox.ts",
|
||||
"src/format.ts",
|
||||
"src/imports.ts",
|
||||
"src/jsx.ts"
|
||||
],
|
||||
"files": [
|
||||
"lib/",
|
||||
"package.json",
|
||||
"README.md"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "libundler watch --dest lib --ts -e all",
|
||||
"build": "libundler build --dest lib --ts -e all --c",
|
||||
"fix": "run-s fix:*",
|
||||
"fix:prettier": "prettier \"src/**/*.{ts,tsx}\" --write",
|
||||
"fix:tslint": "tslint --fix --project .",
|
||||
"tslint": "tslint --project ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/generator": "^7.0.0",
|
||||
"@babel/parser": "^7.1.0",
|
||||
"@babel/traverse": "^7.1.0",
|
||||
"codesandboxer-fs": "^0.3.1",
|
||||
"fs-extra": "^7.0.0",
|
||||
"humanize-string": "^1.0.2",
|
||||
"jsx-ast-utils": "^2.0.1",
|
||||
"lodash.get": "^4.4.2",
|
||||
"prettier": "^1.14.3",
|
||||
"remark-frontmatter": "^1.2.1",
|
||||
"remark-parse": "^5.0.0",
|
||||
"remark-parse-yaml": "^0.0.1",
|
||||
"remark-slug": "^5.1.0",
|
||||
"signale": "^1.3.0",
|
||||
"strip-indent": "^2.0.0",
|
||||
"to-vfile": "^5.0.1",
|
||||
"unified": "^7.0.0",
|
||||
"unist-util-find": "^1.0.1",
|
||||
"unist-util-is": "^2.1.2",
|
||||
"unist-util-visit": "^1.4.0"
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,19 @@ import * as parser from '@babel/parser'
|
||||
import traverse from '@babel/traverse'
|
||||
|
||||
type Condition = (path: any) => boolean
|
||||
type Predicate = (path: any) => any
|
||||
|
||||
export const codeFromNode = (condition: Condition) => (code: string) => {
|
||||
export const valueFromTraverse = (
|
||||
condition: Condition,
|
||||
predicate: Predicate = p => p
|
||||
) => (code: string) => {
|
||||
let value = ''
|
||||
const ast = parser.parse(code, { plugins: ['jsx'] })
|
||||
|
||||
traverse(ast, {
|
||||
enter(path: any): void {
|
||||
if (condition(path)) {
|
||||
value = code.slice(path.node.start, path.node.end)
|
||||
value = predicate(path)
|
||||
path.stop()
|
||||
return
|
||||
}
|
||||
@@ -19,3 +23,6 @@ export const codeFromNode = (condition: Condition) => (code: string) => {
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
export const codeFromNode = (condition: Condition) => (code: string) =>
|
||||
valueFromTraverse(condition, p => code.slice(p.node.start, p.node.end))(code)
|
||||
@@ -1,5 +1,5 @@
|
||||
import { assembleFiles } from 'codesandboxer-fs'
|
||||
import * as path from 'path'
|
||||
import { assembleFiles } from 'codesandboxer-fs'
|
||||
|
||||
const wrapCode = (code: string): string => {
|
||||
return `import React from 'react';
|
||||
@@ -24,7 +24,7 @@ export default () => (
|
||||
)`
|
||||
}
|
||||
|
||||
export function getCodeSandboxFiles(
|
||||
function getSandboxFiles(
|
||||
code: string,
|
||||
imports: string[],
|
||||
cwd: string
|
||||
@@ -37,3 +37,20 @@ export function getCodeSandboxFiles(
|
||||
contents: rawCode,
|
||||
})
|
||||
}
|
||||
|
||||
export const getSandboxImportInfo = async (
|
||||
child: any,
|
||||
imports: string[],
|
||||
cwd: string
|
||||
) => {
|
||||
let info: string | undefined
|
||||
|
||||
try {
|
||||
const { parameters } = await getSandboxFiles(child, imports, cwd)
|
||||
info = parameters
|
||||
} catch (e) {
|
||||
console.error('Could not create Open in CodeSandbox', e)
|
||||
}
|
||||
|
||||
return info
|
||||
}
|
||||
39
packages/docz-utils/src/imports.ts
Normal file
39
packages/docz-utils/src/imports.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import * as parser from '@babel/parser'
|
||||
import * as generator from '@babel/generator'
|
||||
import traverse from '@babel/traverse'
|
||||
import get from 'lodash.get'
|
||||
|
||||
const fromSpecifiers = (specifiers: any = []) =>
|
||||
Array.isArray(specifiers) && specifiers.length > 0
|
||||
? specifiers.map(specifier => get(specifier, 'local.name'))
|
||||
: []
|
||||
|
||||
const traverseOnImports = (fn: (path: any) => any[]) => (node: any) => {
|
||||
try {
|
||||
const ast = parser.parse(node.value, { sourceType: 'module' })
|
||||
let populated: any[] = []
|
||||
|
||||
traverse(ast, {
|
||||
enter(path: any): void {
|
||||
if (path.isImportDeclaration()) {
|
||||
if (get(path, 'node.source.value') !== 'docz') {
|
||||
populated = populated.concat(fn(path))
|
||||
}
|
||||
return
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return populated
|
||||
} catch (err) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
export const getFullImports = traverseOnImports((path: any) => [
|
||||
get(generator.default(path.node), 'code'),
|
||||
])
|
||||
|
||||
export const getImportsVariables = traverseOnImports((path: any) =>
|
||||
fromSpecifiers(path.node.specifiers)
|
||||
)
|
||||
8
packages/docz-utils/src/index.ts
Normal file
8
packages/docz-utils/src/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import * as ast from './ast'
|
||||
import * as mdast from './mdast'
|
||||
import * as jsx from './jsx'
|
||||
import * as imports from './imports'
|
||||
import * as codesandbox from './codesandbox'
|
||||
import { format } from './format'
|
||||
|
||||
export { ast, mdast, format, imports, jsx, codesandbox }
|
||||
28
packages/docz-utils/src/jsx.ts
Normal file
28
packages/docz-utils/src/jsx.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import * as jsxUtils from 'jsx-ast-utils'
|
||||
import strip from 'strip-indent'
|
||||
|
||||
import { valueFromTraverse, codeFromNode } from './ast'
|
||||
|
||||
export const propFromElement = (prop: string) =>
|
||||
valueFromTraverse(
|
||||
p => p.isJSXOpeningElement(),
|
||||
p => jsxUtils.getPropValue(jsxUtils.getProp(p.node.attributes, prop))
|
||||
)
|
||||
|
||||
export const removeTags = (code: string) => {
|
||||
const open = codeFromNode(p => p.isJSXOpeningElement())
|
||||
const close = codeFromNode(p => p.isJSXClosingElement())
|
||||
|
||||
return code.replace(open(code), '').replace(close(code), '')
|
||||
}
|
||||
|
||||
export const sanitizeCode = (code: string) =>
|
||||
strip(code)
|
||||
.trim()
|
||||
.replace(/'/g, `\\'`)
|
||||
.replace(/`/g, '\\`')
|
||||
|
||||
export const componentName = (value: any) => {
|
||||
const match = value.match(/^\<\\?(\w+)/)
|
||||
return match && match[1]
|
||||
}
|
||||
@@ -4,6 +4,9 @@ import remark from 'remark-parse'
|
||||
import matter from 'remark-frontmatter'
|
||||
import slug from 'remark-slug'
|
||||
import parseFrontmatter from 'remark-parse-yaml'
|
||||
import find from 'unist-util-find'
|
||||
import is from 'unist-util-is'
|
||||
import visit from 'unist-util-visit'
|
||||
import humanize from 'humanize-string'
|
||||
import get from 'lodash.get'
|
||||
|
||||
@@ -18,7 +21,7 @@ export const parseMdx = (file: string): Promise<string> => {
|
||||
return parser.run(parser.parse(raw))
|
||||
}
|
||||
|
||||
export const valueFromHeading = (node: any): string => {
|
||||
const valueFromHeading = (node: any): string => {
|
||||
const children = get(node, 'children')
|
||||
const slug = get(node, 'data.id')
|
||||
|
||||
@@ -31,3 +34,35 @@ export const valueFromHeading = (node: any): string => {
|
||||
|
||||
return humanize(slug)
|
||||
}
|
||||
|
||||
export interface Heading {
|
||||
depth: number
|
||||
slug: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export const headingsFromAst = (ast: any): Heading[] => {
|
||||
const headings: Heading[] = []
|
||||
|
||||
visit(ast, 'heading', (node: any) => {
|
||||
const slug = get(node, 'data.id')
|
||||
const depth = get(node, 'depth')
|
||||
|
||||
headings.push({
|
||||
depth,
|
||||
slug,
|
||||
value: valueFromHeading(node),
|
||||
})
|
||||
})
|
||||
|
||||
return headings
|
||||
}
|
||||
|
||||
export interface ParsedData {
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
export const getParsedData = (ast: any): ParsedData => {
|
||||
const node = find(ast, (node: any) => is('yaml', node))
|
||||
return get(node, `data.parsedValue`) || {}
|
||||
}
|
||||
18
packages/docz-utils/src/types.d.ts
vendored
Normal file
18
packages/docz-utils/src/types.d.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
declare module 'deepmerge'
|
||||
declare module 'to-vfile'
|
||||
declare module 'unified'
|
||||
declare module 'remark-parse'
|
||||
declare module 'remark-frontmatter'
|
||||
declare module 'remark-slug'
|
||||
declare module 'remark-parse-yaml'
|
||||
declare module 'humanize-string'
|
||||
declare module 'signale'
|
||||
declare module '@babel/parser'
|
||||
declare module '@babel/traverse'
|
||||
declare module '@babel/generator'
|
||||
declare module 'jsx-ast-utils'
|
||||
declare module 'strip-indent'
|
||||
declare module 'unist-util-visit'
|
||||
declare module 'unist-util-is'
|
||||
declare module 'unist-util-find'
|
||||
declare module 'codesandboxer-fs'
|
||||
12
packages/docz-utils/tsconfig.json
Normal file
12
packages/docz-utils/tsconfig.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"declaration": true,
|
||||
"types": ["node"],
|
||||
"typeRoots": ["node_modules/@types"]
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules/**"]
|
||||
}
|
||||
3
packages/docz-utils/tslint.json
Normal file
3
packages/docz-utils/tslint.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../../tslint.json"
|
||||
}
|
||||
@@ -34,17 +34,17 @@
|
||||
"deepmerge": "^2.1.1",
|
||||
"docz-core": "^0.11.2",
|
||||
"docz-theme-default": "^0.11.2",
|
||||
"lodash": "^4.17.10",
|
||||
"lodash": "^4.17.11",
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^16.5.0",
|
||||
"react": "^16.5.2",
|
||||
"react-copy-write": "^0.8.0",
|
||||
"react-dom": "^16.5.0",
|
||||
"react-dom": "^16.5.2",
|
||||
"react-imported-component": "^4.6.2",
|
||||
"react-router": "^4.3.1",
|
||||
"react-router-dom": "^4.3.1",
|
||||
"react-router-hash-link": "^1.2.0",
|
||||
"ulid": "^2.3.0",
|
||||
"yargs": "^12.0.1"
|
||||
"yargs": "^12.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.2.0",
|
||||
@@ -53,9 +53,9 @@
|
||||
"devDependencies": {
|
||||
"@types/deepmerge": "^2.1.0",
|
||||
"@types/lodash": "^4.14.116",
|
||||
"@types/react": "^16.4.7",
|
||||
"@types/react": "^16.4.14",
|
||||
"@types/react-copy-write": "^0.7.1",
|
||||
"@types/react-dom": "^16.0.6",
|
||||
"@types/react-router-dom": "^4.3.0"
|
||||
"@types/react-router-dom": "^4.3.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"deepmerge": "^2.1.1",
|
||||
"esm": "^3.0.82",
|
||||
"esm": "^3.0.84",
|
||||
"find-up": "^3.0.0",
|
||||
"fs-extra": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/find-up": "^2.1.1",
|
||||
"@types/node": "^10.9.4"
|
||||
"@types/node": "^10.10.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,20 +22,13 @@
|
||||
"tslint": "tslint --project ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/generator": "^7.0.0",
|
||||
"@babel/parser": "^7.0.0",
|
||||
"@babel/traverse": "^7.0.0",
|
||||
"codesandboxer-fs": "^0.3.1",
|
||||
"docz-utils": "^0.11.2",
|
||||
"hast-util-to-string": "^1.0.1",
|
||||
"jsx-ast-utils": "^2.0.1",
|
||||
"lodash.flatten": "^4.4.0",
|
||||
"lodash.get": "^4.4.2",
|
||||
"prettier": "^1.14.2",
|
||||
"signale": "^1.2.1",
|
||||
"strip-indent": "^2.0.0",
|
||||
"unist-util-is": "^2.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash.flatten": "^4.4.4",
|
||||
"@types/lodash.get": "^4.4.4"
|
||||
"@types/lodash.flatten": "^4.4.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import * as prettier from 'prettier'
|
||||
import logger from 'signale'
|
||||
|
||||
export const format = (code: string): Promise<string> =>
|
||||
new Promise((resolve, reject) => {
|
||||
try {
|
||||
const result = prettier.format(code, {
|
||||
parser: 'babylon',
|
||||
semi: false,
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
})
|
||||
|
||||
resolve(result)
|
||||
} catch (err) {
|
||||
logger.fatal(err)
|
||||
resolve(err)
|
||||
}
|
||||
})
|
||||
@@ -1,60 +0,0 @@
|
||||
import * as parser from '@babel/parser'
|
||||
import traverse from '@babel/traverse'
|
||||
import * as generator from '@babel/generator'
|
||||
import get from 'lodash.get'
|
||||
|
||||
const fromSpecifiers = (specifiers: any = []) =>
|
||||
Array.isArray(specifiers) && specifiers.length > 0
|
||||
? specifiers.map(specifier => get(specifier, 'local.name'))
|
||||
: []
|
||||
|
||||
export const scopesFromEntry = (node: any) => {
|
||||
try {
|
||||
const ast = parser.parse(node.value, { sourceType: 'module' })
|
||||
const scopes: any[] = []
|
||||
|
||||
traverse(ast, {
|
||||
enter(path: any): void {
|
||||
if (path.isImportDeclaration()) {
|
||||
const sourceValue = get(path, 'node.source.value')
|
||||
|
||||
if (sourceValue !== 'docz') {
|
||||
scopes.push(...fromSpecifiers(path.node.specifiers))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return scopes
|
||||
} catch (err) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
export const importsFromEntry = (node: any) => {
|
||||
try {
|
||||
const ast = parser.parse(node.value, { sourceType: 'module' })
|
||||
const imports: any[] = []
|
||||
|
||||
traverse(ast, {
|
||||
enter(path: any): void {
|
||||
if (path.isImportDeclaration()) {
|
||||
const sourceValue = get(path, 'node.source.value')
|
||||
|
||||
if (sourceValue !== 'docz') {
|
||||
const { code } = generator.default(path.node)
|
||||
imports.push(code)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return imports
|
||||
} catch (err) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
@@ -1,77 +1,54 @@
|
||||
import is from 'unist-util-is'
|
||||
import nodeToString from 'hast-util-to-string'
|
||||
import strip from 'strip-indent'
|
||||
import flatten from 'lodash.flatten'
|
||||
import * as path from 'path'
|
||||
|
||||
import { codeFromNode } from './code-from-node'
|
||||
import { importsFromEntry, scopesFromEntry } from './imports-from-entry'
|
||||
import { format } from './format'
|
||||
import { getCodeSandboxFiles } from './codesandbox-files'
|
||||
|
||||
const componentName = (value: any) => {
|
||||
const match = value.match(/^\<\\?(\w+)/)
|
||||
return match && match[1]
|
||||
}
|
||||
import is from 'unist-util-is'
|
||||
import flatten from 'lodash.flatten'
|
||||
import nodeToString from 'hast-util-to-string'
|
||||
import { jsx, imports as imps } from 'docz-utils'
|
||||
import { format } from 'docz-utils/lib/format'
|
||||
import { getSandboxImportInfo } from 'docz-utils/lib/codesandbox'
|
||||
|
||||
const isPlayground = (name: string) => name === 'Playground'
|
||||
|
||||
const isOpenTag = (p: any) =>
|
||||
p.isJSXOpeningElement() && isPlayground(p.node.name.name)
|
||||
|
||||
const isClosetag = (p: any) =>
|
||||
p.isJSXClosingElement() && isPlayground(p.node.name.name)
|
||||
|
||||
const removePlayground = (code: string) => {
|
||||
const open = codeFromNode(isOpenTag)
|
||||
const close = codeFromNode(isClosetag)
|
||||
|
||||
return code.replace(open(code), '').replace(close(code), '')
|
||||
}
|
||||
|
||||
const sanitizeCode = (code: string) =>
|
||||
strip(code)
|
||||
.trim()
|
||||
.replace(/'/g, `\\'`)
|
||||
.replace(/`/g, '\\`')
|
||||
|
||||
const addCodeProp = (
|
||||
const addPropsOnPlayground = async (
|
||||
node: any,
|
||||
idx: number,
|
||||
scopes: string[],
|
||||
imports: string[],
|
||||
cwd: string
|
||||
) => async (node: any, idx: number) => {
|
||||
const name = componentName(node.value)
|
||||
) => {
|
||||
const name = jsx.componentName(node.value)
|
||||
const tagOpen = new RegExp(`^\\<${name}`)
|
||||
|
||||
if (isPlayground(name)) {
|
||||
const formatted = await format(nodeToString(node))
|
||||
const code = formatted.slice(1, Infinity)
|
||||
const scope = `{props,${scopes.join(',')}}`
|
||||
const child = sanitizeCode(removePlayground(code))
|
||||
|
||||
let codeSandboxImportInfo: string | undefined
|
||||
try {
|
||||
const { parameters } = await getCodeSandboxFiles(child, imports, cwd)
|
||||
codeSandboxImportInfo = parameters
|
||||
} catch (e) {
|
||||
console.error('Could not create Open in CodeSandbox', e)
|
||||
}
|
||||
const child = jsx.sanitizeCode(jsx.removeTags(code))
|
||||
const codesandBoxInfo = await getSandboxImportInfo(child, imports, cwd)
|
||||
|
||||
node.value = node.value.replace(
|
||||
tagOpen,
|
||||
`<${name} __position={${idx}} __codesandbox={\`${codeSandboxImportInfo}\`} __code={\`${child}\`} __scope={${scope}}`
|
||||
`<${name} __position={${idx}} __codesandbox={\`${codesandBoxInfo}\`} __code={\`${child}\`} __scope={${scope}}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default () => (tree: any, fileInfo: any) => {
|
||||
const addComponentsProps = (
|
||||
scopes: string[],
|
||||
imports: string[],
|
||||
cwd: string
|
||||
) => async (node: any, idx: number) => {
|
||||
await addPropsOnPlayground(node, idx, scopes, imports, cwd)
|
||||
}
|
||||
|
||||
export default (root: string) => () => (tree: any, fileInfo: any) => {
|
||||
const importNodes = tree.children.filter((node: any) => is('import', node))
|
||||
const imports: string[] = flatten(importNodes.map(importsFromEntry))
|
||||
const scopes: string[] = flatten(importNodes.map(scopesFromEntry))
|
||||
const imports: string[] = flatten(importNodes.map(imps.getFullImports))
|
||||
const scopes: string[] = flatten(importNodes.map(imps.getImportsVariables))
|
||||
const fileCwd = path.relative(root, path.dirname(fileInfo.history[0]))
|
||||
|
||||
const nodes = tree.children
|
||||
.filter((node: any) => is('jsx', node))
|
||||
.map(addCodeProp(scopes, imports, path.dirname(fileInfo.history[0])))
|
||||
.map(addComponentsProps(scopes, imports, fileCwd))
|
||||
|
||||
return Promise.all(nodes).then(() => tree)
|
||||
}
|
||||
|
||||
8
packages/rehype-docz/src/types.d.ts
vendored
8
packages/rehype-docz/src/types.d.ts
vendored
@@ -1,8 +1,2 @@
|
||||
declare module 'unist-util-is'
|
||||
declare module 'hast-util-to-string'
|
||||
declare module 'strip-indent'
|
||||
declare module 'signale'
|
||||
declare module '@babel/parser'
|
||||
declare module '@babel/traverse'
|
||||
declare module '@babel/generator'
|
||||
declare module 'codesandboxer-fs'
|
||||
declare module 'unist-util-is'
|
||||
|
||||
Reference in New Issue
Block a user