index.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.importAssertions = importAssertions;
  6. var _acorn = _interopRequireWildcard(require("acorn"));
  7. function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
  8. function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  9. const leftCurlyBrace = "{".charCodeAt(0);
  10. const space = " ".charCodeAt(0);
  11. const keyword = "assert";
  12. const FUNC_STATEMENT = 1,
  13. FUNC_HANGING_STATEMENT = 2,
  14. FUNC_NULLABLE_ID = 4;
  15. function importAssertions(Parser) {
  16. // Use supplied version acorn version if present, to avoid
  17. // reference mismatches due to different acorn versions. This
  18. // allows this plugin to be used with Rollup which supplies
  19. // its own internal version of acorn and thereby sidesteps
  20. // the package manager.
  21. const acorn = Parser.acorn || _acorn;
  22. const {
  23. tokTypes: tt,
  24. TokenType
  25. } = acorn;
  26. return class extends Parser {
  27. constructor(...args) {
  28. super(...args);
  29. this.assertToken = new TokenType(keyword);
  30. }
  31. _codeAt(i) {
  32. return this.input.charCodeAt(i);
  33. }
  34. _eat(t) {
  35. if (this.type !== t) {
  36. this.unexpected();
  37. }
  38. this.next();
  39. }
  40. readToken(code) {
  41. let i = 0;
  42. for (; i < keyword.length; i++) {
  43. if (this._codeAt(this.pos + i) !== keyword.charCodeAt(i)) {
  44. return super.readToken(code);
  45. }
  46. } // ensure that the keyword is at the correct location
  47. // ie `assert{...` or `assert {...`
  48. for (;; i++) {
  49. if (this._codeAt(this.pos + i) === leftCurlyBrace) {
  50. // Found '{'
  51. break;
  52. } else if (this._codeAt(this.pos + i) === space) {
  53. // white space is allowed between `assert` and `{`, so continue.
  54. continue;
  55. } else {
  56. return super.readToken(code);
  57. }
  58. } // If we're inside a dynamic import expression we'll parse
  59. // the `assert` keyword as a standard object property name
  60. // ie `import(""./foo.json", { assert: { type: "json" } })`
  61. if (this.type.label === "{") {
  62. return super.readToken(code);
  63. }
  64. this.pos += keyword.length;
  65. return this.finishToken(this.assertToken);
  66. }
  67. parseDynamicImport(node) {
  68. this.next(); // skip `(`
  69. // Parse node.source.
  70. node.source = this.parseMaybeAssign();
  71. if (this.eat(tt.comma)) {
  72. const obj = this.parseObj(false);
  73. node.arguments = [obj];
  74. }
  75. this._eat(tt.parenR);
  76. return this.finishNode(node, "ImportExpression");
  77. } // ported from acorn/src/statement.js pp.parseExport
  78. parseExport(node, exports) {
  79. this.next(); // export * from '...'
  80. if (this.eat(tt.star)) {
  81. if (this.options.ecmaVersion >= 11) {
  82. if (this.eatContextual("as")) {
  83. node.exported = this.parseIdent(true);
  84. this.checkExport(exports, node.exported.name, this.lastTokStart);
  85. } else {
  86. node.exported = null;
  87. }
  88. }
  89. this.expectContextual("from");
  90. if (this.type !== tt.string) {
  91. this.unexpected();
  92. }
  93. node.source = this.parseExprAtom();
  94. if (this.type === this.assertToken) {
  95. this.next();
  96. const assertions = this.parseImportAssertions();
  97. if (assertions) {
  98. node.assertions = assertions;
  99. }
  100. }
  101. this.semicolon();
  102. return this.finishNode(node, "ExportAllDeclaration");
  103. }
  104. if (this.eat(tt._default)) {
  105. // export default ...
  106. this.checkExport(exports, "default", this.lastTokStart);
  107. var isAsync;
  108. if (this.type === tt._function || (isAsync = this.isAsyncFunction())) {
  109. var fNode = this.startNode();
  110. this.next();
  111. if (isAsync) {
  112. this.next();
  113. }
  114. node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync);
  115. } else if (this.type === tt._class) {
  116. var cNode = this.startNode();
  117. node.declaration = this.parseClass(cNode, "nullableID");
  118. } else {
  119. node.declaration = this.parseMaybeAssign();
  120. this.semicolon();
  121. }
  122. return this.finishNode(node, "ExportDefaultDeclaration");
  123. } // export var|const|let|function|class ...
  124. if (this.shouldParseExportStatement()) {
  125. node.declaration = this.parseStatement(null);
  126. if (node.declaration.type === "VariableDeclaration") {
  127. this.checkVariableExport(exports, node.declaration.declarations);
  128. } else {
  129. this.checkExport(exports, node.declaration.id.name, node.declaration.id.start);
  130. }
  131. node.specifiers = [];
  132. node.source = null;
  133. } else {
  134. // export { x, y as z } [from '...']
  135. node.declaration = null;
  136. node.specifiers = this.parseExportSpecifiers(exports);
  137. if (this.eatContextual("from")) {
  138. if (this.type !== tt.string) {
  139. this.unexpected();
  140. }
  141. node.source = this.parseExprAtom();
  142. if (this.type === this.assertToken) {
  143. this.next();
  144. const assertions = this.parseImportAssertions();
  145. if (assertions) {
  146. node.assertions = assertions;
  147. }
  148. }
  149. } else {
  150. for (var i = 0, list = node.specifiers; i < list.length; i += 1) {
  151. // check for keywords used as local names
  152. var spec = list[i];
  153. this.checkUnreserved(spec.local); // check if export is defined
  154. this.checkLocalExport(spec.local);
  155. }
  156. node.source = null;
  157. }
  158. this.semicolon();
  159. }
  160. return this.finishNode(node, "ExportNamedDeclaration");
  161. }
  162. parseImport(node) {
  163. this.next(); // import '...'
  164. if (this.type === tt.string) {
  165. node.specifiers = [];
  166. node.source = this.parseExprAtom();
  167. } else {
  168. node.specifiers = this.parseImportSpecifiers();
  169. this.expectContextual("from");
  170. node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
  171. }
  172. if (this.type === this.assertToken) {
  173. this.next();
  174. const assertions = this.parseImportAssertions();
  175. if (assertions) {
  176. node.assertions = assertions;
  177. }
  178. }
  179. this.semicolon();
  180. return this.finishNode(node, "ImportDeclaration");
  181. }
  182. parseImportAssertions() {
  183. this._eat(tt.braceL);
  184. const attrs = this.parseAssertEntries();
  185. this._eat(tt.braceR);
  186. return attrs;
  187. }
  188. parseAssertEntries() {
  189. const attrs = [];
  190. const attrNames = new Set();
  191. do {
  192. if (this.type === tt.braceR) {
  193. break;
  194. }
  195. const node = this.startNode(); // parse AssertionKey : IdentifierName, StringLiteral
  196. let assertionKeyNode;
  197. if (this.type === tt.string) {
  198. assertionKeyNode = this.parseLiteral(this.value);
  199. } else {
  200. assertionKeyNode = this.parseIdent(true);
  201. }
  202. this.next();
  203. node.key = assertionKeyNode; // check if we already have an entry for an attribute
  204. // if a duplicate entry is found, throw an error
  205. // for now this logic will come into play only when someone declares `type` twice
  206. if (attrNames.has(node.key.name)) {
  207. this.raise(this.pos, "Duplicated key in assertions");
  208. }
  209. attrNames.add(node.key.name);
  210. if (this.type !== tt.string) {
  211. this.raise(this.pos, "Only string is supported as an assertion value");
  212. }
  213. node.value = this.parseLiteral(this.value);
  214. attrs.push(this.finishNode(node, "ImportAttribute"));
  215. } while (this.eat(tt.comma));
  216. return attrs;
  217. }
  218. };
  219. }