@metamask/snaps-cli 0.8.0 → 0.10.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +42 -1
  2. package/README.md +62 -20
  3. package/dist/builders.d.ts +16 -8
  4. package/dist/builders.js +66 -41
  5. package/dist/builders.js.map +1 -1
  6. package/dist/cli.js +3 -2
  7. package/dist/cli.js.map +1 -1
  8. package/dist/cmds/build/buildHandler.js +1 -1
  9. package/dist/cmds/build/buildHandler.js.map +1 -1
  10. package/dist/cmds/build/bundle.d.ts +9 -7
  11. package/dist/cmds/build/bundle.js +35 -31
  12. package/dist/cmds/build/bundle.js.map +1 -1
  13. package/dist/cmds/build/index.js +10 -4
  14. package/dist/cmds/build/index.js.map +1 -1
  15. package/dist/cmds/build/utils.d.ts +59 -0
  16. package/dist/cmds/build/utils.js +148 -0
  17. package/dist/cmds/build/utils.js.map +1 -0
  18. package/dist/cmds/init/initHandler.d.ts +2 -0
  19. package/dist/cmds/init/initHandler.js +6 -1
  20. package/dist/cmds/init/initHandler.js.map +1 -1
  21. package/dist/cmds/watch/index.js +11 -1
  22. package/dist/cmds/watch/index.js.map +1 -1
  23. package/dist/cmds/watch/watchHandler.js +32 -19
  24. package/dist/cmds/watch/watchHandler.js.map +1 -1
  25. package/dist/utils/misc.d.ts +10 -1
  26. package/dist/utils/misc.js +25 -4
  27. package/dist/utils/misc.js.map +1 -1
  28. package/dist/utils/snap-config.__GENERATED__.d.ts +2 -0
  29. package/dist/utils/snap-config.__GENERATED__.js +18 -0
  30. package/dist/utils/snap-config.__GENERATED__.js.map +1 -0
  31. package/dist/utils/snap-config.d.ts +8 -1
  32. package/dist/utils/snap-config.js +39 -32
  33. package/dist/utils/snap-config.js.map +1 -1
  34. package/package.json +11 -8
  35. package/dist/cmds/build/bundleUtils.d.ts +0 -42
  36. package/dist/cmds/build/bundleUtils.js +0 -95
  37. package/dist/cmds/build/bundleUtils.js.map +0 -1
@@ -3,12 +3,38 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.applyConfig = void 0;
7
- const fs_1 = require("fs");
6
+ exports.applyConfig = exports.loadConfig = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
8
  const yargs_parser_1 = __importDefault(require("yargs-parser"));
9
9
  const builders_1 = __importDefault(require("../builders"));
10
10
  const misc_1 = require("./misc");
11
- const _1 = require(".");
11
+ const snap_config___GENERATED__1 = require("./snap-config.__GENERATED__");
12
+ let snapConfigCache;
13
+ function loadConfig(cached = true) {
14
+ if (snapConfigCache !== undefined && cached === true) {
15
+ return snapConfigCache;
16
+ }
17
+ let config;
18
+ try {
19
+ // eslint-disable-next-line node/global-require, import/no-dynamic-require, @typescript-eslint/no-require-imports
20
+ config = require(path_1.default.resolve(process.cwd(), misc_1.CONFIG_FILE));
21
+ }
22
+ catch (err) {
23
+ if (err.code === 'MODULE_NOT_FOUND') {
24
+ snapConfigCache = {};
25
+ return snapConfigCache;
26
+ }
27
+ misc_1.logError(`Error during parsing of ${misc_1.CONFIG_FILE}`, err);
28
+ return process.exit(1);
29
+ }
30
+ if (!snap_config___GENERATED__1.isSnapConfig(config)) {
31
+ misc_1.logError(`Can't validate ${misc_1.CONFIG_FILE}. Ensure it's a proper javascript file and abides with the structure of a snap configuration file`);
32
+ return process.exit(1);
33
+ }
34
+ snapConfigCache = config;
35
+ return config;
36
+ }
37
+ exports.loadConfig = loadConfig;
12
38
  // Note that the below function is necessary because yarg's .config() function
13
39
  // leaves much to be desired.
14
40
  //
@@ -21,7 +47,7 @@ const _1 = require(".");
21
47
  * Arguments are only set per the snap-cli config file if they were not specified
22
48
  * on the command line.
23
49
  */
