Repository: Kocal/jsdoc-vuejs Branch: master Commit: e73bd4f74bfd Files: 59 Total size: 93.3 KB Directory structure: gitextract_1cmywy0n/ ├── .eslintrc.json ├── .github/ │ ├── FUNDING.yml │ └── workflows/ │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .releaserc ├── LICENSE ├── README.md ├── UPGRADE.md ├── __tests__/ │ ├── core/ │ │ ├── __fixtures__/ │ │ │ ├── Component.vue │ │ │ └── methods/ │ │ │ ├── Component/ │ │ │ │ └── Component.js │ │ │ ├── Component.vue │ │ │ ├── ComponentWithExportDefaultInTemplate.vue │ │ │ ├── ComponentWithSpaces.vue │ │ │ └── ScriptBeforeTemplate.vue │ │ ├── __snapshots__/ │ │ │ └── vueScriptExtractor.js.snap │ │ ├── getTemplatePath.test.js │ │ ├── renderer.test.js │ │ ├── seekExportDefaultLine.js │ │ └── vueScriptExtractor.js │ └── stubs/ │ └── jsdoc/ │ └── lib/ │ └── jsdoc/ │ └── util/ │ └── templateHelper.js ├── config.js ├── cypress/ │ ├── fixtures/ │ │ └── example.json │ ├── integration/ │ │ └── templates/ │ │ ├── default.spec.js │ │ ├── docstrap.spec.js │ │ ├── minami.spec.js │ │ └── tui.spec.js │ ├── plugins/ │ │ └── index.js │ └── support/ │ ├── commands.js │ └── index.js ├── cypress.json ├── example/ │ ├── .jsdoc-docstrap.js │ ├── .jsdoc-minami.js │ ├── .jsdoc-tui.js │ ├── .jsdoc.js │ ├── README.md │ ├── package.json │ └── src/ │ ├── Counter.vue │ ├── better-components/ │ │ └── BetterCounter.vue │ └── js/ │ ├── CounterJS.js │ ├── NotVueComponent.js │ └── NotVueComponent2.js ├── index.js ├── jest.config.js ├── lib/ │ ├── core/ │ │ ├── getTemplatePath.js │ │ ├── issers.js │ │ ├── renderer.js │ │ ├── seekExportDefaultLine.js │ │ └── vueScriptExtractor.js │ ├── tags/ │ │ ├── vue-computed.js │ │ ├── vue-data.js │ │ ├── vue-event.js │ │ └── vue-prop.js │ └── templates/ │ ├── default.ejs │ ├── docstrap.ejs │ ├── minami.ejs │ ├── tui.ejs │ └── utils/ │ └── renderType.js └── package.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .eslintrc.json ================================================ { "extends": [ "airbnb-base" ], "env": { "es6": true, "node": true, "jest": true, "cypress/globals": true }, "plugins": [ "cypress" ], "settings": { "import/core-modules": [ "jsdoc/env" ] }, "rules": { "no-param-reassign": ["error", { "props": true, "ignorePropertyModificationsFor": [ "doclet", // _isVueFile, ... "e" // for e.doclet ] }], "no-underscore-dangle": ["error", { "allow": [ "_isVueDoc", "_vueProps", "_vueData", "_vueComputed", "_vueEvent" ] }] } } ================================================ FILE: .github/FUNDING.yml ================================================ github: Kocal custom: paypal.me/HAlliaume ================================================ FILE: .github/workflows/ci.yml ================================================ name: Node CI on: pull_request: branches: - '*' jobs: ci: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest] node-version: [10.x, 12.x, 14.x] include: - os: windows-latest node: 12.x steps: - name: Set git to use LF run: | git config --global core.autocrlf false git config --global core.eol lf if: matrix.os == 'windows-latest' - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - name: Get yarn cache directory id: yarn-cache run: echo "::set-output name=dir::$(yarn cache dir)" - name: Restore yarn cache (if available) uses: actions/cache@v1 with: path: ${{ steps.yarn-cache.outputs.dir }} key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} restore-keys: | ${{ runner.os }}-yarn- - run: yarn install --frozen-lockfile - run: | cd example yarn install --frozen-lockfile yarn docs yarn docs:docstrap yarn docs:minami yarn docs:tui cd .. - run: yarn lint - run: yarn test -i && npx codecov ================================================ FILE: .github/workflows/release.yml ================================================ name: Release on: push: branches: - master jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Install Node.js uses: actions/setup-node@v1 with: node-version: 12.x - run: yarn install --frozen-lockfile - run: yarn semantic-release env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* # Runtime data pids *.pid *.seed *.pid.lock # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage # nyc test coverage .nyc_output # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) .grunt # Bower dependency directory (https://bower.io/) bower_components # node-waf configuration .lock-wscript # Compiled binary addons (http://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules/ jspm_packages/ # Typescript v1 declaration files typings/ # Optional npm cache directory .npm # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history # Output of 'npm pack' *.tgz # Yarn Integrity file .yarn-integrity # dotenv environment variables file .env example/docs* cypress/screenshots/ cypress/videos/ ================================================ FILE: .releaserc ================================================ { "extends": "@kocal/semantic-release-preset" } ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 Hugo Alliaume Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ JSDoc for VueJS =============== [![npm version](https://badge.fury.io/js/jsdoc-vuejs.svg)](https://badge.fury.io/js/jsdoc-vuejs) [![Build Status (Travis)](https://travis-ci.org/Kocal/jsdoc-vuejs.svg?branch=master)](https://travis-ci.org/Kocal/jsdoc-vuejs) [![Build Status (AppVeyor)](https://ci.appveyor.com/api/projects/status/a36pui6w1qhqq582?svg=true)](https://ci.appveyor.com/project/Kocal/jsdoc-vuejs) [![codecov](https://codecov.io/gh/Kocal/jsdoc-vuejs/branch/master/graph/badge.svg)](https://codecov.io/gh/Kocal/jsdoc-vuejs) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/850b7601f2bf4e8787a6aadbafa8afef)](https://www.codacy.com/app/kocal/jsdoc-vuejs?utm_source=github.com&utm_medium=referral&utm_content=Kocal/jsdoc-vuejs&utm_campaign=Badge_Grade) A JSDoc plugin for listing props, data, computed data, and methods from `.vue` files. :warning: This branch is for Vue 3. If you still use Vue 2, please see [`3.x` branch](https://github.com/Kocal/jsdoc-vuejs/tree/3.x). --- ## Requirements - Node 10+ - Vue 3 ## Installation ```bash $ npm install --save-dev jsdoc jsdoc-vuejs ``` You also need to install `@vue/compiler-sfc` that match your Vue version: ```bash $ npm install --save-dev @vue/compiler-sfc ``` ## Usage Your should update your JSDoc configuration to enable JSDoc-VueJS: ```json { "plugins": [ "node_modules/jsdoc-vuejs" ], "source": { "includePattern": "\\.(vue|js)$" } } ``` Update your .vue files with one of the following tags: - `@vue-prop` - `@vue-data` - `@vue-computed` - `@vue-event` All of those tags work the same way than [`@param` tag](http://usejsdoc.org/tags-param.html). ```vue ``` ## Supported templates The rendering engine has been rewritten in v2, it can supports every JSDoc templates that exists. Actually, it supports 4 templates: - Default - [Docstrap](https://github.com/docstrap/docstrap) - [Minami](https://github.com/nijikokun/minami) - [Tui](https://github.com/nhnent/tui.jsdoc-template) If you use a template that is not supported, it will use the default one as a fallback. Feel free to open an issue/pull request if your template is not supported!
Default ![](./screenshots/templates/default.png)
Docstrap ![](./screenshots/templates/docstrap.png)
Minami ![](./screenshots/templates/minami.png)
Tui ![](./screenshots/templates/tui.png)
## Testing ### Install Dependencies ```bash $ git clone https://github.com/Kocal/jsdoc-vuejs $ cd jsdoc-vuejs $ yarn install # For testing the example docs $ cd example $ yarn install ``` #### Generate documentations ```bash $ cd example # Generate docs for every renderer $ yarn docs:all # or one by one $ yarn docs # default jsdoc template $ yarn docs:docstrap $ yarn docs:minami $ yarn docs:tui ``` ### Unit ```bash $ yarn test ``` ### E2E Before running integration tests with [Cypress](https://cypress.io), you should generate documentation with all renderers: ```bash $ cd example $ yarn docs:all ``` And then run Cypress: ```bash $ cd .. $ yarn cypress run ``` ## License MIT. ================================================ FILE: UPGRADE.md ================================================ ## Upgrade from 1.x to 2.x ### Configuration You MUST remove `jsdoc-vuejs` configuration key inside JSDoc config file, because it is not used anymore. **Before:** ```json { "plugins": [ "node_modules/jsdoc-vuejs" ], "source": { "includePattern": "\\.(vue|js)$" }, "jsdoc-vuejs": { "followImports": true // enable/disable require/import function } } ``` **After:** ```json { "plugins": [ "node_modules/jsdoc-vuejs" ], "source": { "includePattern": "\\.(vue|js)$" } } ``` ### Usage You SHOULD NOT use `@vue` tag anymore. Instead, you should use `@vue-prop`, `@vue-data`, and `@vue-computed` like this: ```vue ``` ================================================ FILE: __tests__/core/__fixtures__/Component.vue ================================================ ================================================ FILE: __tests__/core/__fixtures__/methods/Component/Component.js ================================================ /** * @vue-prop {String} test - test description * @vue-data {String} [foo=bar] - Foo description */ export default ({ name: 'component', props: { test: { type: String, }, }, data() { return { foo: 'bar', }; }, methods: {}, computed: {}, }); ================================================ FILE: __tests__/core/__fixtures__/methods/Component.vue ================================================ ================================================ FILE: __tests__/core/__fixtures__/methods/ComponentWithExportDefaultInTemplate.vue ================================================ ================================================ FILE: __tests__/core/__fixtures__/methods/ComponentWithSpaces.vue ================================================ ================================================ FILE: __tests__/core/__fixtures__/methods/ScriptBeforeTemplate.vue ================================================ ================================================ FILE: __tests__/core/__snapshots__/vueScriptExtractor.js.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`core.extractVueScript extract script 1`] = ` " /** * @vue-data {String} [foo=bar] Foo description */ export default { name: 'Component', data() { return { foo: 'bar' } } } " `; ================================================ FILE: __tests__/core/getTemplatePath.test.js ================================================ /* eslint-disable no-console */ const { normalize } = require('path'); const getTemplatePath = require('../../lib/core/getTemplatePath'); describe('guessTemplatePath', () => { test('guess default', () => { expect(getTemplatePath().endsWith(normalize('lib/templates/default.ejs'))).toBeTruthy(); expect(getTemplatePath('default').endsWith(normalize('lib/templates/default.ejs'))).toBeTruthy(); }); test('guess docstrap', () => { const templatePath = getTemplatePath('./node_modules/ink-docstrap/template'); expect(templatePath.endsWith(normalize('lib/templates/docstrap.ejs'))).toBeTruthy(); }); test('guess minami', () => { const templatePath = getTemplatePath('node_modules/minami'); expect(templatePath.endsWith(normalize('lib/templates/minami.ejs'))).toBeTruthy(); }); test('guess tui', () => { const templatePath = getTemplatePath('node_modules/tui-jsdoc-template'); expect(templatePath.endsWith(normalize('lib/templates/tui.ejs'))).toBeTruthy(); }); test('guess unsupported', () => { console.warn = jest.fn(); expect(getTemplatePath('foo-bar').endsWith(normalize('lib/templates/default.ejs'))).toBeTruthy(); expect(console.warn).toHaveBeenCalledWith('The template "foo-bar" is not recognized by jsdoc-vuejs. Using default template as fallback.'); }); }); ================================================ FILE: __tests__/core/renderer.test.js ================================================ const ejs = require('ejs'); const renderer = require('../../lib/core/renderer'); describe('code.renderer', () => { beforeEach(() => { ejs.renderFile = jest.fn(); }); it('should call ejs render method', () => { const cb = () => {}; renderer('my-template', { props: ['props'], data: ['data'], computed: ['computed'], event: ['event'], }, cb); expect(ejs.renderFile).toHaveBeenCalledTimes(1); expect(ejs.renderFile).toHaveBeenCalledWith( 'my-template', { props: ['props'], data: ['data'], computed: ['computed'], event: ['event'], // an helper function, it should be under keys "utils" or "helpers" btw renderType: expect.any(Function), }, cb, ); }); }); ================================================ FILE: __tests__/core/seekExportDefaultLine.js ================================================ const path = require('path'); const fs = require('fs'); const seekExportDefaultLine = require('../../lib/core/seekExportDefaultLine'); const readComponent = (componentPath, cb) => { const filename = path.join(__dirname, `__fixtures__/methods/${componentPath}`); fs.readFile(filename, 'utf8', (err, source) => cb(source)); }; describe('core.seekExportDefaultLine', () => { test('A normal component', (done) => { readComponent('Component.vue', (source) => { expect(seekExportDefaultLine(source)).toBe(9); done(); }); }); test('A normal component with a lot of spaces', (done) => { readComponent('ComponentWithSpaces.vue', (source) => { expect(seekExportDefaultLine(source)).toBe(14); done(); }); }); test('When ================================================ FILE: example/src/better-components/BetterCounter.vue ================================================ ================================================ FILE: example/src/js/CounterJS.js ================================================ import { mapState } from 'vuex'; /** * @module CounterJS * @vue-prop {Number} initialCounter * @vue-prop {Number} [step=1] Step * @vue-data {Number} counter - Current counter's value * @vue-computed {Array.} fooList - A list of foo * @vue-computed {Array.} barList - A list of bar * @vue-computed {String} message A message */ export default { name: 'CounterJS', props: { initialCounter: { type: Number, required: true }, step: { type: Number, default: 1 }, }, data() { return { counter: this.initialCounter, }; }, computed: { ...mapState({ fooList: state => state.$_foo.fooList, barList: state => state.$_foo.barList, }), message() { return `Counter: ${this.counter}`; }, }, methods: { /** * Increment counter. */ increment() { this.counter += this.step; }, /** * Decrement counter. */ decrement() { this.counter -= this.step; }, /** * Show a dialog displaying counter value. * @param {Number} counter - Counter value */ showDialog(counter) { alert(`Counter value is ${counter}.`); }, }, /** * Counter.vue `created` hook. */ created() { console.info('Counter.vue: created()'); }, mounted() { console.info('Counter.vue: mounted()'); }, }; ================================================ FILE: example/src/js/NotVueComponent.js ================================================ import NotVueComponent2 from './NotVueComponent2'; NotVueComponent2.theMethod('123'); /** * @return {Boolean} */ const helloWorld = () => { console.log('Hello world'); return false; }; export { helloWorld, }; ================================================ FILE: example/src/js/NotVueComponent2.js ================================================ /** * @module NotVueComponent2 */ module.exports = { state: { foo: 'bar', }, /** * @param {String} i */ theMethod(i) { console.log(i); }, }; ================================================ FILE: index.js ================================================ const { join } = require('path'); const config = require('./config'); const render = require('./lib/core/renderer'); const extractVueScript = require('./lib/core/vueScriptExtractor'); const seekExportDefaultLine = require('./lib/core/seekExportDefaultLine'); const { isSingleFileComponent, isJSComponent } = require('./lib/core/issers'); const vueDataTag = require('./lib/tags/vue-data'); const vuePropTag = require('./lib/tags/vue-prop'); const vueComputedTag = require('./lib/tags/vue-computed'); const vueEventTag = require('./lib/tags/vue-event'); // Used to compute good line number for Vue methods const exportDefaultLines = {}; const mainDocletLines = {}; exports.handlers = { beforeParse(e) { if (/\.vue$/.test(e.filename)) { exportDefaultLines[e.filename] = seekExportDefaultLine(e.source, e.filename); e.source = extractVueScript(e.filename); } }, newDoclet(e) { const fileIsSingleFileComponent = isSingleFileComponent(e.doclet); const fileIsJSComponent = isJSComponent(e.doclet); if (!fileIsSingleFileComponent && !fileIsJSComponent) { return; } const fullPath = join(e.doclet.meta.path, e.doclet.meta.filename); const componentName = e.doclet.meta.filename.replace(/\.(vue|js)$/, ''); // The main doclet before `export default {}` if (e.doclet.longname === 'module.exports') { e.doclet.kind = 'module'; e.doclet.name = componentName; e.doclet.alias = componentName; e.doclet.longname = `module:${componentName}`; } if ( !/[.~#]/.test(e.doclet.longname) // filter component's properties and member, not the best way but it werks && e.doclet.longname.startsWith('module:') ) { mainDocletLines[fullPath] = e.doclet.meta.lineno; } // It can be the main doclet before `export default {}` // with at least one `@vue-*` tag if (e.doclet._isVueDoc) { const { template } = config['jsdoc-vuejs']; const data = { props: e.doclet._vueProps || [], data: e.doclet._vueData || [], computed: e.doclet._vueComputed || [], event: e.doclet._vueEvent || [], }; render(template, data, (err, str) => { if (err) throw err; e.doclet.description = (e.doclet.description || '') + str; }); // Remove meta for not rendering source for this doclet delete e.doclet.meta; } // Methods and hooks if (e.doclet.kind === 'function' && 'memberof' in e.doclet) { if (e.doclet.memberof.endsWith('.methods')) { e.doclet.scope = 'instance'; e.doclet.memberof = e.doclet.memberof.replace(/\.methods$/, ''); // force method to be displayed if (fileIsSingleFileComponent) { e.doclet.meta.lineno += exportDefaultLines[fullPath] - mainDocletLines[fullPath]; } } else { e.doclet.memberof = null; // don't include Vue hooks } } }, }; exports.defineTags = function defineTags(dictionary) { dictionary.defineTag(vueDataTag.name, vueDataTag.options); dictionary.defineTag(vuePropTag.name, vuePropTag.options); dictionary.defineTag(vueComputedTag.name, vueComputedTag.options); dictionary.defineTag(vueEventTag.name, vueEventTag.options); }; ================================================ FILE: jest.config.js ================================================ module.exports = { bail: true, verbose: !process.env.CI, collectCoverage: !!process.env.CI, collectCoverageFrom: [ 'lib/core/*.js', ], testPathIgnorePatterns: [ '/node_modules/', '/__fixtures__/', '/__tests__/stubs', '/cypress/', ], moduleNameMapper: { 'jsdoc/(.*)': '/__tests__/stubs/jsdoc/$1.js', }, }; ================================================ FILE: lib/core/getTemplatePath.js ================================================ const { resolve } = require('path'); module.exports = function getTemplatePath(template) { // eslint-disable-next-line no-param-reassign template = template || 'default'; const templateFilename = (() => { switch (true) { case template === 'default': return 'default.ejs'; case /ink-docstrap\/template/.test(template): return 'docstrap.ejs'; case /minami/.test(template): return 'minami.ejs'; case /tui-jsdoc-template/.test(template): return 'tui.ejs'; default: // eslint-disable-next-line no-console console.warn(`The template "${template}" is not recognized by jsdoc-vuejs. Using default template as fallback.`); return 'default.ejs'; } })(); const path = resolve(__dirname, '../templates', templateFilename); return resolve(path); }; ================================================ FILE: lib/core/issers.js ================================================ const path = require('path'); const hasVueTagRE = /\s*\*\s*@vue/; // Useful because we use `@vue` tag from first doclet of a .js file // to determine if this file is a Vue Component. /** * @type {Object.} */ const jsComponentsCache = {}; /** * @param {Doclet} doclet */ function isSingleFileComponent(doclet) { return doclet.meta.filename.endsWith('.vue'); } /** * @param {Doclet} doclet */ function isJSComponent(doclet) { const fullPath = path.join(doclet.meta.path, doclet.meta.filename); if (fullPath in jsComponentsCache) { return jsComponentsCache[fullPath]; } const res = doclet.meta.filename.endsWith('.js') && hasVueTagRE.test(doclet.comment || ''); if (res) { jsComponentsCache[fullPath] = true; } return res; } module.exports = { isSingleFileComponent, isJSComponent, }; ================================================ FILE: lib/core/renderer.js ================================================ const ejs = require('ejs'); const renderType = require('../templates/utils/renderType'); module.exports = function render(template, { props, data, computed, event, }, cb) { ejs.renderFile( template, { renderType, props, data, computed, event, }, cb, ); }; ================================================ FILE: lib/core/seekExportDefaultLine.js ================================================ /* eslint-disable no-continue */ module.exports = function seekExportDefaultLine(source, filename) { let inScript = filename ? filename.endsWith('.js') : false; // eslint-disable-next-line no-restricted-syntax for (const [i, line] of source.split(/\r?\n/).entries()) { if (line.trim() === '') { continue; } if (/]*>/.test(line)) { inScript = true; } else if (!inScript && /<\/script>/.test(line)) { inScript = false; } if (inScript && /export\s+default/.test(line)) { return i + 1; // index starts at 0, but file's lines start at 1 } } return 0; }; ================================================ FILE: lib/core/vueScriptExtractor.js ================================================ const fs = require('fs'); const compiler = require('@vue/compiler-sfc'); module.exports = function extractVueScript(filename) { const source = fs.readFileSync(filename, 'utf8'); const parsedComponent = compiler.parse(source); const scriptContent = parsedComponent.descriptor.script ? parsedComponent.descriptor.script.content : ''; return scriptContent; }; ================================================ FILE: lib/tags/vue-computed.js ================================================ exports.name = 'vue-computed'; exports.options = { canHaveType: true, canHaveName: true, onTagged(doclet, tag) { doclet._isVueDoc = true; doclet._vueComputed = doclet._vueComputed || []; doclet._vueComputed.push(tag.value || {}); }, }; ================================================ FILE: lib/tags/vue-data.js ================================================ exports.name = 'vue-data'; exports.options = { canHaveType: true, canHaveName: true, onTagged(doclet, tag) { doclet._isVueDoc = true; doclet._vueData = doclet._vueData || []; doclet._vueData.push(tag.value || {}); }, }; ================================================ FILE: lib/tags/vue-event.js ================================================ exports.name = 'vue-event'; exports.options = { canHaveType: true, // type of event-payload canHaveName: true, // name of emitted event onTagged(doclet, tag) { doclet._isVueDoc = true; doclet._vueEvent = doclet._vueEvent || []; doclet._vueEvent.push(tag.value || {}); }, }; ================================================ FILE: lib/tags/vue-prop.js ================================================ exports.name = 'vue-prop'; exports.options = { canHaveType: true, canHaveName: true, onTagged(doclet, tag) { doclet._isVueDoc = true; doclet._vueProps = doclet._vueProps || []; doclet._vueProps.push(tag.value || {}); }, }; ================================================ FILE: lib/templates/default.ejs ================================================

<%# Prematurely close JSDoc default template tags %> <% if(props.length > 0) { %>

Props

<% props.forEach(function(prop) { %><% }) %>
Name Type Default value Required? Description
<%- prop.name %> <%- renderType(prop.type) %> <%- typeof prop.defaultvalue === 'undefined' ? '-' : `${prop.defaultvalue}` %> <%- prop.optional ? 'No' : 'Yes' %> <%- typeof prop.description === 'undefined' ? '-' : prop.description %>
<% } %> <% if(data.length > 0) { %>

Data

<% data.forEach(function(d) { %><% }) %>
Name Type Default value Description
<%- d.name %> <%- renderType(d.type) %> <%- typeof d.defaultvalue === 'undefined' ? '-' : `${d.defaultvalue}` %> <%- typeof d.description === 'undefined' ? '-' : d.description %>
<% } %> <% if(computed.length > 0) { %>

Computed

<% computed.forEach(function(c) { %><% }) %>
Name Type Description
<%- c.name %> <%- renderType(c.type) %> <%- typeof c.description === 'undefined' ? '-' : c.description %>
<% } %> <% if(event.length > 0) { %>

Events

<% event.forEach(function(c) { %><% }) %>
Name Payload Type Description
<%- c.name %> <%- renderType(c.type) %> <%- typeof c.description === 'undefined' ? '-' : c.description %>
<% } %>

<%# Re-open JSDoc template tags %> ================================================ FILE: lib/templates/docstrap.ejs ================================================

<%# Prematurely close JSDoc default template tags %> <% if(props.length > 0) { %>

Props

<% props.forEach(function(prop) { %><% }) %>
Name Type Default value Required? Description
<%- prop.name %> <%- renderType(prop.type) %> <%- typeof prop.defaultvalue === 'undefined' ? '-' : `${prop.defaultvalue}` %> <%- prop.optional ? 'No' : 'Yes' %> <%- typeof prop.description === 'undefined' ? '-' : prop.description %>
<% } %> <% if(data.length > 0) { %>

Data

<% data.forEach(function(d) { %><% }) %>
Name Type Default value Description
<%- d.name %> <%- renderType(d.type) %> <%- typeof d.defaultvalue === 'undefined' ? '-' : `${d.defaultvalue}` %> <%- typeof d.description === 'undefined' ? '-' : d.description %>
<% } %> <% if(computed.length > 0) { %>

Computed

<% computed.forEach(function(c) { %><% }) %>
Name Type Description
<%- c.name %> <%- renderType(c.type) %> <%- typeof c.description === 'undefined' ? '-' : c.description %>
<% } %> <% if(event.length > 0) { %>

Events

<% event.forEach(function(c) { %><% }) %>
Name Payload Type Description
<%- c.name %> <%- renderType(c.type) %> <%- typeof c.description === 'undefined' ? '-' : c.description %>
<% } %>

<%# Re-open JSDoc template tags %> ================================================ FILE: lib/templates/minami.ejs ================================================

<%# Prematurely close JSDoc default template tags %> <% if(props.length > 0) { %>

Props

<% props.forEach(function(prop) { %><% }) %>
Name Type Default value Required? Description
<%- prop.name %> <%- renderType(prop.type) %> <%- typeof prop.defaultvalue === 'undefined' ? '-' : `${prop.defaultvalue}` %> <%- prop.optional ? 'No' : 'Yes' %> <%- typeof prop.description === 'undefined' ? '-' : prop.description %>
<% } %> <% if(data.length > 0) { %>

Data

<% data.forEach(function(d) { %><% }) %>
Name Type Default value Description
<%- d.name %> <%- renderType(d.type) %> <%- typeof d.defaultvalue === 'undefined' ? '-' : `${d.defaultvalue}` %> <%- typeof d.description === 'undefined' ? '-' : d.description %>
<% } %> <% if(computed.length > 0) { %>

Computed

<% computed.forEach(function(c) { %><% }) %>
Name Type Description
<%- c.name %> <%- renderType(c.type) %> <%- typeof c.description === 'undefined' ? '-' : c.description %>
<% } %> <% if(event.length > 0) { %>

Events

<% event.forEach(function(c) { %><% }) %>
Name Payload Type Description
<%- c.name %> <%- renderType(c.type) %> <%- typeof c.description === 'undefined' ? '-' : c.description %>
<% } %>

<%# Re-open JSDoc template tags %> ================================================ FILE: lib/templates/tui.ejs ================================================

<%# Prematurely close JSDoc default template tags %> <% if(props.length > 0) { %>

Props

<% props.forEach(function(prop) { %><% }) %>
Name Type Default value Required? Description
<%- prop.name %> <%- renderType(prop.type) %> <%- typeof prop.defaultvalue === 'undefined' ? '-' : `${prop.defaultvalue}` %> <%- prop.optional ? 'No' : 'Yes' %> <%- typeof prop.description === 'undefined' ? '-' : prop.description %>
<% } %> <% if(data.length > 0) { %>

Data

<% data.forEach(function(d) { %><% }) %>
Name Type Default value Description
<%- d.name %> <%- renderType(d.type) %> <%- typeof d.defaultvalue === 'undefined' ? '-' : `${d.defaultvalue}` %> <%- typeof d.description === 'undefined' ? '-' : d.description %>
<% } %> <% if(computed.length > 0) { %>

Computed

<% computed.forEach(function(c) { %><% }) %>
Name Type Description
<%- c.name %> <%- renderType(c.type) %> <%- typeof c.description === 'undefined' ? '-' : c.description %>
<% } %> <% if(event.length > 0) { %>

Events

<% event.forEach(function(c) { %><% }) %>
Name Payload Type Description
<%- c.name %> <%- renderType(c.type) %> <%- typeof c.description === 'undefined' ? '-' : c.description %>
<% } %>

<%# Re-open JSDoc template tags %> ================================================ FILE: lib/templates/utils/renderType.js ================================================ const { htmlsafe } = require('jsdoc/lib/jsdoc/util/templateHelper'); module.exports = function renderTypes(type) { return ((type && type.names) || []).map(htmlsafe).join('|'); }; ================================================ FILE: package.json ================================================ { "name": "jsdoc-vuejs", "version": "0.0.0-development", "description": "A JSDoc plugin for documenting vue 3 files.", "main": "index.js", "files": [ "lib", "config.js" ], "scripts": { "test": "jest", "lint": "eslint --ext .js index.js config.js lib __tests__ cypress", "semantic-release": "semantic-release" }, "repository": { "type": "git", "url": "https://github.com/Kocal/jsdoc-vuejs" }, "keywords": [ "jsdoc", "vuejs", "vue component", "vue file", "vue 3" ], "author": "Hugo Alliaume ", "license": "MIT", "bugs": { "url": "https://github.com/Kocal/jsdoc-vuejs/issues" }, "homepage": "https://github.com/Kocal/jsdoc-vuejs#readme", "engines": { "node": "^10.13.0 || >=12.0.0" }, "dependencies": { "ejs": "^3.0.1" }, "peerDependencies": { "jsdoc": ">=3.0.0", "@vue/compiler-sfc": ">= 3.0.0" }, "devDependencies": { "@kocal/semantic-release-preset": "^2.0.6", "@vue/compiler-sfc": "^3.1.4", "cypress": "^4.0.1", "eslint": "^6.2.0", "eslint-config-airbnb-base": "^14.0.0", "eslint-plugin-cypress": "^2.0.1", "eslint-plugin-import": "^2.13.0", "jest": "^24.0.0", "jsdoc": "^3.6.2", "semantic-release": "^17.1.1" } }