@metamask/snaps-cli 5.0.0 → 5.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -1
- package/dist/cjs/config.js +1 -5
- package/dist/cjs/config.js.map +1 -1
- package/dist/cjs/webpack/config.js +23 -7
- package/dist/cjs/webpack/config.js.map +1 -1
- package/dist/cjs/webpack/loaders/wasm.js +3 -1
- package/dist/cjs/webpack/loaders/wasm.js.map +1 -1
- package/dist/cjs/webpack/plugins.js +22 -21
- package/dist/cjs/webpack/plugins.js.map +1 -1
- package/dist/cjs/webpack/utils.js +77 -4
- package/dist/cjs/webpack/utils.js.map +1 -1
- package/dist/esm/config.js +1 -5
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/webpack/config.js +25 -9
- package/dist/esm/webpack/config.js.map +1 -1
- package/dist/esm/webpack/loaders/wasm.js +3 -1
- package/dist/esm/webpack/loaders/wasm.js.map +1 -1
- package/dist/esm/webpack/plugins.js +24 -23
- package/dist/esm/webpack/plugins.js.map +1 -1
- package/dist/esm/webpack/utils.js +81 -4
- package/dist/esm/webpack/utils.js.map +1 -1
- package/dist/types/webpack/plugins.d.ts +1 -1
- package/dist/types/webpack/utils.d.ts +30 -3
- package/package.json +6 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/webpack/plugins.ts"],"sourcesContent":["import { indent } from '@metamask/snaps-utils';\nimport { assert, hasProperty, isObject } from '@metamask/utils';\nimport { dim, red, yellow } from 'chalk';\nimport { isBuiltin } from 'module';\nimport type { Ora } from 'ora';\nimport type {\n Compiler,\n ProvidePlugin,\n ResolvePluginInstance,\n Resolver,\n StatsError,\n WebpackPluginInstance,\n} from 'webpack';\n\nimport { evaluate } from '../commands/eval';\nimport { error, getErrorMessage, info, warn } from '../utils';\nimport { pluralize } from './utils';\n\nexport type SnapsStatsPluginOptions = {\n /**\n * Whether to log the verbose stats.\n */\n verbose?: boolean;\n};\n\n/**\n * A plugin that logs the stats after compilation. This is useful for logging\n * the number of files compiled, and the time taken to compile them.\n */\nexport class SnapsStatsPlugin implements WebpackPluginInstance {\n /**\n * The options for the plugin.\n */\n readonly options: SnapsStatsPluginOptions;\n\n /**\n * The spinner to use for logging.\n */\n readonly #spinner?: Ora;\n\n constructor(\n options: SnapsStatsPluginOptions = {\n verbose: false,\n },\n spinner?: Ora,\n ) {\n this.options = options;\n this.#spinner = spinner;\n }\n\n /**\n * Apply the plugin to the Webpack compiler.\n *\n * @param compiler - The Webpack compiler.\n */\n apply(compiler: Compiler) {\n compiler.hooks.afterDone.tap(this.constructor.name, (stats) => {\n if (!stats) {\n return;\n }\n\n const { modules, time, errors } = stats.toJson();\n\n assert(modules, 'Modules must be defined in stats.');\n assert(time, 'Time must be defined in stats.');\n\n if (errors?.length) {\n const formattedErrors = errors\n .map(this.#getStatsErrorMessage.bind(this))\n .join('\\n\\n');\n\n error(\n `Compiled ${modules.length} ${pluralize(\n modules.length,\n 'file',\n )} in ${time}ms with ${errors.length} ${pluralize(\n errors.length,\n 'error',\n )}.\\n\\n${formattedErrors}\\n`,\n this.#spinner,\n );\n\n this.#spinner?.stop();\n\n process.exitCode = 1;\n return;\n }\n\n info(\n `Compiled ${modules.length} ${pluralize(\n modules.length,\n 'file',\n )} in ${time}ms.`,\n this.#spinner,\n );\n\n if (compiler.watchMode) {\n // The spinner may be restarted by the watch plugin, outside of the\n // `executeSteps` flow, so we stop it here just in case.\n this.#spinner?.succeed('Done!');\n }\n });\n }\n\n /**\n * Get the error message for the given stats error.\n *\n * @param statsError - The stats error.\n * @returns The error message.\n */\n #getStatsErrorMessage(statsError: StatsError) {\n const baseMessage = this.options.verbose\n ? getErrorMessage(statsError)\n : statsError.message;\n\n const [first, ...rest] = baseMessage.split('\\n');\n\n return [\n indent(red(`• ${first}`), 2),\n ...rest.map((message) => indent(red(message), 4)),\n statsError.details && indent(dim(statsError.details), 4),\n ]\n .filter(Boolean)\n .join('\\n');\n }\n}\n\n/**\n * The options for the {@link SnapsWatchPlugin}.\n */\nexport type SnapsWatchPluginOptions = {\n /**\n * The bundle path. This is the file that will be evaluated, if the `evaluate`\n * option is set.\n */\n bundle?: string;\n\n /**\n * Whether to evaluate the bundle. This only applies if the `bundle` option is\n * set.\n */\n evaluate?: boolean;\n\n /**\n * The extra files to watch.\n */\n files?: string[];\n};\n\n/**\n * A plugin that adds extra files to watch. This is useful for watching files\n * that are not imported by the entry point, such as the `snap.manifest.json`\n * file.\n */\nexport class SnapsWatchPlugin implements WebpackPluginInstance {\n /**\n * The options for the plugin.\n */\n readonly options: SnapsWatchPluginOptions;\n\n /**\n * The spinner to use for logging.\n */\n readonly #spinner?: Ora;\n\n constructor(options: SnapsWatchPluginOptions, spinner?: Ora) {\n this.options = options;\n this.#spinner = spinner;\n }\n\n /**\n * Apply the plugin to the Webpack compiler.\n *\n * @param compiler - The Webpack compiler.\n */\n apply(compiler: Compiler) {\n compiler.hooks.invalid.tap(this.constructor.name, (file) => {\n this.#spinner?.start();\n info(`Changes detected in ${yellow(file)}, recompiling.`, this.#spinner);\n });\n\n compiler.hooks.afterEmit.tapPromise(\n this.constructor.name,\n async ({ fileDependencies }) => {\n this.options.files?.forEach(\n fileDependencies.add.bind(fileDependencies),\n );\n\n if (this.options.bundle && this.options.evaluate) {\n await this.#safeEvaluate(this.options.bundle);\n }\n },\n );\n }\n\n /**\n * Safely evaluate the bundle at the given path. If an error occurs, it will\n * be logged to the console, rather than throwing an error.\n *\n * This function should never throw an error.\n *\n * @param bundlePath - The path to the bundle.\n */\n async #safeEvaluate(bundlePath: string) {\n try {\n await evaluate(bundlePath);\n info(`Snap bundle evaluated successfully.`, this.#spinner);\n } catch (evaluateError) {\n error(evaluateError.message, this.#spinner);\n }\n }\n}\n\n/**\n * The options for the {@link SnapsBuiltInResolver}.\n */\nexport type SnapsBuiltInResolverOptions = {\n /**\n * The built-in modules to ignore.\n */\n ignore?: string[];\n};\n\n/**\n * A plugin that logs a message when a built-in module is not resolved. The\n * MetaMask Snaps CLI does not support built-in modules by default, and this\n * plugin is used to warn the user when they try to import a built-in module,\n * when no fallback is configured.\n */\nexport class SnapsBuiltInResolver implements ResolvePluginInstance {\n /**\n * The built-in modules that have been imported, but not resolved.\n */\n readonly unresolvedModules = new Set<string>();\n\n /**\n * The name of the resolver hook to tap into.\n */\n readonly #source = 'described-resolve';\n\n /**\n * The options for the plugin.\n */\n readonly options: SnapsBuiltInResolverOptions;\n\n /**\n * The spinner to use for logging.\n */\n readonly #spinner?: Ora;\n\n constructor(\n options: SnapsBuiltInResolverOptions = {\n ignore: [],\n },\n spinner?: Ora,\n ) {\n this.options = options;\n this.#spinner = spinner;\n }\n\n /**\n * Apply the plugin to the Webpack resolver.\n *\n * @param resolver - The Webpack resolver.\n */\n apply(resolver: Resolver) {\n resolver\n .getHook(this.#source)\n .tapAsync(\n this.constructor.name,\n ({ module: isModule, request }, _, callback) => {\n if (!isModule || !request) {\n return callback();\n }\n\n const baseRequest = request.split('/')[0];\n if (\n isBuiltin(baseRequest) &&\n !this.options.ignore?.includes(baseRequest)\n ) {\n const fallback = resolver.options.fallback.find(\n ({ name }) => name === baseRequest,\n );\n\n if (fallback && !fallback.alias) {\n this.unresolvedModules.add(baseRequest);\n }\n }\n\n return callback();\n },\n );\n }\n}\n\n/**\n * The options for the {@link SnapsBundleWarningsPlugin}.\n */\nexport type SnapsBundleWarningsPluginOptions = {\n /**\n * The {@link SnapsBuiltInResolver} instance to use for detecting built-in\n * modules.\n */\n builtInResolver?: SnapsBuiltInResolver | false;\n\n /**\n * Whether to show warnings if built-in modules are used, but not provided by\n * Webpack's `fallback` configuration.\n */\n builtIns?: boolean;\n\n /**\n * Whether to show warnings if the `Buffer` global is used, but not provided\n * by Webpack's `DefinePlugin`.\n */\n buffer?: boolean;\n};\n\n/**\n * A plugin that logs a message when:\n *\n * - A built-in module is not resolved. The MetaMask Snaps CLI does not support\n * built-in modules by default, and this plugin is used to warn the user when\n * they try to import a built-in module, when no fallback is configured.\n * - A snap uses the `Buffer` global. The MetaMask Snaps CLI does not support\n * the `Buffer` global by default, and this plugin is used to warn the user when\n * they try to use the `Buffer` global.\n *\n * We use both a resolver and a plugin, because the resolver is used to detect\n * when a built-in module is imported, and the plugin is used to log a single\n * message when the compilation is complete. We can't do everything in a single\n * plugin, because the resolver doesn't have access to the compilation, and the\n * plugin doesn't have access to the resolver.\n */\n\nexport class SnapsBundleWarningsPlugin implements WebpackPluginInstance {\n /**\n * The spinner to use for logging.\n */\n readonly #spinner?: Ora;\n\n /**\n * The options for the plugin.\n */\n readonly options: SnapsBundleWarningsPluginOptions;\n\n constructor(\n options: SnapsBundleWarningsPluginOptions = {\n buffer: true,\n builtIns: true,\n },\n spinner?: Ora,\n ) {\n this.options = options;\n this.#spinner = spinner;\n }\n\n /**\n * Apply the plugin to the Webpack compiler.\n *\n * @param compiler - The Webpack compiler.\n */\n apply(compiler: Compiler) {\n if (this.options.builtIns) {\n this.#checkBuiltIns(compiler);\n }\n\n if (this.options.buffer) {\n this.#checkBuffer(compiler);\n }\n }\n\n /**\n * Check if a built-in module is used, but not provided by Webpack's\n * `fallback` configuration.\n *\n * @param compiler - The Webpack compiler.\n */\n #checkBuiltIns(compiler: Compiler) {\n compiler.hooks.afterCompile.tap(this.constructor.name, () => {\n if (!this.options.builtInResolver) {\n return;\n }\n\n const { unresolvedModules } = this.options.builtInResolver;\n if (unresolvedModules.size === 0) {\n return;\n }\n\n const formattedModules = new Array(...unresolvedModules)\n .map((name) => indent(`• ${name}`, 2))\n .join('\\n');\n\n warn(\n `The snap attempted to use one or more Node.js builtins, but no browser fallback has been provided.\\n` +\n `The MetaMask Snaps CLI does not support Node.js builtins by default. If you want to use this module, you must set ${yellow(\n `polyfills`,\n )} to ${yellow(\n `true`,\n )} or an object with the builtins to polyfill as the key and ${yellow(\n `true`,\n )} as the value.\\n` +\n `To disable this warning, set ${yellow(\n '`stats.builtIns`',\n )} to ${yellow(\n '`false`',\n )} in your snap config file, or add the module to the ${yellow(\n '`stats.builtIns.ignore`',\n )} array.\\n\\n${formattedModules}\\n`,\n this.#spinner,\n );\n });\n }\n\n /**\n * Check if the given instance is a `ProvidePlugin`. This is not guaranteed to\n * be accurate, but it's good enough for our purposes. If we were to use\n * `instanceof` instead, it might not work if multiple versions of Webpack are\n * installed.\n *\n * @param instance - The instance to check.\n * @returns Whether the instance is a `ProvidePlugin`, i.e., whether it's an\n * object with the name `ProvidePlugin` and a `definitions` property.\n */\n #isProvidePlugin(instance: unknown): instance is ProvidePlugin {\n return (\n isObject(instance) &&\n instance.constructor.name === 'ProvidePlugin' &&\n hasProperty(instance, 'definitions')\n );\n }\n\n /**\n * Check if the `Buffer` global is used, but not provided by Webpack's\n * `DefinePlugin`.\n *\n * @param compiler - The Webpack compiler.\n */\n #checkBuffer(compiler: Compiler) {\n const plugin = compiler.options.plugins?.find((instance) =>\n this.#isProvidePlugin(instance),\n ) as ProvidePlugin | undefined;\n\n // If the `ProvidePlugin` is configured to provide `Buffer`, then we don't\n // need to warn the user.\n if (plugin) {\n const { definitions } = plugin;\n if (definitions.Buffer) {\n return;\n }\n }\n\n compiler.hooks.compilation.tap(this.constructor.name, (compilation) => {\n compilation.hooks.afterProcessAssets.tap(\n this.constructor.name,\n (assets) => {\n // Check if assets use `Buffer`.\n const bufferAssets = Object.entries(assets)\n .filter(([name]) => name.endsWith('.js'))\n .filter(([, asset]) => asset.source().includes('Buffer'));\n\n if (bufferAssets.length === 0) {\n return;\n }\n\n warn(\n `The snap attempted to use the Node.js Buffer global, which is not supported in the MetaMask Snaps CLI by default.\\n` +\n `To use the Buffer global, you must polyfill Buffer by setting ${yellow(\n `buffer`,\n )} to ${yellow(`true`)} in the ${yellow(\n `polyfills`,\n )} config object in your snap config.\\n` +\n `To disable this warning, set ${yellow(\n '`stats.buffer`',\n )} to ${yellow('`false`')} in your snap config file.`,\n this.#spinner,\n );\n },\n );\n });\n }\n}\n"],"names":["SnapsStatsPlugin","SnapsWatchPlugin","SnapsBuiltInResolver","SnapsBundleWarningsPlugin","apply","compiler","hooks","afterDone","tap","constructor","name","stats","modules","time","errors","toJson","assert","length","formattedErrors","map","getStatsErrorMessage","bind","join","error","pluralize","spinner","stop","process","exitCode","info","watchMode","succeed","options","verbose","statsError","baseMessage","getErrorMessage","message","first","rest","split","indent","red","details","dim","filter","Boolean","invalid","file","start","yellow","afterEmit","tapPromise","fileDependencies","files","forEach","add","bundle","evaluate","safeEvaluate","bundlePath","evaluateError","resolver","getHook","source","tapAsync","module","isModule","request","_","callback","baseRequest","isBuiltin","ignore","includes","fallback","find","alias","unresolvedModules","Set","builtIns","checkBuiltIns","buffer","checkBuffer","afterCompile","builtInResolver","size","formattedModules","Array","warn","instance","isObject","hasProperty","plugin","plugins","isProvidePlugin","definitions","Buffer","compilation","afterProcessAssets","assets","bufferAssets","Object","entries","endsWith","asset"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/webpack/plugins.ts"],"sourcesContent":["import { assert, hasProperty, isObject } from '@metamask/utils';\nimport { bold, dim, red, yellow } from 'chalk';\nimport { isBuiltin } from 'module';\nimport type { Ora } from 'ora';\nimport type {\n Compiler,\n ProvidePlugin,\n ResolvePluginInstance,\n Resolver,\n StatsError,\n WebpackPluginInstance,\n} from 'webpack';\nimport { WebpackError } from 'webpack';\n\nimport { evaluate } from '../commands/eval';\nimport { error, getErrorMessage, info, warn } from '../utils';\nimport { formatText, pluralize } from './utils';\n\nexport type SnapsStatsPluginOptions = {\n /**\n * Whether to log the verbose stats.\n */\n verbose?: boolean;\n};\n\n/**\n * A plugin that logs the stats after compilation. This is useful for logging\n * the number of files compiled, and the time taken to compile them.\n */\nexport class SnapsStatsPlugin implements WebpackPluginInstance {\n /**\n * The options for the plugin.\n */\n readonly options: SnapsStatsPluginOptions;\n\n /**\n * The spinner to use for logging.\n */\n readonly #spinner?: Ora;\n\n constructor(\n options: SnapsStatsPluginOptions = {\n verbose: false,\n },\n spinner?: Ora,\n ) {\n this.options = options;\n this.#spinner = spinner;\n }\n\n /**\n * Apply the plugin to the Webpack compiler.\n *\n * @param compiler - The Webpack compiler.\n */\n apply(compiler: Compiler) {\n compiler.hooks.afterDone.tap(this.constructor.name, (stats) => {\n if (!stats) {\n return;\n }\n\n const { modules, time, errors, warnings } = stats.toJson();\n\n assert(modules, 'Modules must be defined in stats.');\n assert(time, 'Time must be defined in stats.');\n\n if (errors?.length) {\n const formattedErrors = errors\n .map((statsError) => this.#getStatsErrorMessage(statsError))\n .join('\\n\\n');\n\n error(\n `Compiled ${modules.length} ${pluralize(\n modules.length,\n 'file',\n )} in ${time}ms with ${errors.length} ${pluralize(\n errors.length,\n 'error',\n )}.\\n\\n${formattedErrors}\\n`,\n this.#spinner,\n );\n\n this.#spinner?.stop();\n\n process.exitCode = 1;\n return;\n }\n\n if (warnings?.length) {\n const formattedWarnings = warnings\n .map((statsWarning) =>\n this.#getStatsErrorMessage(statsWarning, yellow),\n )\n .join('\\n\\n');\n\n warn(\n `Compiled ${modules.length} ${pluralize(\n modules.length,\n 'file',\n )} in ${time}ms with ${warnings.length} ${pluralize(\n warnings.length,\n 'warning',\n )}.\\n\\n${formattedWarnings}\\n`,\n this.#spinner,\n );\n } else {\n info(\n `Compiled ${modules.length} ${pluralize(\n modules.length,\n 'file',\n )} in ${time}ms.`,\n this.#spinner,\n );\n }\n\n if (compiler.watchMode) {\n // The spinner may be restarted by the watch plugin, outside of the\n // `executeSteps` flow, so we stop it here just in case.\n this.#spinner?.succeed('Done!');\n }\n });\n }\n\n /**\n * Get the error message for the given stats error.\n *\n * @param statsError - The stats error.\n * @param color - The color to use for the error message.\n * @returns The error message.\n */\n #getStatsErrorMessage(statsError: StatsError, color = red) {\n const baseMessage = this.options.verbose\n ? getErrorMessage(statsError)\n : statsError.message;\n\n const [first, ...rest] = baseMessage.split('\\n');\n\n return [\n color(formatText(`• ${first}`, 4, 2)),\n ...rest.map((message) => formatText(color(message), 4)),\n statsError.details && `\\n${formatText(dim(statsError.details), 6)}`,\n ]\n .filter(Boolean)\n .join('\\n');\n }\n}\n\n/**\n * The options for the {@link SnapsWatchPlugin}.\n */\nexport type SnapsWatchPluginOptions = {\n /**\n * The bundle path. This is the file that will be evaluated, if the `evaluate`\n * option is set.\n */\n bundle?: string;\n\n /**\n * Whether to evaluate the bundle. This only applies if the `bundle` option is\n * set.\n */\n evaluate?: boolean;\n\n /**\n * The extra files to watch.\n */\n files?: string[];\n};\n\n/**\n * A plugin that adds extra files to watch. This is useful for watching files\n * that are not imported by the entry point, such as the `snap.manifest.json`\n * file.\n */\nexport class SnapsWatchPlugin implements WebpackPluginInstance {\n /**\n * The options for the plugin.\n */\n readonly options: SnapsWatchPluginOptions;\n\n /**\n * The spinner to use for logging.\n */\n readonly #spinner?: Ora;\n\n constructor(options: SnapsWatchPluginOptions, spinner?: Ora) {\n this.options = options;\n this.#spinner = spinner;\n }\n\n /**\n * Apply the plugin to the Webpack compiler.\n *\n * @param compiler - The Webpack compiler.\n */\n apply(compiler: Compiler) {\n compiler.hooks.invalid.tap(this.constructor.name, (file) => {\n this.#spinner?.start();\n info(`Changes detected in ${yellow(file)}, recompiling.`, this.#spinner);\n });\n\n compiler.hooks.afterEmit.tapPromise(\n this.constructor.name,\n async ({ fileDependencies }) => {\n this.options.files?.forEach(\n fileDependencies.add.bind(fileDependencies),\n );\n\n if (this.options.bundle && this.options.evaluate) {\n await this.#safeEvaluate(this.options.bundle);\n }\n },\n );\n }\n\n /**\n * Safely evaluate the bundle at the given path. If an error occurs, it will\n * be logged to the console, rather than throwing an error.\n *\n * This function should never throw an error.\n *\n * @param bundlePath - The path to the bundle.\n */\n async #safeEvaluate(bundlePath: string) {\n try {\n await evaluate(bundlePath);\n info(`Snap bundle evaluated successfully.`, this.#spinner);\n } catch (evaluateError) {\n error(evaluateError.message, this.#spinner);\n }\n }\n}\n\n/**\n * The options for the {@link SnapsBuiltInResolver}.\n */\nexport type SnapsBuiltInResolverOptions = {\n /**\n * The built-in modules to ignore.\n */\n ignore?: string[];\n};\n\n/**\n * A plugin that logs a message when a built-in module is not resolved. The\n * MetaMask Snaps CLI does not support built-in modules by default, and this\n * plugin is used to warn the user when they try to import a built-in module,\n * when no fallback is configured.\n */\nexport class SnapsBuiltInResolver implements ResolvePluginInstance {\n /**\n * The built-in modules that have been imported, but not resolved.\n */\n readonly unresolvedModules = new Set<string>();\n\n /**\n * The name of the resolver hook to tap into.\n */\n readonly #source = 'described-resolve';\n\n /**\n * The options for the plugin.\n */\n readonly options: SnapsBuiltInResolverOptions;\n\n /**\n * The spinner to use for logging.\n */\n readonly #spinner?: Ora;\n\n constructor(\n options: SnapsBuiltInResolverOptions = {\n ignore: [],\n },\n spinner?: Ora,\n ) {\n this.options = options;\n this.#spinner = spinner;\n }\n\n /**\n * Apply the plugin to the Webpack resolver.\n *\n * @param resolver - The Webpack resolver.\n */\n apply(resolver: Resolver) {\n resolver\n .getHook(this.#source)\n .tapAsync(\n this.constructor.name,\n ({ module: isModule, request }, _, callback) => {\n if (!isModule || !request) {\n return callback();\n }\n\n const baseRequest = request.split('/')[0];\n if (\n isBuiltin(baseRequest) &&\n !this.options.ignore?.includes(baseRequest)\n ) {\n const fallback = resolver.options.fallback.find(\n ({ name }) => name === baseRequest,\n );\n\n if (fallback && !fallback.alias) {\n this.unresolvedModules.add(baseRequest);\n }\n }\n\n return callback();\n },\n );\n }\n}\n\n/**\n * The options for the {@link SnapsBundleWarningsPlugin}.\n */\nexport type SnapsBundleWarningsPluginOptions = {\n /**\n * The {@link SnapsBuiltInResolver} instance to use for detecting built-in\n * modules.\n */\n builtInResolver?: SnapsBuiltInResolver | false;\n\n /**\n * Whether to show warnings if built-in modules are used, but not provided by\n * Webpack's `fallback` configuration.\n */\n builtIns?: boolean;\n\n /**\n * Whether to show warnings if the `Buffer` global is used, but not provided\n * by Webpack's `DefinePlugin`.\n */\n buffer?: boolean;\n};\n\n/**\n * A plugin that logs a message when:\n *\n * - A built-in module is not resolved. The MetaMask Snaps CLI does not support\n * built-in modules by default, and this plugin is used to warn the user when\n * they try to import a built-in module, when no fallback is configured.\n * - A snap uses the `Buffer` global. The MetaMask Snaps CLI does not support\n * the `Buffer` global by default, and this plugin is used to warn the user when\n * they try to use the `Buffer` global.\n *\n * We use both a resolver and a plugin, because the resolver is used to detect\n * when a built-in module is imported, and the plugin is used to log a single\n * message when the compilation is complete. We can't do everything in a single\n * plugin, because the resolver doesn't have access to the compilation, and the\n * plugin doesn't have access to the resolver.\n */\n\nexport class SnapsBundleWarningsPlugin implements WebpackPluginInstance {\n /**\n * The options for the plugin.\n */\n readonly options: SnapsBundleWarningsPluginOptions;\n\n constructor(\n options: SnapsBundleWarningsPluginOptions = {\n buffer: true,\n builtIns: true,\n },\n ) {\n this.options = options;\n }\n\n /**\n * Apply the plugin to the Webpack compiler.\n *\n * @param compiler - The Webpack compiler.\n */\n apply(compiler: Compiler) {\n if (this.options.builtIns) {\n this.#checkBuiltIns(compiler);\n }\n\n if (this.options.buffer) {\n this.#checkBuffer(compiler);\n }\n }\n\n /**\n * Check if a built-in module is used, but not provided by Webpack's\n * `fallback` configuration.\n *\n * @param compiler - The Webpack compiler.\n */\n #checkBuiltIns(compiler: Compiler) {\n compiler.hooks.afterCompile.tap(this.constructor.name, (compilation) => {\n if (!this.options.builtInResolver) {\n return;\n }\n\n const { unresolvedModules } = this.options.builtInResolver;\n if (unresolvedModules.size === 0) {\n return;\n }\n\n const formattedModules = new Array(...unresolvedModules)\n .map((name) => `• ${name}`)\n .join('\\n');\n\n const webpackError = new WebpackError(\n `The snap attempted to use one or more Node.js builtins, but no browser fallback has been provided. The MetaMask Snaps CLI does not support Node.js builtins by default. If you want to use this module, you must set ${bold(\n '`polyfills`',\n )} to ${bold(\n '`true`',\n )} or an object with the builtins to polyfill as the key and ${bold(\n '`true`',\n )} as the value. To disable this warning, set ${bold(\n '`stats.builtIns`',\n )} to ${bold(\n '`false`',\n )} in your snap config file, or add the module to the ${bold(\n '`stats.builtIns.ignore`',\n )} array.`,\n );\n\n webpackError.details = formattedModules;\n compilation.warnings.push(webpackError);\n });\n }\n\n /**\n * Check if the given instance is a `ProvidePlugin`. This is not guaranteed to\n * be accurate, but it's good enough for our purposes. If we were to use\n * `instanceof` instead, it might not work if multiple versions of Webpack are\n * installed.\n *\n * @param instance - The instance to check.\n * @returns Whether the instance is a `ProvidePlugin`, i.e., whether it's an\n * object with the name `ProvidePlugin` and a `definitions` property.\n */\n #isProvidePlugin(instance: unknown): instance is ProvidePlugin {\n return (\n isObject(instance) &&\n instance.constructor.name === 'ProvidePlugin' &&\n hasProperty(instance, 'definitions')\n );\n }\n\n /**\n * Check if the `Buffer` global is used, but not provided by Webpack's\n * `DefinePlugin`.\n *\n * @param compiler - The Webpack compiler.\n */\n #checkBuffer(compiler: Compiler) {\n const plugin = compiler.options.plugins?.find((instance) =>\n this.#isProvidePlugin(instance),\n ) as ProvidePlugin | undefined;\n\n // If the `ProvidePlugin` is configured to provide `Buffer`, then we don't\n // need to warn the user.\n if (plugin) {\n const { definitions } = plugin;\n if (definitions.Buffer) {\n return;\n }\n }\n\n compiler.hooks.compilation.tap(this.constructor.name, (compilation) => {\n compilation.hooks.afterProcessAssets.tap(\n this.constructor.name,\n (assets) => {\n // Check if assets use `Buffer`.\n const bufferAssets = Object.entries(assets)\n .filter(([name]) => name.endsWith('.js'))\n .filter(([, asset]) => asset.source().includes('Buffer'));\n\n if (bufferAssets.length === 0) {\n return;\n }\n\n compilation.warnings.push(\n new WebpackError(\n `The snap attempted to use the Node.js Buffer global, which is not supported in the MetaMask Snaps CLI by default. To use the Buffer global, you must polyfill Buffer by setting ${bold(\n '`buffer`',\n )} to ${bold('`true`')} in the ${bold(\n '`polyfills`',\n )} config object in your snap config. To disable this warning, set ${bold(\n '`stats.buffer`',\n )} to ${bold('`false`')} in your snap config file.`,\n ),\n );\n },\n );\n });\n }\n}\n"],"names":["SnapsStatsPlugin","SnapsWatchPlugin","SnapsBuiltInResolver","SnapsBundleWarningsPlugin","apply","compiler","hooks","afterDone","tap","constructor","name","stats","modules","time","errors","warnings","toJson","assert","length","formattedErrors","map","statsError","getStatsErrorMessage","join","error","pluralize","spinner","stop","process","exitCode","formattedWarnings","statsWarning","yellow","warn","info","watchMode","succeed","options","verbose","color","red","baseMessage","getErrorMessage","message","first","rest","split","formatText","details","dim","filter","Boolean","invalid","file","start","afterEmit","tapPromise","fileDependencies","files","forEach","add","bind","bundle","evaluate","safeEvaluate","bundlePath","evaluateError","resolver","getHook","source","tapAsync","module","isModule","request","_","callback","baseRequest","isBuiltin","ignore","includes","fallback","find","alias","unresolvedModules","Set","builtIns","checkBuiltIns","buffer","checkBuffer","afterCompile","compilation","builtInResolver","size","formattedModules","Array","webpackError","WebpackError","bold","push","instance","isObject","hasProperty","plugin","plugins","isProvidePlugin","definitions","Buffer","afterProcessAssets","assets","bufferAssets","Object","entries","endsWith","asset"],"mappings":"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"}
|
|
@@ -32,12 +32,24 @@ _export(exports, {
|
|
|
32
32
|
},
|
|
33
33
|
getFallbacks: function() {
|
|
34
34
|
return getFallbacks;
|
|
35
|
+
},
|
|
36
|
+
getEnvironmentVariables: function() {
|
|
37
|
+
return getEnvironmentVariables;
|
|
38
|
+
},
|
|
39
|
+
formatText: function() {
|
|
40
|
+
return formatText;
|
|
35
41
|
}
|
|
36
42
|
});
|
|
37
43
|
const _chalk = require("chalk");
|
|
38
44
|
const _fs = require("fs");
|
|
39
45
|
const _module = require("module");
|
|
40
46
|
const _path = require("path");
|
|
47
|
+
const _stripansi = /*#__PURE__*/ _interop_require_default(require("strip-ansi"));
|
|
48
|
+
function _interop_require_default(obj) {
|
|
49
|
+
return obj && obj.__esModule ? obj : {
|
|
50
|
+
default: obj
|
|
51
|
+
};
|
|
52
|
+
}
|
|
41
53
|
const BROWSERSLIST_FILE = (0, _path.resolve)((0, _path.dirname)(// eslint-disable-next-line n/no-extraneous-require
|
|
42
54
|
require.resolve('@metamask/snaps-cli/package.json')), '.browserslistrc');
|
|
43
55
|
const WEBPACK_FALLBACKS = {
|
|
@@ -124,11 +136,13 @@ async function getDefaultLoader({ legacy, sourceMap }) {
|
|
|
124
136
|
* @see https://swc.rs/docs/configuration/modules
|
|
125
137
|
*/ module: {
|
|
126
138
|
/**
|
|
127
|
-
* This tells SWC to output
|
|
128
|
-
*
|
|
139
|
+
* This tells SWC to output ES6 modules. This will allow Webpack to
|
|
140
|
+
* optimize the output code better. Snaps don't support ES6 however, so
|
|
141
|
+
* the output code will be transpiled to CommonJS by Webpack later in
|
|
142
|
+
* the build process.
|
|
129
143
|
*
|
|
130
|
-
* @see https://swc.rs/docs/configuration/modules#
|
|
131
|
-
*/ type: '
|
|
144
|
+
* @see https://swc.rs/docs/configuration/modules#es6
|
|
145
|
+
*/ type: 'es6'
|
|
132
146
|
},
|
|
133
147
|
env: {
|
|
134
148
|
targets: targets.join(', ')
|
|
@@ -177,5 +191,64 @@ function getFallbacks(polyfills) {
|
|
|
177
191
|
polyfills[name] ? WEBPACK_FALLBACKS[name] : false
|
|
178
192
|
]));
|
|
179
193
|
}
|
|
194
|
+
function getEnvironmentVariables(environment, defaults = {
|
|
195
|
+
NODE_DEBUG: 'false',
|
|
196
|
+
NODE_ENV: 'production',
|
|
197
|
+
DEBUG: 'false'
|
|
198
|
+
}) {
|
|
199
|
+
return Object.fromEntries(Object.entries({
|
|
200
|
+
...defaults,
|
|
201
|
+
...environment
|
|
202
|
+
}).map(([key, value])=>[
|
|
203
|
+
`process.env.${key}`,
|
|
204
|
+
JSON.stringify(value)
|
|
205
|
+
]));
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Format the given line to fit within the terminal width.
|
|
209
|
+
*
|
|
210
|
+
* @param line - The line to format.
|
|
211
|
+
* @param indent - The indentation to use.
|
|
212
|
+
* @param initialIndent - The initial indentation to use, i.e., the indentation
|
|
213
|
+
* for the first line.
|
|
214
|
+
* @returns The formatted line.
|
|
215
|
+
*/ function formatLine(line, indent, initialIndent) {
|
|
216
|
+
const terminalWidth = process.stdout.columns;
|
|
217
|
+
if (!terminalWidth) {
|
|
218
|
+
return `${' '.repeat(initialIndent)}${line}`;
|
|
219
|
+
}
|
|
220
|
+
return line.split(' ').reduce(({ formattedText, currentLineLength }, word, index)=>{
|
|
221
|
+
// `chalk` adds ANSI escape codes to the text, which are not visible
|
|
222
|
+
// characters. We need to strip them to get the visible length of the
|
|
223
|
+
// text.
|
|
224
|
+
const visibleWord = (0, _stripansi.default)(word);
|
|
225
|
+
// Determine if a space should be added before the word.
|
|
226
|
+
const spaceBeforeWord = index > 0 ? ' ' : '';
|
|
227
|
+
const wordLengthWithSpace = visibleWord.length + spaceBeforeWord.length;
|
|
228
|
+
// If the word would exceed the terminal width, start a new line.
|
|
229
|
+
if (currentLineLength + wordLengthWithSpace > terminalWidth) {
|
|
230
|
+
return {
|
|
231
|
+
formattedText: `${formattedText}\n${' '.repeat(indent)}${word}`,
|
|
232
|
+
currentLineLength: indent + visibleWord.length
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
// Otherwise, add the word to the current line.
|
|
236
|
+
return {
|
|
237
|
+
formattedText: formattedText + spaceBeforeWord + word,
|
|
238
|
+
currentLineLength: currentLineLength + wordLengthWithSpace
|
|
239
|
+
};
|
|
240
|
+
}, {
|
|
241
|
+
formattedText: ' '.repeat(initialIndent),
|
|
242
|
+
currentLineLength: initialIndent
|
|
243
|
+
}).formattedText;
|
|
244
|
+
}
|
|
245
|
+
function formatText(text, indent, initialIndent = indent) {
|
|
246
|
+
const lines = text.split('\n');
|
|
247
|
+
// Apply formatting to each line separately and then join them.
|
|
248
|
+
return lines.map((line, index)=>{
|
|
249
|
+
const lineIndent = index === 0 ? initialIndent : indent;
|
|
250
|
+
return formatLine(line, indent, lineIndent);
|
|
251
|
+
}).join('\n');
|
|
252
|
+
}
|
|
180
253
|
|
|
181
254
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/webpack/utils.ts"],"sourcesContent":["import { dim } from 'chalk';\nimport { promises as fs } from 'fs';\nimport { builtinModules } from 'module';\nimport type { Ora } from 'ora';\nimport { dirname, resolve } from 'path';\nimport type { Configuration } from 'webpack';\n\nimport type { ProcessedWebpackConfig } from '../config';\n\nexport const BROWSERSLIST_FILE = resolve(\n dirname(\n // eslint-disable-next-line n/no-extraneous-require\n require.resolve('@metamask/snaps-cli/package.json'),\n ),\n '.browserslistrc',\n);\n\nexport const WEBPACK_FALLBACKS = {\n assert: require.resolve('assert/'),\n buffer: require.resolve('buffer/'),\n console: require.resolve('console-browserify'),\n constants: require.resolve('constants-browserify'),\n crypto: require.resolve('crypto-browserify'),\n domain: require.resolve('domain-browser'),\n events: require.resolve('events/'),\n http: require.resolve('stream-http'),\n https: require.resolve('https-browserify'),\n os: require.resolve('os-browserify/browser'),\n path: require.resolve('path-browserify'),\n punycode: require.resolve('punycode/'),\n process: require.resolve('process/browser'),\n querystring: require.resolve('querystring-es3'),\n stream: require.resolve('stream-browserify'),\n /* eslint-disable @typescript-eslint/naming-convention */\n _stream_duplex: require.resolve('readable-stream/lib/_stream_duplex'),\n _stream_passthrough: require.resolve(\n 'readable-stream/lib/_stream_passthrough',\n ),\n _stream_readable: require.resolve('readable-stream/lib/_stream_readable'),\n _stream_transform: require.resolve('readable-stream/lib/_stream_transform'),\n _stream_writable: require.resolve('readable-stream/lib/_stream_writable'),\n string_decoder: require.resolve('string_decoder/'),\n /* eslint-enable @typescript-eslint/naming-convention */\n sys: require.resolve('util/'),\n timers: require.resolve('timers-browserify'),\n tty: require.resolve('tty-browserify'),\n url: require.resolve('url/'),\n util: require.resolve('util/'),\n vm: require.resolve('vm-browserify'),\n zlib: require.resolve('browserify-zlib'),\n};\n\n/**\n * Get the default loader for JavaScript and TypeScript files, based on the\n * config object.\n *\n * - If the `legacy` option is set, we use the custom `browserify` loader. This\n * uses the legacy Browserify config to transpile the code.\n * - Otherwise, we use the `swc-loader`. This is a Webpack loader that uses the\n * `SWC` compiler, which is a much faster alternative to Babel and TypeScript's\n * own compiler.\n *\n * @param config - The processed snap Webpack config.\n * @param config.legacy - The legacy config object, if any.\n * @param config.sourceMap - Whether to generate source maps.\n * @see https://swc.rs/docs/usage/swc-loader\n * @returns The default loader.\n */\nexport async function getDefaultLoader({\n legacy,\n sourceMap,\n}: ProcessedWebpackConfig) {\n if (legacy) {\n return {\n /**\n * If the snap uses the legacy config, we use the custom `browserify`\n * loader. This uses the legacy Browserify config to transpile the code.\n * This is necessary for backwards compatibility with the\n * `bundlerCustomizer` function.\n */\n loader: resolve(__dirname, 'loaders', 'browserify'),\n\n /**\n * The options for the `browserify` loader. These can be overridden in the\n * snap config.\n */\n options: legacy,\n };\n }\n\n const targets = await getBrowserslistTargets();\n return {\n /**\n * We use the `swc-loader` to transpile TypeScript and JavaScript files.\n * This is a Webpack loader that uses the `SWC` compiler, which is a much\n * faster alternative to Babel and TypeScript's own compiler.\n */\n loader: require.resolve('swc-loader'),\n\n /**\n * The options for the `swc-loader`. These can be overridden in the\n * `.swcrc` file.\n *\n * @see https://swc.rs/docs/configuration/swcrc\n */\n options: {\n sync: false,\n\n /**\n * This tells SWC to generate source maps. We set it to the\n * `sourceMap` value from the config object.\n *\n * This must be enabled if source maps are enabled in the config.\n */\n sourceMaps: Boolean(getDevTool(sourceMap)),\n\n jsc: {\n parser: {\n /**\n * This tells the parser to parse TypeScript files. If you\n * don't need to support TypeScript, you can set this to\n * `ecmascript` instead, but there's no harm in leaving it\n * as `typescript`.\n *\n * @see https://swc.rs/docs/configuration/compilation#jscparser\n */\n syntax: 'typescript',\n },\n },\n\n /**\n * The module configuration. This tells SWC how to output the\n * transpiled code.\n *\n * @see https://swc.rs/docs/configuration/modules\n */\n module: {\n /**\n * This tells SWC to output CommonJS modules. MetaMask Snaps\n * doesn't support ES modules yet, so this is necessary.\n *\n * @see https://swc.rs/docs/configuration/modules#commonjs\n */\n type: 'commonjs',\n },\n\n env: {\n targets: targets.join(', '),\n },\n },\n };\n}\n\n/**\n * Get the Webpack devtool configuration based on the given snap config.\n *\n * - If `sourceMap` is `inline`, return `inline-source-map`.\n * - If `sourceMap` is `true`, return `source-map`.\n * - Otherwise, return `false`.\n *\n * @param sourceMap - The `sourceMap` value from the snap config.\n * @returns The Webpack devtool configuration.\n */\nexport function getDevTool(\n sourceMap: ProcessedWebpackConfig['sourceMap'],\n): Configuration['devtool'] {\n if (sourceMap === 'inline') {\n return 'inline-source-map';\n }\n\n if (sourceMap === true) {\n return 'source-map';\n }\n\n return false;\n}\n\n/**\n * Get a function that can be used as handler function for Webpack's\n * `ProgressPlugin`.\n *\n * @param spinner - The spinner to update.\n * @param spinnerText - The initial spinner text. This will be prepended to the\n * percentage.\n * @returns A function that can be used as handler function for Webpack's\n * `ProgressPlugin`.\n */\n// Note: This is extracted for testing purposes.\nexport function getProgressHandler(spinner?: Ora, spinnerText?: string) {\n return (percentage: number) => {\n if (spinner && spinnerText) {\n spinner.text = `${spinnerText} ${dim(\n `(${Math.round(percentage * 100)}%)`,\n )}`;\n }\n };\n}\n\n/**\n * Get the targets from the `.browserslistrc` file.\n *\n * @returns The browser targets as an array of strings.\n */\nexport async function getBrowserslistTargets() {\n const contents = await fs.readFile(BROWSERSLIST_FILE, 'utf8');\n return contents\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line && !line.startsWith('#'));\n}\n\n/**\n * Get a singular or plural string based on the given count. This is useful for\n * generating messages like \"1 error\" or \"2 errors\". By default, the plural\n * string is the singular string with an \"s\" appended to it.\n *\n * This assumes that the text is in English, and likely won't work for some\n * other languages.\n *\n * @param count - The count.\n * @param singular - The singular string.\n * @param plural - The plural string.\n * @returns The singular or plural string.\n * @example\n * ```typescript\n * pluralize(1, 'error'); // => 'error'\n * pluralize(2, 'error'); // => 'errors'\n * pluralize(1, 'error', 'problem'); // => 'error'\n * pluralize(2, 'error', 'problems'); // => 'problems'\n * ```\n */\nexport function pluralize(\n count: number,\n singular: string,\n plural = `${singular}s`,\n) {\n return count === 1 ? singular : plural;\n}\n\n/**\n * Get an object that can be used as fallback config for Webpack's\n * `fallback` config.\n *\n * @param polyfills - The polyfill object from the snap config.\n * @returns The webpack fallback config.\n */\nexport function getFallbacks(polyfills: ProcessedWebpackConfig['polyfills']): {\n [index: string]: string | false;\n} {\n if (polyfills === true) {\n return Object.fromEntries(\n builtinModules.map((name) => [\n name,\n WEBPACK_FALLBACKS[name as keyof typeof WEBPACK_FALLBACKS] ?? false,\n ]),\n );\n }\n\n if (polyfills === false) {\n return Object.fromEntries(builtinModules.map((name) => [name, false]));\n }\n\n return Object.fromEntries(\n builtinModules.map((name) => [\n name,\n polyfills[name as keyof ProcessedWebpackConfig['polyfills']]\n ? WEBPACK_FALLBACKS[name as keyof typeof WEBPACK_FALLBACKS]\n : false,\n ]),\n );\n}\n"],"names":["BROWSERSLIST_FILE","WEBPACK_FALLBACKS","getDefaultLoader","getDevTool","getProgressHandler","getBrowserslistTargets","pluralize","getFallbacks","resolve","dirname","require","assert","buffer","console","constants","crypto","domain","events","http","https","os","path","punycode","process","querystring","stream","_stream_duplex","_stream_passthrough","_stream_readable","_stream_transform","_stream_writable","string_decoder","sys","timers","tty","url","util","vm","zlib","legacy","sourceMap","loader","__dirname","options","targets","sync","sourceMaps","Boolean","jsc","parser","syntax","module","type","env","join","spinner","spinnerText","percentage","text","dim","Math","round","contents","fs","readFile","split","map","line","trim","filter","startsWith","count","singular","plural","polyfills","Object","fromEntries","builtinModules","name"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/webpack/utils.ts"],"sourcesContent":["import { dim } from 'chalk';\nimport { promises as fs } from 'fs';\nimport { builtinModules } from 'module';\nimport type { Ora } from 'ora';\nimport { dirname, resolve } from 'path';\nimport stripAnsi from 'strip-ansi';\nimport type { Configuration } from 'webpack';\n\nimport type { ProcessedWebpackConfig } from '../config';\n\nexport const BROWSERSLIST_FILE = resolve(\n dirname(\n // eslint-disable-next-line n/no-extraneous-require\n require.resolve('@metamask/snaps-cli/package.json'),\n ),\n '.browserslistrc',\n);\n\nexport const WEBPACK_FALLBACKS = {\n assert: require.resolve('assert/'),\n buffer: require.resolve('buffer/'),\n console: require.resolve('console-browserify'),\n constants: require.resolve('constants-browserify'),\n crypto: require.resolve('crypto-browserify'),\n domain: require.resolve('domain-browser'),\n events: require.resolve('events/'),\n http: require.resolve('stream-http'),\n https: require.resolve('https-browserify'),\n os: require.resolve('os-browserify/browser'),\n path: require.resolve('path-browserify'),\n punycode: require.resolve('punycode/'),\n process: require.resolve('process/browser'),\n querystring: require.resolve('querystring-es3'),\n stream: require.resolve('stream-browserify'),\n /* eslint-disable @typescript-eslint/naming-convention */\n _stream_duplex: require.resolve('readable-stream/lib/_stream_duplex'),\n _stream_passthrough: require.resolve(\n 'readable-stream/lib/_stream_passthrough',\n ),\n _stream_readable: require.resolve('readable-stream/lib/_stream_readable'),\n _stream_transform: require.resolve('readable-stream/lib/_stream_transform'),\n _stream_writable: require.resolve('readable-stream/lib/_stream_writable'),\n string_decoder: require.resolve('string_decoder/'),\n /* eslint-enable @typescript-eslint/naming-convention */\n sys: require.resolve('util/'),\n timers: require.resolve('timers-browserify'),\n tty: require.resolve('tty-browserify'),\n url: require.resolve('url/'),\n util: require.resolve('util/'),\n vm: require.resolve('vm-browserify'),\n zlib: require.resolve('browserify-zlib'),\n};\n\n/**\n * Get the default loader for JavaScript and TypeScript files, based on the\n * config object.\n *\n * - If the `legacy` option is set, we use the custom `browserify` loader. This\n * uses the legacy Browserify config to transpile the code.\n * - Otherwise, we use the `swc-loader`. This is a Webpack loader that uses the\n * `SWC` compiler, which is a much faster alternative to Babel and TypeScript's\n * own compiler.\n *\n * @param config - The processed snap Webpack config.\n * @param config.legacy - The legacy config object, if any.\n * @param config.sourceMap - Whether to generate source maps.\n * @see https://swc.rs/docs/usage/swc-loader\n * @returns The default loader.\n */\nexport async function getDefaultLoader({\n legacy,\n sourceMap,\n}: ProcessedWebpackConfig) {\n if (legacy) {\n return {\n /**\n * If the snap uses the legacy config, we use the custom `browserify`\n * loader. This uses the legacy Browserify config to transpile the code.\n * This is necessary for backwards compatibility with the\n * `bundlerCustomizer` function.\n */\n loader: resolve(__dirname, 'loaders', 'browserify'),\n\n /**\n * The options for the `browserify` loader. These can be overridden in the\n * snap config.\n */\n options: legacy,\n };\n }\n\n const targets = await getBrowserslistTargets();\n return {\n /**\n * We use the `swc-loader` to transpile TypeScript and JavaScript files.\n * This is a Webpack loader that uses the `SWC` compiler, which is a much\n * faster alternative to Babel and TypeScript's own compiler.\n */\n loader: require.resolve('swc-loader'),\n\n /**\n * The options for the `swc-loader`. These can be overridden in the\n * `.swcrc` file.\n *\n * @see https://swc.rs/docs/configuration/swcrc\n */\n options: {\n sync: false,\n\n /**\n * This tells SWC to generate source maps. We set it to the\n * `sourceMap` value from the config object.\n *\n * This must be enabled if source maps are enabled in the config.\n */\n sourceMaps: Boolean(getDevTool(sourceMap)),\n\n jsc: {\n parser: {\n /**\n * This tells the parser to parse TypeScript files. If you\n * don't need to support TypeScript, you can set this to\n * `ecmascript` instead, but there's no harm in leaving it\n * as `typescript`.\n *\n * @see https://swc.rs/docs/configuration/compilation#jscparser\n */\n syntax: 'typescript',\n },\n },\n\n /**\n * The module configuration. This tells SWC how to output the\n * transpiled code.\n *\n * @see https://swc.rs/docs/configuration/modules\n */\n module: {\n /**\n * This tells SWC to output ES6 modules. This will allow Webpack to\n * optimize the output code better. Snaps don't support ES6 however, so\n * the output code will be transpiled to CommonJS by Webpack later in\n * the build process.\n *\n * @see https://swc.rs/docs/configuration/modules#es6\n */\n type: 'es6',\n },\n\n env: {\n targets: targets.join(', '),\n },\n },\n };\n}\n\n/**\n * Get the Webpack devtool configuration based on the given snap config.\n *\n * - If `sourceMap` is `inline`, return `inline-source-map`.\n * - If `sourceMap` is `true`, return `source-map`.\n * - Otherwise, return `false`.\n *\n * @param sourceMap - The `sourceMap` value from the snap config.\n * @returns The Webpack devtool configuration.\n */\nexport function getDevTool(\n sourceMap: ProcessedWebpackConfig['sourceMap'],\n): Configuration['devtool'] {\n if (sourceMap === 'inline') {\n return 'inline-source-map';\n }\n\n if (sourceMap === true) {\n return 'source-map';\n }\n\n return false;\n}\n\n/**\n * Get a function that can be used as handler function for Webpack's\n * `ProgressPlugin`.\n *\n * @param spinner - The spinner to update.\n * @param spinnerText - The initial spinner text. This will be prepended to the\n * percentage.\n * @returns A function that can be used as handler function for Webpack's\n * `ProgressPlugin`.\n */\n// Note: This is extracted for testing purposes.\nexport function getProgressHandler(spinner?: Ora, spinnerText?: string) {\n return (percentage: number) => {\n if (spinner && spinnerText) {\n spinner.text = `${spinnerText} ${dim(\n `(${Math.round(percentage * 100)}%)`,\n )}`;\n }\n };\n}\n\n/**\n * Get the targets from the `.browserslistrc` file.\n *\n * @returns The browser targets as an array of strings.\n */\nexport async function getBrowserslistTargets() {\n const contents = await fs.readFile(BROWSERSLIST_FILE, 'utf8');\n return contents\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line && !line.startsWith('#'));\n}\n\n/**\n * Get a singular or plural string based on the given count. This is useful for\n * generating messages like \"1 error\" or \"2 errors\". By default, the plural\n * string is the singular string with an \"s\" appended to it.\n *\n * This assumes that the text is in English, and likely won't work for some\n * other languages.\n *\n * @param count - The count.\n * @param singular - The singular string.\n * @param plural - The plural string.\n * @returns The singular or plural string.\n * @example\n * ```typescript\n * pluralize(1, 'error'); // => 'error'\n * pluralize(2, 'error'); // => 'errors'\n * pluralize(1, 'error', 'problem'); // => 'error'\n * pluralize(2, 'error', 'problems'); // => 'problems'\n * ```\n */\nexport function pluralize(\n count: number,\n singular: string,\n plural = `${singular}s`,\n) {\n return count === 1 ? singular : plural;\n}\n\n/**\n * Get an object that can be used as fallback config for Webpack's\n * `fallback` config.\n *\n * @param polyfills - The polyfill object from the snap config.\n * @returns The webpack fallback config.\n */\nexport function getFallbacks(polyfills: ProcessedWebpackConfig['polyfills']): {\n [index: string]: string | false;\n} {\n if (polyfills === true) {\n return Object.fromEntries(\n builtinModules.map((name) => [\n name,\n WEBPACK_FALLBACKS[name as keyof typeof WEBPACK_FALLBACKS] ?? false,\n ]),\n );\n }\n\n if (polyfills === false) {\n return Object.fromEntries(builtinModules.map((name) => [name, false]));\n }\n\n return Object.fromEntries(\n builtinModules.map((name) => [\n name,\n polyfills[name as keyof ProcessedWebpackConfig['polyfills']]\n ? WEBPACK_FALLBACKS[name as keyof typeof WEBPACK_FALLBACKS]\n : false,\n ]),\n );\n}\n\n/**\n * Get an object that can be used as environment variables for Webpack's\n * `DefinePlugin`.\n *\n * @param environment - The environment object from the Snap config.\n * @param defaults - The default environment variables.\n * @returns The Webpack environment variables.\n */\nexport function getEnvironmentVariables(\n environment: Record<string, unknown>,\n defaults = {\n NODE_DEBUG: 'false',\n NODE_ENV: 'production',\n DEBUG: 'false',\n },\n) {\n return Object.fromEntries(\n Object.entries({\n ...defaults,\n ...environment,\n }).map(([key, value]) => [`process.env.${key}`, JSON.stringify(value)]),\n );\n}\n\n/**\n * Format the given line to fit within the terminal width.\n *\n * @param line - The line to format.\n * @param indent - The indentation to use.\n * @param initialIndent - The initial indentation to use, i.e., the indentation\n * for the first line.\n * @returns The formatted line.\n */\nfunction formatLine(line: string, indent: number, initialIndent: number) {\n const terminalWidth = process.stdout.columns;\n if (!terminalWidth) {\n return `${' '.repeat(initialIndent)}${line}`;\n }\n\n return line.split(' ').reduce(\n ({ formattedText, currentLineLength }, word, index) => {\n // `chalk` adds ANSI escape codes to the text, which are not visible\n // characters. We need to strip them to get the visible length of the\n // text.\n const visibleWord = stripAnsi(word);\n\n // Determine if a space should be added before the word.\n const spaceBeforeWord = index > 0 ? ' ' : '';\n const wordLengthWithSpace = visibleWord.length + spaceBeforeWord.length;\n\n // If the word would exceed the terminal width, start a new line.\n if (currentLineLength + wordLengthWithSpace > terminalWidth) {\n return {\n formattedText: `${formattedText}\\n${' '.repeat(indent)}${word}`,\n currentLineLength: indent + visibleWord.length,\n };\n }\n\n // Otherwise, add the word to the current line.\n return {\n formattedText: formattedText + spaceBeforeWord + word,\n currentLineLength: currentLineLength + wordLengthWithSpace,\n };\n },\n {\n formattedText: ' '.repeat(initialIndent),\n currentLineLength: initialIndent,\n },\n ).formattedText;\n}\n\n/**\n * Format the given text to fit within the terminal width.\n *\n * @param text - The text to format.\n * @param indent - The indentation to use.\n * @param initialIndent - The initial indentation to use, i.e., the indentation\n * for the first line.\n * @returns The formatted text.\n */\nexport function formatText(\n text: string,\n indent: number,\n initialIndent = indent,\n) {\n const lines = text.split('\\n');\n\n // Apply formatting to each line separately and then join them.\n return lines\n .map((line, index) => {\n const lineIndent = index === 0 ? initialIndent : indent;\n return formatLine(line, indent, lineIndent);\n })\n .join('\\n');\n}\n"],"names":["BROWSERSLIST_FILE","WEBPACK_FALLBACKS","getDefaultLoader","getDevTool","getProgressHandler","getBrowserslistTargets","pluralize","getFallbacks","getEnvironmentVariables","formatText","resolve","dirname","require","assert","buffer","console","constants","crypto","domain","events","http","https","os","path","punycode","process","querystring","stream","_stream_duplex","_stream_passthrough","_stream_readable","_stream_transform","_stream_writable","string_decoder","sys","timers","tty","url","util","vm","zlib","legacy","sourceMap","loader","__dirname","options","targets","sync","sourceMaps","Boolean","jsc","parser","syntax","module","type","env","join","spinner","spinnerText","percentage","text","dim","Math","round","contents","fs","readFile","split","map","line","trim","filter","startsWith","count","singular","plural","polyfills","Object","fromEntries","builtinModules","name","environment","defaults","NODE_DEBUG","NODE_ENV","DEBUG","entries","key","value","JSON","stringify","formatLine","indent","initialIndent","terminalWidth","stdout","columns","repeat","reduce","formattedText","currentLineLength","word","index","visibleWord","stripAnsi","spaceBeforeWord","wordLengthWithSpace","length","lines","lineIndent"],"mappings":"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"}
|
package/dist/esm/config.js
CHANGED
|
@@ -71,11 +71,7 @@ export const SnapsWebpackConfigStruct = object({
|
|
|
71
71
|
root: defaulted(file(), process.cwd()),
|
|
72
72
|
port: defaulted(number(), 8081)
|
|
73
73
|
}), {}),
|
|
74
|
-
environment: defaulted(record(string(), unknown()), {
|
|
75
|
-
NODE_DEBUG: false,
|
|
76
|
-
NODE_ENV: 'production',
|
|
77
|
-
DEBUG: false
|
|
78
|
-
}),
|
|
74
|
+
environment: defaulted(record(string(), unknown()), {}),
|
|
79
75
|
stats: defaulted(object({
|
|
80
76
|
verbose: defaulted(boolean(), false),
|
|
81
77
|
builtIns: defaulted(union([
|
package/dist/esm/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config.ts"],"sourcesContent":["import { literal, union } from '@metamask/snaps-sdk';\nimport {\n createFromStruct,\n file,\n indent,\n isFile,\n SnapsStructError,\n named,\n} from '@metamask/snaps-utils';\nimport { hasProperty } from '@metamask/utils';\nimport { transform } from '@swc/core';\nimport type { BrowserifyObject } from 'browserify';\nimport { dim } from 'chalk';\nimport { readFile } from 'fs/promises';\nimport Module from 'module';\nimport { basename, dirname, resolve } from 'path';\nimport type { Infer } from 'superstruct';\nimport {\n array,\n boolean,\n create,\n defaulted,\n define,\n func,\n number,\n object,\n optional,\n record,\n string,\n type,\n unknown,\n empty,\n} from 'superstruct';\nimport type { Configuration as WebpackConfiguration } from 'webpack';\n\nimport { TranspilationModes } from './builders';\nimport { ConfigError } from './errors';\nimport type { YargsArgs } from './types/yargs';\nimport { CONFIG_FILE, TS_CONFIG_FILE } from './utils';\n\nconst CONFIG_FILES = [CONFIG_FILE, TS_CONFIG_FILE];\n\n/**\n * The configuration for the Snaps CLI, stored as `snap.config.js` or\n * `snap.config.ts` in the root of the project.\n *\n * @deprecated The Browserify bundler is deprecated and will be removed in a\n * future release. Use the Webpack bundler instead.\n */\nexport type SnapBrowserifyConfig = {\n /**\n * The bundler to use to build the snap. For backwards compatibility, if not\n * specified, Browserify will be used. However, the Browserify bundler is\n * deprecated and will be removed in a future release, so it's recommended to\n * use the Webpack bundler instead.\n */\n bundler?: 'browserify';\n\n /**\n * The options for the Snaps CLI. These are merged with the options passed to\n * the CLI, with the CLI options taking precedence.\n *\n * @deprecated The Browserify bundler is deprecated and will be removed in a\n * future release. Use the Webpack bundler instead.\n */\n cliOptions?: {\n /**\n * The path to the snap bundle file.\n *\n * @default 'dist/bundle.js'\n */\n bundle?: string;\n\n /**\n * The directory to output the snap to. This is only used if `bundle` is\n * not specified.\n *\n * @default 'dist'\n */\n dist?: string;\n\n /**\n * Whether to attempt to evaluate the snap in SES. This can catch some errors\n * that would otherwise only be caught at runtime.\n *\n * @default true\n */\n eval?: boolean;\n\n /**\n * Whether to validate the snap manifest.\n *\n * @default true\n */\n manifest?: boolean;\n\n /**\n * The name of the bundle file. This is only used if `bundle` is not\n * specified.\n *\n * @default 'bundle.js'\n */\n outfileName?: string;\n\n /**\n * The port to run the server on.\n *\n * @default 8081\n */\n port?: number;\n\n /**\n * The root directory to serve the snap from.\n *\n * @default `process.cwd()`\n */\n root?: string;\n\n /**\n * Whether to generate source maps for the snap bundle.\n *\n * @default false\n */\n sourceMaps?: boolean;\n\n /**\n * The path to the snap entry point.\n *\n * @default 'src/index.js'\n */\n src?: string;\n\n /**\n * Whether to remove comments from the bundle.\n *\n * @default true\n */\n stripComments?: boolean;\n\n /**\n * Whether to suppress warnings.\n *\n * @default false\n */\n suppressWarnings?: boolean;\n\n /**\n * The transpilation mode to use, which determines which files are\n * transpiled.\n *\n * - `'localAndDeps'`: Transpile the snap entry point and all dependencies.\n * - `'localOnly'`: Transpile only the snap entry point.\n * - `'none'`: Don't transpile any files.\n *\n * @default 'localOnly'\n */\n transpilationMode?: 'localAndDeps' | 'localOnly' | 'none';\n\n /**\n * The dependencies to transpile when `transpilationMode` is set to\n * `'localAndDeps'`. If not specified, all dependencies will be transpiled.\n */\n depsToTranspile?: string[];\n\n /**\n * Whether to show original errors.\n *\n * @default true\n */\n verboseErrors?: boolean;\n\n /**\n * Whether to write the updated manifest to disk.\n *\n * @default true\n */\n writeManifest?: boolean;\n\n /**\n * Whether to serve the snap locally.\n *\n * @default true\n */\n serve?: boolean;\n };\n\n /**\n * A function that can be used to customize the Browserify instance used to\n * build the snap.\n *\n * @param bundler - The Browserify instance.\n * @deprecated The Browserify bundler is deprecated and will be removed in a\n * future release. Use the Webpack bundler instead.\n */\n bundlerCustomizer?: (bundler: BrowserifyObject) => void;\n};\n\n/**\n * The configuration for the Snaps CLI, stored as `snap.config.js` or\n * `snap.config.ts` in the root of the project.\n */\nexport type SnapWebpackConfig = {\n /**\n * The bundler to use to build the snap. For backwards compatibility, if not\n * specified, Browserify will be used. However, the Browserify bundler is\n * deprecated and will be removed in a future release, so it's recommended to\n * use the Webpack bundler instead.\n */\n bundler: 'webpack';\n\n /**\n * The path to the snap entry point. This should be a JavaScript or TypeScript\n * file.\n */\n input: string;\n\n /**\n * Whether to generate source maps for the snap. If `true`, source maps will\n * be generated as separate files. If `'inline'`, source maps will be\n * inlined in the generated JavaScript bundle.\n *\n * @default true\n */\n sourceMap?: boolean | 'inline';\n\n /**\n * Whether to attempt to evaluate the snap in SES. This can catch some errors\n * that would otherwise only be caught at runtime.\n *\n * @default true\n */\n evaluate?: boolean;\n\n output?: {\n /**\n * The path to the directory where the snap will be built. This directory\n * will be created if it doesn't exist.\n *\n * If the path is relative, it will be resolved relative to the current\n * working directory.\n *\n * @default 'dist'\n */\n path?: string;\n\n /**\n * The name of the JavaScript bundle file.\n *\n * @default 'bundle.js'\n */\n filename?: string;\n\n /**\n * Whether to clean the output directory before building the snap. If\n * `true`, the output directory will be deleted and recreated. Otherwise,\n * the output directory will be left as-is.\n *\n * @default false\n */\n clean?: boolean;\n\n /**\n * Whether to minimize the snap bundle. If `true`, the bundle will be\n * minified. Otherwise, the bundle will be left as-is.\n *\n * @default true\n */\n minimize?: boolean;\n };\n\n manifest?: {\n /**\n * The path to the snap manifest file. If the path is relative, it will be\n * resolved relative to the current working directory.\n *\n * @default 'snap.manifest.json'\n */\n path?: string;\n\n /**\n * Whether to automatically update the manifest. If `true`, the manifest\n * will be updated with the latest shasum of the snap bundle, and some\n * common fields will be updated if they are missing or incorrect. If\n * `false`, the manifest will be left as-is.\n *\n * @default true\n */\n update?: boolean;\n };\n\n server?: {\n /**\n * Whether to enable the local server. If `true`, the snap will be served\n * from a local server, when running the `watch` command. If `false`, the\n * snap will not be served.\n *\n * @default true\n */\n enabled?: boolean;\n\n /**\n * The root directory to serve the snap from. If the path is relative, it\n * will be resolved relative to the current working directory.\n *\n * @default `process.cwd()`\n */\n root?: string;\n\n /**\n * The port to run the server on.\n *\n * @default 8081\n */\n port?: number;\n };\n\n /**\n * The environment variables to set when building the snap. These will be\n * available in the snap as `process.env`. In addition to these environment\n * variables, the following environment variables will always be set:\n *\n * - `NODE_DEBUG`: `false`\n * - `NODE_ENV`: `'production'`\n * - `DEBUG`: `false`\n *\n * Any environment variables specified here will override these defaults. You\n * can also override any variables here by setting them in your shell when\n * running the CLI.\n */\n environment?: Record<string, unknown>;\n\n /**\n * Options that control the logging output of the CLI.\n */\n stats?: {\n /**\n * Whether to enable verbose logging.\n *\n * @default false\n */\n verbose?: boolean;\n\n /**\n * Whether to log warnings about unresolved built-in modules. If `false`,\n * warnings will not be logged.\n */\n builtIns?:\n | {\n /**\n * The built-in modules to ignore when resolving modules. If a module\n * is ignored, no warning will be logged if it is not resolved.\n */\n ignore?: string[];\n }\n | false;\n\n /**\n * Whether to log warnings about the use of the `Buffer` global. If `false`,\n * warnings will not be logged. If `true`, the CLI will warn if the `Buffer`\n * global is used, but not provided by Webpack's `DefinePlugin`.\n */\n buffer?: boolean;\n };\n\n /**\n * Whether to provide polyfills for node builtins. If `true`, all the available\n * polyfills will be provided. If `false` no polyfills will be provided. If a\n * configuration object is passed only the polyfills set to `true` will be provided.\n *\n * @default false\n * @example\n * ```ts\n * polyfills: true\n *\n * // or\n *\n * polyfills: {\n * assert: true,\n * buffer: true\n * }\n * ```\n */\n polyfills?:\n | boolean\n | {\n assert?: boolean;\n buffer?: boolean;\n console?: boolean;\n constants?: boolean;\n crypto?: boolean;\n domain?: boolean;\n events?: boolean;\n http?: boolean;\n https?: boolean;\n os?: boolean;\n path?: boolean;\n punycode?: boolean;\n process?: boolean;\n querystring?: boolean;\n stream?: boolean;\n /* eslint-disable @typescript-eslint/naming-convention */\n _stream_duplex?: boolean;\n _stream_passthrough?: boolean;\n _stream_readable?: boolean;\n _stream_transform?: boolean;\n _stream_writable?: boolean;\n string_decoder?: boolean;\n /* eslint-enable @typescript-eslint/naming-convention */\n sys?: boolean;\n timers?: boolean;\n tty?: boolean;\n url?: boolean;\n util?: boolean;\n vm?: boolean;\n zlib?: boolean;\n };\n\n /**\n * A function to customize the Webpack configuration used to build the snap.\n * This function will be called with the default Webpack configuration, and\n * should return the modified configuration. If not specified, the default\n * configuration will be used.\n *\n * It's recommended to use the `webpack-merge` package to merge the default\n * configuration with your customizations. The merge function is exported as\n * `merge` from the `@metamask/snaps-cli` package.\n *\n * @example\n * ```ts\n * import type { SnapsConfig } from '@metamask/snaps-cli';\n * import { merge } from '@metamask/snaps-cli';\n *\n * const config: SnapsConfig = {\n * bundler: 'webpack',\n * entry: 'src/index.ts',\n * customizeWebpackConfig: (config) => merge(config, {\n * module: {\n * rules: [\n * {\n * test: /\\.wasm$/,\n * type: 'assets/resource',\n * },\n * ],\n * },\n * }),\n * };\n *\n * export default config;\n * ```\n */\n customizeWebpackConfig?: (\n config: WebpackConfiguration,\n ) => WebpackConfiguration;\n\n /**\n * Experimental features that can be enabled. These features are not\n * guaranteed to be stable, and may be removed or changed in a future release.\n */\n experimental?: {\n /**\n * Whether to enable WebAssembly support. If `true`, the Webpack\n * configuration will be modified to support WebAssembly. If `false`, the\n * Webpack configuration will not be modified.\n *\n * @default false\n */\n wasm?: boolean;\n };\n};\n\n/**\n * The configuration for the Snaps CLI, stored as `snap.config.js` or\n * `snap.config.ts` in the root of the project.\n */\nexport type SnapConfig = SnapBrowserifyConfig | SnapWebpackConfig;\n\ntype SnapsBrowserifyBundlerCustomizerFunction = (\n bundler: BrowserifyObject,\n) => void;\n\n// This struct is essentially the same as the `func` struct, but it's defined\n// separately so that we include the function type in the inferred TypeScript\n// type definitions.\nconst SnapsBrowserifyBundlerCustomizerFunctionStruct =\n define<SnapsBrowserifyBundlerCustomizerFunction>(\n 'function',\n func().validator,\n );\n\nexport const SnapsBrowserifyConfigStruct = object({\n bundler: defaulted(literal('browserify'), 'browserify'),\n cliOptions: defaulted(\n object({\n bundle: optional(file()),\n dist: defaulted(file(), 'dist'),\n eval: defaulted(boolean(), true),\n manifest: defaulted(boolean(), true),\n port: defaulted(number(), 8081),\n outfileName: defaulted(string(), 'bundle.js'),\n root: defaulted(file(), process.cwd()),\n sourceMaps: defaulted(boolean(), false),\n src: defaulted(file(), 'src/index.js'),\n stripComments: defaulted(boolean(), true),\n suppressWarnings: defaulted(boolean(), false),\n transpilationMode: defaulted(\n union([literal('localAndDeps'), literal('localOnly'), literal('none')]),\n 'localOnly',\n ),\n depsToTranspile: defaulted(array(string()), []),\n verboseErrors: defaulted(boolean(), true),\n writeManifest: defaulted(boolean(), true),\n serve: defaulted(boolean(), true),\n }),\n {},\n ),\n bundlerCustomizer: optional(SnapsBrowserifyBundlerCustomizerFunctionStruct),\n});\n\ntype SnapsWebpackCustomizeWebpackConfigFunction = (\n config: WebpackConfiguration,\n) => WebpackConfiguration;\n\n// This struct is essentially the same as the `func` struct, but it's defined\n// separately so that we include the function type in the inferred TypeScript\n// type definitions.\nconst SnapsWebpackCustomizeWebpackConfigFunctionStruct =\n define<SnapsWebpackCustomizeWebpackConfigFunction>(\n 'function',\n func().validator,\n );\n\nexport const SnapsWebpackConfigStruct = object({\n bundler: literal('webpack'),\n input: defaulted(file(), resolve(process.cwd(), 'src/index.js')),\n sourceMap: defaulted(union([boolean(), literal('inline')]), false),\n evaluate: defaulted(boolean(), true),\n\n output: defaulted(\n object({\n path: defaulted(file(), resolve(process.cwd(), 'dist')),\n filename: defaulted(string(), 'bundle.js'),\n clean: defaulted(boolean(), false),\n minimize: defaulted(boolean(), true),\n }),\n {},\n ),\n\n manifest: defaulted(\n object({\n path: defaulted(file(), resolve(process.cwd(), 'snap.manifest.json')),\n update: defaulted(boolean(), true),\n }),\n {},\n ),\n\n server: defaulted(\n object({\n enabled: defaulted(boolean(), true),\n root: defaulted(file(), process.cwd()),\n port: defaulted(number(), 8081),\n }),\n {},\n ),\n\n environment: defaulted(record(string(), unknown()), {\n NODE_DEBUG: false,\n NODE_ENV: 'production',\n DEBUG: false,\n }),\n\n stats: defaulted(\n object({\n verbose: defaulted(boolean(), false),\n builtIns: defaulted(\n union([\n object({ ignore: defaulted(array(string()), []) }),\n literal(false),\n ]),\n {},\n ),\n buffer: defaulted(boolean(), true),\n }),\n {},\n ),\n\n polyfills: defaulted(\n union([\n boolean(),\n object({\n assert: defaulted(boolean(), false),\n buffer: defaulted(boolean(), false),\n console: defaulted(boolean(), false),\n constants: defaulted(boolean(), false),\n crypto: defaulted(boolean(), false),\n domain: defaulted(boolean(), false),\n events: defaulted(boolean(), false),\n http: defaulted(boolean(), false),\n https: defaulted(boolean(), false),\n os: defaulted(boolean(), false),\n path: defaulted(boolean(), false),\n punycode: defaulted(boolean(), false),\n process: defaulted(boolean(), false),\n querystring: defaulted(boolean(), false),\n stream: defaulted(boolean(), false),\n /* eslint-disable @typescript-eslint/naming-convention */\n _stream_duplex: defaulted(boolean(), false),\n _stream_passthrough: defaulted(boolean(), false),\n _stream_readable: defaulted(boolean(), false),\n _stream_transform: defaulted(boolean(), false),\n _stream_writable: defaulted(boolean(), false),\n string_decoder: defaulted(boolean(), false),\n /* eslint-enable @typescript-eslint/naming-convention */\n sys: defaulted(boolean(), false),\n timers: defaulted(boolean(), false),\n tty: defaulted(boolean(), false),\n url: defaulted(boolean(), false),\n util: defaulted(boolean(), false),\n vm: defaulted(boolean(), false),\n zlib: defaulted(boolean(), false),\n }),\n ]),\n false,\n ),\n\n customizeWebpackConfig: optional(\n SnapsWebpackCustomizeWebpackConfigFunctionStruct,\n ),\n\n experimental: defaulted(\n object({\n wasm: defaulted(boolean(), false),\n }),\n {},\n ),\n});\n\nexport const SnapsConfigStruct = type({\n bundler: defaulted(\n union([literal('browserify'), literal('webpack')]),\n 'browserify',\n ),\n});\n\nexport const LegacyOptionsStruct = union([\n named(\n 'object with `transpilationMode` set to `localAndDeps` and `depsToTranspile` set to an array of strings',\n type({\n depsToTranspile: array(string()),\n transpilationMode: literal(TranspilationModes.LocalAndDeps),\n writeManifest: boolean(),\n bundlerCustomizer: optional(\n SnapsBrowserifyBundlerCustomizerFunctionStruct,\n ),\n }),\n ),\n named(\n 'object without `depsToTranspile`',\n type({\n depsToTranspile: named('empty array', empty(array())),\n transpilationMode: union([\n literal(TranspilationModes.LocalOnly),\n literal(TranspilationModes.None),\n ]),\n writeManifest: boolean(),\n bundlerCustomizer: optional(\n SnapsBrowserifyBundlerCustomizerFunctionStruct,\n ),\n }),\n ),\n]);\n\nexport type LegacyOptions = Infer<typeof LegacyOptionsStruct>;\n\nexport type ProcessedBrowserifyConfig = Infer<\n typeof SnapsBrowserifyConfigStruct\n>;\n\nexport type ProcessedWebpackConfig = Infer<typeof SnapsWebpackConfigStruct> & {\n /**\n * The legacy Browserify config, if the bundler is Browserify. This is used\n * to support the legacy config format.\n */\n legacy?: LegacyOptions;\n};\n\nexport type ProcessedConfig = ProcessedWebpackConfig;\n\n/**\n * Get a validated snap config. This validates the config and adds default\n * values for any missing properties.\n *\n * @param config - The config to validate.\n * @param argv - The CLI arguments.\n * @returns The validated config.\n */\nexport function getConfig(config: unknown, argv: YargsArgs): ProcessedConfig {\n const prefix = 'The snap config file is invalid';\n const suffix = dim(\n // TODO: Link to `docs.metamask.io` once the docs are published.\n 'Refer to the documentation for more information: https://github.com/MetaMask/snaps/tree/main/packages/snaps-cli/',\n );\n\n const { bundler } = createFromStruct(\n config,\n SnapsConfigStruct,\n prefix,\n suffix,\n );\n\n if (bundler === 'browserify') {\n const legacyConfig = createFromStruct(\n config,\n SnapsBrowserifyConfigStruct,\n prefix,\n suffix,\n );\n\n return getWebpackConfig(mergeLegacyOptions(argv, legacyConfig));\n }\n\n return createFromStruct(config, SnapsWebpackConfigStruct, prefix, suffix);\n}\n\n/**\n * Load a snap config from a file. This supports both JavaScript and TypeScript\n * config files, in the CommonJS module format and the ES module format.\n *\n * This assumes that the config file exports a default object, either through\n * `module.exports` or `export default`.\n *\n * @param path - The full path to the config file.\n * @param argv - The CLI arguments.\n * @returns The validated config.\n * @throws If the config file is invalid, or if the config file does not have a\n * default export.\n */\nexport async function loadConfig(path: string, argv: YargsArgs) {\n try {\n const contents = await readFile(path, 'utf8');\n const source = await transform(contents, {\n swcrc: false,\n jsc: {\n parser: {\n syntax: 'typescript',\n },\n },\n module: {\n type: 'commonjs',\n },\n });\n\n const config = new Module(path);\n\n // @ts-expect-error - This function is not typed.\n config.paths = Module._nodeModulePaths(dirname(path));\n\n // @ts-expect-error - This function is not typed.\n config._compile(source.code, path);\n\n if (!hasProperty(config.exports, 'default')) {\n return getConfig(config.exports, argv);\n }\n\n return getConfig(config.exports.default, argv);\n } catch (error) {\n if (error instanceof SnapsStructError) {\n throw new ConfigError(error.message);\n }\n\n throw new ConfigError(\n `Unable to load snap config file at \"${path}\".\\n\\n${indent(\n error.message,\n )}`,\n );\n }\n}\n\n/**\n * Resolve a snap config. This function will look for a `snap.config.js` or\n * `snap.config.ts` file in the current or specified directory.\n *\n * @param path - The path to resolve the snap config from. Defaults to the\n * current working directory.\n * @param argv - The CLI arguments.\n * @returns The resolved and validated snap config.\n * @throws If a snap config could not be found.\n */\nexport async function resolveConfig(path: string, argv: YargsArgs) {\n for (const configFile of CONFIG_FILES) {\n const filePath = resolve(path, configFile);\n if (await isFile(filePath)) {\n return await loadConfig(filePath, argv);\n }\n }\n\n throw new ConfigError(\n `Could not find a \"snap.config.js\" or \"snap.config.ts\" file in the current or specified directory (\"${path}\").`,\n );\n}\n\n/**\n * Get a snap config from the CLI arguments. This will either load the config\n * from the specified config file, or resolve the config from the current\n * working directory.\n *\n * @param argv - The CLI arguments.\n * @param cwd - The current working directory. Defaults to `process.cwd()`.\n * @returns The resolved and validated snap config.\n */\nexport async function getConfigByArgv(\n argv: YargsArgs,\n cwd: string = process.cwd(),\n) {\n if (argv.config) {\n if (!(await isFile(argv.config))) {\n throw new ConfigError(\n `Could not find a config file at \"${argv.config}\". Make sure that the path is correct.`,\n );\n }\n\n return await loadConfig(argv.config, argv);\n }\n\n return await resolveConfig(cwd, argv);\n}\n\n/**\n * Merge legacy CLI options into the config. This is used to support the legacy\n * config format, where options can be specified both in the config file and\n * through CLI flags.\n *\n * @param argv - The CLI arguments.\n * @param config - The config to merge the CLI options into.\n * @returns The config with the CLI options merged in.\n * @deprecated This function is only used to support the legacy config format.\n */\nexport function mergeLegacyOptions(\n argv: YargsArgs,\n config: ProcessedBrowserifyConfig,\n) {\n const cliOptions = Object.keys(config.cliOptions).reduce<\n ProcessedBrowserifyConfig['cliOptions']\n >((accumulator, key) => {\n if (argv[key] !== undefined) {\n return {\n ...accumulator,\n [key]: argv[key],\n };\n }\n\n return accumulator;\n }, config.cliOptions);\n\n return {\n ...config,\n cliOptions,\n };\n}\n\n/**\n * Get a Webpack config from a legacy browserify config. This is used to\n * support the legacy config format, and convert it to the new format.\n *\n * @param legacyConfig - The legacy browserify config.\n * @returns The Webpack config.\n */\nexport function getWebpackConfig(\n legacyConfig: ProcessedBrowserifyConfig,\n): ProcessedWebpackConfig {\n const defaultConfig = create(\n { bundler: 'webpack' },\n SnapsWebpackConfigStruct,\n );\n\n // The legacy config has two options for specifying the output path and\n // filename: `bundle`, and `dist` + `outfileName`. If `bundle` is specified,\n // we use that as the output path and filename. Otherwise, we use `dist` and\n // `outfileName`.\n const path = legacyConfig.cliOptions.bundle\n ? dirname(legacyConfig.cliOptions.bundle)\n : legacyConfig.cliOptions.dist;\n\n const filename = legacyConfig.cliOptions.bundle\n ? basename(legacyConfig.cliOptions.bundle)\n : legacyConfig.cliOptions.outfileName;\n\n return {\n ...defaultConfig,\n input: legacyConfig.cliOptions.src,\n evaluate: legacyConfig.cliOptions.eval,\n sourceMap: legacyConfig.cliOptions.sourceMaps,\n output: {\n path,\n filename,\n\n // The legacy config has an option to remove comments from the bundle, but\n // the terser plugin does this by default, so we only enable the terser if\n // the legacy config has `stripComments` set to `true`. This is not a\n // perfect solution, but it's the best we can do without breaking the\n // legacy config.\n minimize: legacyConfig.cliOptions.stripComments,\n\n // The legacy config does not have a `clean` option, so we default to\n // `false` here.\n clean: false,\n },\n manifest: {\n // The legacy config does not have a `manifest` option, so we default to\n // `process.cwd()/snap.manifest.json`.\n path: resolve(process.cwd(), 'snap.manifest.json'),\n update: legacyConfig.cliOptions.writeManifest,\n },\n server: {\n enabled: legacyConfig.cliOptions.serve,\n port: legacyConfig.cliOptions.port,\n root: legacyConfig.cliOptions.root,\n },\n stats: {\n verbose: false,\n\n // These plugins are designed to be used with the modern config format, so\n // we disable them for the legacy config format.\n builtIns: false,\n buffer: false,\n },\n legacy: createFromStruct(\n {\n ...legacyConfig.cliOptions,\n bundlerCustomizer: legacyConfig.bundlerCustomizer,\n },\n LegacyOptionsStruct,\n 'Invalid Browserify CLI options',\n ),\n };\n}\n"],"names":["literal","union","createFromStruct","file","indent","isFile","SnapsStructError","named","hasProperty","transform","dim","readFile","Module","basename","dirname","resolve","array","boolean","create","defaulted","define","func","number","object","optional","record","string","type","unknown","empty","TranspilationModes","ConfigError","CONFIG_FILE","TS_CONFIG_FILE","CONFIG_FILES","SnapsBrowserifyBundlerCustomizerFunctionStruct","validator","SnapsBrowserifyConfigStruct","bundler","cliOptions","bundle","dist","eval","manifest","port","outfileName","root","process","cwd","sourceMaps","src","stripComments","suppressWarnings","transpilationMode","depsToTranspile","verboseErrors","writeManifest","serve","bundlerCustomizer","SnapsWebpackCustomizeWebpackConfigFunctionStruct","SnapsWebpackConfigStruct","input","sourceMap","evaluate","output","path","filename","clean","minimize","update","server","enabled","environment","NODE_DEBUG","NODE_ENV","DEBUG","stats","verbose","builtIns","ignore","buffer","polyfills","assert","console","constants","crypto","domain","events","http","https","os","punycode","querystring","stream","_stream_duplex","_stream_passthrough","_stream_readable","_stream_transform","_stream_writable","string_decoder","sys","timers","tty","url","util","vm","zlib","customizeWebpackConfig","experimental","wasm","SnapsConfigStruct","LegacyOptionsStruct","LocalAndDeps","LocalOnly","None","getConfig","config","argv","prefix","suffix","legacyConfig","getWebpackConfig","mergeLegacyOptions","loadConfig","contents","source","swcrc","jsc","parser","syntax","module","paths","_nodeModulePaths","_compile","code","exports","default","error","message","resolveConfig","configFile","filePath","getConfigByArgv","Object","keys","reduce","accumulator","key","undefined","defaultConfig","legacy"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/config.ts"],"sourcesContent":["import { literal, union } from '@metamask/snaps-sdk';\nimport {\n createFromStruct,\n file,\n indent,\n isFile,\n SnapsStructError,\n named,\n} from '@metamask/snaps-utils';\nimport { hasProperty } from '@metamask/utils';\nimport { transform } from '@swc/core';\nimport type { BrowserifyObject } from 'browserify';\nimport { dim } from 'chalk';\nimport { readFile } from 'fs/promises';\nimport Module from 'module';\nimport { basename, dirname, resolve } from 'path';\nimport type { Infer } from 'superstruct';\nimport {\n array,\n boolean,\n create,\n defaulted,\n define,\n func,\n number,\n object,\n optional,\n record,\n string,\n type,\n unknown,\n empty,\n} from 'superstruct';\nimport type { Configuration as WebpackConfiguration } from 'webpack';\n\nimport { TranspilationModes } from './builders';\nimport { ConfigError } from './errors';\nimport type { YargsArgs } from './types/yargs';\nimport { CONFIG_FILE, TS_CONFIG_FILE } from './utils';\n\nconst CONFIG_FILES = [CONFIG_FILE, TS_CONFIG_FILE];\n\n/**\n * The configuration for the Snaps CLI, stored as `snap.config.js` or\n * `snap.config.ts` in the root of the project.\n *\n * @deprecated The Browserify bundler is deprecated and will be removed in a\n * future release. Use the Webpack bundler instead.\n */\nexport type SnapBrowserifyConfig = {\n /**\n * The bundler to use to build the snap. For backwards compatibility, if not\n * specified, Browserify will be used. However, the Browserify bundler is\n * deprecated and will be removed in a future release, so it's recommended to\n * use the Webpack bundler instead.\n */\n bundler?: 'browserify';\n\n /**\n * The options for the Snaps CLI. These are merged with the options passed to\n * the CLI, with the CLI options taking precedence.\n *\n * @deprecated The Browserify bundler is deprecated and will be removed in a\n * future release. Use the Webpack bundler instead.\n */\n cliOptions?: {\n /**\n * The path to the snap bundle file.\n *\n * @default 'dist/bundle.js'\n */\n bundle?: string;\n\n /**\n * The directory to output the snap to. This is only used if `bundle` is\n * not specified.\n *\n * @default 'dist'\n */\n dist?: string;\n\n /**\n * Whether to attempt to evaluate the snap in SES. This can catch some errors\n * that would otherwise only be caught at runtime.\n *\n * @default true\n */\n eval?: boolean;\n\n /**\n * Whether to validate the snap manifest.\n *\n * @default true\n */\n manifest?: boolean;\n\n /**\n * The name of the bundle file. This is only used if `bundle` is not\n * specified.\n *\n * @default 'bundle.js'\n */\n outfileName?: string;\n\n /**\n * The port to run the server on.\n *\n * @default 8081\n */\n port?: number;\n\n /**\n * The root directory to serve the snap from.\n *\n * @default `process.cwd()`\n */\n root?: string;\n\n /**\n * Whether to generate source maps for the snap bundle.\n *\n * @default false\n */\n sourceMaps?: boolean;\n\n /**\n * The path to the snap entry point.\n *\n * @default 'src/index.js'\n */\n src?: string;\n\n /**\n * Whether to remove comments from the bundle.\n *\n * @default true\n */\n stripComments?: boolean;\n\n /**\n * Whether to suppress warnings.\n *\n * @default false\n */\n suppressWarnings?: boolean;\n\n /**\n * The transpilation mode to use, which determines which files are\n * transpiled.\n *\n * - `'localAndDeps'`: Transpile the snap entry point and all dependencies.\n * - `'localOnly'`: Transpile only the snap entry point.\n * - `'none'`: Don't transpile any files.\n *\n * @default 'localOnly'\n */\n transpilationMode?: 'localAndDeps' | 'localOnly' | 'none';\n\n /**\n * The dependencies to transpile when `transpilationMode` is set to\n * `'localAndDeps'`. If not specified, all dependencies will be transpiled.\n */\n depsToTranspile?: string[];\n\n /**\n * Whether to show original errors.\n *\n * @default true\n */\n verboseErrors?: boolean;\n\n /**\n * Whether to write the updated manifest to disk.\n *\n * @default true\n */\n writeManifest?: boolean;\n\n /**\n * Whether to serve the snap locally.\n *\n * @default true\n */\n serve?: boolean;\n };\n\n /**\n * A function that can be used to customize the Browserify instance used to\n * build the snap.\n *\n * @param bundler - The Browserify instance.\n * @deprecated The Browserify bundler is deprecated and will be removed in a\n * future release. Use the Webpack bundler instead.\n */\n bundlerCustomizer?: (bundler: BrowserifyObject) => void;\n};\n\n/**\n * The configuration for the Snaps CLI, stored as `snap.config.js` or\n * `snap.config.ts` in the root of the project.\n */\nexport type SnapWebpackConfig = {\n /**\n * The bundler to use to build the snap. For backwards compatibility, if not\n * specified, Browserify will be used. However, the Browserify bundler is\n * deprecated and will be removed in a future release, so it's recommended to\n * use the Webpack bundler instead.\n */\n bundler: 'webpack';\n\n /**\n * The path to the snap entry point. This should be a JavaScript or TypeScript\n * file.\n */\n input: string;\n\n /**\n * Whether to generate source maps for the snap. If `true`, source maps will\n * be generated as separate files. If `'inline'`, source maps will be\n * inlined in the generated JavaScript bundle.\n *\n * @default true\n */\n sourceMap?: boolean | 'inline';\n\n /**\n * Whether to attempt to evaluate the snap in SES. This can catch some errors\n * that would otherwise only be caught at runtime.\n *\n * @default true\n */\n evaluate?: boolean;\n\n output?: {\n /**\n * The path to the directory where the snap will be built. This directory\n * will be created if it doesn't exist.\n *\n * If the path is relative, it will be resolved relative to the current\n * working directory.\n *\n * @default 'dist'\n */\n path?: string;\n\n /**\n * The name of the JavaScript bundle file.\n *\n * @default 'bundle.js'\n */\n filename?: string;\n\n /**\n * Whether to clean the output directory before building the snap. If\n * `true`, the output directory will be deleted and recreated. Otherwise,\n * the output directory will be left as-is.\n *\n * @default false\n */\n clean?: boolean;\n\n /**\n * Whether to minimize the snap bundle. If `true`, the bundle will be\n * minified. Otherwise, the bundle will be left as-is.\n *\n * @default true\n */\n minimize?: boolean;\n };\n\n manifest?: {\n /**\n * The path to the snap manifest file. If the path is relative, it will be\n * resolved relative to the current working directory.\n *\n * @default 'snap.manifest.json'\n */\n path?: string;\n\n /**\n * Whether to automatically update the manifest. If `true`, the manifest\n * will be updated with the latest shasum of the snap bundle, and some\n * common fields will be updated if they are missing or incorrect. If\n * `false`, the manifest will be left as-is.\n *\n * @default true\n */\n update?: boolean;\n };\n\n server?: {\n /**\n * Whether to enable the local server. If `true`, the snap will be served\n * from a local server, when running the `watch` command. If `false`, the\n * snap will not be served.\n *\n * @default true\n */\n enabled?: boolean;\n\n /**\n * The root directory to serve the snap from. If the path is relative, it\n * will be resolved relative to the current working directory.\n *\n * @default `process.cwd()`\n */\n root?: string;\n\n /**\n * The port to run the server on.\n *\n * @default 8081\n */\n port?: number;\n };\n\n /**\n * The environment variables to set when building the snap. These will be\n * available in the snap as `process.env`. In addition to these environment\n * variables, the following environment variables will always be set:\n *\n * - `NODE_DEBUG`: `false`\n * - `NODE_ENV`: `'production'`\n * - `DEBUG`: `false`\n *\n * Any environment variables specified here will override these defaults. You\n * can also override any variables here by setting them in your shell when\n * running the CLI.\n */\n environment?: Record<string, unknown>;\n\n /**\n * Options that control the logging output of the CLI.\n */\n stats?: {\n /**\n * Whether to enable verbose logging.\n *\n * @default false\n */\n verbose?: boolean;\n\n /**\n * Whether to log warnings about unresolved built-in modules. If `false`,\n * warnings will not be logged.\n */\n builtIns?:\n | {\n /**\n * The built-in modules to ignore when resolving modules. If a module\n * is ignored, no warning will be logged if it is not resolved.\n */\n ignore?: string[];\n }\n | false;\n\n /**\n * Whether to log warnings about the use of the `Buffer` global. If `false`,\n * warnings will not be logged. If `true`, the CLI will warn if the `Buffer`\n * global is used, but not provided by Webpack's `DefinePlugin`.\n */\n buffer?: boolean;\n };\n\n /**\n * Whether to provide polyfills for node builtins. If `true`, all the available\n * polyfills will be provided. If `false` no polyfills will be provided. If a\n * configuration object is passed only the polyfills set to `true` will be provided.\n *\n * @default false\n * @example\n * ```ts\n * polyfills: true\n *\n * // or\n *\n * polyfills: {\n * assert: true,\n * buffer: true\n * }\n * ```\n */\n polyfills?:\n | boolean\n | {\n assert?: boolean;\n buffer?: boolean;\n console?: boolean;\n constants?: boolean;\n crypto?: boolean;\n domain?: boolean;\n events?: boolean;\n http?: boolean;\n https?: boolean;\n os?: boolean;\n path?: boolean;\n punycode?: boolean;\n process?: boolean;\n querystring?: boolean;\n stream?: boolean;\n /* eslint-disable @typescript-eslint/naming-convention */\n _stream_duplex?: boolean;\n _stream_passthrough?: boolean;\n _stream_readable?: boolean;\n _stream_transform?: boolean;\n _stream_writable?: boolean;\n string_decoder?: boolean;\n /* eslint-enable @typescript-eslint/naming-convention */\n sys?: boolean;\n timers?: boolean;\n tty?: boolean;\n url?: boolean;\n util?: boolean;\n vm?: boolean;\n zlib?: boolean;\n };\n\n /**\n * A function to customize the Webpack configuration used to build the snap.\n * This function will be called with the default Webpack configuration, and\n * should return the modified configuration. If not specified, the default\n * configuration will be used.\n *\n * It's recommended to use the `webpack-merge` package to merge the default\n * configuration with your customizations. The merge function is exported as\n * `merge` from the `@metamask/snaps-cli` package.\n *\n * @example\n * ```ts\n * import type { SnapsConfig } from '@metamask/snaps-cli';\n * import { merge } from '@metamask/snaps-cli';\n *\n * const config: SnapsConfig = {\n * bundler: 'webpack',\n * entry: 'src/index.ts',\n * customizeWebpackConfig: (config) => merge(config, {\n * module: {\n * rules: [\n * {\n * test: /\\.wasm$/,\n * type: 'assets/resource',\n * },\n * ],\n * },\n * }),\n * };\n *\n * export default config;\n * ```\n */\n customizeWebpackConfig?: (\n config: WebpackConfiguration,\n ) => WebpackConfiguration;\n\n /**\n * Experimental features that can be enabled. These features are not\n * guaranteed to be stable, and may be removed or changed in a future release.\n */\n experimental?: {\n /**\n * Whether to enable WebAssembly support. If `true`, the Webpack\n * configuration will be modified to support WebAssembly. If `false`, the\n * Webpack configuration will not be modified.\n *\n * @default false\n */\n wasm?: boolean;\n };\n};\n\n/**\n * The configuration for the Snaps CLI, stored as `snap.config.js` or\n * `snap.config.ts` in the root of the project.\n */\nexport type SnapConfig = SnapBrowserifyConfig | SnapWebpackConfig;\n\ntype SnapsBrowserifyBundlerCustomizerFunction = (\n bundler: BrowserifyObject,\n) => void;\n\n// This struct is essentially the same as the `func` struct, but it's defined\n// separately so that we include the function type in the inferred TypeScript\n// type definitions.\nconst SnapsBrowserifyBundlerCustomizerFunctionStruct =\n define<SnapsBrowserifyBundlerCustomizerFunction>(\n 'function',\n func().validator,\n );\n\nexport const SnapsBrowserifyConfigStruct = object({\n bundler: defaulted(literal('browserify'), 'browserify'),\n cliOptions: defaulted(\n object({\n bundle: optional(file()),\n dist: defaulted(file(), 'dist'),\n eval: defaulted(boolean(), true),\n manifest: defaulted(boolean(), true),\n port: defaulted(number(), 8081),\n outfileName: defaulted(string(), 'bundle.js'),\n root: defaulted(file(), process.cwd()),\n sourceMaps: defaulted(boolean(), false),\n src: defaulted(file(), 'src/index.js'),\n stripComments: defaulted(boolean(), true),\n suppressWarnings: defaulted(boolean(), false),\n transpilationMode: defaulted(\n union([literal('localAndDeps'), literal('localOnly'), literal('none')]),\n 'localOnly',\n ),\n depsToTranspile: defaulted(array(string()), []),\n verboseErrors: defaulted(boolean(), true),\n writeManifest: defaulted(boolean(), true),\n serve: defaulted(boolean(), true),\n }),\n {},\n ),\n bundlerCustomizer: optional(SnapsBrowserifyBundlerCustomizerFunctionStruct),\n});\n\ntype SnapsWebpackCustomizeWebpackConfigFunction = (\n config: WebpackConfiguration,\n) => WebpackConfiguration;\n\n// This struct is essentially the same as the `func` struct, but it's defined\n// separately so that we include the function type in the inferred TypeScript\n// type definitions.\nconst SnapsWebpackCustomizeWebpackConfigFunctionStruct =\n define<SnapsWebpackCustomizeWebpackConfigFunction>(\n 'function',\n func().validator,\n );\n\nexport const SnapsWebpackConfigStruct = object({\n bundler: literal('webpack'),\n input: defaulted(file(), resolve(process.cwd(), 'src/index.js')),\n sourceMap: defaulted(union([boolean(), literal('inline')]), false),\n evaluate: defaulted(boolean(), true),\n\n output: defaulted(\n object({\n path: defaulted(file(), resolve(process.cwd(), 'dist')),\n filename: defaulted(string(), 'bundle.js'),\n clean: defaulted(boolean(), false),\n minimize: defaulted(boolean(), true),\n }),\n {},\n ),\n\n manifest: defaulted(\n object({\n path: defaulted(file(), resolve(process.cwd(), 'snap.manifest.json')),\n update: defaulted(boolean(), true),\n }),\n {},\n ),\n\n server: defaulted(\n object({\n enabled: defaulted(boolean(), true),\n root: defaulted(file(), process.cwd()),\n port: defaulted(number(), 8081),\n }),\n {},\n ),\n\n environment: defaulted(record(string(), unknown()), {}),\n\n stats: defaulted(\n object({\n verbose: defaulted(boolean(), false),\n builtIns: defaulted(\n union([\n object({ ignore: defaulted(array(string()), []) }),\n literal(false),\n ]),\n {},\n ),\n buffer: defaulted(boolean(), true),\n }),\n {},\n ),\n\n polyfills: defaulted(\n union([\n boolean(),\n object({\n assert: defaulted(boolean(), false),\n buffer: defaulted(boolean(), false),\n console: defaulted(boolean(), false),\n constants: defaulted(boolean(), false),\n crypto: defaulted(boolean(), false),\n domain: defaulted(boolean(), false),\n events: defaulted(boolean(), false),\n http: defaulted(boolean(), false),\n https: defaulted(boolean(), false),\n os: defaulted(boolean(), false),\n path: defaulted(boolean(), false),\n punycode: defaulted(boolean(), false),\n process: defaulted(boolean(), false),\n querystring: defaulted(boolean(), false),\n stream: defaulted(boolean(), false),\n /* eslint-disable @typescript-eslint/naming-convention */\n _stream_duplex: defaulted(boolean(), false),\n _stream_passthrough: defaulted(boolean(), false),\n _stream_readable: defaulted(boolean(), false),\n _stream_transform: defaulted(boolean(), false),\n _stream_writable: defaulted(boolean(), false),\n string_decoder: defaulted(boolean(), false),\n /* eslint-enable @typescript-eslint/naming-convention */\n sys: defaulted(boolean(), false),\n timers: defaulted(boolean(), false),\n tty: defaulted(boolean(), false),\n url: defaulted(boolean(), false),\n util: defaulted(boolean(), false),\n vm: defaulted(boolean(), false),\n zlib: defaulted(boolean(), false),\n }),\n ]),\n false,\n ),\n\n customizeWebpackConfig: optional(\n SnapsWebpackCustomizeWebpackConfigFunctionStruct,\n ),\n\n experimental: defaulted(\n object({\n wasm: defaulted(boolean(), false),\n }),\n {},\n ),\n});\n\nexport const SnapsConfigStruct = type({\n bundler: defaulted(\n union([literal('browserify'), literal('webpack')]),\n 'browserify',\n ),\n});\n\nexport const LegacyOptionsStruct = union([\n named(\n 'object with `transpilationMode` set to `localAndDeps` and `depsToTranspile` set to an array of strings',\n type({\n depsToTranspile: array(string()),\n transpilationMode: literal(TranspilationModes.LocalAndDeps),\n writeManifest: boolean(),\n bundlerCustomizer: optional(\n SnapsBrowserifyBundlerCustomizerFunctionStruct,\n ),\n }),\n ),\n named(\n 'object without `depsToTranspile`',\n type({\n depsToTranspile: named('empty array', empty(array())),\n transpilationMode: union([\n literal(TranspilationModes.LocalOnly),\n literal(TranspilationModes.None),\n ]),\n writeManifest: boolean(),\n bundlerCustomizer: optional(\n SnapsBrowserifyBundlerCustomizerFunctionStruct,\n ),\n }),\n ),\n]);\n\nexport type LegacyOptions = Infer<typeof LegacyOptionsStruct>;\n\nexport type ProcessedBrowserifyConfig = Infer<\n typeof SnapsBrowserifyConfigStruct\n>;\n\nexport type ProcessedWebpackConfig = Infer<typeof SnapsWebpackConfigStruct> & {\n /**\n * The legacy Browserify config, if the bundler is Browserify. This is used\n * to support the legacy config format.\n */\n legacy?: LegacyOptions;\n};\n\nexport type ProcessedConfig = ProcessedWebpackConfig;\n\n/**\n * Get a validated snap config. This validates the config and adds default\n * values for any missing properties.\n *\n * @param config - The config to validate.\n * @param argv - The CLI arguments.\n * @returns The validated config.\n */\nexport function getConfig(config: unknown, argv: YargsArgs): ProcessedConfig {\n const prefix = 'The snap config file is invalid';\n const suffix = dim(\n // TODO: Link to `docs.metamask.io` once the docs are published.\n 'Refer to the documentation for more information: https://github.com/MetaMask/snaps/tree/main/packages/snaps-cli/',\n );\n\n const { bundler } = createFromStruct(\n config,\n SnapsConfigStruct,\n prefix,\n suffix,\n );\n\n if (bundler === 'browserify') {\n const legacyConfig = createFromStruct(\n config,\n SnapsBrowserifyConfigStruct,\n prefix,\n suffix,\n );\n\n return getWebpackConfig(mergeLegacyOptions(argv, legacyConfig));\n }\n\n return createFromStruct(config, SnapsWebpackConfigStruct, prefix, suffix);\n}\n\n/**\n * Load a snap config from a file. This supports both JavaScript and TypeScript\n * config files, in the CommonJS module format and the ES module format.\n *\n * This assumes that the config file exports a default object, either through\n * `module.exports` or `export default`.\n *\n * @param path - The full path to the config file.\n * @param argv - The CLI arguments.\n * @returns The validated config.\n * @throws If the config file is invalid, or if the config file does not have a\n * default export.\n */\nexport async function loadConfig(path: string, argv: YargsArgs) {\n try {\n const contents = await readFile(path, 'utf8');\n const source = await transform(contents, {\n swcrc: false,\n jsc: {\n parser: {\n syntax: 'typescript',\n },\n },\n module: {\n type: 'commonjs',\n },\n });\n\n const config = new Module(path);\n\n // @ts-expect-error - This function is not typed.\n config.paths = Module._nodeModulePaths(dirname(path));\n\n // @ts-expect-error - This function is not typed.\n config._compile(source.code, path);\n\n if (!hasProperty(config.exports, 'default')) {\n return getConfig(config.exports, argv);\n }\n\n return getConfig(config.exports.default, argv);\n } catch (error) {\n if (error instanceof SnapsStructError) {\n throw new ConfigError(error.message);\n }\n\n throw new ConfigError(\n `Unable to load snap config file at \"${path}\".\\n\\n${indent(\n error.message,\n )}`,\n );\n }\n}\n\n/**\n * Resolve a snap config. This function will look for a `snap.config.js` or\n * `snap.config.ts` file in the current or specified directory.\n *\n * @param path - The path to resolve the snap config from. Defaults to the\n * current working directory.\n * @param argv - The CLI arguments.\n * @returns The resolved and validated snap config.\n * @throws If a snap config could not be found.\n */\nexport async function resolveConfig(path: string, argv: YargsArgs) {\n for (const configFile of CONFIG_FILES) {\n const filePath = resolve(path, configFile);\n if (await isFile(filePath)) {\n return await loadConfig(filePath, argv);\n }\n }\n\n throw new ConfigError(\n `Could not find a \"snap.config.js\" or \"snap.config.ts\" file in the current or specified directory (\"${path}\").`,\n );\n}\n\n/**\n * Get a snap config from the CLI arguments. This will either load the config\n * from the specified config file, or resolve the config from the current\n * working directory.\n *\n * @param argv - The CLI arguments.\n * @param cwd - The current working directory. Defaults to `process.cwd()`.\n * @returns The resolved and validated snap config.\n */\nexport async function getConfigByArgv(\n argv: YargsArgs,\n cwd: string = process.cwd(),\n) {\n if (argv.config) {\n if (!(await isFile(argv.config))) {\n throw new ConfigError(\n `Could not find a config file at \"${argv.config}\". Make sure that the path is correct.`,\n );\n }\n\n return await loadConfig(argv.config, argv);\n }\n\n return await resolveConfig(cwd, argv);\n}\n\n/**\n * Merge legacy CLI options into the config. This is used to support the legacy\n * config format, where options can be specified both in the config file and\n * through CLI flags.\n *\n * @param argv - The CLI arguments.\n * @param config - The config to merge the CLI options into.\n * @returns The config with the CLI options merged in.\n * @deprecated This function is only used to support the legacy config format.\n */\nexport function mergeLegacyOptions(\n argv: YargsArgs,\n config: ProcessedBrowserifyConfig,\n) {\n const cliOptions = Object.keys(config.cliOptions).reduce<\n ProcessedBrowserifyConfig['cliOptions']\n >((accumulator, key) => {\n if (argv[key] !== undefined) {\n return {\n ...accumulator,\n [key]: argv[key],\n };\n }\n\n return accumulator;\n }, config.cliOptions);\n\n return {\n ...config,\n cliOptions,\n };\n}\n\n/**\n * Get a Webpack config from a legacy browserify config. This is used to\n * support the legacy config format, and convert it to the new format.\n *\n * @param legacyConfig - The legacy browserify config.\n * @returns The Webpack config.\n */\nexport function getWebpackConfig(\n legacyConfig: ProcessedBrowserifyConfig,\n): ProcessedWebpackConfig {\n const defaultConfig = create(\n { bundler: 'webpack' },\n SnapsWebpackConfigStruct,\n );\n\n // The legacy config has two options for specifying the output path and\n // filename: `bundle`, and `dist` + `outfileName`. If `bundle` is specified,\n // we use that as the output path and filename. Otherwise, we use `dist` and\n // `outfileName`.\n const path = legacyConfig.cliOptions.bundle\n ? dirname(legacyConfig.cliOptions.bundle)\n : legacyConfig.cliOptions.dist;\n\n const filename = legacyConfig.cliOptions.bundle\n ? basename(legacyConfig.cliOptions.bundle)\n : legacyConfig.cliOptions.outfileName;\n\n return {\n ...defaultConfig,\n input: legacyConfig.cliOptions.src,\n evaluate: legacyConfig.cliOptions.eval,\n sourceMap: legacyConfig.cliOptions.sourceMaps,\n output: {\n path,\n filename,\n\n // The legacy config has an option to remove comments from the bundle, but\n // the terser plugin does this by default, so we only enable the terser if\n // the legacy config has `stripComments` set to `true`. This is not a\n // perfect solution, but it's the best we can do without breaking the\n // legacy config.\n minimize: legacyConfig.cliOptions.stripComments,\n\n // The legacy config does not have a `clean` option, so we default to\n // `false` here.\n clean: false,\n },\n manifest: {\n // The legacy config does not have a `manifest` option, so we default to\n // `process.cwd()/snap.manifest.json`.\n path: resolve(process.cwd(), 'snap.manifest.json'),\n update: legacyConfig.cliOptions.writeManifest,\n },\n server: {\n enabled: legacyConfig.cliOptions.serve,\n port: legacyConfig.cliOptions.port,\n root: legacyConfig.cliOptions.root,\n },\n stats: {\n verbose: false,\n\n // These plugins are designed to be used with the modern config format, so\n // we disable them for the legacy config format.\n builtIns: false,\n buffer: false,\n },\n legacy: createFromStruct(\n {\n ...legacyConfig.cliOptions,\n bundlerCustomizer: legacyConfig.bundlerCustomizer,\n },\n LegacyOptionsStruct,\n 'Invalid Browserify CLI options',\n ),\n };\n}\n"],"names":["literal","union","createFromStruct","file","indent","isFile","SnapsStructError","named","hasProperty","transform","dim","readFile","Module","basename","dirname","resolve","array","boolean","create","defaulted","define","func","number","object","optional","record","string","type","unknown","empty","TranspilationModes","ConfigError","CONFIG_FILE","TS_CONFIG_FILE","CONFIG_FILES","SnapsBrowserifyBundlerCustomizerFunctionStruct","validator","SnapsBrowserifyConfigStruct","bundler","cliOptions","bundle","dist","eval","manifest","port","outfileName","root","process","cwd","sourceMaps","src","stripComments","suppressWarnings","transpilationMode","depsToTranspile","verboseErrors","writeManifest","serve","bundlerCustomizer","SnapsWebpackCustomizeWebpackConfigFunctionStruct","SnapsWebpackConfigStruct","input","sourceMap","evaluate","output","path","filename","clean","minimize","update","server","enabled","environment","stats","verbose","builtIns","ignore","buffer","polyfills","assert","console","constants","crypto","domain","events","http","https","os","punycode","querystring","stream","_stream_duplex","_stream_passthrough","_stream_readable","_stream_transform","_stream_writable","string_decoder","sys","timers","tty","url","util","vm","zlib","customizeWebpackConfig","experimental","wasm","SnapsConfigStruct","LegacyOptionsStruct","LocalAndDeps","LocalOnly","None","getConfig","config","argv","prefix","suffix","legacyConfig","getWebpackConfig","mergeLegacyOptions","loadConfig","contents","source","swcrc","jsc","parser","syntax","module","paths","_nodeModulePaths","_compile","code","exports","default","error","message","resolveConfig","configFile","filePath","getConfigByArgv","Object","keys","reduce","accumulator","key","undefined","defaultConfig","legacy"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import SnapsWebpackPlugin from '@metamask/snaps-webpack-plugin';
|
|
2
2
|
import { resolve } from 'path';
|
|
3
3
|
import TerserPlugin from 'terser-webpack-plugin';
|
|
4
|
-
import {
|
|
4
|
+
import { DefinePlugin, ProgressPlugin, ProvidePlugin } from 'webpack';
|
|
5
5
|
import { SnapsBuiltInResolver, SnapsBundleWarningsPlugin, SnapsStatsPlugin, SnapsWatchPlugin } from './plugins';
|
|
6
|
-
import { BROWSERSLIST_FILE, getDefaultLoader, getDevTool, getFallbacks, getProgressHandler } from './utils';
|
|
6
|
+
import { BROWSERSLIST_FILE, getDefaultLoader, getDevTool, getEnvironmentVariables, getFallbacks, getProgressHandler } from './utils';
|
|
7
7
|
/**
|
|
8
8
|
* Get the default Webpack configuration. This is the configuration that will
|
|
9
9
|
* be used if the user doesn't provide a custom Webpack configuration. The
|
|
@@ -119,7 +119,7 @@ import { BROWSERSLIST_FILE, getDefaultLoader, getDevTool, getFallbacks, getProgr
|
|
|
119
119
|
*/ module: {
|
|
120
120
|
rules: [
|
|
121
121
|
{
|
|
122
|
-
test: /\.
|
|
122
|
+
test: /\.(js|mjs|cjs|ts)$/u,
|
|
123
123
|
exclude: /node_modules/u,
|
|
124
124
|
use: await getDefaultLoader(config)
|
|
125
125
|
},
|
|
@@ -149,10 +149,12 @@ import { BROWSERSLIST_FILE, getDefaultLoader, getDevTool, getFallbacks, getProgr
|
|
|
149
149
|
* @see https://webpack.js.org/configuration/resolve/
|
|
150
150
|
*/ resolve: {
|
|
151
151
|
/**
|
|
152
|
-
* The extensions to resolve. We set it to resolve `.js` and `.ts`
|
|
152
|
+
* The extensions to resolve. We set it to resolve `.(c|m)?js` and `.ts`
|
|
153
153
|
* files.
|
|
154
154
|
*/ extensions: [
|
|
155
155
|
'.js',
|
|
156
|
+
'.mjs',
|
|
157
|
+
'.cjs',
|
|
156
158
|
'.ts'
|
|
157
159
|
],
|
|
158
160
|
/**
|
|
@@ -189,10 +191,11 @@ import { BROWSERSLIST_FILE, getDefaultLoader, getDevTool, getFallbacks, getProgr
|
|
|
189
191
|
verbose: config.stats.verbose
|
|
190
192
|
}, options.spinner),
|
|
191
193
|
/**
|
|
192
|
-
* The `
|
|
193
|
-
*
|
|
194
|
-
* environment variables
|
|
195
|
-
|
|
194
|
+
* The `DefinePlugin` is a Webpack plugin that adds static values to the
|
|
195
|
+
* bundle. We use it to add the `NODE_DEBUG`, `NODE_ENV`, and `DEBUG`
|
|
196
|
+
* environment variables, as well as any custom environment
|
|
197
|
+
* variables (as `process.env`).
|
|
198
|
+
*/ new DefinePlugin(getEnvironmentVariables(config.environment)),
|
|
196
199
|
/**
|
|
197
200
|
* The `ProgressPlugin` is a Webpack plugin that logs the progress of
|
|
198
201
|
* the build. We set it to log the progress to the spinner.
|
|
@@ -207,7 +210,7 @@ import { BROWSERSLIST_FILE, getDefaultLoader, getDevTool, getFallbacks, getProgr
|
|
|
207
210
|
builtInResolver,
|
|
208
211
|
builtIns: Boolean(config.stats.builtIns),
|
|
209
212
|
buffer: config.stats.buffer
|
|
210
|
-
}
|
|
213
|
+
}),
|
|
211
214
|
/**
|
|
212
215
|
* The `WatchPlugin` is a Webpack plugin that adds extra files to watch
|
|
213
216
|
* for changes. This is useful for rebuilding the bundle when the
|
|
@@ -244,6 +247,19 @@ import { BROWSERSLIST_FILE, getDefaultLoader, getDevTool, getFallbacks, getProgr
|
|
|
244
247
|
]
|
|
245
248
|
},
|
|
246
249
|
/**
|
|
250
|
+
* The performance configuration. This tells Webpack how to handle
|
|
251
|
+
* performance hints.
|
|
252
|
+
*
|
|
253
|
+
* @see https://webpack.js.org/configuration/performance/
|
|
254
|
+
*/ performance: {
|
|
255
|
+
/**
|
|
256
|
+
* The hints to show. We set it to `false`, so that we don't get
|
|
257
|
+
* performance hints, as they are not relevant for Snaps.
|
|
258
|
+
*
|
|
259
|
+
* @see https://webpack.js.org/configuration/performance/#performancehints
|
|
260
|
+
*/ hints: false
|
|
261
|
+
},
|
|
262
|
+
/**
|
|
247
263
|
* The infrastructure logging configuration. This tells Webpack how to
|
|
248
264
|
* log messages.
|
|
249
265
|
*
|