24
- function applyConfig(processArgv, yargsArgv, yargsInstance) {
50
+ function applyConfig(snapConfig, processArgv, yargsArgv, yargsInstance) {
25
51
  // Instances of yargs has a number of undocumented functions, including
26
52
  // getOptions. This function returns an object with properties "key" and
27
53
  // "alias", which specify the options associated with the current command and
@@ -43,36 +69,17 @@ function applyConfig(processArgv, yargsArgv, yargsInstance) {
43
69
  return (commandOptions.has(key) &&
44
70
  !Object.prototype.hasOwnProperty.call(parsedProcessArgv, key));
45
71
  };
46
- // Now, we attempt to read and apply config from the config file, if any.
47
- let cfg = {};
48
- try {
49
- cfg = JSON.parse(fs_1.readFileSync(_1.CONFIG_FILE, 'utf8'));
50
- }
51
- catch (err) {
52
- if (err.code === 'ENOENT') {
53
- // If there's no config file, we're done here.
54
- return;
55
- }
56
- misc_1.logError(`Error: "${_1.CONFIG_FILE}" exists but could not be parsed. Ensure your config file is valid JSON and try again.`, err);
57
- process.exit(1);
58
- }
59
- if (cfg && typeof cfg === 'object' && !Array.isArray(cfg)) {
60
- for (const key of Object.keys(cfg)) {
61
- if (Object.hasOwnProperty.call(builders_1.default, key)) {
62
- if (shouldSetArg(key)) {
63
- yargsArgv[key] = cfg[key];
64
- }
65
- }
66
- else {
67
- misc_1.logError(`Error: Encountered unrecognized config property "${key}" in config file "${_1.CONFIG_FILE}". Remove the property and try again.`);
68
- process.exit(1);
72
+ const cfg = snapConfig.cliOptions || {};
73
+ for (const key of Object.keys(cfg)) {
74
+ if (Object.hasOwnProperty.call(builders_1.default, key)) {
75
+ if (shouldSetArg(key)) {
76
+ yargsArgv[key] = cfg[key];
69
77
  }
70
78
  }
71
- }
72
- else {
73
- const cfgType = cfg === null ? 'null' : typeof cfg;
74
- misc_1.logError(`Error: The config file must consist of a top-level JSON object. Received "${cfgType}" from "${_1.CONFIG_FILE}". Fix your config file and try again.`);
75
- process.exit(1);
79
+ else {
80
+ misc_1.logError(`Error: Encountered unrecognized config property "options.${key}" in config file "${misc_1.CONFIG_FILE}". Remove the property and try again.`);
81
+ process.exit(1);
82
+ }
76
83
  }
77
84
  }
78
85
  exports.applyConfig = applyConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"snap-config.js","sourceRoot":"","sources":["../../src/utils/snap-config.ts"],"names":[],"mappings":";;;;;;AAAA,2BAAkC;AAElC,gEAAsC;AAEtC,2DAAmC;AACnC,iCAAkC;AAClC,wBAAgC;AAEhC,8EAA8E;AAC9E,6BAA6B;AAC7B,EAAE;AACF,wEAAwE;AACxE,4DAA4D;AAE5D;;;;;;GAMG;AACH,SAAgB,WAAW,CACzB,WAAqB,EACrB,SAAoB,EACpB,aAA2B;IAE3B,uEAAuE;IACvE,wEAAwE;IACxE,6EAA6E;IAC7E,+BAA+B;IAC/B,EAAE;IACF,8EAA8E;IAC9E,2EAA2E;IAC3E,oBAAoB;IACpB,EAAE;IACF,6EAA6E;IAC7E,qBAAqB;IACrB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GACpC,aACD,CAAC,UAAU,EAGX,CAAC;IAEF,MAAM,iBAAiB,GAAG,sBAAU,CAAC,WAAW,EAAE;QAChD,KAAK,EAAE,OAAO;KACf,CAA4B,CAAC;IAC9B,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC,mCAAmC;IAE/D,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAErD,MAAM,YAAY,GAAG,CAAC,GAAW,EAAW,EAAE;QAC5C,OAAO,CACL,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;YACvB,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAC9D,CAAC;IACJ,CAAC,CAAC;IAEF,yEAAyE;IACzE,IAAI,GAAG,GAA4B,EAAE,CAAC;IACtC,IAAI;QACF,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAY,CAAC,cAAW,EAAE,MAAM,CAAC,CAAC,CAAC;KACrD;IAAC,OAAO,GAAG,EAAE;QACZ,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE;YACzB,8CAA8C;YAC9C,OAAO;SACR;QAED,eAAQ,CACN,WAAW,cAAW,wFAAwF,EAC9G,GAAG,CACJ,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;IAED,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QACzD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;YAClC,IAAI,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,kBAAQ,EAAE,GAAG,CAAC,EAAE;gBAC7C,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE;oBACrB,SAAS,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;iBAC3B;aACF;iBAAM;gBACL,eAAQ,CACN,oDAAoD,GAAG,qBAAqB,cAAW,uCAAuC,CAC/H,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACjB;SACF;KACF;SAAM;QACL,MAAM,OAAO,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC;QAEnD,eAAQ,CACN,6EAA6E,OAAO,WAAW,cAAW,wCAAwC,CACnJ,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;AACH,CAAC;AA3ED,kCA2EC","sourcesContent":["import { readFileSync } from 'fs';\nimport { Arguments } from 'yargs';\nimport yargsParse from 'yargs-parser';\nimport yargs from 'yargs/yargs';\nimport builders from '../builders';\nimport { logError } from './misc';\nimport { CONFIG_FILE } from '.';\n\n// Note that the below function is necessary because yarg's .config() function\n// leaves much to be desired.\n//\n// In particular, it will set all properties included in the config file\n// regardless of the command, which fails during validation.\n\n/**\n * Attempts to read configuration options for package.json and the config file,\n * and apply them to argv if they weren't already set.\n *\n * Arguments are only set per the snap-cli config file if they were not specified\n * on the command line.\n */\nexport function applyConfig(\n processArgv: string[],\n yargsArgv: Arguments,\n yargsInstance: typeof yargs,\n): void {\n // Instances of yargs has a number of undocumented functions, including\n // getOptions. This function returns an object with properties \"key\" and\n // \"alias\", which specify the options associated with the current command and\n // their aliases, respectively.\n //\n // We leverage this to ensure that the config is only applied to args that are\n // valid for the current command, and that weren't specified by the user on\n // the command line.\n //\n // If we set args that aren't valid for the current command, yargs will error\n // during validation.\n const { alias: aliases, key: options } = (\n yargsInstance as any\n ).getOptions() as {\n alias: Record<string, string[]>;\n key: Record<string, unknown>;\n };\n\n const parsedProcessArgv = yargsParse(processArgv, {\n alias: aliases,\n }) as Record<string, unknown>;\n delete parsedProcessArgv._; // irrelevant yargs parser artifact\n\n const commandOptions = new Set(Object.keys(options));\n\n const shouldSetArg = (key: string): boolean => {\n return (\n commandOptions.has(key) &&\n !Object.prototype.hasOwnProperty.call(parsedProcessArgv, key)\n );\n };\n\n // Now, we attempt to read and apply config from the config file, if any.\n let cfg: Record<string, unknown> = {};\n try {\n cfg = JSON.parse(readFileSync(CONFIG_FILE, 'utf8'));\n } catch (err) {\n if (err.code === 'ENOENT') {\n // If there's no config file, we're done here.\n return;\n }\n\n logError(\n `Error: \"${CONFIG_FILE}\" exists but could not be parsed. Ensure your config file is valid JSON and try again.`,\n err,\n );\n process.exit(1);\n }\n\n if (cfg && typeof cfg === 'object' && !Array.isArray(cfg)) {\n for (const key of Object.keys(cfg)) {\n if (Object.hasOwnProperty.call(builders, key)) {\n if (shouldSetArg(key)) {\n yargsArgv[key] = cfg[key];\n }\n } else {\n logError(\n `Error: Encountered unrecognized config property \"${key}\" in config file \"${CONFIG_FILE}\". Remove the property and try again.`,\n );\n process.exit(1);\n }\n }\n } else {\n const cfgType = cfg === null ? 'null' : typeof cfg;\n\n logError(\n `Error: The config file must consist of a top-level JSON object. Received \"${cfgType}\" from \"${CONFIG_FILE}\". Fix your config file and try again.`,\n );\n process.exit(1);\n }\n}\n"]}
1
+ {"version":3,"file":"snap-config.js","sourceRoot":"","sources":["../../src/utils/snap-config.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AAGxB,gEAAsC;AAEtC,2DAAmC;AACnC,iCAA+C;AAC/C,0EAA2D;AAQ3D,IAAI,eAAuC,CAAC;AAE5C,SAAgB,UAAU,CAAC,MAAM,GAAG,IAAI;IACtC,IAAI,eAAe,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,EAAE;QACpD,OAAO,eAAe,CAAC;KACxB;IAED,IAAI,MAAW,CAAC;IAChB,IAAI;QACF,iHAAiH;QACjH,MAAM,GAAG,OAAO,CAAC,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,kBAAW,CAAC,CAAC,CAAC;KAC5D;IAAC,OAAO,GAAQ,EAAE;QACjB,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,EAAE;YACnC,eAAe,GAAG,EAAE,CAAC;YACrB,OAAO,eAAe,CAAC;SACxB;QACD,eAAQ,CAAC,2BAA2B,kBAAW,EAAE,EAAE,GAAG,CAAC,CAAC;QACxD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACxB;IAED,IAAI,CAAC,uCAAY,CAAC,MAAM,CAAC,EAAE;QACzB,eAAQ,CACN,kBAAkB,kBAAW,mGAAmG,CACjI,CAAC;QACF,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACxB;IACD,eAAe,GAAG,MAAM,CAAC;IACzB,OAAO,MAAM,CAAC;AAChB,CAAC;AA1BD,gCA0BC;AAED,8EAA8E;AAC9E,6BAA6B;AAC7B,EAAE;AACF,wEAAwE;AACxE,4DAA4D;AAE5D;;;;;;GAMG;AACH,SAAgB,WAAW,CACzB,UAAsB,EACtB,WAAqB,EACrB,SAAoB,EACpB,aAA2B;IAE3B,uEAAuE;IACvE,wEAAwE;IACxE,6EAA6E;IAC7E,+BAA+B;IAC/B,EAAE;IACF,8EAA8E;IAC9E,2EAA2E;IAC3E,oBAAoB;IACpB,EAAE;IACF,6EAA6E;IAC7E,qBAAqB;IACrB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GACpC,aACD,CAAC,UAAU,EAGX,CAAC;IAEF,MAAM,iBAAiB,GAAG,sBAAU,CAAC,WAAW,EAAE;QAChD,KAAK,EAAE,OAAO;KACf,CAA4B,CAAC;IAC9B,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC,mCAAmC;IAE/D,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAErD,MAAM,YAAY,GAAG,CAAC,GAAW,EAAW,EAAE;QAC5C,OAAO,CACL,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;YACvB,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAC9D,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,GAAG,GAA4B,UAAU,CAAC,UAAU,IAAI,EAAE,CAAC;IACjE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAClC,IAAI,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,kBAAQ,EAAE,GAAG,CAAC,EAAE;YAC7C,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE;gBACrB,SAAS,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;aAC3B;SACF;aAAM;YACL,eAAQ,CACN,4DAA4D,GAAG,qBAAqB,kBAAW,uCAAuC,CACvI,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACjB;KACF;AACH,CAAC;AAnDD,kCAmDC","sourcesContent":["import path from 'path';\nimport type browserify from 'browserify';\nimport { Arguments } from 'yargs';\nimport yargsParse from 'yargs-parser';\nimport yargs from 'yargs/yargs';\nimport builders from '../builders';\nimport { CONFIG_FILE, logError } from './misc';\nimport { isSnapConfig } from './snap-config.__GENERATED__';\n\n/** @see {isSnapConfig} ts-auto-guard:type-guard */\nexport type SnapConfig = {\n cliOptions?: Record<string, unknown>;\n bundlerCustomizer?: (bundler: browserify.BrowserifyObject) => void;\n};\n\nlet snapConfigCache: SnapConfig | undefined;\n\nexport function loadConfig(cached = true): SnapConfig {\n if (snapConfigCache !== undefined && cached === true) {\n return snapConfigCache;\n }\n\n let config: any;\n try {\n // eslint-disable-next-line node/global-require, import/no-dynamic-require, @typescript-eslint/no-require-imports\n config = require(path.resolve(process.cwd(), CONFIG_FILE));\n } catch (err: any) {\n if (err.code === 'MODULE_NOT_FOUND') {\n snapConfigCache = {};\n return snapConfigCache;\n }\n logError(`Error during parsing of ${CONFIG_FILE}`, err);\n return process.exit(1);\n }\n\n if (!isSnapConfig(config)) {\n logError(\n `Can't validate ${CONFIG_FILE}. Ensure it's a proper javascript file and abides with the structure of a snap configuration file`,\n );\n return process.exit(1);\n }\n snapConfigCache = config;\n return config;\n}\n\n// Note that the below function is necessary because yarg's .config() function\n// leaves much to be desired.\n//\n// In particular, it will set all properties included in the config file\n// regardless of the command, which fails during validation.\n\n/**\n * Attempts to read configuration options for package.json and the config file,\n * and apply them to argv if they weren't already set.\n *\n * Arguments are only set per the snap-cli config file if they were not specified\n * on the command line.\n */\nexport function applyConfig(\n snapConfig: SnapConfig,\n processArgv: string[],\n yargsArgv: Arguments,\n yargsInstance: typeof yargs,\n): void {\n // Instances of yargs has a number of undocumented functions, including\n // getOptions. This function returns an object with properties \"key\" and\n // \"alias\", which specify the options associated with the current command and\n // their aliases, respectively.\n //\n // We leverage this to ensure that the config is only applied to args that are\n // valid for the current command, and that weren't specified by the user on\n // the command line.\n //\n // If we set args that aren't valid for the current command, yargs will error\n // during validation.\n const { alias: aliases, key: options } = (\n yargsInstance as any\n ).getOptions() as {\n alias: Record<string, string[]>;\n key: Record<string, unknown>;\n };\n\n const parsedProcessArgv = yargsParse(processArgv, {\n alias: aliases,\n }) as Record<string, unknown>;\n delete parsedProcessArgv._; // irrelevant yargs parser artifact\n\n const commandOptions = new Set(Object.keys(options));\n\n const shouldSetArg = (key: string): boolean => {\n return (\n commandOptions.has(key) &&\n !Object.prototype.hasOwnProperty.call(parsedProcessArgv, key)\n );\n };\n\n const cfg: Record<string, unknown> = snapConfig.cliOptions || {};\n for (const key of Object.keys(cfg)) {\n if (Object.hasOwnProperty.call(builders, key)) {\n if (shouldSetArg(key)) {\n yargsArgv[key] = cfg[key];\n }\n } else {\n logError(\n `Error: Encountered unrecognized config property \"options.${key}\" in config file \"${CONFIG_FILE}\". Remove the property and try again.`,\n );\n process.exit(1);\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/snaps-cli",
3
- "version": "0.8.0",
3
+ "version": "0.10.1",
4
4
  "description": "A CLI for developing MetaMask Snaps.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,14 +17,16 @@
17
17
  "setup": "yarn install && yarn allow-scripts",
18
18
  "shasum": "node ./scripts/computeSnapShasum.js",
19
19
  "build:init-template": "node ./scripts/createInitTemplate.js && yarn prettier --check src/cmds/init/init-template.json",
20
- "build:typescript": "tsc --project ./tsconfig.local.json",
20
+ "build:guards": "ts-auto-guard --guard-file-name=__GENERATED__ ./src/utils/snap-config.ts",
21
+ "build:tsc": "tsc --project ./tsconfig.local.json",
21
22
  "build:chmod": "chmod +x ./dist/main.js",
22
- "build": "yarn build:init-template && yarn build:typescript && yarn build:chmod",
23
- "build:pre-tsc": "echo 'N/A'",
24
- "build:post-tsc": "yarn build:init-template && yarn build:chmod",
23
+ "build:readme": "node ./scripts/updateReadme.js",
24
+ "build": "yarn build:pre-tsc && yarn build:tsc && yarn build:post-tsc",
25
+ "build:pre-tsc": "yarn build:init-template && yarn build:guards",
26
+ "build:post-tsc": "yarn build:chmod && yarn build:readme",
25
27
  "build:clean": "yarn clean && yarn build",
26
28
  "build:watch": "tsc-watch --onSuccess 'yarn build:chmod'",
27
- "clean": "rimraf dist/*",
29
+ "clean": "rimraf dist/* src/**/*__GENERATED__*",
28
30
  "test": "yarn build:init-template && jest",
29
31
  "test:watch": "yarn test --watch",
30
32
  "test:ci": "yarn test",
@@ -43,8 +45,8 @@
43
45
  "@babel/plugin-proposal-optional-chaining": "^7.16.7",
44
46
  "@babel/plugin-transform-runtime": "^7.16.7",
45
47
  "@babel/preset-env": "^7.16.7",
46
- "@metamask/snap-controllers": "^0.8.0",
47
- "@nodefactory/strip-comments": "^1.0.2",
48
+ "@metamask/snap-controllers": "^0.10.1",
49
+ "@nodefactory/strip-comments": "^1.0.4",
48
50
  "babelify": "^10.0.0",
49
51
  "browserify": "^17.0.0",
50
52
  "chokidar": "^3.0.2",
@@ -89,6 +91,7 @@
89
91
  "patch-package": "^6.4.7",
90
92
  "prettier": "^2.3.2",
91
93
  "rimraf": "^3.0.2",
94
+ "ts-auto-guard": "^2.3.0",
92
95
  "ts-jest": "^26.5.6",
93
96
  "ts-node": "^9.1.1",
94
97
  "tsc-watch": "^4.5.0",
@@ -1,42 +0,0 @@
1
- /// <reference types="node" />
2
- import { Option, YargsArgs } from '../../types/yargs';
3
- /**
4
- * Opens a stream to write the destination file path.
5
- *
6
- * @param dest - The output file path
7
- * @returns - The stream
8
- */
9
- export declare function createBundleStream(dest: string): NodeJS.WritableStream;
10
- declare type CloseStreamArgs = {
11
- bundleError: Error;
12
- bundleBuffer: Buffer;
13
- bundleStream: NodeJS.WritableStream;
14
- src: string;
15
- dest: string;
16
- resolve: (value: boolean) => void;
17
- argv: YargsArgs;
18
- };
19
- /**
20
- * Postprocesses the bundle string and closes the write stream.
21
- *
22
- * @param stream - The write stream
23
- * @param bundleString - The bundle string
24
- * @param options - post process options
25
- * @param options.stripComments
26
- */
27
- export declare function closeBundleStream({ bundleError, bundleBuffer, bundleStream, src, dest, resolve, argv, }: CloseStreamArgs): Promise<void>;
28
- /**
29
- * Postprocesses a JavaScript bundle string such that it can be evaluated in SES.
30
- * Currently:
31
- * - converts certain dot notation to string notation (for indexing)
32
- * - makes all direct calls to eval indirect
33
- * - wraps original bundle in anonymous function
34
- * - handles certain Babel-related edge cases
35
- *
36
- * @param bundleString - The bundle string
37
- * @param options - post process options
38
- * @param options.stripComments
39
- * @returns - The postprocessed bundle string
40
- */
41
- export declare function postProcess(bundleString: string | null, options?: Partial<Option>): string | null;
42
- export {};
@@ -1,95 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.postProcess = exports.closeBundleStream = exports.createBundleStream = void 0;
7
- const fs_1 = require("fs");
8
- const strip_comments_1 = __importDefault(require("@nodefactory/strip-comments"));
9
- const misc_1 = require("../../utils/misc");
10
- /**
11
- * Opens a stream to write the destination file path.
12
- *
13
- * @param dest - The output file path
14
- * @returns - The stream
15
- */
16
- function createBundleStream(dest) {
17
- const stream = fs_1.createWriteStream(dest, {
18
- autoClose: false,
19
- encoding: 'utf8',
20
- });
21
- stream.on('error', (err) => {
22
- misc_1.writeError('Write error:', err.message, err, dest);
23
- });
24
- return stream;
25
- }
26
- exports.createBundleStream = createBundleStream;
27
- /**
28
- * Postprocesses the bundle string and closes the write stream.
29
- *
30
- * @param stream - The write stream
31
- * @param bundleString - The bundle string
32
- * @param options - post process options
33
- * @param options.stripComments
34
- */
35
- async function closeBundleStream({ bundleError, bundleBuffer, bundleStream, src, dest, resolve, argv, }) {
36
- if (bundleError) {
37
- await misc_1.writeError('Build error:', bundleError.message, bundleError);
38
- }
39
- try {
40
- bundleStream.end(postProcess(bundleBuffer ? bundleBuffer.toString() : null, {
41
- stripComments: argv.stripComments,
42
- }));
43
- if (bundleBuffer) {
44
- console.log(`Build success: '${src}' bundled as '${dest}'!`);
45
- }
46
- resolve(true);
47
- }
48
- catch (closeError) {
49
- await misc_1.writeError('Write error:', closeError.message, closeError, dest);
50
- }
51
- }
52
- exports.closeBundleStream = closeBundleStream;
53
- /**
54
- * Postprocesses a JavaScript bundle string such that it can be evaluated in SES.
55
- * Currently:
56
- * - converts certain dot notation to string notation (for indexing)
57
- * - makes all direct calls to eval indirect
58
- * - wraps original bundle in anonymous function
59
- * - handles certain Babel-related edge cases
60
- *
61
- * @param bundleString - The bundle string
62
- * @param options - post process options
63
- * @param options.stripComments
64
- * @returns - The postprocessed bundle string
65
- */
66
- function postProcess(bundleString, options = {}) {
67
- if (typeof bundleString !== 'string') {
68
- return null;
69
- }
70
- let processedString = bundleString.trim();
71
- if (options.stripComments) {
72
- processedString = strip_comments_1.default(processedString);
73
- }
74
- // stuff.eval(otherStuff) => (1, stuff.eval)(otherStuff)
75
- processedString = processedString.replace(/((?:\b[\w\d]*[\])]?\.)+eval)(\([^)]*\))/gu, '(1, $1)$2');
76
- // if we don't do the above, the below causes syntax errors if it encounters
77
- // things of the form: "something.eval(stuff)"
78
- // eval(stuff) => (1, eval)(stuff)
79
- processedString = processedString.replace(/(\b)(eval)(\([^)]*\))/gu, '$1(1, $2)$3');
80
- // Browserify provides the Buffer global as an argument to modules that use
81
- // it, but this does not work in SES. Since we pass in Buffer as an endowment,
82
- // we can simply remove the argument.
83
- processedString = processedString.replace(/^\(function \(Buffer\)\{$/gmu, '(function (){');
84
- if (processedString.length === 0) {
85
- throw new Error(`Bundled code is empty after postprocessing.`);
86
- }
87
- // handle some cases by declaring missing globals
88
- // Babel regeneratorRuntime
89
- if (processedString.indexOf('regeneratorRuntime') !== -1) {
90
- processedString = `var regeneratorRuntime;\n${processedString}`;
91
- }
92
- return processedString;
93
- }
94
- exports.postProcess = postProcess;
95
- //# sourceMappingURL=bundleUtils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bundleUtils.js","sourceRoot":"","sources":["../../../src/cmds/build/bundleUtils.ts"],"names":[],"mappings":";;;;;;AAAA,2BAAuC;AACvC,iFAAwD;AACxD,2CAA8C;AAG9C;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,MAAM,MAAM,GAAG,sBAAiB,CAAC,IAAI,EAAE;QACrC,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,MAAM;KACjB,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACzB,iBAAU,CAAC,cAAc,EAAE,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AATD,gDASC;AAYD;;;;;;;GAOG;AACI,KAAK,UAAU,iBAAiB,CAAC,EACtC,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,GAAG,EACH,IAAI,EACJ,OAAO,EACP,IAAI,GACY;IAChB,IAAI,WAAW,EAAE;QACf,MAAM,iBAAU,CAAC,cAAc,EAAE,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;KACpE;IAED,IAAI;QACF,YAAY,CAAC,GAAG,CACd,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;YACzD,aAAa,EAAE,IAAI,CAAC,aAAa;SAClC,CAAW,CACb,CAAC;QAEF,IAAI,YAAY,EAAE;YAChB,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,iBAAiB,IAAI,IAAI,CAAC,CAAC;SAC9D;QACD,OAAO,CAAC,IAAI,CAAC,CAAC;KACf;IAAC,OAAO,UAAU,EAAE;QACnB,MAAM,iBAAU,CAAC,cAAc,EAAE,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;KACxE;AACH,CAAC;AA3BD,8CA2BC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,WAAW,CACzB,YAA2B,EAC3B,UAA2B,EAAE;IAE7B,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE;QACpC,OAAO,IAAI,CAAC;KACb;IAED,IAAI,eAAe,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;IAE1C,IAAI,OAAO,CAAC,aAAa,EAAE;QACzB,eAAe,GAAG,wBAAa,CAAC,eAAe,CAAC,CAAC;KAClD;IAED,wDAAwD;IACxD,eAAe,GAAG,eAAe,CAAC,OAAO,CACvC,2CAA2C,EAC3C,WAAW,CACZ,CAAC;IAEF,4EAA4E;IAC5E,8CAA8C;IAC9C,kCAAkC;IAClC,eAAe,GAAG,eAAe,CAAC,OAAO,CACvC,yBAAyB,EACzB,aAAa,CACd,CAAC;IAEF,2EAA2E;IAC3E,8EAA8E;IAC9E,qCAAqC;IACrC,eAAe,GAAG,eAAe,CAAC,OAAO,CACvC,8BAA8B,EAC9B,eAAe,CAChB,CAAC;IAEF,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;QAChC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;KAChE;IAED,iDAAiD;IACjD,2BAA2B;IAC3B,IAAI,eAAe,CAAC,OAAO,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,EAAE;QACxD,eAAe,GAAG,4BAA4B,eAAe,EAAE,CAAC;KACjE;IAED,OAAO,eAAe,CAAC;AACzB,CAAC;AA/CD,kCA+CC","sourcesContent":["import { createWriteStream } from 'fs';\nimport stripComments from '@nodefactory/strip-comments';\nimport { writeError } from '../../utils/misc';\nimport { Option, YargsArgs } from '../../types/yargs';\n\n/**\n * Opens a stream to write the destination file path.\n *\n * @param dest - The output file path\n * @returns - The stream\n */\nexport function createBundleStream(dest: string): NodeJS.WritableStream {\n const stream = createWriteStream(dest, {\n autoClose: false,\n encoding: 'utf8',\n });\n stream.on('error', (err) => {\n writeError('Write error:', err.message, err, dest);\n });\n return stream;\n}\n\ntype CloseStreamArgs = {\n bundleError: Error;\n bundleBuffer: Buffer;\n bundleStream: NodeJS.WritableStream;\n src: string;\n dest: string;\n resolve: (value: boolean) => void;\n argv: YargsArgs;\n};\n\n/**\n * Postprocesses the bundle string and closes the write stream.\n *\n * @param stream - The write stream\n * @param bundleString - The bundle string\n * @param options - post process options\n * @param options.stripComments\n */\nexport async function closeBundleStream({\n bundleError,\n bundleBuffer,\n bundleStream,\n src,\n dest,\n resolve,\n argv,\n}: CloseStreamArgs) {\n if (bundleError) {\n await writeError('Build error:', bundleError.message, bundleError);\n }\n\n try {\n bundleStream.end(\n postProcess(bundleBuffer ? bundleBuffer.toString() : null, {\n stripComments: argv.stripComments,\n }) as string,\n );\n\n if (bundleBuffer) {\n console.log(`Build success: '${src}' bundled as '${dest}'!`);\n }\n resolve(true);\n } catch (closeError) {\n await writeError('Write error:', closeError.message, closeError, dest);\n }\n}\n\n/**\n * Postprocesses a JavaScript bundle string such that it can be evaluated in SES.\n * Currently:\n * - converts certain dot notation to string notation (for indexing)\n * - makes all direct calls to eval indirect\n * - wraps original bundle in anonymous function\n * - handles certain Babel-related edge cases\n *\n * @param bundleString - The bundle string\n * @param options - post process options\n * @param options.stripComments\n * @returns - The postprocessed bundle string\n */\nexport function postProcess(\n bundleString: string | null,\n options: Partial<Option> = {},\n): string | null {\n if (typeof bundleString !== 'string') {\n return null;\n }\n\n let processedString = bundleString.trim();\n\n if (options.stripComments) {\n processedString = stripComments(processedString);\n }\n\n // stuff.eval(otherStuff) => (1, stuff.eval)(otherStuff)\n processedString = processedString.replace(\n /((?:\\b[\\w\\d]*[\\])]?\\.)+eval)(\\([^)]*\\))/gu,\n '(1, $1)$2',\n );\n\n // if we don't do the above, the below causes syntax errors if it encounters\n // things of the form: \"something.eval(stuff)\"\n // eval(stuff) => (1, eval)(stuff)\n processedString = processedString.replace(\n /(\\b)(eval)(\\([^)]*\\))/gu,\n '$1(1, $2)$3',\n );\n\n // Browserify provides the Buffer global as an argument to modules that use\n // it, but this does not work in SES. Since we pass in Buffer as an endowment,\n // we can simply remove the argument.\n processedString = processedString.replace(\n /^\\(function \\(Buffer\\)\\{$/gmu,\n '(function (){',\n );\n\n if (processedString.length === 0) {\n throw new Error(`Bundled code is empty after postprocessing.`);\n }\n\n // handle some cases by declaring missing globals\n // Babel regeneratorRuntime\n if (processedString.indexOf('regeneratorRuntime') !== -1) {\n processedString = `var regeneratorRuntime;\\n${processedString}`;\n }\n\n return processedString;\n}\n"]}