@metamask-previews/build-utils 3.0.4-preview-8bfa290fb → 4.0.0-preview-0a30e47

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +12 -4
  2. package/dist/index.d.ts +4 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +3 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/transforms/{remove-fenced-code.d.cts → remove-fenced-code.d.ts} +1 -1
  7. package/dist/transforms/remove-fenced-code.d.ts.map +1 -0
  8. package/dist/transforms/{remove-fenced-code.mjs → remove-fenced-code.js} +2 -2
  9. package/dist/transforms/remove-fenced-code.js.map +1 -0
  10. package/dist/transforms/{utils.d.cts → utils.d.ts} +2 -2
  11. package/dist/transforms/utils.d.ts.map +1 -0
  12. package/dist/transforms/{utils.mjs → utils.js} +1 -1
  13. package/dist/transforms/utils.js.map +1 -0
  14. package/package.json +12 -16
  15. package/dist/index.cjs +0 -8
  16. package/dist/index.cjs.map +0 -1
  17. package/dist/index.d.cts +0 -4
  18. package/dist/index.d.cts.map +0 -1
  19. package/dist/index.d.mts +0 -4
  20. package/dist/index.d.mts.map +0 -1
  21. package/dist/index.mjs +0 -3
  22. package/dist/index.mjs.map +0 -1
  23. package/dist/transforms/remove-fenced-code.cjs +0 -321
  24. package/dist/transforms/remove-fenced-code.cjs.map +0 -1
  25. package/dist/transforms/remove-fenced-code.d.cts.map +0 -1
  26. package/dist/transforms/remove-fenced-code.d.mts +0 -70
  27. package/dist/transforms/remove-fenced-code.d.mts.map +0 -1
  28. package/dist/transforms/remove-fenced-code.mjs.map +0 -1
  29. package/dist/transforms/utils.cjs +0 -48
  30. package/dist/transforms/utils.cjs.map +0 -1
  31. package/dist/transforms/utils.d.cts.map +0 -1
  32. package/dist/transforms/utils.d.mts +0 -25
  33. package/dist/transforms/utils.d.mts.map +0 -1
  34. package/dist/transforms/utils.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,8 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [4.0.0]
11
+
10
12
  ### Changed
11
13
 
