@mintlify/common 1.0.1274 → 1.0.1275
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/mdx/estreeReferences.d.ts +2 -0
- package/dist/mdx/estreeReferences.js +32 -0
- package/dist/mdx/plugins/remark/remarkVisibilityForMarkdown.js +52 -3
- package/dist/mdx/plugins/remark/staticEvaluator.d.ts +19 -0
- package/dist/mdx/plugins/remark/staticEvaluator.js +221 -4
- package/dist/mdx/plugins/remark/unfoldComponentsForMarkdown.d.ts +1 -0
- package/dist/mdx/plugins/remark/unfoldComponentsForMarkdown.js +238 -38
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -37,3 +37,5 @@ export declare function hasEagerCall(node: unknown): boolean;
|
|
|
37
37
|
* local may alias that object; a local initialized from fresh values passes nothing on.
|
|
38
38
|
*/
|
|
39
39
|
export declare function collectModuleWrites(node: unknown, eagerOnly?: boolean): ModuleWrites;
|
|
40
|
+
/** Every name `node` declares or binds, at any depth. */
|
|
41
|
+
export declare function collectDeclaredNames(node: unknown, names?: Set<string>): Set<string>;
|
|
@@ -961,3 +961,35 @@ export function collectModuleWrites(node, eagerOnly = false) {
|
|
|
961
961
|
});
|
|
962
962
|
return writes;
|
|
963
963
|
}
|
|
964
|
+
/** Every name `node` declares or binds, at any depth. */
|
|
965
|
+
export function collectDeclaredNames(node, names = new Set()) {
|
|
966
|
+
if (Array.isArray(node)) {
|
|
967
|
+
for (const child of node)
|
|
968
|
+
collectDeclaredNames(child, names);
|
|
969
|
+
return names;
|
|
970
|
+
}
|
|
971
|
+
if (!isObject(node))
|
|
972
|
+
return names;
|
|
973
|
+
if (node.type === 'VariableDeclarator')
|
|
974
|
+
collectPatternNames(node.id, names);
|
|
975
|
+
if ((node.type === 'FunctionDeclaration' || node.type === 'ClassDeclaration') &&
|
|
976
|
+
isObject(node.id) &&
|
|
977
|
+
typeof node.id.name === 'string') {
|
|
978
|
+
names.add(node.id.name);
|
|
979
|
+
}
|
|
980
|
+
if (Array.isArray(node.params)) {
|
|
981
|
+
for (const param of node.params)
|
|
982
|
+
collectPatternNames(param, names);
|
|
983
|
+
}
|
|
984
|
+
if (node.type === 'CatchClause')
|
|
985
|
+
collectPatternNames(node.param, names);
|
|
986
|
+
if ((node.type === 'ImportSpecifier' ||
|
|
987
|
+
node.type === 'ImportDefaultSpecifier' ||
|
|
988
|
+
node.type === 'ImportNamespaceSpecifier') &&
|
|
989
|
+
isObject(node.local) &&
|
|
990
|
+
typeof node.local.name === 'string') {
|
|
991
|
+
names.add(node.local.name);
|
|
992
|
+
}
|
|
993
|
+
forEachCodeChild(node, (child) => collectDeclaredNames(child, names));
|
|
994
|
+
return names;
|
|
995
|
+
}
|
|
@@ -3,7 +3,7 @@ import { isObject } from '../../../types/guards.js';
|
|
|
3
3
|
import { getAST, stringifyTree } from '../../remark-core.js';
|
|
4
4
|
import { BLOCK_LINK_LABEL } from './firstPartyMarkdownComponents.js';
|
|
5
5
|
import { evaluateStatic } from './staticEvaluator.js';
|
|
6
|
-
import { chargeUnfoldBudget, chargeUnfoldCall, collectMarkdownComponentContext, collectUsageProps, containsJsx, createUnfoldBudget, definitionGatesContent, DROP_ELEMENTS, dropPairedDarkOnly, escapeInterpolatedText, HEADING_ELEMENTS, isPresentationalAttribute, UNWRAP_BLOCK_ELEMENTS, UNWRAP_INLINE_ELEMENTS, escapeLinkLabel, extractProgramExpression, markdownLinkDestination, MAX_UNFOLD_DEPTH, GFM_ALERT_PATTERN, HEADLINE_ATTRIBUTES, KEEP_TAG_COMPONENTS, materializeComponent, serializeExpressionJsx, } from './unfoldComponentsForMarkdown.js';
|
|
6
|
+
import { chargeUnfoldBudget, chargeUnfoldCall, collectMarkdownComponentContext, collectUsageProps, containsJsx, createUnfoldBudget, definitionGatesContent, DROP_ELEMENTS, FORM_CONTROL_ELEMENTS, dropPairedDarkOnly, escapeInterpolatedText, HEADING_ELEMENTS, isPresentationalAttribute, UNWRAP_BLOCK_ELEMENTS, UNWRAP_INLINE_ELEMENTS, escapeLinkLabel, extractProgramExpression, markdownLinkDestination, MAX_UNFOLD_DEPTH, GFM_ALERT_PATTERN, HEADLINE_ATTRIBUTES, KEEP_TAG_COMPONENTS, materializeComponent, serializeExpressionJsx, } from './unfoldComponentsForMarkdown.js';
|
|
7
7
|
export function isVisibilityElement(node) {
|
|
8
8
|
return ((node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement') &&
|
|
9
9
|
node.name === 'Visibility');
|
|
@@ -403,6 +403,7 @@ function bodyExpressionValue(bodyChildren, ctx) {
|
|
|
403
403
|
return undefined;
|
|
404
404
|
const evaluated = evaluateStatic(extractProgramExpression((_a = only.data) === null || _a === void 0 ? void 0 : _a.estree), {
|
|
405
405
|
scope: ctx.moduleScope,
|
|
406
|
+
declaredNames: ctx.declaredNames,
|
|
406
407
|
});
|
|
407
408
|
if (!evaluated.ok || (typeof evaluated.value === 'object' && evaluated.value !== null)) {
|
|
408
409
|
return undefined;
|
|
@@ -475,12 +476,44 @@ function headlineMarkdown(title, href) {
|
|
|
475
476
|
return `**${label}**`;
|
|
476
477
|
return `[${escapeLinkLabel(label)}](${markdownLinkDestination(href)})`;
|
|
477
478
|
}
|
|
479
|
+
// Text an inline component shows when it has no children. `path` names a location, not a label.
|
|
480
|
+
const INLINE_TEXT_PROPS = [
|
|
481
|
+
'children',
|
|
482
|
+
'title',
|
|
483
|
+
'label',
|
|
484
|
+
'name',
|
|
485
|
+
'description',
|
|
486
|
+
'alt',
|
|
487
|
+
'aria-label',
|
|
488
|
+
];
|
|
489
|
+
/** Inside running text a component stands for a word or phrase: its text, linked when it has an `href`. */
|
|
490
|
+
function unfoldInlineForeignUsage(node, props, ctx, transformed) {
|
|
491
|
+
const children = flattenToPhrasing(transformed !== null && transformed !== void 0 ? transformed : transformChildren([...node.children], ctx)).filter(isPhrasingContent);
|
|
492
|
+
const hasChildContent = children.some((child) => !(child.type === 'text' && child.value.trim() === ''));
|
|
493
|
+
const childrenProp = props.get('children');
|
|
494
|
+
const text = typeof childrenProp === 'number'
|
|
495
|
+
? String(childrenProp)
|
|
496
|
+
: firstTextProp(props, INLINE_TEXT_PROPS);
|
|
497
|
+
const content = hasChildContent
|
|
498
|
+
? children
|
|
499
|
+
: text === undefined
|
|
500
|
+
? []
|
|
501
|
+
: [{ type: 'text', value: text }];
|
|
502
|
+
const href = props.get('href');
|
|
503
|
+
if (content.length === 0 || typeof href !== 'string' || href === '')
|
|
504
|
+
return content;
|
|
505
|
+
return [
|
|
506
|
+
{ type: 'link', url: href, children: flattenToPhrasing(content).filter(isPhrasingContent) },
|
|
507
|
+
];
|
|
508
|
+
}
|
|
478
509
|
function unfoldForeignUsage(node, name, ctx, transformed) {
|
|
479
510
|
if (KEEP_TAG_COMPONENTS.has(name))
|
|
480
511
|
return undefined;
|
|
481
512
|
const props = collectUsageProps(node, ctx);
|
|
482
513
|
if (props.get('aria-hidden') === true || props.get('aria-hidden') === 'true')
|
|
483
514
|
return [];
|
|
515
|
+
if (node.type === 'mdxJsxTextElement')
|
|
516
|
+
return unfoldInlineForeignUsage(node, props, ctx, transformed);
|
|
484
517
|
const result = [];
|
|
485
518
|
const title = firstTextProp(props, HEADLINE_ATTRIBUTES);
|
|
486
519
|
if (title !== undefined) {
|
|
@@ -535,6 +568,8 @@ function transformIntrinsicElement(node, name, ctx) {
|
|
|
535
568
|
const fallback = () => fallbackLabel === '' ? [] : [{ type: 'text', value: fallbackLabel }];
|
|
536
569
|
if (DROP_ELEMENTS.has(name))
|
|
537
570
|
return fallback();
|
|
571
|
+
if (FORM_CONTROL_ELEMENTS.has(name))
|
|
572
|
+
return [];
|
|
538
573
|
if (name === 'br')
|
|
539
574
|
return node.type === 'mdxJsxTextElement' ? [{ type: 'break' }] : [];
|
|
540
575
|
if (name === 'hr')
|
|
@@ -579,7 +614,18 @@ function transformIntrinsicElement(node, name, ctx) {
|
|
|
579
614
|
return children.length > 0 ? children : fallback();
|
|
580
615
|
return linkContent(children, href, fallbackLabel);
|
|
581
616
|
}
|
|
582
|
-
|
|
617
|
+
// Attributes, spreads included, are kept only as resolved static values: an unresolved
|
|
618
|
+
// expression would print code
|
|
619
|
+
node.attributes = [...props].flatMap(([attrName, value]) => {
|
|
620
|
+
if (attrName === 'children' || isPresentationalAttribute(attrName))
|
|
621
|
+
return [];
|
|
622
|
+
if (value === true)
|
|
623
|
+
return [{ type: 'mdxJsxAttribute', name: attrName, value: null }];
|
|
624
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
625
|
+
return [{ type: 'mdxJsxAttribute', name: attrName, value: String(value) }];
|
|
626
|
+
}
|
|
627
|
+
return [];
|
|
628
|
+
});
|
|
583
629
|
replaceChildren(node.children, children);
|
|
584
630
|
return [node];
|
|
585
631
|
}
|
|
@@ -702,7 +748,10 @@ function transformExpression(node, ctx) {
|
|
|
702
748
|
return [{ type: 'text', value: trimmed }];
|
|
703
749
|
}
|
|
704
750
|
}
|
|
705
|
-
const evaluated = evaluateStatic(expression, {
|
|
751
|
+
const evaluated = evaluateStatic(expression, {
|
|
752
|
+
scope: ctx.moduleScope,
|
|
753
|
+
declaredNames: ctx.declaredNames,
|
|
754
|
+
});
|
|
706
755
|
if (evaluated.ok) {
|
|
707
756
|
const value = evaluated.value;
|
|
708
757
|
if (value === null || value === undefined || typeof value === 'boolean')
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Root } from 'mdast';
|
|
2
|
+
import { type UnknownRecord } from '../../estreeReferences.js';
|
|
2
3
|
export declare function nodeType(value: unknown): string | undefined;
|
|
3
4
|
export type StaticValue = string | number | boolean | null | undefined | {
|
|
4
5
|
readonly [key: string]: StaticValue;
|
|
@@ -28,6 +29,8 @@ export type MarkdownComponentContext = {
|
|
|
28
29
|
* produce them, so no write the evaluator cannot see can make them stale.
|
|
29
30
|
*/
|
|
30
31
|
literalScope: StaticScope;
|
|
32
|
+
/** Every name the module declares or binds, in any scope. */
|
|
33
|
+
declaredNames?: ReadonlySet<string>;
|
|
31
34
|
};
|
|
32
35
|
export type EvalResult = {
|
|
33
36
|
ok: true;
|
|
@@ -38,6 +41,18 @@ export type EvalResult = {
|
|
|
38
41
|
export declare const EVAL_FAILED: EvalResult;
|
|
39
42
|
export type EvalEnv = {
|
|
40
43
|
scope: StaticScope;
|
|
44
|
+
/** The parameter a component's children are bound to. */
|
|
45
|
+
childrenName?: string;
|
|
46
|
+
/**
|
|
47
|
+
* The children are markdown built from the usage, with links or formatting in it. Reading or
|
|
48
|
+
* transforming them as a string would act on that markdown, not on the text a reader sees.
|
|
49
|
+
*/
|
|
50
|
+
markdownChildren?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Every name the module declares or binds, in any scope. A browser-only global is known to be
|
|
53
|
+
* absent only when the module does not declare that name itself.
|
|
54
|
+
*/
|
|
55
|
+
declaredNames?: ReadonlySet<string>;
|
|
41
56
|
propsObjectName?: string;
|
|
42
57
|
failedProps?: ReadonlySet<string>;
|
|
43
58
|
restName?: string;
|
|
@@ -46,6 +61,10 @@ export type EvalEnv = {
|
|
|
46
61
|
export declare function unbindPattern(pattern: unknown, env: EvalEnv): void;
|
|
47
62
|
export declare function bindPattern(pattern: unknown, value: StaticValue, env: EvalEnv): void;
|
|
48
63
|
export declare function evaluateStatic(node: unknown, env: EvalEnv): EvalResult;
|
|
64
|
+
/** Whether `node` reads children that are markdown, directly or as `props.children`. */
|
|
65
|
+
export declare function readsMarkdownChildren(node: unknown, env: EvalEnv): boolean;
|
|
66
|
+
/** The property a member reads when it is fixed: `a.children` or `a["children"]`. */
|
|
67
|
+
export declare function staticPropertyName(member: UnknownRecord): string | undefined;
|
|
49
68
|
/**
|
|
50
69
|
* Collects a module's component definitions and its statically known values. Objects are only
|
|
51
70
|
* bound when the module never writes through any object: tracking which objects a write can reach
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isObject } from '../../../types/guards.js';
|
|
2
|
-
import { collectModuleWrites, collectPatternNames, hasEagerCall, } from '../../estreeReferences.js';
|
|
2
|
+
import { collectDeclaredNames, collectModuleWrites, collectPatternNames, hasEagerCall, } from '../../estreeReferences.js';
|
|
3
3
|
export function nodeType(value) {
|
|
4
4
|
return isObject(value) && typeof value.type === 'string' ? value.type : undefined;
|
|
5
5
|
}
|
|
@@ -256,6 +256,8 @@ export function evaluateStatic(node, env) {
|
|
|
256
256
|
case 'ParenthesizedExpression':
|
|
257
257
|
return evaluateStatic(node.expression, env);
|
|
258
258
|
case 'MemberExpression': {
|
|
259
|
+
if (readsMarkdownChildren(node.object, env))
|
|
260
|
+
return EVAL_FAILED;
|
|
259
261
|
const property = node.property;
|
|
260
262
|
const key = node.computed === true
|
|
261
263
|
? evaluateStatic(property, env)
|
|
@@ -415,7 +417,11 @@ export function evaluateStatic(node, env) {
|
|
|
415
417
|
return EVAL_FAILED;
|
|
416
418
|
return evaluateStatic(test.value ? node.consequent : node.alternate, env);
|
|
417
419
|
}
|
|
420
|
+
case 'CallExpression':
|
|
421
|
+
return evaluateMethodCall(node, env);
|
|
418
422
|
case 'UnaryExpression': {
|
|
423
|
+
if (node.operator === 'typeof')
|
|
424
|
+
return evaluateTypeof(node.argument, env);
|
|
419
425
|
const argument = evaluateStatic(node.argument, env);
|
|
420
426
|
if (!argument.ok)
|
|
421
427
|
return EVAL_FAILED;
|
|
@@ -437,6 +443,216 @@ export function evaluateStatic(node, env) {
|
|
|
437
443
|
return EVAL_FAILED;
|
|
438
444
|
}
|
|
439
445
|
}
|
|
446
|
+
function isIndex(value) {
|
|
447
|
+
return value === undefined || (typeof value === 'number' && Number.isFinite(value));
|
|
448
|
+
}
|
|
449
|
+
/** Pure string methods, called on a known string with known arguments. */
|
|
450
|
+
function callStringMethod(text, method, args) {
|
|
451
|
+
const [first, second] = args;
|
|
452
|
+
const stringArg = typeof first === 'string' ? first : undefined;
|
|
453
|
+
switch (method) {
|
|
454
|
+
case 'startsWith':
|
|
455
|
+
case 'endsWith':
|
|
456
|
+
case 'includes':
|
|
457
|
+
case 'indexOf':
|
|
458
|
+
case 'lastIndexOf':
|
|
459
|
+
if (stringArg === undefined || !isIndex(second))
|
|
460
|
+
return EVAL_FAILED;
|
|
461
|
+
return { ok: true, value: text[method](stringArg, second) };
|
|
462
|
+
case 'slice':
|
|
463
|
+
case 'substring':
|
|
464
|
+
if (!isIndex(first) || !isIndex(second))
|
|
465
|
+
return EVAL_FAILED;
|
|
466
|
+
return { ok: true, value: text[method](first !== null && first !== void 0 ? first : 0, second) };
|
|
467
|
+
case 'at':
|
|
468
|
+
case 'charAt':
|
|
469
|
+
if (!isIndex(first))
|
|
470
|
+
return EVAL_FAILED;
|
|
471
|
+
return { ok: true, value: method === 'at' ? text.at(first !== null && first !== void 0 ? first : 0) : text.charAt(first !== null && first !== void 0 ? first : 0) };
|
|
472
|
+
case 'toLowerCase':
|
|
473
|
+
case 'toUpperCase':
|
|
474
|
+
case 'trim':
|
|
475
|
+
case 'trimStart':
|
|
476
|
+
case 'trimEnd':
|
|
477
|
+
return args.length === 0 ? { ok: true, value: text[method]() } : EVAL_FAILED;
|
|
478
|
+
case 'replace':
|
|
479
|
+
case 'replaceAll': {
|
|
480
|
+
// `$` patterns can copy large parts of the text into each replacement
|
|
481
|
+
if (stringArg === undefined || typeof second !== 'string' || second.includes('$')) {
|
|
482
|
+
return EVAL_FAILED;
|
|
483
|
+
}
|
|
484
|
+
const occurrences = stringArg === ''
|
|
485
|
+
? method === 'replaceAll'
|
|
486
|
+
? text.length + 1
|
|
487
|
+
: 1
|
|
488
|
+
: method === 'replaceAll'
|
|
489
|
+
? text.split(stringArg).length - 1
|
|
490
|
+
: Number(text.includes(stringArg));
|
|
491
|
+
const length = text.length + occurrences * (second.length - stringArg.length);
|
|
492
|
+
if (length > MAX_STATIC_VALUE_WEIGHT)
|
|
493
|
+
return EVAL_FAILED;
|
|
494
|
+
return { ok: true, value: text[method](stringArg, second) };
|
|
495
|
+
}
|
|
496
|
+
case 'split':
|
|
497
|
+
if (stringArg === undefined || !isIndex(second))
|
|
498
|
+
return EVAL_FAILED;
|
|
499
|
+
return withinBudget(text.split(stringArg, second));
|
|
500
|
+
case 'padStart':
|
|
501
|
+
case 'padEnd':
|
|
502
|
+
if (typeof first !== 'number' || first > MAX_STATIC_VALUE_WEIGHT)
|
|
503
|
+
return EVAL_FAILED;
|
|
504
|
+
if (second !== undefined && typeof second !== 'string')
|
|
505
|
+
return EVAL_FAILED;
|
|
506
|
+
return { ok: true, value: text[method](first, second) };
|
|
507
|
+
case 'repeat':
|
|
508
|
+
if (typeof first !== 'number' || first < 0 || text.length * first > MAX_STATIC_VALUE_WEIGHT) {
|
|
509
|
+
return EVAL_FAILED;
|
|
510
|
+
}
|
|
511
|
+
return { ok: true, value: text.repeat(first) };
|
|
512
|
+
case 'concat': {
|
|
513
|
+
if (!args.every((arg) => typeof arg === 'string' || typeof arg === 'number')) {
|
|
514
|
+
return EVAL_FAILED;
|
|
515
|
+
}
|
|
516
|
+
const parts = args.map(String);
|
|
517
|
+
const length = parts.reduce((total, part) => total + part.length, text.length);
|
|
518
|
+
if (length > MAX_STATIC_VALUE_WEIGHT)
|
|
519
|
+
return EVAL_FAILED;
|
|
520
|
+
return { ok: true, value: text.concat(...parts) };
|
|
521
|
+
}
|
|
522
|
+
default:
|
|
523
|
+
return EVAL_FAILED;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
/** Pure array methods that read a known array without changing it. */
|
|
527
|
+
function callArrayMethod(items, method, args) {
|
|
528
|
+
const [first, second] = args;
|
|
529
|
+
switch (method) {
|
|
530
|
+
case 'join': {
|
|
531
|
+
if (first !== undefined && typeof first !== 'string')
|
|
532
|
+
return EVAL_FAILED;
|
|
533
|
+
if (!items.every((item) => item === null || typeof item !== 'object'))
|
|
534
|
+
return EVAL_FAILED;
|
|
535
|
+
const parts = items.map((item) => (item == null ? '' : String(item)));
|
|
536
|
+
const separator = first !== null && first !== void 0 ? first : ',';
|
|
537
|
+
const length = parts.reduce((total, part) => total + part.length, 0) +
|
|
538
|
+
separator.length * Math.max(parts.length - 1, 0);
|
|
539
|
+
if (length > MAX_STATIC_VALUE_WEIGHT)
|
|
540
|
+
return EVAL_FAILED;
|
|
541
|
+
return { ok: true, value: parts.join(separator) };
|
|
542
|
+
}
|
|
543
|
+
case 'includes':
|
|
544
|
+
case 'indexOf':
|
|
545
|
+
if (first !== null && typeof first === 'object')
|
|
546
|
+
return EVAL_FAILED;
|
|
547
|
+
if (!isIndex(second))
|
|
548
|
+
return EVAL_FAILED;
|
|
549
|
+
return { ok: true, value: items[method](first, second) };
|
|
550
|
+
case 'slice':
|
|
551
|
+
if (!isIndex(first) || !isIndex(second))
|
|
552
|
+
return EVAL_FAILED;
|
|
553
|
+
return { ok: true, value: items.slice(first, second) };
|
|
554
|
+
case 'at':
|
|
555
|
+
if (!isIndex(first))
|
|
556
|
+
return EVAL_FAILED;
|
|
557
|
+
return { ok: true, value: items.at(first !== null && first !== void 0 ? first : 0) };
|
|
558
|
+
default:
|
|
559
|
+
return EVAL_FAILED;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
/** A call to a pure built-in method on a known string or array, such as `path.startsWith("/")`. */
|
|
563
|
+
function evaluateMethodCall(node, env) {
|
|
564
|
+
const callee = node.callee;
|
|
565
|
+
if (nodeType(callee) !== 'MemberExpression' || !isObject(callee) || callee.optional === true) {
|
|
566
|
+
return EVAL_FAILED;
|
|
567
|
+
}
|
|
568
|
+
const method = callee.computed === true
|
|
569
|
+
? isObject(callee.property) && typeof callee.property.value === 'string'
|
|
570
|
+
? callee.property.value
|
|
571
|
+
: undefined
|
|
572
|
+
: identifierName(callee.property);
|
|
573
|
+
if (method === undefined)
|
|
574
|
+
return EVAL_FAILED;
|
|
575
|
+
if (readsMarkdownChildren(callee.object, env))
|
|
576
|
+
return EVAL_FAILED;
|
|
577
|
+
const receiver = evaluateStatic(callee.object, env);
|
|
578
|
+
if (!receiver.ok)
|
|
579
|
+
return EVAL_FAILED;
|
|
580
|
+
const rawArgs = Array.isArray(node.arguments) ? node.arguments : [];
|
|
581
|
+
const args = [];
|
|
582
|
+
for (const rawArg of rawArgs) {
|
|
583
|
+
if (nodeType(rawArg) === 'SpreadElement')
|
|
584
|
+
return EVAL_FAILED;
|
|
585
|
+
const evaluated = evaluateStatic(rawArg, env);
|
|
586
|
+
if (!evaluated.ok)
|
|
587
|
+
return EVAL_FAILED;
|
|
588
|
+
args.push(evaluated.value);
|
|
589
|
+
}
|
|
590
|
+
// Sizes are checked before each call; a native error still fails evaluation instead of throwing
|
|
591
|
+
try {
|
|
592
|
+
if (typeof receiver.value === 'string')
|
|
593
|
+
return callStringMethod(receiver.value, method, args);
|
|
594
|
+
if (Array.isArray(receiver.value))
|
|
595
|
+
return callArrayMethod(receiver.value, method, args);
|
|
596
|
+
}
|
|
597
|
+
catch (_a) {
|
|
598
|
+
return EVAL_FAILED;
|
|
599
|
+
}
|
|
600
|
+
return EVAL_FAILED;
|
|
601
|
+
}
|
|
602
|
+
// Markdown is rendered without a browser, as on a server, so these globals do not exist there
|
|
603
|
+
const BROWSER_ONLY_GLOBALS = new Set([
|
|
604
|
+
'window',
|
|
605
|
+
'document',
|
|
606
|
+
'navigator',
|
|
607
|
+
'location',
|
|
608
|
+
'history',
|
|
609
|
+
'localStorage',
|
|
610
|
+
'sessionStorage',
|
|
611
|
+
'matchMedia',
|
|
612
|
+
'requestAnimationFrame',
|
|
613
|
+
]);
|
|
614
|
+
/** Whether `node` reads children that are markdown, directly or as `props.children`. */
|
|
615
|
+
export function readsMarkdownChildren(node, env) {
|
|
616
|
+
var _a, _b;
|
|
617
|
+
if (env.markdownChildren !== true || !isObject(node))
|
|
618
|
+
return false;
|
|
619
|
+
if (node.type === 'Identifier') {
|
|
620
|
+
return node.name === env.childrenName && !((_b = (_a = env.failedProps) === null || _a === void 0 ? void 0 : _a.has('children')) !== null && _b !== void 0 ? _b : false);
|
|
621
|
+
}
|
|
622
|
+
if (node.type !== 'MemberExpression')
|
|
623
|
+
return false;
|
|
624
|
+
const objectName = identifierName(node.object);
|
|
625
|
+
return (staticPropertyName(node) === 'children' &&
|
|
626
|
+
objectName !== undefined &&
|
|
627
|
+
(objectName === env.propsObjectName || objectName === env.restName));
|
|
628
|
+
}
|
|
629
|
+
/** The property a member reads when it is fixed: `a.children` or `a["children"]`. */
|
|
630
|
+
export function staticPropertyName(member) {
|
|
631
|
+
if (member.computed !== true)
|
|
632
|
+
return identifierName(member.property);
|
|
633
|
+
const property = member.property;
|
|
634
|
+
return isObject(property) && property.type === 'Literal' && typeof property.value === 'string'
|
|
635
|
+
? property.value
|
|
636
|
+
: undefined;
|
|
637
|
+
}
|
|
638
|
+
function evaluateTypeof(argument, env) {
|
|
639
|
+
if (readsMarkdownChildren(argument, env))
|
|
640
|
+
return EVAL_FAILED;
|
|
641
|
+
if (nodeType(argument) === 'Identifier' &&
|
|
642
|
+
isObject(argument) &&
|
|
643
|
+
typeof argument.name === 'string' &&
|
|
644
|
+
BROWSER_ONLY_GLOBALS.has(argument.name) &&
|
|
645
|
+
!env.scope.has(argument.name) &&
|
|
646
|
+
env.declaredNames !== undefined &&
|
|
647
|
+
!env.declaredNames.has(argument.name)) {
|
|
648
|
+
return { ok: true, value: 'undefined' };
|
|
649
|
+
}
|
|
650
|
+
const evaluated = evaluateStatic(argument, env);
|
|
651
|
+
if (!evaluated.ok)
|
|
652
|
+
return EVAL_FAILED;
|
|
653
|
+
const value = evaluated.value;
|
|
654
|
+
return { ok: true, value: value === null ? 'object' : typeof value };
|
|
655
|
+
}
|
|
440
656
|
function isFunctionNode(value) {
|
|
441
657
|
const type = nodeType(value);
|
|
442
658
|
return (type === 'ArrowFunctionExpression' ||
|
|
@@ -515,7 +731,7 @@ export function collectContextFromTree(tree) {
|
|
|
515
731
|
}
|
|
516
732
|
if (kind !== 'const')
|
|
517
733
|
return;
|
|
518
|
-
const literal = evaluateStatic(init, { scope: literalScope });
|
|
734
|
+
const literal = evaluateStatic(init, { scope: literalScope, declaredNames });
|
|
519
735
|
if (literal.ok) {
|
|
520
736
|
// Defaults and computed keys in the pattern may read earlier literal values
|
|
521
737
|
const bound = new Map(literalScope);
|
|
@@ -531,13 +747,14 @@ export function collectContextFromTree(tree) {
|
|
|
531
747
|
literalScope.set(boundName, value);
|
|
532
748
|
}
|
|
533
749
|
}
|
|
534
|
-
const evaluated = evaluateStatic(init, { scope: moduleScope });
|
|
750
|
+
const evaluated = evaluateStatic(init, { scope: moduleScope, declaredNames });
|
|
535
751
|
if (!evaluated.ok)
|
|
536
752
|
return;
|
|
537
753
|
bindPattern(declarator.id, evaluated.value, { scope: moduleScope });
|
|
538
754
|
};
|
|
539
755
|
const estrees = [];
|
|
540
756
|
collectEstrees(tree, estrees);
|
|
757
|
+
const declaredNames = collectDeclaredNames(estrees);
|
|
541
758
|
const { reassigned, mutated } = collectModuleWrites(estrees);
|
|
542
759
|
const moduleWrites = reassigned.size > 0 || mutated.size > 0;
|
|
543
760
|
for (const statement of statements) {
|
|
@@ -635,5 +852,5 @@ export function collectContextFromTree(tree) {
|
|
|
635
852
|
}
|
|
636
853
|
}
|
|
637
854
|
}
|
|
638
|
-
return { defs, moduleScope, literalScope };
|
|
855
|
+
return { defs, moduleScope, literalScope, declaredNames };
|
|
639
856
|
}
|
|
@@ -37,6 +37,7 @@ export declare const FAILED_SPREAD = "*";
|
|
|
37
37
|
export declare function collectMarkdownComponentContext(tree: Root): MarkdownComponentContext;
|
|
38
38
|
export declare function getFirstPartyComponentDefs(): Map<string, ComponentDef>;
|
|
39
39
|
export declare const DROP_ELEMENTS: Set<string>;
|
|
40
|
+
export declare const FORM_CONTROL_ELEMENTS: Set<string>;
|
|
40
41
|
export declare const UNWRAP_BLOCK_ELEMENTS: Set<string>;
|
|
41
42
|
export declare const UNWRAP_INLINE_ELEMENTS: Set<string>;
|
|
42
43
|
export declare const HEADING_ELEMENTS: Record<string, Heading['depth']>;
|