@storybook/docs-mdx
Advanced tools
Comparing version 0.0.1-canary.1.e6d40d7.0 to 0.0.1-canary.9a7e7e1.0
@@ -1,25 +0,7 @@ | ||
"use strict"; | ||
import * as t from '@babel/types'; | ||
import toBabel from 'estree-to-babel'; | ||
import * as babelTraverse from '@babel/traverse'; | ||
import { compileSync } from '@mdx-js/mdx'; | ||
import { toEstree } from 'hast-util-to-estree'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.plugin = exports.extractImports = exports.analyze = exports.OF_TITLE = exports.NO_TITLE = void 0; | ||
var t = _interopRequireWildcard(require("@babel/types")); | ||
var _estreeToBabel = _interopRequireDefault(require("estree-to-babel")); | ||
var _traverse = _interopRequireDefault(require("@babel/traverse")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } | ||
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } | ||
const NO_TITLE = '__sb_undefined__'; | ||
exports.NO_TITLE = NO_TITLE; | ||
const OF_TITLE = '__sb_of__:'; | ||
exports.OF_TITLE = OF_TITLE; | ||
const getAttr = (elt, what) => { | ||
@@ -31,3 +13,6 @@ const attr = elt.attributes.find(n => n.name.name === what); | ||
const extractTitle = (root, varToImport) => { | ||
let title; | ||
const result = { | ||
title: undefined, | ||
of: undefined | ||
}; | ||
let contents; | ||
@@ -49,3 +34,3 @@ root.program.body.forEach(child => { | ||
if (name === 'Meta') { | ||
if (title) { | ||
if (result.title) { | ||
throw new Error('Meta can only be declared once'); | ||
@@ -58,3 +43,3 @@ } | ||
if (t.isStringLiteral(titleAttr)) { | ||
title = titleAttr.value; | ||
result.title = titleAttr.value; | ||
} else { | ||
@@ -75,3 +60,3 @@ throw new Error(`Expected string literal title, received ${titleAttr.type}`); | ||
if (importName) { | ||
title = `${OF_TITLE}${importName}`; | ||
result.of = importName; | ||
} else { | ||
@@ -96,12 +81,44 @@ throw new Error(`Unknown identifier ${of.name}`); | ||
if (title) { | ||
return title; | ||
} else { | ||
return NO_TITLE; | ||
return result; | ||
}; | ||
/** | ||
* This is a hack to get around inconsistencies between | ||
* Babel's own weird interop code AND the typescript types (definitelyTyped) | ||
* and the fact that we're using `type: "module"` in this package | ||
* which has some weird behaviors | ||
*/ | ||
const getTraverse = input => { | ||
switch (true) { | ||
case typeof input === 'function': | ||
{ | ||
return input; | ||
} | ||
case typeof input.traverse === 'function': | ||
{ | ||
return input.traverse; | ||
} | ||
case typeof input.default === 'function': | ||
{ | ||
return input.default; | ||
} | ||
case typeof input.default.default === 'function': | ||
{ | ||
return input.default.default; | ||
} | ||
default: | ||
{ | ||
throw new Error(`Unable to get traverse function from ${input}`); | ||
} | ||
} | ||
}; | ||
const extractImports = root => { | ||
export const extractImports = root => { | ||
const varToImport = {}; | ||
(0, _traverse.default)(root, { | ||
getTraverse(babelTraverse)(root, { | ||
ImportDeclaration: { | ||
@@ -129,6 +146,3 @@ enter({ | ||
}; | ||
exports.extractImports = extractImports; | ||
const plugin = store => root => { | ||
export const plugin = store => root => { | ||
const imports = root.children.find(child => child.type === 'mdxjsEsm'); | ||
@@ -138,3 +152,3 @@ let varToImport = {}; | ||
if (imports) { | ||
varToImport = extractImports((0, _estreeToBabel.default)(imports.data.estree)); | ||
varToImport = extractImports(toBabel(imports.data.estree)); | ||
} | ||
@@ -146,20 +160,17 @@ | ||
const babel = (0, _estreeToBabel.default)(estree); | ||
store.title = extractTitle(babel, varToImport); | ||
const babel = toBabel(estree); | ||
const { | ||
title, | ||
of | ||
} = extractTitle(babel, varToImport); | ||
store.title = title; | ||
store.of = of; | ||
store.imports = Array.from(new Set(Object.values(varToImport))); | ||
return root; | ||
}; | ||
exports.plugin = plugin; | ||
const analyze = code => { | ||
const { | ||
compileSync | ||
} = require('@mdx-js/mdx'); | ||
const { | ||
toEstree | ||
} = require('hast-util-to-estree'); | ||
export const analyze = code => { | ||
const store = { | ||
title: undefined, | ||
of: undefined, | ||
imports: undefined, | ||
toEstree | ||
@@ -171,20 +182,11 @@ }; | ||
const { | ||
title | ||
title, | ||
of, | ||
imports = [] | ||
} = store; | ||
if (title === NO_TITLE) { | ||
return { | ||
title: undefined | ||
}; | ||
} else if (title.startsWith(OF_TITLE)) { | ||
return { | ||
of: title.substring(OF_TITLE.length) | ||
}; | ||
} | ||
return { | ||
title | ||
title, | ||
of, | ||
imports | ||
}; | ||
}; | ||
exports.analyze = analyze; | ||
}; |
@@ -1,25 +0,13 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.babelParse = void 0; | ||
var _tsDedent = require("ts-dedent"); | ||
var _analyze = require("./analyze"); | ||
var _parser = require("@babel/parser"); | ||
const babelParse = code => (0, _parser.parse)(code, { | ||
import { dedent } from 'ts-dedent'; | ||
import { analyze, extractImports } from "./analyze.js"; | ||
import { parse } from '@babel/parser'; | ||
export const babelParse = code => parse(code, { | ||
sourceType: 'module' | ||
}); | ||
exports.babelParse = babelParse; | ||
describe('extractImports', () => { | ||
const ast = babelParse((0, _tsDedent.dedent)` | ||
const ast = babelParse(dedent` | ||
import { Meta } from '@storybook/blocks'; | ||
import meta, { Basic } from './Button.stories'; | ||
`); | ||
expect((0, _analyze.extractImports)(ast)).toMatchInlineSnapshot(` | ||
expect(extractImports(ast)).toMatchInlineSnapshot(` | ||
Object { | ||
@@ -35,3 +23,3 @@ "Basic": "./Button.stories", | ||
it('string literal title', () => { | ||
const input = (0, _tsDedent.dedent)` | ||
const input = dedent` | ||
# hello | ||
@@ -41,10 +29,12 @@ | ||
`; | ||
expect((0, _analyze.analyze)(input)).toMatchInlineSnapshot(` | ||
Object { | ||
"title": "foobar", | ||
} | ||
`); | ||
expect(analyze(input)).toMatchInlineSnapshot(` | ||
Object { | ||
"imports": Array [], | ||
"of": undefined, | ||
"title": "foobar", | ||
} | ||
`); | ||
}); | ||
it('template literal title', () => { | ||
const input = (0, _tsDedent.dedent)` | ||
const input = dedent` | ||
# hello | ||
@@ -54,6 +44,6 @@ | ||
`; | ||
expect(() => (0, _analyze.analyze)(input)).toThrowErrorMatchingInlineSnapshot(`"Expected string literal title, received JSXExpressionContainer"`); | ||
expect(() => analyze(input)).toThrowErrorMatchingInlineSnapshot(`"Expected string literal title, received JSXExpressionContainer"`); | ||
}); | ||
it('duplicate titles', () => { | ||
const input = (0, _tsDedent.dedent)` | ||
const input = dedent` | ||
<Meta title="foobar" /> | ||
@@ -63,3 +53,3 @@ | ||
`; | ||
expect(() => (0, _analyze.analyze)(input)).toThrowErrorMatchingInlineSnapshot(`"Meta can only be declared once"`); | ||
expect(() => analyze(input)).toThrowErrorMatchingInlineSnapshot(`"Meta can only be declared once"`); | ||
}); | ||
@@ -69,3 +59,3 @@ }); | ||
it('basic', () => { | ||
const input = (0, _tsDedent.dedent)` | ||
const input = dedent` | ||
import { Meta } from '@storybook/blocks'; | ||
@@ -76,5 +66,10 @@ import meta, { Basic } from './Button.stories'; | ||
`; | ||
expect((0, _analyze.analyze)(input)).toMatchInlineSnapshot(` | ||
expect(analyze(input)).toMatchInlineSnapshot(` | ||
Object { | ||
"imports": Array [ | ||
"@storybook/blocks", | ||
"./Button.stories", | ||
], | ||
"of": "./Button.stories", | ||
"title": undefined, | ||
} | ||
@@ -84,9 +79,9 @@ `); | ||
it('missing variable', () => { | ||
const input = (0, _tsDedent.dedent)` | ||
const input = dedent` | ||
<Meta of={meta} /> | ||
`; | ||
expect(() => (0, _analyze.analyze)(input)).toThrowErrorMatchingInlineSnapshot(`"Unknown identifier meta"`); | ||
expect(() => analyze(input)).toThrowErrorMatchingInlineSnapshot(`"Unknown identifier meta"`); | ||
}); | ||
it('string literal', () => { | ||
const input = (0, _tsDedent.dedent)` | ||
const input = dedent` | ||
import meta, { Basic } from './Button.stories'; | ||
@@ -96,3 +91,3 @@ | ||
`; | ||
expect(() => (0, _analyze.analyze)(input)).toThrowErrorMatchingInlineSnapshot(`"Expected JSX expression, received StringLiteral"`); | ||
expect(() => analyze(input)).toThrowErrorMatchingInlineSnapshot(`"Expected JSX expression, received StringLiteral"`); | ||
}); | ||
@@ -102,7 +97,9 @@ }); | ||
it('no title', () => { | ||
const input = (0, _tsDedent.dedent)` | ||
const input = dedent` | ||
# hello | ||
`; | ||
expect((0, _analyze.analyze)(input)).toMatchInlineSnapshot(` | ||
expect(analyze(input)).toMatchInlineSnapshot(` | ||
Object { | ||
"imports": Array [], | ||
"of": undefined, | ||
"title": undefined, | ||
@@ -113,3 +110,3 @@ } | ||
it('Bad MDX formatting', () => { | ||
const input = (0, _tsDedent.dedent)` | ||
const input = dedent` | ||
import meta, { Basic } from './Button.stories'; | ||
@@ -119,9 +116,13 @@ | ||
`; | ||
expect((0, _analyze.analyze)(input)).toMatchInlineSnapshot(` | ||
Object { | ||
"title": undefined, | ||
} | ||
`); | ||
expect(analyze(input)).toMatchInlineSnapshot(` | ||
Object { | ||
"imports": Array [ | ||
"./Button.stories", | ||
], | ||
"of": undefined, | ||
"title": undefined, | ||
} | ||
`); | ||
}); | ||
}); | ||
}); |
@@ -1,18 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _analyze = require("./analyze"); | ||
Object.keys(_analyze).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _analyze[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _analyze[key]; | ||
} | ||
}); | ||
}); | ||
export * from "./analyze.js"; |
import * as t from '@babel/types'; | ||
export declare const NO_TITLE = "__sb_undefined__"; | ||
export declare const OF_TITLE = "__sb_of__:"; | ||
export declare const extractImports: (root: t.File) => Record<string, string>; | ||
export declare const plugin: (store: any) => (root: any) => any; | ||
export declare const analyze: (code: string) => { | ||
title: any; | ||
of: any; | ||
title?: undefined; | ||
} | { | ||
title: any; | ||
of?: undefined; | ||
imports: any; | ||
}; |
{ | ||
"name": "@storybook/docs-mdx", | ||
"version": "0.0.1-canary.1.e6d40d7.0", | ||
"version": "0.0.1-canary.9a7e7e1.0", | ||
"description": "Storybook Docs MDX analyzer", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/storybookjs/docs2-mdx" | ||
"url": "https://github.com/storybookjs/docs-mdx" | ||
}, | ||
"author": "Michael Shilman <michael@lab80.co>", | ||
"license": "MIT", | ||
"main": "compiler.js", | ||
"module": "dist/esm/index.js", | ||
"type": "module", | ||
"main": "index", | ||
"types": "dist/ts/index.d.ts", | ||
@@ -18,9 +18,8 @@ "files": [ | ||
"*.js", | ||
"*.d.ts" | ||
"*.d.ts", | ||
"index.cjs" | ||
], | ||
"scripts": { | ||
"clean": "rimraf ./dist", | ||
"buildBabel": "concurrently \"yarn buildBabel:cjs\" \"yarn buildBabel:esm\"", | ||
"buildBabel:cjs": "babel ./src -d ./dist/cjs --extensions \".js,.jsx,.ts,.tsx\"", | ||
"buildBabel:esm": "babel ./src -d ./dist/esm --env-name esm --extensions \".js,.jsx,.ts,.tsx\"", | ||
"buildBabel": "babel ./src -d ./dist/esm --env-name dist --extensions \".js,.jsx,.ts,.tsx\"", | ||
"buildTsc": "tsc --declaration --emitDeclarationOnly --outDir ./dist/ts", | ||
@@ -45,5 +44,5 @@ "prebuild": "yarn clean", | ||
"devDependencies": { | ||
"@babel/parser": "^7.12.11", | ||
"@babel/cli": "^7.12.1", | ||
"@babel/core": "^7.12.3", | ||
"@babel/parser": "^7.12.11", | ||
"@babel/preset-env": "^7.12.1", | ||
@@ -58,2 +57,3 @@ "@babel/preset-typescript": "^7.13.0", | ||
"babel-loader": "^8.1.0", | ||
"babel-plugin-add-import-extension": "^1.6.0", | ||
"concurrently": "^7.0.0", | ||
@@ -60,0 +60,0 @@ "husky": ">=6", |
@@ -7,2 +7,10 @@ ## @storybook/docs-mdx | ||
It currently produces: | ||
| name | example | description | | ||
| ------- | ---------------------------------- | --------------------------------------- | | ||
| title | `<Meta title="x">` | A manually specified title | | ||
| of | `<Meta of={buttonMeta}>` | A title specified by an imported object | | ||
| imports | `import * from './Button.stories'` | The list of ESM imports | | ||
## Getting Started | ||
@@ -9,0 +17,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
30
Yes
12624
23
10
279
1