@mintlify/common 1.0.1221 → 1.0.1223
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/colors.d.ts +4 -0
- package/dist/colors.js +6 -1
- package/dist/mdx/getMDXOptions.d.ts +3 -1
- package/dist/mdx/getMDXOptions.js +7 -1
- package/dist/mdx/index.d.ts +1 -0
- package/dist/mdx/index.js +1 -0
- package/dist/mdx/islands/extractPackageIslands.d.ts +5 -0
- package/dist/mdx/islands/extractPackageIslands.js +147 -0
- package/dist/mdx/islands/index.d.ts +5 -0
- package/dist/mdx/islands/index.js +5 -0
- package/dist/mdx/islands/island-bindings.d.ts +40 -0
- package/dist/mdx/islands/island-bindings.js +149 -0
- package/dist/mdx/islands/island-module-builder.d.ts +37 -0
- package/dist/mdx/islands/island-module-builder.js +472 -0
- package/dist/mdx/islands/island-placement.d.ts +10 -0
- package/dist/mdx/islands/island-placement.js +229 -0
- package/dist/mdx/islands/packageImports.d.ts +28 -0
- package/dist/mdx/islands/packageImports.js +155 -0
- package/dist/mdx/islands/remarkPackageIslands.d.ts +23 -0
- package/dist/mdx/islands/remarkPackageIslands.js +177 -0
- package/dist/mdx/islands/sha256.d.ts +1 -0
- package/dist/mdx/islands/sha256.js +71 -0
- package/dist/mdx/islands/static-expressions.d.ts +24 -0
- package/dist/mdx/islands/static-expressions.js +169 -0
- package/dist/mdx/islands/types.d.ts +36 -0
- package/dist/mdx/islands/types.js +1 -0
- package/dist/mdx/plugins/remark/remarkMdxExpandExpressions.js +1 -1
- package/dist/mdx/plugins/remark/remarkMdxInjectSnippets.d.ts +4 -1
- package/dist/mdx/plugins/remark/remarkMdxInjectSnippets.js +68 -17
- package/dist/mdx/plugins/remark/remarkMdxRemoveJs.js +1 -1
- package/dist/mdx/plugins/remark/remarkResolveRelativeLinks.d.ts +1 -0
- package/dist/mdx/plugins/remark/remarkResolveRelativeLinks.js +6 -3
- package/dist/mdx/server-only/getMdx.d.ts +11 -1
- package/dist/mdx/server-only/getMdx.js +66 -31
- package/dist/mdx/server-only/index.d.ts +1 -1
- package/dist/mdx/server-only/index.js +1 -1
- package/dist/mdx/snippets/resolveAllImports.d.ts +3 -1
- package/dist/mdx/snippets/resolveAllImports.js +65 -1
- package/dist/mdx/static-object-keys.d.ts +1 -0
- package/dist/mdx/static-object-keys.js +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/mdx/MdxExtracts.d.ts +6 -0
- package/package.json +3 -3
package/dist/colors.d.ts
CHANGED
|
@@ -52,6 +52,10 @@ export declare const generateDynamicGrayScale: (primaryColor: string) => Tailwin
|
|
|
52
52
|
* "255 0 128", the function will return "255, 0, 128".
|
|
53
53
|
*/
|
|
54
54
|
export declare const convertColorsToRgbWithCommas: (color: string) => string;
|
|
55
|
+
export declare const getDefaultBackgroundColors: (primaryLight?: string) => {
|
|
56
|
+
light: string;
|
|
57
|
+
dark: string;
|
|
58
|
+
};
|
|
55
59
|
export declare function getBackgroundColors(docsConfig?: DocsConfig): {
|
|
56
60
|
light: string;
|
|
57
61
|
dark: string;
|
package/dist/colors.js
CHANGED
|
@@ -98,10 +98,15 @@ export const generateDynamicGrayScale = (primaryColor) => {
|
|
|
98
98
|
export const convertColorsToRgbWithCommas = (color) => {
|
|
99
99
|
return color.split(' ').join(', ');
|
|
100
100
|
};
|
|
101
|
+
const DEFAULT_PRIMARY_LIGHT = '#4ADE80';
|
|
102
|
+
export const getDefaultBackgroundColors = (primaryLight = DEFAULT_PRIMARY_LIGHT) => ({
|
|
103
|
+
light: '#ffffff',
|
|
104
|
+
dark: generateDynamicBackgroundDarkColor(primaryLight, undefined, true),
|
|
105
|
+
});
|
|
101
106
|
export function getBackgroundColors(docsConfig) {
|
|
102
107
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
103
108
|
const primaryColor = (docsConfig === null || docsConfig === void 0 ? void 0 : docsConfig.colors.primary) || '#16A34A';
|
|
104
|
-
const primaryLight = (_a = docsConfig === null || docsConfig === void 0 ? void 0 : docsConfig.colors.light) !== null && _a !== void 0 ? _a :
|
|
109
|
+
const primaryLight = (_a = docsConfig === null || docsConfig === void 0 ? void 0 : docsConfig.colors.light) !== null && _a !== void 0 ? _a : DEFAULT_PRIMARY_LIGHT;
|
|
105
110
|
if ((docsConfig === null || docsConfig === void 0 ? void 0 : docsConfig.theme) === 'linden') {
|
|
106
111
|
docsConfig.background = Object.assign(Object.assign({}, docsConfig.background), { color: {
|
|
107
112
|
light: ((_c = (_b = docsConfig.background) === null || _b === void 0 ? void 0 : _b.color) === null || _c === void 0 ? void 0 : _c.light) ||
|
|
@@ -4,6 +4,7 @@ import { DocsConfig } from '@mintlify/validation';
|
|
|
4
4
|
import type { Root } from 'mdast';
|
|
5
5
|
import type { PluggableList } from 'unified';
|
|
6
6
|
import { MdxExtracts } from '../types/mdx/MdxExtracts.js';
|
|
7
|
+
import { type RemarkPackageIslandsOptions } from './islands/remarkPackageIslands.js';
|
|
7
8
|
import { type MdxJsDetection } from './plugins/remark/remarkMdxRemoveJs.js';
|
|
8
9
|
type MDXOptionsData = {
|
|
9
10
|
snippetTreeMap: Record<string, Root>;
|
|
@@ -13,7 +14,7 @@ type MDXOptionsData = {
|
|
|
13
14
|
tailwindSelectors?: string[];
|
|
14
15
|
path?: string;
|
|
15
16
|
};
|
|
16
|
-
export declare const getMDXOptions: ({ data, remarkPlugins, earlyRemarkPlugins, rehypePlugins, mdxExtracts, allowedComponents, fragmentPlugins, detectJs, }: {
|
|
17
|
+
export declare const getMDXOptions: ({ data, remarkPlugins, earlyRemarkPlugins, rehypePlugins, mdxExtracts, allowedComponents, fragmentPlugins, packageIslands, detectJs, }: {
|
|
17
18
|
data: MDXOptionsData;
|
|
18
19
|
remarkPlugins?: PluggableList;
|
|
19
20
|
earlyRemarkPlugins?: PluggableList;
|
|
@@ -25,6 +26,7 @@ export declare const getMDXOptions: ({ data, remarkPlugins, earlyRemarkPlugins,
|
|
|
25
26
|
remarkPlugins: PluggableList;
|
|
26
27
|
rehypePlugins: PluggableList;
|
|
27
28
|
};
|
|
29
|
+
packageIslands?: Omit<RemarkPackageIslandsOptions, "mdxExtracts">;
|
|
28
30
|
detectJs?: MdxJsDetection;
|
|
29
31
|
}) => SerializeOptions["mdxOptions"];
|
|
30
32
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { remarkPackageIslands, } from './islands/remarkPackageIslands.js';
|
|
1
2
|
import { rehypeCodeBlocks, rehypeDynamicTailwindCss, rehypeKeyboardSymbols, rehypeListItemText, rehypeMdxExtractEndpoint, rehypeMdxExtractExamples, rehypeParamFieldIds, rehypeRawComponents, rehypeTable, rehypeUnicodeIds, rehypeZoomImages, remarkExtractChangelogFilters, remarkExtractTableOfContents, remarkFileTree, remarkFrames, remarkComponentIds, remarkMdxInjectSnippets, remarkMdxStyleStringToObject, remarkMdxRemoveUnusedVariables, remarkRemoveImports, remarkMdxExtractPanel, remarkResolveRelativeLinks, remarkVideo, remarkMdxClientComponentBoundaries, remarkExtractMultiView, remarkPrompt, remarkUnwrapInlineJsx, remarkUnwrapJsxHeadings, remarkMapExplicitAnchors, } from './plugins/index.js';
|
|
2
3
|
import { remarkMdxExpandExpressions, } from './plugins/remark/remarkMdxExpandExpressions.js';
|
|
3
4
|
import { remarkMdxDetectJs } from './plugins/remark/remarkMdxRemoveJs.js';
|
|
@@ -14,7 +15,7 @@ const rehypeExtractors = (mdxExtracts, data) => {
|
|
|
14
15
|
[rehypeMdxExtractEndpoint, data.pageMetadata, data.config, mdxExtracts],
|
|
15
16
|
];
|
|
16
17
|
};
|
|
17
|
-
export const getMDXOptions = ({ data, remarkPlugins = [], earlyRemarkPlugins = [], rehypePlugins = [], mdxExtracts, allowedComponents = [], fragmentPlugins, detectJs, }) => {
|
|
18
|
+
export const getMDXOptions = ({ data, remarkPlugins = [], earlyRemarkPlugins = [], rehypePlugins = [], mdxExtracts, allowedComponents = [], fragmentPlugins, packageIslands, detectJs, }) => {
|
|
18
19
|
// `fragment`: the list is compiling the body of an `<MDX>` inside an expression. Page-level
|
|
19
20
|
// extractors that hoist an element out of the tree (`<Panel>`, `<RequestExample>`,
|
|
20
21
|
// `<ResponseExample>`) are skipped there so the element stays in its branch and renders inline
|
|
@@ -26,6 +27,11 @@ export const getMDXOptions = ({ data, remarkPlugins = [], earlyRemarkPlugins = [
|
|
|
26
27
|
remarkPlugins: [
|
|
27
28
|
// first, so `<Snippet file>` is injected on the page and inside every `<MDX>` fragment
|
|
28
29
|
[remarkMdxInjectSnippets, data.snippetTreeMap],
|
|
30
|
+
...(fragment || !packageIslands
|
|
31
|
+
? []
|
|
32
|
+
: [
|
|
33
|
+
[remarkPackageIslands, Object.assign(Object.assign({}, packageIslands), { mdxExtracts: extracts })],
|
|
34
|
+
]),
|
|
29
35
|
[
|
|
30
36
|
remarkMdxExpandExpressions,
|
|
31
37
|
{
|
package/dist/mdx/index.d.ts
CHANGED
package/dist/mdx/index.js
CHANGED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Parent, Root, RootContent } from 'mdast';
|
|
2
|
+
import type { ExtractPackageIslandsOptions, ExtractPackageIslandsResult } from './types.js';
|
|
3
|
+
export declare const islandIdFor: (module: string) => string;
|
|
4
|
+
export declare const soleParagraphChild: (paragraph: Parent) => RootContent | undefined;
|
|
5
|
+
export declare const extractPackageIslands: (tree: Root, options: ExtractPackageIslandsOptions) => ExtractPackageIslandsResult;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { bindingHead, collectBindings, collectConsts, esmStatements, lineOf, referencesIn, } from './island-bindings.js';
|
|
2
|
+
import { IslandModuleBuilder, MOVE_TO_SNIPPET } from './island-module-builder.js';
|
|
3
|
+
import { blockerWithin, childrenPlacements, isIntrinsic, isListLoose, } from './island-placement.js';
|
|
4
|
+
import { sha256Hex } from './sha256.js';
|
|
5
|
+
const CSS_SPECIFIER = /\.css(?:[?#].*)?$/;
|
|
6
|
+
export const islandIdFor = (module) => `i${sha256Hex(module).slice(0, 16)}`;
|
|
7
|
+
const withPlacement = (module, placement) => `${module.endsWith('\n') ? module : `${module}\n`}// placement ${placement}\n`;
|
|
8
|
+
export const soleParagraphChild = (paragraph) => {
|
|
9
|
+
const meaningful = paragraph.children.filter((child) => child.type !== 'text' || child.value.trim() !== '');
|
|
10
|
+
return meaningful.length === 1 ? meaningful[0] : undefined;
|
|
11
|
+
};
|
|
12
|
+
export const extractPackageIslands = (tree, options) => {
|
|
13
|
+
const statements = esmStatements(tree, options.pagePath);
|
|
14
|
+
const { bindings, undeclared, conflicts, sideEffects, order } = collectBindings(statements, options);
|
|
15
|
+
const islands = new Map();
|
|
16
|
+
const errors = [...conflicts];
|
|
17
|
+
const roots = [];
|
|
18
|
+
const sideEffectErrors = () => {
|
|
19
|
+
if (errors.length > 0 || roots.length > 0)
|
|
20
|
+
return [];
|
|
21
|
+
return [...sideEffects].map(([source, line]) => {
|
|
22
|
+
const message = CSS_SPECIFIER.test(source)
|
|
23
|
+
? `"${source}" is imported on a page without package components, so it never loads. List it in packages.css in docs.json to load it on every page and remove this import, or use a package component on this page.`
|
|
24
|
+
: `"${source}" is imported on a page without package components, so it never runs. Use a package component on this page or remove this import.`;
|
|
25
|
+
return { line, code: 'side-effect-import-without-island', message };
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
if (bindings.size === 0 && undeclared.size === 0) {
|
|
29
|
+
return { islands: [], errors: [...errors, ...sideEffectErrors()], roots };
|
|
30
|
+
}
|
|
31
|
+
const consts = collectConsts(statements, options);
|
|
32
|
+
const wrappers = childrenPlacements(statements);
|
|
33
|
+
const reportReferences = (node, fallbackLine) => {
|
|
34
|
+
var _a;
|
|
35
|
+
for (const reference of referencesIn(node, bindings)) {
|
|
36
|
+
const binding = bindings.get(reference.name);
|
|
37
|
+
const from = binding ? `"${binding.source}"` : 'a package';
|
|
38
|
+
errors.push({
|
|
39
|
+
line: (_a = reference.line) !== null && _a !== void 0 ? _a : fallbackLine,
|
|
40
|
+
message: reference.jsx
|
|
41
|
+
? `<${reference.name}> (from ${from}) is used inside JavaScript. Package components can only be written as JSX directly in MDX. ${MOVE_TO_SNIPPET}`
|
|
42
|
+
: `${reference.name} (from ${from}) is used inside JavaScript. Package components can only be written as JSX directly in MDX. ${MOVE_TO_SNIPPET}`,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
for (const { statement, line } of statements) {
|
|
47
|
+
if (statement.type !== 'ImportDeclaration')
|
|
48
|
+
reportReferences(statement, line);
|
|
49
|
+
}
|
|
50
|
+
const tightItems = new WeakSet();
|
|
51
|
+
const placements = new Map();
|
|
52
|
+
const visitChildren = (parent, blocker, outside = blocker, via) => {
|
|
53
|
+
var _a, _b, _c, _d, _e;
|
|
54
|
+
for (const child of parent.children) {
|
|
55
|
+
if (child.type === 'mdxJsxFlowElement' || child.type === 'mdxJsxTextElement') {
|
|
56
|
+
const head = child.name ? bindingHead(child.name) : undefined;
|
|
57
|
+
const binding = head === undefined ? undefined : bindings.get(head);
|
|
58
|
+
if (child.name && binding) {
|
|
59
|
+
const blocking = parent.type === 'paragraph' && soleParagraphChild(parent) === child ? outside : blocker;
|
|
60
|
+
if (blocking) {
|
|
61
|
+
let message;
|
|
62
|
+
if (blocking === 'paragraph') {
|
|
63
|
+
message = `<${child.name}> is inside a line of text. Package components render as a block, so put <${child.name}> on its own line.`;
|
|
64
|
+
}
|
|
65
|
+
else if (via) {
|
|
66
|
+
message = `<${child.name}> is inside <${via}>, which renders it inside a <${blocking}>. Package components render as a block, so move <${child.name}> out of <${via}>.`;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
message = `<${child.name}> is inside a <${blocking}>. Package components render as a block, so move <${child.name}> out of the <${blocking}>.`;
|
|
70
|
+
}
|
|
71
|
+
errors.push({ line: lineOf(child), message });
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const builder = new IslandModuleBuilder(child.name, options.pagePath, bindings, undeclared, consts, sideEffects, order);
|
|
75
|
+
const element = builder.element(child);
|
|
76
|
+
if (builder.errors.length > 0 || !element) {
|
|
77
|
+
errors.push(...builder.errors);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const base = builder.module(element);
|
|
81
|
+
const baseId = islandIdFor(base);
|
|
82
|
+
const placement = ((_a = placements.get(baseId)) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
83
|
+
placements.set(baseId, placement);
|
|
84
|
+
const module = placement === 1 ? base : withPlacement(base, placement);
|
|
85
|
+
const id = placement === 1 ? baseId : islandIdFor(module);
|
|
86
|
+
if (!islands.has(id)) {
|
|
87
|
+
islands.set(id, {
|
|
88
|
+
id,
|
|
89
|
+
pagePath: options.pagePath,
|
|
90
|
+
kind: binding.kind === 'snippet' ? 'snippet' : 'inline',
|
|
91
|
+
imports: builder.imports(),
|
|
92
|
+
module,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
roots.push({ id, name: child.name, node: child, parent });
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (child.name && head !== undefined && undeclared.has(head)) {
|
|
99
|
+
errors.push({
|
|
100
|
+
line: lineOf(child),
|
|
101
|
+
message: `<${child.name}> is imported from "${undeclared.get(head)}", which isn't listed in package.json dependencies.`,
|
|
102
|
+
});
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
for (const attribute of child.attributes) {
|
|
106
|
+
let estree;
|
|
107
|
+
if (attribute.type === 'mdxJsxExpressionAttribute') {
|
|
108
|
+
estree = (_b = attribute.data) === null || _b === void 0 ? void 0 : _b.estree;
|
|
109
|
+
}
|
|
110
|
+
else if (typeof attribute.value === 'object') {
|
|
111
|
+
estree = (_d = (_c = attribute.value) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.estree;
|
|
112
|
+
}
|
|
113
|
+
if (estree)
|
|
114
|
+
reportReferences(estree, lineOf(child));
|
|
115
|
+
}
|
|
116
|
+
const inside = blockerWithin(child.name, blocker, wrappers);
|
|
117
|
+
let by;
|
|
118
|
+
if (inside === blocker) {
|
|
119
|
+
by = via;
|
|
120
|
+
}
|
|
121
|
+
else if (child.name && !isIntrinsic(child.name)) {
|
|
122
|
+
by = child.name;
|
|
123
|
+
}
|
|
124
|
+
visitChildren(child, inside, inside, by);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (child.type === 'mdxFlowExpression' || child.type === 'mdxTextExpression') {
|
|
128
|
+
if ((_e = child.data) === null || _e === void 0 ? void 0 : _e.estree)
|
|
129
|
+
reportReferences(child.data.estree, lineOf(child));
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (child.type === 'list' && !isListLoose(child)) {
|
|
133
|
+
for (const item of child.children)
|
|
134
|
+
tightItems.add(item);
|
|
135
|
+
}
|
|
136
|
+
if (child.type === 'paragraph') {
|
|
137
|
+
const rendersP = !(parent.type === 'listItem' && tightItems.has(parent));
|
|
138
|
+
visitChildren(child, blocker === 'p' || !rendersP ? blocker : 'paragraph', blocker, via);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if ('children' in child)
|
|
142
|
+
visitChildren(child, blocker, blocker, via);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
visitChildren(tree, false);
|
|
146
|
+
return { islands: [...islands.values()], errors: [...errors, ...sideEffectErrors()], roots };
|
|
147
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Node as EstreeNode, Program } from 'estree-jsx';
|
|
2
|
+
import type { Root } from 'mdast';
|
|
3
|
+
import { type ConstEntry } from './static-expressions.js';
|
|
4
|
+
import type { ExtractPackageIslandsOptions, IslandError } from './types.js';
|
|
5
|
+
export type Binding = {
|
|
6
|
+
local: string;
|
|
7
|
+
source: string;
|
|
8
|
+
imported: string;
|
|
9
|
+
kind: 'package' | 'snippet';
|
|
10
|
+
invalidName?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare const lineOf: (node: {
|
|
13
|
+
position?: {
|
|
14
|
+
start: {
|
|
15
|
+
line: number;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
}) => number | undefined;
|
|
19
|
+
type EsmStatement = Program['body'][number];
|
|
20
|
+
export type LocatedStatement = {
|
|
21
|
+
statement: EsmStatement;
|
|
22
|
+
line?: number;
|
|
23
|
+
importer: string;
|
|
24
|
+
};
|
|
25
|
+
export declare const esmStatements: (tree: Root, pagePath: string) => LocatedStatement[];
|
|
26
|
+
export declare const collectBindings: (statements: LocatedStatement[], options: ExtractPackageIslandsOptions) => {
|
|
27
|
+
bindings: Map<string, Binding>;
|
|
28
|
+
undeclared: Map<string, string>;
|
|
29
|
+
conflicts: IslandError[];
|
|
30
|
+
sideEffects: Map<string, number | undefined>;
|
|
31
|
+
order: string[];
|
|
32
|
+
};
|
|
33
|
+
export declare const collectConsts: (statements: LocatedStatement[], options: ExtractPackageIslandsOptions) => Map<string, ConstEntry>;
|
|
34
|
+
export declare const bindingHead: (name: string) => string | undefined;
|
|
35
|
+
export declare const referencesIn: (node: EstreeNode, bindings: Map<string, Binding>) => {
|
|
36
|
+
name: string;
|
|
37
|
+
jsx: boolean;
|
|
38
|
+
line?: number;
|
|
39
|
+
}[];
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { walk } from 'estree-walker';
|
|
2
|
+
import { importedExportName, isIdentifierName } from '../snippets/importedExportName.js';
|
|
3
|
+
import { resolveImportPath } from '../snippets/resolveImportPath.js';
|
|
4
|
+
import { isMdxJsEsm } from '../utils.js';
|
|
5
|
+
import { importingFile, isDeclaredPackageImport, isNonHostBareImport, isPackageSnippetPath, } from './packageImports.js';
|
|
6
|
+
import { IDENTIFIER_NAME, toStaticExpression, valueToExpression, } from './static-expressions.js';
|
|
7
|
+
export const lineOf = (node) => { var _a; return (_a = node.position) === null || _a === void 0 ? void 0 : _a.start.line; };
|
|
8
|
+
const importedName = (specifier) => {
|
|
9
|
+
if (specifier.type === 'ImportDefaultSpecifier')
|
|
10
|
+
return { imported: 'default' };
|
|
11
|
+
if (specifier.type === 'ImportNamespaceSpecifier')
|
|
12
|
+
return { imported: '*' };
|
|
13
|
+
const imported = importedExportName(specifier);
|
|
14
|
+
return isIdentifierName(imported) ? { imported } : { imported, invalidName: true };
|
|
15
|
+
};
|
|
16
|
+
export const esmStatements = (tree, pagePath) => {
|
|
17
|
+
const statements = [];
|
|
18
|
+
const visitNode = (node) => {
|
|
19
|
+
var _a, _b, _c, _d, _e;
|
|
20
|
+
if (isMdxJsEsm(node)) {
|
|
21
|
+
const importer = importingFile(node, pagePath);
|
|
22
|
+
for (const statement of (_c = (_b = (_a = node.data) === null || _a === void 0 ? void 0 : _a.estree) === null || _b === void 0 ? void 0 : _b.body) !== null && _c !== void 0 ? _c : []) {
|
|
23
|
+
statements.push({ statement, line: (_e = (_d = statement.loc) === null || _d === void 0 ? void 0 : _d.start.line) !== null && _e !== void 0 ? _e : lineOf(node), importer });
|
|
24
|
+
}
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if ('children' in node)
|
|
28
|
+
for (const child of node.children)
|
|
29
|
+
visitNode(child);
|
|
30
|
+
};
|
|
31
|
+
visitNode(tree);
|
|
32
|
+
return statements;
|
|
33
|
+
};
|
|
34
|
+
const describeImport = (imported, source) => `${imported === '*' || isIdentifierName(imported) ? imported : JSON.stringify(imported)} from "${source}"`;
|
|
35
|
+
export const collectBindings = (statements, options) => {
|
|
36
|
+
const bindings = new Map();
|
|
37
|
+
const undeclared = new Map();
|
|
38
|
+
const conflicts = [];
|
|
39
|
+
const sideEffects = new Map();
|
|
40
|
+
const order = new Set();
|
|
41
|
+
const firstImports = new Map();
|
|
42
|
+
const reported = new Set();
|
|
43
|
+
const track = (local, described, island, line) => {
|
|
44
|
+
const first = firstImports.get(local);
|
|
45
|
+
if (!first) {
|
|
46
|
+
firstImports.set(local, { described, island });
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const key = JSON.stringify([local, described]);
|
|
50
|
+
if (first.described === described || !(first.island || island) || reported.has(key))
|
|
51
|
+
return;
|
|
52
|
+
reported.add(key);
|
|
53
|
+
conflicts.push({
|
|
54
|
+
line,
|
|
55
|
+
message: `${local} is imported twice on this page, as ${first.described} and as ${described}. Snippets on a page share its imports, so import one of them under another name.`,
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
for (const { statement, importer, line } of statements) {
|
|
59
|
+
if (statement.type !== 'ImportDeclaration')
|
|
60
|
+
continue;
|
|
61
|
+
const source = statement.source.value;
|
|
62
|
+
if (typeof source !== 'string')
|
|
63
|
+
continue;
|
|
64
|
+
const declared = isDeclaredPackageImport(source, options.packageNames);
|
|
65
|
+
const bare = !declared && isNonHostBareImport(source);
|
|
66
|
+
const resolved = declared || bare ? null : resolveImportPath(source, importer);
|
|
67
|
+
const isSnippet = resolved !== null &&
|
|
68
|
+
(options.packageSnippets
|
|
69
|
+
? options.packageSnippets.has(resolved)
|
|
70
|
+
: isPackageSnippetPath(resolved));
|
|
71
|
+
const origin = isSnippet ? resolved : source;
|
|
72
|
+
if (declared || isSnippet) {
|
|
73
|
+
order.add(origin);
|
|
74
|
+
if (statement.specifiers.length === 0 && !sideEffects.has(origin)) {
|
|
75
|
+
sideEffects.set(origin, line);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
for (const specifier of statement.specifiers) {
|
|
79
|
+
const local = specifier.local.name;
|
|
80
|
+
const imported = importedName(specifier);
|
|
81
|
+
track(local, describeImport(imported.imported, origin), declared || bare || isSnippet, line);
|
|
82
|
+
if (bare)
|
|
83
|
+
undeclared.set(local, source);
|
|
84
|
+
else if (declared || isSnippet) {
|
|
85
|
+
bindings.set(local, Object.assign({ source: origin, kind: declared ? 'package' : 'snippet', local }, imported));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return { bindings, undeclared, conflicts, sideEffects, order: [...order] };
|
|
90
|
+
};
|
|
91
|
+
export const collectConsts = (statements, options) => {
|
|
92
|
+
var _a;
|
|
93
|
+
const consts = new Map();
|
|
94
|
+
for (const [name, value] of Object.entries((_a = options.exportedConsts) !== null && _a !== void 0 ? _a : {})) {
|
|
95
|
+
if (IDENTIFIER_NAME.test(name))
|
|
96
|
+
consts.set(name, { expression: valueToExpression(value) });
|
|
97
|
+
}
|
|
98
|
+
const ignored = new Set();
|
|
99
|
+
for (const { statement } of statements) {
|
|
100
|
+
if (statement.type !== 'ExportNamedDeclaration')
|
|
101
|
+
continue;
|
|
102
|
+
const declaration = statement.declaration;
|
|
103
|
+
if ((declaration === null || declaration === void 0 ? void 0 : declaration.type) !== 'VariableDeclaration')
|
|
104
|
+
continue;
|
|
105
|
+
for (const declarator of declaration.declarations) {
|
|
106
|
+
if (declarator.id.type !== 'Identifier')
|
|
107
|
+
continue;
|
|
108
|
+
const converted = declaration.kind === 'const'
|
|
109
|
+
? toStaticExpression(declarator.init, undefined, ignored)
|
|
110
|
+
: undefined;
|
|
111
|
+
consts.set(declarator.id.name, {
|
|
112
|
+
expression: (converted === null || converted === void 0 ? void 0 : converted.ok) ? converted.expression : undefined,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return consts;
|
|
117
|
+
};
|
|
118
|
+
export const bindingHead = (name) => name.includes(':') ? undefined : name.split('.')[0];
|
|
119
|
+
export const referencesIn = (node, bindings) => {
|
|
120
|
+
const found = [];
|
|
121
|
+
walk(node, {
|
|
122
|
+
enter(estree, parent, key) {
|
|
123
|
+
var _a, _b;
|
|
124
|
+
if (estree.type === 'JSXIdentifier') {
|
|
125
|
+
if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'JSXAttribute' ||
|
|
126
|
+
((parent === null || parent === void 0 ? void 0 : parent.type) === 'JSXMemberExpression' && key === 'property'))
|
|
127
|
+
return;
|
|
128
|
+
if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'JSXNamespacedName')
|
|
129
|
+
return;
|
|
130
|
+
if (bindings.has(estree.name))
|
|
131
|
+
found.push({ name: estree.name, jsx: true, line: (_a = estree.loc) === null || _a === void 0 ? void 0 : _a.start.line });
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (estree.type !== 'Identifier' || !bindings.has(estree.name))
|
|
135
|
+
return;
|
|
136
|
+
if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'MemberExpression' && key === 'property' && !parent.computed)
|
|
137
|
+
return;
|
|
138
|
+
if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'Property' && key === 'key' && !parent.computed)
|
|
139
|
+
return;
|
|
140
|
+
if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'ImportSpecifier' ||
|
|
141
|
+
(parent === null || parent === void 0 ? void 0 : parent.type) === 'ImportDefaultSpecifier' ||
|
|
142
|
+
(parent === null || parent === void 0 ? void 0 : parent.type) === 'ImportNamespaceSpecifier') {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
found.push({ name: estree.name, jsx: false, line: (_b = estree.loc) === null || _b === void 0 ? void 0 : _b.start.line });
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
return found;
|
|
149
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { JSXElement, JSXExpressionContainer, JSXFragment } from 'estree-jsx';
|
|
2
|
+
import type { RootContent } from 'mdast';
|
|
3
|
+
import { type Binding } from './island-bindings.js';
|
|
4
|
+
import { type ConstEntry } from './static-expressions.js';
|
|
5
|
+
import type { IslandError, IslandImport } from './types.js';
|
|
6
|
+
type JsxNode = Extract<RootContent, {
|
|
7
|
+
type: 'mdxJsxFlowElement' | 'mdxJsxTextElement';
|
|
8
|
+
}>;
|
|
9
|
+
type JsxChild = JSXElement | JSXFragment | JSXExpressionContainer;
|
|
10
|
+
export declare const MOVE_TO_SNIPPET = "Move this into a snippet.";
|
|
11
|
+
export declare class IslandModuleBuilder {
|
|
12
|
+
private readonly rootName;
|
|
13
|
+
private readonly pagePath;
|
|
14
|
+
private readonly bindings;
|
|
15
|
+
private readonly undeclared;
|
|
16
|
+
private readonly consts;
|
|
17
|
+
private readonly sideEffects;
|
|
18
|
+
private readonly order;
|
|
19
|
+
readonly usedBindings: Map<string, Binding>;
|
|
20
|
+
readonly usedConsts: Set<string>;
|
|
21
|
+
readonly errors: IslandError[];
|
|
22
|
+
constructor(rootName: string, pagePath: string, bindings: Map<string, Binding>, undeclared: Map<string, string>, consts: Map<string, ConstEntry>, sideEffects: ReadonlyMap<string, unknown>, order: readonly string[]);
|
|
23
|
+
private url;
|
|
24
|
+
private fail;
|
|
25
|
+
private insideRoot;
|
|
26
|
+
element(node: JsxNode): JSXElement | JSXFragment | undefined;
|
|
27
|
+
private attribute;
|
|
28
|
+
private propFailure;
|
|
29
|
+
private intrinsic;
|
|
30
|
+
children(nodes: RootContent[]): JsxChild[];
|
|
31
|
+
private child;
|
|
32
|
+
private listItem;
|
|
33
|
+
private isRenderableText;
|
|
34
|
+
module(root: JSXElement | JSXFragment): string;
|
|
35
|
+
imports(): IslandImport[];
|
|
36
|
+
}
|
|
37
|
+
export {};
|