]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
docs: fix slug generation api
authorEduardo San Martin Morote <posva13@gmail.com>
Tue, 10 Jan 2023 22:50:20 +0000 (23:50 +0100)
committerEduardo San Martin Morote <posva@users.noreply.github.com>
Wed, 15 Feb 2023 09:52:57 +0000 (10:52 +0100)
packages/docs-new/.vitepress/config/shared.ts
packages/docs-new/run-typedoc.js [new file with mode: 0644]
packages/docs-new/typedoc-markdown.js [new file with mode: 0644]
packages/docs-new/typedoc.tsconfig.json [new file with mode: 0644]
packages/docs-new/vite-typedoc-plugin.ts [new file with mode: 0644]
packages/docs-new/vite.config.ts [new file with mode: 0644]

index 0a20fd949e0c0b89f748a519574d2e04c32cf074..514837f512ff4d76c0548aa84021f92172b85ab8 100644 (file)
@@ -23,17 +23,11 @@ export const sharedConfig = defineConfig({
       dark: 'dracula-soft',
       light: 'vitesse-light',
     },
+
     attrs: {
       leftDelimiter: '%{',
       rightDelimiter: '}%',
     },
-    // TODO: are these needed for API maybe?
-    // anchor: {
-    //   permalink: renderPermaLink,
-    // },
-    // config: (md) => {
-    //   md.use(MarkDownItCustomAnchor)
-    // },
   },
 
   head: [
diff --git a/packages/docs-new/run-typedoc.js b/packages/docs-new/run-typedoc.js
new file mode 100644 (file)
index 0000000..841fbe0
--- /dev/null
@@ -0,0 +1,15 @@
+const { createTypeDocApp } = require('./typedoc-markdown')
+const path = require('path')
+
+createTypeDocApp({
+  name: 'API Documentation',
+  tsconfig: path.resolve(__dirname, './typedoc.tsconfig.json'),
+  // entryPointStrategy: 'packages',
+  githubPages: false,
+  disableSources: true,
+  entryPoints: [
+    path.resolve(__dirname, '../pinia/src/index.ts'),
+    path.resolve(__dirname, '../testing/src/index.ts'),
+    path.resolve(__dirname, '../nuxt/src/module.ts'),
+  ],
+}).build()
diff --git a/packages/docs-new/typedoc-markdown.js b/packages/docs-new/typedoc-markdown.js
new file mode 100644 (file)
index 0000000..c94b3c7
--- /dev/null
@@ -0,0 +1,154 @@
+const _fs = require('fs')
+const path = require('path')
+const TypeDoc = require('typedoc')
+const { PageEvent } = TypeDoc
+const {
+  prependYAML,
+} = require('typedoc-plugin-markdown/dist/utils/front-matter')
+
+const fs = _fs.promises
+
+const DEFAULT_OPTIONS = {
+  // disableOutputCheck: true,
+  cleanOutputDir: true,
+  excludeInternal: true,
+  readme: 'none',
+  out: path.resolve(__dirname, './api'),
+  entryDocument: 'index.md',
+  hideBreadcrumbs: false,
+  hideInPageTOC: true,
+}
+
+/**
+ *
+ * @param {Partial<import('typedoc').TypeDocOptions>} config
+ */
+exports.createTypeDocApp = function createTypeDocApp(config = {}) {
+  const options = {
+    ...DEFAULT_OPTIONS,
+    ...config,
+  }
+
+  const app = new TypeDoc.Application()
+
+  // If you want TypeDoc to load tsconfig.json / typedoc.json files
+  app.options.addReader(new TypeDoc.TSConfigReader())
+  // app.options.addReader(new TypeDoc.TypeDocReader())
+
+  /** @type {'build' | 'serve'} */
+  let targetMode = 'build'
+
+  const slugify = (s) => s.replaceAll(' ', '-')
+  // encodeURIComponent(String(s).trim().toLowerCase().replace(/\s+/g, '-'))
+
+  app.renderer.on(
+    PageEvent.END,
+    /**
+     *
+     * @param {import('typedoc/dist/lib/output/events').PageEvent} page
+     */
+    (page) => {
+      if (page.url !== 'index.md' && page.contents) {
+        page.contents = prependYAML(page.contents, {
+          sidebar: 'auto',
+          // TODO: figure out a way to point to the source files?
+          editLinks: false,
+          sidebarDepth: 3,
+        })
+      }
+
+      // avoid duplicated id titles
+      if (page.contents) {
+        const lines = page.contents.split('\n')
+        const titleStack = []
+        let currentLevel = 0
+        const TITLE_LEVEL = /^#+/
+        const existingIds = new Map()
+        for (let i = 0; i < lines.length; i++) {
+          const line = lines[i]
+          if (!line.startsWith('#')) continue
+          const level = line.match(TITLE_LEVEL)[0].length
+
+          // remove extra levels
+          if (level <= currentLevel) {
+            titleStack.splice(level - 1)
+          }
+          // add the current title
+          titleStack.push(line.slice(level).trim())
+          currentLevel = level
+
+          const slugifiedTitle = slugify(titleStack.join('-'))
+          let id
+          if (existingIds.has(slugifiedTitle)) {
+            const current = existingIds.get(slugifiedTitle)
+            existingIds.set(slugifiedTitle, current + 1)
+            id = ` %{#${slugifiedTitle}_${current + 1}}%`
+          } else {
+            existingIds.set(slugifiedTitle, 0)
+            id = ` %{#${slugifiedTitle}}%`
+          }
+          const newLine = line + id
+          lines.splice(i, 1, newLine)
+        }
+
+        page.contents = lines.join('\n')
+      }
+    }
+  )
+
+  async function serve() {
+    app.bootstrap(options)
+    app.convertAndWatch(handleProject)
+  }
+
+  async function build() {
+    if (
+      (await exists(options.out)) &&
+      (await fs.stat(options.out)).isDirectory()
+    ) {
+      await fs.rm(options.out, { recursive: true })
+    }
+    app.bootstrap(options)
+    const project = app.convert()
+    return handleProject(project)
+  }
+
+  /**
+   *
+   * @param {import('typedoc').ProjectReflection} project
+   */
+  async function handleProject(project) {
+    if (project) {
+      // Rendered docs
+      try {
+        await app.generateDocs(project, options.out)
+        app.logger.info(`generated at ${options.out}.`)
+      } catch (error) {
+        app.logger.error(error)
+      }
+    } else {
+      app.logger.error('No project')
+    }
+  }
+
+  return {
+    build,
+    serve,
+    /**
+     *
+     * @param {'build' | 'serve'} command
+     */
+    setTargetMode(command) {
+      targetMode = command
+    },
+  }
+}
+
+async function exists(path) {
+  try {
+    await fs.access(path)
+    return true
+  } catch {
+    return false
+  }
+}
diff --git a/packages/docs-new/typedoc.tsconfig.json b/packages/docs-new/typedoc.tsconfig.json
new file mode 100644 (file)
index 0000000..a93dc1c
--- /dev/null
@@ -0,0 +1,46 @@
+{
+  "include": ["../pinia/src/global.d.ts", "../*/src/**/*.ts"],
+  "exclude": [
+    "../test-vue-2",
+    "../pinia/__tests__/test-utils.ts",
+    "../pinia/test-dts",
+    "../*/__tests__/**/*.ts",
+    "../*/src/*.spec.ts",
+    "../nuxt/playground",
+    "../nuxt/src/runtime",
+    "**/*.spec.ts"
+  ],
+  "compilerOptions": {
+    "baseUrl": ".",
+    "rootDir": "..",
+    "outDir": "dist",
+    "sourceMap": false,
+    "noEmit": true,
+    "paths": {
+      "@pinia/*": ["../*/src"],
+      "pinia": ["../pinia/src"]
+    },
+
+    "target": "esnext",
+    "module": "esnext",
+    "moduleResolution": "node",
+    "allowJs": false,
+    "skipLibCheck": true,
+
+    "noUnusedLocals": true,
+    "strictNullChecks": true,
+    "noImplicitAny": true,
+    "noImplicitThis": true,
+    "noImplicitReturns": false,
+    "strict": true,
+    "isolatedModules": true,
+
+    "experimentalDecorators": true,
+    "resolveJsonModule": true,
+    "esModuleInterop": true,
+    "removeComments": false,
+    "jsx": "preserve",
+    "lib": ["esnext", "dom"],
+    "types": ["vitest", "node", "vite/client"]
+  }
+}
diff --git a/packages/docs-new/vite-typedoc-plugin.ts b/packages/docs-new/vite-typedoc-plugin.ts
new file mode 100644 (file)
index 0000000..006b644
--- /dev/null
@@ -0,0 +1,19 @@
+import { Plugin } from 'vite'
+import _fs from 'fs'
+import { TypeDocOptions } from 'typedoc'
+import { createTypeDocApp } from './typedoc-markdown'
+
+export default function TypeDocPlugin(
+  config: Partial<TypeDocOptions> = {}
+): Plugin {
+  const { serve, setTargetMode } = createTypeDocApp(config)
+  setTargetMode('serve')
+
+  return {
+    name: 'typedoc',
+    apply: 'serve',
+    buildStart() {
+      return serve()
+    },
+  }
+}
diff --git a/packages/docs-new/vite.config.ts b/packages/docs-new/vite.config.ts
new file mode 100644 (file)
index 0000000..a084967
--- /dev/null
@@ -0,0 +1,47 @@
+import { defineConfig, Plugin } from 'vite'
+import _fs from 'fs'
+import path from 'path'
+// import TypeDocPlugin from './vite-typedoc-plugin'
+
+const fs = _fs.promises
+
+export default defineConfig({
+  clearScreen: false,
+  plugins: [
+    ...(process.env.NETLIFY ? [] : [copyPiniaPlugin()]),
+    // TODO: actual plugin that works well
+    // TypeDocPlugin({
+    //   name: 'Pinia',
+    //   entryPoints: [
+    //     path.resolve(__dirname, '../pinia/src/index.ts'),
+    //     path.resolve(__dirname, '../testing/src/index.ts'),
+    //     path.resolve(__dirname, '../nuxt/src/index.ts'),
+    //   ],
+    // }),
+  ],
+  define: {
+    __DEV__: 'true',
+    __BROWSER__: 'true',
+  },
+  optimizeDeps: {
+    exclude: ['vue-demi', '@vueuse/shared', '@vueuse/core', 'pinia'],
+  },
+})
+
+function copyPiniaPlugin(): Plugin {
+  return {
+    name: 'copy-pinia',
+    async generateBundle() {
+      const filePath = path.resolve(__dirname, '../pinia/dist/pinia.mjs')
+
+      // throws if file doesn't exist
+      await fs.access(filePath)
+
+      this.emitFile({
+        type: 'asset',
+        fileName: 'pinia.mjs',
+        source: await fs.readFile(filePath, 'utf-8'),
+      })
+    },
+  }
+}