From f89b017e5d528b68698c00540a629a5bd0cf262d Mon Sep 17 00:00:00 2001 From: zce Date: Sun, 12 Nov 2023 22:20:03 +0800 Subject: [PATCH] feat: plugin feature --- .github/renovate.json | 4 ++++ .github/workflows/main.yml | 2 -- .vscode/extensions.json | 10 ---------- .vscode/settings.json | 12 ++---------- package.json | 2 +- readme.md | 4 ++++ src/config.ts | 26 +++++++++++++++----------- src/index.ts | 2 +- src/loader.ts | 31 +++++++++++++++++++++++++++++++ tsconfig.json | 1 + types.d.ts | 1 + 11 files changed, 60 insertions(+), 35 deletions(-) create mode 100644 .github/renovate.json delete mode 100644 .vscode/extensions.json create mode 100644 types.d.ts diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..47ca42a --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["github>zce/renovate-config"] +} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1e0f35b..895d340 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,7 +1,5 @@ name: CI - on: push - jobs: publish: if: startsWith(github.ref, 'refs/tags') diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 977cb68..0000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "recommendations": [ - // Linting / Formatting - "esbenp.prettier-vscode", - "usernamehw.errorlens", - - // Showing todo comments - "gruntfuggly.todo-tree" - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json index a9d7df9..56a6819 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,22 +1,14 @@ { "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, - "editor.quickSuggestions": { - "strings": true - }, "explorer.fileNesting.enabled": true, "explorer.fileNesting.expand": false, "explorer.fileNesting.patterns": { "package.json": "package-lock.json, yarn.lock, pnpm-lock.yaml", - "readme.md": "license, changelog.md" + "readme.md": "license" }, - // exclude files that are not frequently modified or built. "files.exclude": { "node_modules": true }, - "javascript.preferences.quoteStyle": "single", - "javascript.updateImportsOnFileMove.enabled": "never", - "typescript.preferences.quoteStyle": "single", - "typescript.tsdk": "node_modules/typescript/lib", - "typescript.updateImportsOnFileMove.enabled": "never" + "typescript.tsdk": "node_modules/typescript/lib" } diff --git a/package.json b/package.json index 85cef71..b8ee530 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "dist" ], "scripts": { - "build": "tsup", + "build": "tsc && tsup", "format": "prettier --write ." }, "tsup": { diff --git a/readme.md b/readme.md index e2702e1..8b2d8fa 100644 --- a/readme.md +++ b/readme.md @@ -10,6 +10,10 @@ [![Dependency Status][dependency-img]][dependency-url] [![Code Style][style-img]][style-url] +## TODOs + +- [ ] nextjs plugin + ## Installation ```shell diff --git a/src/config.ts b/src/config.ts index 0f55c6a..e41369a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -2,15 +2,14 @@ import { bundleRequire } from 'bundle-require' import JoyCon from 'joycon' import { name } from '../package.json' -import { addLoader } from './loader' +import { addLoader, addPlugin } from './loader' import { init } from './static' -import type { Loader } from './loader' +import type { Loader, Plugin } from './loader' import type { Collections } from './types' import type { ZodType } from 'zod' type Schema = { - name: string pattern: string single?: boolean fields: ZodType @@ -29,6 +28,7 @@ type Config = { } schemas: { [name: string]: Schema } loaders?: Loader[] + plugins?: Plugin[] callback: (collections: Collections) => void | Promise } @@ -40,17 +40,17 @@ type Options = { const joycon = new JoyCon() +joycon.addLoader({ + test: /\.(js|cjs|mjs|ts)$/, + load: async filepath => { + const { mod: config } = await bundleRequire({ filepath }) + return config.default || config + } +}) + export const resolveConfig = async (options: Options = {}): Promise => { const configPaths = [options.filename, name + '.config.js', name + '.config.ts'].filter(Boolean) as string[] - joycon.addLoader({ - test: /\.(js|cjs|mjs|ts)$/, - load: async filepath => { - const { mod: config } = await bundleRequire({ filepath }) - return config.default || config - } - }) - const { data: config, path } = await joycon.load(configPaths) options.verbose && console.log(`using config '${path}'`) @@ -61,6 +61,10 @@ export const resolveConfig = async (options: Options = {}): Promise => { config.loaders.forEach((loader: Loader) => addLoader(loader)) } + if (config.plugins != null) { + config.plugins.forEach((plugin: Plugin) => addPlugin(plugin)) + } + init(config.output.static, config.output.base) return config diff --git a/src/index.ts b/src/index.ts index ffa17bb..84bb9ff 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ export { z, shared } from './shared' export { defineConfig } from './config' -export { addLoader, removeLoader } from './loader' +export { addLoader, removeLoader, addPlugin, removePlugin } from './loader' export { build } from './build' export { image } from './image' diff --git a/src/loader.ts b/src/loader.ts index 73d1b58..f6f592f 100644 --- a/src/loader.ts +++ b/src/loader.ts @@ -18,8 +18,24 @@ export type Loader = { load: (file: VFile) => Promise } +type MdastPlugin = { + name: string + type: 'mdast' + apply: (mdast: ReturnType) => void | Promise +} + +type HastPlugin = { + name: string + type: 'hast' + apply: (hast: ReturnType) => void | Promise +} + +export type Plugin = MdastPlugin | HastPlugin + const loaders: Loader[] = [] +const plugins: Plugin[] = [] + export const addLoader = (loader: Loader) => { loaders.unshift(loader) } @@ -28,6 +44,14 @@ export const removeLoader = (name: string) => { const loader = loaders.find(loader => loader.name === name) loader && loaders.splice(loaders.indexOf(loader), 1) } +export const addPlugin = (plugin: Plugin) => { + plugins.unshift(plugin) +} + +export const removePlugin = (name: string) => { + const plugin = plugins.find(plugin => plugin.name === name) + plugin && plugins.splice(plugins.indexOf(plugin), 1) +} export const load = (file: VFile) => { const loader = loaders.find(loader => loader.test.test(file.path)) @@ -118,10 +142,17 @@ addLoader({ ) // #endregion + // apply mdast plugins + await Promise.all(plugins.map(async p => p.type === 'mdast' && (await p.apply(mdast)))) + // generate markdown data.raw = toMarkdown(mdast, { extensions: [gfmToMarkdown()] }) // parse to hast const hast = raw(toHast(mdast, { allowDangerousHtml: true })) + + // apply hast plugins + await Promise.all(plugins.map(async p => p.type === 'hast' && (await p.apply(hast)))) + // console.log((await import('unist-util-inspect')).inspect(hast)) const lines: string[] = [] visit(hast, 'text', node => { diff --git a/tsconfig.json b/tsconfig.json index 8d992fd..17e22ad 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,6 +4,7 @@ "module": "es2022", "moduleResolution": "bundler", "esModuleInterop": true, + "noEmit": true, "strict": true } } diff --git a/types.d.ts b/types.d.ts new file mode 100644 index 0000000..3247981 --- /dev/null +++ b/types.d.ts @@ -0,0 +1 @@ +declare module 'load-tsconfig'