Skip to content

Commit

Permalink
Svelte: Generate docgen (#392)
Browse files Browse the repository at this point in the history
  • Loading branch information
j3rem1e authored May 31, 2022
1 parent e9da98e commit fef5a12
Show file tree
Hide file tree
Showing 4 changed files with 214 additions and 5 deletions.
1 change: 1 addition & 0 deletions packages/builder-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"magic-string": "^0.26.1",
"react-docgen": "^6.0.0-alpha.0",
"slash": "^3.0.0",
"sveltedoc-parser": "^4.2.1",
"vite-plugin-mdx": "^3.5.6"
},
"devDependencies": {
Expand Down
97 changes: 97 additions & 0 deletions packages/builder-vite/plugins/svelte-docgen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import type { Plugin } from 'vite';
import MagicString from 'magic-string';
import path from 'path';
import fs from 'fs';
import svelteDoc from 'sveltedoc-parser';
import type { SvelteParserOptions } from 'sveltedoc-parser';
import { logger } from '@storybook/node-logger';
import { preprocess } from 'svelte/compiler';

// Most of the code here should probably be exported by @storybook/svelte and reused here.
// See: https://github.com/storybookjs/storybook/blob/next/app/svelte/src/server/svelte-docgen-loader.ts

// From https://github.com/sveltejs/svelte/blob/8db3e8d0297e052556f0b6dde310ef6e197b8d18/src/compiler/compile/utils/get_name_from_filename.ts
// Copied because it is not exported from the compiler
function getNameFromFilename(filename: string) {
if (!filename) return null;

const parts = filename.split(/[/\\]/).map(encodeURI);

if (parts.length > 1) {
const index_match = parts[parts.length - 1].match(/^index(\.\w+)/);
if (index_match) {
parts.pop();
parts[parts.length - 1] += index_match[1];
}
}

const base = parts
.pop()
?.replace(/%/g, 'u')
.replace(/\.[^.]+$/, '')
.replace(/[^a-zA-Z_$0-9]+/g, '_')
.replace(/^_/, '')
.replace(/_$/, '')
.replace(/^(\d)/, '_$1');

if (!base) {
throw new Error(`Could not derive component name from file ${filename}`);
}

return base[0].toUpperCase() + base.slice(1);
}

export function svelteDocgen(svelteOptions: Record<string, any>): Plugin {
const cwd = process.cwd();
const { preprocess: preprocessOptions, logDocgen = false } = svelteOptions;

return {
name: 'svelte-docgen',
async transform(src: string, id: string) {
if (/\.(svelte)$/.test(id)) {
const resource = path.relative(cwd, id);

let docOptions;
if (preprocessOptions) {
const src = fs.readFileSync(resource).toString();

const { code: fileContent } = await preprocess(src, preprocessOptions, { filename: resource });

docOptions = {
fileContent,
};
} else {
docOptions = { filename: resource };
}

// set SvelteDoc options
const options: SvelteParserOptions = {
...docOptions,
version: 3,
};

const s = new MagicString(src);

try {
const componentDoc = await svelteDoc.parse(options);
// get filename for source content
const file = path.basename(resource);

componentDoc.name = path.basename(file);

const componentName = getNameFromFilename(resource);
s.append(`;${componentName}.__docgen = ${JSON.stringify(componentDoc)}`);
} catch (error: any) {
if (logDocgen) {
logger.error(error);
}
}

return {
code: s.toString(),
map: s.generateMap(),
};
}
},
};
}
3 changes: 3 additions & 0 deletions packages/builder-vite/vite-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ export async function pluginConfig(options: ExtendedOptions, _type: PluginConfig
throw err;
}
}

const { svelteDocgen } = await import('./plugins/svelte-docgen');
plugins.push(svelteDocgen(svelteOptions));
}

