-
Notifications
You must be signed in to change notification settings - Fork 1
/
instrument.js
93 lines (92 loc) · 2.52 KB
/
instrument.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
'use strict';
const babel = require('babel-standalone');
const t = require('babel-types');
const transform = (referrer, meta) => {
const prefix = `/redirect?referrer=${encodeURIComponent(referrer)}&specifier=`;
return {
visitor: {
ExportDefaultDeclaration(path) {
meta.hasDefault = true;
},
ExportSpecifier(path) {
if (path.node.exported.name === 'default') {
meta.hasDefault = true;
}
},
ImportDeclaration(path) {
const specifier = path.node.source.value;
path.node.source = t.stringLiteral(
`${prefix}${encodeURIComponent(specifier)}`
);
const ns_i = path.node.specifiers.findIndex(n => n.type === 'ImportNamespaceSpecifier');
if (ns_i >= 0) {
const ns = path.node.specifiers[ns_i];
const node_i = path.parent.body.indexOf(path.node);
if (path.node.specifiers.length === 1) {
path.parent.body.splice(node_i, 1);
} else {
path.node.specifiers.splice(ns_i, 1);
}
path.parent.body.splice(
node_i,
0,
t.importDeclaration(
[
t.importDefaultSpecifier(ns.local)
],
t.stringLiteral(
`${prefix}${encodeURIComponent(specifier)}&namespace`
)
)
)
}
},
Import(path) {
path.parent.arguments[0] = t.templateLiteral(
[
t.templateElement({
raw: prefix,
cooked: prefix,
}),
t.templateElement({ raw: '&namespace', cooked: '&namespace' }, true),
],
[
t.callExpression(t.identifier('encodeURIComponent'), [
path.parent.arguments[0],
]),
]
);
},
},
};
};
module.exports = (code, { referrer = '' } = {}) => {
let meta = {
hasDefault: false
};
// double parse because we don't know what this thing is
try {
return {
code: babel.transform(code, {
sourceType: 'module',
plugins: [transform(referrer, meta)],
parserOpts: {
plugins: ['dynamicImport', 'importMeta'],
},
}).code,
meta,
};
} catch (e) {
console.error(e);
return {
code: babel.transform(code, {
sourceType: 'script',
plugins: [transform(referrer, meta)],
parserOpts: {
plugins: ['dynamicImport', 'importMeta'],
},
}).code,
meta,
};
}
};