1 | import { loadPartialConfig, parseSync } from '@babel/core';
|
2 | import { extname } from 'path';
|
3 | const TYPESCRIPT_EXTS = new Set(['.cts', '.mts', '.ts', '.tsx']);
|
4 | function getDefaultPlugins(options) {
|
5 | return [
|
6 | 'jsx',
|
7 | options.filename && TYPESCRIPT_EXTS.has(extname(options.filename))
|
8 | ? 'typescript'
|
9 | : 'flow',
|
10 | 'asyncDoExpressions',
|
11 | 'decimal',
|
12 | ['decorators', { decoratorsBeforeExport: false }],
|
13 | 'decoratorAutoAccessors',
|
14 | 'destructuringPrivate',
|
15 | 'doExpressions',
|
16 | 'exportDefaultFrom',
|
17 | 'functionBind',
|
18 | 'importAssertions',
|
19 | 'moduleBlocks',
|
20 | 'partialApplication',
|
21 | ['pipelineOperator', { proposal: 'minimal' }],
|
22 | ['recordAndTuple', { syntaxType: 'bar' }],
|
23 | 'regexpUnicodeSets',
|
24 | 'throwExpressions',
|
25 | ];
|
26 | }
|
27 | function buildPluginList(options) {
|
28 | let plugins = [];
|
29 | if (options.parserOpts?.plugins) {
|
30 | plugins = [...options.parserOpts.plugins];
|
31 | }
|
32 |
|
33 |
|
34 | const partialConfig = loadPartialConfig(options);
|
35 | if (plugins.length === 0 &&
|
36 | partialConfig &&
|
37 | !partialConfig.hasFilesystemConfig()) {
|
38 | plugins = getDefaultPlugins(options);
|
39 | }
|
40 |
|
41 |
|
42 | return plugins.filter((plugin) => plugin !== 'estree');
|
43 | }
|
44 | function buildParserOptions(options) {
|
45 | const plugins = buildPluginList(options);
|
46 | return {
|
47 | sourceType: 'unambiguous',
|
48 | ...(options.parserOpts || {}),
|
49 | plugins,
|
50 | tokens: false,
|
51 | };
|
52 | }
|
53 | export default function babelParser(src, options = {}) {
|
54 | const parserOpts = buildParserOptions(options);
|
55 | const opts = {
|
56 | ...options,
|
57 | parserOpts,
|
58 | };
|
59 | const ast = parseSync(src, opts);
|
60 | if (!ast) {
|
61 | throw new Error('Unable to parse source code.');
|
62 | }
|
63 | return ast;
|
64 | }
|