14
+ - **BREAKING:** Drop CommonJS support ([#9536](https://github.com/MetaMask/core/pull/9536))
15
+ - This package is now ESM-only, but can still be used in CommonJS projects via `require(esm)` in modern Node.js versions (22+), or dynamic imports in older Node.js versions.
16
+ - **BREAKING:** Bump minimum Node.js version to 22 ([#9976](https://github.com/MetaMask/core/pull/9976))
17
+ - **BREAKING:** Bump TypeScript target to ES2022 ([#10019](https://github.com/MetaMask/core/pull/10019))
18
+ - This package now ships ES2022 code, requiring a compatible modern environment or bundler configuration to consume.
12
19
  - Bump `@metamask/utils` from `^11.8.1` to `^11.12.0` ([#7511](https://github.com/MetaMask/core/pull/7511), [#9074](https://github.com/MetaMask/core/pull/9074), [#10076](https://github.com/MetaMask/core/pull/10076))
13
20
 
14
21
  ## [3.0.4]
@@ -21,7 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
21
28
 
22
29
  ### Changed
23
30
 
24
- - Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080)), ([#5223](https://github.com/MetaMask/core/pull/5223))
31
+ - Bump `@metamask/utils` from `^10.0.0` to `^11.1.0` ([#5080](https://github.com/MetaMask/core/pull/5080), [#5223](https://github.com/MetaMask/core/pull/5223))
25
32
 
26
33
  ## [3.0.2]
27
34
 
@@ -47,7 +54,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
47
54
  ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as
48
55
  ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md).
49
56
  All of the ATTW checks now pass.
50
- - Remove chunk files ([#4648](https://github.com/MetaMask/core/pull/4648)).
57
+ - Remove chunk files. ([#4648](https://github.com/MetaMask/core/pull/4648))
51
58
  - Previously, the build tool we used to generate JavaScript files extracted
52
59
  common code to "chunk" files. While this was intended to make this package
53
60
  more tree-shakeable, it also made debugging more difficult for our
@@ -89,9 +96,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
89
96
 
90
97
  ### Added
91
98
 
92
- - Initial release ([#3577](https://github.com/MetaMask/core/pull/3577) [#3588](https://github.com/MetaMask/core/pull/3588))
99
+ - Initial release ([#3577](https://github.com/MetaMask/core/pull/3577), [#3588](https://github.com/MetaMask/core/pull/3588))
93
100
 
94
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/build-utils@3.0.4...HEAD
101
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/build-utils@4.0.0...HEAD
102
+ [4.0.0]: https://github.com/MetaMask/core/compare/@metamask/build-utils@3.0.4...@metamask/build-utils@4.0.0
95
103
  [3.0.4]: https://github.com/MetaMask/core/compare/@metamask/build-utils@3.0.3...@metamask/build-utils@3.0.4
96
104
  [3.0.3]: https://github.com/MetaMask/core/compare/@metamask/build-utils@3.0.2...@metamask/build-utils@3.0.3
97
105
  [3.0.2]: https://github.com/MetaMask/core/compare/@metamask/build-utils@3.0.1...@metamask/build-utils@3.0.2
@@ -0,0 +1,4 @@
1
+ export type { FeatureLabels } from './transforms/remove-fenced-code.js';
2
+ export { removeFencedCode } from './transforms/remove-fenced-code.js';
3
+ export { lintTransformedFile } from './transforms/utils.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { removeFencedCode } from './transforms/remove-fenced-code.js';
2
+ export { lintTransformedFile } from './transforms/utils.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC","sourcesContent":["export type { FeatureLabels } from './transforms/remove-fenced-code.js';\nexport { removeFencedCode } from './transforms/remove-fenced-code.js';\nexport { lintTransformedFile } from './transforms/utils.js';\n"]}
@@ -67,4 +67,4 @@ export declare function multiSplice(toSplice: string, splicingIndices: number[])
67
67
  * @param featureLabels - The possible feature labels.
68
68
  */
69
69
  export declare function validateCommand(command: unknown, params: string[], filePath: string, featureLabels: FeatureLabels): asserts command is DirectiveCommand;
70
- //# sourceMappingURL=remove-fenced-code.d.cts.map
70
+ //# sourceMappingURL=remove-fenced-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-fenced-code.d.ts","sourceRoot":"","sources":["../../src/transforms/remove-fenced-code.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5B,GAAG,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC1B,CAAC;AAOF,oBAAY,gBAAgB;IAI1B,eAAe,oBAAoB;CACpC;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,aAAa,GAC3B,CAAC,MAAM,EAAE,OAAO,CAAC,CA6NnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EAAE,GACxB,MAAM,CAuCR;AAsFD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,OAAO,IAAI,gBAAgB,CA6BrC"}
@@ -1,4 +1,4 @@
1
- import { hasProperty } from "@metamask/utils";
1
+ import { hasProperty } from '@metamask/utils';
2
2
  var DirectiveTerminus;
3
3
  (function (DirectiveTerminus) {
4
4
  DirectiveTerminus["BEGIN"] = "BEGIN";
@@ -312,4 +312,4 @@ export function validateCommand(command, params, filePath, featureLabels) {
312
312
  throw new Error(`Unrecognized command "${String(command)}".`);
313
313
  }
314
314
  }
315
- //# sourceMappingURL=remove-fenced-code.mjs.map
315
+ //# sourceMappingURL=remove-fenced-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-fenced-code.js","sourceRoot":"","sources":["../../src/transforms/remove-fenced-code.ts"],"names":[],"mappings":"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","sourcesContent":["import { hasProperty } from '@metamask/utils';\n\n/**\n * Two sets of feature labels, where:\n * - `active` is the set of labels that are active for the current build.\n * - `all` is the set of all labels that are declared in the codebase.\n *\n * For `ONLY_INCLUDE_IF` fences, the code fence removal transform will\n * include the fenced code if any of the specified labels are active. See\n * {@link removeFencedCode} for details.\n */\nexport type FeatureLabels = {\n active: ReadonlySet<string>;\n all: ReadonlySet<string>;\n};\n\nenum DirectiveTerminus {\n BEGIN = 'BEGIN',\n END = 'END',\n}\n\nexport enum DirectiveCommand {\n // TODO: This should be `OnlyIncludeIf`, but we need to preserve\n // backwards-compatibility for now.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ONLY_INCLUDE_IF = 'ONLY_INCLUDE_IF',\n}\n\n// Matches lines starting with \"///:\", and any preceding whitespace, except\n// newlines. We except newlines to avoid eating blank lines preceding a fenced\n// line.\n// Double-negative RegEx credit: https://stackoverflow.com/a/3469155\nconst linesWithFenceRegex = /^[^\\S\\r\\n]*\\/\\/\\/:.*$/gmu;\n\n// Matches the first \"///:\" in a string, and any preceding whitespace\nconst fenceSentinelRegex = /^\\s*\\/\\/\\/:/u;\n\n// Breaks a fence directive into its constituent components.\n// At this stage of parsing, we are looking for one of:\n// - TERMINUS:COMMAND(PARAMS)\n// - TERMINUS:COMMAND\nconst directiveParsingRegex =\n /^([A-Z]+):([A-Z_]+)(?:\\(((?:\\w[-\\w]*,)*\\w[-\\w]*)\\))?$/u;\n\n/**\n * Removes fenced code from the given JavaScript source string. \"Fenced code\"\n * includes the entire fence lines, including their trailing newlines, and the\n * lines that they surround.\n *\n * A valid fence consists of two well-formed fence lines, separated by one or\n * more lines that should be excluded. The first line must contain a `BEGIN`\n * directive, and the second most contain an `END` directive. Both directives\n * must specify the same command.\n *\n * Here's an example of a valid fence:\n *\n * ```javascript\n * ///: BEGIN:ONLY_INCLUDE_IF(build-flask)\n * console.log('I am Flask.');\n * ///: END:ONLY_INCLUDE_IF\n * ```\n *\n * For details, please see the documentation.\n *\n * @param filePath - The path to the file being transformed.\n * @param fileContent - The contents of the file being transformed.\n * @param featureLabels - FeatureLabels that are currently active.\n * @returns A tuple of the post-transform file contents and a boolean indicating\n * whether they were modified.\n */\nexport function removeFencedCode(\n filePath: string,\n fileContent: string,\n featureLabels: FeatureLabels,\n): [string, boolean] {\n // Do not modify the file if we detect an inline sourcemap. For reasons\n // yet to be determined, the transform receives every file twice while in\n // watch mode, the second after Babel has transpiled the file. Babel adds\n // inline source maps to the file, something we will never do in our own\n // source files, so we use the existence of inline source maps to determine\n // whether we should ignore the file.\n if (/^\\/\\/# sourceMappingURL=/gmu.test(fileContent)) {\n return [fileContent, false];\n }\n\n // If we didn't match any lines, return the unmodified file contents.\n const matchedLines = [...fileContent.matchAll(linesWithFenceRegex)];\n\n if (matchedLines.length === 0) {\n return [fileContent, false];\n }\n\n // Parse fence lines\n const parsedDirectives = matchedLines.map((matchArray) => {\n const line = matchArray[0];\n\n /* istanbul ignore next: should be impossible */\n if (\n matchArray.index === undefined ||\n !line ||\n !fenceSentinelRegex.test(line)\n ) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line ?? '',\n `Fence sentinel may only appear at the start of a line, optionally preceded by whitespace.`,\n ),\n );\n }\n\n // Store the start and end indices of each line\n // Increment the end index by 1 to including the trailing newline when\n // performing string operations.\n const indices: [number, number] = [\n matchArray.index,\n matchArray.index + line.length + 1,\n ];\n\n const lineWithoutSentinel = line.replace(fenceSentinelRegex, '');\n if (!/^ \\w\\w+/u.test(lineWithoutSentinel)) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line,\n `Fence sentinel must be followed by a single space and an alphabetical string of two or more characters.`,\n ),\n );\n }\n\n const directiveMatches = lineWithoutSentinel\n .trim()\n .match(directiveParsingRegex);\n\n if (!directiveMatches) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line,\n `Failed to parse fence directive.`,\n ),\n );\n }\n\n // The first element of a RegEx match array is the input.\n // Typecast: If there's a match, the expected elements must exist.\n const [, terminus, command, parameters] = directiveMatches as [\n string,\n string,\n string,\n string,\n ];\n\n if (!isValidTerminus(terminus)) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line,\n `Line contains invalid directive terminus \"${terminus}\".`,\n ),\n );\n }\n\n if (!isValidCommand(command)) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line,\n `Line contains invalid directive command \"${command}\".`,\n ),\n );\n }\n\n if (terminus === DirectiveTerminus.BEGIN) {\n if (!parameters) {\n throw new Error(\n getInvalidParamsMessage(filePath, `No parameters specified.`),\n );\n }\n\n return {\n command,\n indices,\n line,\n parameters: parameters.split(','),\n terminus,\n };\n }\n return { command, indices, line, terminus };\n });\n\n if (parsedDirectives.length % 2 !== 0) {\n throw new Error(\n getInvalidFenceStructureMessage(\n filePath,\n `A valid fence consists of two fence lines, but the file contains an uneven number, \"${parsedDirectives.length}\", of fence lines.`,\n ),\n );\n }\n\n // The below for-loop iterates over the parsed fence directives and performs\n // the following work:\n // - Ensures that the array of parsed directives consists of valid directive\n // pairs, as specified in the documentation.\n // - For each directive pair, determines whether their fenced lines should be\n // removed for the current build, and if so, stores the indices we will use\n // to splice the file content string.\n\n const splicingIndices: number[] = [];\n let shouldSplice = false;\n let currentCommand: string;\n\n parsedDirectives.forEach((directive, i) => {\n const { line, indices, terminus, command } = directive;\n\n if (i % 2 === 0) {\n if (terminus !== DirectiveTerminus.BEGIN) {\n throw new Error(\n getInvalidFencePairMessage(\n filePath,\n line,\n `The first directive of a pair must be a \"BEGIN\" directive.`,\n ),\n );\n }\n\n const { parameters } = directive;\n currentCommand = command;\n validateCommand(command, parameters, filePath, featureLabels);\n\n const blockIsActive = parameters.some((param) =>\n featureLabels.active.has(param),\n );\n\n if (blockIsActive) {\n shouldSplice = false;\n } else {\n shouldSplice = true;\n\n // Add start index of BEGIN directive line to splicing indices\n splicingIndices.push(indices[0]);\n }\n } else {\n if (terminus !== DirectiveTerminus.END) {\n throw new Error(\n getInvalidFencePairMessage(\n filePath,\n line,\n `The second directive of a pair must be an \"END\" directive.`,\n ),\n );\n }\n\n /* istanbul ignore next: impossible until there's more than one command */\n if (command !== currentCommand) {\n throw new Error(\n getInvalidFencePairMessage(\n filePath,\n line,\n `Expected \"END\" directive to have command \"${currentCommand}\" but found \"${command}\".`,\n ),\n );\n }\n\n // Forbid empty fences\n const { line: previousLine, indices: previousIndices } =\n // We're only in this case if i > 0, so this will always be defined.\n parsedDirectives[i - 1];\n if (fileContent.substring(previousIndices[1], indices[0]).trim() === '') {\n throw new Error(\n `Empty fence found in file \"${filePath}\":\\n${previousLine}\\n${line}\\n`,\n );\n }\n\n if (shouldSplice) {\n // Add end index of END directive line to splicing indices\n splicingIndices.push(indices[1]);\n }\n }\n });\n\n // This indicates that the present build type should include all fenced code,\n // and so we just returned the unmodified file contents.\n if (splicingIndices.length === 0) {\n return [fileContent, false];\n }\n\n /* istanbul ignore next: should be impossible */\n if (splicingIndices.length % 2 !== 0) {\n throw new Error(\n `Internal error while transforming file \"${filePath}\":\\nCollected an uneven number of splicing indices: \"${splicingIndices.length}\"`,\n );\n }\n\n return [multiSplice(fileContent, splicingIndices), true];\n}\n\n/**\n * Returns a copy of the given string, without the character ranges specified\n * by the splicing indices array.\n *\n * The splicing indices must be a non-empty, even-length array of non-negative\n * integers, specifying the character ranges to remove from the given string, as\n * follows:\n *\n * `[ start, end, start, end, start, end, ... ]`\n *\n * Throws if the array is not an even-length array of non-negative integers.\n *\n * @param toSplice - The string to splice.\n * @param splicingIndices - Indices to splice at.\n * @returns The spliced string.\n */\nexport function multiSplice(\n toSplice: string,\n splicingIndices: number[],\n): string {\n if (splicingIndices.length === 0 || splicingIndices.length % 2 !== 0) {\n throw new Error('Expected non-empty, even-length array.');\n }\n if (splicingIndices.some((index) => !Number.isInteger(index) || index < 0)) {\n throw new Error('Expected array of non-negative integers.');\n }\n\n const retainedSubstrings: string[] = [];\n\n // Get the first part to be included\n // The substring() call returns an empty string if splicingIndices[0] is 0,\n // which is exactly what we want in that case.\n retainedSubstrings.push(toSplice.substring(0, splicingIndices[0]));\n\n // This loop gets us all parts of the string that should be retained, except\n // the first and the last.\n // It iterates over all \"end\" indices of the array except the last one, and\n // pushes the substring between each \"end\" index and the next \"begin\" index\n // to the array of retained substrings.\n if (splicingIndices.length > 2) {\n // Note the boundary index of \"splicingIndices.length - 1\". This loop must\n // not iterate over the last element of the array, which is handled outside\n // of this loop.\n for (let i = 1; i < splicingIndices.length - 1; i += 2) {\n retainedSubstrings.push(\n // splicingIndices[i] refers to an element between the first and last\n // elements of the array, and will always be defined.\n toSplice.substring(splicingIndices[i], splicingIndices[i + 1]),\n );\n }\n }\n\n // Get the last part to be included\n retainedSubstrings.push(\n // The last element of a non-empty array will always be defined.\n toSplice.substring(splicingIndices[splicingIndices.length - 1]),\n );\n return retainedSubstrings.join('');\n}\n\n/**\n * Gets an invalid fence line error message.\n *\n * @param filePath - The path to the file that caused the error.\n * @param line - The contents of the line with the error.\n * @param details - An explanation of the error.\n * @returns The error message.\n */\nfunction getInvalidFenceLineMessage(\n filePath: string,\n line: string,\n details: string,\n): string {\n return `Invalid fence line in file \"${filePath}\": \"${line}\":\\n${details}`;\n}\n\n/**\n * Gets an invalid fence structure error message.\n *\n * @param filePath - The path to the file that caused the error.\n * @param details - An explanation of the error.\n * @returns The error message.\n */\nfunction getInvalidFenceStructureMessage(\n filePath: string,\n details: string,\n): string {\n return `Invalid fence structure in file \"${filePath}\":\\n${details}`;\n}\n\n/**\n * Gets an invalid fence pair error message.\n *\n * @param filePath - The path to the file that caused the error.\n * @param line - The contents of the line with the error.\n * @param details - An explanation of the error.\n * @returns The error message.\n */\nfunction getInvalidFencePairMessage(\n filePath: string,\n line: string,\n details: string,\n): string {\n return `Invalid fence pair in file \"${filePath}\" due to line \"${line}\":\\n${details}`;\n}\n\n/**\n * Gets an invalid command params error message.\n *\n * @param filePath - The path to the file that caused the error.\n * @param details - An explanation of the error.\n * @param command - The command of the directive with the invalid parameters, if known.\n * @returns The error message.\n */\nfunction getInvalidParamsMessage(\n filePath: string,\n details: string,\n command?: string,\n): string {\n return `Invalid code fence parameters in file \"${filePath}\"${\n command ? `for command \"${command}\"` : ''\n }:\\n${details}`;\n}\n\n/**\n * Checks whether the given terminus string is valid, i.e. one of `BEGIN` or `END`.\n *\n * @param terminus - The terminus string to validate.\n * @returns Whether the string is a valid terminus string.\n */\nfunction isValidTerminus(terminus: string): terminus is DirectiveTerminus {\n return hasProperty(DirectiveTerminus, terminus);\n}\n\n/**\n * Checks whether the given command string is valid.\n *\n * @param command - The command string to validate.\n * @returns Whether the string is a valid command string.\n */\nfunction isValidCommand(command: string): command is DirectiveCommand {\n return hasProperty(DirectiveCommand, command);\n}\n\n/**\n * Validates the specified command. Throws if validation fails.\n *\n * @param command - The command to validate.\n * @param params - The parameters of the command.\n * @param filePath - The path of the current file.\n * @param featureLabels - The possible feature labels.\n */\nexport function validateCommand(\n command: unknown,\n params: string[],\n filePath: string,\n featureLabels: FeatureLabels,\n): asserts command is DirectiveCommand {\n switch (command) {\n case DirectiveCommand.ONLY_INCLUDE_IF:\n if (!params || params.length === 0) {\n throw new Error(\n getInvalidParamsMessage(\n filePath,\n `No parameters specified.`,\n DirectiveCommand.ONLY_INCLUDE_IF,\n ),\n );\n }\n\n for (const param of params) {\n if (!featureLabels.all.has(param)) {\n throw new Error(\n getInvalidParamsMessage(\n filePath,\n `\"${param}\" is not a declared build feature.`,\n DirectiveCommand.ONLY_INCLUDE_IF,\n ),\n );\n }\n }\n break;\n\n default:\n throw new Error(`Unrecognized command \"${String(command)}\".`);\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { ESLint } from "eslint";
1
+ import type { ESLint } from 'eslint';
2
2
  /**
3
3
  * Lints a transformed file by invoking ESLint programmatically on the string
4
4
  * file contents. The path to the file must be specified so that the repository
@@ -22,4 +22,4 @@ import type { ESLint } from "eslint";
22
22
  * any errors, or if the linted file is ignored.
23
23
  */
24
24
  export declare function lintTransformedFile(eslintInstance: ESLint, filePath: string, fileContent: string): Promise<void>;
25
- //# sourceMappingURL=utils.d.cts.map
25
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/transforms/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAKrC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
@@ -41,4 +41,4 @@ export async function lintTransformedFile(eslintInstance, filePath, fileContent)
41
41
  }, '');
42
42
  throw new Error(`MetaMask build: Lint errors encountered for transformed file "${filePath}":\n\n${errorsString}`);
43
43
  }
44
- //# sourceMappingURL=utils.mjs.map
44
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/transforms/utils.ts"],"names":[],"mappings":"AAEA,cAAc;AACd,MAAM,GAAG,GAAG,MAAM,CAAC;AAEnB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,cAAsB,EACtB,QAAgB,EAChB,WAAmB;IAEnB,MAAM,UAAU,GAAG,CACjB,MAAM,cAAc,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAC7E,CAAC,CAAC,CAAC,CAAC;IAEL,8EAA8E;IAC9E,sBAAsB;IACtB,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,qCAAqC,QAAQ,oCAAoC,CAClF,CAAC;IACJ,CAAC;IAED,2BAA2B;IAC3B,IAAI,UAAU,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO;IACT,CAAC;IAED,qEAAqE;IACrE,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ;SACrC,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,KAAK,CAAC,CAAC;SACxC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QACzC,OAAO,SAAS,CAAC,MAAM,CACrB,GAAG,GAAG,GAAG,MAAM,IAAI,gBAAgB,KAAK,GAAG,GAAG,OAAO,MAAM,CAC5D,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAET,MAAM,IAAI,KAAK,CACb,iEAAiE,QAAQ,SAAS,YAAY,EAAE,CACjG,CAAC;AACJ,CAAC","sourcesContent":["import type { ESLint } from 'eslint';\n\n// Four spaces\nconst TAB = ' ';\n\n/**\n * Lints a transformed file by invoking ESLint programmatically on the string\n * file contents. The path to the file must be specified so that the repository\n * ESLint config can be applied properly.\n *\n * **ATTN:** See the `eslintInstance` parameter documentation for important usage\n * information.\n *\n * An error is thrown if linting produced any errors, or if the file is ignored\n * by ESLint. Files linted by this function must not be ignored by ESLint.\n *\n * @param eslintInstance - The ESLint instance to use for linting. This instance\n * needs to be initialized with the options `{ baseConfig, useEslintrc: false}`,\n * where `baseConfig` is the desired ESLint configuration for linting. If using\n * your project's regular `.eslintrc` file, you may need to modify certain rules\n * for linting to pass after code fences are removed. Stylistic rules are\n * particularly likely to cause problems.\n * @param filePath - The path to the file.\n * @param fileContent - The file content.\n * @returns Returns `undefined` or throws an error if linting produced\n * any errors, or if the linted file is ignored.\n */\nexport async function lintTransformedFile(\n eslintInstance: ESLint,\n filePath: string,\n fileContent: string,\n): Promise<void> {\n const lintResult = (\n await eslintInstance.lintText(fileContent, { filePath, warnIgnored: false })\n )[0];\n\n // This indicates that the file is ignored, which should never be the case for\n // a transformed file.\n if (lintResult === undefined) {\n throw new Error(\n `MetaMask build: Transformed file \"${filePath}\" appears to be ignored by ESLint.`,\n );\n }\n\n // This is the success case\n if (lintResult.errorCount === 0) {\n return;\n }\n\n // Errors are stored in the messages array, and their \"severity\" is 2\n const errorsString = lintResult.messages\n .filter(({ severity }) => severity === 2)\n .reduce((allErrors, { message, ruleId }) => {\n return allErrors.concat(\n `${TAB}${ruleId ?? '<Unknown rule>'}\\n${TAB}${message}\\n\\n`,\n );\n }, '');\n\n throw new Error(\n `MetaMask build: Lint errors encountered for transformed file \"${filePath}\":\\n\\n${errorsString}`,\n );\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/build-utils",
3
- "version": "3.0.4-preview-8bfa290fb",
3
+ "version": "4.0.0-preview-0a30e47",
4
4
  "description": "Utilities for building MetaMask applications",
5
5
  "keywords": [
6
6
  "Ethereum",
@@ -18,19 +18,12 @@
18
18
  "files": [
19
19
  "dist/"
20
20
  ],
21
+ "type": "module",
21
22
  "sideEffects": false,
22
- "main": "./dist/index.cjs",
23
- "types": "./dist/index.d.cts",
24
23
  "exports": {
25
24
  ".": {
26
- "import": {
27
- "types": "./dist/index.d.mts",
28
- "default": "./dist/index.mjs"
29
- },
30
- "require": {
31
- "types": "./dist/index.d.cts",
32
- "default": "./dist/index.cjs"
33
- }
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
34
27
  },
35
28
  "./package.json": "./package.json"
36
29
  },
@@ -39,9 +32,11 @@
39
32
  "registry": "https://registry.npmjs.org/"
40
33
  },
41
34
  "scripts": {
42
- "build": "ts-bridge --project tsconfig.build.json --verbose --clean --no-references",
43
- "build:all": "ts-bridge --project tsconfig.build.json --verbose --clean",
35
+ "build": "tsc --project tsconfig.build.json",
36
+ "build:all": "tsc --build tsconfig.build.json --verbose",
37
+ "build:clean": "yarn build:only-clean && yarn build",
44
38
  "build:docs": "typedoc",
39
+ "build:only-clean": "rimraf './dist' './tsconfig.build.tsbuildinfo'",
45
40
  "changelog:update": "../../scripts/update-changelog.sh @metamask/build-utils",
46
41
  "changelog:validate": "../../scripts/validate-changelog.sh @metamask/build-utils",
47
42
  "lint:tsconfigs": "tsx ../../scripts/lint-tsconfigs/lint-tsconfigs.mts",
@@ -58,17 +53,18 @@
58
53
  },
59
54
  "devDependencies": {
60
55
  "@metamask/auto-changelog": "^6.1.0",
61
- "@ts-bridge/cli": "^0.6.4",
62
56
  "@types/jest": "^30.0.0",
57
+ "@typescript/native": "npm:typescript@^7.0.2",
63
58
  "deepmerge": "^4.2.2",
64
59
  "jest": "^30.4.2",
60
+ "rimraf": "^5.0.5",
65
61
  "ts-jest": "^29.4.11",
66
62
  "tsx": "^4.20.5",
67
63
  "typedoc": "^0.25.13",
68
64
  "typedoc-plugin-missing-exports": "^2.0.0",
69
- "typescript": "~5.3.3"
65
+ "typescript": "npm:@typescript/typescript6@^6.0.2"
70
66
  },
71
67
  "engines": {
72
- "node": "^18.18 || >=20"
68
+ "node": "^22.14.0 || ^24"
73
69
  }
74
70
  }
package/dist/index.cjs DELETED
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.lintTransformedFile = exports.removeFencedCode = void 0;
4
- var remove_fenced_code_js_1 = require("./transforms/remove-fenced-code.cjs");
5
- Object.defineProperty(exports, "removeFencedCode", { enumerable: true, get: function () { return remove_fenced_code_js_1.removeFencedCode; } });
6
- var utils_js_1 = require("./transforms/utils.cjs");
7
- Object.defineProperty(exports, "lintTransformedFile", { enumerable: true, get: function () { return utils_js_1.lintTransformedFile; } });
8
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,6EAAsE;AAA7D,yHAAA,gBAAgB,OAAA;AACzB,mDAA4D;AAAnD,+GAAA,mBAAmB,OAAA","sourcesContent":["export type { FeatureLabels } from './transforms/remove-fenced-code.js';\nexport { removeFencedCode } from './transforms/remove-fenced-code.js';\nexport { lintTransformedFile } from './transforms/utils.js';\n"]}
package/dist/index.d.cts DELETED
@@ -1,4 +0,0 @@
1
- export type { FeatureLabels } from "./transforms/remove-fenced-code.cjs";
2
- export { removeFencedCode } from "./transforms/remove-fenced-code.cjs";
3
- export { lintTransformedFile } from "./transforms/utils.cjs";
4
- //# sourceMappingURL=index.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,4CAA2C;AACxE,OAAO,EAAE,gBAAgB,EAAE,4CAA2C;AACtE,OAAO,EAAE,mBAAmB,EAAE,+BAA8B"}
package/dist/index.d.mts DELETED
@@ -1,4 +0,0 @@
1
- export type { FeatureLabels } from "./transforms/remove-fenced-code.mjs";
2
- export { removeFencedCode } from "./transforms/remove-fenced-code.mjs";
3
- export { lintTransformedFile } from "./transforms/utils.mjs";
4
- //# sourceMappingURL=index.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,4CAA2C;AACxE,OAAO,EAAE,gBAAgB,EAAE,4CAA2C;AACtE,OAAO,EAAE,mBAAmB,EAAE,+BAA8B"}
package/dist/index.mjs DELETED
@@ -1,3 +0,0 @@
1
- export { removeFencedCode } from "./transforms/remove-fenced-code.mjs";
2
- export { lintTransformedFile } from "./transforms/utils.mjs";
3
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,4CAA2C;AACtE,OAAO,EAAE,mBAAmB,EAAE,+BAA8B","sourcesContent":["export type { FeatureLabels } from './transforms/remove-fenced-code.js';\nexport { removeFencedCode } from './transforms/remove-fenced-code.js';\nexport { lintTransformedFile } from './transforms/utils.js';\n"]}
@@ -1,321 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateCommand = exports.multiSplice = exports.removeFencedCode = exports.DirectiveCommand = void 0;
4
- const utils_1 = require("@metamask/utils");
5
- var DirectiveTerminus;
6
- (function (DirectiveTerminus) {
7
- DirectiveTerminus["BEGIN"] = "BEGIN";
8
- DirectiveTerminus["END"] = "END";
9
- })(DirectiveTerminus || (DirectiveTerminus = {}));
10
- var DirectiveCommand;
11
- (function (DirectiveCommand) {
12
- // TODO: This should be `OnlyIncludeIf`, but we need to preserve
13
- // backwards-compatibility for now.
14
- // eslint-disable-next-line @typescript-eslint/naming-convention
15
- DirectiveCommand["ONLY_INCLUDE_IF"] = "ONLY_INCLUDE_IF";
16
- })(DirectiveCommand || (exports.DirectiveCommand = DirectiveCommand = {}));
17
- // Matches lines starting with "///:", and any preceding whitespace, except
18
- // newlines. We except newlines to avoid eating blank lines preceding a fenced
19
- // line.
20
- // Double-negative RegEx credit: https://stackoverflow.com/a/3469155
21
- const linesWithFenceRegex = /^[^\S\r\n]*\/\/\/:.*$/gmu;
22
- // Matches the first "///:" in a string, and any preceding whitespace
23
- const fenceSentinelRegex = /^\s*\/\/\/:/u;
24
- // Breaks a fence directive into its constituent components.
25
- // At this stage of parsing, we are looking for one of:
26
- // - TERMINUS:COMMAND(PARAMS)
27
- // - TERMINUS:COMMAND
28
- const directiveParsingRegex = /^([A-Z]+):([A-Z_]+)(?:\(((?:\w[-\w]*,)*\w[-\w]*)\))?$/u;
29
- /**
30
- * Removes fenced code from the given JavaScript source string. "Fenced code"
31
- * includes the entire fence lines, including their trailing newlines, and the
32
- * lines that they surround.
33
- *
34
- * A valid fence consists of two well-formed fence lines, separated by one or
35
- * more lines that should be excluded. The first line must contain a `BEGIN`
36
- * directive, and the second most contain an `END` directive. Both directives
37
- * must specify the same command.
38
- *
39
- * Here's an example of a valid fence:
40
- *
41
- * ```javascript
42
- * ///: BEGIN:ONLY_INCLUDE_IF(build-flask)
43
- * console.log('I am Flask.');
44
- * ///: END:ONLY_INCLUDE_IF
45
- * ```
46
- *
47
- * For details, please see the documentation.
48
- *
49
- * @param filePath - The path to the file being transformed.
50
- * @param fileContent - The contents of the file being transformed.
51
- * @param featureLabels - FeatureLabels that are currently active.
52
- * @returns A tuple of the post-transform file contents and a boolean indicating
53
- * whether they were modified.
54
- */
55
- function removeFencedCode(filePath, fileContent, featureLabels) {
56
- // Do not modify the file if we detect an inline sourcemap. For reasons
57
- // yet to be determined, the transform receives every file twice while in
58
- // watch mode, the second after Babel has transpiled the file. Babel adds
59
- // inline source maps to the file, something we will never do in our own
60
- // source files, so we use the existence of inline source maps to determine
61
- // whether we should ignore the file.
62
- if (/^\/\/# sourceMappingURL=/gmu.test(fileContent)) {
63
- return [fileContent, false];
64
- }
65
- // If we didn't match any lines, return the unmodified file contents.
66
- const matchedLines = [...fileContent.matchAll(linesWithFenceRegex)];
67
- if (matchedLines.length === 0) {
68
- return [fileContent, false];
69
- }
70
- // Parse fence lines
71
- const parsedDirectives = matchedLines.map((matchArray) => {
72
- const line = matchArray[0];
73
- /* istanbul ignore next: should be impossible */
74
- if (matchArray.index === undefined ||
75
- !line ||
76
- !fenceSentinelRegex.test(line)) {
77
- throw new Error(getInvalidFenceLineMessage(filePath, line ?? '', `Fence sentinel may only appear at the start of a line, optionally preceded by whitespace.`));
78
- }
79
- // Store the start and end indices of each line
80
- // Increment the end index by 1 to including the trailing newline when
81
- // performing string operations.
82
- const indices = [
83
- matchArray.index,
84
- matchArray.index + line.length + 1,
85
- ];
86
- const lineWithoutSentinel = line.replace(fenceSentinelRegex, '');
87
- if (!/^ \w\w+/u.test(lineWithoutSentinel)) {
88
- throw new Error(getInvalidFenceLineMessage(filePath, line, `Fence sentinel must be followed by a single space and an alphabetical string of two or more characters.`));
89
- }
90
- const directiveMatches = lineWithoutSentinel
91
- .trim()
92
- .match(directiveParsingRegex);
93
- if (!directiveMatches) {
94
- throw new Error(getInvalidFenceLineMessage(filePath, line, `Failed to parse fence directive.`));
95
- }
96
- // The first element of a RegEx match array is the input.
97
- // Typecast: If there's a match, the expected elements must exist.
98
- const [, terminus, command, parameters] = directiveMatches;
99
- if (!isValidTerminus(terminus)) {
100
- throw new Error(getInvalidFenceLineMessage(filePath, line, `Line contains invalid directive terminus "${terminus}".`));
101
- }
102
- if (!isValidCommand(command)) {
103
- throw new Error(getInvalidFenceLineMessage(filePath, line, `Line contains invalid directive command "${command}".`));
104
- }
105
- if (terminus === DirectiveTerminus.BEGIN) {
106
- if (!parameters) {
107
- throw new Error(getInvalidParamsMessage(filePath, `No parameters specified.`));
108
- }
109
- return {
110
- command,
111
- indices,
112
- line,
113
- parameters: parameters.split(','),
114
- terminus,
115
- };
116
- }
117
- return { command, indices, line, terminus };
118
- });
119
- if (parsedDirectives.length % 2 !== 0) {
120
- throw new Error(getInvalidFenceStructureMessage(filePath, `A valid fence consists of two fence lines, but the file contains an uneven number, "${parsedDirectives.length}", of fence lines.`));
121
- }
122
- // The below for-loop iterates over the parsed fence directives and performs
123
- // the following work:
124
- // - Ensures that the array of parsed directives consists of valid directive
125
- // pairs, as specified in the documentation.
126
- // - For each directive pair, determines whether their fenced lines should be
127
- // removed for the current build, and if so, stores the indices we will use
128
- // to splice the file content string.
129
- const splicingIndices = [];
130
- let shouldSplice = false;
131
- let currentCommand;
132
- parsedDirectives.forEach((directive, i) => {
133
- const { line, indices, terminus, command } = directive;
134
- if (i % 2 === 0) {
135
- if (terminus !== DirectiveTerminus.BEGIN) {
136
- throw new Error(getInvalidFencePairMessage(filePath, line, `The first directive of a pair must be a "BEGIN" directive.`));
137
- }
138
- const { parameters } = directive;
139
- currentCommand = command;
140
- validateCommand(command, parameters, filePath, featureLabels);
141
- const blockIsActive = parameters.some((param) => featureLabels.active.has(param));
142
- if (blockIsActive) {
143
- shouldSplice = false;
144
- }
145
- else {
146
- shouldSplice = true;
147
- // Add start index of BEGIN directive line to splicing indices
148
- splicingIndices.push(indices[0]);
149
- }
150
- }
151
- else {
152
- if (terminus !== DirectiveTerminus.END) {
153
- throw new Error(getInvalidFencePairMessage(filePath, line, `The second directive of a pair must be an "END" directive.`));
154
- }
155
- /* istanbul ignore next: impossible until there's more than one command */
156
- if (command !== currentCommand) {
157
- throw new Error(getInvalidFencePairMessage(filePath, line, `Expected "END" directive to have command "${currentCommand}" but found "${command}".`));
158
- }
159
- // Forbid empty fences
160
- const { line: previousLine, indices: previousIndices } =
161
- // We're only in this case if i > 0, so this will always be defined.
162
- parsedDirectives[i - 1];
163
- if (fileContent.substring(previousIndices[1], indices[0]).trim() === '') {
164
- throw new Error(`Empty fence found in file "${filePath}":\n${previousLine}\n${line}\n`);
165
- }
166
- if (shouldSplice) {
167
- // Add end index of END directive line to splicing indices
168
- splicingIndices.push(indices[1]);
169
- }
170
- }
171
- });
172
- // This indicates that the present build type should include all fenced code,
173
- // and so we just returned the unmodified file contents.
174
- if (splicingIndices.length === 0) {
175
- return [fileContent, false];
176
- }
177
- /* istanbul ignore next: should be impossible */
178
- if (splicingIndices.length % 2 !== 0) {
179
- throw new Error(`Internal error while transforming file "${filePath}":\nCollected an uneven number of splicing indices: "${splicingIndices.length}"`);
180
- }
181
- return [multiSplice(fileContent, splicingIndices), true];
182
- }
183
- exports.removeFencedCode = removeFencedCode;
184
- /**
185
- * Returns a copy of the given string, without the character ranges specified
186
- * by the splicing indices array.
187
- *
188
- * The splicing indices must be a non-empty, even-length array of non-negative
189
- * integers, specifying the character ranges to remove from the given string, as
190
- * follows:
191
- *
192
- * `[ start, end, start, end, start, end, ... ]`
193
- *
194
- * Throws if the array is not an even-length array of non-negative integers.
195
- *
196
- * @param toSplice - The string to splice.
197
- * @param splicingIndices - Indices to splice at.
198
- * @returns The spliced string.
199
- */
200
- function multiSplice(toSplice, splicingIndices) {
201
- if (splicingIndices.length === 0 || splicingIndices.length % 2 !== 0) {
202
- throw new Error('Expected non-empty, even-length array.');
203
- }
204
- if (splicingIndices.some((index) => !Number.isInteger(index) || index < 0)) {
205
- throw new Error('Expected array of non-negative integers.');
206
- }
207
- const retainedSubstrings = [];
208
- // Get the first part to be included
209
- // The substring() call returns an empty string if splicingIndices[0] is 0,
210
- // which is exactly what we want in that case.
211
- retainedSubstrings.push(toSplice.substring(0, splicingIndices[0]));
212
- // This loop gets us all parts of the string that should be retained, except
213
- // the first and the last.
214
- // It iterates over all "end" indices of the array except the last one, and
215
- // pushes the substring between each "end" index and the next "begin" index
216
- // to the array of retained substrings.
217
- if (splicingIndices.length > 2) {
218
- // Note the boundary index of "splicingIndices.length - 1". This loop must
219
- // not iterate over the last element of the array, which is handled outside
220
- // of this loop.
221
- for (let i = 1; i < splicingIndices.length - 1; i += 2) {
222
- retainedSubstrings.push(
223
- // splicingIndices[i] refers to an element between the first and last
224
- // elements of the array, and will always be defined.
225
- toSplice.substring(splicingIndices[i], splicingIndices[i + 1]));
226
- }
227
- }
228
- // Get the last part to be included
229
- retainedSubstrings.push(
230
- // The last element of a non-empty array will always be defined.
231
- toSplice.substring(splicingIndices[splicingIndices.length - 1]));
232
- return retainedSubstrings.join('');
233
- }
234
- exports.multiSplice = multiSplice;
235
- /**
236
- * Gets an invalid fence line error message.
237
- *
238
- * @param filePath - The path to the file that caused the error.
239
- * @param line - The contents of the line with the error.
240
- * @param details - An explanation of the error.
241
- * @returns The error message.
242
- */
243
- function getInvalidFenceLineMessage(filePath, line, details) {
244
- return `Invalid fence line in file "${filePath}": "${line}":\n${details}`;
245
- }
246
- /**
247
- * Gets an invalid fence structure error message.
248
- *
249
- * @param filePath - The path to the file that caused the error.
250
- * @param details - An explanation of the error.
251
- * @returns The error message.
252
- */
253
- function getInvalidFenceStructureMessage(filePath, details) {
254
- return `Invalid fence structure in file "${filePath}":\n${details}`;
255
- }
256
- /**
257
- * Gets an invalid fence pair error message.
258
- *
259
- * @param filePath - The path to the file that caused the error.
260
- * @param line - The contents of the line with the error.
261
- * @param details - An explanation of the error.
262
- * @returns The error message.
263
- */
264
- function getInvalidFencePairMessage(filePath, line, details) {
265
- return `Invalid fence pair in file "${filePath}" due to line "${line}":\n${details}`;
266
- }
267
- /**
268
- * Gets an invalid command params error message.
269
- *
270
- * @param filePath - The path to the file that caused the error.
271
- * @param details - An explanation of the error.
272
- * @param command - The command of the directive with the invalid parameters, if known.
273
- * @returns The error message.
274
- */
275
- function getInvalidParamsMessage(filePath, details, command) {
276
- return `Invalid code fence parameters in file "${filePath}"${command ? `for command "${command}"` : ''}:\n${details}`;
277
- }
278
- /**
279
- * Checks whether the given terminus string is valid, i.e. one of `BEGIN` or `END`.
280
- *
281
- * @param terminus - The terminus string to validate.
282
- * @returns Whether the string is a valid terminus string.
283
- */
284
- function isValidTerminus(terminus) {
285
- return (0, utils_1.hasProperty)(DirectiveTerminus, terminus);
286
- }
287
- /**
288
- * Checks whether the given command string is valid.
289
- *
290
- * @param command - The command string to validate.
291
- * @returns Whether the string is a valid command string.
292
- */
293
- function isValidCommand(command) {
294
- return (0, utils_1.hasProperty)(DirectiveCommand, command);
295
- }
296
- /**
297
- * Validates the specified command. Throws if validation fails.
298
- *
299
- * @param command - The command to validate.
300
- * @param params - The parameters of the command.
301
- * @param filePath - The path of the current file.
302
- * @param featureLabels - The possible feature labels.
303
- */
304
- function validateCommand(command, params, filePath, featureLabels) {
305
- switch (command) {
306
- case DirectiveCommand.ONLY_INCLUDE_IF:
307
- if (!params || params.length === 0) {
308
- throw new Error(getInvalidParamsMessage(filePath, `No parameters specified.`, DirectiveCommand.ONLY_INCLUDE_IF));
309
- }
310
- for (const param of params) {
311
- if (!featureLabels.all.has(param)) {
312
- throw new Error(getInvalidParamsMessage(filePath, `"${param}" is not a declared build feature.`, DirectiveCommand.ONLY_INCLUDE_IF));
313
- }
314
- }
315
- break;
316
- default:
317
- throw new Error(`Unrecognized command "${String(command)}".`);
318
- }
319
- }
320
- exports.validateCommand = validateCommand;
321
- //# sourceMappingURL=remove-fenced-code.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"remove-fenced-code.cjs","sourceRoot":"","sources":["../../src/transforms/remove-fenced-code.ts"],"names":[],"mappings":"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","sourcesContent":["import { hasProperty } from '@metamask/utils';\n\n/**\n * Two sets of feature labels, where:\n * - `active` is the set of labels that are active for the current build.\n * - `all` is the set of all labels that are declared in the codebase.\n *\n * For `ONLY_INCLUDE_IF` fences, the code fence removal transform will\n * include the fenced code if any of the specified labels are active. See\n * {@link removeFencedCode} for details.\n */\nexport type FeatureLabels = {\n active: ReadonlySet<string>;\n all: ReadonlySet<string>;\n};\n\nenum DirectiveTerminus {\n BEGIN = 'BEGIN',\n END = 'END',\n}\n\nexport enum DirectiveCommand {\n // TODO: This should be `OnlyIncludeIf`, but we need to preserve\n // backwards-compatibility for now.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ONLY_INCLUDE_IF = 'ONLY_INCLUDE_IF',\n}\n\n// Matches lines starting with \"///:\", and any preceding whitespace, except\n// newlines. We except newlines to avoid eating blank lines preceding a fenced\n// line.\n// Double-negative RegEx credit: https://stackoverflow.com/a/3469155\nconst linesWithFenceRegex = /^[^\\S\\r\\n]*\\/\\/\\/:.*$/gmu;\n\n// Matches the first \"///:\" in a string, and any preceding whitespace\nconst fenceSentinelRegex = /^\\s*\\/\\/\\/:/u;\n\n// Breaks a fence directive into its constituent components.\n// At this stage of parsing, we are looking for one of:\n// - TERMINUS:COMMAND(PARAMS)\n// - TERMINUS:COMMAND\nconst directiveParsingRegex =\n /^([A-Z]+):([A-Z_]+)(?:\\(((?:\\w[-\\w]*,)*\\w[-\\w]*)\\))?$/u;\n\n/**\n * Removes fenced code from the given JavaScript source string. \"Fenced code\"\n * includes the entire fence lines, including their trailing newlines, and the\n * lines that they surround.\n *\n * A valid fence consists of two well-formed fence lines, separated by one or\n * more lines that should be excluded. The first line must contain a `BEGIN`\n * directive, and the second most contain an `END` directive. Both directives\n * must specify the same command.\n *\n * Here's an example of a valid fence:\n *\n * ```javascript\n * ///: BEGIN:ONLY_INCLUDE_IF(build-flask)\n * console.log('I am Flask.');\n * ///: END:ONLY_INCLUDE_IF\n * ```\n *\n * For details, please see the documentation.\n *\n * @param filePath - The path to the file being transformed.\n * @param fileContent - The contents of the file being transformed.\n * @param featureLabels - FeatureLabels that are currently active.\n * @returns A tuple of the post-transform file contents and a boolean indicating\n * whether they were modified.\n */\nexport function removeFencedCode(\n filePath: string,\n fileContent: string,\n featureLabels: FeatureLabels,\n): [string, boolean] {\n // Do not modify the file if we detect an inline sourcemap. For reasons\n // yet to be determined, the transform receives every file twice while in\n // watch mode, the second after Babel has transpiled the file. Babel adds\n // inline source maps to the file, something we will never do in our own\n // source files, so we use the existence of inline source maps to determine\n // whether we should ignore the file.\n if (/^\\/\\/# sourceMappingURL=/gmu.test(fileContent)) {\n return [fileContent, false];\n }\n\n // If we didn't match any lines, return the unmodified file contents.\n const matchedLines = [...fileContent.matchAll(linesWithFenceRegex)];\n\n if (matchedLines.length === 0) {\n return [fileContent, false];\n }\n\n // Parse fence lines\n const parsedDirectives = matchedLines.map((matchArray) => {\n const line = matchArray[0];\n\n /* istanbul ignore next: should be impossible */\n if (\n matchArray.index === undefined ||\n !line ||\n !fenceSentinelRegex.test(line)\n ) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line ?? '',\n `Fence sentinel may only appear at the start of a line, optionally preceded by whitespace.`,\n ),\n );\n }\n\n // Store the start and end indices of each line\n // Increment the end index by 1 to including the trailing newline when\n // performing string operations.\n const indices: [number, number] = [\n matchArray.index,\n matchArray.index + line.length + 1,\n ];\n\n const lineWithoutSentinel = line.replace(fenceSentinelRegex, '');\n if (!/^ \\w\\w+/u.test(lineWithoutSentinel)) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line,\n `Fence sentinel must be followed by a single space and an alphabetical string of two or more characters.`,\n ),\n );\n }\n\n const directiveMatches = lineWithoutSentinel\n .trim()\n .match(directiveParsingRegex);\n\n if (!directiveMatches) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line,\n `Failed to parse fence directive.`,\n ),\n );\n }\n\n // The first element of a RegEx match array is the input.\n // Typecast: If there's a match, the expected elements must exist.\n const [, terminus, command, parameters] = directiveMatches as [\n string,\n string,\n string,\n string,\n ];\n\n if (!isValidTerminus(terminus)) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line,\n `Line contains invalid directive terminus \"${terminus}\".`,\n ),\n );\n }\n\n if (!isValidCommand(command)) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line,\n `Line contains invalid directive command \"${command}\".`,\n ),\n );\n }\n\n if (terminus === DirectiveTerminus.BEGIN) {\n if (!parameters) {\n throw new Error(\n getInvalidParamsMessage(filePath, `No parameters specified.`),\n );\n }\n\n return {\n command,\n indices,\n line,\n parameters: parameters.split(','),\n terminus,\n };\n }\n return { command, indices, line, terminus };\n });\n\n if (parsedDirectives.length % 2 !== 0) {\n throw new Error(\n getInvalidFenceStructureMessage(\n filePath,\n `A valid fence consists of two fence lines, but the file contains an uneven number, \"${parsedDirectives.length}\", of fence lines.`,\n ),\n );\n }\n\n // The below for-loop iterates over the parsed fence directives and performs\n // the following work:\n // - Ensures that the array of parsed directives consists of valid directive\n // pairs, as specified in the documentation.\n // - For each directive pair, determines whether their fenced lines should be\n // removed for the current build, and if so, stores the indices we will use\n // to splice the file content string.\n\n const splicingIndices: number[] = [];\n let shouldSplice = false;\n let currentCommand: string;\n\n parsedDirectives.forEach((directive, i) => {\n const { line, indices, terminus, command } = directive;\n\n if (i % 2 === 0) {\n if (terminus !== DirectiveTerminus.BEGIN) {\n throw new Error(\n getInvalidFencePairMessage(\n filePath,\n line,\n `The first directive of a pair must be a \"BEGIN\" directive.`,\n ),\n );\n }\n\n const { parameters } = directive;\n currentCommand = command;\n validateCommand(command, parameters, filePath, featureLabels);\n\n const blockIsActive = parameters.some((param) =>\n featureLabels.active.has(param),\n );\n\n if (blockIsActive) {\n shouldSplice = false;\n } else {\n shouldSplice = true;\n\n // Add start index of BEGIN directive line to splicing indices\n splicingIndices.push(indices[0]);\n }\n } else {\n if (terminus !== DirectiveTerminus.END) {\n throw new Error(\n getInvalidFencePairMessage(\n filePath,\n line,\n `The second directive of a pair must be an \"END\" directive.`,\n ),\n );\n }\n\n /* istanbul ignore next: impossible until there's more than one command */\n if (command !== currentCommand) {\n throw new Error(\n getInvalidFencePairMessage(\n filePath,\n line,\n `Expected \"END\" directive to have command \"${currentCommand}\" but found \"${command}\".`,\n ),\n );\n }\n\n // Forbid empty fences\n const { line: previousLine, indices: previousIndices } =\n // We're only in this case if i > 0, so this will always be defined.\n parsedDirectives[i - 1];\n if (fileContent.substring(previousIndices[1], indices[0]).trim() === '') {\n throw new Error(\n `Empty fence found in file \"${filePath}\":\\n${previousLine}\\n${line}\\n`,\n );\n }\n\n if (shouldSplice) {\n // Add end index of END directive line to splicing indices\n splicingIndices.push(indices[1]);\n }\n }\n });\n\n // This indicates that the present build type should include all fenced code,\n // and so we just returned the unmodified file contents.\n if (splicingIndices.length === 0) {\n return [fileContent, false];\n }\n\n /* istanbul ignore next: should be impossible */\n if (splicingIndices.length % 2 !== 0) {\n throw new Error(\n `Internal error while transforming file \"${filePath}\":\\nCollected an uneven number of splicing indices: \"${splicingIndices.length}\"`,\n );\n }\n\n return [multiSplice(fileContent, splicingIndices), true];\n}\n\n/**\n * Returns a copy of the given string, without the character ranges specified\n * by the splicing indices array.\n *\n * The splicing indices must be a non-empty, even-length array of non-negative\n * integers, specifying the character ranges to remove from the given string, as\n * follows:\n *\n * `[ start, end, start, end, start, end, ... ]`\n *\n * Throws if the array is not an even-length array of non-negative integers.\n *\n * @param toSplice - The string to splice.\n * @param splicingIndices - Indices to splice at.\n * @returns The spliced string.\n */\nexport function multiSplice(\n toSplice: string,\n splicingIndices: number[],\n): string {\n if (splicingIndices.length === 0 || splicingIndices.length % 2 !== 0) {\n throw new Error('Expected non-empty, even-length array.');\n }\n if (splicingIndices.some((index) => !Number.isInteger(index) || index < 0)) {\n throw new Error('Expected array of non-negative integers.');\n }\n\n const retainedSubstrings: string[] = [];\n\n // Get the first part to be included\n // The substring() call returns an empty string if splicingIndices[0] is 0,\n // which is exactly what we want in that case.\n retainedSubstrings.push(toSplice.substring(0, splicingIndices[0]));\n\n // This loop gets us all parts of the string that should be retained, except\n // the first and the last.\n // It iterates over all \"end\" indices of the array except the last one, and\n // pushes the substring between each \"end\" index and the next \"begin\" index\n // to the array of retained substrings.\n if (splicingIndices.length > 2) {\n // Note the boundary index of \"splicingIndices.length - 1\". This loop must\n // not iterate over the last element of the array, which is handled outside\n // of this loop.\n for (let i = 1; i < splicingIndices.length - 1; i += 2) {\n retainedSubstrings.push(\n // splicingIndices[i] refers to an element between the first and last\n // elements of the array, and will always be defined.\n toSplice.substring(splicingIndices[i], splicingIndices[i + 1]),\n );\n }\n }\n\n // Get the last part to be included\n retainedSubstrings.push(\n // The last element of a non-empty array will always be defined.\n toSplice.substring(splicingIndices[splicingIndices.length - 1]),\n );\n return retainedSubstrings.join('');\n}\n\n/**\n * Gets an invalid fence line error message.\n *\n * @param filePath - The path to the file that caused the error.\n * @param line - The contents of the line with the error.\n * @param details - An explanation of the error.\n * @returns The error message.\n */\nfunction getInvalidFenceLineMessage(\n filePath: string,\n line: string,\n details: string,\n): string {\n return `Invalid fence line in file \"${filePath}\": \"${line}\":\\n${details}`;\n}\n\n/**\n * Gets an invalid fence structure error message.\n *\n * @param filePath - The path to the file that caused the error.\n * @param details - An explanation of the error.\n * @returns The error message.\n */\nfunction getInvalidFenceStructureMessage(\n filePath: string,\n details: string,\n): string {\n return `Invalid fence structure in file \"${filePath}\":\\n${details}`;\n}\n\n/**\n * Gets an invalid fence pair error message.\n *\n * @param filePath - The path to the file that caused the error.\n * @param line - The contents of the line with the error.\n * @param details - An explanation of the error.\n * @returns The error message.\n */\nfunction getInvalidFencePairMessage(\n filePath: string,\n line: string,\n details: string,\n): string {\n return `Invalid fence pair in file \"${filePath}\" due to line \"${line}\":\\n${details}`;\n}\n\n/**\n * Gets an invalid command params error message.\n *\n * @param filePath - The path to the file that caused the error.\n * @param details - An explanation of the error.\n * @param command - The command of the directive with the invalid parameters, if known.\n * @returns The error message.\n */\nfunction getInvalidParamsMessage(\n filePath: string,\n details: string,\n command?: string,\n): string {\n return `Invalid code fence parameters in file \"${filePath}\"${\n command ? `for command \"${command}\"` : ''\n }:\\n${details}`;\n}\n\n/**\n * Checks whether the given terminus string is valid, i.e. one of `BEGIN` or `END`.\n *\n * @param terminus - The terminus string to validate.\n * @returns Whether the string is a valid terminus string.\n */\nfunction isValidTerminus(terminus: string): terminus is DirectiveTerminus {\n return hasProperty(DirectiveTerminus, terminus);\n}\n\n/**\n * Checks whether the given command string is valid.\n *\n * @param command - The command string to validate.\n * @returns Whether the string is a valid command string.\n */\nfunction isValidCommand(command: string): command is DirectiveCommand {\n return hasProperty(DirectiveCommand, command);\n}\n\n/**\n * Validates the specified command. Throws if validation fails.\n *\n * @param command - The command to validate.\n * @param params - The parameters of the command.\n * @param filePath - The path of the current file.\n * @param featureLabels - The possible feature labels.\n */\nexport function validateCommand(\n command: unknown,\n params: string[],\n filePath: string,\n featureLabels: FeatureLabels,\n): asserts command is DirectiveCommand {\n switch (command) {\n case DirectiveCommand.ONLY_INCLUDE_IF:\n if (!params || params.length === 0) {\n throw new Error(\n getInvalidParamsMessage(\n filePath,\n `No parameters specified.`,\n DirectiveCommand.ONLY_INCLUDE_IF,\n ),\n );\n }\n\n for (const param of params) {\n if (!featureLabels.all.has(param)) {\n throw new Error(\n getInvalidParamsMessage(\n filePath,\n `\"${param}\" is not a declared build feature.`,\n DirectiveCommand.ONLY_INCLUDE_IF,\n ),\n );\n }\n }\n break;\n\n default:\n throw new Error(`Unrecognized command \"${String(command)}\".`);\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"remove-fenced-code.d.cts","sourceRoot":"","sources":["../../src/transforms/remove-fenced-code.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5B,GAAG,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC1B,CAAC;AAOF,oBAAY,gBAAgB;IAI1B,eAAe,oBAAoB;CACpC;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,aAAa,GAC3B,CAAC,MAAM,EAAE,OAAO,CAAC,CA6NnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EAAE,GACxB,MAAM,CAuCR;AAsFD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,OAAO,IAAI,gBAAgB,CA6BrC"}
@@ -1,70 +0,0 @@
1
- /**
2
- * Two sets of feature labels, where:
3
- * - `active` is the set of labels that are active for the current build.
4
- * - `all` is the set of all labels that are declared in the codebase.
5
- *
6
- * For `ONLY_INCLUDE_IF` fences, the code fence removal transform will
7
- * include the fenced code if any of the specified labels are active. See
8
- * {@link removeFencedCode} for details.
9
- */
10
- export type FeatureLabels = {
11
- active: ReadonlySet<string>;
12
- all: ReadonlySet<string>;
13
- };
14
- export declare enum DirectiveCommand {
15
- ONLY_INCLUDE_IF = "ONLY_INCLUDE_IF"
16
- }
17
- /**
18
- * Removes fenced code from the given JavaScript source string. "Fenced code"
19
- * includes the entire fence lines, including their trailing newlines, and the
20
- * lines that they surround.
21
- *
22
- * A valid fence consists of two well-formed fence lines, separated by one or
23
- * more lines that should be excluded. The first line must contain a `BEGIN`
24
- * directive, and the second most contain an `END` directive. Both directives
25
- * must specify the same command.
26
- *
27
- * Here's an example of a valid fence:
28
- *
29
- * ```javascript
30
- * ///: BEGIN:ONLY_INCLUDE_IF(build-flask)
31
- * console.log('I am Flask.');
32
- * ///: END:ONLY_INCLUDE_IF
33
- * ```
34
- *
35
- * For details, please see the documentation.
36
- *
37
- * @param filePath - The path to the file being transformed.
38
- * @param fileContent - The contents of the file being transformed.
39
- * @param featureLabels - FeatureLabels that are currently active.
40
- * @returns A tuple of the post-transform file contents and a boolean indicating
41
- * whether they were modified.
42
- */
43
- export declare function removeFencedCode(filePath: string, fileContent: string, featureLabels: FeatureLabels): [string, boolean];
44
- /**
45
- * Returns a copy of the given string, without the character ranges specified
46
- * by the splicing indices array.
47
- *
48
- * The splicing indices must be a non-empty, even-length array of non-negative
49
- * integers, specifying the character ranges to remove from the given string, as
50
- * follows:
51
- *
52
- * `[ start, end, start, end, start, end, ... ]`
53
- *
54
- * Throws if the array is not an even-length array of non-negative integers.
55
- *
56
- * @param toSplice - The string to splice.
57
- * @param splicingIndices - Indices to splice at.
58
- * @returns The spliced string.
59
- */
60
- export declare function multiSplice(toSplice: string, splicingIndices: number[]): string;
61
- /**
62
- * Validates the specified command. Throws if validation fails.
63
- *
64
- * @param command - The command to validate.
65
- * @param params - The parameters of the command.
66
- * @param filePath - The path of the current file.
67
- * @param featureLabels - The possible feature labels.
68
- */
69
- export declare function validateCommand(command: unknown, params: string[], filePath: string, featureLabels: FeatureLabels): asserts command is DirectiveCommand;
70
- //# sourceMappingURL=remove-fenced-code.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"remove-fenced-code.d.mts","sourceRoot":"","sources":["../../src/transforms/remove-fenced-code.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC5B,GAAG,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC1B,CAAC;AAOF,oBAAY,gBAAgB;IAI1B,eAAe,oBAAoB;CACpC;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,aAAa,GAC3B,CAAC,MAAM,EAAE,OAAO,CAAC,CA6NnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,EAAE,GACxB,MAAM,CAuCR;AAsFD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,OAAO,IAAI,gBAAgB,CA6BrC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"remove-fenced-code.mjs","sourceRoot":"","sources":["../../src/transforms/remove-fenced-code.ts"],"names":[],"mappings":"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","sourcesContent":["import { hasProperty } from '@metamask/utils';\n\n/**\n * Two sets of feature labels, where:\n * - `active` is the set of labels that are active for the current build.\n * - `all` is the set of all labels that are declared in the codebase.\n *\n * For `ONLY_INCLUDE_IF` fences, the code fence removal transform will\n * include the fenced code if any of the specified labels are active. See\n * {@link removeFencedCode} for details.\n */\nexport type FeatureLabels = {\n active: ReadonlySet<string>;\n all: ReadonlySet<string>;\n};\n\nenum DirectiveTerminus {\n BEGIN = 'BEGIN',\n END = 'END',\n}\n\nexport enum DirectiveCommand {\n // TODO: This should be `OnlyIncludeIf`, but we need to preserve\n // backwards-compatibility for now.\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ONLY_INCLUDE_IF = 'ONLY_INCLUDE_IF',\n}\n\n// Matches lines starting with \"///:\", and any preceding whitespace, except\n// newlines. We except newlines to avoid eating blank lines preceding a fenced\n// line.\n// Double-negative RegEx credit: https://stackoverflow.com/a/3469155\nconst linesWithFenceRegex = /^[^\\S\\r\\n]*\\/\\/\\/:.*$/gmu;\n\n// Matches the first \"///:\" in a string, and any preceding whitespace\nconst fenceSentinelRegex = /^\\s*\\/\\/\\/:/u;\n\n// Breaks a fence directive into its constituent components.\n// At this stage of parsing, we are looking for one of:\n// - TERMINUS:COMMAND(PARAMS)\n// - TERMINUS:COMMAND\nconst directiveParsingRegex =\n /^([A-Z]+):([A-Z_]+)(?:\\(((?:\\w[-\\w]*,)*\\w[-\\w]*)\\))?$/u;\n\n/**\n * Removes fenced code from the given JavaScript source string. \"Fenced code\"\n * includes the entire fence lines, including their trailing newlines, and the\n * lines that they surround.\n *\n * A valid fence consists of two well-formed fence lines, separated by one or\n * more lines that should be excluded. The first line must contain a `BEGIN`\n * directive, and the second most contain an `END` directive. Both directives\n * must specify the same command.\n *\n * Here's an example of a valid fence:\n *\n * ```javascript\n * ///: BEGIN:ONLY_INCLUDE_IF(build-flask)\n * console.log('I am Flask.');\n * ///: END:ONLY_INCLUDE_IF\n * ```\n *\n * For details, please see the documentation.\n *\n * @param filePath - The path to the file being transformed.\n * @param fileContent - The contents of the file being transformed.\n * @param featureLabels - FeatureLabels that are currently active.\n * @returns A tuple of the post-transform file contents and a boolean indicating\n * whether they were modified.\n */\nexport function removeFencedCode(\n filePath: string,\n fileContent: string,\n featureLabels: FeatureLabels,\n): [string, boolean] {\n // Do not modify the file if we detect an inline sourcemap. For reasons\n // yet to be determined, the transform receives every file twice while in\n // watch mode, the second after Babel has transpiled the file. Babel adds\n // inline source maps to the file, something we will never do in our own\n // source files, so we use the existence of inline source maps to determine\n // whether we should ignore the file.\n if (/^\\/\\/# sourceMappingURL=/gmu.test(fileContent)) {\n return [fileContent, false];\n }\n\n // If we didn't match any lines, return the unmodified file contents.\n const matchedLines = [...fileContent.matchAll(linesWithFenceRegex)];\n\n if (matchedLines.length === 0) {\n return [fileContent, false];\n }\n\n // Parse fence lines\n const parsedDirectives = matchedLines.map((matchArray) => {\n const line = matchArray[0];\n\n /* istanbul ignore next: should be impossible */\n if (\n matchArray.index === undefined ||\n !line ||\n !fenceSentinelRegex.test(line)\n ) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line ?? '',\n `Fence sentinel may only appear at the start of a line, optionally preceded by whitespace.`,\n ),\n );\n }\n\n // Store the start and end indices of each line\n // Increment the end index by 1 to including the trailing newline when\n // performing string operations.\n const indices: [number, number] = [\n matchArray.index,\n matchArray.index + line.length + 1,\n ];\n\n const lineWithoutSentinel = line.replace(fenceSentinelRegex, '');\n if (!/^ \\w\\w+/u.test(lineWithoutSentinel)) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line,\n `Fence sentinel must be followed by a single space and an alphabetical string of two or more characters.`,\n ),\n );\n }\n\n const directiveMatches = lineWithoutSentinel\n .trim()\n .match(directiveParsingRegex);\n\n if (!directiveMatches) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line,\n `Failed to parse fence directive.`,\n ),\n );\n }\n\n // The first element of a RegEx match array is the input.\n // Typecast: If there's a match, the expected elements must exist.\n const [, terminus, command, parameters] = directiveMatches as [\n string,\n string,\n string,\n string,\n ];\n\n if (!isValidTerminus(terminus)) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line,\n `Line contains invalid directive terminus \"${terminus}\".`,\n ),\n );\n }\n\n if (!isValidCommand(command)) {\n throw new Error(\n getInvalidFenceLineMessage(\n filePath,\n line,\n `Line contains invalid directive command \"${command}\".`,\n ),\n );\n }\n\n if (terminus === DirectiveTerminus.BEGIN) {\n if (!parameters) {\n throw new Error(\n getInvalidParamsMessage(filePath, `No parameters specified.`),\n );\n }\n\n return {\n command,\n indices,\n line,\n parameters: parameters.split(','),\n terminus,\n };\n }\n return { command, indices, line, terminus };\n });\n\n if (parsedDirectives.length % 2 !== 0) {\n throw new Error(\n getInvalidFenceStructureMessage(\n filePath,\n `A valid fence consists of two fence lines, but the file contains an uneven number, \"${parsedDirectives.length}\", of fence lines.`,\n ),\n );\n }\n\n // The below for-loop iterates over the parsed fence directives and performs\n // the following work:\n // - Ensures that the array of parsed directives consists of valid directive\n // pairs, as specified in the documentation.\n // - For each directive pair, determines whether their fenced lines should be\n // removed for the current build, and if so, stores the indices we will use\n // to splice the file content string.\n\n const splicingIndices: number[] = [];\n let shouldSplice = false;\n let currentCommand: string;\n\n parsedDirectives.forEach((directive, i) => {\n const { line, indices, terminus, command } = directive;\n\n if (i % 2 === 0) {\n if (terminus !== DirectiveTerminus.BEGIN) {\n throw new Error(\n getInvalidFencePairMessage(\n filePath,\n line,\n `The first directive of a pair must be a \"BEGIN\" directive.`,\n ),\n );\n }\n\n const { parameters } = directive;\n currentCommand = command;\n validateCommand(command, parameters, filePath, featureLabels);\n\n const blockIsActive = parameters.some((param) =>\n featureLabels.active.has(param),\n );\n\n if (blockIsActive) {\n shouldSplice = false;\n } else {\n shouldSplice = true;\n\n // Add start index of BEGIN directive line to splicing indices\n splicingIndices.push(indices[0]);\n }\n } else {\n if (terminus !== DirectiveTerminus.END) {\n throw new Error(\n getInvalidFencePairMessage(\n filePath,\n line,\n `The second directive of a pair must be an \"END\" directive.`,\n ),\n );\n }\n\n /* istanbul ignore next: impossible until there's more than one command */\n if (command !== currentCommand) {\n throw new Error(\n getInvalidFencePairMessage(\n filePath,\n line,\n `Expected \"END\" directive to have command \"${currentCommand}\" but found \"${command}\".`,\n ),\n );\n }\n\n // Forbid empty fences\n const { line: previousLine, indices: previousIndices } =\n // We're only in this case if i > 0, so this will always be defined.\n parsedDirectives[i - 1];\n if (fileContent.substring(previousIndices[1], indices[0]).trim() === '') {\n throw new Error(\n `Empty fence found in file \"${filePath}\":\\n${previousLine}\\n${line}\\n`,\n );\n }\n\n if (shouldSplice) {\n // Add end index of END directive line to splicing indices\n splicingIndices.push(indices[1]);\n }\n }\n });\n\n // This indicates that the present build type should include all fenced code,\n // and so we just returned the unmodified file contents.\n if (splicingIndices.length === 0) {\n return [fileContent, false];\n }\n\n /* istanbul ignore next: should be impossible */\n if (splicingIndices.length % 2 !== 0) {\n throw new Error(\n `Internal error while transforming file \"${filePath}\":\\nCollected an uneven number of splicing indices: \"${splicingIndices.length}\"`,\n );\n }\n\n return [multiSplice(fileContent, splicingIndices), true];\n}\n\n/**\n * Returns a copy of the given string, without the character ranges specified\n * by the splicing indices array.\n *\n * The splicing indices must be a non-empty, even-length array of non-negative\n * integers, specifying the character ranges to remove from the given string, as\n * follows:\n *\n * `[ start, end, start, end, start, end, ... ]`\n *\n * Throws if the array is not an even-length array of non-negative integers.\n *\n * @param toSplice - The string to splice.\n * @param splicingIndices - Indices to splice at.\n * @returns The spliced string.\n */\nexport function multiSplice(\n toSplice: string,\n splicingIndices: number[],\n): string {\n if (splicingIndices.length === 0 || splicingIndices.length % 2 !== 0) {\n throw new Error('Expected non-empty, even-length array.');\n }\n if (splicingIndices.some((index) => !Number.isInteger(index) || index < 0)) {\n throw new Error('Expected array of non-negative integers.');\n }\n\n const retainedSubstrings: string[] = [];\n\n // Get the first part to be included\n // The substring() call returns an empty string if splicingIndices[0] is 0,\n // which is exactly what we want in that case.\n retainedSubstrings.push(toSplice.substring(0, splicingIndices[0]));\n\n // This loop gets us all parts of the string that should be retained, except\n // the first and the last.\n // It iterates over all \"end\" indices of the array except the last one, and\n // pushes the substring between each \"end\" index and the next \"begin\" index\n // to the array of retained substrings.\n if (splicingIndices.length > 2) {\n // Note the boundary index of \"splicingIndices.length - 1\". This loop must\n // not iterate over the last element of the array, which is handled outside\n // of this loop.\n for (let i = 1; i < splicingIndices.length - 1; i += 2) {\n retainedSubstrings.push(\n // splicingIndices[i] refers to an element between the first and last\n // elements of the array, and will always be defined.\n toSplice.substring(splicingIndices[i], splicingIndices[i + 1]),\n );\n }\n }\n\n // Get the last part to be included\n retainedSubstrings.push(\n // The last element of a non-empty array will always be defined.\n toSplice.substring(splicingIndices[splicingIndices.length - 1]),\n );\n return retainedSubstrings.join('');\n}\n\n/**\n * Gets an invalid fence line error message.\n *\n * @param filePath - The path to the file that caused the error.\n * @param line - The contents of the line with the error.\n * @param details - An explanation of the error.\n * @returns The error message.\n */\nfunction getInvalidFenceLineMessage(\n filePath: string,\n line: string,\n details: string,\n): string {\n return `Invalid fence line in file \"${filePath}\": \"${line}\":\\n${details}`;\n}\n\n/**\n * Gets an invalid fence structure error message.\n *\n * @param filePath - The path to the file that caused the error.\n * @param details - An explanation of the error.\n * @returns The error message.\n */\nfunction getInvalidFenceStructureMessage(\n filePath: string,\n details: string,\n): string {\n return `Invalid fence structure in file \"${filePath}\":\\n${details}`;\n}\n\n/**\n * Gets an invalid fence pair error message.\n *\n * @param filePath - The path to the file that caused the error.\n * @param line - The contents of the line with the error.\n * @param details - An explanation of the error.\n * @returns The error message.\n */\nfunction getInvalidFencePairMessage(\n filePath: string,\n line: string,\n details: string,\n): string {\n return `Invalid fence pair in file \"${filePath}\" due to line \"${line}\":\\n${details}`;\n}\n\n/**\n * Gets an invalid command params error message.\n *\n * @param filePath - The path to the file that caused the error.\n * @param details - An explanation of the error.\n * @param command - The command of the directive with the invalid parameters, if known.\n * @returns The error message.\n */\nfunction getInvalidParamsMessage(\n filePath: string,\n details: string,\n command?: string,\n): string {\n return `Invalid code fence parameters in file \"${filePath}\"${\n command ? `for command \"${command}\"` : ''\n }:\\n${details}`;\n}\n\n/**\n * Checks whether the given terminus string is valid, i.e. one of `BEGIN` or `END`.\n *\n * @param terminus - The terminus string to validate.\n * @returns Whether the string is a valid terminus string.\n */\nfunction isValidTerminus(terminus: string): terminus is DirectiveTerminus {\n return hasProperty(DirectiveTerminus, terminus);\n}\n\n/**\n * Checks whether the given command string is valid.\n *\n * @param command - The command string to validate.\n * @returns Whether the string is a valid command string.\n */\nfunction isValidCommand(command: string): command is DirectiveCommand {\n return hasProperty(DirectiveCommand, command);\n}\n\n/**\n * Validates the specified command. Throws if validation fails.\n *\n * @param command - The command to validate.\n * @param params - The parameters of the command.\n * @param filePath - The path of the current file.\n * @param featureLabels - The possible feature labels.\n */\nexport function validateCommand(\n command: unknown,\n params: string[],\n filePath: string,\n featureLabels: FeatureLabels,\n): asserts command is DirectiveCommand {\n switch (command) {\n case DirectiveCommand.ONLY_INCLUDE_IF:\n if (!params || params.length === 0) {\n throw new Error(\n getInvalidParamsMessage(\n filePath,\n `No parameters specified.`,\n DirectiveCommand.ONLY_INCLUDE_IF,\n ),\n );\n }\n\n for (const param of params) {\n if (!featureLabels.all.has(param)) {\n throw new Error(\n getInvalidParamsMessage(\n filePath,\n `\"${param}\" is not a declared build feature.`,\n DirectiveCommand.ONLY_INCLUDE_IF,\n ),\n );\n }\n }\n break;\n\n default:\n throw new Error(`Unrecognized command \"${String(command)}\".`);\n }\n}\n"]}
@@ -1,48 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.lintTransformedFile = void 0;
4
- // Four spaces
5
- const TAB = ' ';
6
- /**
7
- * Lints a transformed file by invoking ESLint programmatically on the string
8
- * file contents. The path to the file must be specified so that the repository
9
- * ESLint config can be applied properly.
10
- *
11
- * **ATTN:** See the `eslintInstance` parameter documentation for important usage
12
- * information.
13
- *
14
- * An error is thrown if linting produced any errors, or if the file is ignored
15
- * by ESLint. Files linted by this function must not be ignored by ESLint.
16
- *
17
- * @param eslintInstance - The ESLint instance to use for linting. This instance
18
- * needs to be initialized with the options `{ baseConfig, useEslintrc: false}`,
19
- * where `baseConfig` is the desired ESLint configuration for linting. If using
20
- * your project's regular `.eslintrc` file, you may need to modify certain rules
21
- * for linting to pass after code fences are removed. Stylistic rules are
22
- * particularly likely to cause problems.
23
- * @param filePath - The path to the file.
24
- * @param fileContent - The file content.
25
- * @returns Returns `undefined` or throws an error if linting produced
26
- * any errors, or if the linted file is ignored.
27
- */
28
- async function lintTransformedFile(eslintInstance, filePath, fileContent) {
29
- const lintResult = (await eslintInstance.lintText(fileContent, { filePath, warnIgnored: false }))[0];
30
- // This indicates that the file is ignored, which should never be the case for
31
- // a transformed file.
32
- if (lintResult === undefined) {
33
- throw new Error(`MetaMask build: Transformed file "${filePath}" appears to be ignored by ESLint.`);
34
- }
35
- // This is the success case
36
- if (lintResult.errorCount === 0) {
37
- return;
38
- }
39
- // Errors are stored in the messages array, and their "severity" is 2
40
- const errorsString = lintResult.messages
41
- .filter(({ severity }) => severity === 2)
42
- .reduce((allErrors, { message, ruleId }) => {
43
- return allErrors.concat(`${TAB}${ruleId ?? '<Unknown rule>'}\n${TAB}${message}\n\n`);
44
- }, '');
45
- throw new Error(`MetaMask build: Lint errors encountered for transformed file "${filePath}":\n\n${errorsString}`);
46
- }
47
- exports.lintTransformedFile = lintTransformedFile;
48
- //# sourceMappingURL=utils.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../src/transforms/utils.ts"],"names":[],"mappings":";;;AAEA,cAAc;AACd,MAAM,GAAG,GAAG,MAAM,CAAC;AAEnB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACI,KAAK,UAAU,mBAAmB,CACvC,cAAsB,EACtB,QAAgB,EAChB,WAAmB;IAEnB,MAAM,UAAU,GAAG,CACjB,MAAM,cAAc,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAC7E,CAAC,CAAC,CAAC,CAAC;IAEL,8EAA8E;IAC9E,sBAAsB;IACtB,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,qCAAqC,QAAQ,oCAAoC,CAClF,CAAC;IACJ,CAAC;IAED,2BAA2B;IAC3B,IAAI,UAAU,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO;IACT,CAAC;IAED,qEAAqE;IACrE,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ;SACrC,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,KAAK,CAAC,CAAC;SACxC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QACzC,OAAO,SAAS,CAAC,MAAM,CACrB,GAAG,GAAG,GAAG,MAAM,IAAI,gBAAgB,KAAK,GAAG,GAAG,OAAO,MAAM,CAC5D,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAET,MAAM,IAAI,KAAK,CACb,iEAAiE,QAAQ,SAAS,YAAY,EAAE,CACjG,CAAC;AACJ,CAAC;AAlCD,kDAkCC","sourcesContent":["import type { ESLint } from 'eslint';\n\n// Four spaces\nconst TAB = ' ';\n\n/**\n * Lints a transformed file by invoking ESLint programmatically on the string\n * file contents. The path to the file must be specified so that the repository\n * ESLint config can be applied properly.\n *\n * **ATTN:** See the `eslintInstance` parameter documentation for important usage\n * information.\n *\n * An error is thrown if linting produced any errors, or if the file is ignored\n * by ESLint. Files linted by this function must not be ignored by ESLint.\n *\n * @param eslintInstance - The ESLint instance to use for linting. This instance\n * needs to be initialized with the options `{ baseConfig, useEslintrc: false}`,\n * where `baseConfig` is the desired ESLint configuration for linting. If using\n * your project's regular `.eslintrc` file, you may need to modify certain rules\n * for linting to pass after code fences are removed. Stylistic rules are\n * particularly likely to cause problems.\n * @param filePath - The path to the file.\n * @param fileContent - The file content.\n * @returns Returns `undefined` or throws an error if linting produced\n * any errors, or if the linted file is ignored.\n */\nexport async function lintTransformedFile(\n eslintInstance: ESLint,\n filePath: string,\n fileContent: string,\n): Promise<void> {\n const lintResult = (\n await eslintInstance.lintText(fileContent, { filePath, warnIgnored: false })\n )[0];\n\n // This indicates that the file is ignored, which should never be the case for\n // a transformed file.\n if (lintResult === undefined) {\n throw new Error(\n `MetaMask build: Transformed file \"${filePath}\" appears to be ignored by ESLint.`,\n );\n }\n\n // This is the success case\n if (lintResult.errorCount === 0) {\n return;\n }\n\n // Errors are stored in the messages array, and their \"severity\" is 2\n const errorsString = lintResult.messages\n .filter(({ severity }) => severity === 2)\n .reduce((allErrors, { message, ruleId }) => {\n return allErrors.concat(\n `${TAB}${ruleId ?? '<Unknown rule>'}\\n${TAB}${message}\\n\\n`,\n );\n }, '');\n\n throw new Error(\n `MetaMask build: Lint errors encountered for transformed file \"${filePath}\":\\n\\n${errorsString}`,\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../src/transforms/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe;AAKrC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
@@ -1,25 +0,0 @@
1
- import type { ESLint } from "eslint";
2
- /**
3
- * Lints a transformed file by invoking ESLint programmatically on the string
4
- * file contents. The path to the file must be specified so that the repository
5
- * ESLint config can be applied properly.
6
- *
7
- * **ATTN:** See the `eslintInstance` parameter documentation for important usage
8
- * information.
9
- *
10
- * An error is thrown if linting produced any errors, or if the file is ignored
11
- * by ESLint. Files linted by this function must not be ignored by ESLint.
12
- *
13
- * @param eslintInstance - The ESLint instance to use for linting. This instance
14
- * needs to be initialized with the options `{ baseConfig, useEslintrc: false}`,
15
- * where `baseConfig` is the desired ESLint configuration for linting. If using
16
- * your project's regular `.eslintrc` file, you may need to modify certain rules
17
- * for linting to pass after code fences are removed. Stylistic rules are
18
- * particularly likely to cause problems.
19
- * @param filePath - The path to the file.
20
- * @param fileContent - The file content.
21
- * @returns Returns `undefined` or throws an error if linting produced
22
- * any errors, or if the linted file is ignored.
23
- */
24
- export declare function lintTransformedFile(eslintInstance: ESLint, filePath: string, fileContent: string): Promise<void>;
25
- //# sourceMappingURL=utils.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../src/transforms/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe;AAKrC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CA8Bf"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.mjs","sourceRoot":"","sources":["../../src/transforms/utils.ts"],"names":[],"mappings":"AAEA,cAAc;AACd,MAAM,GAAG,GAAG,MAAM,CAAC;AAEnB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,cAAsB,EACtB,QAAgB,EAChB,WAAmB;IAEnB,MAAM,UAAU,GAAG,CACjB,MAAM,cAAc,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAC7E,CAAC,CAAC,CAAC,CAAC;IAEL,8EAA8E;IAC9E,sBAAsB;IACtB,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,qCAAqC,QAAQ,oCAAoC,CAClF,CAAC;IACJ,CAAC;IAED,2BAA2B;IAC3B,IAAI,UAAU,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO;IACT,CAAC;IAED,qEAAqE;IACrE,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ;SACrC,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,QAAQ,KAAK,CAAC,CAAC;SACxC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QACzC,OAAO,SAAS,CAAC,MAAM,CACrB,GAAG,GAAG,GAAG,MAAM,IAAI,gBAAgB,KAAK,GAAG,GAAG,OAAO,MAAM,CAC5D,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAET,MAAM,IAAI,KAAK,CACb,iEAAiE,QAAQ,SAAS,YAAY,EAAE,CACjG,CAAC;AACJ,CAAC","sourcesContent":["import type { ESLint } from 'eslint';\n\n// Four spaces\nconst TAB = ' ';\n\n/**\n * Lints a transformed file by invoking ESLint programmatically on the string\n * file contents. The path to the file must be specified so that the repository\n * ESLint config can be applied properly.\n *\n * **ATTN:** See the `eslintInstance` parameter documentation for important usage\n * information.\n *\n * An error is thrown if linting produced any errors, or if the file is ignored\n * by ESLint. Files linted by this function must not be ignored by ESLint.\n *\n * @param eslintInstance - The ESLint instance to use for linting. This instance\n * needs to be initialized with the options `{ baseConfig, useEslintrc: false}`,\n * where `baseConfig` is the desired ESLint configuration for linting. If using\n * your project's regular `.eslintrc` file, you may need to modify certain rules\n * for linting to pass after code fences are removed. Stylistic rules are\n * particularly likely to cause problems.\n * @param filePath - The path to the file.\n * @param fileContent - The file content.\n * @returns Returns `undefined` or throws an error if linting produced\n * any errors, or if the linted file is ignored.\n */\nexport async function lintTransformedFile(\n eslintInstance: ESLint,\n filePath: string,\n fileContent: string,\n): Promise<void> {\n const lintResult = (\n await eslintInstance.lintText(fileContent, { filePath, warnIgnored: false })\n )[0];\n\n // This indicates that the file is ignored, which should never be the case for\n // a transformed file.\n if (lintResult === undefined) {\n throw new Error(\n `MetaMask build: Transformed file \"${filePath}\" appears to be ignored by ESLint.`,\n );\n }\n\n // This is the success case\n if (lintResult.errorCount === 0) {\n return;\n }\n\n // Errors are stored in the messages array, and their \"severity\" is 2\n const errorsString = lintResult.messages\n .filter(({ severity }) => severity === 2)\n .reduce((allErrors, { message, ruleId }) => {\n return allErrors.concat(\n `${TAB}${ruleId ?? '<Unknown rule>'}\\n${TAB}${message}\\n\\n`,\n );\n }, '');\n\n throw new Error(\n `MetaMask build: Lint errors encountered for transformed file \"${filePath}\":\\n\\n${errorsString}`,\n );\n}\n"]}