@readme/markdown 15.0.1 → 15.0.2
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/components/Tabs/style.scss +4 -0
- package/dist/lib/ast-processor.d.ts +1 -0
- package/dist/lib/utils/literal-expression.d.ts +16 -0
- package/dist/lib/utils/mdxish/mdxish-variables.d.ts +1 -1
- package/dist/main.css +1 -1
- package/dist/main.css.map +1 -1
- package/dist/main.js +182 -26
- package/dist/main.node.js +182 -26
- package/dist/main.node.js.map +1 -1
- package/dist/processor/transform/flatten-attribute-expressions.d.ts +11 -0
- package/dist/processor/transform/index.d.ts +2 -1
- package/dist/render-fixture.css +1 -1
- package/dist/render-fixture.css.map +1 -1
- package/dist/render-fixture.node.js +182 -26
- package/dist/render-fixture.node.js.map +1 -1
- package/dist/utils/user.d.ts +15 -2
- package/package.json +2 -2
- package/types.d.ts +1 -1
package/dist/main.js
CHANGED
|
@@ -54765,12 +54765,104 @@ const mdast = (text, opts = {}) => {
|
|
|
54765
54765
|
*/
|
|
54766
54766
|
const jsxAcornParser = external_acorn_.Parser.extend(acorn_jsx_default()());
|
|
54767
54767
|
|
|
54768
|
+
;// ./lib/utils/literal-expression.ts
|
|
54769
|
+
|
|
54770
|
+
const unsupported = (description) => new Error(`not a literal expression: ${description}`);
|
|
54771
|
+
/** Narrows a resolved value for arithmetic, so operands never coerce to `NaN` or `"[object Object]"`. */
|
|
54772
|
+
const asNumber = (value) => {
|
|
54773
|
+
if (typeof value !== 'number')
|
|
54774
|
+
throw unsupported('non-numeric operand');
|
|
54775
|
+
return value;
|
|
54776
|
+
};
|
|
54777
|
+
const asOperand = (value) => {
|
|
54778
|
+
if (typeof value !== 'number' && typeof value !== 'string')
|
|
54779
|
+
throw unsupported('non-primitive operand');
|
|
54780
|
+
return value;
|
|
54781
|
+
};
|
|
54782
|
+
const ARITHMETIC_OPERATORS = {
|
|
54783
|
+
// `+` doubles as string concatenation, so it accepts a string on either side.
|
|
54784
|
+
'+': (left, right) => (typeof left === 'number' && typeof right === 'number' ? left + right : `${left}${right}`),
|
|
54785
|
+
'-': (left, right) => asNumber(left) - asNumber(right),
|
|
54786
|
+
'*': (left, right) => asNumber(left) * asNumber(right),
|
|
54787
|
+
'/': (left, right) => asNumber(left) / asNumber(right),
|
|
54788
|
+
};
|
|
54789
|
+
/** Resolve one estree node, recursing into arrays and objects. Throws for anything not on the allowlist. */
|
|
54790
|
+
const resolveNode = (node) => {
|
|
54791
|
+
switch (node.type) {
|
|
54792
|
+
case 'Literal':
|
|
54793
|
+
// Regex and bigint `Literal`s hold values a tree consumer can't serialise;
|
|
54794
|
+
// a BigInt throws outright in `JSON.stringify`.
|
|
54795
|
+
if ('regex' in node || 'bigint' in node)
|
|
54796
|
+
throw unsupported('regex or bigint literal');
|
|
54797
|
+
return node.value;
|
|
54798
|
+
case 'Identifier':
|
|
54799
|
+
if (node.name !== 'undefined')
|
|
54800
|
+
throw unsupported(`identifier \`${node.name}\``);
|
|
54801
|
+
return undefined;
|
|
54802
|
+
case 'TemplateLiteral':
|
|
54803
|
+
if (node.expressions.length)
|
|
54804
|
+
throw unsupported('template substitution');
|
|
54805
|
+
return node.quasis.map(quasi => quasi.value.cooked).join('');
|
|
54806
|
+
case 'UnaryExpression':
|
|
54807
|
+
if (node.operator !== '-')
|
|
54808
|
+
throw unsupported(`operator \`${node.operator}\``);
|
|
54809
|
+
return -asNumber(resolveNode(node.argument));
|
|
54810
|
+
case 'BinaryExpression': {
|
|
54811
|
+
const applyOperator = ARITHMETIC_OPERATORS[node.operator];
|
|
54812
|
+
if (!applyOperator)
|
|
54813
|
+
throw unsupported(`operator \`${node.operator}\``);
|
|
54814
|
+
return applyOperator(asOperand(resolveNode(node.left)), asOperand(resolveNode(node.right)));
|
|
54815
|
+
}
|
|
54816
|
+
case 'ArrayExpression':
|
|
54817
|
+
return node.elements.map(element => (element === null ? null : resolveNode(element)));
|
|
54818
|
+
case 'ObjectExpression':
|
|
54819
|
+
return node.properties.reduce((memo, property) => {
|
|
54820
|
+
if (property.type !== 'Property' || property.computed)
|
|
54821
|
+
throw unsupported('computed or spread property');
|
|
54822
|
+
const { key } = property;
|
|
54823
|
+
if (key.type !== 'Identifier' && key.type !== 'Literal')
|
|
54824
|
+
throw unsupported('property key');
|
|
54825
|
+
const name = key.type === 'Identifier' ? key.name : String(key.value);
|
|
54826
|
+
// `__proto__` would replace the object's prototype rather than add a property.
|
|
54827
|
+
if (name === '__proto__')
|
|
54828
|
+
throw unsupported('`__proto__` key');
|
|
54829
|
+
memo[name] = resolveNode(property.value);
|
|
54830
|
+
return memo;
|
|
54831
|
+
}, {});
|
|
54832
|
+
default:
|
|
54833
|
+
throw unsupported(node.type);
|
|
54834
|
+
}
|
|
54835
|
+
};
|
|
54836
|
+
/**
|
|
54837
|
+
* Resolve a JSX attribute expression's source to its value without executing it.
|
|
54838
|
+
*
|
|
54839
|
+
* Supports the literal syntax attributes actually use — `true`, `"a"`, `` `a` ``,
|
|
54840
|
+
* `undefined`, `{ textAlign: "left" }`, `["left"]`, `1 + 1`, `'https://' + 'x.com'` —
|
|
54841
|
+
* and refuses everything else, so no identifier, member access, call, assignment or
|
|
54842
|
+
* function body can ever run. The trade-off is that expressions needing a scope or a
|
|
54843
|
+
* method call (`{item.url}`, `{"a".toUpperCase()}`) throw, and callers keep the raw
|
|
54844
|
+
* source instead — the same fallback they already used for an expression that threw.
|
|
54845
|
+
* mdxish rendering is unaffected, since it resolves those later with its scoped
|
|
54846
|
+
* evaluator; only consumers reading attributes straight off the tree see the source.
|
|
54847
|
+
*
|
|
54848
|
+
* @param source expression body, without the surrounding braces
|
|
54849
|
+
* @throws if `source` is unparseable or isn't a supported literal expression
|
|
54850
|
+
*/
|
|
54851
|
+
const evaluateLiteralExpression = (source) => {
|
|
54852
|
+
const expression = jsxAcornParser.parseExpressionAt(source, 0, { ecmaVersion: 'latest' });
|
|
54853
|
+
// acorn stops at the first complete expression, so anything trailing means this isn't one.
|
|
54854
|
+
if (expression.end !== source.trimEnd().length)
|
|
54855
|
+
throw unsupported('trailing content');
|
|
54856
|
+
return resolveNode(expression);
|
|
54857
|
+
};
|
|
54858
|
+
|
|
54768
54859
|
;// ./processor/utils.ts
|
|
54769
54860
|
|
|
54770
54861
|
|
|
54771
54862
|
|
|
54772
54863
|
|
|
54773
54864
|
|
|
54865
|
+
|
|
54774
54866
|
/**
|
|
54775
54867
|
* Evaluate a JavaScript expression source and return its value.
|
|
54776
54868
|
*
|
|
@@ -54868,8 +54960,10 @@ const getAttrs = (jsx) => jsx.attributes.reduce((memo, attr) => {
|
|
|
54868
54960
|
memo[attr.name] = decode_decodeHTMLStrict(attr.value);
|
|
54869
54961
|
}
|
|
54870
54962
|
else if (attr.value?.value !== undefined) {
|
|
54963
|
+
// Expression values only survive to here when safeMode is off; `flattenAttributeExpressions`
|
|
54964
|
+
// rewrites them to plain strings at the head of the pipeline otherwise.
|
|
54871
54965
|
try {
|
|
54872
|
-
memo[attr.name] =
|
|
54966
|
+
memo[attr.name] = evaluateLiteralExpression(attr.value.value);
|
|
54873
54967
|
}
|
|
54874
54968
|
catch {
|
|
54875
54969
|
memo[attr.name] = attr.value.value;
|
|
@@ -55650,6 +55744,31 @@ const embedTransformer = () => {
|
|
|
55650
55744
|
};
|
|
55651
55745
|
/* harmony default export */ const transform_embeds = (embedTransformer);
|
|
55652
55746
|
|
|
55747
|
+
;// ./processor/transform/flatten-attribute-expressions.ts
|
|
55748
|
+
|
|
55749
|
+
|
|
55750
|
+
/**
|
|
55751
|
+
* Rewrites JSX attribute expressions (`icon={String(1 + 3)}`) into plain string attributes
|
|
55752
|
+
* holding their literal source, so nothing downstream can evaluate them.
|
|
55753
|
+
*
|
|
55754
|
+
* This is the RMDX counterpart to mdxish's `preserveExpressionsAsText` parse option: safeMode's
|
|
55755
|
+
* contract is enforced once, at the head of the pipeline, rather than at every `getAttrs()` call
|
|
55756
|
+
* site. Only registered when safeMode is on.
|
|
55757
|
+
*/
|
|
55758
|
+
const flattenAttributeExpressions = () => tree => {
|
|
55759
|
+
visit(tree, isMDXElement, (node) => {
|
|
55760
|
+
node.attributes.forEach(attr => {
|
|
55761
|
+
if (!('name' in attr))
|
|
55762
|
+
return;
|
|
55763
|
+
if (attr.value === null || typeof attr.value === 'string')
|
|
55764
|
+
return;
|
|
55765
|
+
attr.value = attr.value.value;
|
|
55766
|
+
});
|
|
55767
|
+
});
|
|
55768
|
+
return tree;
|
|
55769
|
+
};
|
|
55770
|
+
/* harmony default export */ const flatten_attribute_expressions = (flattenAttributeExpressions);
|
|
55771
|
+
|
|
55653
55772
|
;// ./node_modules/gemoji/index.js
|
|
55654
55773
|
/**
|
|
55655
55774
|
* @typedef Gemoji
|
|
@@ -81419,6 +81538,7 @@ const variables = ({ asMdx } = { asMdx: true }) => tree => {
|
|
|
81419
81538
|
|
|
81420
81539
|
|
|
81421
81540
|
|
|
81541
|
+
|
|
81422
81542
|
const defaultTransforms = {
|
|
81423
81543
|
calloutTransformer: callouts,
|
|
81424
81544
|
codeTabsTransformer: code_tabs,
|
|
@@ -81446,6 +81566,9 @@ const astProcessor = (opts = {}) => {
|
|
|
81446
81566
|
const components = opts.components || {};
|
|
81447
81567
|
let processor = remark()
|
|
81448
81568
|
.use(remarkMdx)
|
|
81569
|
+
// Must precede every other transformer: it strips evaluable attribute expressions so no
|
|
81570
|
+
// downstream `getAttrs()` call can reach `evaluate()`.
|
|
81571
|
+
.use(opts.safeMode ? flatten_attribute_expressions : undefined)
|
|
81449
81572
|
.use(remarkPlugins)
|
|
81450
81573
|
.use(opts.remarkPlugins)
|
|
81451
81574
|
.use(transform_variables, { asMdx: false })
|
|
@@ -96025,12 +96148,59 @@ const hastscript_lib_h = create_h_createH(node_modules_property_information_html
|
|
|
96025
96148
|
/** @type {ReturnType<createH>} */
|
|
96026
96149
|
const lib_s = create_h_createH(node_modules_property_information_svg, 'g', svg_case_sensitive_tag_names_svgCaseSensitiveTagNames)
|
|
96027
96150
|
|
|
96151
|
+
;// ./utils/user.ts
|
|
96152
|
+
/**
|
|
96153
|
+
* Coerce a user variable value to a string for substitution into markdown text.
|
|
96154
|
+
* Non-string values (arrays, objects, numbers) are stringified via JSON or `String()`
|
|
96155
|
+
* so that `<<var>>` syntax doesn't produce `[object Object]` for structured data like
|
|
96156
|
+
* JWT `keys`.
|
|
96157
|
+
*/
|
|
96158
|
+
const stringifyVariableValue = (value) => {
|
|
96159
|
+
if (typeof value === 'string')
|
|
96160
|
+
return value;
|
|
96161
|
+
if (value == null)
|
|
96162
|
+
return '';
|
|
96163
|
+
if (typeof value === 'object') {
|
|
96164
|
+
try {
|
|
96165
|
+
return JSON.stringify(value) ?? '';
|
|
96166
|
+
}
|
|
96167
|
+
catch {
|
|
96168
|
+
console.warn('[WARNING] Could not stringify a structured user variable.');
|
|
96169
|
+
return '';
|
|
96170
|
+
}
|
|
96171
|
+
}
|
|
96172
|
+
return String(value);
|
|
96173
|
+
};
|
|
96174
|
+
/**
|
|
96175
|
+
* Flatten `variables.user` into a string-keyed string-valued record by coercing
|
|
96176
|
+
* each value. Used by markdown substitution paths that need a plain
|
|
96177
|
+
* `Record<string, string>` lookup.
|
|
96178
|
+
*/
|
|
96179
|
+
const flattenUserVariables = (user) => Object.fromEntries(Object.entries(user).map(([name, value]) => [name, stringifyVariableValue(value)]));
|
|
96180
|
+
const User = (variables) => {
|
|
96181
|
+
const { user = {}, defaults = [] } = variables || {};
|
|
96182
|
+
return new Proxy(user, {
|
|
96183
|
+
get(target, attribute) {
|
|
96184
|
+
if (typeof attribute === 'symbol') {
|
|
96185
|
+
return '';
|
|
96186
|
+
}
|
|
96187
|
+
if (attribute in target) {
|
|
96188
|
+
return target[attribute];
|
|
96189
|
+
}
|
|
96190
|
+
const def = defaults.find((d) => d.name === attribute);
|
|
96191
|
+
return def ? def.default : attribute.toUpperCase();
|
|
96192
|
+
},
|
|
96193
|
+
});
|
|
96194
|
+
};
|
|
96195
|
+
/* harmony default export */ const user = (User);
|
|
96196
|
+
|
|
96028
96197
|
;// ./processor/plugin/toc.ts
|
|
96029
96198
|
|
|
96030
96199
|
|
|
96031
96200
|
|
|
96032
96201
|
|
|
96033
96202
|
|
|
96203
|
+
|
|
96034
96204
|
const HEADING_TAGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
|
96035
96205
|
const isHeadingTag = (tag) => (tag ? HEADING_TAGS.includes(tag) : false);
|
|
96036
96206
|
const isStandardHtmlElement = (node) => STANDARD_HTML_TAGS.has(node.tagName.toLowerCase());
|
|
@@ -96142,7 +96312,7 @@ const flattenVariables = (variables) => {
|
|
|
96142
96312
|
if (!variables)
|
|
96143
96313
|
return {};
|
|
96144
96314
|
return {
|
|
96145
|
-
...variables.user,
|
|
96315
|
+
...flattenUserVariables(variables.user),
|
|
96146
96316
|
...Object.fromEntries((variables.defaults || []).filter(d => !(d.name in variables.user)).map(d => [d.name, d.default])),
|
|
96147
96317
|
};
|
|
96148
96318
|
};
|
|
@@ -96290,7 +96460,7 @@ const exports_exports = (doc) => {
|
|
|
96290
96460
|
|
|
96291
96461
|
const hast = (text, opts = {}) => {
|
|
96292
96462
|
const components = Object.entries(opts.components || {}).reduce((memo, [name, doc]) => {
|
|
96293
|
-
memo[name] = lib_mdast(doc);
|
|
96463
|
+
memo[name] = lib_mdast(doc, { safeMode: opts.safeMode });
|
|
96294
96464
|
return memo;
|
|
96295
96465
|
}, {});
|
|
96296
96466
|
const processor = ast_processor(opts)
|
|
@@ -106926,6 +107096,7 @@ function normalizeTableSeparator(content) {
|
|
|
106926
107096
|
;// ./processor/transform/mdxish/variables-code.ts
|
|
106927
107097
|
|
|
106928
107098
|
|
|
107099
|
+
|
|
106929
107100
|
// Single combined regex so that resolved values from one pattern are never re-scanned by the other.
|
|
106930
107101
|
const COMBINED_VARIABLE_REGEX = new RegExp(`${variable_.VARIABLE_REGEXP}|${variable_.MDX_VARIABLE_REGEXP}`, 'giu');
|
|
106931
107102
|
// Flatten variables into a single object for easy lookup
|
|
@@ -106934,7 +107105,7 @@ function variables_code_flattenVariables(variables) {
|
|
|
106934
107105
|
return {};
|
|
106935
107106
|
return {
|
|
106936
107107
|
...Object.fromEntries((variables.defaults || []).map(d => [d.name, d.default])),
|
|
106937
|
-
...variables.user,
|
|
107108
|
+
...flattenUserVariables(variables.user),
|
|
106938
107109
|
};
|
|
106939
107110
|
}
|
|
106940
107111
|
function resolveCodeVariables(value, resolvedVariables) {
|
|
@@ -107478,24 +107649,6 @@ const Contexts = ({ children, terms = [], variables = { user: {}, defaults: [] }
|
|
|
107478
107649
|
};
|
|
107479
107650
|
/* harmony default export */ const contexts = (Contexts);
|
|
107480
107651
|
|
|
107481
|
-
;// ./utils/user.ts
|
|
107482
|
-
const User = (variables) => {
|
|
107483
|
-
const { user = {}, defaults = [] } = variables || {};
|
|
107484
|
-
return new Proxy(user, {
|
|
107485
|
-
get(target, attribute) {
|
|
107486
|
-
if (typeof attribute === 'symbol') {
|
|
107487
|
-
return '';
|
|
107488
|
-
}
|
|
107489
|
-
if (attribute in target) {
|
|
107490
|
-
return target[attribute];
|
|
107491
|
-
}
|
|
107492
|
-
const def = defaults.find((d) => d.name === attribute);
|
|
107493
|
-
return def ? def.default : attribute.toUpperCase();
|
|
107494
|
-
},
|
|
107495
|
-
});
|
|
107496
|
-
};
|
|
107497
|
-
/* harmony default export */ const user = (User);
|
|
107498
|
-
|
|
107499
107652
|
;// ./lib/utils/makeUseMdxComponents.ts
|
|
107500
107653
|
|
|
107501
107654
|
|
|
@@ -107528,6 +107681,7 @@ const makeUseMDXComponents = (more = {}) => {
|
|
|
107528
107681
|
|
|
107529
107682
|
;// ./lib/utils/mdxish/mdxish-variables.ts
|
|
107530
107683
|
|
|
107684
|
+
|
|
107531
107685
|
// The `$` guard skips template-literal interpolation: `${user.name}` embeds `{user.name}`, and
|
|
107532
107686
|
// substituting it would leave a mangled `` `Hi $Name` `` behind. Those belong to an expression,
|
|
107533
107687
|
// which either evaluated already or is meant to stay literal.
|
|
@@ -107551,7 +107705,7 @@ function resolveAttributeVariables(value, user) {
|
|
|
107551
107705
|
.replace(MDX_VARIABLE_REGEX, (source, escapePrefix, name, escapeSuffix) => {
|
|
107552
107706
|
if (escapePrefix || escapeSuffix)
|
|
107553
107707
|
return source;
|
|
107554
|
-
return user[name];
|
|
107708
|
+
return stringifyVariableValue(user[name]);
|
|
107555
107709
|
});
|
|
107556
107710
|
}
|
|
107557
107711
|
|
|
@@ -107827,7 +107981,8 @@ const run_run = (string, _opts = {}) => {
|
|
|
107827
107981
|
|
|
107828
107982
|
const tags = (doc) => {
|
|
107829
107983
|
const set = new Set();
|
|
107830
|
-
|
|
107984
|
+
// Tag names never depend on evaluated attribute values, so always parse in safeMode.
|
|
107985
|
+
visit(lib_mdast(doc, { safeMode: true }), isMDXElement, (node) => {
|
|
107831
107986
|
if (node.name?.match(/^[A-Z]/)) {
|
|
107832
107987
|
set.add(node.name);
|
|
107833
107988
|
}
|
|
@@ -107843,13 +107998,14 @@ const tags = (doc) => {
|
|
|
107843
107998
|
|
|
107844
107999
|
|
|
107845
108000
|
|
|
107846
|
-
const { micromarkExtensions, fromMarkdownExtensions } = mdxishExtensions(FEATURES.tags);
|
|
108001
|
+
const { micromarkExtensions, fromMarkdownExtensions } = mdxishExtensions(FEATURES.tags, { safeMode: true });
|
|
107847
108002
|
const mdxishTags_tags = (doc) => {
|
|
107848
108003
|
const set = new Set();
|
|
107849
108004
|
const processor = remark()
|
|
107850
108005
|
.data('micromarkExtensions', micromarkExtensions)
|
|
107851
108006
|
.data('fromMarkdownExtensions', fromMarkdownExtensions)
|
|
107852
|
-
.
|
|
108007
|
+
// Tag names never depend on evaluated attribute values, so always parse in safeMode.
|
|
108008
|
+
.use(mdx_blocks, { safeMode: true })
|
|
107853
108009
|
.use(mdxish_tables);
|
|
107854
108010
|
const tree = processor.parse(doc);
|
|
107855
108011
|
visit(processor.runSync(tree), isMDXElement, (node) => {
|
package/dist/main.node.js
CHANGED
|
@@ -74989,12 +74989,104 @@ const mdast = (text, opts = {}) => {
|
|
|
74989
74989
|
*/
|
|
74990
74990
|
const jsxAcornParser = Parser.extend(acorn_jsx_default()());
|
|
74991
74991
|
|
|
74992
|
+
;// ./lib/utils/literal-expression.ts
|
|
74993
|
+
|
|
74994
|
+
const unsupported = (description) => new Error(`not a literal expression: ${description}`);
|
|
74995
|
+
/** Narrows a resolved value for arithmetic, so operands never coerce to `NaN` or `"[object Object]"`. */
|
|
74996
|
+
const asNumber = (value) => {
|
|
74997
|
+
if (typeof value !== 'number')
|
|
74998
|
+
throw unsupported('non-numeric operand');
|
|
74999
|
+
return value;
|
|
75000
|
+
};
|
|
75001
|
+
const asOperand = (value) => {
|
|
75002
|
+
if (typeof value !== 'number' && typeof value !== 'string')
|
|
75003
|
+
throw unsupported('non-primitive operand');
|
|
75004
|
+
return value;
|
|
75005
|
+
};
|
|
75006
|
+
const ARITHMETIC_OPERATORS = {
|
|
75007
|
+
// `+` doubles as string concatenation, so it accepts a string on either side.
|
|
75008
|
+
'+': (left, right) => (typeof left === 'number' && typeof right === 'number' ? left + right : `${left}${right}`),
|
|
75009
|
+
'-': (left, right) => asNumber(left) - asNumber(right),
|
|
75010
|
+
'*': (left, right) => asNumber(left) * asNumber(right),
|
|
75011
|
+
'/': (left, right) => asNumber(left) / asNumber(right),
|
|
75012
|
+
};
|
|
75013
|
+
/** Resolve one estree node, recursing into arrays and objects. Throws for anything not on the allowlist. */
|
|
75014
|
+
const resolveNode = (node) => {
|
|
75015
|
+
switch (node.type) {
|
|
75016
|
+
case 'Literal':
|
|
75017
|
+
// Regex and bigint `Literal`s hold values a tree consumer can't serialise;
|
|
75018
|
+
// a BigInt throws outright in `JSON.stringify`.
|
|
75019
|
+
if ('regex' in node || 'bigint' in node)
|
|
75020
|
+
throw unsupported('regex or bigint literal');
|
|
75021
|
+
return node.value;
|
|
75022
|
+
case 'Identifier':
|
|
75023
|
+
if (node.name !== 'undefined')
|
|
75024
|
+
throw unsupported(`identifier \`${node.name}\``);
|
|
75025
|
+
return undefined;
|
|
75026
|
+
case 'TemplateLiteral':
|
|
75027
|
+
if (node.expressions.length)
|
|
75028
|
+
throw unsupported('template substitution');
|
|
75029
|
+
return node.quasis.map(quasi => quasi.value.cooked).join('');
|
|
75030
|
+
case 'UnaryExpression':
|
|
75031
|
+
if (node.operator !== '-')
|
|
75032
|
+
throw unsupported(`operator \`${node.operator}\``);
|
|
75033
|
+
return -asNumber(resolveNode(node.argument));
|
|
75034
|
+
case 'BinaryExpression': {
|
|
75035
|
+
const applyOperator = ARITHMETIC_OPERATORS[node.operator];
|
|
75036
|
+
if (!applyOperator)
|
|
75037
|
+
throw unsupported(`operator \`${node.operator}\``);
|
|
75038
|
+
return applyOperator(asOperand(resolveNode(node.left)), asOperand(resolveNode(node.right)));
|
|
75039
|
+
}
|
|
75040
|
+
case 'ArrayExpression':
|
|
75041
|
+
return node.elements.map(element => (element === null ? null : resolveNode(element)));
|
|
75042
|
+
case 'ObjectExpression':
|
|
75043
|
+
return node.properties.reduce((memo, property) => {
|
|
75044
|
+
if (property.type !== 'Property' || property.computed)
|
|
75045
|
+
throw unsupported('computed or spread property');
|
|
75046
|
+
const { key } = property;
|
|
75047
|
+
if (key.type !== 'Identifier' && key.type !== 'Literal')
|
|
75048
|
+
throw unsupported('property key');
|
|
75049
|
+
const name = key.type === 'Identifier' ? key.name : String(key.value);
|
|
75050
|
+
// `__proto__` would replace the object's prototype rather than add a property.
|
|
75051
|
+
if (name === '__proto__')
|
|
75052
|
+
throw unsupported('`__proto__` key');
|
|
75053
|
+
memo[name] = resolveNode(property.value);
|
|
75054
|
+
return memo;
|
|
75055
|
+
}, {});
|
|
75056
|
+
default:
|
|
75057
|
+
throw unsupported(node.type);
|
|
75058
|
+
}
|
|
75059
|
+
};
|
|
75060
|
+
/**
|
|
75061
|
+
* Resolve a JSX attribute expression's source to its value without executing it.
|
|
75062
|
+
*
|
|
75063
|
+
* Supports the literal syntax attributes actually use — `true`, `"a"`, `` `a` ``,
|
|
75064
|
+
* `undefined`, `{ textAlign: "left" }`, `["left"]`, `1 + 1`, `'https://' + 'x.com'` —
|
|
75065
|
+
* and refuses everything else, so no identifier, member access, call, assignment or
|
|
75066
|
+
* function body can ever run. The trade-off is that expressions needing a scope or a
|
|
75067
|
+
* method call (`{item.url}`, `{"a".toUpperCase()}`) throw, and callers keep the raw
|
|
75068
|
+
* source instead — the same fallback they already used for an expression that threw.
|
|
75069
|
+
* mdxish rendering is unaffected, since it resolves those later with its scoped
|
|
75070
|
+
* evaluator; only consumers reading attributes straight off the tree see the source.
|
|
75071
|
+
*
|
|
75072
|
+
* @param source expression body, without the surrounding braces
|
|
75073
|
+
* @throws if `source` is unparseable or isn't a supported literal expression
|
|
75074
|
+
*/
|
|
75075
|
+
const evaluateLiteralExpression = (source) => {
|
|
75076
|
+
const expression = jsxAcornParser.parseExpressionAt(source, 0, { ecmaVersion: 'latest' });
|
|
75077
|
+
// acorn stops at the first complete expression, so anything trailing means this isn't one.
|
|
75078
|
+
if (expression.end !== source.trimEnd().length)
|
|
75079
|
+
throw unsupported('trailing content');
|
|
75080
|
+
return resolveNode(expression);
|
|
75081
|
+
};
|
|
75082
|
+
|
|
74992
75083
|
;// ./processor/utils.ts
|
|
74993
75084
|
|
|
74994
75085
|
|
|
74995
75086
|
|
|
74996
75087
|
|
|
74997
75088
|
|
|
75089
|
+
|
|
74998
75090
|
/**
|
|
74999
75091
|
* Evaluate a JavaScript expression source and return its value.
|
|
75000
75092
|
*
|
|
@@ -75092,8 +75184,10 @@ const getAttrs = (jsx) => jsx.attributes.reduce((memo, attr) => {
|
|
|
75092
75184
|
memo[attr.name] = decode_decodeHTMLStrict(attr.value);
|
|
75093
75185
|
}
|
|
75094
75186
|
else if (attr.value?.value !== undefined) {
|
|
75187
|
+
// Expression values only survive to here when safeMode is off; `flattenAttributeExpressions`
|
|
75188
|
+
// rewrites them to plain strings at the head of the pipeline otherwise.
|
|
75095
75189
|
try {
|
|
75096
|
-
memo[attr.name] =
|
|
75190
|
+
memo[attr.name] = evaluateLiteralExpression(attr.value.value);
|
|
75097
75191
|
}
|
|
75098
75192
|
catch {
|
|
75099
75193
|
memo[attr.name] = attr.value.value;
|
|
@@ -75874,6 +75968,31 @@ const embedTransformer = () => {
|
|
|
75874
75968
|
};
|
|
75875
75969
|
/* harmony default export */ const transform_embeds = (embedTransformer);
|
|
75876
75970
|
|
|
75971
|
+
;// ./processor/transform/flatten-attribute-expressions.ts
|
|
75972
|
+
|
|
75973
|
+
|
|
75974
|
+
/**
|
|
75975
|
+
* Rewrites JSX attribute expressions (`icon={String(1 + 3)}`) into plain string attributes
|
|
75976
|
+
* holding their literal source, so nothing downstream can evaluate them.
|
|
75977
|
+
*
|
|
75978
|
+
* This is the RMDX counterpart to mdxish's `preserveExpressionsAsText` parse option: safeMode's
|
|
75979
|
+
* contract is enforced once, at the head of the pipeline, rather than at every `getAttrs()` call
|
|
75980
|
+
* site. Only registered when safeMode is on.
|
|
75981
|
+
*/
|
|
75982
|
+
const flattenAttributeExpressions = () => tree => {
|
|
75983
|
+
visit(tree, isMDXElement, (node) => {
|
|
75984
|
+
node.attributes.forEach(attr => {
|
|
75985
|
+
if (!('name' in attr))
|
|
75986
|
+
return;
|
|
75987
|
+
if (attr.value === null || typeof attr.value === 'string')
|
|
75988
|
+
return;
|
|
75989
|
+
attr.value = attr.value.value;
|
|
75990
|
+
});
|
|
75991
|
+
});
|
|
75992
|
+
return tree;
|
|
75993
|
+
};
|
|
75994
|
+
/* harmony default export */ const flatten_attribute_expressions = (flattenAttributeExpressions);
|
|
75995
|
+
|
|
75877
75996
|
;// ./node_modules/gemoji/index.js
|
|
75878
75997
|
/**
|
|
75879
75998
|
* @typedef Gemoji
|
|
@@ -101643,6 +101762,7 @@ const variables = ({ asMdx } = { asMdx: true }) => tree => {
|
|
|
101643
101762
|
|
|
101644
101763
|
|
|
101645
101764
|
|
|
101765
|
+
|
|
101646
101766
|
const defaultTransforms = {
|
|
101647
101767
|
calloutTransformer: callouts,
|
|
101648
101768
|
codeTabsTransformer: code_tabs,
|
|
@@ -101670,6 +101790,9 @@ const astProcessor = (opts = {}) => {
|
|
|
101670
101790
|
const components = opts.components || {};
|
|
101671
101791
|
let processor = remark()
|
|
101672
101792
|
.use(remarkMdx)
|
|
101793
|
+
// Must precede every other transformer: it strips evaluable attribute expressions so no
|
|
101794
|
+
// downstream `getAttrs()` call can reach `evaluate()`.
|
|
101795
|
+
.use(opts.safeMode ? flatten_attribute_expressions : undefined)
|
|
101673
101796
|
.use(remarkPlugins)
|
|
101674
101797
|
.use(opts.remarkPlugins)
|
|
101675
101798
|
.use(transform_variables, { asMdx: false })
|
|
@@ -116249,12 +116372,59 @@ const hastscript_lib_h = create_h_createH(node_modules_property_information_html
|
|
|
116249
116372
|
/** @type {ReturnType<createH>} */
|
|
116250
116373
|
const lib_s = create_h_createH(node_modules_property_information_svg, 'g', svg_case_sensitive_tag_names_svgCaseSensitiveTagNames)
|
|
116251
116374
|
|
|
116375
|
+
;// ./utils/user.ts
|
|
116376
|
+
/**
|
|
116377
|
+
* Coerce a user variable value to a string for substitution into markdown text.
|
|
116378
|
+
* Non-string values (arrays, objects, numbers) are stringified via JSON or `String()`
|
|
116379
|
+
* so that `<<var>>` syntax doesn't produce `[object Object]` for structured data like
|
|
116380
|
+
* JWT `keys`.
|
|
116381
|
+
*/
|
|
116382
|
+
const stringifyVariableValue = (value) => {
|
|
116383
|
+
if (typeof value === 'string')
|
|
116384
|
+
return value;
|
|
116385
|
+
if (value == null)
|
|
116386
|
+
return '';
|
|
116387
|
+
if (typeof value === 'object') {
|
|
116388
|
+
try {
|
|
116389
|
+
return JSON.stringify(value) ?? '';
|
|
116390
|
+
}
|
|
116391
|
+
catch {
|
|
116392
|
+
console.warn('[WARNING] Could not stringify a structured user variable.');
|
|
116393
|
+
return '';
|
|
116394
|
+
}
|
|
116395
|
+
}
|
|
116396
|
+
return String(value);
|
|
116397
|
+
};
|
|
116398
|
+
/**
|
|
116399
|
+
* Flatten `variables.user` into a string-keyed string-valued record by coercing
|
|
116400
|
+
* each value. Used by markdown substitution paths that need a plain
|
|
116401
|
+
* `Record<string, string>` lookup.
|
|
116402
|
+
*/
|
|
116403
|
+
const flattenUserVariables = (user) => Object.fromEntries(Object.entries(user).map(([name, value]) => [name, stringifyVariableValue(value)]));
|
|
116404
|
+
const User = (variables) => {
|
|
116405
|
+
const { user = {}, defaults = [] } = variables || {};
|
|
116406
|
+
return new Proxy(user, {
|
|
116407
|
+
get(target, attribute) {
|
|
116408
|
+
if (typeof attribute === 'symbol') {
|
|
116409
|
+
return '';
|
|
116410
|
+
}
|
|
116411
|
+
if (attribute in target) {
|
|
116412
|
+
return target[attribute];
|
|
116413
|
+
}
|
|
116414
|
+
const def = defaults.find((d) => d.name === attribute);
|
|
116415
|
+
return def ? def.default : attribute.toUpperCase();
|
|
116416
|
+
},
|
|
116417
|
+
});
|
|
116418
|
+
};
|
|
116419
|
+
/* harmony default export */ const user = (User);
|
|
116420
|
+
|
|
116252
116421
|
;// ./processor/plugin/toc.ts
|
|
116253
116422
|
|
|
116254
116423
|
|
|
116255
116424
|
|
|
116256
116425
|
|
|
116257
116426
|
|
|
116427
|
+
|
|
116258
116428
|
const HEADING_TAGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
|
116259
116429
|
const isHeadingTag = (tag) => (tag ? HEADING_TAGS.includes(tag) : false);
|
|
116260
116430
|
const isStandardHtmlElement = (node) => STANDARD_HTML_TAGS.has(node.tagName.toLowerCase());
|
|
@@ -116366,7 +116536,7 @@ const flattenVariables = (variables) => {
|
|
|
116366
116536
|
if (!variables)
|
|
116367
116537
|
return {};
|
|
116368
116538
|
return {
|
|
116369
|
-
...variables.user,
|
|
116539
|
+
...flattenUserVariables(variables.user),
|
|
116370
116540
|
...Object.fromEntries((variables.defaults || []).filter(d => !(d.name in variables.user)).map(d => [d.name, d.default])),
|
|
116371
116541
|
};
|
|
116372
116542
|
};
|
|
@@ -116514,7 +116684,7 @@ const exports_exports = (doc) => {
|
|
|
116514
116684
|
|
|
116515
116685
|
const hast = (text, opts = {}) => {
|
|
116516
116686
|
const components = Object.entries(opts.components || {}).reduce((memo, [name, doc]) => {
|
|
116517
|
-
memo[name] = lib_mdast(doc);
|
|
116687
|
+
memo[name] = lib_mdast(doc, { safeMode: opts.safeMode });
|
|
116518
116688
|
return memo;
|
|
116519
116689
|
}, {});
|
|
116520
116690
|
const processor = ast_processor(opts)
|
|
@@ -127150,6 +127320,7 @@ function normalizeTableSeparator(content) {
|
|
|
127150
127320
|
;// ./processor/transform/mdxish/variables-code.ts
|
|
127151
127321
|
|
|
127152
127322
|
|
|
127323
|
+
|
|
127153
127324
|
// Single combined regex so that resolved values from one pattern are never re-scanned by the other.
|
|
127154
127325
|
const COMBINED_VARIABLE_REGEX = new RegExp(`${variable_dist.VARIABLE_REGEXP}|${variable_dist.MDX_VARIABLE_REGEXP}`, 'giu');
|
|
127155
127326
|
// Flatten variables into a single object for easy lookup
|
|
@@ -127158,7 +127329,7 @@ function variables_code_flattenVariables(variables) {
|
|
|
127158
127329
|
return {};
|
|
127159
127330
|
return {
|
|
127160
127331
|
...Object.fromEntries((variables.defaults || []).map(d => [d.name, d.default])),
|
|
127161
|
-
...variables.user,
|
|
127332
|
+
...flattenUserVariables(variables.user),
|
|
127162
127333
|
};
|
|
127163
127334
|
}
|
|
127164
127335
|
function resolveCodeVariables(value, resolvedVariables) {
|
|
@@ -127702,24 +127873,6 @@ const Contexts = ({ children, terms = [], variables = { user: {}, defaults: [] }
|
|
|
127702
127873
|
};
|
|
127703
127874
|
/* harmony default export */ const contexts = (Contexts);
|
|
127704
127875
|
|
|
127705
|
-
;// ./utils/user.ts
|
|
127706
|
-
const User = (variables) => {
|
|
127707
|
-
const { user = {}, defaults = [] } = variables || {};
|
|
127708
|
-
return new Proxy(user, {
|
|
127709
|
-
get(target, attribute) {
|
|
127710
|
-
if (typeof attribute === 'symbol') {
|
|
127711
|
-
return '';
|
|
127712
|
-
}
|
|
127713
|
-
if (attribute in target) {
|
|
127714
|
-
return target[attribute];
|
|
127715
|
-
}
|
|
127716
|
-
const def = defaults.find((d) => d.name === attribute);
|
|
127717
|
-
return def ? def.default : attribute.toUpperCase();
|
|
127718
|
-
},
|
|
127719
|
-
});
|
|
127720
|
-
};
|
|
127721
|
-
/* harmony default export */ const user = (User);
|
|
127722
|
-
|
|
127723
127876
|
;// ./lib/utils/makeUseMdxComponents.ts
|
|
127724
127877
|
|
|
127725
127878
|
|
|
@@ -127752,6 +127905,7 @@ const makeUseMDXComponents = (more = {}) => {
|
|
|
127752
127905
|
|
|
127753
127906
|
;// ./lib/utils/mdxish/mdxish-variables.ts
|
|
127754
127907
|
|
|
127908
|
+
|
|
127755
127909
|
// The `$` guard skips template-literal interpolation: `${user.name}` embeds `{user.name}`, and
|
|
127756
127910
|
// substituting it would leave a mangled `` `Hi $Name` `` behind. Those belong to an expression,
|
|
127757
127911
|
// which either evaluated already or is meant to stay literal.
|
|
@@ -127775,7 +127929,7 @@ function resolveAttributeVariables(value, user) {
|
|
|
127775
127929
|
.replace(MDX_VARIABLE_REGEX, (source, escapePrefix, name, escapeSuffix) => {
|
|
127776
127930
|
if (escapePrefix || escapeSuffix)
|
|
127777
127931
|
return source;
|
|
127778
|
-
return user[name];
|
|
127932
|
+
return stringifyVariableValue(user[name]);
|
|
127779
127933
|
});
|
|
127780
127934
|
}
|
|
127781
127935
|
|
|
@@ -128051,7 +128205,8 @@ const run_run = (string, _opts = {}) => {
|
|
|
128051
128205
|
|
|
128052
128206
|
const tags = (doc) => {
|
|
128053
128207
|
const set = new Set();
|
|
128054
|
-
|
|
128208
|
+
// Tag names never depend on evaluated attribute values, so always parse in safeMode.
|
|
128209
|
+
visit(lib_mdast(doc, { safeMode: true }), isMDXElement, (node) => {
|
|
128055
128210
|
if (node.name?.match(/^[A-Z]/)) {
|
|
128056
128211
|
set.add(node.name);
|
|
128057
128212
|
}
|
|
@@ -128067,13 +128222,14 @@ const tags = (doc) => {
|
|
|
128067
128222
|
|
|
128068
128223
|
|
|
128069
128224
|
|
|
128070
|
-
const { micromarkExtensions, fromMarkdownExtensions } = mdxishExtensions(FEATURES.tags);
|
|
128225
|
+
const { micromarkExtensions, fromMarkdownExtensions } = mdxishExtensions(FEATURES.tags, { safeMode: true });
|
|
128071
128226
|
const mdxishTags_tags = (doc) => {
|
|
128072
128227
|
const set = new Set();
|
|
128073
128228
|
const processor = remark()
|
|
128074
128229
|
.data('micromarkExtensions', micromarkExtensions)
|
|
128075
128230
|
.data('fromMarkdownExtensions', fromMarkdownExtensions)
|
|
128076
|
-
.
|
|
128231
|
+
// Tag names never depend on evaluated attribute values, so always parse in safeMode.
|
|
128232
|
+
.use(mdx_blocks, { safeMode: true })
|
|
128077
128233
|
.use(mdxish_tables);
|
|
128078
128234
|
const tree = processor.parse(doc);
|
|
128079
128235
|
visit(processor.runSync(tree), isMDXElement, (node) => {
|