diff --git a/packages/snaps-rpc-methods/scripts/generate-schema.mts b/packages/snaps-rpc-methods/scripts/generate-schema.mts
index 1ed18b5f2a..6da13fea5c 100644
--- a/packages/snaps-rpc-methods/scripts/generate-schema.mts
+++ b/packages/snaps-rpc-methods/scripts/generate-schema.mts
@@ -31,9 +31,12 @@ const NULLABLE_TYPES = ['null', 'undefined', 'void', 'never'];
// property descriptions in JSDoc `@property` tags.
const PROPERTY_DESCRIPTION_REGEX = /^\s?-\s/u;
+// A regular expression to parse the optional title from example JSDoc tags.
+const EXAMPLE_TITLE_REGEX = /^(?:(?
.+)\n)?```/u;
+
// A regular expression to parse example content from JSDoc comments.
const EXAMPLE_JSDOC_REGEX =
- /^(?:(?.+)\n)?```(?\w+)\n(?[\s\S]+)```$/u;
+ /```(?\w+)(?: name="(?[^"]+)")?\n(?[\s\S]+?)```/gu;
// Mapping of file extensions to Prettier parsers, used to format example code
// in the JSDoc comments of the handlers.
@@ -81,8 +84,11 @@ type MethodParameter = {
*/
type MethodExample = {
title?: string;
- language: string;
- content: string;
+ examples: {
+ name?: string;
+ language: string;
+ content: string;
+ }[];
};
/**
@@ -713,36 +719,50 @@ async function parseJsDocExample(tag: JSDocTag): Promise {
}
// The example JSDoc tag is expected to be in this format:
- // ```
+ //
// @example [optional title]
- // ```[language]
+ // ```[language] name="[optional name]"
// example content
// ```
- const match = text.match(EXAMPLE_JSDOC_REGEX);
- if (!match) {
+ // ```[language] name="[optional name]"
+ // optional second example content
+ // ```
+ const matches = text.matchAll(EXAMPLE_JSDOC_REGEX);
+ const matchesArray = Array.from(matches);
+ if (matchesArray.length === 0) {
return null;
}
- const { title, language, content } = match.groups as {
- title?: string;
- language: string;
- content: string;
- };
+ const titleMatch = text.match(EXAMPLE_TITLE_REGEX);
+ const title = titleMatch?.groups?.title?.trim();
- // While examples should be formatted correctly in the JSDoc comments,
- // TypeScript does not preserve the formatting of the example content, so we
- // use Prettier to format the example content based on the specified language.
- const parser = PRETTIER_PARSER[language];
- if (!parser) {
- throw new Error(
- `Unable to format example with language "${language}" because there is no corresponding Prettier parser. Supported languages are: ${Object.keys(PRETTIER_PARSER).join(', ')}. To resolve this, either change the language of the example to a supported language or add a corresponding Prettier parser to the \`PRETTIER_PARSER\` mapping in the script.\n\nThis error occurred while parsing "${tag.getSourceFile().getFilePath()}" at line ${tag.getStartLineNumber()}.`,
- );
- }
+ const examples = matchesArray.map(async (match) => {
+ const { name, language, content } = match.groups as {
+ name?: string;
+ language: string;
+ content: string;
+ };
+
+ // While examples should be formatted correctly in the JSDoc comments,
+ // TypeScript does not preserve the formatting of the example content, so we
+ // use Prettier to format the example content based on the specified language.
+ const parser = PRETTIER_PARSER[language];
+ if (!parser) {
+ throw new Error(
+ `Unable to format example with language "${language}" because there is no corresponding Prettier parser. Supported languages are: ${Object.keys(PRETTIER_PARSER).join(', ')}. To resolve this, either change the language of the example to a supported language or add a corresponding Prettier parser to the \`PRETTIER_PARSER\` mapping in the script.\n\nThis error occurred while parsing "${tag.getSourceFile().getFilePath()}" at line ${tag.getStartLineNumber()}.`,
+ );
+ }
+
+ return {
+ name: name?.trim(),
+ language,
+ content: await format(content, { parser }),
+ };
+ });
return {
- title: title?.trim(),
- language,
- content: await format(content, { parser }),
+ title,
+ examples: await Promise.all(examples),
};
}