@metamask/snaps-utils 9.0.0 → 9.0.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 +8 -1
- package/dist/eval-worker.cjs +1 -1
- package/dist/eval-worker.cjs.map +1 -1
- package/dist/eval-worker.mjs +1 -1
- package/dist/eval-worker.mjs.map +1 -1
- package/dist/fs.cjs +1 -1
- package/dist/fs.cjs.map +1 -1
- package/dist/fs.mjs +1 -1
- package/dist/fs.mjs.map +1 -1
- package/dist/iframe.cjs +0 -1
- package/dist/iframe.cjs.map +1 -1
- package/dist/iframe.d.cts +0 -1
- package/dist/iframe.d.cts.map +1 -1
- package/dist/iframe.d.mts +0 -1
- package/dist/iframe.d.mts.map +1 -1
- package/dist/iframe.mjs +0 -1
- package/dist/iframe.mjs.map +1 -1
- package/dist/index.cjs +0 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +0 -1
- package/dist/index.mjs.map +1 -1
- package/dist/json-rpc.cjs +2 -6
- package/dist/json-rpc.cjs.map +1 -1
- package/dist/json-rpc.d.cts.map +1 -1
- package/dist/json-rpc.d.mts.map +1 -1
- package/dist/json-rpc.mjs +2 -6
- package/dist/json-rpc.mjs.map +1 -1
- package/dist/manifest/manifest.cjs +1 -1
- package/dist/manifest/manifest.cjs.map +1 -1
- package/dist/manifest/manifest.d.cts +2 -2
- package/dist/manifest/manifest.d.cts.map +1 -1
- package/dist/manifest/manifest.d.mts +2 -2
- package/dist/manifest/manifest.d.mts.map +1 -1
- package/dist/manifest/manifest.mjs +1 -1
- package/dist/manifest/manifest.mjs.map +1 -1
- package/dist/manifest/validator-types.cjs.map +1 -1
- package/dist/manifest/validator-types.d.cts +1 -1
- package/dist/manifest/validator-types.d.cts.map +1 -1
- package/dist/manifest/validator-types.d.mts +1 -1
- package/dist/manifest/validator-types.d.mts.map +1 -1
- package/dist/manifest/validator-types.mjs.map +1 -1
- package/dist/manifest/validator.cjs.map +1 -1
- package/dist/manifest/validator.d.cts +1 -1
- package/dist/manifest/validator.d.cts.map +1 -1
- package/dist/manifest/validator.d.mts +1 -1
- package/dist/manifest/validator.d.mts.map +1 -1
- package/dist/manifest/validator.mjs.map +1 -1
- package/dist/manifest/validators/platform-version.cjs +1 -1
- package/dist/manifest/validators/platform-version.cjs.map +1 -1
- package/dist/manifest/validators/platform-version.mjs +1 -1
- package/dist/manifest/validators/platform-version.mjs.map +1 -1
- package/dist/mock.cjs +0 -3
- package/dist/mock.cjs.map +1 -1
- package/dist/mock.d.cts.map +1 -1
- package/dist/mock.d.mts.map +1 -1
- package/dist/mock.mjs +0 -3
- package/dist/mock.mjs.map +1 -1
- package/dist/node.cjs +1 -1
- package/dist/node.cjs.map +1 -1
- package/dist/node.mjs +1 -1
- package/dist/node.mjs.map +1 -1
- package/dist/post-process.cjs.map +1 -1
- package/dist/post-process.d.cts.map +1 -1
- package/dist/post-process.d.mts.map +1 -1
- package/dist/post-process.mjs.map +1 -1
- package/dist/snaps.cjs +21 -3
- package/dist/snaps.cjs.map +1 -1
- package/dist/snaps.d.cts +2 -1
- package/dist/snaps.d.cts.map +1 -1
- package/dist/snaps.d.mts +2 -1
- package/dist/snaps.d.mts.map +1 -1
- package/dist/snaps.mjs +22 -4
- package/dist/snaps.mjs.map +1 -1
- package/dist/types.cjs +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +3 -3
- package/dist/types.mjs.map +1 -1
- package/dist/ui.cjs +7 -5
- package/dist/ui.cjs.map +1 -1
- package/dist/ui.d.cts.map +1 -1
- package/dist/ui.d.mts.map +1 -1
- package/dist/ui.mjs +7 -5
- package/dist/ui.mjs.map +1 -1
- package/dist/virtual-file/VirtualFile.cjs.map +1 -1
- package/dist/virtual-file/VirtualFile.mjs.map +1 -1
- package/package.json +8 -22
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.cjs","sourceRoot":"","sources":["../../src/manifest/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import { getErrorMessage } from '@metamask/snaps-sdk';\nimport type { Json } from '@metamask/utils';\nimport { assert, isPlainObject } from '@metamask/utils';\nimport { promises as fs } from 'fs';\nimport pathUtils from 'path';\n\nimport { deepClone } from '../deep-clone';\nimport { readJsonFile } from '../fs';\nimport { parseJson } from '../json';\nimport type { SnapFiles, UnvalidatedSnapFiles } from '../types';\nimport { NpmSnapFileNames } from '../types';\nimport { readVirtualFile, VirtualFile } from '../virtual-file/node';\nimport type { SnapManifest } from './validation';\nimport type { ValidatorResults } from './validator';\nimport { hasFixes, runValidators } from './validator';\nimport type { ValidatorMeta, ValidatorReport } from './validator-types';\n\nconst MANIFEST_SORT_ORDER: Record<keyof SnapManifest, number> = {\n $schema: 1,\n version: 2,\n description: 3,\n proposedName: 4,\n repository: 5,\n source: 6,\n initialConnections: 7,\n initialPermissions: 8,\n platformVersion: 9,\n manifestVersion: 10,\n};\n\nexport type CheckManifestReport = Omit<ValidatorReport, 'fix'> & {\n wasFixed?: boolean;\n};\n\n/**\n * The result from the `checkManifest` function.\n *\n * @property manifest - The fixed manifest object.\n * @property updated - Whether the manifest was written and updated.\n */\nexport type CheckManifestResult = {\n files?: SnapFiles;\n updated: boolean;\n reports: CheckManifestReport[];\n};\n\nexport type WriteFileFunction = (path: string, data: string) => Promise<void>;\n\n/**\n * Validates a snap.manifest.json file. Attempts to fix the manifest and write\n * the fixed version to disk if `writeManifest` is true. Throws if validation\n * fails.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param options - Additional options for the function.\n * @param options.sourceCode - The source code of the Snap.\n * @param options.writeFileFn - The function to use to write the manifest to disk.\n * @param options.updateAndWriteManifest - Whether to auto-magically try to fix errors and then write the manifest to disk.\n * @returns Whether the manifest was updated, and an array of warnings that\n * were encountered during processing of the manifest files.\n */\nexport async function checkManifest(\n basePath: string,\n {\n updateAndWriteManifest = true,\n sourceCode,\n writeFileFn = fs.writeFile,\n }: {\n updateAndWriteManifest?: boolean;\n sourceCode?: string;\n writeFileFn?: WriteFileFunction;\n } = {},\n): Promise<CheckManifestResult> {\n const manifestPath = pathUtils.join(basePath, NpmSnapFileNames.Manifest);\n const manifestFile = await readJsonFile(manifestPath);\n const unvalidatedManifest = manifestFile.result;\n\n const packageFile = await readJsonFile(\n pathUtils.join(basePath, NpmSnapFileNames.PackageJson),\n );\n\n const auxiliaryFilePaths = getSnapFilePaths(\n unvalidatedManifest,\n (manifest) => manifest?.source?.files,\n );\n\n const localizationFilePaths = getSnapFilePaths(\n unvalidatedManifest,\n (manifest) => manifest?.source?.locales,\n );\n const localizationFiles =\n (await getSnapFiles(basePath, localizationFilePaths)) ?? [];\n for (const localization of localizationFiles) {\n try {\n localization.result = parseJson(localization.toString());\n } catch (error) {\n assert(error instanceof SyntaxError, error);\n throw new Error(\n `Failed to parse localization file \"${localization.path}\" as JSON.`,\n );\n }\n }\n\n const snapFiles: UnvalidatedSnapFiles = {\n manifest: manifestFile,\n packageJson: packageFile,\n sourceCode: await getSnapSourceCode(\n basePath,\n unvalidatedManifest,\n sourceCode,\n ),\n svgIcon: await getSnapIcon(basePath, unvalidatedManifest),\n // Intentionally pass null as the encoding here since the files may be binary\n auxiliaryFiles:\n (await getSnapFiles(basePath, auxiliaryFilePaths, null)) ?? [],\n localizationFiles,\n };\n\n const validatorResults = await runValidators(snapFiles);\n let manifestResults: CheckManifestResult = {\n updated: false,\n files: validatorResults.files,\n reports: validatorResults.reports,\n };\n\n if (updateAndWriteManifest && hasFixes(manifestResults)) {\n const fixedResults = await runFixes(validatorResults);\n\n if (fixedResults.updated) {\n manifestResults = fixedResults;\n\n assert(manifestResults.files);\n\n try {\n await writeFileFn(\n pathUtils.join(basePath, NpmSnapFileNames.Manifest),\n manifestResults.files.manifest.toString(),\n );\n } catch (error) {\n // Note: This error isn't pushed to the errors array, because it's not an\n // error in the manifest itself.\n throw new Error(\n `Failed to update \"snap.manifest.json\": ${getErrorMessage(error)}`,\n );\n }\n }\n }\n\n return manifestResults;\n}\n\n/**\n * Run the algorithm for automatically fixing errors in manifest.\n *\n * The algorithm updates the manifest by fixing all fixable problems,\n * and then run validation again to check if the new manifest is now correct.\n * If not correct, the algorithm will use the manifest from previous iteration\n * and try again `MAX_ATTEMPTS` times to update it before bailing and\n * resulting in failure.\n *\n * @param results - Results of the initial run of validation.\n * @param rules - Optional list of rules to run the fixes with.\n * @returns The updated manifest and whether it was updated.\n */\nexport async function runFixes(\n results: ValidatorResults,\n rules?: ValidatorMeta[],\n): Promise<CheckManifestResult> {\n let shouldRunFixes = true;\n const MAX_ATTEMPTS = 10;\n\n assert(results.files);\n\n let fixResults: ValidatorResults = results;\n assert(fixResults.files);\n fixResults.files.manifest = fixResults.files.manifest.clone();\n\n for (\n let attempts = 1;\n shouldRunFixes && attempts <= MAX_ATTEMPTS;\n attempts++\n ) {\n assert(fixResults.files);\n\n let manifest = fixResults.files.manifest.result;\n\n const fixable = fixResults.reports.filter((report) => report.fix);\n for (const report of fixable) {\n assert(report.fix);\n ({ manifest } = await report.fix({ manifest }));\n }\n\n fixResults.files.manifest.value = `${JSON.stringify(\n getWritableManifest(manifest),\n null,\n 2,\n )}\\n`;\n fixResults.files.manifest.result = manifest;\n\n fixResults = await runValidators(fixResults.files, rules);\n shouldRunFixes = hasFixes(fixResults);\n }\n\n const initialReports: (CheckManifestReport & ValidatorReport)[] = deepClone(\n results.reports,\n );\n\n // Was fixed\n if (!shouldRunFixes) {\n for (const report of initialReports) {\n if (report.fix) {\n report.wasFixed = true;\n delete report.fix;\n }\n }\n\n return {\n files: fixResults.files,\n updated: true,\n reports: initialReports,\n };\n }\n\n for (const report of initialReports) {\n delete report.fix;\n }\n\n return {\n files: results.files,\n updated: false,\n reports: initialReports,\n };\n}\n\n/**\n * Given an unvalidated Snap manifest, attempts to extract the location of the\n * bundle source file location and read the file.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param manifest - The unvalidated Snap manifest file contents.\n * @param sourceCode - Override source code for plugins.\n * @returns The contents of the bundle file, if any.\n */\nexport async function getSnapSourceCode(\n basePath: string,\n manifest: Json,\n sourceCode?: string,\n): Promise<VirtualFile | undefined> {\n if (!isPlainObject(manifest)) {\n return undefined;\n }\n\n const sourceFilePath = (manifest as Partial<SnapManifest>).source?.location\n ?.npm?.filePath;\n\n if (!sourceFilePath) {\n return undefined;\n }\n\n if (sourceCode) {\n return new VirtualFile({\n path: pathUtils.join(basePath, sourceFilePath),\n value: sourceCode,\n });\n }\n\n try {\n const virtualFile = await readVirtualFile(\n pathUtils.join(basePath, sourceFilePath),\n 'utf8',\n );\n return virtualFile;\n } catch (error) {\n throw new Error(\n `Failed to read snap bundle file: ${getErrorMessage(error)}`,\n );\n }\n}\n\n/**\n * Given an unvalidated Snap manifest, attempts to extract the location of the\n * icon and read the file.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param manifest - The unvalidated Snap manifest file contents.\n * @returns The contents of the icon, if any.\n */\nexport async function getSnapIcon(\n basePath: string,\n manifest: Json,\n): Promise<VirtualFile | undefined> {\n if (!isPlainObject(manifest)) {\n return undefined;\n }\n\n const iconPath = (manifest as Partial<SnapManifest>).source?.location?.npm\n ?.iconPath;\n\n if (!iconPath) {\n return undefined;\n }\n\n try {\n const virtualFile = await readVirtualFile(\n pathUtils.join(basePath, iconPath),\n 'utf8',\n );\n return virtualFile;\n } catch (error) {\n throw new Error(`Failed to read snap icon file: ${getErrorMessage(error)}`);\n }\n}\n\n/**\n * Get an array of paths from an unvalidated Snap manifest.\n *\n * @param manifest - The unvalidated Snap manifest file contents.\n * @param selector - A function that returns the paths to the files.\n * @returns The paths to the files, if any.\n */\nexport function getSnapFilePaths(\n manifest: Json,\n selector: (manifest: Partial<SnapManifest>) => string[] | undefined,\n) {\n if (!isPlainObject(manifest)) {\n return undefined;\n }\n\n const snapManifest = manifest as Partial<SnapManifest>;\n const paths = selector(snapManifest);\n\n if (!Array.isArray(paths)) {\n return undefined;\n }\n\n return paths;\n}\n\n/**\n * Given an unvalidated Snap manifest, attempts to extract the files with the\n * given paths and read them.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param paths - The paths to the files.\n * @param encoding - An optional encoding to pass down to readVirtualFile.\n * @returns A list of auxiliary files and their contents, if any.\n */\nexport async function getSnapFiles(\n basePath: string,\n paths: string[] | undefined,\n encoding: BufferEncoding | null = 'utf8',\n): Promise<VirtualFile[] | undefined> {\n if (!paths) {\n return undefined;\n }\n\n try {\n return await Promise.all(\n paths.map(async (filePath) =>\n readVirtualFile(pathUtils.join(basePath, filePath), encoding),\n ),\n );\n } catch (error) {\n throw new Error(`Failed to read snap files: ${getErrorMessage(error)}`);\n }\n}\n\n/**\n * Sorts the given manifest in our preferred sort order and removes the\n * `repository` field if it is falsy (it may be `null`).\n *\n * @param manifest - The manifest to sort and modify.\n * @returns The disk-ready manifest.\n */\nexport function getWritableManifest(manifest: SnapManifest): SnapManifest {\n const { repository, ...remaining } = manifest;\n\n const keys = Object.keys(\n repository ? { ...remaining, repository } : remaining,\n ) as (keyof SnapManifest)[];\n\n const writableManifest = keys\n .sort((a, b) => MANIFEST_SORT_ORDER[a] - MANIFEST_SORT_ORDER[b])\n .reduce<Partial<SnapManifest>>(\n (result, key) => ({\n ...result,\n [key]: manifest[key],\n }),\n {},\n );\n\n return writableManifest as SnapManifest;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"manifest.cjs","sourceRoot":"","sources":["../../src/manifest/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import { getErrorMessage } from '@metamask/snaps-sdk';\nimport type { Json } from '@metamask/utils';\nimport { assert, isPlainObject } from '@metamask/utils';\nimport { promises as fs } from 'fs';\nimport pathUtils from 'path';\n\nimport type { SnapManifest } from './validation';\nimport type { ValidatorResults } from './validator';\nimport { hasFixes, runValidators } from './validator';\nimport type { ValidatorMeta, ValidatorReport } from './validator-types';\nimport { deepClone } from '../deep-clone';\nimport { readJsonFile } from '../fs';\nimport { parseJson } from '../json';\nimport type { SnapFiles, UnvalidatedSnapFiles } from '../types';\nimport { NpmSnapFileNames } from '../types';\nimport { readVirtualFile, VirtualFile } from '../virtual-file/node';\n\nconst MANIFEST_SORT_ORDER: Record<keyof SnapManifest, number> = {\n $schema: 1,\n version: 2,\n description: 3,\n proposedName: 4,\n repository: 5,\n source: 6,\n initialConnections: 7,\n initialPermissions: 8,\n platformVersion: 9,\n manifestVersion: 10,\n};\n\nexport type CheckManifestReport = Omit<ValidatorReport, 'fix'> & {\n wasFixed?: boolean;\n};\n\n/**\n * The result from the `checkManifest` function.\n *\n * @property manifest - The fixed manifest object.\n * @property updated - Whether the manifest was written and updated.\n */\nexport type CheckManifestResult = {\n files?: SnapFiles;\n updated: boolean;\n reports: CheckManifestReport[];\n};\n\nexport type WriteFileFunction = (path: string, data: string) => Promise<void>;\n\n/**\n * Validates a snap.manifest.json file. Attempts to fix the manifest and write\n * the fixed version to disk if `writeManifest` is true. Throws if validation\n * fails.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param options - Additional options for the function.\n * @param options.sourceCode - The source code of the Snap.\n * @param options.writeFileFn - The function to use to write the manifest to disk.\n * @param options.updateAndWriteManifest - Whether to auto-magically try to fix errors and then write the manifest to disk.\n * @returns Whether the manifest was updated, and an array of warnings that\n * were encountered during processing of the manifest files.\n */\nexport async function checkManifest(\n basePath: string,\n {\n updateAndWriteManifest = true,\n sourceCode,\n writeFileFn = fs.writeFile,\n }: {\n updateAndWriteManifest?: boolean;\n sourceCode?: string;\n writeFileFn?: WriteFileFunction;\n } = {},\n): Promise<CheckManifestResult> {\n const manifestPath = pathUtils.join(basePath, NpmSnapFileNames.Manifest);\n const manifestFile = await readJsonFile(manifestPath);\n const unvalidatedManifest = manifestFile.result;\n\n const packageFile = await readJsonFile(\n pathUtils.join(basePath, NpmSnapFileNames.PackageJson),\n );\n\n const auxiliaryFilePaths = getSnapFilePaths(\n unvalidatedManifest,\n (manifest) => manifest?.source?.files,\n );\n\n const localizationFilePaths = getSnapFilePaths(\n unvalidatedManifest,\n (manifest) => manifest?.source?.locales,\n );\n const localizationFiles =\n (await getSnapFiles(basePath, localizationFilePaths)) ?? [];\n for (const localization of localizationFiles) {\n try {\n localization.result = parseJson(localization.toString());\n } catch (error) {\n assert(error instanceof SyntaxError, error);\n throw new Error(\n `Failed to parse localization file \"${localization.path}\" as JSON.`,\n );\n }\n }\n\n const snapFiles: UnvalidatedSnapFiles = {\n manifest: manifestFile,\n packageJson: packageFile,\n sourceCode: await getSnapSourceCode(\n basePath,\n unvalidatedManifest,\n sourceCode,\n ),\n svgIcon: await getSnapIcon(basePath, unvalidatedManifest),\n // Intentionally pass null as the encoding here since the files may be binary\n auxiliaryFiles:\n (await getSnapFiles(basePath, auxiliaryFilePaths, null)) ?? [],\n localizationFiles,\n };\n\n const validatorResults = await runValidators(snapFiles);\n let manifestResults: CheckManifestResult = {\n updated: false,\n files: validatorResults.files,\n reports: validatorResults.reports,\n };\n\n if (updateAndWriteManifest && hasFixes(manifestResults)) {\n const fixedResults = await runFixes(validatorResults);\n\n if (fixedResults.updated) {\n manifestResults = fixedResults;\n\n assert(manifestResults.files);\n\n try {\n await writeFileFn(\n pathUtils.join(basePath, NpmSnapFileNames.Manifest),\n manifestResults.files.manifest.toString(),\n );\n } catch (error) {\n // Note: This error isn't pushed to the errors array, because it's not an\n // error in the manifest itself.\n throw new Error(\n `Failed to update \"snap.manifest.json\": ${getErrorMessage(error)}`,\n );\n }\n }\n }\n\n return manifestResults;\n}\n\n/**\n * Run the algorithm for automatically fixing errors in manifest.\n *\n * The algorithm updates the manifest by fixing all fixable problems,\n * and then run validation again to check if the new manifest is now correct.\n * If not correct, the algorithm will use the manifest from previous iteration\n * and try again `MAX_ATTEMPTS` times to update it before bailing and\n * resulting in failure.\n *\n * @param results - Results of the initial run of validation.\n * @param rules - Optional list of rules to run the fixes with.\n * @returns The updated manifest and whether it was updated.\n */\nexport async function runFixes(\n results: ValidatorResults,\n rules?: ValidatorMeta[],\n): Promise<CheckManifestResult> {\n let shouldRunFixes = true;\n const MAX_ATTEMPTS = 10;\n\n assert(results.files);\n\n let fixResults: ValidatorResults = results;\n assert(fixResults.files);\n fixResults.files.manifest = fixResults.files.manifest.clone();\n\n for (\n let attempts = 1;\n shouldRunFixes && attempts <= MAX_ATTEMPTS;\n attempts++\n ) {\n assert(fixResults.files);\n\n let manifest = fixResults.files.manifest.result;\n\n const fixable = fixResults.reports.filter((report) => report.fix);\n for (const report of fixable) {\n assert(report.fix);\n ({ manifest } = await report.fix({ manifest }));\n }\n\n fixResults.files.manifest.value = `${JSON.stringify(\n getWritableManifest(manifest),\n null,\n 2,\n )}\\n`;\n fixResults.files.manifest.result = manifest;\n\n fixResults = await runValidators(fixResults.files, rules);\n shouldRunFixes = hasFixes(fixResults);\n }\n\n const initialReports: (CheckManifestReport & ValidatorReport)[] = deepClone(\n results.reports,\n );\n\n // Was fixed\n if (!shouldRunFixes) {\n for (const report of initialReports) {\n if (report.fix) {\n report.wasFixed = true;\n delete report.fix;\n }\n }\n\n return {\n files: fixResults.files,\n updated: true,\n reports: initialReports,\n };\n }\n\n for (const report of initialReports) {\n delete report.fix;\n }\n\n return {\n files: results.files,\n updated: false,\n reports: initialReports,\n };\n}\n\n/**\n * Given an unvalidated Snap manifest, attempts to extract the location of the\n * bundle source file location and read the file.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param manifest - The unvalidated Snap manifest file contents.\n * @param sourceCode - Override source code for plugins.\n * @returns The contents of the bundle file, if any.\n */\nexport async function getSnapSourceCode(\n basePath: string,\n manifest: Json,\n sourceCode?: string,\n): Promise<VirtualFile | undefined> {\n if (!isPlainObject(manifest)) {\n return undefined;\n }\n\n const sourceFilePath = (manifest as Partial<SnapManifest>).source?.location\n ?.npm?.filePath;\n\n if (!sourceFilePath) {\n return undefined;\n }\n\n if (sourceCode) {\n return new VirtualFile({\n path: pathUtils.join(basePath, sourceFilePath),\n value: sourceCode,\n });\n }\n\n try {\n const virtualFile = await readVirtualFile(\n pathUtils.join(basePath, sourceFilePath),\n 'utf8',\n );\n return virtualFile;\n } catch (error) {\n throw new Error(\n `Failed to read snap bundle file: ${getErrorMessage(error)}`,\n );\n }\n}\n\n/**\n * Given an unvalidated Snap manifest, attempts to extract the location of the\n * icon and read the file.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param manifest - The unvalidated Snap manifest file contents.\n * @returns The contents of the icon, if any.\n */\nexport async function getSnapIcon(\n basePath: string,\n manifest: Json,\n): Promise<VirtualFile | undefined> {\n if (!isPlainObject(manifest)) {\n return undefined;\n }\n\n const iconPath = (manifest as Partial<SnapManifest>).source?.location?.npm\n ?.iconPath;\n\n if (!iconPath) {\n return undefined;\n }\n\n try {\n const virtualFile = await readVirtualFile(\n pathUtils.join(basePath, iconPath),\n 'utf8',\n );\n return virtualFile;\n } catch (error) {\n throw new Error(`Failed to read snap icon file: ${getErrorMessage(error)}`);\n }\n}\n\n/**\n * Get an array of paths from an unvalidated Snap manifest.\n *\n * @param manifest - The unvalidated Snap manifest file contents.\n * @param selector - A function that returns the paths to the files.\n * @returns The paths to the files, if any.\n */\nexport function getSnapFilePaths(\n manifest: Json,\n selector: (manifest: Partial<SnapManifest>) => string[] | undefined,\n) {\n if (!isPlainObject(manifest)) {\n return undefined;\n }\n\n const snapManifest = manifest as Partial<SnapManifest>;\n const paths = selector(snapManifest);\n\n if (!Array.isArray(paths)) {\n return undefined;\n }\n\n return paths;\n}\n\n/**\n * Given an unvalidated Snap manifest, attempts to extract the files with the\n * given paths and read them.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param paths - The paths to the files.\n * @param encoding - An optional encoding to pass down to readVirtualFile.\n * @returns A list of auxiliary files and their contents, if any.\n */\nexport async function getSnapFiles(\n basePath: string,\n paths: string[] | undefined,\n encoding: BufferEncoding | null = 'utf8',\n): Promise<VirtualFile[] | undefined> {\n if (!paths) {\n return undefined;\n }\n\n try {\n return await Promise.all(\n paths.map(async (filePath) =>\n readVirtualFile(pathUtils.join(basePath, filePath), encoding),\n ),\n );\n } catch (error) {\n throw new Error(`Failed to read snap files: ${getErrorMessage(error)}`);\n }\n}\n\n/**\n * Sorts the given manifest in our preferred sort order and removes the\n * `repository` field if it is falsy (it may be `null`).\n *\n * @param manifest - The manifest to sort and modify.\n * @returns The disk-ready manifest.\n */\nexport function getWritableManifest(manifest: SnapManifest): SnapManifest {\n const { repository, ...remaining } = manifest;\n\n const keys = Object.keys(\n repository ? { ...remaining, repository } : remaining,\n ) as (keyof SnapManifest)[];\n\n const writableManifest = keys\n .sort((a, b) => MANIFEST_SORT_ORDER[a] - MANIFEST_SORT_ORDER[b])\n .reduce<Partial<SnapManifest>>(\n (result, key) => ({\n ...result,\n [key]: manifest[key],\n }),\n {},\n );\n\n return writableManifest as SnapManifest;\n}\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { Json } from "@metamask/utils";
|
|
3
|
-
import type { SnapFiles } from "../types.cjs";
|
|
4
|
-
import { VirtualFile } from "../virtual-file/node.cjs";
|
|
5
3
|
import type { SnapManifest } from "./validation.cjs";
|
|
6
4
|
import type { ValidatorResults } from "./validator.cjs";
|
|
7
5
|
import type { ValidatorMeta, ValidatorReport } from "./validator-types.cjs";
|
|
6
|
+
import type { SnapFiles } from "../types.cjs";
|
|
7
|
+
import { VirtualFile } from "../virtual-file/node.cjs";
|
|
8
8
|
export type CheckManifestReport = Omit<ValidatorReport, 'fix'> & {
|
|
9
9
|
wasFixed?: boolean;
|
|
10
10
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.cts","sourceRoot":"","sources":["../../src/manifest/manifest.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"manifest.d.cts","sourceRoot":"","sources":["../../src/manifest/manifest.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAK5C,OAAO,KAAK,EAAE,YAAY,EAAE,yBAAqB;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,wBAAoB;AAEpD,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,8BAA0B;AAIxE,OAAO,KAAK,EAAE,SAAS,EAAwB,qBAAiB;AAEhE,OAAO,EAAmB,WAAW,EAAE,iCAA6B;AAepE,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,GAAG;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9E;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,EACE,sBAA6B,EAC7B,UAAU,EACV,WAA0B,GAC3B,GAAE;IACD,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,iBAAiB,CAAC;CAC5B,GACL,OAAO,CAAC,mBAAmB,CAAC,CA6E9B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,gBAAgB,EACzB,KAAK,CAAC,EAAE,aAAa,EAAE,GACtB,OAAO,CAAC,mBAAmB,CAAC,CAiE9B;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,IAAI,EACd,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CA8BlC;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,IAAI,GACb,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAqBlC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,IAAI,EACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,MAAM,EAAE,GAAG,SAAS,wBAcpE;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,EAC3B,QAAQ,GAAE,cAAc,GAAG,IAAa,GACvC,OAAO,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC,CAcpC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,GAAG,YAAY,CAkBxE"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { Json } from "@metamask/utils";
|
|
3
|
-
import type { SnapFiles } from "../types.mjs";
|
|
4
|
-
import { VirtualFile } from "../virtual-file/node.mjs";
|
|
5
3
|
import type { SnapManifest } from "./validation.mjs";
|
|
6
4
|
import type { ValidatorResults } from "./validator.mjs";
|
|
7
5
|
import type { ValidatorMeta, ValidatorReport } from "./validator-types.mjs";
|
|
6
|
+
import type { SnapFiles } from "../types.mjs";
|
|
7
|
+
import { VirtualFile } from "../virtual-file/node.mjs";
|
|
8
8
|
export type CheckManifestReport = Omit<ValidatorReport, 'fix'> & {
|
|
9
9
|
wasFixed?: boolean;
|
|
10
10
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.mts","sourceRoot":"","sources":["../../src/manifest/manifest.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"manifest.d.mts","sourceRoot":"","sources":["../../src/manifest/manifest.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAK5C,OAAO,KAAK,EAAE,YAAY,EAAE,yBAAqB;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,wBAAoB;AAEpD,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,8BAA0B;AAIxE,OAAO,KAAK,EAAE,SAAS,EAAwB,qBAAiB;AAEhE,OAAO,EAAmB,WAAW,EAAE,iCAA6B;AAepE,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,GAAG;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9E;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,EACE,sBAA6B,EAC7B,UAAU,EACV,WAA0B,GAC3B,GAAE;IACD,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,iBAAiB,CAAC;CAC5B,GACL,OAAO,CAAC,mBAAmB,CAAC,CA6E9B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,gBAAgB,EACzB,KAAK,CAAC,EAAE,aAAa,EAAE,GACtB,OAAO,CAAC,mBAAmB,CAAC,CAiE9B;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,IAAI,EACd,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CA8BlC;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,IAAI,GACb,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAqBlC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,IAAI,EACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,MAAM,EAAE,GAAG,SAAS,wBAcpE;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,EAC3B,QAAQ,GAAE,cAAc,GAAG,IAAa,GACvC,OAAO,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC,CAcpC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,GAAG,YAAY,CAkBxE"}
|
|
@@ -2,12 +2,12 @@ import { getErrorMessage } from "@metamask/snaps-sdk";
|
|
|
2
2
|
import { assert, isPlainObject } from "@metamask/utils";
|
|
3
3
|
import { promises as fs } from "fs";
|
|
4
4
|
import pathUtils from "path";
|
|
5
|
+
import { hasFixes, runValidators } from "./validator.mjs";
|
|
5
6
|
import { deepClone } from "../deep-clone.mjs";
|
|
6
7
|
import { readJsonFile } from "../fs.mjs";
|
|
7
8
|
import { parseJson } from "../json.mjs";
|
|
8
9
|
import { NpmSnapFileNames } from "../types.mjs";
|
|
9
10
|
import { readVirtualFile, VirtualFile } from "../virtual-file/node.mjs";
|
|
10
|
-
import { hasFixes, runValidators } from "./validator.mjs";
|
|
11
11
|
const MANIFEST_SORT_ORDER = {
|
|
12
12
|
$schema: 1,
|
|
13
13
|
version: 2,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.mjs","sourceRoot":"","sources":["../../src/manifest/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import { getErrorMessage } from '@metamask/snaps-sdk';\nimport type { Json } from '@metamask/utils';\nimport { assert, isPlainObject } from '@metamask/utils';\nimport { promises as fs } from 'fs';\nimport pathUtils from 'path';\n\nimport { deepClone } from '../deep-clone';\nimport { readJsonFile } from '../fs';\nimport { parseJson } from '../json';\nimport type { SnapFiles, UnvalidatedSnapFiles } from '../types';\nimport { NpmSnapFileNames } from '../types';\nimport { readVirtualFile, VirtualFile } from '../virtual-file/node';\nimport type { SnapManifest } from './validation';\nimport type { ValidatorResults } from './validator';\nimport { hasFixes, runValidators } from './validator';\nimport type { ValidatorMeta, ValidatorReport } from './validator-types';\n\nconst MANIFEST_SORT_ORDER: Record<keyof SnapManifest, number> = {\n $schema: 1,\n version: 2,\n description: 3,\n proposedName: 4,\n repository: 5,\n source: 6,\n initialConnections: 7,\n initialPermissions: 8,\n platformVersion: 9,\n manifestVersion: 10,\n};\n\nexport type CheckManifestReport = Omit<ValidatorReport, 'fix'> & {\n wasFixed?: boolean;\n};\n\n/**\n * The result from the `checkManifest` function.\n *\n * @property manifest - The fixed manifest object.\n * @property updated - Whether the manifest was written and updated.\n */\nexport type CheckManifestResult = {\n files?: SnapFiles;\n updated: boolean;\n reports: CheckManifestReport[];\n};\n\nexport type WriteFileFunction = (path: string, data: string) => Promise<void>;\n\n/**\n * Validates a snap.manifest.json file. Attempts to fix the manifest and write\n * the fixed version to disk if `writeManifest` is true. Throws if validation\n * fails.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param options - Additional options for the function.\n * @param options.sourceCode - The source code of the Snap.\n * @param options.writeFileFn - The function to use to write the manifest to disk.\n * @param options.updateAndWriteManifest - Whether to auto-magically try to fix errors and then write the manifest to disk.\n * @returns Whether the manifest was updated, and an array of warnings that\n * were encountered during processing of the manifest files.\n */\nexport async function checkManifest(\n basePath: string,\n {\n updateAndWriteManifest = true,\n sourceCode,\n writeFileFn = fs.writeFile,\n }: {\n updateAndWriteManifest?: boolean;\n sourceCode?: string;\n writeFileFn?: WriteFileFunction;\n } = {},\n): Promise<CheckManifestResult> {\n const manifestPath = pathUtils.join(basePath, NpmSnapFileNames.Manifest);\n const manifestFile = await readJsonFile(manifestPath);\n const unvalidatedManifest = manifestFile.result;\n\n const packageFile = await readJsonFile(\n pathUtils.join(basePath, NpmSnapFileNames.PackageJson),\n );\n\n const auxiliaryFilePaths = getSnapFilePaths(\n unvalidatedManifest,\n (manifest) => manifest?.source?.files,\n );\n\n const localizationFilePaths = getSnapFilePaths(\n unvalidatedManifest,\n (manifest) => manifest?.source?.locales,\n );\n const localizationFiles =\n (await getSnapFiles(basePath, localizationFilePaths)) ?? [];\n for (const localization of localizationFiles) {\n try {\n localization.result = parseJson(localization.toString());\n } catch (error) {\n assert(error instanceof SyntaxError, error);\n throw new Error(\n `Failed to parse localization file \"${localization.path}\" as JSON.`,\n );\n }\n }\n\n const snapFiles: UnvalidatedSnapFiles = {\n manifest: manifestFile,\n packageJson: packageFile,\n sourceCode: await getSnapSourceCode(\n basePath,\n unvalidatedManifest,\n sourceCode,\n ),\n svgIcon: await getSnapIcon(basePath, unvalidatedManifest),\n // Intentionally pass null as the encoding here since the files may be binary\n auxiliaryFiles:\n (await getSnapFiles(basePath, auxiliaryFilePaths, null)) ?? [],\n localizationFiles,\n };\n\n const validatorResults = await runValidators(snapFiles);\n let manifestResults: CheckManifestResult = {\n updated: false,\n files: validatorResults.files,\n reports: validatorResults.reports,\n };\n\n if (updateAndWriteManifest && hasFixes(manifestResults)) {\n const fixedResults = await runFixes(validatorResults);\n\n if (fixedResults.updated) {\n manifestResults = fixedResults;\n\n assert(manifestResults.files);\n\n try {\n await writeFileFn(\n pathUtils.join(basePath, NpmSnapFileNames.Manifest),\n manifestResults.files.manifest.toString(),\n );\n } catch (error) {\n // Note: This error isn't pushed to the errors array, because it's not an\n // error in the manifest itself.\n throw new Error(\n `Failed to update \"snap.manifest.json\": ${getErrorMessage(error)}`,\n );\n }\n }\n }\n\n return manifestResults;\n}\n\n/**\n * Run the algorithm for automatically fixing errors in manifest.\n *\n * The algorithm updates the manifest by fixing all fixable problems,\n * and then run validation again to check if the new manifest is now correct.\n * If not correct, the algorithm will use the manifest from previous iteration\n * and try again `MAX_ATTEMPTS` times to update it before bailing and\n * resulting in failure.\n *\n * @param results - Results of the initial run of validation.\n * @param rules - Optional list of rules to run the fixes with.\n * @returns The updated manifest and whether it was updated.\n */\nexport async function runFixes(\n results: ValidatorResults,\n rules?: ValidatorMeta[],\n): Promise<CheckManifestResult> {\n let shouldRunFixes = true;\n const MAX_ATTEMPTS = 10;\n\n assert(results.files);\n\n let fixResults: ValidatorResults = results;\n assert(fixResults.files);\n fixResults.files.manifest = fixResults.files.manifest.clone();\n\n for (\n let attempts = 1;\n shouldRunFixes && attempts <= MAX_ATTEMPTS;\n attempts++\n ) {\n assert(fixResults.files);\n\n let manifest = fixResults.files.manifest.result;\n\n const fixable = fixResults.reports.filter((report) => report.fix);\n for (const report of fixable) {\n assert(report.fix);\n ({ manifest } = await report.fix({ manifest }));\n }\n\n fixResults.files.manifest.value = `${JSON.stringify(\n getWritableManifest(manifest),\n null,\n 2,\n )}\\n`;\n fixResults.files.manifest.result = manifest;\n\n fixResults = await runValidators(fixResults.files, rules);\n shouldRunFixes = hasFixes(fixResults);\n }\n\n const initialReports: (CheckManifestReport & ValidatorReport)[] = deepClone(\n results.reports,\n );\n\n // Was fixed\n if (!shouldRunFixes) {\n for (const report of initialReports) {\n if (report.fix) {\n report.wasFixed = true;\n delete report.fix;\n }\n }\n\n return {\n files: fixResults.files,\n updated: true,\n reports: initialReports,\n };\n }\n\n for (const report of initialReports) {\n delete report.fix;\n }\n\n return {\n files: results.files,\n updated: false,\n reports: initialReports,\n };\n}\n\n/**\n * Given an unvalidated Snap manifest, attempts to extract the location of the\n * bundle source file location and read the file.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param manifest - The unvalidated Snap manifest file contents.\n * @param sourceCode - Override source code for plugins.\n * @returns The contents of the bundle file, if any.\n */\nexport async function getSnapSourceCode(\n basePath: string,\n manifest: Json,\n sourceCode?: string,\n): Promise<VirtualFile | undefined> {\n if (!isPlainObject(manifest)) {\n return undefined;\n }\n\n const sourceFilePath = (manifest as Partial<SnapManifest>).source?.location\n ?.npm?.filePath;\n\n if (!sourceFilePath) {\n return undefined;\n }\n\n if (sourceCode) {\n return new VirtualFile({\n path: pathUtils.join(basePath, sourceFilePath),\n value: sourceCode,\n });\n }\n\n try {\n const virtualFile = await readVirtualFile(\n pathUtils.join(basePath, sourceFilePath),\n 'utf8',\n );\n return virtualFile;\n } catch (error) {\n throw new Error(\n `Failed to read snap bundle file: ${getErrorMessage(error)}`,\n );\n }\n}\n\n/**\n * Given an unvalidated Snap manifest, attempts to extract the location of the\n * icon and read the file.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param manifest - The unvalidated Snap manifest file contents.\n * @returns The contents of the icon, if any.\n */\nexport async function getSnapIcon(\n basePath: string,\n manifest: Json,\n): Promise<VirtualFile | undefined> {\n if (!isPlainObject(manifest)) {\n return undefined;\n }\n\n const iconPath = (manifest as Partial<SnapManifest>).source?.location?.npm\n ?.iconPath;\n\n if (!iconPath) {\n return undefined;\n }\n\n try {\n const virtualFile = await readVirtualFile(\n pathUtils.join(basePath, iconPath),\n 'utf8',\n );\n return virtualFile;\n } catch (error) {\n throw new Error(`Failed to read snap icon file: ${getErrorMessage(error)}`);\n }\n}\n\n/**\n * Get an array of paths from an unvalidated Snap manifest.\n *\n * @param manifest - The unvalidated Snap manifest file contents.\n * @param selector - A function that returns the paths to the files.\n * @returns The paths to the files, if any.\n */\nexport function getSnapFilePaths(\n manifest: Json,\n selector: (manifest: Partial<SnapManifest>) => string[] | undefined,\n) {\n if (!isPlainObject(manifest)) {\n return undefined;\n }\n\n const snapManifest = manifest as Partial<SnapManifest>;\n const paths = selector(snapManifest);\n\n if (!Array.isArray(paths)) {\n return undefined;\n }\n\n return paths;\n}\n\n/**\n * Given an unvalidated Snap manifest, attempts to extract the files with the\n * given paths and read them.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param paths - The paths to the files.\n * @param encoding - An optional encoding to pass down to readVirtualFile.\n * @returns A list of auxiliary files and their contents, if any.\n */\nexport async function getSnapFiles(\n basePath: string,\n paths: string[] | undefined,\n encoding: BufferEncoding | null = 'utf8',\n): Promise<VirtualFile[] | undefined> {\n if (!paths) {\n return undefined;\n }\n\n try {\n return await Promise.all(\n paths.map(async (filePath) =>\n readVirtualFile(pathUtils.join(basePath, filePath), encoding),\n ),\n );\n } catch (error) {\n throw new Error(`Failed to read snap files: ${getErrorMessage(error)}`);\n }\n}\n\n/**\n * Sorts the given manifest in our preferred sort order and removes the\n * `repository` field if it is falsy (it may be `null`).\n *\n * @param manifest - The manifest to sort and modify.\n * @returns The disk-ready manifest.\n */\nexport function getWritableManifest(manifest: SnapManifest): SnapManifest {\n const { repository, ...remaining } = manifest;\n\n const keys = Object.keys(\n repository ? { ...remaining, repository } : remaining,\n ) as (keyof SnapManifest)[];\n\n const writableManifest = keys\n .sort((a, b) => MANIFEST_SORT_ORDER[a] - MANIFEST_SORT_ORDER[b])\n .reduce<Partial<SnapManifest>>(\n (result, key) => ({\n ...result,\n [key]: manifest[key],\n }),\n {},\n );\n\n return writableManifest as SnapManifest;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"manifest.mjs","sourceRoot":"","sources":["../../src/manifest/manifest.ts"],"names":[],"mappings":"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","sourcesContent":["import { getErrorMessage } from '@metamask/snaps-sdk';\nimport type { Json } from '@metamask/utils';\nimport { assert, isPlainObject } from '@metamask/utils';\nimport { promises as fs } from 'fs';\nimport pathUtils from 'path';\n\nimport type { SnapManifest } from './validation';\nimport type { ValidatorResults } from './validator';\nimport { hasFixes, runValidators } from './validator';\nimport type { ValidatorMeta, ValidatorReport } from './validator-types';\nimport { deepClone } from '../deep-clone';\nimport { readJsonFile } from '../fs';\nimport { parseJson } from '../json';\nimport type { SnapFiles, UnvalidatedSnapFiles } from '../types';\nimport { NpmSnapFileNames } from '../types';\nimport { readVirtualFile, VirtualFile } from '../virtual-file/node';\n\nconst MANIFEST_SORT_ORDER: Record<keyof SnapManifest, number> = {\n $schema: 1,\n version: 2,\n description: 3,\n proposedName: 4,\n repository: 5,\n source: 6,\n initialConnections: 7,\n initialPermissions: 8,\n platformVersion: 9,\n manifestVersion: 10,\n};\n\nexport type CheckManifestReport = Omit<ValidatorReport, 'fix'> & {\n wasFixed?: boolean;\n};\n\n/**\n * The result from the `checkManifest` function.\n *\n * @property manifest - The fixed manifest object.\n * @property updated - Whether the manifest was written and updated.\n */\nexport type CheckManifestResult = {\n files?: SnapFiles;\n updated: boolean;\n reports: CheckManifestReport[];\n};\n\nexport type WriteFileFunction = (path: string, data: string) => Promise<void>;\n\n/**\n * Validates a snap.manifest.json file. Attempts to fix the manifest and write\n * the fixed version to disk if `writeManifest` is true. Throws if validation\n * fails.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param options - Additional options for the function.\n * @param options.sourceCode - The source code of the Snap.\n * @param options.writeFileFn - The function to use to write the manifest to disk.\n * @param options.updateAndWriteManifest - Whether to auto-magically try to fix errors and then write the manifest to disk.\n * @returns Whether the manifest was updated, and an array of warnings that\n * were encountered during processing of the manifest files.\n */\nexport async function checkManifest(\n basePath: string,\n {\n updateAndWriteManifest = true,\n sourceCode,\n writeFileFn = fs.writeFile,\n }: {\n updateAndWriteManifest?: boolean;\n sourceCode?: string;\n writeFileFn?: WriteFileFunction;\n } = {},\n): Promise<CheckManifestResult> {\n const manifestPath = pathUtils.join(basePath, NpmSnapFileNames.Manifest);\n const manifestFile = await readJsonFile(manifestPath);\n const unvalidatedManifest = manifestFile.result;\n\n const packageFile = await readJsonFile(\n pathUtils.join(basePath, NpmSnapFileNames.PackageJson),\n );\n\n const auxiliaryFilePaths = getSnapFilePaths(\n unvalidatedManifest,\n (manifest) => manifest?.source?.files,\n );\n\n const localizationFilePaths = getSnapFilePaths(\n unvalidatedManifest,\n (manifest) => manifest?.source?.locales,\n );\n const localizationFiles =\n (await getSnapFiles(basePath, localizationFilePaths)) ?? [];\n for (const localization of localizationFiles) {\n try {\n localization.result = parseJson(localization.toString());\n } catch (error) {\n assert(error instanceof SyntaxError, error);\n throw new Error(\n `Failed to parse localization file \"${localization.path}\" as JSON.`,\n );\n }\n }\n\n const snapFiles: UnvalidatedSnapFiles = {\n manifest: manifestFile,\n packageJson: packageFile,\n sourceCode: await getSnapSourceCode(\n basePath,\n unvalidatedManifest,\n sourceCode,\n ),\n svgIcon: await getSnapIcon(basePath, unvalidatedManifest),\n // Intentionally pass null as the encoding here since the files may be binary\n auxiliaryFiles:\n (await getSnapFiles(basePath, auxiliaryFilePaths, null)) ?? [],\n localizationFiles,\n };\n\n const validatorResults = await runValidators(snapFiles);\n let manifestResults: CheckManifestResult = {\n updated: false,\n files: validatorResults.files,\n reports: validatorResults.reports,\n };\n\n if (updateAndWriteManifest && hasFixes(manifestResults)) {\n const fixedResults = await runFixes(validatorResults);\n\n if (fixedResults.updated) {\n manifestResults = fixedResults;\n\n assert(manifestResults.files);\n\n try {\n await writeFileFn(\n pathUtils.join(basePath, NpmSnapFileNames.Manifest),\n manifestResults.files.manifest.toString(),\n );\n } catch (error) {\n // Note: This error isn't pushed to the errors array, because it's not an\n // error in the manifest itself.\n throw new Error(\n `Failed to update \"snap.manifest.json\": ${getErrorMessage(error)}`,\n );\n }\n }\n }\n\n return manifestResults;\n}\n\n/**\n * Run the algorithm for automatically fixing errors in manifest.\n *\n * The algorithm updates the manifest by fixing all fixable problems,\n * and then run validation again to check if the new manifest is now correct.\n * If not correct, the algorithm will use the manifest from previous iteration\n * and try again `MAX_ATTEMPTS` times to update it before bailing and\n * resulting in failure.\n *\n * @param results - Results of the initial run of validation.\n * @param rules - Optional list of rules to run the fixes with.\n * @returns The updated manifest and whether it was updated.\n */\nexport async function runFixes(\n results: ValidatorResults,\n rules?: ValidatorMeta[],\n): Promise<CheckManifestResult> {\n let shouldRunFixes = true;\n const MAX_ATTEMPTS = 10;\n\n assert(results.files);\n\n let fixResults: ValidatorResults = results;\n assert(fixResults.files);\n fixResults.files.manifest = fixResults.files.manifest.clone();\n\n for (\n let attempts = 1;\n shouldRunFixes && attempts <= MAX_ATTEMPTS;\n attempts++\n ) {\n assert(fixResults.files);\n\n let manifest = fixResults.files.manifest.result;\n\n const fixable = fixResults.reports.filter((report) => report.fix);\n for (const report of fixable) {\n assert(report.fix);\n ({ manifest } = await report.fix({ manifest }));\n }\n\n fixResults.files.manifest.value = `${JSON.stringify(\n getWritableManifest(manifest),\n null,\n 2,\n )}\\n`;\n fixResults.files.manifest.result = manifest;\n\n fixResults = await runValidators(fixResults.files, rules);\n shouldRunFixes = hasFixes(fixResults);\n }\n\n const initialReports: (CheckManifestReport & ValidatorReport)[] = deepClone(\n results.reports,\n );\n\n // Was fixed\n if (!shouldRunFixes) {\n for (const report of initialReports) {\n if (report.fix) {\n report.wasFixed = true;\n delete report.fix;\n }\n }\n\n return {\n files: fixResults.files,\n updated: true,\n reports: initialReports,\n };\n }\n\n for (const report of initialReports) {\n delete report.fix;\n }\n\n return {\n files: results.files,\n updated: false,\n reports: initialReports,\n };\n}\n\n/**\n * Given an unvalidated Snap manifest, attempts to extract the location of the\n * bundle source file location and read the file.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param manifest - The unvalidated Snap manifest file contents.\n * @param sourceCode - Override source code for plugins.\n * @returns The contents of the bundle file, if any.\n */\nexport async function getSnapSourceCode(\n basePath: string,\n manifest: Json,\n sourceCode?: string,\n): Promise<VirtualFile | undefined> {\n if (!isPlainObject(manifest)) {\n return undefined;\n }\n\n const sourceFilePath = (manifest as Partial<SnapManifest>).source?.location\n ?.npm?.filePath;\n\n if (!sourceFilePath) {\n return undefined;\n }\n\n if (sourceCode) {\n return new VirtualFile({\n path: pathUtils.join(basePath, sourceFilePath),\n value: sourceCode,\n });\n }\n\n try {\n const virtualFile = await readVirtualFile(\n pathUtils.join(basePath, sourceFilePath),\n 'utf8',\n );\n return virtualFile;\n } catch (error) {\n throw new Error(\n `Failed to read snap bundle file: ${getErrorMessage(error)}`,\n );\n }\n}\n\n/**\n * Given an unvalidated Snap manifest, attempts to extract the location of the\n * icon and read the file.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param manifest - The unvalidated Snap manifest file contents.\n * @returns The contents of the icon, if any.\n */\nexport async function getSnapIcon(\n basePath: string,\n manifest: Json,\n): Promise<VirtualFile | undefined> {\n if (!isPlainObject(manifest)) {\n return undefined;\n }\n\n const iconPath = (manifest as Partial<SnapManifest>).source?.location?.npm\n ?.iconPath;\n\n if (!iconPath) {\n return undefined;\n }\n\n try {\n const virtualFile = await readVirtualFile(\n pathUtils.join(basePath, iconPath),\n 'utf8',\n );\n return virtualFile;\n } catch (error) {\n throw new Error(`Failed to read snap icon file: ${getErrorMessage(error)}`);\n }\n}\n\n/**\n * Get an array of paths from an unvalidated Snap manifest.\n *\n * @param manifest - The unvalidated Snap manifest file contents.\n * @param selector - A function that returns the paths to the files.\n * @returns The paths to the files, if any.\n */\nexport function getSnapFilePaths(\n manifest: Json,\n selector: (manifest: Partial<SnapManifest>) => string[] | undefined,\n) {\n if (!isPlainObject(manifest)) {\n return undefined;\n }\n\n const snapManifest = manifest as Partial<SnapManifest>;\n const paths = selector(snapManifest);\n\n if (!Array.isArray(paths)) {\n return undefined;\n }\n\n return paths;\n}\n\n/**\n * Given an unvalidated Snap manifest, attempts to extract the files with the\n * given paths and read them.\n *\n * @param basePath - The path to the folder with the manifest files.\n * @param paths - The paths to the files.\n * @param encoding - An optional encoding to pass down to readVirtualFile.\n * @returns A list of auxiliary files and their contents, if any.\n */\nexport async function getSnapFiles(\n basePath: string,\n paths: string[] | undefined,\n encoding: BufferEncoding | null = 'utf8',\n): Promise<VirtualFile[] | undefined> {\n if (!paths) {\n return undefined;\n }\n\n try {\n return await Promise.all(\n paths.map(async (filePath) =>\n readVirtualFile(pathUtils.join(basePath, filePath), encoding),\n ),\n );\n } catch (error) {\n throw new Error(`Failed to read snap files: ${getErrorMessage(error)}`);\n }\n}\n\n/**\n * Sorts the given manifest in our preferred sort order and removes the\n * `repository` field if it is falsy (it may be `null`).\n *\n * @param manifest - The manifest to sort and modify.\n * @returns The disk-ready manifest.\n */\nexport function getWritableManifest(manifest: SnapManifest): SnapManifest {\n const { repository, ...remaining } = manifest;\n\n const keys = Object.keys(\n repository ? { ...remaining, repository } : remaining,\n ) as (keyof SnapManifest)[];\n\n const writableManifest = keys\n .sort((a, b) => MANIFEST_SORT_ORDER[a] - MANIFEST_SORT_ORDER[b])\n .reduce<Partial<SnapManifest>>(\n (result, key) => ({\n ...result,\n [key]: manifest[key],\n }),\n {},\n );\n\n return writableManifest as SnapManifest;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator-types.cjs","sourceRoot":"","sources":["../../src/manifest/validator-types.ts"],"names":[],"mappings":"","sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"validator-types.cjs","sourceRoot":"","sources":["../../src/manifest/validator-types.ts"],"names":[],"mappings":"","sourcesContent":["import type { SnapManifest } from './validation';\nimport type { Promisable } from '../promise';\nimport type { SnapFiles, UnvalidatedSnapFiles } from '../types';\n\n// Eslint uses patch based fixing, but it's too complex for our needs.\n// https://eslint.org/docs/latest/extend/custom-rules#applying-fixes\nexport type ValidatorFix = (files: {\n manifest: SnapManifest;\n}) => Promisable<{ manifest: SnapManifest }>;\n\nexport type ValidatorSeverity = 'error' | 'warning';\n\nexport type ValidatorContext = {\n report: (message: string, fix?: ValidatorFix) => void;\n};\n\nexport type ValidatorReport = {\n severity: ValidatorSeverity;\n message: string;\n fix?: ValidatorFix;\n};\n\nexport type ValidatorMeta = {\n severity: ValidatorSeverity;\n\n /**\n * 1. Run the validator on unverified files to ensure that the files are structurally sound.\n *\n * @param files - Files to be verified\n * @param context - Validator context to report errors\n */\n structureCheck?: (\n files: UnvalidatedSnapFiles,\n context: ValidatorContext,\n ) => void | Promise<void>;\n\n /**\n * 2. Run the validator after the files were checked to be structurally sound.\n *\n * @param files - Files to be verified\n * @param context - Validator context to report errors\n */\n semanticCheck?: (\n files: SnapFiles,\n context: ValidatorContext,\n ) => void | Promise<void>;\n};\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { SnapManifest } from "./validation.cjs";
|
|
1
2
|
import type { Promisable } from "../promise.cjs";
|
|
2
3
|
import type { SnapFiles, UnvalidatedSnapFiles } from "../types.cjs";
|
|
3
|
-
import type { SnapManifest } from "./validation.cjs";
|
|
4
4
|
export type ValidatorFix = (files: {
|
|
5
5
|
manifest: SnapManifest;
|
|
6
6
|
}) => Promisable<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator-types.d.cts","sourceRoot":"","sources":["../../src/manifest/validator-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"validator-types.d.cts","sourceRoot":"","sources":["../../src/manifest/validator-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,yBAAqB;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,uBAAmB;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAiB;AAIhE,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE;IACjC,QAAQ,EAAE,YAAY,CAAC;CACxB,KAAK,UAAU,CAAC;IAAE,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC;AAE7C,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,SAAS,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,iBAAiB,CAAC;IAE5B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CACf,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,gBAAgB,KACtB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CACd,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,gBAAgB,KACtB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { SnapManifest } from "./validation.mjs";
|
|
1
2
|
import type { Promisable } from "../promise.mjs";
|
|
2
3
|
import type { SnapFiles, UnvalidatedSnapFiles } from "../types.mjs";
|
|
3
|
-
import type { SnapManifest } from "./validation.mjs";
|
|
4
4
|
export type ValidatorFix = (files: {
|
|
5
5
|
manifest: SnapManifest;
|
|
6
6
|
}) => Promisable<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator-types.d.mts","sourceRoot":"","sources":["../../src/manifest/validator-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"validator-types.d.mts","sourceRoot":"","sources":["../../src/manifest/validator-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,yBAAqB;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,uBAAmB;AAC7C,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAiB;AAIhE,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE;IACjC,QAAQ,EAAE,YAAY,CAAC;CACxB,KAAK,UAAU,CAAC;IAAE,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAC,CAAC;AAE7C,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,SAAS,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;CACvD,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,iBAAiB,CAAC;IAE5B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CACf,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,gBAAgB,KACtB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CACd,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,gBAAgB,KACtB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator-types.mjs","sourceRoot":"","sources":["../../src/manifest/validator-types.ts"],"names":[],"mappings":"","sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"validator-types.mjs","sourceRoot":"","sources":["../../src/manifest/validator-types.ts"],"names":[],"mappings":"","sourcesContent":["import type { SnapManifest } from './validation';\nimport type { Promisable } from '../promise';\nimport type { SnapFiles, UnvalidatedSnapFiles } from '../types';\n\n// Eslint uses patch based fixing, but it's too complex for our needs.\n// https://eslint.org/docs/latest/extend/custom-rules#applying-fixes\nexport type ValidatorFix = (files: {\n manifest: SnapManifest;\n}) => Promisable<{ manifest: SnapManifest }>;\n\nexport type ValidatorSeverity = 'error' | 'warning';\n\nexport type ValidatorContext = {\n report: (message: string, fix?: ValidatorFix) => void;\n};\n\nexport type ValidatorReport = {\n severity: ValidatorSeverity;\n message: string;\n fix?: ValidatorFix;\n};\n\nexport type ValidatorMeta = {\n severity: ValidatorSeverity;\n\n /**\n * 1. Run the validator on unverified files to ensure that the files are structurally sound.\n *\n * @param files - Files to be verified\n * @param context - Validator context to report errors\n */\n structureCheck?: (\n files: UnvalidatedSnapFiles,\n context: ValidatorContext,\n ) => void | Promise<void>;\n\n /**\n * 2. Run the validator after the files were checked to be structurally sound.\n *\n * @param files - Files to be verified\n * @param context - Validator context to report errors\n */\n semanticCheck?: (\n files: SnapFiles,\n context: ValidatorContext,\n ) => void | Promise<void>;\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.cjs","sourceRoot":"","sources":["../../src/manifest/validator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAyC;
|
|
1
|
+
{"version":3,"file":"validator.cjs","sourceRoot":"","sources":["../../src/manifest/validator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAyC;AASzC,0EAAkD;AAQlD,MAAM,OAAO;IAAb;QACE,YAAO,GAAsB,EAAE,CAAC;QAEhC,gCAAoC,SAAS,EAAC;IAkBhD,CAAC;IAhBC,MAAM,CAAC,OAAe,EAAE,GAAkB;QACxC,IAAA,cAAM,EAAC,uBAAA,IAAI,6BAAc,KAAK,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,QAAQ,EAAE,uBAAA,IAAI,6BAAc;YAC5B,OAAO;YACP,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;IAED,mBAAmB,CAAC,QAAyC;QAC3D,uBAAA,IAAI,yBAAiB,QAAQ,CAAC,QAAQ,MAAA,CAAC;IACzC,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IACpE,CAAC;CACF;;AAED;;;;;;;;GAQG;AACH,iEAAiE;AACjE,8DAA8D;AAC9D,+BAA+B;AACxB,KAAK,UAAU,aAAa,CACjC,KAA2B,EAC3B,QAAyB,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAEzD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,mBAAmB,CAAC;YAC1B,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,mBAAmB,CAAC;YAC1B,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,KAAkB,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO;QACL,KAAK,EAAE,KAAkB;QACzB,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;AACJ,CAAC;AA5BD,sCA4BC;AAED;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,OAAyB;IAChD,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACtD,CAAC;AAFD,4BAEC","sourcesContent":["import { assert } from '@metamask/utils';\n\nimport type {\n ValidatorContext,\n ValidatorFix,\n ValidatorMeta,\n ValidatorReport,\n ValidatorSeverity,\n} from './validator-types';\nimport * as defaultValidators from './validators';\nimport type { SnapFiles, UnvalidatedSnapFiles } from '../types';\n\nexport type ValidatorResults = {\n files?: SnapFiles;\n reports: ValidatorReport[];\n};\n\nclass Context implements ValidatorContext {\n reports: ValidatorReport[] = [];\n\n #nextSeverity?: ValidatorSeverity = undefined;\n\n report(message: string, fix?: ValidatorFix): void {\n assert(this.#nextSeverity !== undefined);\n this.reports.push({\n severity: this.#nextSeverity,\n message,\n fix,\n });\n }\n\n prepareForValidator(settings: { severity: ValidatorSeverity }) {\n this.#nextSeverity = settings.severity;\n }\n\n get hasErrors() {\n return this.reports.some((report) => report.severity === 'error');\n }\n}\n\n/**\n * Verify that snap files are completely valid.\n * First it runs validators on unparsed files to check structure.\n * Secondly it runs validators on parsed files to check semantics.\n *\n * @param files - All files required to run a snap.\n * @param rules - Validators to run.\n * @returns The validation results.\n */\n// TODO(ritave): snap.manifest.json and package.json should check\n// json parsing as well instead of assuming it's\n// already parsed\nexport async function runValidators(\n files: UnvalidatedSnapFiles,\n rules: ValidatorMeta[] = Object.values(defaultValidators),\n): Promise<ValidatorResults> {\n const context = new Context();\n\n for (const rule of rules) {\n context.prepareForValidator({\n severity: rule.severity,\n });\n await rule.structureCheck?.(files, context);\n }\n if (context.hasErrors) {\n return {\n reports: context.reports,\n };\n }\n\n for (const rule of rules) {\n context.prepareForValidator({\n severity: rule.severity,\n });\n await rule.semanticCheck?.(files as SnapFiles, context);\n }\n return {\n files: files as SnapFiles,\n reports: context.reports,\n };\n}\n\n/**\n * Get whether any reports has pending fixes.\n *\n * @param results - Results of the validation run.\n * @returns Whether there are fixes pending.\n */\nexport function hasFixes(results: ValidatorResults): boolean {\n return results.reports.some((report) => report.fix);\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { SnapFiles, UnvalidatedSnapFiles } from "../types.cjs";
|
|
2
1
|
import type { ValidatorMeta, ValidatorReport } from "./validator-types.cjs";
|
|
2
|
+
import type { SnapFiles, UnvalidatedSnapFiles } from "../types.cjs";
|
|
3
3
|
export type ValidatorResults = {
|
|
4
4
|
files?: SnapFiles;
|
|
5
5
|
reports: ValidatorReport[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.cts","sourceRoot":"","sources":["../../src/manifest/validator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"validator.d.cts","sourceRoot":"","sources":["../../src/manifest/validator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,aAAa,EACb,eAAe,EAEhB,8BAA0B;AAE3B,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAiB;AAEhE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B,CAAC;AAyBF;;;;;;;;GAQG;AAIH,wBAAsB,aAAa,CACjC,KAAK,EAAE,oBAAoB,EAC3B,KAAK,GAAE,aAAa,EAAqC,GACxD,OAAO,CAAC,gBAAgB,CAAC,CAyB3B;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAE3D"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { SnapFiles, UnvalidatedSnapFiles } from "../types.mjs";
|
|
2
1
|
import type { ValidatorMeta, ValidatorReport } from "./validator-types.mjs";
|
|
2
|
+
import type { SnapFiles, UnvalidatedSnapFiles } from "../types.mjs";
|
|
3
3
|
export type ValidatorResults = {
|
|
4
4
|
files?: SnapFiles;
|
|
5
5
|
reports: ValidatorReport[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.mts","sourceRoot":"","sources":["../../src/manifest/validator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"validator.d.mts","sourceRoot":"","sources":["../../src/manifest/validator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,aAAa,EACb,eAAe,EAEhB,8BAA0B;AAE3B,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,qBAAiB;AAEhE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B,CAAC;AAyBF;;;;;;;;GAQG;AAIH,wBAAsB,aAAa,CACjC,KAAK,EAAE,oBAAoB,EAC3B,KAAK,GAAE,aAAa,EAAqC,GACxD,OAAO,CAAC,gBAAgB,CAAC,CAyB3B;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAE3D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.mjs","sourceRoot":"","sources":["../../src/manifest/validator.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"validator.mjs","sourceRoot":"","sources":["../../src/manifest/validator.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,wBAAwB;AASzC,OAAO,KAAK,iBAAiB,+BAAqB;AAQlD,MAAM,OAAO;IAAb;QACE,YAAO,GAAsB,EAAE,CAAC;QAEhC,gCAAoC,SAAS,EAAC;IAkBhD,CAAC;IAhBC,MAAM,CAAC,OAAe,EAAE,GAAkB;QACxC,MAAM,CAAC,uBAAA,IAAI,6BAAc,KAAK,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,QAAQ,EAAE,uBAAA,IAAI,6BAAc;YAC5B,OAAO;YACP,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;IAED,mBAAmB,CAAC,QAAyC;QAC3D,uBAAA,IAAI,yBAAiB,QAAQ,CAAC,QAAQ,MAAA,CAAC;IACzC,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IACpE,CAAC;CACF;;AAED;;;;;;;;GAQG;AACH,iEAAiE;AACjE,8DAA8D;AAC9D,+BAA+B;AAC/B,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAA2B,EAC3B,QAAyB,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAEzD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,mBAAmB,CAAC;YAC1B,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,mBAAmB,CAAC;YAC1B,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,KAAkB,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO;QACL,KAAK,EAAE,KAAkB;QACzB,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAyB;IAChD,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACtD,CAAC","sourcesContent":["import { assert } from '@metamask/utils';\n\nimport type {\n ValidatorContext,\n ValidatorFix,\n ValidatorMeta,\n ValidatorReport,\n ValidatorSeverity,\n} from './validator-types';\nimport * as defaultValidators from './validators';\nimport type { SnapFiles, UnvalidatedSnapFiles } from '../types';\n\nexport type ValidatorResults = {\n files?: SnapFiles;\n reports: ValidatorReport[];\n};\n\nclass Context implements ValidatorContext {\n reports: ValidatorReport[] = [];\n\n #nextSeverity?: ValidatorSeverity = undefined;\n\n report(message: string, fix?: ValidatorFix): void {\n assert(this.#nextSeverity !== undefined);\n this.reports.push({\n severity: this.#nextSeverity,\n message,\n fix,\n });\n }\n\n prepareForValidator(settings: { severity: ValidatorSeverity }) {\n this.#nextSeverity = settings.severity;\n }\n\n get hasErrors() {\n return this.reports.some((report) => report.severity === 'error');\n }\n}\n\n/**\n * Verify that snap files are completely valid.\n * First it runs validators on unparsed files to check structure.\n * Secondly it runs validators on parsed files to check semantics.\n *\n * @param files - All files required to run a snap.\n * @param rules - Validators to run.\n * @returns The validation results.\n */\n// TODO(ritave): snap.manifest.json and package.json should check\n// json parsing as well instead of assuming it's\n// already parsed\nexport async function runValidators(\n files: UnvalidatedSnapFiles,\n rules: ValidatorMeta[] = Object.values(defaultValidators),\n): Promise<ValidatorResults> {\n const context = new Context();\n\n for (const rule of rules) {\n context.prepareForValidator({\n severity: rule.severity,\n });\n await rule.structureCheck?.(files, context);\n }\n if (context.hasErrors) {\n return {\n reports: context.reports,\n };\n }\n\n for (const rule of rules) {\n context.prepareForValidator({\n severity: rule.severity,\n });\n await rule.semanticCheck?.(files as SnapFiles, context);\n }\n return {\n files: files as SnapFiles,\n reports: context.reports,\n };\n}\n\n/**\n * Get whether any reports has pending fixes.\n *\n * @param results - Results of the validation run.\n * @returns Whether there are fixes pending.\n */\nexport function hasFixes(results: ValidatorResults): boolean {\n return results.reports.some((report) => report.fix);\n}\n"]}
|
|
@@ -14,7 +14,7 @@ exports.platformVersion = {
|
|
|
14
14
|
// file to avoid potentially loading the wrong version of the Snaps SDK.
|
|
15
15
|
const require = (0, module_1.createRequire)(files.manifest.path);
|
|
16
16
|
const packageJson = require.resolve('@metamask/snaps-sdk/package.json');
|
|
17
|
-
// eslint-disable-next-line import/no-dynamic-require
|
|
17
|
+
// eslint-disable-next-line import-x/no-dynamic-require
|
|
18
18
|
const actualVersion = require(packageJson).version;
|
|
19
19
|
if (!manifestPlatformVersion) {
|
|
20
20
|
context.report('The "platformVersion" field is missing from the manifest.', ({ manifest }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-version.cjs","sourceRoot":"","sources":["../../../src/manifest/validators/platform-version.ts"],"names":[],"mappings":";;;AAAA,mCAAuC;AAIvC;;;GAGG;AACU,QAAA,eAAe,GAAkB;IAC5C,QAAQ,EAAE,OAAO;IACjB,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO;QAChC,MAAM,uBAAuB,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAC;QAEtE,2EAA2E;QAC3E,wEAAwE;QACxE,MAAM,OAAO,GAAG,IAAA,sBAAa,EAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEnD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;QACxE,
|
|
1
|
+
{"version":3,"file":"platform-version.cjs","sourceRoot":"","sources":["../../../src/manifest/validators/platform-version.ts"],"names":[],"mappings":";;;AAAA,mCAAuC;AAIvC;;;GAGG;AACU,QAAA,eAAe,GAAkB;IAC5C,QAAQ,EAAE,OAAO;IACjB,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO;QAChC,MAAM,uBAAuB,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAC;QAEtE,2EAA2E;QAC3E,wEAAwE;QACxE,MAAM,OAAO,GAAG,IAAA,sBAAa,EAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEnD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;QACxE,uDAAuD;QACvD,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC;QAEnD,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC7B,OAAO,CAAC,MAAM,CACZ,2DAA2D,EAC3D,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;gBACf,QAAQ,CAAC,eAAe,GAAG,aAAa,CAAC;gBACzC,OAAO,EAAE,QAAQ,EAAE,CAAC;YACtB,CAAC,CACF,CAAC;YAEF,OAAO;QACT,CAAC;QAED,IAAI,uBAAuB,KAAK,aAAa,EAAE,CAAC;YAC9C,OAAO,CAAC,MAAM,CACZ,6FAA6F,uBAAuB,gBAAgB,aAAa,IAAI,EACrJ,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;gBACrB,QAAQ,CAAC,eAAe,GAAG,aAAa,CAAC;gBACzC,OAAO,EAAE,QAAQ,EAAE,CAAC;YACtB,CAAC,CACF,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC","sourcesContent":["import { createRequire } from 'module';\n\nimport type { ValidatorMeta } from '../validator-types';\n\n/**\n * Check if the platform version in manifest matches the version of the Snaps\n * SDK.\n */\nexport const platformVersion: ValidatorMeta = {\n severity: 'error',\n async semanticCheck(files, context) {\n const manifestPlatformVersion = files.manifest.result.platformVersion;\n\n // Create a require function in the context of the location of the manifest\n // file to avoid potentially loading the wrong version of the Snaps SDK.\n const require = createRequire(files.manifest.path);\n\n const packageJson = require.resolve('@metamask/snaps-sdk/package.json');\n // eslint-disable-next-line import-x/no-dynamic-require\n const actualVersion = require(packageJson).version;\n\n if (!manifestPlatformVersion) {\n context.report(\n 'The \"platformVersion\" field is missing from the manifest.',\n ({ manifest }) => {\n manifest.platformVersion = actualVersion;\n return { manifest };\n },\n );\n\n return;\n }\n\n if (manifestPlatformVersion !== actualVersion) {\n context.report(\n `The \"platformVersion\" field in the manifest must match the version of the Snaps SDK. Got \"${manifestPlatformVersion}\", expected \"${actualVersion}\".`,\n async ({ manifest }) => {\n manifest.platformVersion = actualVersion;\n return { manifest };\n },\n );\n }\n },\n};\n"]}
|
|
@@ -11,7 +11,7 @@ export const platformVersion = {
|
|
|
11
11
|
// file to avoid potentially loading the wrong version of the Snaps SDK.
|
|
12
12
|
const require = createRequire(files.manifest.path);
|
|
13
13
|
const packageJson = require.resolve('@metamask/snaps-sdk/package.json');
|
|
14
|
-
// eslint-disable-next-line import/no-dynamic-require
|
|
14
|
+
// eslint-disable-next-line import-x/no-dynamic-require
|
|
15
15
|
const actualVersion = require(packageJson).version;
|
|
16
16
|
if (!manifestPlatformVersion) {
|
|
17
17
|
context.report('The "platformVersion" field is missing from the manifest.', ({ manifest }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-version.mjs","sourceRoot":"","sources":["../../../src/manifest/validators/platform-version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,eAAe;AAIvC;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAkB;IAC5C,QAAQ,EAAE,OAAO;IACjB,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO;QAChC,MAAM,uBAAuB,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAC;QAEtE,2EAA2E;QAC3E,wEAAwE;QACxE,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEnD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;QACxE,
|
|
1
|
+
{"version":3,"file":"platform-version.mjs","sourceRoot":"","sources":["../../../src/manifest/validators/platform-version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,eAAe;AAIvC;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAkB;IAC5C,QAAQ,EAAE,OAAO;IACjB,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO;QAChC,MAAM,uBAAuB,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAC;QAEtE,2EAA2E;QAC3E,wEAAwE;QACxE,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEnD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC;QACxE,uDAAuD;QACvD,MAAM,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC;QAEnD,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC7B,OAAO,CAAC,MAAM,CACZ,2DAA2D,EAC3D,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;gBACf,QAAQ,CAAC,eAAe,GAAG,aAAa,CAAC;gBACzC,OAAO,EAAE,QAAQ,EAAE,CAAC;YACtB,CAAC,CACF,CAAC;YAEF,OAAO;QACT,CAAC;QAED,IAAI,uBAAuB,KAAK,aAAa,EAAE,CAAC;YAC9C,OAAO,CAAC,MAAM,CACZ,6FAA6F,uBAAuB,gBAAgB,aAAa,IAAI,EACrJ,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;gBACrB,QAAQ,CAAC,eAAe,GAAG,aAAa,CAAC;gBACzC,OAAO,EAAE,QAAQ,EAAE,CAAC;YACtB,CAAC,CACF,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC","sourcesContent":["import { createRequire } from 'module';\n\nimport type { ValidatorMeta } from '../validator-types';\n\n/**\n * Check if the platform version in manifest matches the version of the Snaps\n * SDK.\n */\nexport const platformVersion: ValidatorMeta = {\n severity: 'error',\n async semanticCheck(files, context) {\n const manifestPlatformVersion = files.manifest.result.platformVersion;\n\n // Create a require function in the context of the location of the manifest\n // file to avoid potentially loading the wrong version of the Snaps SDK.\n const require = createRequire(files.manifest.path);\n\n const packageJson = require.resolve('@metamask/snaps-sdk/package.json');\n // eslint-disable-next-line import-x/no-dynamic-require\n const actualVersion = require(packageJson).version;\n\n if (!manifestPlatformVersion) {\n context.report(\n 'The \"platformVersion\" field is missing from the manifest.',\n ({ manifest }) => {\n manifest.platformVersion = actualVersion;\n return { manifest };\n },\n );\n\n return;\n }\n\n if (manifestPlatformVersion !== actualVersion) {\n context.report(\n `The \"platformVersion\" field in the manifest must match the version of the Snaps SDK. Got \"${manifestPlatformVersion}\", expected \"${actualVersion}\".`,\n async ({ manifest }) => {\n manifest.platformVersion = actualVersion;\n return { manifest };\n },\n );\n }\n },\n};\n"]}
|
package/dist/mock.cjs
CHANGED
|
@@ -19,7 +19,6 @@ exports.ALL_APIS = [
|
|
|
19
19
|
* @returns A mocked snap provider.
|
|
20
20
|
*/
|
|
21
21
|
function getMockSnapGlobal() {
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
23
22
|
return { request: async () => true };
|
|
24
23
|
}
|
|
25
24
|
/**
|
|
@@ -29,7 +28,6 @@ function getMockSnapGlobal() {
|
|
|
29
28
|
*/
|
|
30
29
|
function getMockEthereumProvider() {
|
|
31
30
|
const mockProvider = new events_1.default();
|
|
32
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
33
31
|
mockProvider.request = async () => true;
|
|
34
32
|
return mockProvider;
|
|
35
33
|
}
|
|
@@ -50,7 +48,6 @@ const mockFunction = () => true;
|
|
|
50
48
|
class MockClass {
|
|
51
49
|
}
|
|
52
50
|
const handler = {
|
|
53
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
54
51
|
construct(Target, args) {
|
|
55
52
|
return new Proxy(new Target(...args), handler);
|
|
56
53
|
},
|
package/dist/mock.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock.cjs","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAC5B,oDAAkC;AAElC,iEAA0D;AAE1D,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAEpD,QAAA,QAAQ,GAAa;IAChC,GAAG,uCAAkB;IACrB,GAAG,YAAY;IACf,aAAa;CACd,CAAC;AAUF;;;;GAIG;AACH,SAAS,iBAAiB;IACxB,
|
|
1
|
+
{"version":3,"file":"mock.cjs","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from 'crypto';\nimport EventEmitter from 'events';\n\nimport { DEFAULT_ENDOWMENTS } from './default-endowments';\n\nconst NETWORK_APIS = ['fetch', 'Request', 'Headers', 'Response'];\n\nexport const ALL_APIS: string[] = [\n ...DEFAULT_ENDOWMENTS,\n ...NETWORK_APIS,\n 'WebAssembly',\n];\n\ntype MockSnapGlobal = {\n request: () => Promise<any>;\n};\n\ntype MockEthereumProvider = EventEmitter & {\n request: () => Promise<any>;\n};\n\n/**\n * Get a mock snap API, that always returns `true` for requests.\n *\n * @returns A mocked snap provider.\n */\nfunction getMockSnapGlobal(): MockSnapGlobal {\n return { request: async () => true };\n}\n\n/**\n * Get a mock Ethereum provider, that always returns `true` for requests.\n *\n * @returns A mocked ethereum provider.\n */\nfunction getMockEthereumProvider(): MockEthereumProvider {\n const mockProvider = new EventEmitter() as Partial<MockEthereumProvider>;\n mockProvider.request = async () => true;\n return mockProvider as MockEthereumProvider;\n}\n\n/**\n * Check if a value is a constructor.\n *\n * @param value - The value to check.\n * @returns `true` if the value is a constructor, or `false` otherwise.\n */\nexport const isConstructor = (value: any) =>\n Boolean(typeof value?.prototype?.constructor?.name === 'string');\n\n/**\n * A function that always returns `true`.\n *\n * @returns `true`.\n */\nconst mockFunction = () => true;\nclass MockClass {}\n\nconst handler = {\n construct(Target: any, args: any[]): any {\n return new Proxy(new Target(...args), handler);\n },\n get(_target: any, _prop: any) {\n return mockFunction;\n },\n};\n\n/**\n * Generate a mock class for a given value. The value is wrapped in a Proxy, and\n * all methods are replaced with a mock function.\n *\n * @param value - The value to mock.\n * @returns A mock class.\n */\nconst generateMockClass = (value: any) => {\n return new Proxy(value, handler);\n};\n\n// Things not currently auto-mocked because of NodeJS, by adding them here we\n// have types for them and can use that to generate mocks if needed.\nconst mockWindow: Record<string, unknown> = {\n crypto,\n SubtleCrypto: MockClass,\n};\n\n/**\n * Generate a mock endowment for a certain class or function on the `globalThis`\n * object.\n *\n * @param key - The key to generate the mock endowment for.\n * @returns A mocked class or function. If the key is part of the default\n * endowments, the original value is returned.\n */\nconst generateMockEndowment = (key: string) => {\n const globalValue = (globalThis as any)[key];\n\n // Default exposed APIs don't need to be mocked\n if (globalValue && DEFAULT_ENDOWMENTS.includes(key)) {\n return globalValue;\n }\n\n // Fall back to mockWindow for certain APIs not exposed in global in Node.JS\n const globalOrMocked = globalValue ?? mockWindow[key];\n\n const type = typeof globalOrMocked;\n const isFunction = type === 'function';\n if (isFunction && isConstructor(globalOrMocked)) {\n return generateMockClass(globalOrMocked);\n } else if (isFunction || !globalOrMocked) {\n // Fall back to function mock for now\n return mockFunction;\n }\n return globalOrMocked;\n};\n\n/**\n * Generate mock endowments for all the APIs as defined in {@link ALL_APIS}.\n *\n * @returns A map of endowments.\n */\nexport const generateMockEndowments = () => {\n return ALL_APIS.reduce<Record<string, any>>(\n (acc, cur) => ({ ...acc, [cur]: generateMockEndowment(cur) }),\n { snap: getMockSnapGlobal(), ethereum: getMockEthereumProvider() },\n );\n};\n"]}
|
package/dist/mock.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock.d.cts","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,QAAQ,EAAE,MAAM,EAI5B,CAAC;
|
|
1
|
+
{"version":3,"file":"mock.d.cts","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,QAAQ,EAAE,MAAM,EAI5B,CAAC;AA8BF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,UAAW,GAAG,YAC0B,CAAC;AAmEnE;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,2BAKlC,CAAC"}
|
package/dist/mock.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock.d.mts","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,QAAQ,EAAE,MAAM,EAI5B,CAAC;
|
|
1
|
+
{"version":3,"file":"mock.d.mts","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,QAAQ,EAAE,MAAM,EAI5B,CAAC;AA8BF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,UAAW,GAAG,YAC0B,CAAC;AAmEnE;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,2BAKlC,CAAC"}
|
package/dist/mock.mjs
CHANGED
|
@@ -13,7 +13,6 @@ export const ALL_APIS = [
|
|
|
13
13
|
* @returns A mocked snap provider.
|
|
14
14
|
*/
|
|
15
15
|
function getMockSnapGlobal() {
|
|
16
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
17
16
|
return { request: async () => true };
|
|
18
17
|
}
|
|
19
18
|
/**
|
|
@@ -23,7 +22,6 @@ function getMockSnapGlobal() {
|
|
|
23
22
|
*/
|
|
24
23
|
function getMockEthereumProvider() {
|
|
25
24
|
const mockProvider = new EventEmitter();
|
|
26
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
27
25
|
mockProvider.request = async () => true;
|
|
28
26
|
return mockProvider;
|
|
29
27
|
}
|
|
@@ -43,7 +41,6 @@ const mockFunction = () => true;
|
|
|
43
41
|
class MockClass {
|
|
44
42
|
}
|
|
45
43
|
const handler = {
|
|
46
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
47
44
|
construct(Target, args) {
|
|
48
45
|
return new Proxy(new Target(...args), handler);
|
|
49
46
|
},
|
package/dist/mock.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock.mjs","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,eAAe;AAC5B,OAAO,YAAY,eAAe;AAElC,OAAO,EAAE,kBAAkB,EAAE,iCAA6B;AAE1D,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAEjE,MAAM,CAAC,MAAM,QAAQ,GAAa;IAChC,GAAG,kBAAkB;IACrB,GAAG,YAAY;IACf,aAAa;CACd,CAAC;AAUF;;;;GAIG;AACH,SAAS,iBAAiB;IACxB,
|
|
1
|
+
{"version":3,"file":"mock.mjs","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from 'crypto';\nimport EventEmitter from 'events';\n\nimport { DEFAULT_ENDOWMENTS } from './default-endowments';\n\nconst NETWORK_APIS = ['fetch', 'Request', 'Headers', 'Response'];\n\nexport const ALL_APIS: string[] = [\n ...DEFAULT_ENDOWMENTS,\n ...NETWORK_APIS,\n 'WebAssembly',\n];\n\ntype MockSnapGlobal = {\n request: () => Promise<any>;\n};\n\ntype MockEthereumProvider = EventEmitter & {\n request: () => Promise<any>;\n};\n\n/**\n * Get a mock snap API, that always returns `true` for requests.\n *\n * @returns A mocked snap provider.\n */\nfunction getMockSnapGlobal(): MockSnapGlobal {\n return { request: async () => true };\n}\n\n/**\n * Get a mock Ethereum provider, that always returns `true` for requests.\n *\n * @returns A mocked ethereum provider.\n */\nfunction getMockEthereumProvider(): MockEthereumProvider {\n const mockProvider = new EventEmitter() as Partial<MockEthereumProvider>;\n mockProvider.request = async () => true;\n return mockProvider as MockEthereumProvider;\n}\n\n/**\n * Check if a value is a constructor.\n *\n * @param value - The value to check.\n * @returns `true` if the value is a constructor, or `false` otherwise.\n */\nexport const isConstructor = (value: any) =>\n Boolean(typeof value?.prototype?.constructor?.name === 'string');\n\n/**\n * A function that always returns `true`.\n *\n * @returns `true`.\n */\nconst mockFunction = () => true;\nclass MockClass {}\n\nconst handler = {\n construct(Target: any, args: any[]): any {\n return new Proxy(new Target(...args), handler);\n },\n get(_target: any, _prop: any) {\n return mockFunction;\n },\n};\n\n/**\n * Generate a mock class for a given value. The value is wrapped in a Proxy, and\n * all methods are replaced with a mock function.\n *\n * @param value - The value to mock.\n * @returns A mock class.\n */\nconst generateMockClass = (value: any) => {\n return new Proxy(value, handler);\n};\n\n// Things not currently auto-mocked because of NodeJS, by adding them here we\n// have types for them and can use that to generate mocks if needed.\nconst mockWindow: Record<string, unknown> = {\n crypto,\n SubtleCrypto: MockClass,\n};\n\n/**\n * Generate a mock endowment for a certain class or function on the `globalThis`\n * object.\n *\n * @param key - The key to generate the mock endowment for.\n * @returns A mocked class or function. If the key is part of the default\n * endowments, the original value is returned.\n */\nconst generateMockEndowment = (key: string) => {\n const globalValue = (globalThis as any)[key];\n\n // Default exposed APIs don't need to be mocked\n if (globalValue && DEFAULT_ENDOWMENTS.includes(key)) {\n return globalValue;\n }\n\n // Fall back to mockWindow for certain APIs not exposed in global in Node.JS\n const globalOrMocked = globalValue ?? mockWindow[key];\n\n const type = typeof globalOrMocked;\n const isFunction = type === 'function';\n if (isFunction && isConstructor(globalOrMocked)) {\n return generateMockClass(globalOrMocked);\n } else if (isFunction || !globalOrMocked) {\n // Fall back to function mock for now\n return mockFunction;\n }\n return globalOrMocked;\n};\n\n/**\n * Generate mock endowments for all the APIs as defined in {@link ALL_APIS}.\n *\n * @returns A map of endowments.\n */\nexport const generateMockEndowments = () => {\n return ALL_APIS.reduce<Record<string, any>>(\n (acc, cur) => ({ ...acc, [cur]: generateMockEndowment(cur) }),\n { snap: getMockSnapGlobal(), ethereum: getMockEthereumProvider() },\n );\n};\n"]}
|
package/dist/node.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/* eslint-disable import/export */
|
|
2
|
+
/* eslint-disable import-x/export */
|
|
3
3
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
4
|
if (k2 === undefined) k2 = k;
|
|
5
5
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
package/dist/node.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.cjs","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":";AAAA,
|
|
1
|
+
{"version":3,"file":"node.cjs","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,8CAAkB;AAClB,6CAAuB;AACvB,2CAAqB;AACrB,sDAAgC;AAChC,6CAAuB;AACvB,qDAA+B;AAC/B,0DAAoC","sourcesContent":["/* eslint-disable import-x/export */\n\nexport * from '.';\nexport * from './eval';\nexport * from './fs';\nexport * from './manifest/node';\nexport * from './mock';\nexport * from './post-process';\nexport * from './virtual-file/node';\n"]}
|
package/dist/node.mjs
CHANGED