plugin-utils.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.getPluginOption = getPluginOption;
  6. exports.hasPlugin = hasPlugin;
  7. exports.mixinPlugins = exports.mixinPluginNames = void 0;
  8. exports.validatePlugins = validatePlugins;
  9. var _estree = require("./plugins/estree");
  10. var _flow = require("./plugins/flow");
  11. var _jsx = require("./plugins/jsx");
  12. var _typescript = require("./plugins/typescript");
  13. var _placeholders = require("./plugins/placeholders");
  14. var _v8intrinsic = require("./plugins/v8intrinsic");
  15. function hasPlugin(plugins, expectedConfig) {
  16. const [expectedName, expectedOptions] = typeof expectedConfig === "string" ? [expectedConfig, {}] : expectedConfig;
  17. const expectedKeys = Object.keys(expectedOptions);
  18. const expectedOptionsIsEmpty = expectedKeys.length === 0;
  19. return plugins.some(p => {
  20. if (typeof p === "string") {
  21. return expectedOptionsIsEmpty && p === expectedName;
  22. } else {
  23. const [pluginName, pluginOptions] = p;
  24. if (pluginName !== expectedName) {
  25. return false;
  26. }
  27. for (const key of expectedKeys) {
  28. if (pluginOptions[key] !== expectedOptions[key]) {
  29. return false;
  30. }
  31. }
  32. return true;
  33. }
  34. });
  35. }
  36. function getPluginOption(plugins, name, option) {
  37. const plugin = plugins.find(plugin => {
  38. if (Array.isArray(plugin)) {
  39. return plugin[0] === name;
  40. } else {
  41. return plugin === name;
  42. }
  43. });
  44. if (plugin && Array.isArray(plugin) && plugin.length > 1) {
  45. return plugin[1][option];
  46. }
  47. return null;
  48. }
  49. const PIPELINE_PROPOSALS = ["minimal", "fsharp", "hack", "smart"];
  50. const TOPIC_TOKENS = ["^^", "@@", "^", "%", "#"];
  51. const RECORD_AND_TUPLE_SYNTAX_TYPES = ["hash", "bar"];
  52. function validatePlugins(plugins) {
  53. if (hasPlugin(plugins, "decorators")) {
  54. if (hasPlugin(plugins, "decorators-legacy")) {
  55. throw new Error("Cannot use the decorators and decorators-legacy plugin together");
  56. }
  57. const decoratorsBeforeExport = getPluginOption(plugins, "decorators", "decoratorsBeforeExport");
  58. if (decoratorsBeforeExport != null && typeof decoratorsBeforeExport !== "boolean") {
  59. throw new Error("'decoratorsBeforeExport' must be a boolean, if specified.");
  60. }
  61. const allowCallParenthesized = getPluginOption(plugins, "decorators", "allowCallParenthesized");
  62. if (allowCallParenthesized != null && typeof allowCallParenthesized !== "boolean") {
  63. throw new Error("'allowCallParenthesized' must be a boolean.");
  64. }
  65. }
  66. if (hasPlugin(plugins, "flow") && hasPlugin(plugins, "typescript")) {
  67. throw new Error("Cannot combine flow and typescript plugins.");
  68. }
  69. if (hasPlugin(plugins, "placeholders") && hasPlugin(plugins, "v8intrinsic")) {
  70. throw new Error("Cannot combine placeholders and v8intrinsic plugins.");
  71. }
  72. if (hasPlugin(plugins, "pipelineOperator")) {
  73. const proposal = getPluginOption(plugins, "pipelineOperator", "proposal");
  74. if (!PIPELINE_PROPOSALS.includes(proposal)) {
  75. const proposalList = PIPELINE_PROPOSALS.map(p => `"${p}"`).join(", ");
  76. throw new Error(`"pipelineOperator" requires "proposal" option whose value must be one of: ${proposalList}.`);
  77. }
  78. const tupleSyntaxIsHash = hasPlugin(plugins, ["recordAndTuple", {
  79. syntaxType: "hash"
  80. }]);
  81. if (proposal === "hack") {
  82. if (hasPlugin(plugins, "placeholders")) {
  83. throw new Error("Cannot combine placeholders plugin and Hack-style pipes.");
  84. }
  85. if (hasPlugin(plugins, "v8intrinsic")) {
  86. throw new Error("Cannot combine v8intrinsic plugin and Hack-style pipes.");
  87. }
  88. const topicToken = getPluginOption(plugins, "pipelineOperator", "topicToken");
  89. if (!TOPIC_TOKENS.includes(topicToken)) {
  90. const tokenList = TOPIC_TOKENS.map(t => `"${t}"`).join(", ");
  91. throw new Error(`"pipelineOperator" in "proposal": "hack" mode also requires a "topicToken" option whose value must be one of: ${tokenList}.`);
  92. }
  93. if (topicToken === "#" && tupleSyntaxIsHash) {
  94. throw new Error('Plugin conflict between `["pipelineOperator", { proposal: "hack", topicToken: "#" }]` and `["recordAndtuple", { syntaxType: "hash"}]`.');
  95. }
  96. } else if (proposal === "smart" && tupleSyntaxIsHash) {
  97. throw new Error('Plugin conflict between `["pipelineOperator", { proposal: "smart" }]` and `["recordAndtuple", { syntaxType: "hash"}]`.');
  98. }
  99. }
  100. if (hasPlugin(plugins, "moduleAttributes")) {
  101. {
  102. if (hasPlugin(plugins, "importAssertions") || hasPlugin(plugins, "importAttributes")) {
  103. throw new Error("Cannot combine importAssertions, importAttributes and moduleAttributes plugins.");
  104. }
  105. const moduleAttributesVersionPluginOption = getPluginOption(plugins, "moduleAttributes", "version");
  106. if (moduleAttributesVersionPluginOption !== "may-2020") {
  107. throw new Error("The 'moduleAttributes' plugin requires a 'version' option," + " representing the last proposal update. Currently, the" + " only supported value is 'may-2020'.");
  108. }
  109. }
  110. }
  111. if (hasPlugin(plugins, "importAssertions") && hasPlugin(plugins, "importAttributes")) {
  112. throw new Error("Cannot combine importAssertions and importAttributes plugins.");
  113. }
  114. if (hasPlugin(plugins, "recordAndTuple") && getPluginOption(plugins, "recordAndTuple", "syntaxType") != null && !RECORD_AND_TUPLE_SYNTAX_TYPES.includes(getPluginOption(plugins, "recordAndTuple", "syntaxType"))) {
  115. throw new Error("The 'syntaxType' option of the 'recordAndTuple' plugin must be one of: " + RECORD_AND_TUPLE_SYNTAX_TYPES.map(p => `'${p}'`).join(", "));
  116. }
  117. if (hasPlugin(plugins, "asyncDoExpressions") && !hasPlugin(plugins, "doExpressions")) {
  118. const error = new Error("'asyncDoExpressions' requires 'doExpressions', please add 'doExpressions' to parser plugins.");
  119. error.missingPlugins = "doExpressions";
  120. throw error;
  121. }
  122. }
  123. const mixinPlugins = {
  124. estree: _estree.default,
  125. jsx: _jsx.default,
  126. flow: _flow.default,
  127. typescript: _typescript.default,
  128. v8intrinsic: _v8intrinsic.default,
  129. placeholders: _placeholders.default
  130. };
  131. exports.mixinPlugins = mixinPlugins;
  132. const mixinPluginNames = Object.keys(mixinPlugins);
  133. exports.mixinPluginNames = mixinPluginNames;
  134. //# sourceMappingURL=plugin-utils.js.map