if (framework === 'react') {
Expand Down
118 changes: 113 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1762,6 +1762,23 @@ __metadata:
languageName: node
linkType: hard

"@eslint/eslintrc@npm:^1.0.5":
version: 1.3.0
resolution: "@eslint/eslintrc@npm:1.3.0"
dependencies:
ajv: ^6.12.4
debug: ^4.3.2
espree: ^9.3.2
globals: ^13.15.0
ignore: ^5.2.0
import-fresh: ^3.2.1
js-yaml: ^4.1.0
minimatch: ^3.1.2
strip-json-comments: ^3.1.1
checksum: a1e734ad31a8b5328dce9f479f185fd4fc83dd7f06c538e1fa457fd8226b89602a55cc6458cd52b29573b01cdfaf42331be8cfc1fec732570086b591f4ed6515
languageName: node
linkType: hard

"@eslint/eslintrc@npm:^1.2.2":
version: 1.2.2
resolution: "@eslint/eslintrc@npm:1.2.2"
Expand Down Expand Up @@ -2902,6 +2919,7 @@ __metadata:
magic-string: ^0.26.1
react-docgen: ^6.0.0-alpha.0
slash: ^3.0.0
sveltedoc-parser: ^4.2.1
vite-plugin-mdx: ^3.5.6
vue-docgen-api: ^4.40.0
peerDependencies:
Expand Down Expand Up @@ -5106,7 +5124,7 @@ __metadata:
languageName: node
linkType: hard

"acorn-jsx@npm:^5.2.0, acorn-jsx@npm:^5.3.1":
"acorn-jsx@npm:^5.2.0, acorn-jsx@npm:^5.3.1, acorn-jsx@npm:^5.3.2":
version: 5.3.2
resolution: "acorn-jsx@npm:5.3.2"
peerDependencies:
Expand Down Expand Up @@ -5158,7 +5176,7 @@ __metadata:
languageName: node
linkType: hard

"acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.5.0, acorn@npm:^8.7.0":
"acorn@npm:^8.2.4, acorn@npm:^8.4.1, acorn@npm:^8.5.0, acorn@npm:^8.6.0, acorn@npm:^8.7.0, acorn@npm:^8.7.1":
version: 8.7.1
resolution: "acorn@npm:8.7.1"
bin:
Expand Down Expand Up @@ -8744,7 +8762,7 @@ __metadata:
languageName: node
linkType: hard

"eslint-scope@npm:^7.1.1":
"eslint-scope@npm:^7.1.0, eslint-scope@npm:^7.1.1":
version: 7.1.1
resolution: "eslint-scope@npm:7.1.1"
dependencies:
Expand Down Expand Up @@ -8788,7 +8806,7 @@ __metadata:
languageName: node
linkType: hard

"eslint-visitor-keys@npm:^3.0.0, eslint-visitor-keys@npm:^3.3.0":
"eslint-visitor-keys@npm:^3.0.0, eslint-visitor-keys@npm:^3.1.0, eslint-visitor-keys@npm:^3.3.0":
version: 3.3.0
resolution: "eslint-visitor-keys@npm:3.3.0"
checksum: d59e68a7c5a6d0146526b0eec16ce87fbf97fe46b8281e0d41384224375c4e52f5ffb9e16d48f4ea50785cde93f766b0c898e31ab89978d88b0e1720fbfb7808
Expand Down Expand Up @@ -8841,6 +8859,54 @@ __metadata:
languageName: node
linkType: hard

"eslint@npm:8.4.1":
version: 8.4.1
resolution: "eslint@npm:8.4.1"
dependencies:
"@eslint/eslintrc": ^1.0.5
"@humanwhocodes/config-array": ^0.9.2
ajv: ^6.10.0
chalk: ^4.0.0
cross-spawn: ^7.0.2
debug: ^4.3.2
doctrine: ^3.0.0
enquirer: ^2.3.5
escape-string-regexp: ^4.0.0
eslint-scope: ^7.1.0
eslint-utils: ^3.0.0
eslint-visitor-keys: ^3.1.0
espree: ^9.2.0
esquery: ^1.4.0
esutils: ^2.0.2
fast-deep-equal: ^3.1.3
file-entry-cache: ^6.0.1
functional-red-black-tree: ^1.0.1
glob-parent: ^6.0.1
globals: ^13.6.0
ignore: ^4.0.6
import-fresh: ^3.0.0
imurmurhash: ^0.1.4
is-glob: ^4.0.0
js-yaml: ^4.1.0
json-stable-stringify-without-jsonify: ^1.0.1
levn: ^0.4.1
lodash.merge: ^4.6.2
minimatch: ^3.0.4
natural-compare: ^1.4.0
optionator: ^0.9.1
progress: ^2.0.0
regexpp: ^3.2.0
semver: ^7.2.1
strip-ansi: ^6.0.1
strip-json-comments: ^3.1.0
text-table: ^0.2.0
v8-compile-cache: ^2.0.3
bin:
eslint: bin/eslint.js
checksum: d962cd7cd0f68ddc2412f47154b8992ad3af987cf47fa6e60e51a2b7d32a91f934388f7d29e2c45b16b7ac69f0d220d0a483189ec6ba43a8a480110c34f158f9
languageName: node
linkType: hard

"eslint@npm:^8.6.0":
version: 8.14.0
resolution: "eslint@npm:8.14.0"
Expand Down Expand Up @@ -8897,6 +8963,17 @@ __metadata:
languageName: node
linkType: hard

"espree@npm:9.2.0":
version: 9.2.0
resolution: "espree@npm:9.2.0"
dependencies:
acorn: ^8.6.0
acorn-jsx: ^5.3.1
eslint-visitor-keys: ^3.1.0
checksum: ae533a058036e3efeeac43a0ee39c74ab347e2a73bbe2946fba33cc0d84aca657e675bc317ed9afd95338f79d5d5a862afec2f717d2539ae13fa9f1638371761
languageName: node
linkType: hard

"espree@npm:^7.2.0":
version: 7.3.1
resolution: "espree@npm:7.3.1"
Expand All @@ -8908,6 +8985,17 @@ __metadata:
languageName: node
linkType: hard

"espree@npm:^9.2.0, espree@npm:^9.3.2":
version: 9.3.2
resolution: "espree@npm:9.3.2"
dependencies:
acorn: ^8.7.1
acorn-jsx: ^5.3.2
eslint-visitor-keys: ^3.3.0
checksum: 9a790d6779847051e87f70d720a0f6981899a722419e80c92ab6dee01e1ab83b8ce52d11b4dc96c2c490182efb5a4c138b8b0d569205bfe1cd4629e658e58c30
languageName: node
linkType: hard

"espree@npm:^9.3.1":
version: 9.3.1
resolution: "espree@npm:9.3.1"
Expand Down Expand Up @@ -10235,6 +10323,15 @@ __metadata:
languageName: node
linkType: hard

"globals@npm:^13.15.0":
version: 13.15.0
resolution: "globals@npm:13.15.0"
dependencies:
type-fest: ^0.20.2
checksum: 383ade0873b2ab29ce6d143466c203ed960491575bc97406395e5c8434026fb02472ab2dfff5bc16689b8460269b18fda1047975295cd0183904385c51258bae
languageName: node
linkType: hard

"globals@npm:^13.6.0, globals@npm:^13.9.0":
version: 13.13.0
resolution: "globals@npm:13.13.0"
Expand Down Expand Up @@ -13428,7 +13525,7 @@ __metadata:
languageName: node
linkType: hard

"minimatch@npm:^3.0.2, minimatch@npm:^3.0.4":
"minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.1.2":
version: 3.1.2
resolution: "minimatch@npm:3.1.2"
dependencies:
Expand Down Expand Up @@ -17422,6 +17519,17 @@ __metadata:
languageName: node
linkType: hard

"sveltedoc-parser@npm:^4.2.1":
version: 4.3.1
resolution: "sveltedoc-parser@npm:4.3.1"
dependencies:
eslint: 8.4.1
espree: 9.2.0
htmlparser2-svelte: 4.1.0
checksum: c0260161c80d1c5ec52808e98f82def379746020c4ffad6e462fec3cd299a3435430eb55a8fe4265884975575bd2aa74f9eda11617864e8aa5a4ca585b57dc51
languageName: node
linkType: hard

"symbol-tree@npm:^3.2.4":
version: 3.2.4
resolution: "symbol-tree@npm:3.2.4"
Expand Down

0 comments on commit fef5a12

Please sign in to comment.